|
998 | 998 | const rank = o.globalRank; |
999 | 999 | const total = p.owners.length; |
1000 | 1000 | o.tier = rank <= 10 ? 'gold' : rank <= 50 ? 'teal' : rank <= 200 ? 'silver' : 'grey'; |
1001 | | - o.isWhale = rank <= 10; |
| 1001 | + o.isTop10 = rank <= 10; |
1002 | 1002 | o.pctLabel = topPercentLabel(rank, total); |
1003 | 1003 | // Size is driven by market value held (cube root for visual-area-linear scaling) |
1004 | 1004 | const valueRatio = Math.cbrt((o.valueHeld || 0) / maxValueHeld); |
|
1313 | 1313 | if (n.type === 'collector') { |
1314 | 1314 | const rankBadge = n.globalRank <= 10 ? `<span style="color:#f5b840; font-weight:800;">#${n.globalRank}</span>` : `<span style="color:#9aa;">#${n.globalRank}</span>`; |
1315 | 1315 | const badges = []; |
1316 | | - if (n.isWhale) badges.push('<b style="color:#f5b840;">TOP 10 LOCKED</b>'); |
| 1316 | + if (n.isTop10) badges.push('<b style="color:#f5b840;">TOP 10 LOCKED</b>'); |
1317 | 1317 | if (n.crossPlayerFan) badges.push(`<b style="color:#ff9a4a;">MULTI-PLAYER (${n.crossPlayerCount})</b>`); |
1318 | 1318 | return `<div style="background:rgba(0,0,0,0.92); padding:12px 16px; border-radius:8px; color:#fff; border:1px solid ${esc(n.color)}; font-size:12px; min-width:220px;">${rankBadge} <span style="font-weight:700; font-size:14px;">${esc(n.name)}</span>${badges.length ? '<br/>' + badges.join(' · ') : ''}<br/><span style="color:#9aa; font-size:11px;">${fmtLockedScore(n.lockedScore)} locked score · ${n.fullHoldings.toLocaleString()} moments owned · ${esc(n.pctLabel)}</span></div>`; |
1319 | 1319 | } |
|
1566 | 1566 | // avatars + names, even silver tier gets a small avatar + name (not just a grey dot). |
1567 | 1567 | const size = Math.sqrt(n.val) * 2.0; |
1568 | 1568 |
|
1569 | | - if (n.isWhale) { |
| 1569 | + if (n.isTop10) { |
1570 | 1570 | // Inner circle collectors: avatar-first — the real profile image IS the node |
1571 | 1571 | const avatarSize = size * 3.8; |
1572 | 1572 | const placeholder = new THREE.Mesh( |
|
1663 | 1663 | if (l.kind === 'collector-to-player') return l.strokeColor || 'rgba(245,184,64,0.55)'; |
1664 | 1664 | if (l.kind === 'player-moment') return 'rgba(255,217,107,0.55)'; |
1665 | 1665 | const srcNode = typeof l.source === 'object' ? l.source : null; |
1666 | | - if (srcNode?.isWhale) return 'rgba(245,184,64,0.62)'; |
| 1666 | + if (srcNode?.isTop10) return 'rgba(245,184,64,0.62)'; |
1667 | 1667 | if (srcNode?.tier === 'teal') return 'rgba(20,216,196,0.35)'; |
1668 | 1668 | if (srcNode?.crossPlayerFan) return 'rgba(255,154,74,0.32)'; |
1669 | 1669 | return 'rgba(240,242,253,0.05)'; |
|
1673 | 1673 | if (l.kind === 'collector-to-player') return 1.8; |
1674 | 1674 | if (l.kind === 'player-moment') return 1.8; |
1675 | 1675 | const srcNode = typeof l.source === 'object' ? l.source : null; |
1676 | | - if (srcNode?.isWhale) return 1.4; |
| 1676 | + if (srcNode?.isTop10) return 1.4; |
1677 | 1677 | if (srcNode?.tier === 'teal') return 0.8; |
1678 | 1678 | return 0.35; |
1679 | 1679 | }) |
1680 | 1680 | .linkDirectionalParticles(l => { |
1681 | 1681 | if (l.kind === 'collector-to-player') return 3; |
1682 | 1682 | if (l.kind === 'player-moment') return 3; |
1683 | 1683 | const srcNode = typeof l.source === 'object' ? l.source : null; |
1684 | | - if (srcNode?.isWhale) return 2; |
| 1684 | + if (srcNode?.isTop10) return 2; |
1685 | 1685 | return 0; |
1686 | 1686 | }) |
1687 | 1687 | .linkDirectionalParticleSpeed(0.008) |
|
1808 | 1808 | Graph.d3Force('link').distance(l => { |
1809 | 1809 | if (l.kind === 'player-moment') return 120; |
1810 | 1810 | const src = typeof l.source === 'object' ? l.source : null; |
1811 | | - if (src?.isWhale) return 40; |
| 1811 | + if (src?.isTop10) return 40; |
1812 | 1812 | if (src?.tier === 'teal') return 100; |
1813 | 1813 | return 200; |
1814 | 1814 | }); |
|
1951 | 1951 | }; |
1952 | 1952 | animateCount(document.getElementById('gm-moments'), totalMoments, 1500); |
1953 | 1953 | animateCount(document.getElementById('gm-collectors'), currentData.stats.collectors || 0, 1300); |
1954 | | - animateCount(document.getElementById('gm-whales'), currentData.stats.whales || 0, 1100); |
| 1954 | + animateCount(document.getElementById('gm-top10'), currentData.stats.top10 || 0, 1100); |
1955 | 1955 | animateCount(document.getElementById('gm-serials'), currentData.stats.editions || 0, 900); |
1956 | 1956 | // Locked score total (sum of all locked ASP for this player) — shown as currency. |
1957 | 1957 | const lockedTotal = currentData.stats.lockedTotalScore || 0; |
|
2504 | 2504 | row.style.cursor = 'pointer'; |
2505 | 2505 | const addrSp = mkEl('span', { className: 'addr' }); |
2506 | 2506 | addrSp.textContent = `#${h.node.globalRank} · ${h.node.name}`; |
2507 | | - if (h.node.isWhale) addrSp.appendChild(mkEl('span', { className: 'tier-b', text: 'Inner', style: 'margin-left:6px; background:rgba(245,184,64,0.14); border-color:rgba(245,184,64,0.3); color:#f5b840;' })); |
| 2507 | + if (h.node.isTop10) addrSp.appendChild(mkEl('span', { className: 'tier-b', text: 'Inner', style: 'margin-left:6px; background:rgba(245,184,64,0.14); border-color:rgba(245,184,64,0.3); color:#f5b840;' })); |
2508 | 2508 | if (h.node.crossPlayerFan) addrSp.appendChild(mkEl('span', { className: 'tier-b', text: `${h.node.crossPlayerCount}-player`, style: 'margin-left:6px; background:rgba(255,154,74,0.14); border-color:rgba(255,154,74,0.3); color:#ff9a4a;' })); |
2509 | 2509 | row.appendChild(addrSp); |
2510 | 2510 | row.appendChild(mkEl('span', { className: 'count', text: `${h.count} serial${h.count === 1 ? '' : 's'}` })); |
|
2974 | 2974 | window.history.replaceState(null, '', window.location.pathname); |
2975 | 2975 | } |
2976 | 2976 | // Also reset graph-meta fields explicitly so any later read sees blanks not stale |
2977 | | - ['gm-player', 'gm-moments', 'gm-collectors', 'gm-whales', 'gm-serials'].forEach(id => { |
| 2977 | + ['gm-player', 'gm-moments', 'gm-collectors', 'gm-top10', 'gm-serials'].forEach(id => { |
2978 | 2978 | const el = document.getElementById(id); if (el) el.textContent = '—'; |
2979 | 2979 | }); |
2980 | 2980 | window.scrollTo({ top: 0, behavior: 'smooth' }); |
|
3081 | 3081 | fullHoldings: h.owner.holdings, |
3082 | 3082 | holdings: h.cnt, |
3083 | 3083 | momentsOwned: [], |
3084 | | - isWhale: true, |
| 3084 | + isTop10: true, |
3085 | 3085 | tier: 'gold', |
3086 | 3086 | crossPlayerFan: crossCnt > 1, |
3087 | 3087 | crossPlayerCount: crossCnt, |
|
3114 | 3114 | fullHoldings: h.owner.holdings, |
3115 | 3115 | holdings: h.cnt, |
3116 | 3116 | momentsOwned: [], |
3117 | | - isWhale: false, |
| 3117 | + isTop10: false, |
3118 | 3118 | tier: 'teal', |
3119 | 3119 | crossPlayerFan: crossCnt > 1, |
3120 | 3120 | crossPlayerCount: crossCnt, |
|
3148 | 3148 | fullHoldings: h.owner.holdings, |
3149 | 3149 | holdings: h.cnt, |
3150 | 3150 | momentsOwned: [], |
3151 | | - isWhale: false, |
| 3151 | + isTop10: false, |
3152 | 3152 | tier: 'silver', |
3153 | 3153 | crossPlayerFan: crossCnt > 1, |
3154 | 3154 | crossPlayerCount: crossCnt, |
|
3224 | 3224 | document.getElementById('gm-moments').textContent = tierLabel(eg.edition.tier); |
3225 | 3225 | document.getElementById('gm-collectors').textContent = eg.stats.uniqueHolders.toString(); |
3226 | 3226 | const topLabel = eg.stats.topHolder ? (eg.stats.topHolder.owner.username || shortAddr(eg.stats.topHolder.addr)) : '—'; |
3227 | | - document.getElementById('gm-whales').textContent = topLabel; |
| 3227 | + document.getElementById('gm-top10').textContent = topLabel; |
3228 | 3228 | document.getElementById('gm-serials').textContent = eg.stats.circulation.toLocaleString(); |
3229 | 3229 |
|
3230 | 3230 | // Subtitle surfaces total unique holders + how many are visible in the ring |
|
3438 | 3438 | document.getElementById('gm-player').textContent = uname; |
3439 | 3439 | document.getElementById('gm-moments').textContent = cg.totalHoldings.toLocaleString() + ' serials'; |
3440 | 3440 | document.getElementById('gm-collectors').textContent = cg.perPlayer.length + ' players'; |
3441 | | - document.getElementById('gm-whales').textContent = pct.rank ? ('Top ' + pct.pctTile + '%') : '—'; |
| 3441 | + document.getElementById('gm-top10').textContent = pct.rank ? ('Top ' + pct.pctTile + '%') : '—'; |
3442 | 3442 | document.getElementById('gm-serials').textContent = (cg.topMoments || []).length + ' shown · ' + (cg.truncatedMoments || 0) + ' more'; |
3443 | 3443 | document.getElementById('graph-hint').textContent = 'Click a player to enter their universe · Esc returns'; |
3444 | 3444 |
|
|
3617 | 3617 | const p = data.players.find(x => x.name === payload.player); |
3618 | 3618 | if (p) { |
3619 | 3619 | const topOwner = currentData && currentData.ownerArr && currentData.ownerArr[0]; |
3620 | | - const whaleTag = topOwner ? ` · TOP LOCKED ${String(topOwner.name).toUpperCase()} · ${fmtLockedScore(topOwner.lockedScore)}` : ''; |
| 3620 | + const topLockedTag = topOwner ? ` · TOP LOCKED ${String(topOwner.name).toUpperCase()} · ${fmtLockedScore(topOwner.lockedScore)}` : ''; |
3621 | 3621 | const totalMarketValue = p.editions.reduce((a, e) => a + editionMarketValue(e), 0); |
3622 | | - typeLevelSubtitle(`${String(p.name).toUpperCase()} · ${(p.totalMintedMomentCount || 0).toLocaleString()} MOMENTS · ${(p.lockedLeaderboardCount || p.owners.length).toLocaleString()} LOCKED COLLECTORS · ${p.editions.length} EDITIONS${whaleTag}`); |
| 3622 | + typeLevelSubtitle(`${String(p.name).toUpperCase()} · ${(p.totalMintedMomentCount || 0).toLocaleString()} MOMENTS · ${(p.lockedLeaderboardCount || p.owners.length).toLocaleString()} LOCKED COLLECTORS · ${p.editions.length} EDITIONS${topLockedTag}`); |
3623 | 3623 | } else { |
3624 | 3624 | typeLevelSubtitle(''); |
3625 | 3625 | } |
|
0 commit comments