Upload 5 files
Browse files- README.md +11 -0
- index.html +40 -0
- leaderboard.csv +25 -0
- script.js +261 -0
- style.css +131 -0
README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: WorldScore Leaderboard
|
| 3 |
+
emoji: 📊
|
| 4 |
+
colorFrom: green
|
| 5 |
+
colorTo: indigo
|
| 6 |
+
sdk: static
|
| 7 |
+
app_file: index.html
|
| 8 |
+
pinned: false
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# WorldScore Leaderboard
|
index.html
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<title>WorldScore Leaderboard</title>
|
| 6 |
+
<link rel="stylesheet" href="style.css" />
|
| 7 |
+
</head>
|
| 8 |
+
|
| 9 |
+
<body>
|
| 10 |
+
<main class="page">
|
| 11 |
+
|
| 12 |
+
<!-- Intro Section -->
|
| 13 |
+
<div id="intro" class="intro">
|
| 14 |
+
<h1>WorldScore Leaderboard</h1>
|
| 15 |
+
|
| 16 |
+
<div class="intro-links">
|
| 17 |
+
<a href="https://arxiv.org/abs/2504.00983" target="_blank">Paper</a> |
|
| 18 |
+
<a href="https://haoyi-duan.github.io/WorldScore/" target="_blank">Website</a> |
|
| 19 |
+
<a href="https://github.com/haoyi-duan/WorldScore" target="_blank">Code</a> |
|
| 20 |
+
<a href="https://huggingface.co/datasets/Howieeeee/WorldScore" target="_blank">Dataset</a> |
|
| 21 |
+
<a href="https://github.com/haoyi-duan/WorldScore?tab=readme-ov-file#leaderboard" target="_blank">Join Leaderboard</a>
|
| 22 |
+
</div>
|
| 23 |
+
|
| 24 |
+
<p class="intro-text">
|
| 25 |
+
🏆 Welcome to the leaderboard of <b>WorldScore</b>, the first unified evaluation benchmark for world generation.
|
| 26 |
+
</p>
|
| 27 |
+
|
| 28 |
+
<hr class="divider">
|
| 29 |
+
</div>
|
| 30 |
+
|
| 31 |
+
<!-- Table -->
|
| 32 |
+
<div id="table-container" class="table-container">
|
| 33 |
+
Loading leaderboard...
|
| 34 |
+
</div>
|
| 35 |
+
|
| 36 |
+
</main>
|
| 37 |
+
|
| 38 |
+
<script src="script.js"></script>
|
| 39 |
+
</body>
|
| 40 |
+
</html>
|
leaderboard.csv
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Model Type,Model Name,Ability,Sampled by,Evaluated by,Accessibility,Date,WorldScore-Static,WorldScore-Dynamic,Camera Control,Object Control,Content Alignment,3D Consistency,Photometric Consistency,Style Consistency,Subjective Quality,Motion Accuracy,Motion Magnitude,Motion Smoothness
|
| 2 |
+
Video,[Gen-3](https://runwayml.com/),I2V,WorldScore,WorldScore,API,2025.03.30,60.71,57.58,29.47,62.92,50.49,68.31,87.09,62.82,63.85,54.53,27.48,68.87
|
| 3 |
+
Video,[Hailuo](https://hailuoai.video/),I2V,WorldScore,WorldScore,API,2025.03.30,57.55,56.36,22.39,69.56,73.53,67.18,62.82,54.91,52.44,63.46,27.20,70.07
|
| 4 |
+
Video,[DynamiCrafter](https://doubiiu.github.io/projects/DynamiCrafter/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,52.09,47.19,25.15,47.36,25.00,72.90,60.95,78.85,54.40,41.11,39.25,26.92
|
| 5 |
+
Video,[VideoCrafter1-T2V](https://ailab-cvc.github.io/videocrafter1/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,47.10,43.54,21.61,50.44,60.78,64.86,51.36,38.05,42.63,11.76,75.00,18.87
|
| 6 |
+
Video,[VideoCrafter1-I2V](https://ailab-cvc.github.io/videocrafter1/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,50.47,47.64,25.46,24.25,35.27,74.42,73.89,65.17,54.85,55.63,25.00,42.49
|
| 7 |
+
Video,[VideoCrafter2](https://ailab-cvc.github.io/videocrafter2/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,52.57,47.49,28.92,39.07,72.46,65.14,61.85,43.79,56.74,47.12,30.40,29.39
|
| 8 |
+
Video,[T2V-Turbo](https://t2v-turbo.github.io/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,45.65,40.20,27.80,30.68,69.14,38.72,34.84,49.65,68.74,34.87,40.09,7.48
|
| 9 |
+
Video,[EasyAnimate](https://easyanimate.github.io/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,52.85,51.65,26.72,54.50,50.76,67.29,47.35,73.05,50.31,75.00,31.16,40.32
|
| 10 |
+
Video,[CogVideoX-T2V](https://github.com/THUDM/CogVideo),T2V,WorldScore,WorldScore,Open Source,2025.03.30,54.18,48.79,40.22,51.05,68.12,68.81,64.20,42.19,44.67,25.00,47.31,36.28
|
| 11 |
+
Video,[CogVideoX-I2V](https://github.com/THUDM/CogVideo),I2V,WorldScore,WorldScore,Open Source,2025.03.30,62.15,59.12,38.27,40.07,36.73,86.21,88.12,83.22,62.44,69.56,26.42,60.15
|
| 12 |
+
Video,[Allegro](https://github.com/rhymes-ai/Allegro),I2V,WorldScore,WorldScore,Open Source,2025.03.30,55.31,51.97,24.84,57.47,51.48,70.50,69.89,65.60,47.41,54.39,40.28,37.81
|
| 13 |
+
Video,[Vchitect-2.0](https://vchitect.intern-ai.org.cn/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,42.28,38.47,26.55,49.54,65.75,41.53,42.30,25.69,44.58,33.59,33.81,21.31
|
| 14 |
+
Video,[LTX-Video](https://www.lightricks.com/),I2V,WorldScore,WorldScore,Open Source,2025.07.03,55.44,56.54,25.06,53.41,39.73,78.41,88.92,53.50,49.08,76.22,29.95,71.09
|
| 15 |
+
Video,[Wan2.1](https://wan.video/),I2V,WorldScore,WorldScore,Open Source,2025.10.01,57.56,52.85,23.53,40.32,45.44,78.74,78.36,77.18,59.38,54.27,33.26,38.05
|
| 16 |
+
Video,[TeleWorld](https://github.com/Tele-AI/MMPL/),I2V,TeleWorld,TeleWorld,Open Source,2025.12.09,78.23,66.73,76.58,74.44,73.20,87.35,88.82,85.59,61.66,53.94,31.55,34.18
|
| 17 |
+
3D,[SceneScape](https://scenescape.github.io/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,50.73,35.51,84.99,47.44,28.64,76.54,62.88,21.85,32.75,0.00,0.00,0.00
|
| 18 |
+
3D,[Text2Room](https://lukashoel.github.io/text-to-room/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,62.10,43.47,94.01,38.93,50.79,88.71,88.36,37.23,36.69,0.00,0.00,0.00
|
| 19 |
+
3D,[LucidDreamer](https://luciddreamer-cvlab.github.io/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,70.40,49.28,88.93,41.18,75.00,90.37,90.20,48.10,58.99,0.00,0.00,0.00
|
| 20 |
+
3D,[WonderJourney](https://kovenyu.com/wonderjourney/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,63.75,44.63,84.60,37.10,35.54,80.60,79.03,62.82,66.56,0.00,0.00,0.00
|
| 21 |
+
3D,[InvisibleStitch](https://research.paulengstler.com/invisible-stitch/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,61.12,42.78,93.20,36.51,29.53,88.51,89.19,32.37,58.50,0.00,0.00,0.00
|
| 22 |
+
3D,[WonderWorld](https://kovenyu.com/wonderworld/),I2V,WorldScore,WorldScore,Open Source,2025.03.30,72.69,50.88,92.98,51.76,71.25,86.87,85.56,70.57,49.81,0.00,0.00,0.00
|
| 23 |
+
3D,[Voyager](https://3d-models.hunyuan.tencent.com/world/),I2V,Voyager,Voyager,Open Source,2025.06.25,77.62,54.53,85.95,66.92,68.92,81.56,85.99,84.89,71.09,0.00,0.00,0.00
|
| 24 |
+
3D,[FantasyWorld-0.1](https://fantasy-amap.github.io/fantasy-world/),I2V,FantasyAMAP,FantasyAMAP,Open Source,2025.12.28,78.55,54.99,75.55,87.75,63.37,81.10,93.58,85.43,63.08,0.00,0.00,0.00
|
| 25 |
+
4D,[4D-fy](https://sherwinbahmani.github.io/4dfy/),T2V,WorldScore,WorldScore,Open Source,2025.03.30,27.98,32.10,69.92,55.09,0.85,35.47,1.59,32.04,0.89,22.22,22.88,80.06
|
script.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const COL_ORDER = [
|
| 2 |
+
"Model Name",
|
| 3 |
+
"WorldScore-Static",
|
| 4 |
+
"WorldScore-Dynamic",
|
| 5 |
+
"Camera Control",
|
| 6 |
+
"Object Control",
|
| 7 |
+
"Content Alignment",
|
| 8 |
+
"3D Consistency",
|
| 9 |
+
"Photometric Consistency",
|
| 10 |
+
"Style Consistency",
|
| 11 |
+
"Subjective Quality",
|
| 12 |
+
"Motion Accuracy",
|
| 13 |
+
"Motion Magnitude",
|
| 14 |
+
"Motion Smoothness",
|
| 15 |
+
"Model Type",
|
| 16 |
+
"Ability",
|
| 17 |
+
"Sampled by",
|
| 18 |
+
"Evaluated by",
|
| 19 |
+
"Accessibility",
|
| 20 |
+
"Date",
|
| 21 |
+
];
|
| 22 |
+
|
| 23 |
+
// 简单 CSV 解析(你的数据没有带逗号的字段,这样已经够用)
|
| 24 |
+
function parseCsv(text) {
|
| 25 |
+
const lines = text.trim().split(/\r?\n/);
|
| 26 |
+
const header = lines[0].split(",");
|
| 27 |
+
const rows = lines
|
| 28 |
+
.slice(1)
|
| 29 |
+
.map((line) => {
|
| 30 |
+
if (!line.trim()) return null;
|
| 31 |
+
const parts = line.split(",");
|
| 32 |
+
const obj = {};
|
| 33 |
+
header.forEach((h, i) => {
|
| 34 |
+
obj[h.trim()] = (parts[i] || "").trim();
|
| 35 |
+
});
|
| 36 |
+
return obj;
|
| 37 |
+
})
|
| 38 |
+
.filter(Boolean);
|
| 39 |
+
return { header, rows };
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
function parseMarkdownLink(s) {
|
| 43 |
+
const m = s.match(/^\[(.*?)\]\((.*?)\)$/);
|
| 44 |
+
if (m) {
|
| 45 |
+
return { text: m[1], url: m[2] };
|
| 46 |
+
}
|
| 47 |
+
return { text: s, url: null };
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
function isNumericColumn(colName) {
|
| 51 |
+
const numericCols = new Set([
|
| 52 |
+
"WorldScore-Static",
|
| 53 |
+
"WorldScore-Dynamic",
|
| 54 |
+
"Camera Control",
|
| 55 |
+
"Object Control",
|
| 56 |
+
"Content Alignment",
|
| 57 |
+
"3D Consistency",
|
| 58 |
+
"Photometric Consistency",
|
| 59 |
+
"Style Consistency",
|
| 60 |
+
"Subjective Quality",
|
| 61 |
+
"Motion Accuracy",
|
| 62 |
+
"Motion Magnitude",
|
| 63 |
+
"Motion Smoothness",
|
| 64 |
+
]);
|
| 65 |
+
return numericCols.has(colName);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
function buildTable(rows) {
|
| 69 |
+
const container = document.getElementById("table-container");
|
| 70 |
+
container.innerHTML = "";
|
| 71 |
+
|
| 72 |
+
const table = document.createElement("table");
|
| 73 |
+
table.className = "ws-table";
|
| 74 |
+
|
| 75 |
+
const thead = document.createElement("thead");
|
| 76 |
+
const headRow = document.createElement("tr");
|
| 77 |
+
|
| 78 |
+
const firstRow = rows[0] || {};
|
| 79 |
+
const cols = COL_ORDER.filter((c) => c in firstRow);
|
| 80 |
+
|
| 81 |
+
// 表头:全部 sortable
|
| 82 |
+
cols.forEach((col) => {
|
| 83 |
+
const th = document.createElement("th");
|
| 84 |
+
th.textContent = col;
|
| 85 |
+
th.classList.add("sortable");
|
| 86 |
+
th.dataset.col = col;
|
| 87 |
+
|
| 88 |
+
// 默认排序列:WorldScore-Static,标记为 desc
|
| 89 |
+
if (col === "WorldScore-Static") {
|
| 90 |
+
th.classList.add("desc");
|
| 91 |
+
}
|
| 92 |
+
headRow.appendChild(th);
|
| 93 |
+
});
|
| 94 |
+
|
| 95 |
+
thead.appendChild(headRow);
|
| 96 |
+
table.appendChild(thead);
|
| 97 |
+
|
| 98 |
+
const tbody = document.createElement("tbody");
|
| 99 |
+
table.appendChild(tbody);
|
| 100 |
+
container.appendChild(table);
|
| 101 |
+
|
| 102 |
+
// 计算每个数值列的 最大值 / 第二大值
|
| 103 |
+
function computeTopInfo(data) {
|
| 104 |
+
const info = {};
|
| 105 |
+
cols.forEach((col) => {
|
| 106 |
+
if (!isNumericColumn(col)) return;
|
| 107 |
+
|
| 108 |
+
const vals = [];
|
| 109 |
+
data.forEach((row) => {
|
| 110 |
+
const v = parseFloat(row[col] ?? "");
|
| 111 |
+
if (!isNaN(v)) vals.push(v);
|
| 112 |
+
});
|
| 113 |
+
|
| 114 |
+
if (vals.length === 0) {
|
| 115 |
+
info[col] = { max: null, second: null };
|
| 116 |
+
return;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
vals.sort((a, b) => b - a); // 降序
|
| 120 |
+
|
| 121 |
+
const max = vals[0];
|
| 122 |
+
let second = null;
|
| 123 |
+
for (let i = 1; i < vals.length; i++) {
|
| 124 |
+
if (vals[i] !== max) {
|
| 125 |
+
second = vals[i];
|
| 126 |
+
break;
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
info[col] = { max, second };
|
| 130 |
+
});
|
| 131 |
+
return info;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
// 根据当前 rows 渲染 body(使用 topInfo 做加粗/下划线)
|
| 135 |
+
function renderBody(data, topInfo) {
|
| 136 |
+
tbody.innerHTML = "";
|
| 137 |
+
data.forEach((row) => {
|
| 138 |
+
const tr = document.createElement("tr");
|
| 139 |
+
cols.forEach((col) => {
|
| 140 |
+
const td = document.createElement("td");
|
| 141 |
+
const val = row[col] ?? "";
|
| 142 |
+
|
| 143 |
+
if (col === "Model Name") {
|
| 144 |
+
const { text, url } = parseMarkdownLink(val);
|
| 145 |
+
if (url) {
|
| 146 |
+
const a = document.createElement("a");
|
| 147 |
+
a.href = url;
|
| 148 |
+
a.target = "_blank";
|
| 149 |
+
a.rel = "noopener noreferrer";
|
| 150 |
+
a.textContent = text;
|
| 151 |
+
td.appendChild(a);
|
| 152 |
+
} else {
|
| 153 |
+
td.textContent = text;
|
| 154 |
+
}
|
| 155 |
+
} else {
|
| 156 |
+
td.textContent = val;
|
| 157 |
+
|
| 158 |
+
if (isNumericColumn(col)) {
|
| 159 |
+
const num = parseFloat(val);
|
| 160 |
+
const info = topInfo && topInfo[col];
|
| 161 |
+
|
| 162 |
+
if (!isNaN(num) && info) {
|
| 163 |
+
if (info.max != null && num === info.max) {
|
| 164 |
+
// 最大值:加粗
|
| 165 |
+
td.style.fontWeight = "700";
|
| 166 |
+
} else if (info.second != null && num === info.second) {
|
| 167 |
+
// 第二大值:下划线
|
| 168 |
+
td.style.textDecoration = "underline";
|
| 169 |
+
}
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
tr.appendChild(td);
|
| 175 |
+
});
|
| 176 |
+
tbody.appendChild(tr);
|
| 177 |
+
});
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
// 当前排序状态
|
| 181 |
+
let currentSortCol = "WorldScore-Static";
|
| 182 |
+
let currentAsc = false; // 默认降序
|
| 183 |
+
|
| 184 |
+
// 根据列名和升降序排序,然后渲染
|
| 185 |
+
function sortAndRender(col, asc) {
|
| 186 |
+
const sorted = [...rows].sort((a, b) => {
|
| 187 |
+
const va = a[col] ?? "";
|
| 188 |
+
const vb = b[col] ?? "";
|
| 189 |
+
|
| 190 |
+
if (isNumericColumn(col)) {
|
| 191 |
+
const na = parseFloat(va);
|
| 192 |
+
const nb = parseFloat(vb);
|
| 193 |
+
if (isNaN(na) && isNaN(nb)) return 0;
|
| 194 |
+
if (isNaN(na)) return asc ? -1 : 1;
|
| 195 |
+
if (isNaN(nb)) return asc ? 1 : -1;
|
| 196 |
+
return asc ? na - nb : nb - na;
|
| 197 |
+
} else {
|
| 198 |
+
return asc
|
| 199 |
+
? String(va).localeCompare(String(vb))
|
| 200 |
+
: String(vb).localeCompare(String(va));
|
| 201 |
+
}
|
| 202 |
+
});
|
| 203 |
+
|
| 204 |
+
const topInfo = computeTopInfo(sorted);
|
| 205 |
+
renderBody(sorted, topInfo);
|
| 206 |
+
|
| 207 |
+
// 更新箭头 class
|
| 208 |
+
const headers = Array.from(thead.querySelectorAll("th.sortable"));
|
| 209 |
+
headers.forEach((h) => {
|
| 210 |
+
h.classList.remove("asc", "desc");
|
| 211 |
+
});
|
| 212 |
+
const target = headers.find((h) => h.dataset.col === col);
|
| 213 |
+
if (target) {
|
| 214 |
+
target.classList.add(asc ? "asc" : "desc");
|
| 215 |
+
}
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
// 初始渲染:WorldScore-Static 降序
|
| 219 |
+
sortAndRender(currentSortCol, currentAsc);
|
| 220 |
+
|
| 221 |
+
// 给所有表头绑定 click 排序
|
| 222 |
+
const headers = Array.from(thead.querySelectorAll("th.sortable"));
|
| 223 |
+
headers.forEach((th) => {
|
| 224 |
+
th.addEventListener("click", () => {
|
| 225 |
+
const col = th.dataset.col;
|
| 226 |
+
if (col === currentSortCol) {
|
| 227 |
+
currentAsc = !currentAsc; // 同一列就翻转方向
|
| 228 |
+
} else {
|
| 229 |
+
currentSortCol = col;
|
| 230 |
+
currentAsc = true; // 新列默认升序
|
| 231 |
+
}
|
| 232 |
+
sortAndRender(currentSortCol, currentAsc);
|
| 233 |
+
});
|
| 234 |
+
});
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
// 入口:加载 CSV,默认在 JS 里先按 WorldScore-Static 降序排一次,然后 buildTable
|
| 238 |
+
fetch("leaderboard.csv")
|
| 239 |
+
.then((res) => {
|
| 240 |
+
if (!res.ok) {
|
| 241 |
+
throw new Error("HTTP " + res.status);
|
| 242 |
+
}
|
| 243 |
+
return res.text();
|
| 244 |
+
})
|
| 245 |
+
.then((text) => {
|
| 246 |
+
const parsed = parseCsv(text);
|
| 247 |
+
if (!parsed.rows || parsed.rows.length === 0) {
|
| 248 |
+
document.getElementById("table-container").innerHTML =
|
| 249 |
+
"<p>No data rows in leaderboard.csv</p>";
|
| 250 |
+
return;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
// 这里的 rows 保留原始字符串形式(包括 [Name](url))
|
| 254 |
+
const rows = parsed.rows.slice();
|
| 255 |
+
buildTable(rows);
|
| 256 |
+
})
|
| 257 |
+
.catch((err) => {
|
| 258 |
+
console.error("Failed to load CSV:", err);
|
| 259 |
+
document.getElementById("table-container").innerHTML =
|
| 260 |
+
"<p style='color:#f97316'>Failed to load leaderboard.csv: " + String(err) + "</p>";
|
| 261 |
+
});
|
style.css
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Intro Section */
|
| 2 |
+
.intro h1 {
|
| 3 |
+
font-size: 2rem;
|
| 4 |
+
font-weight: 800;
|
| 5 |
+
margin-bottom: 8px;
|
| 6 |
+
color: #ffffff;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
.intro-links {
|
| 10 |
+
margin-bottom: 12px;
|
| 11 |
+
font-size: 1rem;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
.intro-links a {
|
| 15 |
+
color: #60a5fa;
|
| 16 |
+
text-decoration: none;
|
| 17 |
+
font-weight: 600;
|
| 18 |
+
}
|
| 19 |
+
.intro-links a:hover {
|
| 20 |
+
text-decoration: underline;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
.intro-text {
|
| 24 |
+
color: #d1d5db;
|
| 25 |
+
font-size: 1rem;
|
| 26 |
+
margin-top: 6px;
|
| 27 |
+
line-height: 1.5rem;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
.divider {
|
| 31 |
+
margin: 20px 0;
|
| 32 |
+
border: none;
|
| 33 |
+
height: 1px;
|
| 34 |
+
background-color: #374151;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
body {
|
| 39 |
+
margin: 0;
|
| 40 |
+
padding: 0;
|
| 41 |
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
| 42 |
+
background-color: #0b1120;
|
| 43 |
+
color: #e5e7eb;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
.page {
|
| 47 |
+
padding: 24px 32px 40px 32px;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.title {
|
| 51 |
+
font-size: 2rem;
|
| 52 |
+
font-weight: 800;
|
| 53 |
+
margin: 0 0 4px 0;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
.subtitle {
|
| 57 |
+
margin: 0 0 16px 0;
|
| 58 |
+
color: #9ca3af;
|
| 59 |
+
font-size: 0.95rem;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
.table-container {
|
| 63 |
+
margin-top: 12px;
|
| 64 |
+
overflow-x: auto;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
/* 基础表格样式,简单一点 */
|
| 68 |
+
.ws-table {
|
| 69 |
+
border-collapse: collapse;
|
| 70 |
+
width: 100%;
|
| 71 |
+
min-width: 1200px;
|
| 72 |
+
background-color: #ffffff;
|
| 73 |
+
color: #111827;
|
| 74 |
+
font-size: 0.9rem;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.ws-table th,
|
| 78 |
+
.ws-table td {
|
| 79 |
+
border: 1px solid #d1d5db;
|
| 80 |
+
padding: 6px 8px;
|
| 81 |
+
text-align: center;
|
| 82 |
+
white-space: nowrap;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
.ws-table th {
|
| 86 |
+
background-color: #e5e7eb;
|
| 87 |
+
font-weight: 600;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
/* Model Name 列:保持一行 & 悬浮在左侧(sticky) */
|
| 91 |
+
.ws-table th:first-child,
|
| 92 |
+
.ws-table td:first-child {
|
| 93 |
+
position: sticky; /* 悬浮 */
|
| 94 |
+
left: 0; /* 固定在最左边 */
|
| 95 |
+
z-index: 3; /* 保证不被其他列遮挡 */
|
| 96 |
+
background-color: #ffffff; /* 表格背景色,一定要设,否则会透明 */
|
| 97 |
+
white-space: nowrap; /* 不换行 */
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
/* Model Name 列:宽度根据内容自动展开,不换行 */
|
| 102 |
+
.ws-table th:first-child,
|
| 103 |
+
.ws-table td:first-child {
|
| 104 |
+
white-space: nowrap; /* 不换行 */
|
| 105 |
+
width: max-content; /* 自动根据内容宽度展开 */
|
| 106 |
+
max-width: none; /* 禁止压缩 */
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
/* model name 链接样式 */
|
| 111 |
+
.ws-table td:first-child a {
|
| 112 |
+
color: #1d4ed8;
|
| 113 |
+
text-decoration: none;
|
| 114 |
+
font-weight: 600;
|
| 115 |
+
}
|
| 116 |
+
.ws-table td:first-child a:hover {
|
| 117 |
+
text-decoration: underline;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.ws-table th:nth-child(2),
|
| 121 |
+
.ws-table th:nth-child(3) {
|
| 122 |
+
background-color: #ffe5e5; /* 浅红背景 */
|
| 123 |
+
color: #b91c1c; /* 深红文字 */
|
| 124 |
+
font-weight: 700;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
/* 表头可点击(之后加排序) */
|
| 129 |
+
.ws-table th.sortable {
|
| 130 |
+
cursor: pointer;
|
| 131 |
+
}
|