feat(leaderboard): refresh tables and provider logos

#2
by Gh0stAR - opened
CONTRIBUTING.md CHANGED
@@ -4,19 +4,21 @@ Submit results as a pull request to this Space repository. A maintainer reviews
4
 
5
  ## Add a result
6
 
7
- 1. Copy `templates/result-entry.json` into `data/results.json` as a new object in the `entries` array.
8
  2. Replace every example value, including the `null` score and sample-count placeholders. Use a unique, stable `id`; keep separate records for different model versions or evaluation runs.
9
  3. Set `source.type` to `paper`, `participant`, or `maintainer`, and link the paper or result report in `source.url`. Use `paper-2606.07643` for results from the paper's benchmark setting; future benchmark releases should use their published release identifier.
10
- 4. Use scores on a 0–100 scale. Set `coverage.status` to `full` only when all tasks in that benchmark release were evaluated. If sample counts are known, report both counts; a full result must cover all reported samples. Partial results and records without an overall score are displayed without a rank.
11
- 5. Open a pull request in this Space repository. Keep the change limited to `data/results.json`; do not include examples, media, ground-truth labels, raw model responses, API keys, or other credentials.
12
 
13
  ## Required information
14
 
15
  - Display name, provider, exact model identifier, and benchmark release.
16
  - Source type and a public source link.
17
  - Task coverage and any available evaluation date.
18
- - Overall score for a row to be ranked. Stage, taxonomy, and task scores may still be submitted without an overall score when the source does not report one; that row remains visible without a rank.
19
 
20
  The initial paper entries use the model labels as written in the paper. Their dated API snapshots and sample coverage were not reported in the headline table, so these fields remain unspecified rather than inferred.
21
 
 
 
22
  The maintainer runs `python validate_results.py` before merging. A source link and complete metadata help reviewers assess credibility; the maintainer may ask for clarification or decline a record that cannot be checked.
 
4
 
5
  ## Add a result
6
 
7
+ 1. Copy `templates/result-entry.json` into `data/results.json` as a new object in the `entries` array. The active leaderboard reads this file; archived records in `data/archive/` are not loaded into the tables.
8
  2. Replace every example value, including the `null` score and sample-count placeholders. Use a unique, stable `id`; keep separate records for different model versions or evaluation runs.
9
  3. Set `source.type` to `paper`, `participant`, or `maintainer`, and link the paper or result report in `source.url`. Use `paper-2606.07643` for results from the paper's benchmark setting; future benchmark releases should use their published release identifier.
10
+ 4. Use scores on a 0–100 scale. Set `coverage.status` to `full` only when all tasks in that benchmark release were evaluated. If sample counts are known, report both counts; a full result must cover all reported samples. Each table defaults to Overall order; selecting any column header sorts that table independently, and missing values sort last.
11
+ 5. Open a pull request in this Space repository. Keep the result change limited to `data/results.json`; do not include examples, media, ground-truth labels, raw model responses, API keys, logo URLs, or other credentials.
12
 
13
  ## Required information
14
 
15
  - Display name, provider, exact model identifier, and benchmark release.
16
  - Source type and a public source link.
17
  - Task coverage and any available evaluation date.
18
+ - Overall score and any reported stage, taxonomy, or task scores. Missing values are allowed when the source does not report them.
19
 
20
  The initial paper entries use the model labels as written in the paper. Their dated API snapshots and sample coverage were not reported in the headline table, so these fields remain unspecified rather than inferred.
21
 
22
+ Provider logos are curated by maintainers as local assets under `assets/logos/`. A provider without a mapped logo is shown by name and does not need to submit an image.
23
+
24
  The maintainer runs `python validate_results.py` before merging. A source link and complete metadata help reviewers assess credibility; the maintainer may ask for clarification or decline a record that cannot be checked.
DEPLOYMENT.md CHANGED
@@ -4,10 +4,10 @@ This directory contains the leaderboard files for the existing `FudanCVL/AVI-Ben
4
 
5
  ## First publication
6
 
7
- 1. Upload the files in this directory to the root of `https://huggingface.co/spaces/FudanCVL/AVI-Bench`, keeping `data/` and `templates/` as directories. This replaces the current starter `README.md` and `index.html`; existing `style.css` and `.gitattributes` are left alone.
8
  2. Keep the Space **Public** and its SDK set to **Static**.
9
  3. In the Space repository settings, make sure community pull requests and discussions are enabled.
10
- 4. Confirm that the Space displays the seven paper-reported model entries and that the submission guide is visible.
11
 
12
  Hugging Face Static Spaces serve HTML directly without compute. Their repository PRs work across repository types, including Spaces. See the [Static HTML Spaces guide](https://huggingface.co/docs/hub/spaces-sdks-static) and [Pull requests and Discussions guide](https://huggingface.co/docs/hub/repositories-pull-requests-discussions).
13
 
@@ -21,4 +21,6 @@ python3 validate_results.py
21
 
22
  Merge only after the source and record can be checked. A merged result retains its source label and is not described as an independent reproduction unless one was performed.
23
 
 
 
24
  Do not accept benchmark examples, media, labels, raw model responses, or credentials in a result PR.
 
4
 
5
  ## First publication
6
 
7
+ 1. Upload the files in this directory to the root of `https://huggingface.co/spaces/FudanCVL/AVI-Bench`, keeping `assets/`, `data/`, and `templates/` as directories. This replaces the current starter `README.md` and `index.html`; existing `style.css` and `.gitattributes` are left alone.
8
  2. Keep the Space **Public** and its SDK set to **Static**.
9
  3. In the Space repository settings, make sure community pull requests and discussions are enabled.
10
+ 4. Confirm that the Space displays the three active paper-reported models, both score tables, and the provider logos. The four archived entries must not be loaded into the tables.
11
 
12
  Hugging Face Static Spaces serve HTML directly without compute. Their repository PRs work across repository types, including Spaces. See the [Static HTML Spaces guide](https://huggingface.co/docs/hub/spaces-sdks-static) and [Pull requests and Discussions guide](https://huggingface.co/docs/hub/repositories-pull-requests-discussions).
13
 
 
21
 
22
  Merge only after the source and record can be checked. A merged result retains its source label and is not described as an independent reproduction unless one was performed.
23
 
24
+ The initial paper records outside the active three are stored in `data/archive/paper-results.json`. Validate that file separately if it changes; do not merge archived records into the active table unless the leaderboard scope is intentionally updated.
25
+
26
  Do not accept benchmark examples, media, labels, raw model responses, or credentials in a result PR.
README.md CHANGED
@@ -11,6 +11,8 @@ license: apache-2.0
11
 
12
  # AVI-Bench Leaderboard
13
 
14
- Community-submitted results for AVI-Bench, seeded with seven model entries from the paper's headline tables. Results are shown after a maintainer reviews and merges the pull request. The source type identifies whether a score is reported by a paper, a participant, or the maintainers; acceptance does not mean the result was independently reproduced.
 
 
15
 
16
  See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the score format and pull request instructions, and [`DEPLOYMENT.md`](DEPLOYMENT.md) for Space setup and maintenance.
 
11
 
12
  # AVI-Bench Leaderboard
13
 
14
+ The AVI-Bench community leaderboard compares model performance across cognitive stages and the four-level adaptive taxonomy. The public tables are seeded with three paper-reported models: Gemini-2.5-Pro, Qwen2.5-Omni, and GPT-4o. Four additional paper records are preserved in `data/archive/paper-results.json` and are not loaded into the active leaderboard.
15
+
16
+ Submit new results as pull requests to `data/results.json`. A maintainer reviews the source and required metadata before merging. Each row identifies where its score was reported; acceptance does not mean the result was independently reproduced. Provider marks are stored locally and mapped by maintainers; submissions should not add logo URLs or image files.
17
 
18
  See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the score format and pull request instructions, and [`DEPLOYMENT.md`](DEPLOYMENT.md) for Space setup and maintenance.
assets/logos/README.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Provider logo assets
2
+
3
+ These SVG icons were copied from the Simple Icons 15.15.0 release:
4
+
5
+ - Google: https://github.com/simple-icons/simple-icons/blob/15.15.0/icons/google.svg
6
+ - Alibaba Cloud: https://github.com/simple-icons/simple-icons/blob/15.15.0/icons/alibabacloud.svg
7
+ - OpenAI: https://github.com/simple-icons/simple-icons/blob/15.15.0/icons/openai.svg
8
+
9
+ Simple Icons distributes its icon artwork under CC0 1.0. This does not grant trademark rights. AVI-Bench uses these marks only to identify the providers of the listed models, at equal visual weight and without implying endorsement or affiliation. See each provider's current brand guidelines for its trademark terms.
assets/logos/alibabacloud.svg ADDED
assets/logos/google.svg ADDED
assets/logos/openai.svg ADDED
data/archive/paper-results.json ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": 1,
3
+ "entries": [
4
+ {
5
+ "id": "gemini-2-5-flash-paper-2606-07643",
6
+ "model_name": "Gemini-2.5-Flash",
7
+ "provider": "Google",
8
+ "model_id": "Gemini-2.5-Flash (paper label)",
9
+ "benchmark_version": "paper-2606.07643",
10
+ "source": {
11
+ "type": "paper",
12
+ "url": "https://arxiv.org/abs/2606.07643"
13
+ },
14
+ "evaluation_date": null,
15
+ "coverage": {
16
+ "status": "full",
17
+ "tasks_completed": 14,
18
+ "tasks_total": 14,
19
+ "samples_completed": null,
20
+ "samples_total": null
21
+ },
22
+ "scores": {
23
+ "overall": 46.02,
24
+ "stages": {
25
+ "perception": 45.97,
26
+ "understanding": 43.79,
27
+ "reasoning": 63.7,
28
+ "sensation": 30.63
29
+ },
30
+ "taxonomy": {
31
+ "l1_task": 51.15,
32
+ "l2_modality": 48.58,
33
+ "l3_stage": 40.47,
34
+ "l4_domain": 27.72
35
+ },
36
+ "tasks": {}
37
+ },
38
+ "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
39
+ },
40
+ {
41
+ "id": "gemini-2-flash-paper-2606-07643",
42
+ "model_name": "Gemini-2.0-Flash",
43
+ "provider": "Google",
44
+ "model_id": "Gemini-2.0-Flash (paper label)",
45
+ "benchmark_version": "paper-2606.07643",
46
+ "source": {
47
+ "type": "paper",
48
+ "url": "https://arxiv.org/abs/2606.07643"
49
+ },
50
+ "evaluation_date": null,
51
+ "coverage": {
52
+ "status": "full",
53
+ "tasks_completed": 14,
54
+ "tasks_total": 14,
55
+ "samples_completed": null,
56
+ "samples_total": null
57
+ },
58
+ "scores": {
59
+ "overall": 44.97,
60
+ "stages": {
61
+ "perception": 44.27,
62
+ "understanding": 42.11,
63
+ "reasoning": 64.03,
64
+ "sensation": 29.48
65
+ },
66
+ "taxonomy": {
67
+ "l1_task": 50.14,
68
+ "l2_modality": 49.21,
69
+ "l3_stage": 39.79,
70
+ "l4_domain": 27.12
71
+ },
72
+ "tasks": {}
73
+ },
74
+ "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
75
+ },
76
+ {
77
+ "id": "qwen-omni-turbo-paper-2606-07643",
78
+ "model_name": "Qwen-Omni-Turbo",
79
+ "provider": "Alibaba Cloud",
80
+ "model_id": "Qwen-Omni-Turbo (paper label)",
81
+ "benchmark_version": "paper-2606.07643",
82
+ "source": {
83
+ "type": "paper",
84
+ "url": "https://arxiv.org/abs/2606.07643"
85
+ },
86
+ "evaluation_date": null,
87
+ "coverage": {
88
+ "status": "full",
89
+ "tasks_completed": 14,
90
+ "tasks_total": 14,
91
+ "samples_completed": null,
92
+ "samples_total": null
93
+ },
94
+ "scores": {
95
+ "overall": null,
96
+ "stages": {},
97
+ "taxonomy": {
98
+ "l1_task": 46.5,
99
+ "l2_modality": 45.15,
100
+ "l3_stage": 37.7,
101
+ "l4_domain": 26.13
102
+ },
103
+ "tasks": {}
104
+ },
105
+ "notes": "Paper reports taxonomy scores only. The paper table does not specify a dated API snapshot or sample coverage."
106
+ },
107
+ {
108
+ "id": "baichuan-omni-paper-2606-07643",
109
+ "model_name": "Baichuan-Omni",
110
+ "provider": "Baichuan",
111
+ "model_id": "Baichuan-Omni (paper label)",
112
+ "benchmark_version": "paper-2606.07643",
113
+ "source": {
114
+ "type": "paper",
115
+ "url": "https://arxiv.org/abs/2606.07643"
116
+ },
117
+ "evaluation_date": null,
118
+ "coverage": {
119
+ "status": "full",
120
+ "tasks_completed": 14,
121
+ "tasks_total": 14,
122
+ "samples_completed": null,
123
+ "samples_total": null
124
+ },
125
+ "scores": {
126
+ "overall": null,
127
+ "stages": {},
128
+ "taxonomy": {
129
+ "l1_task": 37.35,
130
+ "l2_modality": 35.8,
131
+ "l3_stage": 30.18,
132
+ "l4_domain": 24.1
133
+ },
134
+ "tasks": {}
135
+ },
136
+ "notes": "Paper reports taxonomy scores only. The paper table does not specify a dated API snapshot or sample coverage."
137
+ }
138
+ ]
139
+ }
data/results.json CHANGED
@@ -37,78 +37,6 @@
37
  },
