Spaces:
Running
Running
| const ACCENT = "#5eead4"; | |
| const BASE = "#6b7280"; | |
| const css = (v) => getComputedStyle(document.documentElement).getPropertyValue(v).trim(); | |
| let DATA = null; | |
| let scoreChart = null; | |
| let lenChart = null; | |
| const $ = (id) => document.getElementById(id); | |
| function shortKey(k) { | |
| if (!k || k.length <= 14) return { head: k || "—", tail: "" }; | |
| return { head: k.slice(0, 8), tail: "…" + k.slice(-6) }; | |
| } | |
| async function load() { | |
| try { | |
| const res = await fetch("./data.json", { cache: "no-store" }); | |
| if (!res.ok) throw new Error("HTTP " + res.status); | |
| DATA = await res.json(); | |
| } catch (err) { | |
| console.error("Failed to load data.json", err); | |
| $("board-empty").hidden = false; | |
| $("board-empty").textContent = "Could not load data.json — has the refresh job run yet?"; | |
| return; | |
| } | |
| hydrateUpdated(); | |
| buildViews(); | |
| renderActiveView(); | |
| } | |
| function hydrateUpdated() { | |
| const ts = DATA.generated_at; | |
| const label = ts ? new Date(ts).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" }) : "unknown"; | |
| $("updated").textContent = "updated " + label; | |
| $("footer-meta").textContent = DATA.sample ? "sample data" : "live data"; | |
| } | |
| function buildViews() { | |
| const select = $("validator-select"); | |
| select.innerHTML = ""; | |
| const views = []; | |
| if (DATA.aggregate && Array.isArray(DATA.aggregate.rankings) && DATA.aggregate.rankings.length) { | |
| views.push({ id: "__consensus__", label: "Consensus · all validators" }); | |
| } | |
| for (const v of DATA.validators || []) { | |
| const sk = shortKey(v.hotkey); | |
| views.push({ id: v.hotkey, label: "Validator " + sk.head + sk.tail }); | |
| } | |
| for (const view of views) { | |
| const opt = document.createElement("option"); | |
| opt.value = view.id; | |
| opt.textContent = view.label; | |
| select.appendChild(opt); | |
| } | |
| select.onchange = renderActiveView; | |
| $("stat-validators").textContent = (DATA.validators || []).length || "0"; | |
| const everyMiner = new Set(); | |
| for (const v of DATA.validators || []) for (const r of v.rankings || []) everyMiner.add(r.hotkey); | |
| $("stat-miners").textContent = everyMiner.size || (DATA.aggregate?.rankings?.length ?? 0); | |
| } | |
| function activeView() { | |
| const id = $("validator-select").value; | |
| if (id === "__consensus__" || !id) { | |
| return { | |
| rankings: DATA.aggregate?.rankings || [], | |
| history: DATA.aggregate?.history || null, | |
| }; | |
| } | |
| const v = (DATA.validators || []).find((x) => x.hotkey === id); | |
| return { rankings: v?.rankings || [], history: v?.history || null }; | |
| } | |
| function renderActiveView() { | |
| const view = activeView(); | |
| renderBoard(view.rankings); | |
| renderStats(view); | |
| renderTrends(view); | |
| } | |
| function renderStats(view) { | |
| const top = view.rankings[0]; | |
| $("stat-top").textContent = top ? top.score.toFixed(3) : "—"; | |
| const ep = view.history?.epochs; | |
| $("stat-epoch").textContent = ep && ep.length ? ep[ep.length - 1] : "—"; | |
| } | |
| function renderBoard(rankings) { | |
| const body = $("board-body"); | |
| body.innerHTML = ""; | |
| $("board-empty").hidden = rankings.length > 0; | |
| const max = rankings.reduce((m, r) => Math.max(m, r.score), 0) || 1; | |
| rankings.forEach((r, i) => { | |
| const tr = document.createElement("tr"); | |
| tr.className = "rank-" + (i + 1); | |
| const sk = shortKey(r.hotkey); | |
| const pct = Math.max(2, Math.round((r.score / max) * 100)); | |
| const rankCell = document.createElement("td"); | |
| rankCell.className = "c-rank"; | |
| const rank = document.createElement("span"); | |
| rank.className = "rank-num"; | |
| rank.textContent = String(i + 1).padStart(2, "0"); | |
| rankCell.appendChild(rank); | |
| const hotkeyCell = document.createElement("td"); | |
| const hotkey = document.createElement("span"); | |
| hotkey.className = "hotkey"; | |
| const head = document.createElement("span"); | |
| head.className = "head"; | |
| head.textContent = sk.head; | |
| const tail = document.createElement("span"); | |
| tail.className = "tail"; | |
| tail.textContent = sk.tail; | |
| hotkey.append(head, tail); | |
| hotkeyCell.appendChild(hotkey); | |
| const scoreCell = document.createElement("td"); | |
| scoreCell.className = "score-val"; | |
| scoreCell.textContent = r.score.toFixed(4); | |
| const barCell = document.createElement("td"); | |
| barCell.className = "c-bar"; | |
| const bar = document.createElement("div"); | |
| bar.className = "bar"; | |
| const barFill = document.createElement("i"); | |
| barFill.style.width = `${pct}%`; | |
| bar.appendChild(barFill); | |
| barCell.appendChild(bar); | |
| tr.append(rankCell, hotkeyCell, scoreCell, barCell); | |
| body.appendChild(tr); | |
| }); | |
| } | |
| function seriesFor(history, hotkey) { | |
| if (!history) return null; | |
| const epochs = history.epochs || []; | |
| const miner = history.miners ? history.miners[hotkey] : null; | |
| const original = history.original || null; | |
| return { epochs, miner, original }; | |
| } | |
| function hasPoints(arr) { | |
| return Array.isArray(arr) && arr.some((x) => x !== null && x !== undefined && !Number.isNaN(x)); | |
| } | |
| function renderTrends(view) { | |
| const top = view.rankings[0]; | |
| const s = top ? seriesFor(view.history, top.hotkey) : null; | |
| const sk = top ? shortKey(top.hotkey) : { head: "—", tail: "" }; | |
| $("trend-miner").textContent = sk.head + sk.tail; | |
| drawTrend("score", s, "score", top); | |
| drawTrend("len", s, "completion_len", top); | |
| } | |
| function drawTrend(which, s, field, top) { | |
| const canvasId = which === "score" ? "chart-score" : "chart-len"; | |
| const awaitId = which === "score" ? "await-score" : "await-len"; | |
| const minerData = s?.miner?.[field]; | |
| const origData = s?.original?.[field]; | |
| const ok = top && s && s.epochs.length && (hasPoints(minerData) || hasPoints(origData)); | |
| $(awaitId).hidden = !!ok; | |
| if (!ok) { | |
| destroyChart(which); | |
| return; | |
| } | |
| const ctx = $(canvasId).getContext("2d"); | |
| const datasets = []; | |
| if (hasPoints(minerData)) datasets.push(lineDS("Top miner", minerData, ACCENT, css("--accent-ghost"))); | |
| if (hasPoints(origData)) datasets.push(lineDS("Original model", origData, BASE, "transparent", true)); | |
| const cfg = { | |
| type: "line", | |
| data: { labels: s.epochs, datasets }, | |
| options: chartOptions(which === "len" ? "tokens" : "score"), | |
| }; | |
| destroyChart(which); | |
| const chart = new Chart(ctx, cfg); | |
| if (which === "score") scoreChart = chart; else lenChart = chart; | |
| } | |
| function lineDS(label, data, color, fill, dashed = false) { | |
| return { | |
| label, data, | |
| borderColor: color, | |
| backgroundColor: fill, | |
| borderWidth: 2, | |
| borderDash: dashed ? [5, 4] : [], | |
| pointRadius: 0, | |
| pointHoverRadius: 4, | |
| tension: 0.25, | |
| fill: !dashed, | |
| spanGaps: true, | |
| }; | |
| } | |
| function chartOptions(yLabel) { | |
| const grid = css("--line-soft"); | |
| const tick = css("--faint"); | |
| return { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| interaction: { mode: "index", intersect: false }, | |
| plugins: { | |
| legend: { labels: { color: css("--muted"), boxWidth: 10, boxHeight: 10, usePointStyle: true, font: { size: 11 } } }, | |
| tooltip: { | |
| backgroundColor: "#0b0e12", borderColor: css("--line"), borderWidth: 1, | |
| titleColor: css("--muted"), bodyColor: css("--text"), padding: 10, displayColors: true, | |
| }, | |
| }, | |
| scales: { | |
| x: { title: { display: true, text: "epoch", color: tick, font: { size: 10 } }, grid: { color: grid }, ticks: { color: tick, font: { size: 10 } } }, | |
| y: { title: { display: true, text: yLabel, color: tick, font: { size: 10 } }, grid: { color: grid }, ticks: { color: tick, font: { size: 10 } } }, | |
| }, | |
| }; | |
| } | |
| function destroyChart(which) { | |
| if (which === "score" && scoreChart) { scoreChart.destroy(); scoreChart = null; } | |
| if (which === "len" && lenChart) { lenChart.destroy(); lenChart = null; } | |
| } | |
| window.addEventListener("DOMContentLoaded", load); | |