ankanmbz's picture
Correct Bernini display name
cf0ce78 verified
Raw History Blame Contribute Delete
12.4 kB
"use strict";
(() => {
const DATASET = "ankanmbz/worldguide-results";
const REMOTE_BASE = `https://huggingface.co/datasets/${DATASET}/resolve/main/`;
const MODEL_ORDER = ["Our", "Cosmos2.5", "HunyuanVideo-1.5", "MiniMax-H3", "SkyReels", "LTX-2.5", "Barnini", "TempAct", "PhysAgent"];
const params = new URLSearchParams(location.search);
const local = ["localhost", "127.0.0.1", "[::1]"].includes(location.hostname) && params.get("local") === "1";
const $ = (id) => document.getElementById(id);
let manifest, selectedId, category = "All", query = "", requestVersion = 0, toastTimer;
let videos = [];
function element(tag, className, text) {
const node = document.createElement(tag);
if (className) node.className = className;
if (text !== undefined) node.textContent = text;
return node;
}
function assetURL(path, poster = false) {
const encoded = path.split("/").map(encodeURIComponent).join("/");
return local ? new URL((poster ? "./" : "../") + encoded, location.href).href : REMOTE_BASE + encoded;
}
function announce(message) { $("playback-status").textContent = message; }
function toast(message) {
clearTimeout(toastTimer);
$("toast").textContent = message;
$("toast").hidden = false;
toastTimer = setTimeout(() => { $("toast").hidden = true; }, 3500);
}
function pauseAll() {
requestVersion++;
videos.forEach(video => video.pause());
announce("All videos paused.");
}
function filteredSamples() {
return manifest.samples.filter(sample =>
(category === "All" || sample.category === category) &&
`${sample.title} ${sample.category}`.toLowerCase().includes(query)
);
}
function renderList() {
const samples = filteredSamples();
const fragment = document.createDocumentFragment();
for (const sample of samples) {
const button = element("button", "sample-button");
button.type = "button";
button.dataset.sampleId = sample.id;
button.setAttribute("aria-pressed", String(sample.id === selectedId));
button.setAttribute("aria-controls", "comparison");
const preview = sample.videos.Our || Object.values(sample.videos)[0];
const image = element("img", "sample-thumbnail");
image.src = assetURL(preview.poster, true);
image.alt = "";
image.loading = "lazy";
image.width = 58;
image.height = 42;
const text = element("span", "sample-text");
text.append(element("span", "sample-name", sample.title), element("span", "sample-subtitle", sample.category));
button.append(image, text);
if (sample.id === selectedId) button.append(element("span", "sample-current-dot"));
button.addEventListener("click", () => {
selectSample(sample.id);
if (matchMedia("(max-width: 800px)").matches) {
$("sample-browser").open = false;
$("comparison").focus({ preventScroll: true });
$("comparison").scrollIntoView({ behavior: "instant", block: "start" });
}
});
fragment.append(button);
}
$("sample-list").replaceChildren(fragment);
$("sample-count").textContent = String(samples.length);
$("browse-hint").hidden = samples.length <= 5;
$("browse-hint").textContent = `Scroll to browse all ${samples.length} samples ↓`;
$("empty-results").hidden = samples.length > 0;
}
function renderCategories() {
const fragment = document.createDocumentFragment();
for (const name of ["All", ...new Set(manifest.samples.map(sample => sample.category))]) {
const button = element("button", "category-button", name);
button.type = "button";
button.setAttribute("aria-pressed", String(name === category));
button.addEventListener("click", () => {
category = name;
for (const peer of $("categories").children) peer.setAttribute("aria-pressed", String(peer === button));
renderList();
});
fragment.append(button);
}
$("categories").replaceChildren(fragment);
}
function makeCard(model, sample) {
const metadata = sample.videos[model.id];
const label = model.id === "Our" ? "WorldGuide" : model.id === "Barnini" ? "Bernini*" : model.label;
const card = element("article", `video-card${model.ours ? " ours" : ""}`);
card.dataset.model = model.id;
const heading = element("div", "card-heading");
const title = element("h3", "", label);
title.id = `model-${model.id}`;
heading.append(title, element("span", "model-dot"));
const frame = element("div", "video-frame");
const video = element("video");
video.controls = true;
video.muted = true;
video.defaultMuted = true;
video.playsInline = true;
video.preload = "none";
video.poster = assetURL(metadata.poster, true);
video.src = assetURL(metadata.path);
video.setAttribute("aria-label", `${label}: ${sample.title}`);
video.playbackRate = Number($("playback-speed").value);
frame.append(video);
const footer = element("div", "card-footer");
const specs = element("span", "video-specs mono");
specs.append(element("span", "", `${metadata.duration.toFixed(1)}s`), element("span", "", `${metadata.width} × ${metadata.height}`));
const open = element("a", "", "Open video ↗");
open.href = video.src;
open.target = "_blank";
open.rel = "noopener noreferrer";
open.setAttribute("aria-label", `Open ${label} video`);
footer.append(specs, open);
const error = element("div", "video-error");
error.hidden = true;
error.setAttribute("role", "status");
error.append(element("span", "", "Video couldn’t load."));
const retry = element("button", "text-button", "Retry");
retry.type = "button";
retry.addEventListener("click", () => {
error.hidden = true;
video.load();
video.play().catch(() => { if (video.isConnected) error.hidden = false; });
});
error.append(retry);
video.addEventListener("error", () => { error.hidden = false; });
video.addEventListener("playing", () => { error.hidden = true; });
card.append(heading, frame, footer, error,
window.WorldGuideRatings.createPanel({ sampleId: sample.id, modelId: model.id, label }));
videos.push(video);
return card;
}
function selectSample(id, updateURL = true) {
const sample = manifest.samples.find(item => item.id === id) || manifest.samples[0];
pauseAll();
// Release previous requests when moving between samples.
videos.forEach(video => { video.removeAttribute("src"); video.load(); });
videos = [];
selectedId = sample.id;
$("sample-title").textContent = sample.title;
$("sample-category").textContent = sample.category;
$("sample-position").textContent = `${manifest.samples.indexOf(sample) + 1} / ${manifest.samples.length}`;
document.title = `${sample.title} — WorldGuide`;
const models = MODEL_ORDER.map(id => manifest.models.find(model => model.id === id));
$("video-grid").replaceChildren(...models.map(model => makeCard(model, sample)));
renderList();
announce(`${sample.title}. ${models.length} model videos ready to play.`);
if (updateURL) {
const url = new URL(location.href);
url.searchParams.set("sample", sample.id);
history.replaceState(null, "", url);
}
}
async function playAll() {
const version = ++requestVersion;
announce("Loading and playing all videos.");
const results = await Promise.allSettled(videos.map(video => {
if (video.ended) video.currentTime = 0;
return video.play();
}));
if (version !== requestVersion) return;
const failed = results.filter(result => result.status === "rejected").length;
if (failed) toast("Some videos couldn’t start. Try their individual play controls.");
announce(failed ? "Some videos could not start." : "All videos playing.");
}
function moveSample(delta) {
const index = manifest.samples.findIndex(sample => sample.id === selectedId);
selectSample(manifest.samples[(index + delta + manifest.samples.length) % manifest.samples.length].id);
$("sample-list").querySelector('[aria-pressed="true"]')?.scrollIntoView({ block: "nearest" });
}
async function copyLink() {
const url = new URL(location.href);
url.searchParams.delete("local");
url.searchParams.set("sample", selectedId);
// A Space can be framed, but its direct URL is still a valid share link.
try {
await navigator.clipboard.writeText(url.href);
toast("Comparison link copied.");
} catch {
window.prompt("Copy this comparison link:", url.href);
}
}
function validate(data) {
if (data.schemaVersion !== 1 || data.dataset !== DATASET || !Array.isArray(data.samples) || !data.samples.length || !Array.isArray(data.models) || data.models.length !== MODEL_ORDER.length) throw new Error("Invalid collection manifest");
const ids = new Set();
const modelIds = new Set(data.models.map(model => model.id));
if (modelIds.size !== MODEL_ORDER.length || !MODEL_ORDER.every(id => modelIds.has(id))) throw new Error("Invalid model list");
for (const sample of data.samples) {
if (typeof sample.id !== "string" || ids.has(sample.id) || typeof sample.title !== "string" || typeof sample.category !== "string") throw new Error("Invalid sample");
ids.add(sample.id);
for (const model of data.models) {
const video = sample.videos?.[model.id];
if (!video || !Number.isFinite(video.duration) || video.duration <= 0 || !Number.isFinite(video.width) || !Number.isFinite(video.height)) throw new Error("Missing video metadata");
for (const path of [video.path, video.poster]) {
if (typeof path !== "string" || path.startsWith("/") || path.split("/").includes("..") || path.includes(":")) throw new Error("Invalid asset path");
}
}
}
return data;
}
async function fetchManifest(url) {
const response = await fetch(url, { signal: AbortSignal.timeout(12000) });
if (!response.ok) throw new Error(`Manifest request failed: ${response.status}`);
return validate(await response.json());
}
async function init() {
try {
if (local) manifest = await fetchManifest("./manifest.json");
else {
try { manifest = await fetchManifest(REMOTE_BASE + "manifest.json"); }
catch { manifest = await fetchManifest("./manifest.json"); }
}
$("sample-total").textContent = String(manifest.samples.length);
$("model-total").textContent = String(manifest.models.length);
$("video-total").textContent = String(manifest.samples.length * manifest.models.length);
renderCategories();
selectSample(params.get("sample"), false);
$("comparison").setAttribute("aria-busy", "false");
for (const id of ["previous", "next", "play-all", "pause-all", "restart", "copy-link"]) $(id).disabled = false;
} catch (error) {
console.error("WorldGuide collection failed to load:", error.message);
$("comparison-content").hidden = true;
$("load-error").hidden = false;
$("comparison").setAttribute("aria-busy", "false");
}
}
$("sample-browser").open = !matchMedia("(max-width: 800px)").matches;
$("sample-search").addEventListener("input", event => { query = event.target.value.trim().toLowerCase(); if (manifest) renderList(); });
$("clear-filters").addEventListener("click", () => { category = "All"; query = ""; $("sample-search").value = ""; renderCategories(); renderList(); $("sample-search").focus(); });
$("previous").addEventListener("click", () => moveSample(-1));
$("next").addEventListener("click", () => moveSample(1));
$("play-all").addEventListener("click", playAll);
$("pause-all").addEventListener("click", pauseAll);
$("restart").addEventListener("click", () => { pauseAll(); videos.forEach(video => { video.currentTime = 0; }); announce("All videos reset to the beginning."); });
$("playback-speed").addEventListener("change", event => { videos.forEach(video => { video.playbackRate = Number(event.target.value); }); });
$("copy-link").addEventListener("click", copyLink);
$("reload").addEventListener("click", () => location.reload());
window.addEventListener("popstate", () => { if (manifest) selectSample(new URLSearchParams(location.search).get("sample"), false); });
window.addEventListener("pagehide", pauseAll);
init();
})();