all-leaderboard / backup.html
mayafree's picture
Rename index.html to backup.html
b337911 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>πŸ† Leaderboard of Leaderboards</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=DM+Mono:wght@400;500&family=DM+Sans:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
/* ─── RESET & VARIABLES ─── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* ── LIGHT (default) ── */
:root {
--bg: #F7F6F2;
--surface: #FFFFFF;
--card: #FFFFFF;
--border: #E4E2DA;
--accent: #D4A017;
--accent2: #E8541A;
--text: #1A1A1A;
--muted: #888880;
--green: #16A34A;
--blue: #2563EB;
--pink: #DB2777;
--radius: 10px;
--shadow: 0 1px 4px rgba(0,0,0,0.08);
--grid-color: rgba(180,160,0,0.06);
}
/* ── NIGHT (dark) ── */
html.night {
--bg: #080808;
--surface: #111111;
--card: #161616;
--border: #222222;
--accent: #F5C518;
--accent2: #FF6B35;
--text: #EEEEEE;
--muted: #666666;
--green: #4ADE80;
--blue: #60A5FA;
--pink: #F472B6;
--shadow: 0 1px 6px rgba(0,0,0,0.4);
--grid-color: rgba(245,197,24,0.03);
}
/* ── Smooth theme transition ── */
body, .hero, .controls, .space-card, .podium-card, .stat-item,
.api-sort-toggle, .sort-select, #searchInput {
transition: background 0.3s ease, border-color 0.3s ease, color 0.2s ease, box-shadow 0.3s ease;
}
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--text);
font-family: 'DM Sans', sans-serif;
min-height: 100vh;
overflow-x: hidden;
}
/* ─── BACKGROUND GRID ─── */
body::before {
content: '';
position: fixed;
inset: 0;
background-image:
linear-gradient(var(--grid-color) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
background-size: 40px 40px;
pointer-events: none;
z-index: 0;
}
/* ─── HERO HEADER ─── */
.hero {
position: relative;
z-index: 1;
padding: 3rem 2rem 2rem;
text-align: center;
border-bottom: 1px solid var(--border);
}
.hero-badge {
display: inline-block;
font-family: 'DM Mono', monospace;
font-size: 0.65rem;
letter-spacing: 3px;
text-transform: uppercase;
color: var(--accent);
border: 1px solid rgba(245,197,24,0.3);
padding: 4px 14px;
border-radius: 99px;
margin-bottom: 1rem;
animation: fadeDown 0.6s ease both;
}
.hero h1 {
font-family: 'Bebas Neue', sans-serif;
font-size: clamp(3rem, 8vw, 6.5rem);
letter-spacing: 2px;
line-height: 0.95;
color: var(--text);
animation: fadeDown 0.7s 0.1s ease both;
}
.hero h1 span {
color: var(--accent);
display: block;
}
.hero-sub {
margin-top: 1rem;
font-size: 0.9rem;
color: var(--muted);
font-family: 'DM Mono', monospace;
animation: fadeDown 0.7s 0.2s ease both;
}
/* ─── STATS BAR ─── */
.stats-bar {
position: relative;
z-index: 1;
display: flex;
justify-content: center;
gap: 1.5rem;
padding: 1.5rem 2rem;
flex-wrap: wrap;
border-bottom: 1px solid var(--border);
animation: fadeDown 0.7s 0.3s ease both;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}
.stat-num {
font-family: 'Bebas Neue', sans-serif;
font-size: 2rem;
color: var(--accent);
line-height: 1;
}
.stat-label {
font-family: 'DM Mono', monospace;
font-size: 0.6rem;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 2px;
}
.stat-divider {
width: 1px;
height: 40px;
background: var(--border);
align-self: center;
}
/* ─── CONTROLS ─── */
.controls {
position: sticky;
top: 0;
z-index: 10;
display: flex;
gap: 1rem;
padding: 1.2rem 2rem;
flex-wrap: wrap;
align-items: center;
border-bottom: 1px solid var(--border);
background: rgba(247,246,242,0.92);
backdrop-filter: blur(12px);
}
html.night .controls {
background: rgba(17,17,17,0.92);
}
.search-wrap {
flex: 1;
min-width: 200px;
position: relative;
}
.search-wrap svg {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--muted);
width: 16px;
height: 16px;
}
#searchInput {
width: 100%;
background: var(--card);
border: 1px solid var(--border);
color: var(--text);
padding: 0.6rem 1rem 0.6rem 2.4rem;
border-radius: var(--radius);
font-family: 'DM Mono', monospace;
font-size: 0.8rem;
outline: none;
transition: border-color 0.2s;
}
#searchInput:focus { border-color: var(--accent); }
#searchInput::placeholder { color: var(--muted); }
.filter-pills {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.pill {
font-family: 'DM Mono', monospace;
font-size: 0.65rem;
padding: 5px 12px;
border-radius: 99px;
border: 1px solid var(--border);
background: transparent;
color: var(--muted);
cursor: pointer;
transition: all 0.15s;
white-space: nowrap;
}
.pill:hover { border-color: var(--accent); color: var(--accent); }
.pill.active { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: 500; }
.sort-select {
background: var(--card);
border: 1px solid var(--border);
color: var(--text);
padding: 0.55rem 0.8rem;
border-radius: var(--radius);
font-family: 'DM Mono', monospace;
font-size: 0.72rem;
outline: none;
cursor: pointer;
}
.refresh-btn {
background: var(--accent);
color: var(--bg);
border: none;
padding: 0.55rem 1rem;
border-radius: var(--radius);
font-family: 'DM Mono', monospace;
font-size: 0.72rem;
font-weight: 500;
cursor: pointer;
transition: opacity 0.2s;
white-space: nowrap;
display: flex;
align-items: center;
gap: 6px;
}
.refresh-btn:hover { opacity: 0.85; }
.refresh-btn.loading .spin { animation: spin 1s linear infinite; }
/* ─── API SORT TOGGLE ─── */
.api-sort-toggle {
display: flex;
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
overflow: hidden;
flex-shrink: 0;
}
.api-sort-btn {
font-family: 'DM Mono', monospace;
font-size: 0.68rem;
font-weight: 500;
padding: 0.55rem 1rem;
border: none;
background: transparent;
color: var(--muted);
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
transition: all 0.15s;
white-space: nowrap;
}
.api-sort-btn:first-child { border-right: 1px solid var(--border); }
.api-sort-btn.active { background: var(--accent); color: var(--bg); }
.api-sort-btn:not(.active):hover { color: var(--text); }
.trend-dot {
width: 6px; height: 6px;
border-radius: 50%;
background: currentColor;
flex-shrink: 0;
}
.api-sort-btn.active .trend-dot { animation: pulse 1.4s ease infinite; }
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.5); }
}
/* ─── THEME TOGGLE ─── */
.theme-btn {
font-family: 'DM Mono', monospace;
font-size: 0.72rem;
font-weight: 500;
padding: 0.55rem 0.9rem;
border-radius: var(--radius);
border: 1px solid var(--border);
background: var(--card);
color: var(--muted);
cursor: pointer;
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
transition: all 0.2s;
}
.theme-btn:hover { border-color: var(--accent); color: var(--text); }
.theme-btn .theme-icon { font-size: 1rem; line-height: 1; }
/* ─── MAIN GRID ─── */
.main {
position: relative;
z-index: 1;
max-width: 1400px;
margin: 0 auto;
padding: 1.5rem 2rem 4rem;
}
.results-info {
font-family: 'DM Mono', monospace;
font-size: 0.7rem;
color: var(--muted);
margin-bottom: 1.2rem;
}
.results-info strong { color: var(--accent); }
/* ─── TABLE HEADER ─── */
.table-header {
display: grid;
grid-template-columns: 52px 1fr 90px 130px 70px 90px;
gap: 0.5rem;
padding: 0.6rem 1rem;
font-family: 'DM Mono', monospace;
font-size: 0.6rem;
text-transform: uppercase;
letter-spacing: 1.5px;
color: var(--muted);
border-bottom: 1px solid var(--border);
margin-bottom: 0.4rem;
}
/* ─── SPACE CARD ─── */
.space-list { display: flex; flex-direction: column; gap: 4px; }
.space-card {
display: grid;
grid-template-columns: 52px 1fr 90px 130px 70px 90px;
gap: 0.5rem;
align-items: center;
padding: 0.9rem 1rem;
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow);
transition: all 0.18s ease;
cursor: pointer;
text-decoration: none;
color: inherit;
opacity: 0;
transform: translateY(6px);
animation: cardIn 0.35s ease forwards;
}
.space-card:hover {
border-color: rgba(212,160,23,0.5);
background: var(--surface);
transform: translateX(3px);
box-shadow: -3px 0 0 var(--accent), var(--shadow);
}
/* Rank */
.rank-cell {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
min-width: 52px;
gap: 2px;
}
.rank-num {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.3rem;
line-height: 1;
color: var(--muted);
}
.rank-num.top1 { color: var(--accent); font-size: 1.6rem; }
.global-rank {
font-size: 0.6rem;
font-family: 'DM Mono', monospace;
color: var(--muted);
margin-top: 3px;
letter-spacing: -0.01em;
white-space: nowrap;
text-align: center;
background: rgba(0,0,0,0.06);
border-radius: 4px;
padding: 1px 5px;
font-weight: 600;
}
html.night .global-rank { background: rgba(255,255,255,0.08); }
.rank-num.top2 { color: #C0C0C0; font-size: 1.4rem; }
.rank-num.top3 { color: #CD7F32; font-size: 1.4rem; }
/* Space info */
.space-info { min-width: 0; }
.space-name {
font-size: 0.85rem;
font-weight: 500;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 3px;
}
.space-name .org {
color: var(--muted);
font-weight: 300;
}
.space-desc {
font-size: 0.72rem;
color: var(--muted);
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-family: 'DM Mono', monospace;
line-height: 1.5;
}
/* Likes */
.likes-cell {
display: flex;
align-items: center;
gap: 5px;
font-family: 'DM Mono', monospace;
font-size: 0.8rem;
color: var(--accent);
font-weight: 500;
}
.likes-cell svg { width: 13px; height: 13px; flex-shrink: 0; }
/* Likes bar */
.likes-bar-wrap {
width: 100%;
height: 3px;
background: var(--border);
border-radius: 99px;
margin-top: 3px;
overflow: hidden;
}
.likes-bar {
height: 100%;
background: var(--accent);
border-radius: 99px;
transition: width 0.6s ease;
}
/* Category */
.cat-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-family: 'DM Mono', monospace;
font-size: 0.62rem;
padding: 3px 8px;
border-radius: 4px;
white-space: nowrap;
border: 1px solid;
}
/* SDK */
.sdk-badge {
font-family: 'DM Mono', monospace;
font-size: 0.62rem;
color: var(--muted);
text-align: center;
}
/* Visit btn */
.visit-btn {
display: inline-flex;
align-items: center;
gap: 5px;
font-family: 'DM Mono', monospace;
font-size: 0.65rem;
padding: 5px 10px;
border-radius: 6px;
border: 1px solid var(--border);
color: var(--muted);
background: transparent;
text-decoration: none;
transition: all 0.15s;
white-space: nowrap;
}
.visit-btn:hover {
border-color: var(--accent);
color: var(--accent);
background: rgba(245,197,24,0.05);
}
/* ─── TOP 3 PODIUM ─── */
.podium {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin-bottom: 2rem;
}
.podium-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 1.2rem;
text-align: center;
position: relative;
overflow: hidden;
text-decoration: none;
color: inherit;
display: block;
transition: transform 0.2s;
}
.podium-card:hover { transform: translateY(-3px); }
.podium-card.gold { border-color: rgba(245,197,24,0.5); }
.podium-card.silver { border-color: rgba(192,192,192,0.4); }
.podium-card.bronze { border-color: rgba(205,127,50,0.4); }
.podium-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
}
.podium-card.gold::before { background: var(--accent); }
.podium-card.silver::before { background: #C0C0C0; }
.podium-card.bronze::before { background: #CD7F32; }
.podium-medal {
font-size: 2rem;
display: block;
margin-bottom: 0.5rem;
}
.podium-name {
font-size: 0.8rem;
font-weight: 600;
color: var(--text);
word-break: break-all;
margin-bottom: 0.4rem;
}
.podium-likes {
font-family: 'Bebas Neue', sans-serif;
font-size: 1.5rem;
color: var(--accent);
}
.podium-likes-label {
font-family: 'DM Mono', monospace;
font-size: 0.6rem;
color: var(--muted);
display: block;
}
/* ─── CATEGORY COLORS ─── */
.cat--llm { color: #60A5FA; border-color: rgba(96,165,250,0.25); background: rgba(96,165,250,0.07); }
.cat--code { color: #4ADE80; border-color: rgba(74,222,128,0.25); background: rgba(74,222,128,0.07); }
.cat--multi { color: #F472B6; border-color: rgba(244,114,182,0.25); background: rgba(244,114,182,0.07); }
.cat--agent { color: #FB923C; border-color: rgba(251,146,60,0.25); background: rgba(251,146,60,0.07); }
.cat--agi { color: #F5C518; border-color: rgba(245,197,24,0.35); background: rgba(245,197,24,0.08); }
.cat--chat { color: #A78BFA; border-color: rgba(167,139,250,0.25); background: rgba(167,139,250,0.07); }
.cat--science { color: #34D399; border-color: rgba(52,211,153,0.25); background: rgba(52,211,153,0.07); }
.cat--gen { color: #F87171; border-color: rgba(248,113,113,0.25); background: rgba(248,113,113,0.07); }
.cat--safety { color: #FCD34D; border-color: rgba(252,211,77,0.25); background: rgba(252,211,77,0.07); }
.cat--etc { color: var(--muted); border-color: var(--border); background: transparent; }
/* ─── LOADING ─── */
.loading-screen {
position: fixed;
inset: 0;
background: var(--bg);
z-index: 100;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
transition: opacity 0.5s, visibility 0.5s;
}
.loading-screen.hidden { opacity: 0; visibility: hidden; }
.loading-logo {
font-family: 'Bebas Neue', sans-serif;
font-size: 4rem;
color: var(--accent);
letter-spacing: 3px;
}
.loading-bar {
width: 200px;
height: 2px;
background: var(--border);
border-radius: 99px;
overflow: hidden;
}
.loading-bar-inner {
height: 100%;
background: var(--accent);
border-radius: 99px;
animation: loadBar 1.8s ease-in-out infinite;
}
.loading-text {
font-family: 'DM Mono', monospace;
font-size: 0.7rem;
color: var(--muted);
}
/* ─── EMPTY / ERROR ─── */
.empty-state {
text-align: center;
padding: 4rem 2rem;
color: var(--muted);
}
.empty-state .icon { font-size: 3rem; margin-bottom: 1rem; }
.empty-state p { font-family: 'DM Mono', monospace; font-size: 0.8rem; }
/* ─── FOOTER ─── */
.footer {
position: relative;
z-index: 1;
text-align: center;
padding: 2rem;
border-top: 1px solid var(--border);
font-family: 'DM Mono', monospace;
font-size: 0.65rem;
color: var(--muted);
}
.footer a { color: var(--accent); text-decoration: none; }
/* ─── ANIMATIONS ─── */
@keyframes fadeDown {
from { opacity: 0; transform: translateY(-12px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes cardIn {
to { opacity: 1; transform: translateY(0); }
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes loadBar {
0% { width: 0%; margin-left: 0; }
50% { width: 70%; margin-left: 0; }
100% { width: 0%; margin-left: 100%; }
}
/* ─── RESPONSIVE ─── */
@media (max-width: 900px) {
.table-header { display: none; }
.space-card {
grid-template-columns: 40px 1fr 70px;
grid-template-rows: auto auto;
}
.space-card .likes-cell { order: 3; }
.space-card .cat-badge,
.space-card .sdk-badge,
.space-card .visit-btn { display: none; }
.space-desc { display: none; }
.podium { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
.hero h1 { font-size: 3rem; }
.controls { flex-direction: column; }
.main { padding: 1rem; }
}
</style>
</head>
<body>
<!-- Loading screen -->
<div class="loading-screen" id="loadingScreen">
<div class="loading-logo">LoL</div>
<div class="loading-bar"><div class="loading-bar-inner"></div></div>
<div class="loading-text">Connecting to HuggingFace API...</div>
</div>
<!-- Hero -->
<header class="hero">
<div class="hero-badge">πŸ€— HuggingFace Spaces Β· Live Data</div>
<h1>Leaderboard<span>of Leaderboards</span></h1>
<p class="hero-sub">Ranking the most popular AI benchmark leaderboards on HuggingFace Β· Sorted by Likes</p>
</header>
<!-- Stats -->
<div class="stats-bar" id="statsBar">
<div class="stat-item">
<span class="stat-num" id="statTotal">β€”</span>
<span class="stat-label">Total Leaderboards</span>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<span class="stat-num" id="statLikes">β€”</span>
<span class="stat-label">Total Likes</span>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<span class="stat-num" id="statTop">β€”</span>
<span class="stat-label">Top Likes</span>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<span class="stat-num" id="statUpdated">β€”</span>
<span class="stat-label">Last Fetched</span>
</div>
</div>
<!-- Controls -->
<div class="controls" id="controls">
<div class="search-wrap">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
<input type="text" id="searchInput" placeholder="Search by space name or description..." autocomplete="off"/>
</div>
<!-- API Sort Toggle: Trending vs Likes (re-fetches) -->
<div class="api-sort-toggle">
<button class="api-sort-btn active" id="btnTrending" onclick="setApiSort('trending')">
<span class="trend-dot"></span> Trending
</button>
<button class="api-sort-btn" id="btnLikes" onclick="setApiSort('likes')">
❀️ Most Liked
</button>
</div>
<div class="filter-pills" id="filterPills">
<button class="pill active" data-cat="all">All</button>
<button class="pill" data-cat="llm">🧠 LLM</button>
<button class="pill" data-cat="code">πŸ’» Coding</button>
<button class="pill" data-cat="multi">πŸ‘οΈ Multimodal</button>
<button class="pill" data-cat="agent">πŸ€– Agents</button>
<button class="pill" data-cat="agi">πŸ† AGI</button>
<button class="pill" data-cat="chat">πŸ’¬ Chat</button>
<button class="pill" data-cat="science">πŸ”¬ Reasoning</button>
<button class="pill" data-cat="gen">🎨 Generative</button>
<button class="pill" data-cat="safety">πŸ›‘οΈ Safety</button>
</div>
<select class="sort-select" id="sortSelect">
<option value="api">β€” Secondary Sort β€”</option>
<option value="name">πŸ”€ Name A–Z</option>
<option value="updated">πŸ“… Recently Updated</option>
</select>
<button class="refresh-btn" id="refreshBtn" onclick="fetchData(true)">
<svg class="spin" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
<path d="M21 2v6h-6M3 12a9 9 0 0115-6.7L21 8M3 22v-6h6M21 12a9 9 0 01-15 6.7L3 16"/>
</svg>
Refresh
</button>
<button class="theme-btn" id="themeBtn" onclick="toggleTheme()">
<span class="theme-icon" id="themeIcon">πŸŒ™</span>
<span id="themeLabel">Night</span>
</button>
</div>
<!-- Main content -->
<main class="main">
<div class="results-info" id="resultsInfo"></div>
<!-- Top 3 podium -->
<div class="podium" id="podium"></div>
<!-- Table header -->
<div class="table-header">
<span>Rank</span>
<span>Space / Description</span>
<span>❀️ Likes</span>
<span>Category</span>
<span>SDK</span>
<span>Visit</span>
</div>
<!-- Cards -->
<div class="space-list" id="spaceList"></div>
</main>
<footer class="footer">
Data source: <a href="https://huggingface.co/api/spaces" target="_blank">HuggingFace Hub API</a>
&nbsp;Β·&nbsp;
Built by <a href="https://huggingface.co/FINAL-Bench" target="_blank">FINAL-Bench</a>
&nbsp;Β·&nbsp;
<span id="footerTime"></span>
</footer>
<script>
// ─── CONFIG ───────────────────────────────────────────────────────
const HF_API = 'https://huggingface.co/api/spaces';
const LIMIT = 100;
const CATEGORIES = {
llm: { label: '🧠 LLM', cls: 'cat--llm', keys: ['open-llm','lm-evaluation','llm-bench','language-model','text-generation','instruct','chat','gpt','llama','mistral','gemma','qwen','phi'] },
code: { label: 'πŸ’» Coding', cls: 'cat--code', keys: ['code','human-eval','coding','swe','bigcode','programming','coder','leetcode','benchmark-code'] },
multi: { label: 'πŸ‘οΈ Multimodal', cls: 'cat--multi', keys: ['vision','multimodal','vqa','vlm','mmmu','image-understanding','visual','mmbench'] },
agent: { label: 'πŸ€– Agents', cls: 'cat--agent', keys: ['agent','tool-use','function-call','web-agent','task','swe-bench','agentic','worldcup','tournament','smol'] },
agi: { label: 'πŸ† AGI / Meta', cls: 'cat--agi', keys: ['agi','final','frontier','meta','general','arc','gpqa','mmlu','hellaswag','winogrande'] },
chat: { label: 'πŸ’¬ Chat / Pref', cls: 'cat--chat', keys: ['arena','chatbot','preference','reward','rlhf','dpo','alignment','mt-bench','lmarena'] },
science: { label: 'πŸ”¬ Reasoning', cls: 'cat--science', keys: ['math','reasoning','science','stem','logic','math-bench','gsm','minerva','physic'] },
gen: { label: '🎨 Generative', cls: 'cat--gen', keys: ['image-gen','text-to-image','video','diffusion','stable','dalle','midjourney','flux','text2image','generation','tts','speech','voice','music'] },
safety: { label: 'πŸ›‘οΈ Safety', cls: 'cat--safety', keys: ['safety','bias','toxic','harm','red-team','trustworthy','honest','truthful','hallucin'] },
};
const MEDALS = ['πŸ₯‡','πŸ₯ˆ','πŸ₯‰'];
// ─── CURATED DESCRIPTION DATABASE ───────────────────────────────
// Overrides empty/weak API descriptions for well-known leaderboards
const DESC_DB = {
// ── LLM General ──
'open-llm-leaderboard/open_llm_leaderboard':
'The #1 open LLM benchmark by HuggingFace. Evaluates on IFEval, BBH, MATH, GPQA, MUSR, MMLU-Pro. The gold standard for ranking open-source models.',
'HuggingFaceH4/open_llm_leaderboard':
'Original Open LLM Leaderboard (v1) by HuggingFace. Evaluated on ARC, HellaSwag, TruthfulQA, MMLU. Retired but historically significant.',
'lmarena-ai/arena-leaderboard':
'LMArena (formerly Chatbot Arena) official leaderboard. ELO ratings computed from 1M+ human preference votes. Crowdsourced ground truth for LLM quality.',
'lmarena-ai/chatbot-arena-leaderboard':
'Chatbot Arena leaderboard by LMSYS/UC Berkeley. Ranks models via ELO from blind pairwise human votes. Covers MT-Bench and MMLU alongside Arena scores.',
'lmarena-ai/chatbot-arena':
'Live Chatbot Arena by lmarena-ai. Compare any two LLMs head-to-head and vote on the winner. Powers the most human-validated LLM ranking on the internet.',
'ArtificialAnalysis/LLM-Performance-Leaderboard':
'ArtificialAnalysis LLM benchmark: quality, speed, price, and context length across GPT-4, Claude, Gemini, Llama, and 60+ models. Best for cost-performance decisions.',
'allenai/WildBench':
'WildBench v2 by AI2. Evaluates LLMs on 1024 challenging real-world tasks with GPT-4-as-judge, using win-rate over GPT-4-turbo as the scoring baseline.',
// ── Coding ──
'bigcode/bigcodebench-leaderboard':
'BigCodeBench: 1,140 function-level coding tasks across 139 libraries. Tests real-world tool use and multi-library composition. Pass@1 with greedy decoding.',
'bigcode/bigcode-models-leaderboard':
'Big Code Models Leaderboard by BigCode. Ranks open-source code LLMs on HumanEval and MultiPL-E across 18 programming languages. Includes throughput benchmarks.',
'livecodebench/leaderboard':
'LiveCodeBench: contamination-free coding eval using problems from LeetCode, AtCoder, and CodeForces with release-date filtering. Tests code gen, self-repair, and execution.',
'EvalPlus/leaderboard':
'EvalPlus leaderboard: rigorous HumanEval+ and MBPP+ evaluations with 80Γ— more test cases than the originals. Exposes model weaknesses hidden by weak test suites.',
// ── Embedding / Retrieval ──
'mteb/leaderboard':
'MTEB: Massive Text Embedding Benchmark. 58 datasets Γ— 112 languages Γ— 8 task types (retrieval, clustering, classification, STS…). The definitive embedding model ranking.',
// ── Multimodal ──
'ArtificialAnalysis/Text-to-Image-Leaderboard':
'ArtificialAnalysis Image Arena & Leaderboard. Ranks text-to-image models (DALL-E 3, Midjourney, Flux, SD3…) by quality, speed, and price from human preference votes.',
'ArtificialAnalysis/Video-Generation-Arena-Leaderboard':
'ArtificialAnalysis Video Arena. Ranks text-to-video and image-to-video models (Sora, Runway, Kling…) by quality and human preference votes.',
// ── Speech / Audio ──
'ArtificialAnalysis/Speech-Arena-Leaderboard':
'ArtificialAnalysis TTS Arena. Ranks text-to-speech systems (ElevenLabs, OpenAI TTS, PlayHT…) by naturalness and quality from human preference votes.',
'ArtificialAnalysis/Music-Arena-Leaderboard':
'ArtificialAnalysis Music Arena. Community votes rank AI music generators (Suno, Udio, Google MusicLM…) on creativity, quality, and coherence.',
'TTS-AGI/TTS-Arena':
'TTS Arena: blind pairwise voting leaderboard for text-to-speech models. ELO-rated from thousands of human votes. The Chatbot Arena equivalent for voice AI.',
// ── Chat / Preference / RLHF ──
'allenai/reward-bench':
'RewardBench by AI2: evaluates reward models across Chat, Chat-Hard, Safety, and Reasoning categories. Essential for RLHF / DPO practitioners choosing reward models.',
// ── AGI / Meta ──
'FINAL-Bench/all-bench-leaderboard':
'ALL Bench Leaderboard by FINAL-Bench. Aggregates 91 AI models across multiple benchmarks into a unified metacognitive ranking. Meta-evaluation of AGI progress.',
'FINAL-Bench/Leaderboard':
'FINAL Bench Metacognitive Leaderboard. World\'s first benchmark measuring AI self-correction ability. 100 tasks Γ— 15 domains Γ— 8 TICOS types. HuggingFace Global Top 5 dataset.',
// ── Small / Efficient Models ──
'ginigen-ai/smol-worldcup':
'Smol AI WorldCup by Ginigen AI. Tournament platform for small models (≀8B params). Auto-scored with FINAL Bench. Open competition with live leaderboard and public dataset.',
};
// ─── STATE ──────────────────────────────────────────────────────
let allData = [];
let filtered = [];
let activecat = 'all';
let sortMode = 'api'; // 'api' | 'name' | 'updated'
let apiSort = 'trending'; // 'trending' | 'likes' β†’ triggers re-fetch
let searchQ = '';
let maxLikes = 1;
// ─── API SORT TOGGLE ─────────────────────────────────────────────
function setApiSort(mode) {
if (apiSort === mode) return;
apiSort = mode;
document.getElementById('btnTrending').classList.toggle('active', mode === 'trending');
document.getElementById('btnLikes').classList.toggle('active', mode === 'likes');
// Reset secondary sort to api order
document.getElementById('sortSelect').value = 'api';
sortMode = 'api';
fetchData(true);
}
// ─── CATEGORY DETECTION ─────────────────────────────────────────
function detectCategory(id, tags, desc) {
const text = (id + ' ' + (tags||[]).join(' ') + ' ' + (desc||'')).toLowerCase();
for (const [key, cat] of Object.entries(CATEGORIES)) {
if (cat.keys.some(k => text.includes(k))) return key;
}
return 'etc';
}
// ─── FETCH DATA ──────────────────────────────────────────────────
async function fetchData(forceRefresh = false) {
const btn = document.getElementById('refreshBtn');
btn.classList.add('loading');
showLoading(true);
try {
const params = new URLSearchParams({
search: 'leaderboard',
limit: LIMIT,
full: 'true',
direction: '-1',
});
// Trending = sort=trendingScore&direction=-1
// Most Liked = sort=likes&direction=-1
params.set('sort', apiSort === 'trending' ? 'trendingScore' : 'likes');
const res = await fetch(`${HF_API}?${params}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
// 항상 포함할 슀페이슀 (검색어에 μ•ˆ μž‘νžˆλŠ” 것듀)
// β†’ κ°œλ³„ /api/spaces/:id λŠ” trendingScore λ―Έλ°˜ν™˜ β†’ author κ²€μƒ‰μœΌλ‘œ trendingScore 확보
const PINNED_SPACES = [
{ id: 'ginigen-ai/smol-worldcup', author: 'ginigen-ai', name: 'smol-worldcup' },
{ id: 'lmarena-ai/chatbot-arena', author: 'lmarena-ai', name: 'chatbot-arena' },
{ id: 'TTS-AGI/TTS-Arena', author: 'TTS-AGI', name: 'TTS-Arena' },
];
const pinnedResults = await Promise.all(PINNED_SPACES.map(async ({ id, author, name }) => {
// 이미 메인 검색에 ν¬ν•¨λœ 경우 μŠ€ν‚΅
if (json.some(s => s.id === id)) return null;
try {
// author κ²€μƒ‰μœΌλ‘œ trendingScore ν¬ν•¨λœ 데이터 확보
const r = await fetch(
`${HF_API}?author=${author}&search=${name}&sort=trendingScore&direction=-1&limit=5&full=true`
);
if (!r.ok) return null;
const arr = await r.json();
return arr.find(s => s.id === id) || null;
} catch { return null; }
}));
// 쀑볡 제거 ν›„ 병합
const existingIds = new Set(json.map(s => s.id));
const toMerge = pinnedResults.filter(s => s && !existingIds.has(s.id));
let merged = [...json, ...toMerge];
// μ •λ ¬
if (apiSort === 'likes') {
merged.sort((a, b) => (b.likes || 0) - (a.likes || 0));
} else {
merged.sort((a, b) => (b.trendingScore ?? -1) - (a.trendingScore ?? -1));
}
// ── κΈ€λ‘œλ²Œ μ‹€μ‹œκ°„ μˆœμœ„ λ§΅ ꡬ좕 ──────────────────────────────────
let globalRankMap = {};
try {
const gSort = apiSort === 'trending' ? 'trendingScore' : 'likes';
const gRes = await fetch(`${HF_API}?sort=${gSort}&direction=-1&limit=1000`);
if (gRes.ok) {
const gList = await gRes.json();
gList.forEach((s, i) => { globalRankMap[s.id] = i + 1; });
}
} catch (e) { /* μ‹€νŒ¨ μ‹œ λ¬΄μ‹œ */ }
allData = merged.map((s) => {
const id = s.id || '';
const tags = s.tags || [];
const card = s.cardData || {};
const apiDesc = card.short_description || s.shortDescription || '';
const desc = DESC_DB[id] || apiDesc;
return {
id,
likes: s.likes || 0,
sdk: s.sdk || '',
updated: (s.lastModified || '').slice(0, 10),
desc,
tags,
category: detectCategory(id, tags, desc),
url: `https://huggingface.co/spaces/${id}`,
globalRank: globalRankMap[id] || null,
};
});
maxLikes = Math.max(...allData.map(d => d.likes), 1);
updateStats();
applyFilters();
renderPodium();
document.getElementById('footerTime').textContent =
'Last updated: ' + new Date().toLocaleString('en-US');
} catch (e) {
document.getElementById('spaceList').innerHTML = `
<div class="empty-state">
<div class="icon">⚠️</div>
<p>Failed to load data.<br>${e.message}</p>
</div>`;
console.error(e);
} finally {
btn.classList.remove('loading');
showLoading(false);
}
}
// ─── STATS ───────────────────────────────────────────────────────
function updateStats() {
const total = allData.length;
const totalLikes = allData.reduce((s, d) => s + d.likes, 0);
const topLikes = maxLikes;
animateNum('statTotal', total);
animateNum('statLikes', totalLikes);
animateNum('statTop', topLikes);
document.getElementById('statUpdated').textContent =
new Date().toLocaleTimeString('en-US', {hour:'2-digit', minute:'2-digit'});
}
function animateNum(id, target) {
const el = document.getElementById(id);
const duration = 800, fps = 60;
const steps = duration / (1000 / fps);
let current = 0;
const inc = target / steps;
const timer = setInterval(() => {
current = Math.min(current + inc, target);
el.textContent = Math.round(current).toLocaleString();
if (current >= target) clearInterval(timer);
}, 1000 / fps);
}
// ─── FILTERS ─────────────────────────────────────────────────────
function applyFilters() {
filtered = allData.filter(d => {
if (activecat !== 'all' && d.category !== activecat) return false;
if (searchQ) {
const q = searchQ.toLowerCase();
if (!d.id.toLowerCase().includes(q) && !d.desc.toLowerCase().includes(q)) return false;
}
return true;
});
// Sort
if (sortMode === 'name') filtered.sort((a,b) => a.id.localeCompare(b.id));
else if (sortMode === 'updated') filtered.sort((a,b) => b.updated.localeCompare(a.updated));
// 'api': preserve the order returned by HF API (trending or likes)
renderList();
updateResultsInfo();
}
function updateResultsInfo() {
const el = document.getElementById('resultsInfo');
const modeLabel = apiSort === 'trending' ? 'πŸ”₯ Trending' : '❀️ Most Liked';
el.innerHTML = `Showing <strong>${filtered.length}</strong> of ${allData.length} leaderboards &nbsp;Β·&nbsp; ${modeLabel}`;
}
// ─── PODIUM ──────────────────────────────────────────────────────
function renderPodium() {
const top3 = allData.slice(0, 3);
const colors = ['gold','silver','bronze'];
const podium = document.getElementById('podium');
podium.innerHTML = top3.map((d, i) => {
const parts = d.id.split('/');
const name = parts[parts.length - 1];
return `
<a class="podium-card ${colors[i]}" href="${d.url}" target="_blank">
<span class="podium-medal">${MEDALS[i]}</span>
<div class="podium-name">${d.id}</div>
<div class="podium-likes">${d.likes.toLocaleString()}</div>
<span class="podium-likes-label">❀️ Likes</span>
${d.desc ? `<div style="font-size:0.7rem;color:var(--muted);margin-top:0.5rem;font-family:'DM Mono',monospace">${d.desc.slice(0,60)}${d.desc.length>60?'…':''}</div>` : ''}
</a>`;
}).join('');
}
// ─── RENDER LIST ─────────────────────────────────────────────────
function renderList() {
const list = document.getElementById('spaceList');
if (filtered.length === 0) {
list.innerHTML = `<div class="empty-state"><div class="icon">πŸ”</div><p>No results found.</p></div>`;
return;
}
list.innerHTML = filtered.slice(0, 80).map((d, idx) => {
const rank = idx + 1;
const parts = d.id.split('/');
const org = parts.length > 1 ? parts[0] : '';
const name = parts[parts.length - 1];
const cat = CATEGORIES[d.category] || { label: 'πŸ“‹ Other', cls: 'cat--etc' };
const likesPct = Math.round((d.likes / maxLikes) * 100);
const sdkIcon = { gradio:'πŸŽ›οΈ', streamlit:'🌊', docker:'🐳', static:'πŸ“„' }[d.sdk] || '❓';
const rankCls = rank === 1 ? 'top1' : rank === 2 ? 'top2' : rank === 3 ? 'top3' : '';
const delay = Math.min(idx * 0.025, 1.5);
return `
<a class="space-card" href="${d.url}" target="_blank" style="animation-delay:${delay}s">
<div class="rank-cell">
<div class="rank-num ${rankCls}">${rank <= 3 ? MEDALS[rank-1] : rank}</div>
${d.globalRank
? `<div class="global-rank">HF #${d.globalRank.toLocaleString()}</div>`
: `<div class="global-rank" style="opacity:0.3">β€”</div>`}
</div>
<div class="space-info">
<div class="space-name">
${org ? `<span class="org">${org}/</span>` : ''}${name}
</div>
${d.desc
? `<div class="space-desc">${d.desc}</div>`
: `<div class="space-desc" style="color:#333">No description</div>`}
</div>
<div class="likes-cell" style="flex-direction:column;align-items:flex-start;gap:3px">
<span style="display:flex;align-items:center;gap:4px">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
${d.likes.toLocaleString()}
</span>
<div class="likes-bar-wrap" style="width:80px">
<div class="likes-bar" style="width:${likesPct}%"></div>
</div>
</div>
<div>
<span class="cat-badge ${cat.cls}">${cat.label}</span>
</div>
<div class="sdk-badge">${sdkIcon} ${d.sdk || 'β€”'}</div>
<span class="visit-btn">Visit β†’</span>
</a>`;
}).join('');
}
// ─── EVENT LISTENERS ─────────────────────────────────────────────
document.getElementById('filterPills').addEventListener('click', e => {
const btn = e.target.closest('.pill');
if (!btn) return;
document.querySelectorAll('.pill').forEach(p => p.classList.remove('active'));
btn.classList.add('active');
activecat = btn.dataset.cat;
applyFilters();
});
document.getElementById('searchInput').addEventListener('input', e => {
searchQ = e.target.value;
applyFilters();
});
document.getElementById('sortSelect').addEventListener('change', e => {
sortMode = e.target.value; // 'api' | 'name' | 'updated'
applyFilters();
});
// ─── INIT ────────────────────────────────────────────────────────
fetchData();
function showLoading(show) {
const el = document.getElementById('loadingScreen');
if (show) el.classList.remove('hidden');
else setTimeout(() => el.classList.add('hidden'), 400);
}
// ─── THEME ───────────────────────────────────────────────────────
function toggleTheme() {
const isNight = document.documentElement.classList.toggle('night');
document.getElementById('themeIcon').textContent = isNight ? 'β˜€οΈ' : 'πŸŒ™';
document.getElementById('themeLabel').textContent = isNight ? 'Light' : 'Night';
localStorage.setItem('lol-theme', isNight ? 'night' : 'light');
}
// Apply saved theme on load (default: light)
(function() {
const saved = localStorage.getItem('lol-theme');
if (saved === 'night') {
document.documentElement.classList.add('night');
// update button after DOM loads
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('themeIcon').textContent = 'β˜€οΈ';
document.getElementById('themeLabel').textContent = 'Light';
});
}
})();
</script>
</body>
</html>