Spaces:
Running
Running
| const state = { | |
| data: null, | |
| track: "shared", | |
| category: "quality", | |
| sortMetric: "va", | |
| sortDirection: "desc", | |
| query: "", | |
| paradigm: "all", | |
| access: "all" | |
| }; | |
| const elements = { | |
| trackTabs: document.querySelector("#track-tabs"), | |
| trackDescription: document.querySelector("#track-description"), | |
| categoryTabs: document.querySelector("#category-tabs"), | |
| categoryTitle: document.querySelector("#category-title"), | |
| categoryDescription: document.querySelector("#category-description"), | |
| tablePanel: document.querySelector(".table-panel"), | |
| tableKicker: document.querySelector("#table-kicker"), | |
| rankingLabel: document.querySelector("#ranking-label"), | |
| table: document.querySelector("#leaderboard-table"), | |
| tableStatus: document.querySelector("#table-status"), | |
| contextCopy: document.querySelector("#context-copy"), | |
| search: document.querySelector("#model-search"), | |
| metricSelect: document.querySelector("#metric-select"), | |
| paradigm: document.querySelector("#paradigm-filter"), | |
| access: document.querySelector("#access-filter"), | |
| reset: document.querySelector("#reset-filters"), | |
| download: document.querySelector("#download-csv"), | |
| metricGuide: document.querySelector("#metric-guide"), | |
| error: document.querySelector("#data-error") | |
| }; | |
| const directionFor = (metric) => metric.direction === "higher" ? "desc" : "asc"; | |
| const escapeHtml = (value) => String(value) | |
| .replaceAll("&", "&") | |
| .replaceAll("<", "<") | |
| .replaceAll(">", ">") | |
| .replaceAll('"', """) | |
| .replaceAll("'", "'"); | |
| function formatScore(value) { | |
| if (value === null || value === undefined) return "—"; | |
| return Number(value).toFixed(state.data.meta.publishedPrecision); | |
| } | |
| function sourceLabel(access) { | |
| if (access === "Open") return "Open-source"; | |
| if (access === "Web") return "Closed-source"; | |
| return access; | |
| } | |
| function currentCategory() { | |
| return state.data.categories.find((category) => category.id === state.category); | |
| } | |
| function currentMetric() { | |
| return state.data.metrics[state.sortMetric]; | |
| } | |
| function applyLink(id, url, readyLabel, pendingLabel) { | |
| const link = document.querySelector(`#${id}`); | |
| if (!link) return; | |
| if (url) { | |
| link.href = url; | |
| link.target = "_blank"; | |
| link.rel = "noopener noreferrer"; | |
| link.classList.remove("is-disabled"); | |
| link.removeAttribute("aria-disabled"); | |
| const status = link.querySelector("[data-link-status]"); | |
| if (status) status.textContent = readyLabel; | |
| } else { | |
| link.removeAttribute("href"); | |
| link.classList.add("is-disabled"); | |
| link.setAttribute("aria-disabled", "true"); | |
| const status = link.querySelector("[data-link-status]"); | |
| if (status) status.textContent = pendingLabel; | |
| } | |
| } | |
| function renderMeta() { | |
| const { meta } = state.data; | |
| document.title = meta.title; | |
| document.querySelector("#hero-tagline").textContent = meta.tagline; | |
| document.querySelector("#hero-description").textContent = meta.description; | |
| document.querySelector("#stat-systems").textContent = meta.systemCount; | |
| document.querySelector("#stat-metrics").textContent = meta.metricCount; | |
| document.querySelector("#stat-scenarios").textContent = meta.scenarioCount; | |
| document.querySelector("#stat-duration").textContent = `${meta.durationSeconds}s`; | |
| applyLink("project-link", meta.links.project, "Project page", "Coming soon"); | |
| applyLink("code-link", meta.links.code, "Code repository", "Coming soon"); | |
| applyLink("paper-link", meta.links.paper, "Read paper", "Coming soon"); | |
| applyLink("dataset-link", meta.links.dataset, "Open dataset", "Coming soon"); | |
| } | |
| function renderTrackTabs() { | |
| elements.trackTabs.innerHTML = state.data.tracks.map((track) => { | |
| const active = track.id === state.track; | |
| return ` | |
| <button | |
| class="track-tab ${active ? "is-active" : ""}" | |
| type="button" | |
| role="tab" | |
| aria-selected="${active}" | |
| data-track="${escapeHtml(track.id)}" | |
| > | |
| <span>${escapeHtml(track.label)}</span> | |
| <b>${escapeHtml(track.badge || track.count)}</b> | |
| </button> | |
| `; | |
| }).join(""); | |
| const activeTrack = state.data.tracks.find((track) => track.id === state.track); | |
| elements.trackDescription.textContent = activeTrack.description; | |
| elements.trackTabs.querySelectorAll("[data-track]").forEach((button) => { | |
| button.addEventListener("click", () => { | |
| state.track = button.dataset.track; | |
| const firstCategory = state.data.categories.find((category) => category.track === state.track); | |
| state.category = firstCategory.id; | |
| state.sortMetric = firstCategory.defaultMetric; | |
| state.sortDirection = directionFor(state.data.metrics[state.sortMetric]); | |
| render(); | |
| }); | |
| }); | |
| } | |
| function renderCategoryTabs() { | |
| const categories = state.data.categories.filter((category) => category.track === state.track); | |
| elements.categoryTabs.innerHTML = categories.map((category) => { | |
| const active = category.id === state.category; | |
| return ` | |
| <button | |
| class="category-tab ${active ? "is-active" : ""}" | |
| type="button" | |
| aria-pressed="${active}" | |
| data-category="${escapeHtml(category.id)}" | |
| > | |
| ${escapeHtml(category.label)} | |
| </button> | |
| `; | |
| }).join(""); | |
| elements.categoryTabs.querySelectorAll("[data-category]").forEach((button) => { | |
| button.addEventListener("click", () => { | |
| const category = state.data.categories.find((item) => item.id === button.dataset.category); | |
| state.category = category.id; | |
| state.sortMetric = category.defaultMetric; | |
| state.sortDirection = directionFor(state.data.metrics[state.sortMetric]); | |
| render(); | |
| }); | |
| }); | |
| } | |
| function renderMetricSelect() { | |
| const category = currentCategory(); | |
| elements.metricSelect.innerHTML = category.metrics.map((metricKey) => { | |
| const metric = state.data.metrics[metricKey]; | |
| const direction = metric.direction === "higher" ? "↑" : "↓"; | |
| return `<option value="${escapeHtml(metricKey)}">${escapeHtml(metric.abbr)} ${direction} · ${escapeHtml(metric.name)}</option>`; | |
| }).join(""); | |
| elements.metricSelect.value = state.sortMetric; | |
| } | |
| function compareScores(a, b, metricKey, direction) { | |
| const aValue = a.scores[metricKey]; | |
| const bValue = b.scores[metricKey]; | |
| if (aValue === null && bValue === null) return a.name.localeCompare(b.name); | |
| if (aValue === null) return 1; | |
| if (bValue === null) return -1; | |
| const difference = direction === "desc" ? bValue - aValue : aValue - bValue; | |
| return difference || a.name.localeCompare(b.name); | |
| } | |
| function buildRankMap(metricKey) { | |
| const metric = state.data.metrics[metricKey]; | |
| const sortedValues = state.data.models | |
| .map((model) => model.scores[metricKey]) | |
| .filter((value) => value !== null) | |
| .sort((a, b) => metric.direction === "higher" ? b - a : a - b); | |
| const ranks = new Map(); | |
| sortedValues.forEach((value, index) => { | |
| if (!ranks.has(value)) ranks.set(value, index + 1); | |
| }); | |
| return ranks; | |
| } | |
| function filteredModels() { | |
| const query = state.query.trim().toLocaleLowerCase(); | |
| return state.data.models | |
| .filter((model) => !query || model.name.toLocaleLowerCase().includes(query)) | |
| .filter((model) => state.paradigm === "all" || model.paradigm === state.paradigm) | |
| .filter((model) => state.access === "all" || model.access === state.access) | |
| .sort((a, b) => compareScores(a, b, state.sortMetric, state.sortDirection)); | |
| } | |
| function contextForCategory(categoryId) { | |
| const ranking = ` | |
| <p><strong>Ranking.</strong> Ranks use published three-decimal scores; ties use competition ranking (for example, 1, 1, 3). Select a metric to show the best values first, or click its active table header to reverse the display order.</p> | |
| `; | |
| const notes = { | |
| streaming: ` | |
| <p><strong>Availability.</strong> NBC, FPS, and TTFC are unavailable for PixVerse R1, HappyOyster, and Odyssey-2 because their web interfaces do not expose model-native boundaries or reliable generation-time traces.</p> | |
| `, | |
| adherence: ` | |
| <p><strong>Endpoint drift.</strong> VID and AID are absolute changes between the first and last 30-second intervals; lower values indicate better stability.</p> | |
| `, | |
| stability: ` | |
| <p><strong>Reading drift.</strong> The six drift metrics favor lower endpoint change, while subject and background consistency favor higher values.</p> | |
| `, | |
| response: ` | |
| <p><strong>Conditional latency.</strong> PVRL and PARL are measured only for achieved targets and should be read together with PVUAR and PAUAR.</p> | |
| `, | |
| state: ` | |
| <p><strong>Conditional coverage.</strong> HDF is evaluated only when the required source state was established.</p> | |
| `, | |
| adjusted: ` | |
| <p><strong>Diagnostic status.</strong> These four adjusted diagnostics are separate from the 32 core metrics. SA-PVRL and SA-PARL assign the 30-second cap to unachieved targets; CA-HDF-A and CA-HDF-L assign zero when the required source state was not established.</p> | |
| ` | |
| }; | |
| return `${ranking}${notes[categoryId] || ""}`; | |
| } | |
| function renderTable() { | |
| const category = currentCategory(); | |
| const metric = currentMetric(); | |
| const models = filteredModels(); | |
| const rankMap = buildRankMap(state.sortMetric); | |
| const arrow = state.sortDirection === "desc" ? "↓" : "↑"; | |
| const preferredDirection = metric.direction === "higher" ? "Higher is better" : "Lower is better"; | |
| const displayOrder = state.sortDirection === directionFor(metric) ? "Best to worst" : "Worst to best"; | |
| const isDiagnostics = state.track === "diagnostics"; | |
| elements.tablePanel.classList.toggle("is-diagnostics", isDiagnostics); | |
| elements.tableKicker.textContent = isDiagnostics ? "Adjusted sensitivity analysis" : "Metric-wise ranking"; | |
| elements.categoryTitle.textContent = category.label; | |
| elements.categoryDescription.textContent = category.description; | |
| elements.rankingLabel.innerHTML = ` | |
| Ranked by <strong>${escapeHtml(metric.name)}</strong> | |
| <span>${preferredDirection} · ${displayOrder}</span> | |
| `; | |
| elements.contextCopy.innerHTML = contextForCategory(category.id); | |
| const metricHeaders = category.metrics.map((metricKey) => { | |
| const item = state.data.metrics[metricKey]; | |
| const active = metricKey === state.sortMetric; | |
| const ariaSort = active | |
| ? (state.sortDirection === "desc" ? "descending" : "ascending") | |
| : "none"; | |
| const title = active ? `Reverse ${item.name} order` : `Rank by ${item.name}`; | |
| return ` | |
| <th scope="col" aria-sort="${ariaSort}" class="metric-column ${active ? "is-sorted" : ""}"> | |
| <button type="button" data-sort="${escapeHtml(metricKey)}" title="${escapeHtml(title)}"> | |
| <span>${escapeHtml(item.abbr)}</span> | |
| <i aria-hidden="true">${active ? arrow : "↕"}</i> | |
| <small>${item.direction === "higher" ? "higher" : "lower"}</small> | |
| </button> | |
| </th> | |
| `; | |
| }).join(""); | |
| const rows = models.map((model) => { | |
| const sortedValue = model.scores[state.sortMetric]; | |
| const rank = sortedValue === null ? null : rankMap.get(sortedValue); | |
| const rankClass = rank !== null && rank <= 3 ? ` rank-${rank}` : ""; | |
| const cells = category.metrics.map((metricKey) => { | |
| const value = model.scores[metricKey]; | |
| const metricRankMap = buildMetricRankMap(metricKey); | |
| const cellRank = value === null ? null : metricRankMap.get(value); | |
| const rankClass = cellRank === 1 ? "is-best" : cellRank === 2 ? "is-runner-up" : ""; | |
| const sortedClass = metricKey === state.sortMetric ? "is-sorted" : ""; | |
| const metricInfo = state.data.metrics[metricKey]; | |
| const unit = value !== null && metricInfo.unit ? ` ${metricInfo.unit}` : ""; | |
| const unavailableReason = value === null | |
| ? "Unavailable because the official web interface does not expose model-native boundaries or reliable generation-time traces." | |
| : ""; | |
| return ` | |
| <td | |
| class="score-cell ${rankClass} ${sortedClass}" | |
| data-label="${escapeHtml(metricInfo.abbr)}" | |
| ${unavailableReason ? `title="${escapeHtml(unavailableReason)}"` : ""} | |
| > | |
| ${value === null | |
| ? `<span aria-hidden="true">—</span><span class="sr-only">${escapeHtml(unavailableReason)}</span>` | |
| : `<span>${formatScore(value)}</span>${unit ? `<small>${escapeHtml(unit.trim())}</small>` : ""}` | |
| } | |
| </td> | |
| `; | |
| }).join(""); | |
| return ` | |
| <tr> | |
| <td class="rank-cell" data-label="Rank"> | |
| ${rank === null ? "—" : `<span class="rank-badge${rankClass}">${rank}</span>`} | |
| </td> | |
| <th scope="row" class="model-cell"> | |
| <a href="${escapeHtml(model.reference)}" target="_blank" rel="noopener noreferrer"> | |
| <span>${escapeHtml(model.name)}</span><i aria-hidden="true">↗</i> | |
| </a> | |
| <small>${model.paradigm === "Cascaded" ? "with HunyuanVideo-Foley" : "native audio-video"}</small> | |
| </th> | |
| <td class="meta-cell" data-label="Paradigm"> | |
| <span class="tag tag-${model.paradigm === "Native joint" ? "native" : "cascaded"}">${escapeHtml(model.paradigm)}</span> | |
| </td> | |
| <td class="meta-cell" data-label="Source"> | |
| <span class="access-dot access-${model.access.toLowerCase()}"></span>${escapeHtml(sourceLabel(model.access))} | |
| </td> | |
| ${cells} | |
| </tr> | |
| `; | |
| }).join(""); | |
| elements.table.innerHTML = ` | |
| <thead> | |
| <tr> | |
| <th scope="col" class="rank-heading">#</th> | |
| <th scope="col" class="model-heading">System</th> | |
| <th scope="col">Paradigm</th> | |
| <th scope="col">Source</th> | |
| ${metricHeaders} | |
| </tr> | |
| </thead> | |
| <tbody> | |
| ${rows || ` | |
| <tr> | |
| <td class="empty-row" colspan="${4 + category.metrics.length}"> | |
| No systems match the current filters. | |
| </td> | |
| </tr> | |
| `} | |
| </tbody> | |
| `; | |
| elements.tableStatus.textContent = `${models.length} of ${state.data.models.length} systems · global ranks use published three-decimal scores`; | |
| elements.table.querySelectorAll("[data-sort]").forEach((button) => { | |
| button.addEventListener("click", () => { | |
| const metricKey = button.dataset.sort; | |
| if (state.sortMetric === metricKey) { | |
| state.sortDirection = state.sortDirection === "desc" ? "asc" : "desc"; | |
| } else { | |
| state.sortMetric = metricKey; | |
| state.sortDirection = directionFor(state.data.metrics[metricKey]); | |
| } | |
| elements.metricSelect.value = state.sortMetric; | |
| renderTable(); | |
| renderMetricGuide(); | |
| }); | |
| }); | |
| } | |
| function buildMetricRankMap(metricKey) { | |
| const item = state.data.metrics[metricKey]; | |
| const values = state.data.models | |
| .map((model) => model.scores[metricKey]) | |
| .filter((value) => value !== null) | |
| .sort((a, b) => item.direction === "higher" ? b - a : a - b); | |
| return new Map([...new Set(values)].map((value, index) => [value, index + 1])); | |
| } | |
| function renderMetricGuide() { | |
| const category = currentCategory(); | |
| elements.metricGuide.innerHTML = category.metrics.map((metricKey) => { | |
| const metric = state.data.metrics[metricKey]; | |
| const active = metricKey === state.sortMetric; | |
| return ` | |
| <article class="metric-card ${active ? "is-active" : ""}"> | |
| <button type="button" data-metric-card="${escapeHtml(metricKey)}" aria-label="Rank by ${escapeHtml(metric.name)}"> | |
| <span class="metric-abbr">${escapeHtml(metric.abbr)}</span> | |
| <span class="direction direction-${metric.direction}"> | |
| ${metric.direction === "higher" ? "↑ Higher" : "↓ Lower"} | |
| </span> | |
| </button> | |
| <h3>${escapeHtml(metric.name)}</h3> | |
| <p>${escapeHtml(metric.description)}</p> | |
| <dl> | |
| <div><dt>Reported as</dt><dd>${escapeHtml(metric.range)}${metric.unit ? ` · ${escapeHtml(metric.unit)}` : ""}</dd></div> | |
| </dl> | |
| </article> | |
| `; | |
| }).join(""); | |
| elements.metricGuide.querySelectorAll("[data-metric-card]").forEach((button) => { | |
| button.addEventListener("click", () => { | |
| state.sortMetric = button.dataset.metricCard; | |
| state.sortDirection = directionFor(state.data.metrics[state.sortMetric]); | |
| elements.metricSelect.value = state.sortMetric; | |
| renderTable(); | |
| renderMetricGuide(); | |
| document.querySelector("#leaderboard").scrollIntoView({ behavior: "smooth", block: "start" }); | |
| }); | |
| }); | |
| } | |
| function csvCell(value) { | |
| const stringValue = value === null || value === undefined ? "" : String(value); | |
| return `"${stringValue.replaceAll('"', '""')}"`; | |
| } | |
| function downloadCurrentView() { | |
| const category = currentCategory(); | |
| const models = filteredModels(); | |
| const headers = ["System", "Paradigm", "Source", ...category.metrics.map((key) => state.data.metrics[key].abbr)]; | |
| const lines = [ | |
| headers.map(csvCell).join(","), | |
| ...models.map((model) => [ | |
| model.name, | |
| model.paradigm, | |
| sourceLabel(model.access), | |
| ...category.metrics.map((key) => model.scores[key]) | |
| ].map(csvCell).join(",")) | |
| ]; | |
| const blob = new Blob([`\uFEFF${lines.join("\n")}`], { type: "text/csv;charset=utf-8" }); | |
| const url = URL.createObjectURL(blob); | |
| const anchor = document.createElement("a"); | |
| anchor.href = url; | |
| anchor.download = `streamav-bench-${category.id}.csv`; | |
| document.body.appendChild(anchor); | |
| anchor.click(); | |
| anchor.remove(); | |
| URL.revokeObjectURL(url); | |
| } | |
| function resetFilters() { | |
| state.query = ""; | |
| state.paradigm = "all"; | |
| state.access = "all"; | |
| elements.search.value = ""; | |
| elements.paradigm.value = "all"; | |
| elements.access.value = "all"; | |
| renderTable(); | |
| } | |
| function bindControls() { | |
| elements.search.addEventListener("input", (event) => { | |
| state.query = event.target.value; | |
| renderTable(); | |
| }); | |
| elements.metricSelect.addEventListener("change", (event) => { | |
| state.sortMetric = event.target.value; | |
| state.sortDirection = directionFor(state.data.metrics[state.sortMetric]); | |
| renderTable(); | |
| renderMetricGuide(); | |
| }); | |
| elements.paradigm.addEventListener("change", (event) => { | |
| state.paradigm = event.target.value; | |
| renderTable(); | |
| }); | |
| elements.access.addEventListener("change", (event) => { | |
| state.access = event.target.value; | |
| renderTable(); | |
| }); | |
| elements.reset.addEventListener("click", resetFilters); | |
| elements.download.addEventListener("click", downloadCurrentView); | |
| } | |
| function render() { | |
| renderTrackTabs(); | |
| renderCategoryTabs(); | |
| renderMetricSelect(); | |
| renderTable(); | |
| renderMetricGuide(); | |
| } | |
| async function init() { | |
| try { | |
| const response = await fetch("./data.json", { cache: "no-store" }); | |
| if (!response.ok) throw new Error(`Data request failed with status ${response.status}`); | |
| state.data = await response.json(); | |
| state.sortDirection = directionFor(state.data.metrics[state.sortMetric]); | |
| renderMeta(); | |
| bindControls(); | |
| render(); | |
| document.documentElement.classList.add("is-ready"); | |
| } catch (error) { | |
| console.error(error); | |
| elements.error.hidden = false; | |
| elements.error.querySelector("p").textContent = "The leaderboard data could not be loaded. Please refresh the page or try again later."; | |
| } | |
| } | |
| init(); | |