elmadany commited on
Commit
cffe041
Β·
verified Β·
1 Parent(s): 3728916

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +112 -78
public/index.html CHANGED
@@ -66,8 +66,24 @@
66
  .bar:nth-child(odd) { animation-duration: 1.5s; } .bar:nth-child(2n) { animation-duration: 1.1s; }
67
  @keyframes bounce { 0%, 100% { height: 20px; } 50% { height: 120px; } }
68
 
 
 
 
 
 
 
 
69
  /* --- MAIN BOARD --- */
70
- .main-card { background: white; border-radius: 24px; margin: 0 40px; padding: 40px; color: #0f172a; min-height: 600px; position: relative; z-index: 10; }
 
 
 
 
 
 
 
 
 
71
 
72
  .tabs { display: flex; gap: 10px; border-bottom: 2px solid #e2e8f0; margin-bottom: 30px; padding-bottom: 10px; overflow-x: auto; }
73
  .tab-btn { background: none; border: none; font-size: 15px; font-weight: 600; color: #64748b; padding: 10px 20px; cursor: pointer; transition: 0.3s; border-radius: 8px; white-space: nowrap; }
@@ -93,7 +109,15 @@
93
  h4 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 18px; margin: 0 0 15px 0; border-bottom: 1px solid #eee; padding-bottom: 10px; }
94
 
95
  /* Citations */
96
- .citation-section { width: 100%; margin: 60px 0 0 0; background: #0f172a; border: 1px solid #334155; border-radius: 16px; padding: 40px; box-sizing: border-box; box-shadow: 0 20px 40px rgba(0,0,0,0.3); position: relative; }
 
 
 
 
 
 
 
 
97
  .citation-section h3 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 24px; margin-top: 0; }
98
  .citation-box { background: #1e293b; color: #cbd5e1; padding: 20px; border-radius: 12px; font-family: monospace; white-space: pre-wrap; margin-top: 20px; overflow-x: auto; border: 1px solid #334155; font-size: 13px; line-height: 1.5; }
99
  .copy-btn { position: absolute; top: 40px; right: 40px; background: var(--text-yellow); border: none; padding: 8px 16px; border-radius: 6px; font-weight: bold; cursor: pointer; color: #0f172a; }
@@ -144,76 +168,76 @@
144
  </div>
145
  </div>
146
 
147
- <div class="main-card" id="board">
148
- <div id="loader" style="text-align:center; padding:60px; color:#64748b;">
149
- <i class="fa-solid fa-circle-notch fa-spin fa-3x"></i><br><br>Loading Leaderboard Data...
150
- </div>
151
-
152
- <div id="app-content" style="display:none;">
153
- <div class="tabs">
154
- <button class="tab-btn active" id="tab-btn-asr" onclick="setTab('asr')">Automatic Speech Recognition (ASR)</button>
155
- <button class="tab-btn" id="tab-btn-tts" onclick="setTab('tts')">Text-to-Speech (TTS)</button>
156
- <button class="tab-btn" id="tab-btn-slid" onclick="setTab('slid')">Spoken Language Identification (SLID)</button>
157
- <button class="tab-btn" id="tab-btn-lang" onclick="setTab('lang')">Language Analysis</button>
158
  </div>
159
 
160
- <div id="asr" class="view active">
161
- <div class="controls">
162
- <span style="font-weight:700;">View Mode:</span>
163
- <button id="btn-over" class="action-btn bg-blue" style="padding:8px 16px; font-size:12px; box-shadow:none;" onclick="setASRMode('overview')">Overview</button>
164
- <button id="btn-fam" class="action-btn" style="padding:8px 16px; font-size:12px; background:#e2e8f0; color:#334155;" onclick="setASRMode('family')">By Family</button>
165
- <button id="btn-mod" class="action-btn" style="padding:8px 16px; font-size:12px; background:#e2e8f0; color:#334155;" onclick="setASRMode('model')">By Model</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
- <div style="flex-grow:1; text-align:right;">
168
- <div id="grp-fam" style="display:none;"><label>Select Family: </label><select id="asr-select-fam" onchange="renderASR()"></select></div>
169
- <div id="grp-mod" style="display:none;"><label>Select Model: </label><select id="asr-select-mod" onchange="renderASR()"></select></div>
170
  </div>
 
171
  </div>
172
-
173
- <div style="display:flex; justify-content:space-between; align-items:end; margin-bottom:10px;">
174
- <h3 id="asr-title" style="color:#d97706; margin:0;">Results Overview</h3>
175
- <div id="asr-rank-info" class="rank-info">Ranking: WER (↓) then CER (↓)</div>
176
- </div>
177
- <div id="asr-table" class="table-wrap"></div>
178
- </div>
179
 
180
- <div id="tts" class="view">
181
- <div class="controls">
182
- <span style="font-weight:600;">Select Model:</span>
183
- <select id="tts-select" onchange="renderTTS()"></select>
 
 
 
 
184
  </div>
185
- <h3 id="tts-title" style="color:#d97706; margin-bottom:10px;"></h3>
186
- <div id="tts-summary" style="margin-bottom:20px; font-weight:600; color:#0f172a;"></div>
187
- <div id="tts-table" class="table-wrap"></div>
188
- </div>
189
 
190
- <div id="slid" class="view">
191
- <div style="display:flex; justify-content:space-between; align-items:end; margin-bottom:15px;">
192
- <h3 style="color:#d97706; margin:0;">Spoken Language Identification</h3>
193
- <div class="rank-info">Ranking: F1-Macro (↑)</div>
 
 
194
  </div>
195
- <div id="slid-table" class="table-wrap"></div>
196
- </div>
197
 
198
- <div id="lang" class="view">
199
- <div class="controls">
200
- <span style="font-weight:600;">Select Language:</span>
201
- <select id="lang-select" onchange="renderLanguageView()"></select>
202
- </div>
203
-
204
- <h4>ASR Results <span class="rank-info" style="font-weight:normal;">(Ranked by WER ↓)</span></h4>
205
- <div id="lang-asr-table" class="table-wrap"></div>
206
 
207
- <h4>TTS Results</h4>
208
- <div id="lang-tts-table" class="table-wrap"></div>
209
 
210
- <h4>SLID Results <span class="rank-info" style="font-weight:normal;">(Ranked by Score ↑)</span></h4>
211
- <div id="lang-slid-table" class="table-wrap"></div>
 
212
  </div>
213
  </div>
214
- </div>
215
 
216
- <div class="lb-container">
217
  <div class="citation-section" id="citation">
218
  <h3>Citation</h3>
219
  <button class="copy-btn" onclick="copyCitation()"><i class="fa-regular fa-copy"></i> Copy</button>
@@ -258,17 +282,9 @@
258
  populate('asr-select-mod', DATA.metadata.models);
259
  populate('tts-select', DATA.metadata.tts_models);
260
 
261
- // --- POPULATE LANGUAGES FROM ACTUAL DATA ---
262
  const allLangs = new Set();
263
- // Scan ASR by model data to find every single language present
264
- Object.values(DATA.asr.by_model).forEach(rows => {
265
- rows.forEach(r => allLangs.add(r.Language));
266
- });
267
- // Scan TTS as well
268
- Object.values(DATA.tts).forEach(rows => {
269
- rows.forEach(r => allLangs.add(r.language));
270
- });
271
-
272
  populate('lang-select', Array.from(allLangs).sort());
273
 
274
  renderASR(); renderTTS(); renderSLID();
@@ -303,11 +319,17 @@
303
  if(n>0) modelStats.push({ name: modName, wer: sW/n, cer: sC/n });
304
  });
305
 
 
306
  modelStats.sort((a,b) => a.wer - b.wer);
 
307
 
308
  html = `<table><thead><tr><th>Model</th><th>Simba ASR Score (WER/CER) <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
309
  modelStats.forEach((m, i) => {
310
- let icon = (i<3) ? ['πŸ₯‡','πŸ₯ˆ','πŸ₯‰'][i] + ' ' : '';
 
 
 
 
311
  html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${m.name}</td><td><b>${fmt(m.wer)} / ${fmt(m.cer)}</b></td></tr>`;
312
  });
313
 
@@ -321,13 +343,17 @@
321
  if(!d) return;
322
 
323
  d.data.sort((a,b) => a.Avg_WER - b.Avg_WER);
 
324
 
325
  html = `<table><thead><tr><th>Model</th><th>Simba ASR Family Score <i class="fa-solid fa-arrow-down arrow-down"></i></th>`;
326
  d.languages.forEach(l => html += `<th>${getIso(l.name, l.iso)}</th>`);
327
  html += `</tr></thead><tbody>`;
328
 
329
  d.data.forEach((r, idx) => {
330
- let icon = (idx<3) ? ['πŸ₯‡','πŸ₯ˆ','πŸ₯‰'][idx] + ' ' : '';
 
 
 
331
  html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.Model}</td><td style="font-weight:bold; background:#f8fafc">${fmt(r.Avg_WER)} / ${fmt(r.Avg_CER)}</td>`;
332
  d.languages.forEach(l => {
333
  let w=r[`WER_${l.name}`], c=r[`CER_${l.name}`];
@@ -342,7 +368,7 @@
342
  document.getElementById('grp-mod').style.display='inline-block';
343
 
344
  const rows = DATA.asr.by_model[val];
345
- html = `<table><thead><tr><th>Language (iso)</th><th>Family</th><th>WER (%) <i class="fa-solid fa-arrow-down arrow-down"></i></th><th>CER (%) <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
346
  rows.forEach(r => {
347
  html += `<tr><td>${getIso(r.Language, r.ISO)}</td><td>${r.Family}</td><td>${fmt(r.WER)}</td><td>${fmt(r.CER)}</td></tr>`;
348
  });
@@ -396,7 +422,7 @@
396
  function renderLanguageView() {
397
  const lang = document.getElementById('lang-select').value;
398
 
399
- // 1. ASR
400
  let asrRows = [];
401
  Object.keys(DATA.asr.by_model).forEach(modName => {
402
  const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
@@ -404,12 +430,17 @@
404
  });
405
  asrRows.sort((a,b) => a.wer - b.wer);
406
 
407
- let h1 = `<table><thead><tr><th>Model</th><th>WER (%)</th><th>CER (%)</th></tr></thead><tbody>`;
408
  if(asrRows.length === 0) h1 += `<tr><td colspan="3">No ASR data for this language.</td></tr>`;
409
- else asrRows.forEach((r, i) => {
410
- let icon = (i<3) ? ['πŸ₯‡','πŸ₯ˆ','πŸ₯‰'][i] + ' ' : '';
411
- h1 += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.model}</td><td>${fmt(r.wer)}</td><td>${fmt(r.cer)}</td></tr>`;
412
- });
 
 
 
 
 
413
  h1 += `</tbody></table>`;
414
  document.getElementById('lang-asr-table').innerHTML = h1;
415
 
@@ -429,16 +460,19 @@
429
 
430
  // 3. SLID
431
  let h3 = `<table><thead><tr><th>Model</th><th>F1-Score</th></tr></thead><tbody>`;
432
- // Fuzzy match language name in SLID data (handle "Edo" vs "Edo (bin)")
433
  const slidRow = DATA.slid.find(r => r.Language === lang) ||
434
  DATA.slid.find(r => r.Language.startsWith(lang + " (")) ||
435
  DATA.slid.find(r => r.Language.includes(lang));
436
 
437
  if(slidRow) {
438
  let m = slidRow['MMS-LID-1024'], s = slidRow['Simba-SLID'];
 
439
  let scores = [{n:'Simba-SLID', v:s}, {n:'MMS-LID-1024', v:m}].sort((a,b)=>b.v - a.v);
 
440
  scores.forEach((sc, i) => {
441
- let icon = (i==0) ? 'πŸ₯‡ ' : '';
 
442
  h3 += `<tr><td style="font-weight:600;">${icon}${sc.n}</td><td>${fmt(sc.v)}</td></tr>`;
443
  });
444
  } else {
 
66
  .bar:nth-child(odd) { animation-duration: 1.5s; } .bar:nth-child(2n) { animation-duration: 1.1s; }
67
  @keyframes bounce { 0%, 100% { height: 20px; } 50% { height: 120px; } }
68
 
69
+ /* --- WIDTH CONTROLLER --- */
70
+ .content-container {
71
+ width: 80%; /* Fixed 80% width for both cards */
72
+ max-width: 1600px; /* Optional cap for very large screens */
73
+ margin: 0 auto;
74
+ }
75
+
76
  /* --- MAIN BOARD --- */
77
+ .main-card {
78
+ background: white;
79
+ border-radius: 24px;
80
+ padding: 40px;
81
+ color: #0f172a;
82
+ min-height: 600px;
83
+ position: relative;
84
+ z-index: 10;
85
+ margin-bottom: 60px; /* Space between card and citation */
86
+ }
87
 
88
  .tabs { display: flex; gap: 10px; border-bottom: 2px solid #e2e8f0; margin-bottom: 30px; padding-bottom: 10px; overflow-x: auto; }
89
  .tab-btn { background: none; border: none; font-size: 15px; font-weight: 600; color: #64748b; padding: 10px 20px; cursor: pointer; transition: 0.3s; border-radius: 8px; white-space: nowrap; }
 
109
  h4 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 18px; margin: 0 0 15px 0; border-bottom: 1px solid #eee; padding-bottom: 10px; }
110
 
111
  /* Citations */
112
+ .citation-section {
113
+ background: #0f172a;
114
+ border: 1px solid #334155;
115
+ border-radius: 16px;
116
+ padding: 40px;
117
+ box-sizing: border-box;
118
+ box-shadow: 0 20px 40px rgba(0,0,0,0.3);
119
+ position: relative;
120
+ }
121
  .citation-section h3 { color: var(--text-yellow); font-family: 'Rubik', sans-serif; font-size: 24px; margin-top: 0; }
122
  .citation-box { background: #1e293b; color: #cbd5e1; padding: 20px; border-radius: 12px; font-family: monospace; white-space: pre-wrap; margin-top: 20px; overflow-x: auto; border: 1px solid #334155; font-size: 13px; line-height: 1.5; }
123
  .copy-btn { position: absolute; top: 40px; right: 40px; background: var(--text-yellow); border: none; padding: 8px 16px; border-radius: 6px; font-weight: bold; cursor: pointer; color: #0f172a; }
 
168
  </div>
169
  </div>
170
 
171
+ <div class="content-container">
172
+ <div class="main-card" id="board">
173
+ <div id="loader" style="text-align:center; padding:60px; color:#64748b;">
174
+ <i class="fa-solid fa-circle-notch fa-spin fa-3x"></i><br><br>Loading Leaderboard Data...
 
 
 
 
 
 
 
175
  </div>
176
 
177
+ <div id="app-content" style="display:none;">
178
+ <div class="tabs">
179
+ <button class="tab-btn active" id="tab-btn-asr" onclick="setTab('asr')">Automatic Speech Recognition (ASR)</button>
180
+ <button class="tab-btn" id="tab-btn-tts" onclick="setTab('tts')">Text-to-Speech (TTS)</button>
181
+ <button class="tab-btn" id="tab-btn-slid" onclick="setTab('slid')">Spoken Language Identification (SLID)</button>
182
+ <button class="tab-btn" id="tab-btn-lang" onclick="setTab('lang')">Language Analysis</button>
183
+ </div>
184
+
185
+ <div id="asr" class="view active">
186
+ <div class="controls">
187
+ <span style="font-weight:700;">View Mode:</span>
188
+ <button id="btn-over" class="action-btn bg-blue" style="padding:8px 16px; font-size:12px; box-shadow:none;" onclick="setASRMode('overview')">Overview</button>
189
+ <button id="btn-fam" class="action-btn" style="padding:8px 16px; font-size:12px; background:#e2e8f0; color:#334155;" onclick="setASRMode('family')">By Family</button>
190
+ <button id="btn-mod" class="action-btn" style="padding:8px 16px; font-size:12px; background:#e2e8f0; color:#334155;" onclick="setASRMode('model')">By Model</button>
191
+
192
+ <div style="flex-grow:1; text-align:right;">
193
+ <div id="grp-fam" style="display:none;"><label>Select Family: </label><select id="asr-select-fam" onchange="renderASR()"></select></div>
194
+ <div id="grp-mod" style="display:none;"><label>Select Model: </label><select id="asr-select-mod" onchange="renderASR()"></select></div>
195
+ </div>
196
+ </div>
197
 
198
+ <div style="display:flex; justify-content:space-between; align-items:end; margin-bottom:10px;">
199
+ <h3 id="asr-title" style="color:#d97706; margin:0;">Results Overview</h3>
200
+ <div id="asr-rank-info" class="rank-info">Ranking: WER (↓) then CER (↓)</div>
201
  </div>
202
+ <div id="asr-table" class="table-wrap"></div>
203
  </div>
 
 
 
 
 
 
 
204
 
205
+ <div id="tts" class="view">
206
+ <div class="controls">
207
+ <span style="font-weight:600;">Select Model:</span>
208
+ <select id="tts-select" onchange="renderTTS()"></select>
209
+ </div>
210
+ <h3 id="tts-title" style="color:#d97706; margin-bottom:10px;"></h3>
211
+ <div id="tts-summary" style="margin-bottom:20px; font-weight:600; color:#0f172a;"></div>
212
+ <div id="tts-table" class="table-wrap"></div>
213
  </div>
 
 
 
 
214
 
215
+ <div id="slid" class="view">
216
+ <div style="display:flex; justify-content:space-between; align-items:end; margin-bottom:15px;">
217
+ <h3 style="color:#d97706; margin:0;">Spoken Language Identification</h3>
218
+ <div class="rank-info">Ranking: F1-Macro (↑)</div>
219
+ </div>
220
+ <div id="slid-table" class="table-wrap"></div>
221
  </div>
 
 
222
 
223
+ <div id="lang" class="view">
224
+ <div class="controls">
225
+ <span style="font-weight:600;">Select Language:</span>
226
+ <select id="lang-select" onchange="renderLanguageView()"></select>
227
+ </div>
228
+
229
+ <h4>ASR Results <span class="rank-info" style="font-weight:normal;">(Ranked by WER ↓)</span></h4>
230
+ <div id="lang-asr-table" class="table-wrap"></div>
231
 
232
+ <h4>TTS Results</h4>
233
+ <div id="lang-tts-table" class="table-wrap"></div>
234
 
235
+ <h4>SLID Results <span class="rank-info" style="font-weight:normal;">(Ranked by Score ↑)</span></h4>
236
+ <div id="lang-slid-table" class="table-wrap"></div>
237
+ </div>
238
  </div>
239
  </div>
 
240
 
 
241
  <div class="citation-section" id="citation">
242
  <h3>Citation</h3>
243
  <button class="copy-btn" onclick="copyCitation()"><i class="fa-regular fa-copy"></i> Copy</button>
 
282
  populate('asr-select-mod', DATA.metadata.models);
283
  populate('tts-select', DATA.metadata.tts_models);
284
 
 
285
  const allLangs = new Set();
286
+ Object.values(DATA.asr.by_model).forEach(rows => rows.forEach(r => allLangs.add(r.Language)));
287
+ Object.values(DATA.tts).forEach(rows => rows.forEach(r => allLangs.add(r.language)));
 
 
 
 
 
 
 
288
  populate('lang-select', Array.from(allLangs).sort());
289
 
290
  renderASR(); renderTTS(); renderSLID();
 
319
  if(n>0) modelStats.push({ name: modName, wer: sW/n, cer: sC/n });
320
  });
321
 
322
+ // Tie-Aware Ranking
323
  modelStats.sort((a,b) => a.wer - b.wer);
324
+ let rank=1;
325
 
326
  html = `<table><thead><tr><th>Model</th><th>Simba ASR Score (WER/CER) <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
327
  modelStats.forEach((m, i) => {
328
+ if (i > 0 && Math.abs(m.wer - modelStats[i-1].wer) > 0.001) rank = i + 1;
329
+
330
+ let icon = '';
331
+ if(rank === 1) icon = 'πŸ₯‡ '; else if(rank === 2) icon = 'πŸ₯ˆ '; else if(rank === 3) icon = 'πŸ₯‰ ';
332
+
333
  html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${m.name}</td><td><b>${fmt(m.wer)} / ${fmt(m.cer)}</b></td></tr>`;
334
  });
335
 
 
343
  if(!d) return;
344
 
345
  d.data.sort((a,b) => a.Avg_WER - b.Avg_WER);
346
+ let rank=1;
347
 
348
  html = `<table><thead><tr><th>Model</th><th>Simba ASR Family Score <i class="fa-solid fa-arrow-down arrow-down"></i></th>`;
349
  d.languages.forEach(l => html += `<th>${getIso(l.name, l.iso)}</th>`);
350
  html += `</tr></thead><tbody>`;
351
 
352
  d.data.forEach((r, idx) => {
353
+ if (idx > 0 && Math.abs(r.Avg_WER - d.data[idx-1].Avg_WER) > 0.001) rank = idx + 1;
354
+ let icon = '';
355
+ if(rank === 1) icon = 'πŸ₯‡ '; else if(rank === 2) icon = 'πŸ₯ˆ '; else if(rank === 3) icon = 'πŸ₯‰ ';
356
+
357
  html += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.Model}</td><td style="font-weight:bold; background:#f8fafc">${fmt(r.Avg_WER)} / ${fmt(r.Avg_CER)}</td>`;
358
  d.languages.forEach(l => {
359
  let w=r[`WER_${l.name}`], c=r[`CER_${l.name}`];
 
368
  document.getElementById('grp-mod').style.display='inline-block';
369
 
370
  const rows = DATA.asr.by_model[val];
371
+ html = `<table><thead><tr><th>Language (iso)</th><th>Family</th><th>WER <i class="fa-solid fa-arrow-down arrow-down"></i></th><th>CER <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
372
  rows.forEach(r => {
373
  html += `<tr><td>${getIso(r.Language, r.ISO)}</td><td>${r.Family}</td><td>${fmt(r.WER)}</td><td>${fmt(r.CER)}</td></tr>`;
374
  });
 
422
  function renderLanguageView() {
423
  const lang = document.getElementById('lang-select').value;
424
 
425
+ // 1. ASR (Tie-Aware)
426
  let asrRows = [];
427
  Object.keys(DATA.asr.by_model).forEach(modName => {
428
  const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
 
430
  });
431
  asrRows.sort((a,b) => a.wer - b.wer);
432
 
433
+ let h1 = `<table><thead><tr><th>Model</th><th>WER</th><th>CER</th></tr></thead><tbody>`;
434
  if(asrRows.length === 0) h1 += `<tr><td colspan="3">No ASR data for this language.</td></tr>`;
435
+ else {
436
+ let rank = 1;
437
+ asrRows.forEach((r, i) => {
438
+ if (i > 0 && Math.abs(r.wer - asrRows[i-1].wer) > 0.001) rank = i + 1;
439
+ let icon = '';
440
+ if(rank === 1) icon = 'πŸ₯‡ '; else if(rank === 2) icon = 'πŸ₯ˆ '; else if(rank === 3) icon = 'πŸ₯‰ ';
441
+ h1 += `<tr><td style="font-weight:600; color:var(--simba-navy)">${icon}${r.model}</td><td>${fmt(r.wer)}</td><td>${fmt(r.cer)}</td></tr>`;
442
+ });
443
+ }
444
  h1 += `</tbody></table>`;
445
  document.getElementById('lang-asr-table').innerHTML = h1;
446
 
 
460
 
461
  // 3. SLID
462
  let h3 = `<table><thead><tr><th>Model</th><th>F1-Score</th></tr></thead><tbody>`;
463
+ // Fuzzy match logic
464
  const slidRow = DATA.slid.find(r => r.Language === lang) ||
465
  DATA.slid.find(r => r.Language.startsWith(lang + " (")) ||
466
  DATA.slid.find(r => r.Language.includes(lang));
467
 
468
  if(slidRow) {
469
  let m = slidRow['MMS-LID-1024'], s = slidRow['Simba-SLID'];
470
+ // Sort Descending
471
  let scores = [{n:'Simba-SLID', v:s}, {n:'MMS-LID-1024', v:m}].sort((a,b)=>b.v - a.v);
472
+ let rank = 1;
473
  scores.forEach((sc, i) => {
474
+ if (i > 0 && Math.abs(sc.v - scores[i-1].v) > 0.001) rank = i + 1;
475
+ let icon = (rank==1) ? 'πŸ₯‡ ' : '';
476
  h3 += `<tr><td style="font-weight:600;">${icon}${sc.n}</td><td>${fmt(sc.v)}</td></tr>`;
477
  });
478
  } else {