38
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
39
  },
40
- {
41
- "id": "gemini-2-5-flash-paper-2606-07643",
42
- "model_name": "Gemini-2.5-Flash",
43
- "provider": "Google",
44
- "model_id": "Gemini-2.5-Flash (paper label)",
45
- "benchmark_version": "paper-2606.07643",
46
- "source": {
47
- "type": "paper",
48
- "url": "https://arxiv.org/abs/2606.07643"
49
- },
50
- "evaluation_date": null,
51
- "coverage": {
52
- "status": "full",
53
- "tasks_completed": 14,
54
- "tasks_total": 14,
55
- "samples_completed": null,
56
- "samples_total": null
57
- },
58
- "scores": {
59
- "overall": 46.02,
60
- "stages": {
61
- "perception": 45.97,
62
- "understanding": 43.79,
63
- "reasoning": 63.7,
64
- "sensation": 30.63
65
- },
66
- "taxonomy": {
67
- "l1_task": 51.15,
68
- "l2_modality": 48.58,
69
- "l3_stage": 40.47,
70
- "l4_domain": 27.72
71
- },
72
- "tasks": {}
73
- },
74
- "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
75
- },
76
- {
77
- "id": "gemini-2-flash-paper-2606-07643",
78
- "model_name": "Gemini-2.0-Flash",
79
- "provider": "Google",
80
- "model_id": "Gemini-2.0-Flash (paper label)",
81
- "benchmark_version": "paper-2606.07643",
82
- "source": {
83
- "type": "paper",
84
- "url": "https://arxiv.org/abs/2606.07643"
85
- },
86
- "evaluation_date": null,
87
- "coverage": {
88
- "status": "full",
89
- "tasks_completed": 14,
90
- "tasks_total": 14,
91
- "samples_completed": null,
92
- "samples_total": null
93
- },
94
- "scores": {
95
- "overall": 44.97,
96
- "stages": {
97
- "perception": 44.27,
98
- "understanding": 42.11,
99
- "reasoning": 64.03,
100
- "sensation": 29.48
101
- },
102
- "taxonomy": {
103
- "l1_task": 50.14,
104
- "l2_modality": 49.21,
105
- "l3_stage": 39.79,
106
- "l4_domain": 27.12
107
- },
108
- "tasks": {}
109
- },
110
- "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
111
- },
112
  {
113
  "id": "qwen2-5-omni-paper-2606-07643",
114
  "model_name": "Qwen2.5-Omni",
@@ -145,37 +73,6 @@
145
  },
146
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
147
  },
148
- {
149
- "id": "qwen-omni-turbo-paper-2606-07643",
150
- "model_name": "Qwen-Omni-Turbo",
151
- "provider": "Alibaba Cloud",
152
- "model_id": "Qwen-Omni-Turbo (paper label)",
153
- "benchmark_version": "paper-2606.07643",
154
- "source": {
155
- "type": "paper",
156
- "url": "https://arxiv.org/abs/2606.07643"
157
- },
158
- "evaluation_date": null,
159
- "coverage": {
160
- "status": "full",
161
- "tasks_completed": 14,
162
- "tasks_total": 14,
163
- "samples_completed": null,
164
- "samples_total": null
165
- },
166
- "scores": {
167
- "overall": null,
168
- "stages": {},
169
- "taxonomy": {
170
- "l1_task": 46.5,
171
- "l2_modality": 45.15,
172
- "l3_stage": 37.7,
173
- "l4_domain": 26.13
174
- },
175
- "tasks": {}
176
- },
177
- "notes": "Paper reports taxonomy scores only. The paper table does not specify a dated API snapshot or sample coverage."
178
- },
179
  {
180
  "id": "gpt-4o-paper-2606-07643",
181
  "model_name": "GPT-4o",
@@ -211,37 +108,6 @@
211
  "tasks": {}
212
  },
213
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
214
- },
215
- {
216
- "id": "baichuan-omni-paper-2606-07643",
217
- "model_name": "Baichuan-Omni",
218
- "provider": "Baichuan",
219
- "model_id": "Baichuan-Omni (paper label)",
220
- "benchmark_version": "paper-2606.07643",
221
- "source": {
222
- "type": "paper",
223
- "url": "https://arxiv.org/abs/2606.07643"
224
- },
225
- "evaluation_date": null,
226
- "coverage": {
227
- "status": "full",
228
- "tasks_completed": 14,
229
- "tasks_total": 14,
230
- "samples_completed": null,
231
- "samples_total": null
232
- },
233
- "scores": {
234
- "overall": null,
235
- "stages": {},
236
- "taxonomy": {
237
- "l1_task": 37.35,
238
- "l2_modality": 35.8,
239
- "l3_stage": 30.18,
240
- "l4_domain": 24.1
241
- },
242
- "tasks": {}
243
- },
244
- "notes": "Paper reports taxonomy scores only. The paper table does not specify a dated API snapshot or sample coverage."
245
  }
246
  ]
247
  }
 
37
  },
38
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
39
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  {
41
  "id": "qwen2-5-omni-paper-2606-07643",
42
  "model_name": "Qwen2.5-Omni",
 
73
  },
74
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
75
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  {
77
  "id": "gpt-4o-paper-2606-07643",
78
  "model_name": "GPT-4o",
 
108
  "tasks": {}
109
  },
110
  "notes": "Paper-reported scores. The paper table does not specify a dated API snapshot or sample coverage."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
  ]
113
  }
index.html CHANGED
@@ -3,239 +3,322 @@
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="description" content="Community leaderboard for AVI-Bench audio-visual intelligence evaluations.">
7
- <meta name="theme-color" content="#f6f1e8">
8
  <title>AVI-Bench Leaderboard</title>
9
  <style>
10
  :root {
11
  color-scheme: light;
12
- --paper: #f6f1e8;
13
- --paper-deep: #ece5d6;
14
- --ink: #1a1a1a;
15
- --muted: #6c675f;
16
- --rule: #d1c7b4;
17
- --accent: #8a2422;
18
- --accent-soft: #f3e4de;
19
- --green: #38604d;
20
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
21
- --serif: Georgia, "Times New Roman", serif;
22
  }
