Spaces:
Running
Running
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Live WebApp Viewer</title> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap'); | |
| :root { | |
| --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
| --accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
| --dark-bg: #0a0a0a; | |
| --card-bg: #ffffff; | |
| --text-primary: #1a1a1a; | |
| --text-secondary: #666666; | |
| --text-muted: #888888; | |
| --border-color: #e5e7eb; | |
| --shadow-sm: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); | |
| --shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 1px 3px rgba(0,0,0,0.06); | |
| --shadow-lg: 0 10px 25px rgba(0,0,0,0.1), 0 4px 10px rgba(0,0,0,0.06); | |
| --shadow-xl: 0 20px 40px rgba(0,0,0,0.1), 0 8px 20px rgba(0,0,0,0.08); | |
| --border-radius: 16px; | |
| --border-radius-sm: 12px; | |
| --border-radius-lg: 24px; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 0; | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| color: var(--text-primary); | |
| line-height: 1.6; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| } | |
| .container { | |
| width: 100vw; | |
| padding: 20px; | |
| box-sizing: border-box; | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| } | |
| .loading { | |
| text-align: center; | |
| padding: 80px 20px; | |
| font-size: 18px; | |
| color: var(--text-secondary); | |
| font-weight: 500; | |
| } | |
| /* Main Title Section */ | |
| .main-title { | |
| text-align: center; | |
| margin-bottom: 40px; | |
| padding: 0 20px; | |
| } | |
| .main-title h1 { | |
| font-size: clamp(36px, 8vw, 64px); | |
| font-weight: 900; | |
| margin: 0 0 16px 0; | |
| letter-spacing: -2px; | |
| background: var(--primary-gradient); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| position: relative; | |
| } | |
| .main-title h1::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: -8px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 60px; | |
| height: 4px; | |
| background: var(--accent-gradient); | |
| border-radius: 2px; | |
| } | |
| .main-title p { | |
| font-size: clamp(16px, 4vw, 22px); | |
| margin: 0 0 20px 0; | |
| color: var(--text-secondary); | |
| font-weight: 400; | |
| line-height: 1.5; | |
| max-width: 600px; | |
| margin-left: auto; | |
| margin-right: auto; | |
| } | |
| .aisheets-credit { | |
| font-size: 14px; | |
| color: var(--text-muted); | |
| margin-top: 16px; | |
| font-weight: 500; | |
| } | |
| .aisheets-credit a { | |
| color: #667eea; | |
| text-decoration: none; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| padding: 4px 8px; | |
| border-radius: 6px; | |
| background: rgba(102, 126, 234, 0.1); | |
| } | |
| .aisheets-credit a:hover { | |
| color: #764ba2; | |
| background: rgba(118, 75, 162, 0.1); | |
| transform: translateY(-1px); | |
| } | |
| /* Stats Header */ | |
| .stats-header { | |
| background: var(--card-bg); | |
| color: var(--text-primary); | |
| padding: 40px 30px; | |
| text-align: center; | |
| margin-bottom: 40px; | |
| border-radius: var(--border-radius-lg); | |
| box-shadow: var(--shadow-xl); | |
| border: 1px solid rgba(255,255,255,0.8); | |
| backdrop-filter: blur(20px); | |
| } | |
| .stats-header p { | |
| font-size: 16px; | |
| margin: 0 0 30px 0; | |
| color: var(--text-secondary); | |
| font-weight: 500; | |
| line-height: 1.6; | |
| } | |
| .win-stats { | |
| display: flex; | |
| justify-content: center; | |
| gap: 30px; | |
| margin-top: 30px; | |
| flex-wrap: wrap; | |
| } | |
| .stat { | |
| font-size: 16px; | |
| background: var(--primary-gradient); | |
| padding: 20px 30px; | |
| border-radius: var(--border-radius-sm); | |
| color: white; | |
| box-shadow: var(--shadow-md); | |
| transition: all 0.3s ease; | |
| border: 1px solid rgba(255,255,255,0.2); | |
| } | |
| .stat:hover { | |
| transform: translateY(-2px); | |
| box-shadow: var(--shadow-lg); | |
| } | |
| .stat .model { | |
| font-weight: 600; | |
| display: block; | |
| margin-bottom: 8px; | |
| font-size: 14px; | |
| opacity: 0.9; | |
| } | |
| .stat .wins { | |
| color: #4ade80; | |
| font-weight: 800; | |
| font-size: 24px; | |
| text-shadow: 0 1px 2px rgba(0,0,0,0.1); | |
| } | |
| /* TOC Section */ | |
| .toc-container { | |
| background: var(--card-bg); | |
| border-radius: var(--border-radius-lg); | |
| box-shadow: var(--shadow-xl); | |
| margin-bottom: 40px; | |
| padding: 30px; | |
| border: 1px solid rgba(255,255,255,0.8); | |
| backdrop-filter: blur(20px); | |
| } | |
| .toc-title { | |
| font-size: 20px; | |
| font-weight: 700; | |
| margin-bottom: 20px; | |
| color: var(--text-primary); | |
| text-align: center; | |
| cursor: pointer; | |
| user-select: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 12px; | |
| padding: 12px; | |
| border-radius: var(--border-radius-sm); | |
| transition: all 0.3s ease; | |
| } | |
| .toc-title:hover { | |
| background: rgba(102, 126, 234, 0.1); | |
| color: #667eea; | |
| transform: translateY(-1px); | |
| } | |
| .toc-content { | |
| transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); | |
| overflow: hidden; | |
| } | |
| .toc-content.collapsed { | |
| max-height: 0; | |
| margin-bottom: 0; | |
| } | |
| .toc-content.expanded { | |
| max-height: none; | |
| margin-bottom: 20px; | |
| } | |
| .toc-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); | |
| gap: 16px; | |
| } | |
| .toc-item { | |
| background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); | |
| border: 1px solid var(--border-color); | |
| border-radius: var(--border-radius-sm); | |
| padding: 20px; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| text-decoration: none; | |
| color: inherit; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .toc-item::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 3px; | |
| background: var(--accent-gradient); | |
| transform: scaleX(0); | |
| transition: transform 0.3s ease; | |
| } | |
| .toc-item:hover { | |
| background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%); | |
| border-color: #667eea; | |
| transform: translateY(-4px); | |
| box-shadow: var(--shadow-lg); | |
| } | |
| .toc-item:hover::before { | |
| transform: scaleX(1); | |
| } | |
| .toc-number { | |
| font-weight: 700; | |
| color: #667eea; | |
| margin-right: 12px; | |
| font-size: 16px; | |
| } | |
| .toc-description { | |
| font-size: 15px; | |
| line-height: 1.5; | |
| display: -webkit-box; | |
| -webkit-line-clamp: 2; | |
| -webkit-box-orient: vertical; | |
| overflow: hidden; | |
| font-weight: 500; | |
| } | |
| /* App Sections */ | |
| .app-section { | |
| margin-bottom: 40px; | |
| background: var(--card-bg); | |
| border-radius: var(--border-radius-lg); | |
| box-shadow: var(--shadow-xl); | |
| overflow: hidden; | |
| border: 1px solid rgba(255,255,255,0.8); | |
| backdrop-filter: blur(20px); | |
| transition: all 0.3s ease; | |
| } | |
| .app-section:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 25px 50px rgba(0,0,0,0.15), 0 10px 25px rgba(0,0,0,0.1); | |
| } | |
| .description-header { | |
| background: var(--primary-gradient); | |
| color: white; | |
| padding: 25px 20px; | |
| text-align: center; | |
| font-size: 18px; | |
| font-weight: 700; | |
| letter-spacing: -0.3px; | |
| position: relative; | |
| } | |
| .description-header::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| right: 0; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
| } | |
| /* Evaluation Section */ | |
| .evaluation-section { | |
| background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); | |
| border-bottom: 1px solid var(--border-color); | |
| padding: 20px; | |
| } | |
| .evaluation-result { | |
| background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%); | |
| border: 1px solid #86efac; | |
| border-radius: var(--border-radius-sm); | |
| padding: 20px; | |
| margin-bottom: 15px; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .eval-label { | |
| font-size: 12px; | |
| color: var(--text-muted); | |
| margin-bottom: 8px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| .winner { | |
| color: #166534; | |
| font-weight: 800; | |
| margin-bottom: 8px; | |
| font-size: 16px; | |
| } | |
| .reason { | |
| color: #166534; | |
| font-weight: 500; | |
| } | |
| .view-eval-btn { | |
| background: var(--primary-gradient); | |
| color: white; | |
| border: none; | |
| padding: 8px 16px; | |
| border-radius: var(--border-radius-sm); | |
| cursor: pointer; | |
| margin-top: 12px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| } | |
| .view-eval-btn:hover { | |
| transform: translateY(-1px); | |
| box-shadow: var(--shadow-md); | |
| } | |
| .full-evaluation { | |
| background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
| border: 1px solid #fbbf24; | |
| border-radius: var(--border-radius-sm); | |
| padding: 20px; | |
| margin-top: 15px; | |
| display: none; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .thinking-content { | |
| max-height: 300px; | |
| overflow-y: auto; | |
| font-size: 14px; | |
| line-height: 1.6; | |
| white-space: pre-wrap; | |
| text-align: left; | |
| color: #92400e; | |
| font-weight: 500; | |
| } | |
| /* Implementation Panels */ | |
| .implementations { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 0; | |
| } | |
| .impl-panel { | |
| border-right: 1px solid var(--border-color); | |
| position: relative; | |
| } | |
| .impl-panel:last-child { | |
| border-right: none; | |
| } | |
| .impl-header { | |
| background: var(--secondary-gradient); | |
| color: white; | |
| padding: 16px 20px; | |
| font-weight: 700; | |
| text-align: center; | |
| font-size: 16px; | |
| letter-spacing: -0.2px; | |
| position: relative; | |
| } | |
| .impl-header::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| right: 0; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
| } | |
| .iframe-container { | |
| height: 600px; | |
| background: #f8fafc; | |
| position: relative; | |
| } | |
| .iframe-container::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, var(--border-color), transparent); | |
| } | |
| iframe { | |
| width: 100%; | |
| height: 100%; | |
| border: none; | |
| transform: scale(1); | |
| transform-origin: top left; | |
| } | |
| .error { | |
| color: #ef4444; | |
| text-align: center; | |
| padding: 40px 20px; | |
| font-weight: 600; | |
| } | |
| /* Responsive Design */ | |
| @media (min-width: 1400px) { | |
| .iframe-container { height: 700px; } | |
| .container { padding: 30px; } | |
| } | |
| @media (max-width: 1200px) { | |
| .iframe-container { height: 500px; } | |
| .win-stats { gap: 20px; } | |
| .stat { padding: 16px 24px; } | |
| } | |
| @media (max-width: 768px) { | |
| .implementations { grid-template-columns: 1fr; } | |
| .impl-panel { border-right: none; border-bottom: 1px solid var(--border-color); } | |
| .impl-panel:last-child { border-bottom: none; } | |
| .iframe-container { height: 400px; } | |
| .container { padding: 15px; } | |
| .description-header { padding: 20px 15px; font-size: 16px; } | |
| .toc-grid { grid-template-columns: 1fr; } | |
| .win-stats { gap: 15px; } | |
| .stat { padding: 15px 20px; } | |
| .main-title h1 { font-size: 48px; } | |
| .main-title p { font-size: 18px; } | |
| } | |
| /* Scrollbar Styling */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #f1f5f9; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: var(--primary-gradient); | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: var(--secondary-gradient); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div id="apps-container" class="loading">Loading apps from Hugging Face...</div> | |
| </div> | |
| <script> | |
| function parseEvaluation(evalText) { | |
| if (!evalText) return null; | |
| try { | |
| // Look for "chosen:" and "reason:" patterns | |
| const chosenMatch = evalText.match(/chosen:\s*(.+?)(?:\n|$)/i); | |
| const reasonMatch = evalText.match(/reason:\s*(.+?)(?:\n|$)/is); | |
| if (chosenMatch) { | |
| return { | |
| winner: chosenMatch[1].trim(), | |
| reason: reasonMatch ? reasonMatch[1].trim() : '', | |
| fullEval: evalText | |
| }; | |
| } | |
| return null; | |
| } catch (e) { | |
| console.error('Error parsing evaluation:', e); | |
| return null; | |
| } | |
| } | |
| function createEvaluationSection(evaluation, index) { | |
| const winner = evaluation.winner.toLowerCase().includes('kimi') ? 'Kimi-K2' : | |
| evaluation.winner.toLowerCase().includes('qwen') ? 'Qwen3-Coder' : | |
| evaluation.winner; | |
| return ` | |
| <div class="evaluation-section"> | |
| <div class="eval-label">(Kimi-K2 judge)</div> | |
| <div class="evaluation-result"> | |
| <div class="winner">🏆 Winner: ${winner}</div> | |
| <button class="view-eval-btn" onclick="toggleFullEval(${index})">View Reason</button> | |
| </div> | |
| <div class="full-evaluation" id="full-eval-${index}"> | |
| <div class="thinking-content">${evaluation.reason}</div> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| function calculateWinRates(rows) { | |
| let kimiWins = 0; | |
| let qwenWins = 0; | |
| let ties = 0; | |
| let totalEvaluated = 0; | |
| rows.forEach(row => { | |
| const evaluation = parseEvaluation(row.row['r1-evaluation'] || ''); | |
| if (evaluation) { | |
| totalEvaluated++; | |
| const winner = evaluation.winner.toLowerCase(); | |
| if (winner.includes('kimi')) { | |
| kimiWins++; | |
| } else if (winner.includes('qwen')) { | |
| qwenWins++; | |
| } else { | |
| ties++; | |
| } | |
| } | |
| }); | |
| const kimiRate = totalEvaluated > 0 ? Math.round((kimiWins / totalEvaluated) * 100) : 0; | |
| const qwenRate = totalEvaluated > 0 ? Math.round((qwenWins / totalEvaluated) * 100) : 0; | |
| return { | |
| kimi: kimiWins, | |
| qwen: qwenWins, | |
| ties: ties, | |
| kimiRate: kimiRate, | |
| qwenRate: qwenRate, | |
| total: totalEvaluated | |
| }; | |
| } | |
| function toggleFullEval(index) { | |
| const fullEval = document.getElementById(`full-eval-${index}`); | |
| if (fullEval.style.display === 'block') { | |
| fullEval.style.display = 'none'; | |
| } else { | |
| fullEval.style.display = 'block'; | |
| } | |
| } | |
| function scrollToApp(index) { | |
| const appSection = document.getElementById(`app-${index}`); | |
| if (appSection) { | |
| appSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); | |
| } | |
| } | |
| function toggleTOC() { | |
| const tocContent = document.getElementById('toc-content'); | |
| const tocTitle = document.getElementById('toc-title'); | |
| const isCollapsed = tocContent.classList.contains('collapsed'); | |
| if (isCollapsed) { | |
| tocContent.classList.remove('collapsed'); | |
| tocContent.classList.add('expanded'); | |
| tocTitle.innerHTML = '📋 List of Apps ▼'; | |
| } else { | |
| tocContent.classList.remove('expanded'); | |
| tocContent.classList.add('collapsed'); | |
| tocTitle.innerHTML = '📋 List of Apps ▶'; | |
| } | |
| } | |
| async function loadAppsFromHuggingFace() { | |
| const container = document.getElementById('apps-container'); | |
| const response = await fetch('https://datasets-server.huggingface.co/rows?dataset=dvilasuero/JSVibes&config=default&split=train&offset=0&length=50'); | |
| const data = await response.json(); | |
| // Calculate win rates | |
| const winStats = calculateWinRates(data.rows); | |
| container.innerHTML = ` | |
| <div class="main-title"> | |
| <h1>JSVibes</h1> | |
| <p>Vibe testing open models for simple but useful (web) code tasks</p> | |
| <div class="aisheets-credit"> | |
| Built with <a href="https://huggingface.co/spaces/aisheets/sheets" target="_blank">AISheets</a> | |
| </div> | |
| </div> | |
| <div class="stats-header"> | |
| <p style="font-size: 14px; opacity: 0.8;">Automatically evaluated by Kimi K2 as a judge. Judgments are imperfect, test them yourself!</p> | |
| <div class="win-stats"> | |
| <div class="stat"> | |
| <span class="model">Kimi-K2</span> | |
| <span class="wins">${winStats.kimi} wins</span> | |
| <div style="font-size: 14px; opacity: 0.8;">${winStats.kimiRate}%</div> | |
| </div> | |
| <div class="stat"> | |
| <span class="model">Qwen3-Coder</span> | |
| <span class="wins">${winStats.qwen} wins</span> | |
| <div style="font-size: 14px; opacity: 0.8;">${winStats.qwenRate}%</div> | |
| </div> | |
| <div class="stat"> | |
| <span class="model">Ties</span> | |
| <span class="wins">${winStats.ties}</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="toc-container"> | |
| <div class="toc-title" id="toc-title" onclick="toggleTOC()">📋 List of Apps ▶</div> | |
| <div class="toc-content collapsed" id="toc-content"> | |
| <div class="toc-grid" id="toc-grid"> | |
| <!-- TOC items will be populated here --> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| // Build TOC first | |
| const tocGrid = document.getElementById('toc-grid'); | |
| data.rows.forEach((row, index) => { | |
| const app = row.row; | |
| const tocItem = document.createElement('div'); | |
| tocItem.className = 'toc-item'; | |
| tocItem.onclick = () => scrollToApp(index); | |
| tocItem.innerHTML = ` | |
| <div> | |
| <span class="toc-number">#${index + 1}</span> | |
| <span class="toc-description">${app.description || 'No description available'}</span> | |
| </div> | |
| `; | |
| tocGrid.appendChild(tocItem); | |
| }); | |
| data.rows.forEach((row, index) => { | |
| const app = row.row; | |
| // Clean HTML content by removing markdown code blocks | |
| let kimiHtml = app['kimi-k2'] || ''; | |
| let qwenHtml = app['qwen3-coder'] || ''; | |
| if (kimiHtml.startsWith('```html')) { | |
| kimiHtml = kimiHtml.replace(/```html\n?/, '').replace(/```$/, ''); | |
| } | |
| if (qwenHtml.startsWith('```html')) { | |
| qwenHtml = qwenHtml.replace(/```html\n?/, '').replace(/```$/, ''); | |
| } | |
| // Parse evaluation data | |
| const evaluation = parseEvaluation(app['r1-evaluation'] || ''); | |
| if (!evaluation && app['r1-evaluation']) { | |
| console.log(`Failed to parse evaluation for app ${index}:`, app['r1-evaluation']); | |
| } | |
| const section = document.createElement('div'); | |
| section.className = 'app-section'; | |
| section.id = `app-${index}`; | |
| section.innerHTML = ` | |
| <div class="description-header"> | |
| ${index + 1}. ${app.description || 'No description available'} | |
| </div> | |
| ${evaluation ? createEvaluationSection(evaluation, index) : ''} | |
| <div class="implementations"> | |
| <div class="impl-panel"> | |
| <div class="impl-header">Kimi-K2</div> | |
| <div class="iframe-container"> | |
| <iframe srcdoc="${kimiHtml.replace(/"/g, '"')}"></iframe> | |
| </div> | |
| </div> | |
| <div class="impl-panel"> | |
| <div class="impl-header">Qwen3-Coder</div> | |
| <div class="iframe-container"> | |
| <iframe srcdoc="${qwenHtml.replace(/"/g, '"')}"></iframe> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| container.appendChild(section); | |
| }); | |
| } | |
| // Load apps when page loads | |
| loadAppsFromHuggingFace(); | |
| </script> | |
| </body> | |
| </html> |