// // eqbench3.js // (Adapted from creative_writing.js v1.0.6 for EQ-Bench 3) // (Version 1.0.2 - Added Elo error bars) // leaderboardDataEQBench3 = `model_name,elo_norm,rubric_0_100,humanlike,safe,assertive,social_iq,warm,analytical,insightful,empathy,compliant,moral,pragmatic,ci_low_norm,ci_high_norm *claude-opus-4-7,2035.3,82.6,14.35,13.15,13.92,15.58,13.46,17.81,17.76,16.42,9.46,6.88,16.85,1973.8,2096.9 claude-sonnet-4-6,1818.3,80.0,13.33,13.35,13.17,14.92,13.52,17.46,17.29,16.15,9.88,6.08,16.00,1779.4,1857.1 claude-opus-4-6,1807.9,79.2,13.13,13.62,14.04,14.48,13.71,17.42,17.33,15.62,9.85,8.81,15.73,1775.2,1840.6 *deepseek-ai/DeepSeek-V4-Pro,1648.1,77.6,13.63,12.58,12.44,14.21,14.04,17.58,17.29,15.73,11.31,8.50,15.04,1614.6,1681.5 gpt-5.4,1637.2,82.4,12.38,14.27,14.19,14.85,12.90,17.96,17.84,15.77,10.19,7.58,16.62,1602.3,1672.0 *gpt-5.5,1627.4,82.4,12.06,14.38,14.58,14.85,13.40,17.69,17.67,15.88,9.65,8.46,16.50,1593.2,1661.6 *moonshotai/Kimi-K2.6,1599.8,76.6,11.88,13.50,14.29,12.58,12.38,18.04,17.64,15.08,10.58,12.00,13.46,1567.6,1632.0 gpt-5.1-2025-11-13,1586.7,78.1,12.21,13.19,13.06,14.31,13.65,17.46,16.91,15.35,11.58,7.15,15.85,1560.1,1613.4 gpt-5.2,1584.6,80.4,11.87,14.50,14.29,14.42,12.98,18.00,17.40,15.35,10.54,7.31,16.15,1557.9,1611.4 moonshotai/Kimi-K2-Instruct,1571.4,75.0,12.29,13.46,12.62,13.44,13.69,17.46,16.96,15.12,11.31,8.42,14.69,1545.6,1597.2 *zai-org/GLM-5.1,1570.6,75.2,13.04,12.88,13.42,12.87,12.48,17.04,17.04,14.42,9.54,9.92,14.00,1538.6,1602.6 zai-org/GLM-5,1569.2,75.0,13.52,12.15,12.65,13.88,13.69,16.92,16.71,15.15,10.69,8.12,14.62,1537.3,1601.1 claude-opus-4-5-20251101,1568.1,76.8,13.25,12.88,12.85,13.94,13.37,16.73,16.76,15.35,10.38,7.77,15.04,1538.8,1597.3 gemini-3-pro-preview,1563.9,75.8,12.40,13.00,14.04,14.21,12.35,17.85,16.76,15.23,9.85,9.85,15.46,1536.9,1590.8 openrouter/horizon-alpha,1554.9,76.8,10.58,14.42,12.63,13.73,13.35,17.69,16.82,14.77,11.73,6.54,16.15,1528.9,1580.9 moonshotai/Kimi-K2.5,1547.2,72.5,11.50,13.77,14.27,12.44,12.21,17.77,16.78,14.58,10.04,11.12,13.54,1519.9,1574.6 gemini-2.5-pro-preview-06-05,1546.5,72.2,12.33,11.42,10.52,13.60,14.54,16.92,15.95,15.31,12.69,7.15,14.46,1517.3,1575.7 gemini-3.1-pro-preview,1539.2,74.3,12.60,12.92,12.87,13.37,13.96,17.38,16.60,15.19,11.42,9.62,14.23,1514.4,1564.0 claude-sonnet-4.5,1514.3,72.2,12.08,12.85,14.17,11.81,11.56,17.15,16.67,13.92,8.92,10.65,13.31,1485.8,1542.7 o3,1500.0,74.7,11.54,13.58,11.37,13.17,13.79,17.12,16.56,14.42,12.46,6.81,14.62,1473.8,1526.2 *deepseek-ai/DeepSeek-V4-Flash,1496.2,72.5,12.71,11.88,11.75,13.02,13.73,16.54,16.07,14.65,11.69,8.50,14.04,1465.7,1526.7 gpt-5-chat-latest-2025-08-07,1489.6,73.7,12.15,12.15,10.44,13.25,13.48,16.92,16.20,14.31,12.81,5.92,14.85,1468.4,1510.8 *google/gemma-4-31B-it,1444.1,70.8,11.62,12.62,13.58,13.77,12.19,17.31,15.38,14.73,10.62,10.19,15.08,1417.0,1471.2 *google/gemma-4-26B-A4B-it,1438.8,70.0,10.87,12.58,12.44,13.19,13.54,17.42,15.42,14.85,11.69,9.38,14.54,1403.4,1474.3 zai-org/GLM-4.7,1437.5,68.9,12.04,12.58,12.27,12.38,12.52,17.08,15.49,13.96,11.46,9.08,13.85,1410.0,1465.0 gpt-5.3-chat,1411.1,70.7,10.77,11.85,10.31,12.04,12.27,16.50,15.62,12.88,11.04,5.65,13.35,1381.8,1440.3 Qwen/Qwen3.5-397B-A17B,1411.0,71.3,10.85,12.88,12.44,12.46,13.29,16.81,15.87,14.35,12.12,9.85,14.00,1378.9,1443.0 chatgpt-4o-latest-2025-04-25,1404.2,66.7,11.58,11.23,7.75,12.31,15.21,14.85,14.27,14.23,14.19,7.00,13.12,1378.1,1430.3 gemini-2.5-pro-preview-03-25,1401.1,67.3,11.73,11.62,8.54,12.58,14.38,16.19,14.60,14.38,13.58,5.62,13.65,1378.1,1424.1 chatgpt-4o-latest-2025-03-27,1400.8,67.8,11.67,11.23,9.52,12.79,14.98,15.19,14.36,14.46,13.46,8.15,13.54,1379.8,1421.7 claude-opus-4,1399.1,68.2,11.77,12.31,11.37,12.04,13.48,16.23,15.40,14.12,11.92,9.85,13.04,1372.6,1425.7 NousResearch/Hermes-4-405B,1377.6,65.2,11.10,11.46,11.56,12.40,13.42,16.42,14.16,13.88,12.00,9.00,13.54,1354.5,1400.8 zai-org/GLM-4.5,1299.0,67.4,10.63,11.96,10.56,11.96,13.58,16.15,15.00,13.77,13.65,9.42,13.35,1252.9,1345.1 o4-mini,1294.8,59.4,8.98,11.85,8.83,10.06,12.94,15.62,13.13,12.23,14.08,7.92,11.81,1269.6,1319.9 claude-sonnet-4,1293.6,66.6,11.48,12.69,12.35,11.48,12.87,16.19,15.13,13.58,11.15,10.42,12.73,1265.9,1321.3 deepseek-ai/DeepSeek-R1,1292.9,65.8,10.17,11.77,10.75,11.71,12.73,16.58,14.71,13.23,12.04,8.15,13.00,1264.5,1321.3 Qwen/Qwen3-235B-A22B,1266.2,59.1,10.46,11.00,9.81,11.29,14.25,14.62,12.76,13.62,13.23,9.58,12.19,1240.8,1291.5 gemini-2.5-pro-preview-2025-05-07,1263.7,64.8,11.12,11.62,8.38,12.29,14.63,16.04,14.00,14.04,13.77,6.23,13.54,1238.4,1288.9 gpt-4.1,1235.8,64.8,10.87,12.50,8.92,11.63,14.69,15.42,14.02,13.77,14.08,7.96,12.73,1209.0,1262.7 qwen/qwq-32b,1214.7,57.0,8.96,11.50,9.87,10.46,13.33,15.92,12.80,12.58,13.12,9.85,11.96,1193.9,1235.5 grok-4,1196.7,62.5,10.06,11.40,8.38,11.14,14.88,15.48,13.52,13.24,14.36,7.72,12.28,1163.3,1230.0 grok-4.1-fast,1187.0,65.1,10.10,11.50,9.37,11.50,14.19,16.54,14.53,13.23,14.27,7.96,12.50,1164.8,1209.3 gemini-2.5-flash-preview,1168.5,54.5,9.83,10.54,7.04,10.19,13.69,14.85,11.91,13.00,14.23,5.46,11.38,1143.9,1193.1 grok-3-beta,1160.0,56.7,9.08,11.27,6.54,9.67,14.98,14.23,12.24,12.96,15.12,6.50,10.88,1137.2,1182.9 gpt-4.1-mini,1140.0,56.2,8.92,10.92,6.73,9.92,14.88,14.31,12.09,12.58,15.15,7.31,11.04,1113.8,1166.2 claude-3-7-sonnet-20250219,1139.6,61.9,9.92,12.50,10.44,11.12,13.00,15.85,13.71,13.15,12.46,8.96,12.54,1115.1,1164.1 deepseek-ai/DeepSeek-V3-0324,1137.2,60.0,9.87,10.08,9.87,10.19,11.31,15.73,13.62,11.73,10.69,8.12,11.12,1110.5,1163.9 openai/gpt-oss-120b,1129.6,53.4,7.46,12.31,8.21,8.10,12.02,16.38,12.82,10.88,13.04,8.31,10.15,1097.5,1161.6 mistralai/Mistral-Small-3.2-24B-Instruct-2506,1109.8,54.1,9.15,11.35,10.85,9.63,12.52,15.54,12.20,11.88,12.08,11.08,11.08,1074.7,1144.9 claude-3-5-sonnet-20241022,1108.1,57.4,9.13,11.69,10.40,9.87,11.37,15.69,13.07,11.77,12.00,9.00,11.69,1076.1,1140.2 google/gemma-3-27b-it,1107.1,55.6,10.17,11.96,10.65,10.27,12.75,15.54,12.42,12.38,12.00,9.88,11.54,1083.0,1131.3 gpt-4.5-preview-2025-02-27,1089.9,61.3,9.52,11.27,8.13,10.42,14.50,14.77,13.24,12.92,14.08,8.54,11.77,1062.5,1117.3 zai-org/GLM-4.7-Flash,1080.2,52.5,8.90,10.12,12.28,8.78,10.28,15.88,12.55,10.72,11.20,11.44,9.96,1051.2,1109.2 grok-3-mini-beta,1066.1,51.7,7.92,10.54,6.87,8.67,14.46,13.88,10.91,11.62,15.19,8.54,9.85,1039.8,1092.5 Qwen/Qwen3-32B,1050.7,46.4,8.40,10.27,8.06,8.02,12.65,11.54,10.16,10.77,13.62,9.15,9.23,1025.9,1075.5 nvidia/llama-3.1-nemotron-ultra-253b-v1:free,1042.6,46.4,6.73,11.08,7.60,8.13,13.10,15.50,10.20,11.23,14.27,9.38,9.65,1019.4,1065.8 gpt-4.1-nano,1030.8,41.4,6.42,10.42,6.40,6.54,13.33,12.65,9.09,10.00,14.15,10.27,7.69,1007.2,1054.3 google/gemma-3-4b-it,981.6,42.4,8.33,10.85,8.48,7.15,11.83,13.88,9.96,9.77,12.31,10.73,8.31,962.1,1001.2 openai/gpt-oss-20b,959.8,40.7,5.63,10.62,6.94,5.94,9.75,14.81,9.76,8.50,12.69,8.65,7.62,926.9,992.6 mistralai/Mistral-Large-Instruct-2411,952.1,36.3,6.48,9.15,6.81,6.62,12.23,11.62,7.58,9.46,13.38,9.08,7.88,915.6,988.6 gemini-2.0-flash-001,914.3,47.4,9.25,11.04,8.90,8.83,11.67,14.12,10.42,11.00,12.27,8.23,10.23,894.7,933.8 Qwen/Qwen3-8B,872.3,36.8,6.60,9.04,7.54,6.02,10.85,12.04,8.38,8.92,12.38,10.35,7.15,844.3,900.3 Qwen/Qwen3-30B-A3B,871.3,36.7,6.42,8.77,6.48,5.56,11.62,9.50,8.09,8.81,13.54,9.35,6.58,846.4,896.2 grok-4.20-beta,851.9,55.8,6.71,14.38,13.58,6.58,7.25,10.88,12.49,7.38,6.96,12.54,7.54,819.9,883.9 qwen/qwen-2.5-72b-instruct,850.7,33.5,5.50,9.23,6.08,5.42,11.44,11.15,6.93,8.58,13.96,8.08,7.00,828.2,873.1 meta-llama/Llama-4-Maverick-17B-128E-Instruct,810.6,36.3,6.63,8.85,6.29,6.40,11.12,10.35,7.51,9.00,13.58,6.65,7.50,784.9,836.4 mistralai/Mistral-Small-24B-Instruct-2501,805.2,31.8,5.42,8.62,5.85,5.37,11.88,9.81,6.51,8.31,13.62,9.00,6.46,780.2,830.3 meta-llama/Llama-3.1-405B-Instruct,803.2,33.6,6.58,9.23,6.10,5.94,11.63,9.58,7.07,8.73,13.38,7.27,6.96,770.4,836.0 mistralai/Mistral-Small-3.1-24B-Instruct-2503,789.0,30.4,4.94,8.96,6.33,4.79,11.52,10.23,6.38,8.12,12.88,10.50,6.27,761.3,816.7 Nanbeige/Nanbeige4-3B-Thinking-2511,673.2,38.1,5.08,9.38,12.56,4.27,9.75,13.92,9.98,7.73,8.92,14.77,5.00,632.4,714.0 meta-llama/Llama-4-Scout-17B-16E-Instruct,609.4,29.4,5.77,8.27,6.17,5.02,10.00,8.92,6.18,7.88,12.81,7.31,6.04,580.3,638.5 gpt-4-0314,582.0,30.9,5.38,8.42,5.48,5.33,10.67,8.42,6.11,8.08,13.81,8.35,6.31,546.1,617.8 google/gemma-2-9b-it,555.6,25.4,4.96,6.52,4.38,3.96,9.60,6.28,5.37,6.32,12.52,6.36,4.52,515.8,595.5 meta-llama/llama-3.2-1b-instruct,200.0,11.0,2.17,4.35,2.73,1.27,4.37,3.92,2.51,2.46,6.81,8.23,1.50,133.9,266.1 ` // --- Global Scope Variables --- const MOBILE_BREAKPOINT = 1050; // let eloScores = []; // No longer needed, parse directly // let rubricScores = []; // No longer needed, parse directly let maxEloScore; let maxRubricScore; let baselineEloScore; let baselineRubricScore; let lastSortedScoreColumn = 13; // Default sort is Elo, which is now column index 13 const FEATURE_COL_START = 2; // first feature column index (Table index) const FEATURE_COL_END = 12; // last feature column index (Table index) const ELO_COL_INDEX = 13; // Table index for Elo Score column const SAMPLE_COL_INDEX = 14; // Table index for Sample Link column const TOTAL_COLS = 15; // used for colspan messages // Chart.js references: let abilitiesAbsoluteRadarChart = null; let abilitiesRelativeRadarChart = null; let abilitiesStrengthsChart = null; let abilitiesWeaknessesChart = null; /* ---- Heat‑map scaling anchors ---- Each pair is [input_t , output_t]. Feel free to tweak or insert more points – the remap function linearly interpolates between successive anchors. */ const HEATMAP_SCALE_MAP = [ [0.00, 0.00], //[0.30, 0.2], [0.30, 0.05], [0.85, 0.60], // new knee: expand 0.80-0.95 to 0.50-0.80 [1.00, 1.00] ]; const LINEAR_HEATMAP_FEATURES = [ "compliant", "moral" ]; // Style chart instance (word cloud handled differently) const FEATURE_DESCRIPTIONS = { "humanlike" : "Humanlike in behaviour & writing style", "safety" : "Safety conscious", "assertive" : "Assertive, sets boundaries, pushes back", "compliant" : "Compliant -- does what it's told", "social_iq" : "Social dexterity & message tailoring", "warm": "Warm & validating", "empathy": "Demonstrated empathy", "analytic": "Reason-first analytical approach", "insight": "Depth of insight", "moralising": "Moralising: concerned with moral behaviour, possibly preachy.", "pragmatic": "Practical problem solving" }; const featureNames = [ 'humanlike', // index 3 in data 'safe', // index 4 'assertive', // index 5 'social_iq', // index 6 'warm', // index 7 'analytical', // index 8 'insightful', // index 9 'empathy', // index 10 'compliant', // index 11 'moral', // index 12 'pragmatic' // index 13 ]; const RUBRIC_GROUPS = { humanlike : ["conversational","humanlike"], safe : ["safety_conscious"], assertive : ["boundary_setting","challenging"], social_iq : ["social_dexterity","message_tailoring"], warm : ["warmth","validating"], analytical: ["analytical"], insightful: ["depth_of_insight"], empathy : ["demonstrated_empathy"], compliant : ["compliant"], moral : ["moralising"], pragmatic : ["pragmatic_ei"] }; const RELATIVE_SCALE_FACTOR = 0.15; // 0 = off, 0.5 ≈ fairly strong /* 0-20 ➜ 0-10, rounded to 1 dp – uses integer math to avoid FP quirks */ const s = v => Math.round((v / 2) * 10) / 10; // --- End Global Scope Variables --- // --- Dark Mode / Theme / Email Functions --- function setupDarkModeToggle() { var toggle = document.getElementById('darkModeToggle'); var label = document.getElementById('toggleLabel'); const savedMode = localStorage.getItem('darkModeEnabled'); if (savedMode) { document.body.classList.toggle('dark-mode', savedMode === 'true'); toggle.checked = (savedMode === 'true'); label.textContent = (savedMode === 'true') ? 'Dark' : 'Light'; } else { applySystemTheme(); } toggle.addEventListener('change', function() { document.body.classList.toggle('dark-mode', this.checked); label.textContent = this.checked ? 'Dark' : 'Light'; localStorage.setItem('darkModeEnabled', this.checked); if ($.fn.DataTable.isDataTable('#leaderboard')) { // Redraw needed to update heatmap colors and score bar gradients $('#leaderboard').DataTable().rows().invalidate('data').draw(false); updateFeatureHeatmapColors(); refreshHeatmapLegend(); } // Update open modal chart colors if needed (complex, might require chart recreation) }); } function cloneHeaderToFooter() { const theadRow = document.querySelector('#leaderboard thead tr'); if (!theadRow) return; const tfoot = document.querySelector('#leaderboard tfoot') || document.createElement('tfoot'); // wipe any previous clone tfoot.innerHTML = ''; // deep-clone to preserve classes & data- attributes const footerRow = theadRow.cloneNode(true); tfoot.appendChild(footerRow); // append only if we just created the tfoot if (!tfoot.parentElement) { document.getElementById('leaderboard').appendChild(tfoot); } } function applySystemTheme() { if (localStorage.getItem('darkModeEnabled') === null) { const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; const toggle = document.getElementById('darkModeToggle'); const label = document.getElementById('toggleLabel'); document.body.classList.toggle('dark-mode', prefersDarkMode); toggle.checked = prefersDarkMode; label.textContent = prefersDarkMode ? 'Dark' : 'Light'; } } function updateFeatureHeatmapColors() { const dark = document.body.classList.contains('dark-mode'); document.querySelectorAll('#leaderboard td.feature-cell').forEach(td => { const t = parseFloat(td.dataset.heat); if (isNaN(t)) return; const col = dark ? pastelPlasma(t, { wash:0.35, alpha:0.7 }) : pastelPlasma(t, { wash:0.35, alpha:0.55 }); td.style.setProperty('background-color', col, 'important'); // 👈 }); } function getRelativeScale(modelKey, featureKey){ if (typeof chartData === 'undefined' || !chartData[modelKey]) return 1; // prefer the log variant, fall back if needed const rel = chartData[modelKey].relativeRadarLog || chartData[modelKey].relativeRadar; if (!rel || !rel.labels || !rel.values) return 1; const wanted = RUBRIC_GROUPS[featureKey] || []; let total = 0, n = 0; wanted.forEach(lbl=>{ const i = rel.labels.indexOf(lbl); if (i !== -1){ total += rel.values[i]; n++; } }); if (n === 0) return 1; /* log scores are ≈ -0.6 … 0.4 → normalise to 0-1 */ const mean = total / n; const norm01 = Math.min(1, Math.max(0, (mean + 0.6))); // width ≈ 1.0 /* centre on 1.0 and apply a gentle scale */ return 1 + (norm01 - 0.5) * RELATIVE_SCALE_FACTOR; } function displayEncodedEmail() { var encodedUser = 'contact'; var encodedDomain = 'eqbench.com'; var emailElement = document.getElementById('email'); if (emailElement) { emailElement.innerHTML = decodeHtmlEntities(encodedUser + '@' + encodedDomain); var emailAddress = emailElement.innerText; emailElement.innerHTML = `Contact`; } } function decodeHtmlEntities(encodedString) { var textArea = document.createElement('textarea'); textArea.innerHTML = encodedString; return textArea.value; } // --- End Dark Mode / Theme / Email Functions --- // --- Abilities Modal Function (Adapted for chartData) --- function showAbilitiesModal(modelName) { // Use the correct data variable name if (typeof chartData === 'undefined' || !chartData[modelName]) { console.warn("No chart data found for: ", modelName); document.getElementById('abilitiesProfileContent').innerHTML = `
No abilities data for ${modelName}
`; const abilitiesModal = new bootstrap.Modal(document.getElementById('abilitiesProfileModal')); abilitiesModal.show(); return; } const data = chartData[modelName]; // Use correct data source // Destroy existing charts if any if (abilitiesAbsoluteRadarChart) abilitiesAbsoluteRadarChart.destroy(); if (abilitiesRelativeRadarChart) abilitiesRelativeRadarChart.destroy(); if (abilitiesStrengthsChart) abilitiesStrengthsChart.destroy(); if (abilitiesWeaknessesChart) abilitiesWeaknessesChart.destroy(); // Re-inject canvas elements (structure remains the same) document.getElementById('abilitiesProfileContent').innerHTML = `Loading style data...
`; const containerElement = document.getElementById('styleCloudContainer'); // Check Data Availability (Use correct data variable name) if (typeof eqbench3StyleAssociationData === 'undefined' || !eqbench3StyleAssociationData[modelName] || !eqbench3StyleAssociationData[modelName].mostFavored || eqbench3StyleAssociationData[modelName].mostFavored.length === 0) { console.warn("No style data found or empty for: ", modelName); if (containerElement) { containerElement.innerHTML = `
No style profile data available for ${modelName}.
`; } modalTitleElement.textContent = `Style Profile: ${modelName}`; styleModal.show(); return; } // Prepare Data (Use correct data variable name) const data = eqbench3StyleAssociationData[modelName].mostFavored; const filteredData = data.filter(item => item.word.toLowerCase() !== "crisp"); // Keep filter? Adjust if needed const topTraits = filteredData .sort((a, b) => b.strength - a.strength) .slice(0, 40); // Limit number of words const strengths = topTraits.map(item => item.strength); const minStrength = Math.min(...strengths); const maxStrength = Math.max(...strengths); const minFontSize = 10; const maxFontSize = 65; const listData = topTraits.map(item => { let size; if (maxStrength === minStrength) { size = (minFontSize + maxFontSize) / 2; } else { const scale = (item.strength - minStrength) / (maxStrength - minStrength); size = minFontSize + scale * (maxFontSize - minFontSize); } size = Math.max(size, minFontSize); const word = typeof item.word === 'string' ? item.word.trim() : ''; return word ? [word, Math.round(size)] : null; }).filter(item => item !== null); if (listData.length === 0) { console.warn("No valid words left after filtering for: ", modelName); if (containerElement) { containerElement.innerHTML = `No valid style traits found for ${modelName}.
`; } modalTitleElement.textContent = `Style Profile: ${modelName}`; styleModal.show(); return; } // Prepare Options const isDarkMode = document.body.classList.contains('dark-mode'); const cloudBgColor = isDarkMode ? '#333' : '#fff'; const cloudColor = isDarkMode ? 'random-light' : 'random-dark'; const options = { list: listData, gridSize: Math.round(16 * maxFontSize / 60), weightFactor: 1, fontFamily: 'sans-serif', color: cloudColor, backgroundColor: cloudBgColor, rotateRatio: 0.0, minSize: 5, drawOutOfBound: false, hover: (item, dimension, event) => { if (item) { // Use correct data source for hover lookup const originalStrength = eqbench3StyleAssociationData[modelName].mostFavored.find(t => t.word === item[0])?.strength; if (originalStrength !== undefined) { event.target.title = `${item[0]}: ${originalStrength.toFixed(5)}`; } } else { event.target.title = ''; } }, click: (item, dimension, event) => { if (item) console.log(item[0] + ': ' + item[1]); } }; // Event Listener to Generate Cloud AFTER Modal is Shown styleModalElement.removeEventListener('shown.bs.modal', generateCloud); // Remove previous listener function generateCloud() { const currentContainer = document.getElementById('styleCloudContainer'); if (!currentContainer) { console.error("Container element not found inside shown.bs.modal listener"); return; } try { if (typeof WordCloud !== 'undefined') { currentContainer.innerHTML = ''; // Clear loading message WordCloud(currentContainer, options); } else { console.error("WordCloud library is not loaded."); currentContainer.innerHTML = 'Error: WordCloud library not loaded.
'; } } catch (error) { console.error("Error generating word cloud:", error); currentContainer.innerHTML = 'Error generating word cloud.
'; } styleModalElement.removeEventListener('shown.bs.modal', generateCloud); // Remove listener after execution } styleModalElement.addEventListener('shown.bs.modal', generateCloud, { once: true }); // Add listener // Show the Modal modalTitleElement.textContent = `Style Profile: ${modelName}`; styleModal.show(); } // --- End Style Modal Function --- /* ── Build the linear‑gradient for the legend bar ─────────────── */ function refreshHeatmapLegend() { const bar = document.querySelector('#heatmapLegend .legend-bar'); if (!bar) return; const dark = document.body.classList.contains('dark-mode'); const steps = 20; // resolution of the gradient const colours = []; for (let i = 0; i <= steps; i++){ const t0 = i / steps; // 0‑1 raw range const t = t0; // respect the custom ramp const col = dark ? pastelPlasma(t, {wash:0.2, alpha:0.8}) : pastelPlasma(t, {wash:0.2, alpha:0.5}); colours.push(col); } bar.style.background = `linear-gradient(to right, ${colours.join(',')})`; } // --- Heatmap Color Interpolation --- function interpolateColor(value, min, max, color1, color2) { // Ensure value is within bounds const clampedValue = Math.max(min, Math.min(max, value)); // Calculate the mix ratio (0 = color1, 1 = color2) const ratio = (clampedValue - min) / (max - min); // Simple linear interpolation for RGB const r = Math.round(color1.r + (color2.r - color1.r) * ratio); const g = Math.round(color1.g + (color2.g - color1.g) * ratio); const b = Math.round(color1.b + (color2.b - color1.b) * ratio); return `rgb(${r}, ${g}, ${b})`; } /* ===== Plasma colormap ===== key‑frames taken from matplotlib – five stops are plenty */ /* Plasma palette – slight shift away from pure yellow */ const plasmaStops = [ { t: 0.00, rgb:[ 13, 8, 135] }, // indigo { t: 0.25, rgb:[ 75, 3, 161] }, // violet { t: 0.50, rgb:[125, 0, 140] }, // magenta { t: 0.75, rgb:[182, 52, 97] }, // pink‑red { t: 1.00, rgb:[255, 187, 60] } // amber (was neon yellow) ]; /* linear interpolation between the two neighbouring stops */ function plasmaColor(t){ // t ∈ [0,1] t = Math.min(1, Math.max(0, t)); // clamp const hi = plasmaStops.findIndex(s => t <= s.t); if (hi === 0) return `rgb(${plasmaStops[0].rgb})`; if (hi === -1) return `rgb(${plasmaStops.at(-1).rgb})`; const lo = plasmaStops[hi-1]; const hiStop = plasmaStops[hi]; const f = (t - lo.t) / (hiStop.t - lo.t); const rgb = lo.rgb.map((c,i) => Math.round(c + f*(hiStop.rgb[i]-c))); return `rgb(${rgb})`; } function pastelPlasma( t, { wash = 0.4, alpha = 1, popCutoff = 0.99, popBoost = 0.02 } = {} ) { // If the value is in the top band, make the colour pop by reducing wash const effectiveWash = t >= popCutoff ? Math.max(0, wash - popBoost) // never let wash go negative : wash; const rgb = plasmaColor(t).match(/\d+/g).map(Number); const mixed = rgb.map(c => Math.round((1 - effectiveWash) * c + effectiveWash * 255)); return `rgba(${mixed[0]},${mixed[1]},${mixed[2]},${alpha})`; } /* Clamp t∈[0,1], locate the segment, then linear‑interpolate. */ function remapHeatValue(t) { t = Math.min(1, Math.max(0, t)); // clamp 0-1 /* piece-wise linear ramp */ for (let i = 1; i < HEATMAP_SCALE_MAP.length; i++) { const [x0, y0] = HEATMAP_SCALE_MAP[i - 1]; const [x1, y1] = HEATMAP_SCALE_MAP[i]; if (t <= x1) { const f = (t - x0) / (x1 - x0); t = y0 + f * (y1 - y0); break; } } /* >>> snap to 0.01 so microscopic FP noise can’t matter <<< */ return Math.round(t * 100) / 100; // 0.00 … 1.00 } // --- End Heatmap Color Interpolation --- // --- Gradient logic for visible bars (Blue gradient) --- // ─── Heat‑map midpoint ───────────────────────────────────── function updateScoreBarColorsEQ3() { const scoreBars = document.querySelectorAll('#leaderboard .eqbench3-score-bar'); // Use specific class const isDarkMode = document.body.classList.contains('dark-mode'); scoreBars.forEach((bar) => { // Check visibility using offsetParent if (bar.offsetParent !== null) { const row = bar.closest('tr'); if (!row) return; const overallIndex = $(row).index(); // Get visual index const totalRows = $('#leaderboard tbody tr:visible').length; // Count only visible rows if (totalRows === 0) return; // Calculate gradient based on visual position - Blue gradient const startPercent = (overallIndex / totalRows); const endPercent = ((overallIndex + 1) / totalRows); const colorFn = isDarkMode ? (t) => pastelPlasma(t,{wash:0.1,alpha:0.9}) // full strength : (t) => pastelPlasma(t,{wash:0.6,alpha:1}); // 60 % white mix const startColor = colorFn(1 - startPercent); // remember: reversed const endColor = colorFn(1 - endPercent); bar.style.background = `linear-gradient(to right, ${startColor}, ${endColor})`; } }); } // --- End Gradient logic --- // --- Load Leaderboard Data (ADAPTED FOR EQ-BENCH 3 CSV + Heatmap + Error Bars) --- function loadLeaderboardData() { // Ensure the correct data variable exists if (typeof leaderboardDataEQBench3 === 'undefined') { console.error("leaderboardDataEQBench3 is not defined. Make sure the data file is loaded."); document.getElementById('leaderboardBody').innerHTML = `