23
 
24
  * { box-sizing: border-box; }
25
  body {
26
  margin: 0;
27
- background: var(--paper);
28
  color: var(--ink);
29
  font-family: var(--sans);
30
- font-size: 15px;
31
- line-height: 1.55;
32
  }
33
- a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
34
- a:hover { color: #5f1716; }
35
- button, input, select { font: inherit; }
36
- .page { width: min(1440px, 100% - 40px); margin: 0 auto; }
37
- header { border-bottom: 1px solid var(--rule); }
38
- .masthead {
39
- min-height: 58px;
40
  display: flex;
41
  align-items: center;
42
  justify-content: space-between;
43
- gap: 16px;
44
- color: var(--muted);
45
- font-size: 12px;
46
- letter-spacing: .12em;
47
- text-transform: uppercase;
48
  }
49
- .brand { color: var(--ink); font-family: var(--serif); font-size: 19px; font-weight: 700; letter-spacing: 0; text-transform: none; }
50
- .brand span { color: var(--accent); }
51
- .hero { padding: 54px 0 40px; }
52
- .eyebrow { margin: 0 0 10px; color: var(--accent); font-size: 11px; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; }
53
- h1, h2, h3 { font-family: var(--serif); font-weight: 500; }
54
- h1 { margin: 0; font-size: clamp(36px, 6vw, 64px); letter-spacing: -.04em; line-height: 1.02; }
55
- .intro { max-width: 760px; margin: 16px 0 0; color: #4c4944; font-family: var(--serif); font-size: 19px; }
56
- .links { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 20px; font-size: 13px; }
57
- .callout {
58
  display: grid;
59
- grid-template-columns: minmax(0, 1fr) auto;
60
- align-items: center;
61
- gap: 18px;
62
- margin: 0 0 30px;
63
- padding: 18px 20px;
64
- border: 1px solid var(--rule);
65
- background: rgba(255, 255, 255, .35);
66
  }
67
- .callout p { margin: 0; color: #45413b; }
68
- .button-link {
69
- display: inline-block;
70
- border: 1px solid var(--ink);
71
- padding: 9px 13px;
 
 
 
 
 
 
 
 
72
  color: var(--ink);
73
  font-size: 12px;
74
- font-weight: 700;
75
  text-decoration: none;
76
- white-space: nowrap;
77
  }
78
- .button-link:hover { background: var(--ink); color: var(--paper); }
79
- .section-heading { display: flex; align-items: end; justify-content: space-between; gap: 20px; margin: 0 0 16px; }
80
- .section-heading h2 { margin: 0; font-size: 30px; letter-spacing: -.02em; }
81
- #summary { color: var(--muted); font-size: 12px; text-align: right; }
82
- .filters {
83
- display: grid;
84
- grid-template-columns: minmax(200px, 1.5fr) repeat(3, minmax(145px, .7fr));
85
- gap: 10px;
86
- margin-bottom: 13px;
87
  }
88
- .filters input, .filters select {
89
- width: 100%;
90
- min-height: 42px;
91
- border: 1px solid var(--rule);
92
- border-radius: 0;
93
- background: #fffdf9;
94
- color: var(--ink);
95
- padding: 9px 11px;
 
 
96
  }
97
- .filters input:focus, .filters select:focus, button:focus-visible, a:focus-visible {
98
- outline: 3px solid #c5806d;
99
- outline-offset: 2px;
 
 
 
 
 
 
 
 
 
100
  }
101
- .table-shell { overflow-x: auto; border: 1px solid var(--rule); background: #fffdf9; }
102
- table { width: 100%; min-width: 1120px; border-collapse: collapse; font-size: 12px; }
103
- th, td { padding: 11px 12px; border-bottom: 1px solid #e9e2d5; text-align: right; white-space: nowrap; }
104
- th { background: var(--paper-deep); color: #47423c; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; }
105
- th:first-child, td:first-child, th:nth-child(2), td:nth-child(2), th:nth-child(3), td:nth-child(3) { text-align: left; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  tbody tr:last-child td { border-bottom: 0; }
107
- tbody tr:hover td { background: #faf5eb; }
108
- .sort-button { padding: 0; border: 0; background: none; color: inherit; font-size: inherit; font-weight: 700; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
109
- .model-cell { min-width: 170px; }
110
- .model-name { display: block; color: var(--ink); font-weight: 700; }
111
- .model-id { display: block; max-width: 240px; overflow: hidden; color: var(--muted); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 10px; text-overflow: ellipsis; }
112
- .source-tag, .coverage-tag { display: inline-block; border: 1px solid var(--rule); padding: 2px 6px; background: #fff; color: #514b43; font-size: 10px; }
113
- .source-paper { border-color: #d6b6a7; background: var(--accent-soft); color: #71312a; }
114
- .coverage-full { border-color: #b6cbbd; background: #edf4ef; color: var(--green); }
115
- .score { font-variant-numeric: tabular-nums; }
116
- .score-overall { color: var(--accent); font-weight: 800; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  .details-row td { padding: 0; text-align: left; white-space: normal; }
118
- details { padding: 10px 12px; }
119
- summary { color: var(--accent); cursor: pointer; font-size: 11px; font-weight: 700; }
120
- .detail-content { display: grid; grid-template-columns: repeat(3, minmax(150px, 1fr)); gap: 12px; padding: 13px 0 4px; }
121
- .detail-block h3 { margin: 0 0 5px; font-family: var(--sans); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; }
122
- .detail-block p { margin: 3px 0; color: #514b43; font-size: 11px; overflow-wrap: anywhere; }
123
- .empty, .error { padding: 28px 16px; color: var(--muted); text-align: center; }
124
- .error { color: #8a2422; }
125
- .footnote { margin: 12px 0 40px; color: var(--muted); font-size: 11px; }
126
- .contribute { margin: 42px 0 54px; padding: 26px; border-top: 2px solid var(--accent); background: var(--paper-deep); }
127
- .contribute h2 { margin: 0 0 7px; font-size: 26px; }
128
- .contribute p { max-width: 760px; margin: 0 0 15px; color: #4c4944; }
129
- footer { border-top: 1px solid var(--rule); padding: 20px 0 28px; color: var(--muted); font-size: 11px; }
130
- .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
131
-
132
- @media (max-width: 760px) {
133
- .page { width: min(100% - 24px, 1440px); }
134
- .hero { padding: 38px 0 28px; }
135
- .callout { grid-template-columns: 1fr; }
136
- .button-link { justify-self: start; }
137
- .filters { grid-template-columns: 1fr 1fr; }
138
- .filters input { grid-column: 1 / -1; }
 
 
 
 
 
 
 
 
 
 
 
 
139
  .section-heading { align-items: start; flex-direction: column; gap: 4px; }
140
- #summary { text-align: left; }
141
- .detail-content { grid-template-columns: 1fr 1fr; }
 
 
142
  }
143
- @media (max-width: 440px) {
144
- .masthead { font-size: 10px; }
145
- .intro { font-size: 17px; }
146
- .filters { grid-template-columns: 1fr; }
147
- .filters input { grid-column: auto; }
148
- .detail-content { grid-template-columns: 1fr; }
149
- .contribute { padding: 20px 16px; }
150
  }
151
  </style>
152
  </head>
153
  <body>
154
- <header>
155
- <div class="page masthead">
156
- <div class="brand">AVI<span>·</span>Bench</div>
157
- <div>Audio-Visual Intelligence &nbsp;·&nbsp; Community Leaderboard</div>
 
 
 
 
 
 
 
 
 
158
  </div>
159
  </header>
160
 
161
- <main class="page">
162
- <section class="hero" aria-labelledby="page-title">
163
- <p class="eyebrow">Community results</p>
164
- <h1 id="page-title">AVI-Bench Leaderboard</h1>
165
- <p class="intro">Compare audio-visual intelligence results across perception, understanding, reasoning, and primitive sensation. Every entry links to its reported source.</p>
166
- <nav class="links" aria-label="Project links">
167
- <a href="https://fudancvl.github.io/AVI-Bench/">Project page</a>
168
- <a href="https://github.com/FudanCVL/AVI-Bench">Code</a>
169
- <a href="https://huggingface.co/datasets/FudanCVL/AVIBench">Dataset</a>
170
- <a href="https://arxiv.org/abs/2606.07643">Paper</a>
171
- </nav>
172
  </section>
173
 
174
- <aside class="callout">
175
- <p><strong>Contribute a result.</strong> Submit a pull request with the required model, benchmark, coverage, score, and source information. A maintainer reviews it before merge. A merged entry identifies its source; it does not imply an independent reproduction.</p>
176
- <a class="button-link" href="https://huggingface.co/spaces/FudanCVL/AVI-Bench/tree/main">Submission guide</a>
177
- </aside>
178
-
179
- <section aria-labelledby="results-title">
180
  <div class="section-heading">
181
  <div>
182
- <p class="eyebrow">Results</p>
183
- <h2 id="results-title">Model comparison</h2>
 
184
  </div>
185
- <div id="summary" aria-live="polite">Loading results…</div>
186
  </div>
187
-
188
- <div class="filters" aria-label="Leaderboard filters">
189
- <label class="sr-only" for="search">Search models</label>
190
- <input id="search" type="search" placeholder="Search model, provider, or ID">
191
- <label class="sr-only" for="benchmark-filter">Filter benchmark version</label>
192
- <select id="benchmark-filter"><option value="all">All benchmark versions</option></select>
193
- <label class="sr-only" for="provider-filter">Filter provider</label>
194
- <select id="provider-filter"><option value="all">All providers</option></select>
195
- <label class="sr-only" for="source-filter">Filter source</label>
196
- <select id="source-filter"><option value="all">All sources</option></select>
197
  </div>
 
198
 
199
- <div class="table-shell">
200
- <table aria-describedby="leaderboard-note">
201
- <thead>
202
- <tr>
203
- <th><button class="sort-button" data-sort="rank" aria-label="Sort by rank">Rank</button></th>
204
- <th><button class="sort-button" data-sort="model_name">Model</button></th>
205
- <th><button class="sort-button" data-sort="source">Source</button></th>
206
- <th><button class="sort-button" data-sort="benchmark_version">Benchmark</button></th>
207
- <th><button class="sort-button" data-sort="coverage">Coverage</button></th>
208
- <th><button class="sort-button" data-sort="overall" aria-sort="descending">Overall</button></th>
209
- <th><button class="sort-button" data-sort="perception">Perception</button></th>
210
- <th><button class="sort-button" data-sort="understanding">Understanding</button></th>
211
- <th><button class="sort-button" data-sort="reasoning">Reasoning</button></th>
212
- <th><button class="sort-button" data-sort="sensation">Sensation</button></th>
213
- <th><button class="sort-button" data-sort="l1_task">L1</button></th>
214
- <th><button class="sort-button" data-sort="l2_modality">L2</button></th>
215
- <th><button class="sort-button" data-sort="l3_stage">L3</button></th>
216
- <th><button class="sort-button" data-sort="l4_domain">L4</button></th>
217
- <th><span class="sr-only">Details</span></th>
218
- </tr>
219
- </thead>
220
- <tbody id="results-body">
221
- <tr><td class="empty" colspan="15">Loading results…</td></tr>
222
- </tbody>
223
- </table>
224
  </div>
225
- <p id="leaderboard-note" class="footnote">Scores use percentage points (0–100). Full evaluations with an overall score are ranked within their benchmark version; partial evaluations and entries without an overall score remain visible without a rank. Source labels identify where a score was reported, not an official audit badge.</p>
226
  </section>
227
 
228
- <section class="contribute" aria-labelledby="contribute-title">
229
- <p class="eyebrow">Open contribution</p>
230
- <h2 id="contribute-title">Add a result by pull request</h2>
231
- <p>Copy the result template, add one record to the results file, and open a PR in this Space repository. Include a public source link and keep the diff limited to score metadata. Do not submit benchmark samples, labels, raw model responses, or credentials.</p>
232
- <a class="button-link" href="https://huggingface.co/spaces/FudanCVL/AVI-Bench/discussions">Open Space community</a>
233
- <a class="button-link" href="https://huggingface.co/spaces/FudanCVL/AVI-Bench/tree/main">View files and guide</a>
234
- </section>
235
  </main>
236
 
237
  <footer>
238
- <div class="page">AVI-Bench &copy; 2026. Dataset use is governed by the <a href="https://github.com/FudanCVL/AVI-Bench/blob/main/DATA_USE_POLICY.md">AVI-Bench Data Use Policy</a>.</div>
 
 
 
 
 
 
 
239
  </footer>
240
 
241
  <script>
@@ -243,305 +326,335 @@
243
  "use strict";
244
 
245
  var SOURCE_LABELS = {
246
- paper: "Paper reported",
247
- participant: "Participant submission",
248
- maintainer: "Maintainer evaluation"
 
 
 
 
 
249
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  var entries = [];
251
- var rankById = new Map();
252
- var sortKey = "overall";
253
- var sortDirection = -1;
254
- var body = document.getElementById("results-body");
255
- var summary = document.getElementById("summary");
256
- var search = document.getElementById("search");
257
- var benchmarkFilter = document.getElementById("benchmark-filter");
258
- var providerFilter = document.getElementById("provider-filter");
259
- var sourceFilter = document.getElementById("source-filter");
260
 
261
- function text(value) {
262
- return value === null || value === undefined || value === "" ? "—" : String(value);
 
 
263
  }
264
 
265
- function score(value) {
266
  return typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : "—";
267
  }
268
 
269
  function compareText(left, right) {
270
- return String(left || "").localeCompare(String(right || ""), undefined, { numeric: true, sensitivity: "base" });
271
- }
272
-
273
- function addOption(select, value, label) {
274
- var option = document.createElement("option");
275
- option.value = value;
276
- option.textContent = label;
277
- select.appendChild(option);
278
- }
279
-
280
- function populateFilters() {
281
- Array.from(new Set(entries.map(function (entry) { return entry.benchmark_version; })))
282
- .sort(compareText).forEach(function (value) { addOption(benchmarkFilter, value, value); });
283
- Array.from(new Set(entries.map(function (entry) { return entry.provider; })))
284
- .sort(compareText).forEach(function (value) { addOption(providerFilter, value, value); });
285
- Array.from(new Set(entries.map(function (entry) { return entry.source.type; })))
286
- .sort(compareText).forEach(function (value) { addOption(sourceFilter, value, SOURCE_LABELS[value] || value); });
287
  }
288
 
289
- function buildRanks() {
290
- var groups = new Map();
291
- entries.filter(function (entry) {
292
- return entry.coverage.status === "full" && typeof entry.scores.overall === "number";
293
- }).forEach(function (entry) {
294
- var version = entry.benchmark_version;
295
- if (!groups.has(version)) groups.set(version, []);
296
- groups.get(version).push(entry);
297
- });
298
- groups.forEach(function (group) {
299
- group.sort(function (a, b) { return b.scores.overall - a.scores.overall || compareText(a.model_name, b.model_name); });
300
- group.forEach(function (entry, index) { rankById.set(entry.id, index + 1); });
301
- });
302
  }
303
 
304
- function matches(entry) {
305
- var query = search.value.trim().toLowerCase();
306
- var haystack = [entry.model_name, entry.model_id, entry.provider].join(" ").toLowerCase();
307
- return (!query || haystack.indexOf(query) !== -1)
308
- && (benchmarkFilter.value === "all" || entry.benchmark_version === benchmarkFilter.value)
309
- && (providerFilter.value === "all" || entry.provider === providerFilter.value)
310
- && (sourceFilter.value === "all" || entry.source.type === sourceFilter.value);
 
 
 
 
 
 
 
 
311
  }
312
 
313
- function sortValue(entry, key) {
314
- if (key === "rank") return rankById.has(entry.id) ? rankById.get(entry.id) : Infinity;
315
- if (key === "model_name" || key === "benchmark_version" || key === "provider") return entry[key];
316
- if (key === "source") return SOURCE_LABELS[entry.source.type] || entry.source.type;
317
- if (key === "coverage") return entry.coverage.tasks_completed / entry.coverage.tasks_total;
318
- if (key === "overall") return entry.scores.overall;
319
- if (["perception", "understanding", "reasoning", "sensation"].indexOf(key) !== -1) return (entry.scores.stages || {})[key];
320
- return (entry.scores.taxonomy || {})[key];
321
  }
322
 
323
- function compareEntries(a, b) {
324
- if (sortKey !== "benchmark_version") {
325
- var versionOrder = compareText(a.benchmark_version, b.benchmark_version);
326
- if (versionOrder !== 0) return versionOrder;
327
- }
328
- var left = sortValue(a, sortKey);
329
- var right = sortValue(b, sortKey);
330
- if (sortKey === "rank" && (left === Infinity || right === Infinity)) {
331
- if (left !== right) return left === Infinity ? 1 : -1;
332
- }
333
- if (left === null || left === undefined || right === null || right === undefined) {
334
- if (left !== right) return left === null || left === undefined ? 1 : -1;
335
- }
336
- if (typeof left === "number" || typeof right === "number") {
337
- left = typeof left === "number" ? left : -Infinity;
338
- right = typeof right === "number" ? right : -Infinity;
339
- if (left !== right) return (left - right) * sortDirection;
 
340
  } else {
341
- var textOrder = compareText(left, right);
342
- if (textOrder !== 0) return textOrder * sortDirection;
343
  }
344
- return compareText(a.model_name, b.model_name);
345
  }
346
 
347
- function makeCell(value, className) {
348
  var cell = document.createElement("td");
349
- if (className) cell.className = className;
350
- cell.textContent = value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  return cell;
352
  }
353
 
354
- function addDetailBlock(container, title, lines) {
355
- var block = document.createElement("div");
356
- block.className = "detail-block";
357
  var heading = document.createElement("h3");
358
- heading.textContent = title;
359
- block.appendChild(heading);
360
  lines.forEach(function (line) {
361
  var paragraph = document.createElement("p");
362
  paragraph.textContent = line;
363
- block.appendChild(paragraph);
364
  });
365
- container.appendChild(block);
366
  }
367
 
368
- function detailRow(entry) {
369
  var row = document.createElement("tr");
370
  row.className = "details-row";
371
  var cell = document.createElement("td");
372
- cell.colSpan = 15;
373
- var details = document.createElement("details");
374
- var summaryLine = document.createElement("summary");
375
- summaryLine.textContent = "Details and task scores";
376
- details.appendChild(summaryLine);
377
- var content = document.createElement("div");
378
- content.className = "detail-content";
379
-
380
- var coverage = entry.coverage;
381
- var sampleCoverage = coverage.samples_total === null || coverage.samples_total === undefined
382
  ? "Sample count not reported"
383
- : text(coverage.samples_completed) + " / " + text(coverage.samples_total) + " samples";
384
- var sourceType = SOURCE_LABELS[entry.source.type] || entry.source.type;
385
- addDetailBlock(content, "Record", [
386
- "Model ID: " + entry.model_id,
387
- "Provider: " + entry.provider,
388
- "Benchmark: " + entry.benchmark_version,
389
- "Evaluation date: " + text(entry.evaluation_date),
390
- "Source type: " + sourceType,
391
- "Coverage: " + coverage.tasks_completed + " / " + coverage.tasks_total + " tasks; " + sampleCoverage
392
  ]);
393
- addDetailBlock(content, "Scores", [
394
- "Overall: " + score(entry.scores.overall),
395
- "Stages: " + Object.keys(entry.scores.stages || {}).map(function (key) {
396
- return key + " " + score(entry.scores.stages[key]);
397
- }).join(" · ") || "No stage scores reported",
398
- "Taxonomy: " + Object.keys(entry.scores.taxonomy || {}).map(function (key) {
399
- return key.toUpperCase() + " " + score(entry.scores.taxonomy[key]);
400
- }).join(" · ") || "No taxonomy scores reported"
401
- ]);
402
- var sourceBlock = document.createElement("div");
403
- sourceBlock.className = "detail-block";
404
- var sourceHeading = document.createElement("h3");
405
- sourceHeading.textContent = "Source and notes";
406
- sourceBlock.appendChild(sourceHeading);
407
- var sourceLink = document.createElement("a");
408
- sourceLink.href = entry.source.url;
409
- sourceLink.target = "_blank";
410
- sourceLink.rel = "noopener noreferrer";
411
- sourceLink.textContent = "Open source";
412
- sourceBlock.appendChild(sourceLink);
413
- if (entry.submitter) {
414
- var submitter = document.createElement("p");
415
- submitter.textContent = "Submitted by: " + entry.submitter;
416
- sourceBlock.appendChild(submitter);
417
- }
418
- if (entry.notes) {
419
- var notes = document.createElement("p");
420
- notes.textContent = entry.notes;
421
- sourceBlock.appendChild(notes);
422
- }
423
- content.appendChild(sourceBlock);
424
-
425
- var taskScores = entry.scores.tasks || {};
426
- var taskLines = Object.keys(taskScores).sort(compareText).map(function (task) {
427
- var value = taskScores[task];
428
- if (value && typeof value === "object") {
429
- return task + ": " + Object.keys(value).sort(compareText).map(function (metric) {
430
- return metric + " " + score(value[metric]);
431
- }).join(" · ");
432
- }
433
- return task + ": " + score(value);
434
  });
435
- if (taskLines.length) addDetailBlock(content, "Task scores", taskLines);
436
-
437
- details.appendChild(content);
438
- cell.appendChild(details);
 
 
 
 
 
 
 
 
439
  row.appendChild(cell);
440
  return row;
441
  }
442
 
443
- function render() {
444
- var visible = entries.filter(matches).sort(compareEntries);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  body.replaceChildren();
446
  if (!visible.length) {
447
- var emptyRow = document.createElement("tr");
448
  var emptyCell = document.createElement("td");
449
- emptyCell.className = "empty";
450
- emptyCell.colSpan = 15;
451
- emptyCell.textContent = entries.length ? "No results match these filters." : "No merged results yet. Submit a result by pull request.";
452
- emptyRow.appendChild(emptyCell);
453
- body.appendChild(emptyRow);
454
- summary.textContent = entries.length ? "0 matching records" : "No results published yet";
455
- return;
456
  }
457
-
458
- visible.forEach(function (entry) {
459
  var row = document.createElement("tr");
460
- var rank = rankById.get(entry.id);
461
- row.appendChild(makeCell(rank ? String(rank) : "—"));
462
-
463
- var modelCell = document.createElement("td");
464
- modelCell.className = "model-cell";
465
- var modelName = document.createElement("span");
466
- modelName.className = "model-name";
467
- modelName.textContent = entry.model_name;
468
- var modelId = document.createElement("span");
469
- modelId.className = "model-id";
470
- modelId.textContent = entry.model_id;
471
- modelCell.appendChild(modelName);
472
- modelCell.appendChild(modelId);
473
- row.appendChild(modelCell);
474
-
475
- var sourceCell = document.createElement("td");
476
- var sourceTag = document.createElement("span");
477
- sourceTag.className = "source-tag" + (entry.source.type === "paper" ? " source-paper" : "");
478
- sourceTag.textContent = SOURCE_LABELS[entry.source.type] || entry.source.type;
479
- sourceCell.appendChild(sourceTag);
480
- row.appendChild(sourceCell);
481
- row.appendChild(makeCell(entry.benchmark_version));
482
-
483
- var coverageCell = document.createElement("td");
484
- var coverageTag = document.createElement("span");
485
- coverageTag.className = "coverage-tag" + (entry.coverage.status === "full" ? " coverage-full" : "");
486
- coverageTag.textContent = entry.coverage.tasks_completed + "/" + entry.coverage.tasks_total + " tasks";
487
- coverageCell.appendChild(coverageTag);
488
- row.appendChild(coverageCell);
489
-
490
- row.appendChild(makeCell(score(entry.scores.overall), "score score-overall"));
491
- var stages = entry.scores.stages || {};
492
- ["perception", "understanding", "reasoning", "sensation"].forEach(function (key) {
493
- row.appendChild(makeCell(score(stages[key]), "score"));
494
- });
495
- var taxonomy = entry.scores.taxonomy || {};
496
- ["l1_task", "l2_modality", "l3_stage", "l4_domain"].forEach(function (key) {
497
- row.appendChild(makeCell(score(taxonomy[key]), "score"));
498
- });
499
- var detailCell = document.createElement("td");
500
- var detailButton = document.createElement("button");
501
- detailButton.className = "sort-button";
502
- detailButton.type = "button";
503
- detailButton.textContent = "View";
504
- detailButton.setAttribute("aria-label", "View details for " + entry.model_name);
505
- detailButton.addEventListener("click", function () {
506
- var next = row.nextElementSibling;
507
- if (next && next.classList.contains("details-row")) {
508
- next.remove();
509
  } else {
510
- row.after(detailRow(entry));
 
 
511
  }
512
  });
513
- detailCell.appendChild(detailButton);
514
- row.appendChild(detailCell);
515
  body.appendChild(row);
516
  });
517
- var ranked = visible.filter(function (entry) { return rankById.has(entry.id); }).length;
518
- var unranked = visible.length - ranked;
519
- summary.textContent = visible.length + " records · " + ranked + " ranked · " + unranked + " unranked";
 
 
 
 
 
 
 
 
520
  }
521
 
522
- document.querySelectorAll(".sort-button[data-sort]").forEach(function (button) {
523
- button.addEventListener("click", function () {
524
- var nextKey = button.getAttribute("data-sort");
525
- if (sortKey === nextKey) sortDirection *= -1;
526
- else {
527
- sortKey = nextKey;
528
- sortDirection = nextKey === "overall" || nextKey === "rank" ? -1 : 1;
529
- }
530
- document.querySelectorAll(".sort-button[data-sort]").forEach(function (item) {
531
- item.removeAttribute("aria-sort");
532
- });
533
- button.setAttribute("aria-sort", sortDirection === -1 ? "descending" : "ascending");
534
- render();
 
535
  });
536
- });
537
- [search, benchmarkFilter, providerFilter, sourceFilter].forEach(function (control) {
538
- control.addEventListener("input", render);
539
- control.addEventListener("change", render);
 
 
 
540
  });
541
 
542
  fetch("./data/results.json", { cache: "no-store" })
543
  .then(function (response) {
544
- if (!response.ok) throw new Error("Could not load leaderboard data (HTTP " + response.status + ")");
545
  return response.json();
546
  })
547
  .then(function (data) {
@@ -549,20 +662,12 @@
549
  throw new Error("Leaderboard data does not match the expected schema.");
550
  }
551
  entries = data.entries;
552
- populateFilters();
553
- buildRanks();
554
- render();
555
  })
556
  .catch(function (error) {
557
- body.replaceChildren();
558
- var row = document.createElement("tr");
559
- var cell = document.createElement("td");
560
- cell.className = "error";
561
- cell.colSpan = 15;
562
- cell.textContent = error.message;
563
- row.appendChild(cell);
564
- body.appendChild(row);
565
- summary.textContent = "Results could not be loaded";
566
  });
567
  })();
568
  </script>
 
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="description" content="Compare audio-visual intelligence model results on AVI-Bench.">
7
+ <meta name="theme-color" content="#f7f8fa">
8
  <title>AVI-Bench Leaderboard</title>
9
  <style>
10
  :root {
11
  color-scheme: light;
12
+ --canvas: #f7f8fa;
13
+ --surface: #ffffff;
14
+ --ink: #172033;
15
+ --muted: #687386;
16
+ --line: #e3e7ed;
17
+ --line-strong: #d2d9e3;
18
+ --accent: #3154b8;
 
19
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
20
+ --mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
21
  }
22
 
23
  * { box-sizing: border-box; }
24
  body {
25
  margin: 0;
26
+ background: var(--canvas);
27
  color: var(--ink);
28
  font-family: var(--sans);
29
+ font-size: 14px;
30
+ line-height: 1.5;
31
  }
32
+ a { color: inherit; }
33
+ button { font: inherit; }
34
+ .container { width: min(1320px, calc(100% - 48px)); margin: 0 auto; }
35
+ .topbar { border-bottom: 1px solid var(--line); background: var(--surface); }
36
+ .topbar-inner {
37
+ min-height: 68px;
 
38
  display: flex;
39
  align-items: center;
40
  justify-content: space-between;
41
+ gap: 20px;
 
 
 
 
42
  }
43
+ .brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
44
+ .brand-mark {
45
+ width: 34px;
46
+ height: 34px;
 
 
 
 
 
47
  display: grid;
48
+ place-items: center;
49
+ border-radius: 8px;
50
+ background: var(--ink);
51
+ color: #fff;
52
+ font-size: 10px;
53
+ font-weight: 800;
54
+ letter-spacing: .04em;
55
  }
56
+ .brand-name { display: block; font-size: 14px; font-weight: 750; letter-spacing: -.02em; }
57
+ .brand-description { display: block; margin-top: 1px; color: var(--muted); font-size: 11px; }
58
+ .top-actions { display: flex; align-items: center; gap: 18px; }
59
+ .project-link { color: var(--muted); font-size: 12px; text-decoration: none; }
60
+ .project-link:hover { color: var(--ink); }
61
+ .submit-link {
62
+ display: inline-flex;
63
+ align-items: center;
64
+ min-height: 36px;
65
+ padding: 0 13px;
66
+ border: 1px solid var(--line-strong);
67
+ border-radius: 6px;
68
+ background: var(--surface);
69
  color: var(--ink);
70
  font-size: 12px;
71
+ font-weight: 650;
72
  text-decoration: none;
 
73
  }
74
+ .submit-link:hover { border-color: var(--accent); color: var(--accent); }
75
+ a:focus-visible, button:focus-visible {
76
+ outline: 3px solid #91a9ed;
77
+ outline-offset: 2px;
 
 
 
 
 
78
  }
79
+
80
+ main { padding: 42px 0 30px; }
81
+ .page-intro { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 30px; }
82
+ .eyebrow {
83
+ margin: 0 0 7px;
84
+ color: var(--accent);
85
+ font-size: 10px;
86
+ font-weight: 750;
87
+ letter-spacing: .12em;
88
+ text-transform: uppercase;
89
  }
90
+ h1 { margin: 0; font-size: clamp(28px, 3.6vw, 40px); font-weight: 720; letter-spacing: -.045em; line-height: 1.12; }
91
+ .intro-copy { max-width: 650px; margin: 10px 0 0; color: var(--muted); font-size: 14px; }
92
+ .intro-meta { flex: none; padding-bottom: 2px; color: var(--muted); font-size: 11px; text-align: right; }
93
+ .intro-meta strong { color: var(--ink); font-weight: 700; }
94
+
95
+ .score-section + .score-section { margin-top: 38px; }
96
+ .section-heading {
97
+ display: flex;
98
+ align-items: end;
99
+ justify-content: space-between;
100
+ gap: 18px;
101
+ margin-bottom: 12px;
102
  }
103
+ .section-kicker { margin: 0 0 3px; color: var(--muted); font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
104
+ h2 { margin: 0; font-size: 18px; font-weight: 680; letter-spacing: -.025em; }
105
+ .section-description { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
106
+ .record-count { color: var(--muted); font-size: 11px; white-space: nowrap; }
107
+ .table-frame {
108
+ overflow: hidden;
109
+ border: 1px solid var(--line);
110
+ border-radius: 8px;
111
+ background: var(--surface);
112
+ box-shadow: 0 2px 8px rgba(22, 33, 57, .025);
113
+ }
114
+ .table-scroll { overflow-x: auto; }
115
+ table { width: 100%; min-width: 1080px; border-collapse: collapse; font-size: 12px; }
116
+ th, td { padding: 12px 13px; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
117
+ th {
118
+ height: 42px;
119
+ background: #fafbfc;
120
+ color: #626e80;
121
+ font-size: 10px;
122
+ font-weight: 700;
123
+ letter-spacing: .035em;
124
+ }
125
+ th:first-child, td:first-child { width: 58px; text-align: center; }
126
+ th:nth-child(2), td:nth-child(2) { min-width: 225px; text-align: left; }
127
+ th:nth-child(3), td:nth-child(3) { min-width: 150px; text-align: left; }
128
+ th:nth-child(4), td:nth-child(4) { min-width: 104px; text-align: left; }
129
+ tbody tr.data-row:hover td { background: #fbfcfe; }
130
  tbody tr:last-child td { border-bottom: 0; }
131
+ .sort-button {
132
+ display: inline-flex;
133
+ align-items: center;
134
+ justify-content: flex-end;
135
+ gap: 5px;
136
+ padding: 0;
137
+ border: 0;
138
+ background: transparent;
139
+ color: inherit;
140
+ font-size: inherit;
141
+ font-weight: inherit;
142
+ letter-spacing: inherit;
143
+ text-align: inherit;
144
+ text-transform: inherit;
145
+ cursor: pointer;
146
+ }
147
+ th:first-child .sort-button, th:nth-child(2) .sort-button, th:nth-child(3) .sort-button, th:nth-child(4) .sort-button { justify-content: flex-start; }
148
+ .sort-button:hover, .sort-button[aria-sort] { color: var(--accent); }
149
+ .sort-mark { width: 9px; color: #a2aab7; font-size: 10px; }
150
+ .sort-button[aria-sort="ascending"] .sort-mark,
151
+ .sort-button[aria-sort="descending"] .sort-mark { color: var(--accent); }
152
+ .rank-value { color: #536074; font-variant-numeric: tabular-nums; font-weight: 650; }
153
+ .model-cell { display: flex; align-items: center; gap: 10px; }
154
+ .provider-logo, .provider-fallback {
155
+ width: 30px;
156
+ height: 30px;
157
+ flex: none;
158
+ display: grid;
159
+ place-items: center;
160
+ border: 1px solid var(--line);
161
+ border-radius: 7px;
162
+ background: #fff;
163
+ }
164
+ .provider-logo img { display: block; width: 19px; height: 19px; object-fit: contain; }
165
+ .provider-fallback { color: var(--muted); font-size: 10px; font-weight: 750; }
166
+ .model-info { min-width: 0; }
167
+ .model-name { display: block; overflow: hidden; color: var(--ink); font-size: 12px; font-weight: 700; text-overflow: ellipsis; }
168
+ .model-provider { display: block; margin-top: 1px; color: var(--muted); font-size: 10px; }
169
+ .model-actions { display: flex; align-items: center; gap: 9px; margin-top: 3px; }
170
+ .details-toggle { padding: 0; border: 0; background: transparent; color: var(--accent); font-size: 10px; cursor: pointer; }
171
+ .details-toggle:hover { text-decoration: underline; }
172
+ .benchmark-name { color: #465268; font-family: var(--mono); font-size: 10px; }
173
+ .source-link {
174
+ display: inline-flex;
175
+ align-items: center;
176
+ min-height: 22px;
177
+ padding: 1px 7px;
178
+ border: 1px solid var(--line);
179
+ border-radius: 4px;
180
+ background: #fff;
181
+ color: #535f72;
182
+ font-size: 10px;
183
+ text-decoration: none;
184
+ }
185
+ .source-link:hover { border-color: var(--accent); color: var(--accent); }
186
+ .score { color: #3b4658; font-variant-numeric: tabular-nums; }
187
+ .score-overall { color: var(--accent); font-size: 12px; font-weight: 750; }
188
+ .empty-cell, .error-cell { padding: 24px; color: var(--muted); text-align: center !important; }
189
+ .error-cell { color: #9a3535; }
190
  .details-row td { padding: 0; text-align: left; white-space: normal; }
191
+ .details-panel { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; padding: 16px 20px; background: #fafbfc; }
192
+ .detail-group h3 { margin: 0 0 6px; color: #677286; font-size: 9px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
193
+ .detail-group p { margin: 3px 0; color: #465268; font-size: 11px; overflow-wrap: anywhere; }
194
+ .detail-group a { color: var(--accent); }
195
+ .provenance-note {
196
+ display: flex;
197
+ justify-content: space-between;
198
+ gap: 20px;
199
+ margin: 22px 0 0;
200
+ color: var(--muted);
201
+ font-size: 10px;
202
+ }
203
+ footer { margin-top: 32px; border-top: 1px solid var(--line); background: var(--surface); }
204
+ .footer-inner {
205
+ min-height: 54px;
206
+ display: flex;
207
+ align-items: center;
208
+ justify-content: space-between;
209
+ gap: 16px;
210
+ color: var(--muted);
211
+ font-size: 10px;
212
+ }
213
+ .footer-links { display: flex; gap: 14px; }
214
+ .footer-links a { color: var(--muted); text-decoration: none; }
215
+ .footer-links a:hover { color: var(--accent); }
216
+
217
+ @media (max-width: 700px) {
218
+ .container { width: min(100% - 28px, 1320px); }
219
+ .topbar-inner { min-height: 62px; }
220
+ .brand-description, .project-link { display: none; }
221
+ main { padding-top: 30px; }
222
+ .page-intro { align-items: start; flex-direction: column; gap: 10px; margin-bottom: 24px; }
223
+ .intro-meta { text-align: left; }
224
  .section-heading { align-items: start; flex-direction: column; gap: 4px; }
225
+ .record-count { align-self: start; }
226
+ .score-section + .score-section { margin-top: 30px; }
227
+ .details-panel { grid-template-columns: 1fr 1fr; }
228
+ .provenance-note { flex-direction: column; gap: 5px; }
229
  }
230
+ @media (max-width: 430px) {
231
+ .container { width: calc(100% - 24px); }
232
+ .top-actions { gap: 9px; }
233
+ .submit-link { min-height: 33px; padding: 0 9px; font-size: 11px; }
234
+ h1 { font-size: 31px; }
235
+ .details-panel { grid-template-columns: 1fr; gap: 12px; }
236
+ .footer-inner { align-items: start; flex-direction: column; justify-content: center; padding: 12px 0; }
237
  }
238
  </style>
239
  </head>
240
  <body>
241
+ <header class="topbar">
242
+ <div class="container topbar-inner">
243
+ <a class="brand" href="https://fudancvl.github.io/AVI-Bench/" aria-label="AVI-Bench project">
244
+ <span class="brand-mark" aria-hidden="true">AVI</span>
245
+ <span>
246
+ <span class="brand-name">AVI-Bench</span>
247
+ <span class="brand-description">Audio-Visual Intelligence Benchmark</span>
248
+ </span>
249
+ </a>
250
+ <nav class="top-actions" aria-label="Project links">
251
+ <a class="project-link" href="https://fudancvl.github.io/AVI-Bench/">Project</a>
252
+ <a class="submit-link" href="https://huggingface.co/spaces/FudanCVL/AVI-Bench/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">Submit results <span aria-hidden="true">&nbsp;↗</span></a>
253
+ </nav>
254
  </div>
255
  </header>
256
 
257
+ <main class="container">
258
+ <section class="page-intro" aria-labelledby="page-title">
259
+ <div>
260
+ <p class="eyebrow">Audio-Visual Intelligence</p>
261
+ <h1 id="page-title">Model leaderboard</h1>
262
+ <p class="intro-copy">Compare model performance across cognitive stages and adaptive evaluation levels.</p>
263
+ </div>
264
+ <p class="intro-meta">Currently listing <strong id="global-count" aria-live="polite">Loading</strong></p>
 
 
 
265
  </section>
266
 
267
+ <section class="score-section" aria-labelledby="stage-title">
 
 
 
 
 
268
  <div class="section-heading">
269
  <div>
270
+ <p class="section-kicker">01 / Core performance</p>
271
+ <h2 id="stage-title">Scores by cognitive stage</h2>
272
+ <p class="section-description">Overall accuracy and the four AVI-Bench stages.</p>
273
  </div>
274
+ <span class="record-count" data-count-for="stage-table">Loading…</span>
275
  </div>
276
+ <div class="table-frame">
277
+ <div class="table-scroll" tabindex="0" aria-label="Stage scores table; scroll horizontally to view all columns">
278
+ <table id="stage-table" aria-describedby="stage-caption">
279
+ <caption id="stage-caption" class="sr-only">AVI-Bench overall and stage scores. Select a column heading to sort.</caption>
280
+ <thead><tr></tr></thead>
281
+ <tbody><tr><td class="empty-cell" colspan="9">Loading results…</td></tr></tbody>
282
+ </table>
283
+ </div>
 
 
284
  </div>
285
+ </section>
286
 
287
+ <section class="score-section" aria-labelledby="taxonomy-title">
288
+ <div class="section-heading">
289
+ <div>
290
+ <p class="section-kicker">02 / Adaptive evaluation</p>
291
+ <h2 id="taxonomy-title">Four-level AVI taxonomy</h2>
292
+ <p class="section-description">Task-, modality-, stage-, and domain-adaptive performance.</p>
293
+ </div>
294
+ <span class="record-count" data-count-for="taxonomy-table">Loading…</span>
295
+ </div>
296
+ <div class="table-frame">
297
+ <div class="table-scroll" tabindex="0" aria-label="Adaptive scores table; scroll horizontally to view all columns">
298
+ <table id="taxonomy-table" aria-describedby="taxonomy-caption">
299
+ <caption id="taxonomy-caption" class="sr-only">AVI-Bench overall and adaptive taxonomy scores. Select a column heading to sort.</caption>
300
+ <thead><tr></tr></thead>
301
+ <tbody><tr><td class="empty-cell" colspan="9">Loading results…</td></tr></tbody>
302
+ </table>
303
+ </div>
 
 
 
 
 
 
 
 
304
  </div>
 
305
  </section>
306
 
307
+ <p class="provenance-note">
308
+ <span>Scores are percentage points (0–100). Source links identify where each result was reported; a merged entry does not imply independent reproduction.</span>
309
+ <span>Company marks identify model providers and do not imply affiliation or endorsement.</span>
310
+ </p>
 
 
 
311
  </main>
312
 
313
  <footer>
314
+ <div class="container footer-inner">
315
+ <span>AVI-Bench · Community leaderboard</span>
316
+ <nav class="footer-links" aria-label="Related resources">
317
+ <a href="https://huggingface.co/datasets/FudanCVL/AVIBench">Dataset</a>
318
+ <a href="https://arxiv.org/abs/2606.07643">Paper</a>
319
+ <a href="https://github.com/FudanCVL/AVI-Bench">Code</a>
320
+ </nav>
321
+ </div>
322
  </footer>
323
 
324
  <script>
 
326
  "use strict";
327
 
328
  var SOURCE_LABELS = {
329
+ paper: "Paper",
330
+ participant: "Participant",
331
+ maintainer: "Maintainer"
332
+ };
333
+ var LOGO_BY_PROVIDER = {
334
+ google: "./assets/logos/google.svg",
335
+ "alibaba cloud": "./assets/logos/alibabacloud.svg",
336
+ openai: "./assets/logos/openai.svg"
337
  };
338
+ var TABLES = [
339
+ {
340
+ id: "stage-table",
341
+ columns: [
342
+ { key: "rank", label: "Rank", kind: "rank" },
343
+ { key: "model_name", label: "Model", kind: "model" },
344
+ { key: "benchmark_version", label: "Benchmark", kind: "benchmark" },
345
+ { key: "source", label: "Source", kind: "source" },
346
+ { key: "overall", label: "Overall", kind: "score", path: ["scores", "overall"] },
347
+ { key: "perception", label: "Perception", kind: "score", path: ["scores", "stages", "perception"] },
348
+ { key: "understanding", label: "Understanding", kind: "score", path: ["scores", "stages", "understanding"] },
349
+ { key: "reasoning", label: "Reasoning", kind: "score", path: ["scores", "stages", "reasoning"] },
350
+ { key: "sensation", label: "Sensation", kind: "score", path: ["scores", "stages", "sensation"] }
351
+ ],
352
+ state: { activeKey: "overall", direction: -1 }
353
+ },
354
+ {
355
+ id: "taxonomy-table",
356
+ columns: [
357
+ { key: "rank", label: "Rank", kind: "rank" },
358
+ { key: "model_name", label: "Model", kind: "model" },
359
+ { key: "benchmark_version", label: "Benchmark", kind: "benchmark" },
360
+ { key: "source", label: "Source", kind: "source" },
361
+ { key: "overall", label: "Overall", kind: "score", path: ["scores", "overall"] },
362
+ { key: "l1_task", label: "L1 Task-Adaptive", kind: "score", path: ["scores", "taxonomy", "l1_task"] },
363
+ { key: "l2_modality", label: "L2 Modality-Adaptive", kind: "score", path: ["scores", "taxonomy", "l2_modality"] },
364
+ { key: "l3_stage", label: "L3 Stage-Adaptive", kind: "score", path: ["scores", "taxonomy", "l3_stage"] },
365
+ { key: "l4_domain", label: "L4 Domain-Adaptive", kind: "score", path: ["scores", "taxonomy", "l4_domain"] }
366
+ ],
367
+ state: { activeKey: "overall", direction: -1 }
368
+ }
369
+ ];
370
  var entries = [];
 
 
 
 
 
 
 
 
 
371
 
372
+ function readPath(object, path) {
373
+ return path.reduce(function (value, key) {
374
+ return value && value[key] !== undefined ? value[key] : null;
375
+ }, object);
376
  }
377
 
378
+ function formatScore(value) {
379
  return typeof value === "number" && Number.isFinite(value) ? value.toFixed(2) : "—";
380
  }
381
 
382
  function compareText(left, right) {
383
+ return String(left || "").localeCompare(String(right || ""), undefined, {
384
+ numeric: true,
385
+ sensitivity: "base"
386
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  }
388
 
389
+ function sortValue(entry, column) {
390
+ if (column.kind === "rank") return entry.scores.overall;
391
+ if (column.kind === "model") return entry.model_name;
392
+ if (column.kind === "benchmark") return entry.benchmark_version;
393
+ if (column.kind === "source") return SOURCE_LABELS[entry.source.type] || entry.source.type;
394
+ return readPath(entry, column.path);
 
 
 
 
 
 
 
395
  }
396
 
397
+ function compareEntries(left, right, table) {
398
+ var leftValue = sortValue(left, table.state.sortColumn);
399
+ var rightValue = sortValue(right, table.state.sortColumn);
400
+ var leftMissing = leftValue === null || leftValue === undefined;
401
+ var rightMissing = rightValue === null || rightValue === undefined;
402
+ if (leftMissing !== rightMissing) return leftMissing ? 1 : -1;
403
+ if (!leftMissing && (typeof leftValue === "number" || typeof rightValue === "number")) {
404
+ var leftNumber = typeof leftValue === "number" ? leftValue : -Infinity;
405
+ var rightNumber = typeof rightValue === "number" ? rightValue : -Infinity;
406
+ if (leftNumber !== rightNumber) return (leftNumber - rightNumber) * table.state.direction;
407
+ } else if (!leftMissing) {
408
+ var textOrder = compareText(leftValue, rightValue);
409
+ if (textOrder !== 0) return textOrder * table.state.direction;
410
+ }
411
+ return compareText(left.model_name, right.model_name);
412
  }
413
 
414
+ function makeCell(value, className) {
415
+ var cell = document.createElement("td");
416
+ if (className) cell.className = className;
417
+ cell.textContent = value;
418
+ return cell;
 
 
 
419
  }
420
 
421
+ function providerLogo(provider) {
422
+ var key = String(provider || "").trim().toLowerCase();
423
+ var source = LOGO_BY_PROVIDER[key];
424
+ var wrapper = document.createElement("span");
425
+ wrapper.className = source ? "provider-logo" : "provider-fallback";
426
+ wrapper.setAttribute("aria-hidden", "true");
427
+ if (source) {
428
+ var image = document.createElement("img");
429
+ image.src = source;
430
+ image.alt = "";
431
+ image.addEventListener("error", function () {
432
+ var fallback = document.createElement("span");
433
+ fallback.className = "provider-fallback";
434
+ fallback.setAttribute("aria-hidden", "true");
435
+ fallback.textContent = String(provider || "?").trim().slice(0, 1).toUpperCase();
436
+ wrapper.replaceWith(fallback);
437
+ }, { once: true });
438
+ wrapper.appendChild(image);
439
  } else {
440
+ wrapper.textContent = String(provider || "?").trim().slice(0, 1).toUpperCase();
 
441
  }
442
+ return wrapper;
443
  }
444
 
445
+ function createModelCell(entry, row, columnCount) {
446
  var cell = document.createElement("td");
447
+ var content = document.createElement("div");
448
+ content.className = "model-cell";
449
+ content.appendChild(providerLogo(entry.provider));
450
+
451
+ var info = document.createElement("div");
452
+ info.className = "model-info";
453
+ var name = document.createElement("span");
454
+ name.className = "model-name";
455
+ name.textContent = entry.model_name;
456
+ var provider = document.createElement("span");
457
+ provider.className = "model-provider";
458
+ provider.textContent = entry.provider;
459
+ var actions = document.createElement("div");
460
+ actions.className = "model-actions";
461
+ var toggle = document.createElement("button");
462
+ toggle.className = "details-toggle";
463
+ toggle.type = "button";
464
+ toggle.textContent = "Details";
465
+ toggle.setAttribute("aria-expanded", "false");
466
+ toggle.addEventListener("click", function () {
467
+ var next = row.nextElementSibling;
468
+ if (next && next.classList.contains("details-row")) {
469
+ next.remove();
470
+ toggle.setAttribute("aria-expanded", "false");
471
+ return;
472
+ }
473
+ row.after(createDetailsRow(entry, columnCount));
474
+ toggle.setAttribute("aria-expanded", "true");
475
+ });
476
+ actions.appendChild(toggle);
477
+ info.appendChild(name);
478
+ info.appendChild(provider);
479
+ info.appendChild(actions);
480
+ content.appendChild(info);
481
+ cell.appendChild(content);
482
  return cell;
483
  }
484
 
485
+ function addDetailGroup(container, headingText, lines) {
486
+ var group = document.createElement("div");
487
+ group.className = "detail-group";
488
  var heading = document.createElement("h3");
489
+ heading.textContent = headingText;
490
+ group.appendChild(heading);
491
  lines.forEach(function (line) {
492
  var paragraph = document.createElement("p");
493
  paragraph.textContent = line;
494
+ group.appendChild(paragraph);
495
  });
496
+ container.appendChild(group);
497
  }
498
 
499
+ function createDetailsRow(entry, columnCount) {
500
  var row = document.createElement("tr");
501
  row.className = "details-row";
502
  var cell = document.createElement("td");
503
+ cell.colSpan = columnCount;
504
+ var panel = document.createElement("div");
505
+ panel.className = "details-panel";
506
+ var coverage = entry.coverage || {};
507
+ var sampleLine = coverage.samples_total === null || coverage.samples_total === undefined
 
 
 
 
 
508
  ? "Sample count not reported"
509
+ : String(coverage.samples_completed) + " / " + String(coverage.samples_total) + " samples";
510
+ addDetailGroup(panel, "Evaluation", [
511
+ "Model ID: " + String(entry.model_id || "—"),
512
+ "Benchmark: " + String(entry.benchmark_version || "—"),
513
+ "Evaluation date: " + String(entry.evaluation_date || "Not reported"),
514
+ "Task coverage: " + String(coverage.tasks_completed) + " / " + String(coverage.tasks_total) + " tasks",
515
+ sampleLine
 
 
516
  ]);
517
+ var stageScores = Object.keys(entry.scores.stages || {}).map(function (key) {
518
+ return key + " " + formatScore(entry.scores.stages[key]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  });
520
+ var taxonomyScores = Object.keys(entry.scores.taxonomy || {}).map(function (key) {
521
+ return key.toUpperCase() + " " + formatScore(entry.scores.taxonomy[key]);
522
+ });
523
+ addDetailGroup(panel, "Scores", [
524
+ "Overall: " + formatScore(entry.scores.overall),
525
+ stageScores.length ? "Stages: " + stageScores.join(" · ") : "No stage scores reported",
526
+ taxonomyScores.length ? "Taxonomy: " + taxonomyScores.join(" · ") : "No taxonomy scores reported"
527
+ ]);
528
+ addDetailGroup(panel, "Notes", [
529
+ entry.notes || "No additional notes."
530
+ ]);
531
+ cell.appendChild(panel);
532
  row.appendChild(cell);
533
  return row;
534
  }
535
 
536
+ function createSourceCell(entry) {
537
+ var cell = document.createElement("td");
538
+ var link = document.createElement("a");
539
+ link.className = "source-link";
540
+ link.href = entry.source.url;
541
+ link.target = "_blank";
542
+ link.rel = "noopener noreferrer";
543
+ link.textContent = SOURCE_LABELS[entry.source.type] || entry.source.type;
544
+ cell.appendChild(link);
545
+ return cell;
546
+ }
547
+
548
+ function renderHeader(table) {
549
+ var header = document.querySelector("#" + table.id + " thead tr");
550
+ header.replaceChildren();
551
+ table.columns.forEach(function (column) {
552
+ var cell = document.createElement("th");
553
+ cell.scope = "col";
554
+ var button = document.createElement("button");
555
+ button.className = "sort-button";
556
+ button.type = "button";
557
+ button.dataset.sortKey = column.key;
558
+ button.setAttribute("aria-label", "Sort by " + column.label);
559
+ var label = document.createElement("span");
560
+ label.textContent = column.label;
561
+ var mark = document.createElement("span");
562
+ mark.className = "sort-mark";
563
+ mark.setAttribute("aria-hidden", "true");
564
+ mark.textContent = "↕";
565
+ button.appendChild(label);
566
+ button.appendChild(mark);
567
+ button.addEventListener("click", function () {
568
+ if (table.state.activeKey === column.key) {
569
+ table.state.direction *= -1;
570
+ } else {
571
+ table.state.direction = column.kind === "score" || column.kind === "rank" ? -1 : 1;
572
+ }
573
+ table.state.sortColumn = column;
574
+ table.state.activeKey = column.key;
575
+ renderTable(table);
576
+ });
577
+ cell.appendChild(button);
578
+ header.appendChild(cell);
579
+ });
580
+ }
581
+
582
+ function renderTable(table) {
583
+ var element = document.getElementById(table.id);
584
+ var body = element.querySelector("tbody");
585
+ var visible = entries.slice().sort(function (left, right) {
586
+ return compareEntries(left, right, table);
587
+ });
588
  body.replaceChildren();
589
  if (!visible.length) {
590
+ var empty = document.createElement("tr");
591
  var emptyCell = document.createElement("td");
592
+ emptyCell.className = "empty-cell";
593
+ emptyCell.colSpan = table.columns.length;
594
+ emptyCell.textContent = "No results published yet.";
595
+ empty.appendChild(emptyCell);
596
+ body.appendChild(empty);
 
 
597
  }
598
+ visible.forEach(function (entry, index) {
 
599
  var row = document.createElement("tr");
600
+ row.className = "data-row";
601
+ table.columns.forEach(function (column) {
602
+ if (column.kind === "rank") {
603
+ row.appendChild(makeCell(String(index + 1), "rank-value"));
604
+ } else if (column.kind === "model") {
605
+ row.appendChild(createModelCell(entry, row, table.columns.length));
606
+ } else if (column.kind === "benchmark") {
607
+ row.appendChild(makeCell(entry.benchmark_version, "benchmark-name"));
608
+ } else if (column.kind === "source") {
609
+ row.appendChild(createSourceCell(entry));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  } else {
611
+ var value = readPath(entry, column.path);
612
+ var classes = column.key === "overall" ? "score score-overall" : "score";
613
+ row.appendChild(makeCell(formatScore(value), classes));
614
  }
615
  });
 
 
616
  body.appendChild(row);
617
  });
618
+ var activeButton = element.querySelector('[data-sort-key="' + table.state.activeKey + '"]');
619
+ element.querySelectorAll(".sort-button").forEach(function (button) {
620
+ button.removeAttribute("aria-sort");
621
+ button.querySelector(".sort-mark").textContent = "↕";
622
+ });
623
+ if (activeButton) {
624
+ activeButton.setAttribute("aria-sort", table.state.direction === -1 ? "descending" : "ascending");
625
+ activeButton.querySelector(".sort-mark").textContent = table.state.direction === -1 ? "↓" : "↑";
626
+ }
627
+ var count = document.querySelector('[data-count-for="' + table.id + '"]');
628
+ count.textContent = visible.length + (visible.length === 1 ? " model" : " models");
629
  }
630
 
631
+ function showError(message) {
632
+ document.getElementById("global-count").textContent = "results unavailable";
633
+ TABLES.forEach(function (table) {
634
+ var body = document.querySelector("#" + table.id + " tbody");
635
+ body.replaceChildren();
636
+ var row = document.createElement("tr");
637
+ var cell = document.createElement("td");
638
+ cell.className = "error-cell";
639
+ cell.colSpan = table.columns.length;
640
+ cell.textContent = message;
641
+ row.appendChild(cell);
642
+ body.appendChild(row);
643
+ var count = document.querySelector('[data-count-for="' + table.id + '"]');
644
+ count.textContent = "Unavailable";
645
  });
646
+ }
647
+
648
+ TABLES.forEach(function (table) {
649
+ table.state.sortColumn = table.columns.find(function (column) {
650
+ return column.key === "overall";
651
+ });
652
+ renderHeader(table);
653
  });
654
 
655
  fetch("./data/results.json", { cache: "no-store" })
656
  .then(function (response) {
657
+ if (!response.ok) throw new Error("Could not load leaderboard data (HTTP " + response.status + ").");
658
  return response.json();
659
  })
660
  .then(function (data) {
 
662
  throw new Error("Leaderboard data does not match the expected schema.");
663
  }
664
  entries = data.entries;
665
+ document.getElementById("global-count").textContent = entries.length
666
+ + (entries.length === 1 ? " model result" : " model results");
667
+ TABLES.forEach(renderTable);
668
  })
669
  .catch(function (error) {
670
+ showError(error.message || "Could not load leaderboard data.");
 
 
 
 
 
 
 
 
671
  });
672
  })();
673
  </script>