/*
* NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
* All trademark and other rights reserved by their respective owners
* Copyright 2008-2025 Neongecko.com Inc.
* BSD-3 License
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Neon Leaderboard - static dashboard.
All data is precomputed in data.js (window.LEADERBOARD_DATA) by
scripts/build_data.py, faithful to the neon-router report logic. */
(function () {
"use strict";
const D = window.LEADERBOARD_DATA;
if (!D) { document.body.innerHTML = "
data.js failed to load.
"; return; }
const $ = (s, r) => (r || document).querySelector(s);
const $$ = (s, r) => Array.from((r || document).querySelectorAll(s));
const el = (tag, attrs, kids) => {
const n = document.createElement(tag);
if (attrs) for (const k in attrs) {
if (k === "class") n.className = attrs[k];
else if (k === "html") n.innerHTML = attrs[k];
else if (k === "text") n.textContent = attrs[k];
else if (k.startsWith("on") && typeof attrs[k] === "function") n.addEventListener(k.slice(2), attrs[k]);
else if (attrs[k] != null) n.setAttribute(k, attrs[k]);
}
if (kids) (Array.isArray(kids) ? kids : [kids]).forEach(c => c != null && n.appendChild(typeof c === "string" ? document.createTextNode(c) : c));
return n;
};
const GLOSS = D.glossary || {};
const METRICS = D.metrics_def; // [{key,label,field,higher,fmt,tip}]
// field -> true when higher is better; used to default each column's sort so
// the best value lands on top (desc for higher-better, asc for lower-better).
const METRIC_HIGHER = {};
METRICS.forEach(m => { METRIC_HIGHER[m.field] = m.higher; });
const BENCH = D.benchmarks;
const AGG = D.aggregates;
const CANDS = D.candidates; // map id -> meta
const aggBy = {}; // benchmark -> [agg]
const aggByCand = {}; // candidate_id -> [agg] (across benchmarks)
AGG.forEach(a => {
(aggBy[a.benchmark] = aggBy[a.benchmark] || []).push(a);
(aggByCand[a.candidate_id] = aggByCand[a.candidate_id] || []).push(a);
});
const CAND_IDS = Object.keys(CANDS);
const MODEL_NAMES = Array.from(new Set(CAND_IDS.map(id => CANDS[id].model)));
// Prefer a Neon model with generation data as the default detail selection.
const DEFAULT_CAND = CAND_IDS.find(id => CANDS[id].is_neon) || CAND_IDS[0];
// ---- formatting ----
function num(v, code) {
if (v == null || v === "") return "";
v = Number(v);
// Adaptive codes (g0/g1/g2): keep the base precision for |v| >= 1, but for
// small values add just enough decimals (~2 sig figs, capped at 3) so they
// don't collapse to "0"; trailing zeros are trimmed so columns stay tight.
const base = { g0: 0, g1: 1, g2: 2 }[code];
if (base != null) {
if (v === 0) return "0";
const a = Math.abs(v);
const dec = a >= 1 ? base : Math.min(3, Math.max(base, 1 - Math.floor(Math.log10(a))));
let s = v.toFixed(dec);
if (s.indexOf(".") >= 0) s = s.replace(/0+$/, "").replace(/\.$/, "");
return s;
}
const d = { f0: 0, f1: 1, f2: 2, f3: 3, f5: 5 }[code];
return v.toFixed(d == null ? 3 : d);
}
// Format a metric value, applying its display scale (e.g. $/kq = per-query × 1000).
function mnum(v, m) {
return (v == null || v === "") ? "" : num(v * (m.scale || 1), m.fmt);
}
function modelName(c) { return c.is_retrieval_only ? "no model" : c.model; }
function pipeLabel(c) {
const r = c.reranker && c.reranker !== "none" ? " · " + c.reranker : "";
return modelName(c) + " · " + c.retriever + r;
}
function benchShort(b) { return b.replace(/^dataset-/, "").replace(/-qa$/, ""); }
// ---- tooltip ----
const tip = $("#tip");
function showTip(html, x, y) {
tip.innerHTML = html; tip.style.opacity = "1";
const r = tip.getBoundingClientRect();
let left = x + 14, top = y + 16;
if (left + r.width > innerWidth - 8) left = x - r.width - 12;
if (top + r.height > innerHeight - 8) top = y - r.height - 12;
tip.style.left = Math.max(6, left) + "px"; tip.style.top = Math.max(6, top) + "px";
}
function hideTip() { tip.style.opacity = "0"; }
function bindTip(node, html) {
if (!html) return node;
node.addEventListener("mousemove", e => showTip(html, e.clientX, e.clientY));
node.addEventListener("mouseleave", hideTip);
return node;
}
function glossTip(term, extra) {
const def = GLOSS[term];
if (!def && !extra) return null;
return "" + term + "
" + (def || "") + (extra ? "
" + extra : "");
}
// ---- color heat (sequential blue -> green, darker = better) ----
// Shared ramp: t in 0..1, 1 = best. Smooth blue (worst) -> green (best) that
// DARKENS as values improve. A monotonic luminance ramp is legible for every
// type of colour blindness and prints clearly; the blue->green hue shift is a
// secondary cue. Dark mode keeps a higher saturation floor so colours stay
// vivid on the dark UI. Returns just the hsl() colour.
function heatColor(t) {
const dark = document.documentElement.getAttribute("data-theme") !== "light";
const hue = 216 + (150 - 216) * t; // 216 blue -> 150 green
const sat = dark ? 52 + 20 * t : 36 + 26 * t; // dark: 52->72%, light: 36->62%
const lgt = dark ? 44 - 24 * t : 93 - 28 * t; // dark: 44->20%, light: 93->65%
return "hsl(" + hue.toFixed(0) + "," + sat.toFixed(0) + "%," + lgt.toFixed(1) + "%)";
}
// Legible text colour to pair with a heat background in the current theme.
function heatInk() {
return document.documentElement.getAttribute("data-theme") !== "light" ? "#eef4f8" : "#15181d";
}
function heatStyle(v, min, max, higher) {
if (v == null || v === "" || max === min) return "";
let t = (v - min) / (max - min); // 0..1, 1 = numerically max
if (!higher) t = 1 - t; // 1 = better
return "background:" + heatColor(t);
}
// ---- searchable combobox (single select) ----
function Combo(host, opts) {
// opts: {options:[{value,label,sub,neon}], value, placeholder, onChange, width}
let value = opts.value;
let open = false, kbd = -1, filtered = opts.options;
host.className = "combo";
const btn = el("button", { class: "field", style: "text-align:left;min-width:" + (opts.width || 180) + "px;display:flex;align-items:center;gap:6px" });
const menu = el("div", { class: "menu" });
const search = el("input", { class: "field", placeholder: "Type to search…", style: "width:100%;margin-bottom:5px" });
const list = el("div");
menu.appendChild(search); menu.appendChild(list);
host.appendChild(btn); host.appendChild(menu);
function curLabel() { const o = opts.options.find(o => o.value === value); return o ? o.label : (opts.placeholder || "Select…"); }
function paintBtn() {
btn.innerHTML = "";
const o = opts.options.find(o => o.value === value);
if (o && o.neon) btn.appendChild(el("span", { class: "badge neon", text: "NEON" }));
btn.appendChild(el("span", { text: curLabel(), style: "flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" }));
btn.appendChild(el("span", { text: "▾", style: "color:var(--text-faint);font-size:10px" }));
}
function paintList() {
list.innerHTML = "";
filtered.forEach((o, i) => {
const row = el("div", { class: "opt" + (o.value === value ? " sel" : "") + (i === kbd ? " kbd" : "") });
if (o.neon) row.appendChild(el("span", { class: "badge neon", text: "NEON" }));
row.appendChild(el("span", { text: o.label }));
if (o.sub) row.appendChild(el("small", { text: o.sub }));
row.addEventListener("click", () => { value = o.value; close(); opts.onChange && opts.onChange(value); });
list.appendChild(row);
});
if (!filtered.length) list.appendChild(el("div", { class: "opt", style: "color:var(--text-faint)", text: "No matches" }));
}
function doFilter() {
const q = search.value.trim().toLowerCase();
filtered = !q ? opts.options : opts.options.filter(o =>
(o.label + " " + (o.sub || "")).toLowerCase().includes(q));
kbd = filtered.length ? 0 : -1; paintList();
}
function openMenu() { open = true; host.classList.add("open"); search.value = ""; doFilter(); setTimeout(() => search.focus(), 0); }
function close() { open = false; host.classList.remove("open"); paintBtn(); }
btn.addEventListener("click", e => { e.stopPropagation(); open ? close() : openMenu(); });
search.addEventListener("input", doFilter);
search.addEventListener("keydown", e => {
if (e.key === "ArrowDown") { kbd = Math.min(filtered.length - 1, kbd + 1); paintList(); e.preventDefault(); }
else if (e.key === "ArrowUp") { kbd = Math.max(0, kbd - 1); paintList(); e.preventDefault(); }
else if (e.key === "Enter" && filtered[kbd]) { value = filtered[kbd].value; close(); opts.onChange && opts.onChange(value); }
else if (e.key === "Escape") close();
});
document.addEventListener("click", e => { if (open && !host.contains(e.target)) close(); });
paintBtn();
return {
get value() { return value; },
set value(v) { value = v; paintBtn(); },
setOptions(o, v) { opts.options = o; if (v !== undefined) value = v; paintBtn(); }
};
}
// ===================================================================
// State
// ===================================================================
const S = {
tab: "compare",
cmpMode: "byBench",
bench: BENCH[0],
cand: null, // selected pipeline id (byModel)
filterModel: "__all__",
sortKey: "mrr",
sortDir: -1, // -1 desc, 1 asc
sortKey2: "", sortDir2: 1, // secondary sort (tie-break)
sortKey3: "", sortDir3: 1, // tertiary sort (tie-break)
neonOnly: false,
showDQ: true,
heat: true,
metricMode: "scores",
metricSort: "mrr",
metricNeonOnly: false,
metricHeat: true,
pageCand: null,
};
// ===================================================================
// Header / footer
// ===================================================================
$("#headerMeta").textContent = (D.date || "") + " · " + D.n_candidates + " pipelines · " +
BENCH.length + " benchmarks · " + (D.n_queries || "?") + " queries";
const prov = D.provenance || {};
$("#provFoot").textContent = (prov.weekly ? "weekly roster sweep" : "sweep") + (prov.merged_at ? " · merged " + prov.merged_at.slice(0, 19).replace("T", " ") + "Z" : "");
function paintLegendSwatches() {
$("#lgGood").style.cssText = "width:11px;height:11px;border-radius:3px;display:inline-block;" + heatStyle(1, 0, 1, true);
$("#lgBad").style.cssText = "width:11px;height:11px;border-radius:3px;display:inline-block;" + heatStyle(0, 0, 1, true);
const lgDQ = $("#lgDQ");
if (lgDQ) lgDQ.style.cssText = "padding:0 6px;background:" + heatColor(0) + ";color:" + heatInk() + ";border:1px solid rgba(128,128,128,.25)";
}
// ===================================================================
// Tabs
// ===================================================================
const CTLS = { compare: "#ctl-compare", picks: "#ctl-picks", models: "#ctl-models", metrics: "#ctl-metrics", guide: "#ctl-guide" };
$$("#tabs button").forEach(b => b.addEventListener("click", () => setTab(b.dataset.tab)));
function setTab(t) {
S.tab = t;
try { history.replaceState(null, "", "#" + t); } catch (e) {}
$$("#tabs button").forEach(b => b.classList.toggle("active", b.dataset.tab === t));
$$(".view").forEach(v => v.classList.toggle("active", v.id === "view-" + t));
for (const k in CTLS) $(CTLS[k]).style.display = (k === t ? "flex" : "none");
render();
}
// ===================================================================
// Compare controls
// ===================================================================
const benchCombo = Combo($("#benchCombo"), {
options: BENCH.map(b => ({ value: b, label: benchShort(b), sub: b })),
value: S.bench, width: 170, onChange: v => { S.bench = v; render(); }
});
const candOptions = () => CAND_IDS.map(id => ({ value: id, label: pipeLabel(CANDS[id]), neon: CANDS[id].is_neon, sub: CANDS[id].is_neon ? "Neon" : (CANDS[id].is_retrieval_only ? "retrieval" : "") }));
const modelCombo = Combo($("#modelCombo"), { options: candOptions(), value: DEFAULT_CAND, width: 230, onChange: v => { S.cand = v; render(); } });
S.cand = DEFAULT_CAND;
const filterCombo = Combo($("#filterCombo"), {
options: [{ value: "__all__", label: "All models" }].concat(MODEL_NAMES.map(m => ({ value: m, label: m, neon: (CANDS[CAND_IDS.find(id => CANDS[id].model === m)] || {}).is_neon }))),
value: "__all__", width: 160, onChange: v => { S.filterModel = v; render(); }
});
const sortSel = $("#sortSel"), sortSel2 = $("#sortSel2"), sortSel3 = $("#sortSel3");
// Default direction puts the best value on top: descending for higher-better
// metrics, ascending for lower-better metrics (and ascending A->Z otherwise).
const defDir = k => (k in METRIC_HIGHER ? (METRIC_HIGHER[k] ? -1 : 1) : 1);
sortSel.addEventListener("change", () => { S.sortKey = sortSel.value; S.sortDir = defDir(S.sortKey); render(); });
sortSel2.addEventListener("change", () => { S.sortKey2 = sortSel2.value; if (S.sortKey2) S.sortDir2 = defDir(S.sortKey2); render(); });
sortSel3.addEventListener("change", () => { S.sortKey3 = sortSel3.value; if (S.sortKey3) S.sortDir3 = defDir(S.sortKey3); render(); });
$("#sortDir").addEventListener("click", () => { S.sortDir *= -1; render(); });
$("#sortDir2").addEventListener("click", () => { S.sortDir2 *= -1; render(); });
$("#sortDir3").addEventListener("click", () => { S.sortDir3 *= -1; render(); });
$$("#cmpModeSeg button").forEach(b => b.addEventListener("click", () => {
S.cmpMode = b.dataset.mode;
$$("#cmpModeSeg button").forEach(x => x.classList.toggle("active", x === b));
$("#benchPickWrap").style.display = S.cmpMode === "byBench" ? "flex" : "none";
$("#modelPickWrap").style.display = S.cmpMode === "byModel" ? "flex" : "none";
render();
}));
$("#neonOnly").addEventListener("change", e => { S.neonOnly = e.target.checked; render(); });
$("#showDQ").addEventListener("change", e => { S.showDQ = e.target.checked; render(); });
$("#heat").addEventListener("change", e => { S.heat = e.target.checked; render(); });
// ===================================================================
// Compare render
// ===================================================================
function activeMetricCols(rows) {
return METRICS.filter(m => rows.some(r => r[m.field] != null && r[m.field] !== ""));
}
function hasComp(c, key) {
const meta = (D.retrievers || {})[c.retriever];
if (!meta) return null;
return meta.components.find(x => x.key === key) || null;
}
const COMP_TIP = {
emb: "Dense embedding retrieval (bge-m3 / bge-large). Empty = not used.",
bm25: "BM25 lexical (sparse keyword) retrieval. Empty = not used.",
splade: "SPLADE learned-sparse retrieval. Empty = not used.",
web: "Live web search (DuckDuckGo) merged into retrieval. Empty = not used.",
};
function compCell(c, key) {
const cp = hasComp(c, key);
const td = el("td", { class: "comp-col" });
if (cp) {
const txt = key === "emb" ? (cp.detail || "yes") : "\u2713";
td.appendChild(el("span", { class: "rbadge " + cp.key, text: txt }));
return bindTip(td, retrieverTip(c.retriever));
}
td.appendChild(el("span", { class: "dq-ok", text: "\u2014" }));
return bindTip(td, "Not used \u2014 retriever: " + c.retriever + "");
}
function compCol(key, label) {
return {
key: key, head: label, thClass: "comp-col sortable",
tip: "" + label + "
" + COMP_TIP[key],
render: r => compCell(CANDS[r.candidate_id], key),
sortVal: r => { const cp = hasComp(CANDS[r.candidate_id], key); return { s: cp ? (key === "emb" ? (cp.detail || "yes") : "yes") : "" }; },
};
}
function renderCompare() {
const table = $("#cmpTable");
table.innerHTML = "";
let rows, descCols, flagFor;
if (S.cmpMode === "byBench") {
const bt = D.bench_tables[S.bench] || { order: [], pareto: [], dq: {} };
const paretoSet = new Set(bt.pareto);
rows = (aggBy[S.bench] || []).slice();
if (S.filterModel !== "__all__") rows = rows.filter(r => r.model === S.filterModel);
if (S.neonOnly) rows = rows.filter(r => r.is_neon);
if (!S.showDQ) rows = rows.filter(r => !bt.dq[r.candidate_id]);
flagFor = r => ({ pareto: paretoSet.has(r.candidate_id), dq: bt.dq[r.candidate_id] });
descCols = [
compCol("emb", "Embedding"),
compCol("bm25", "BM25"),
compCol("splade", "SPLADE"),
compCol("web", "Web"),
{ key: "model", head: "model", thClass: "txt lbl sortable",
tip: glossTip("model", "\u201cno model\u201d = retrieval-only pipeline (no LLM generation step)."),
render: r => modelCell(r, flagFor(r)),
sortVal: r => ({ s: modelName(CANDS[r.candidate_id]) }) },
{ key: "reranker", head: "reranker", thClass: "sortable",
tip: glossTip("reranker"),
render: r => rerankerCell(r),
sortVal: r => ({ s: r.reranker || "" }) },
{ key: "dq", head: "DQ", thClass: "dq-col sortable",
tip: glossTip("DQ"),
render: r => dqCell(flagFor(r).dq),
sortVal: r => ({ s: flagFor(r).dq || "" }) },
];
} else {
rows = (aggByCand[S.cand] || []).slice();
flagFor = r => {
const bt = D.bench_tables[r.benchmark] || { pareto: [], dq: {} };
return { pareto: bt.pareto.includes(r.candidate_id), dq: bt.dq[r.candidate_id] };
};
// Mirror the By-benchmark column structure (retriever components, reranker,
// DQ + metric columns) so both modes look and behave the same; the model is
// fixed here, so the "benchmark dataset" column takes that slot.
descCols = [
compCol("emb", "Embedding"),
compCol("bm25", "BM25"),
compCol("splade", "SPLADE"),
compCol("web", "Web"),
{ key: "bench", head: "benchmark dataset", thClass: "txt lbl sortable",
tip: "benchmark dataset
The evaluation dataset for this row.",
render: r => {
const td = el("td", { class: "txt" });
if (flagFor(r).pareto) td.appendChild(el("span", { class: "star", text: "★ " }));
td.appendChild(el("span", { class: "pipe", text: benchShort(r.benchmark) }));
return bindTip(td, "" + r.benchmark + "");
},
sortVal: r => ({ s: r.benchmark }) },
{ key: "reranker", head: "reranker", thClass: "sortable",
tip: glossTip("reranker"),
render: r => rerankerCell(r),
sortVal: r => ({ s: r.reranker || "" }) },
{ key: "dq", head: "DQ", thClass: "dq-col sortable",
tip: glossTip("DQ"),
render: r => dqCell(flagFor(r).dq),
sortVal: r => ({ s: flagFor(r).dq || "" }) },
];
}
const metricDefs = activeMetricCols(rows);
const ranges = {};
metricDefs.forEach(m => {
const vs = rows.map(r => r[m.field]).filter(v => v != null && v !== "");
ranges[m.field] = vs.length ? { min: Math.min(...vs), max: Math.max(...vs) } : null;
});
const metricCols = metricDefs.map(m => ({
key: m.field, head: m.label, thClass: "sortable",
tip: glossTip(m.tip, m.higher ? "Higher is better." : "Lower is better."),
render: r => {
const v = r[m.field];
const td = el("td", { text: mnum(v, m) });
if (S.heat && ranges[m.field]) td.style.cssText = heatStyle(v, ranges[m.field].min, ranges[m.field].max, m.higher);
return td;
},
sortVal: r => ({ n: r[m.field] }),
}));
const columns = descCols.concat(metricCols);
const colMap = {};
columns.forEach(c => { colMap[c.key] = c; });
// every column is sortable, with up to three tie-break levels
if (!colMap[S.sortKey]) S.sortKey = columns[0].key;
const specs = [{ key: S.sortKey, dir: S.sortDir }];
if (S.sortKey2 && colMap[S.sortKey2] && S.sortKey2 !== S.sortKey)
specs.push({ key: S.sortKey2, dir: S.sortDir2 });
if (S.sortKey3 && colMap[S.sortKey3] && S.sortKey3 !== S.sortKey && S.sortKey3 !== S.sortKey2)
specs.push({ key: S.sortKey3, dir: S.sortDir3 });
// keep the three dropdowns + direction arrows in sync
const fillSel = (sel, val, withNone) => {
sel.innerHTML = "";
if (withNone) sel.appendChild(el("option", { value: "", text: "— none —" }));
columns.forEach(c => sel.appendChild(el("option", { value: c.key, text: c.head })));
sel.value = val;
};
fillSel(sortSel, S.sortKey, false);
fillSel(sortSel2, colMap[S.sortKey2] ? S.sortKey2 : "", true);
fillSel(sortSel3, colMap[S.sortKey3] ? S.sortKey3 : "", true);
$("#sortDir").textContent = S.sortDir < 0 ? "▾" : "▴";
$("#sortDir2").textContent = S.sortDir2 < 0 ? "▾" : "▴";
$("#sortDir3").textContent = S.sortDir3 < 0 ? "▾" : "▴";
const cmpSpec = (a, b, spec) => {
const va = colMap[spec.key].sortVal(a), vb = colMap[spec.key].sortVal(b);
if ("n" in va) {
const x = va.n, y = vb.n;
if (x == null && y == null) return 0;
if (x == null) return 1; if (y == null) return -1;
return (x - y) * spec.dir;
}
const x = va.s, y = vb.s;
return x < y ? spec.dir : x > y ? -spec.dir : 0;
};
rows.sort((a, b) => {
for (const spec of specs) { const r = cmpSpec(a, b, spec); if (r) return r; }
return 0;
});
const thead = el("thead");
const htr = el("tr");
columns.forEach(c => {
const arrow = S.sortKey === c.key ? " " + (S.sortDir < 0 ? "▼" : "▲") + "" : "";
const th = el("th", { class: c.thClass || "sortable", html: c.head + arrow });
th.addEventListener("click", () => sortByCol(c.key));
htr.appendChild(bindTip(th, c.tip));
});
thead.appendChild(htr); table.appendChild(thead);
const tb = el("tbody");
if (!rows.length) { tb.appendChild(el("tr", null, el("td", { colspan: columns.length, class: "empty", text: "No rows match the current filters." }))); }
rows.forEach(r => {
const tr = el("tr", { class: r.is_neon ? "neon" : "" });
columns.forEach(c => tr.appendChild(c.render(r)));
tb.appendChild(tr);
});
table.appendChild(tb);
}
function sortByCol(k) {
if (S.sortKey === k) S.sortDir *= -1;
else { S.sortKey = k; S.sortDir = defDir(k); }
if ([...sortSel.options].some(o => o.value === k)) sortSel.value = k;
$("#sortDir").textContent = S.sortDir < 0 ? "▾" : "▴";
render();
}
function modelCell(r, flag) {
const c = CANDS[r.candidate_id];
const td = el("td", { class: "txt" });
td.appendChild(el("span", { class: "pipe" }, el("b", { text: modelName(c) })));
if (flag.pareto) td.appendChild(el("span", { class: "star", text: "★", style: "margin-left:6px" }));
const head = c.is_retrieval_only
? "no model
Retrieval-only pipeline \u2014 the \u201cretrieval-only\u201d candidate runs no LLM generation step."
: "" + c.model + "" + (c.model_repo ? "
repo: " + c.model_repo : "");
return bindTip(td, head +
(flag.pareto ? "
\u2605 On the Pareto front (not dominated on accuracy / latency / build-cost)." : ""));
}
const DQ_REASON = {
latency: "p50 / average latency over a profile's budget.",
cost: "cost per query over a profile's ceiling.",
accuracy: "MRR or generation score below a profile's floor.",
};
// Severity mapped onto the shared heat ramp: accuracy is the most important
// gate (worst failure -> blue, t=0), cost is middle, latency is least
// important (second-best -> t=0.75). The best colour (t=1, green) is reserved
// for pipelines that pass every gate.
const DQ_T = { accuracy: 0, cost: 0.5, latency: 0.75 };
function dqBadge(text, t) {
return el("span", {
class: "badge dq-heat", text: text,
style: "background:" + heatColor(t) + ";color:" + heatInk() + ";border:1px solid rgba(128,128,128,.25)",
});
}
function dqCell(reason) {
const td = el("td", { class: "dq-col" });
if (reason) {
td.appendChild(dqBadge(reason, DQ_T[reason] != null ? DQ_T[reason] : 0));
return bindTip(td, "DQ \u2014 " + reason + "
" + (DQ_REASON[reason] || "") +
"
Reason shown is from the first profile that disqualified this pipeline; other profiles may flag a different gate.");
}
td.appendChild(dqBadge("\u2713", 1));
return bindTip(td, "Passes every profile's hard gates (not disqualified).");
}
// Build the retriever component badges (reused across Compare/Picks/Models/Metrics).
function retrieverBadgeEls(name) {
const meta = (D.retrievers || {})[name];
if (!meta || !meta.components.length) return [el("span", { class: "pipe", text: name })];
return meta.components.map(cp => {
const b = el("span", { class: "rbadge " + cp.key, text: cp.label });
if (cp.detail) b.appendChild(el("small", { text: cp.detail }));
return b;
});
}
function retrieverTip(name) {
const meta = (D.retrievers || {})[name];
return "" + name + "" + (meta ? "
" + meta.summary : "");
}
function rerankerTip(c) {
return "" + c.reranker + "" +
(c.reranker_model ? "
" + c.reranker_model : (c.reranker === "none" ? "
No reranking applied." : ""));
}
function retrieverCell(r) {
const td = el("td", { class: "txt" });
retrieverBadgeEls(r.retriever).forEach(b => td.appendChild(b));
return bindTip(td, retrieverTip(r.retriever));
}
function rerankerCell(r) {
const c = CANDS[r.candidate_id];
const td = el("td", { class: "rerank-col", text: r.reranker });
return bindTip(td, rerankerTip(c));
}
// ===================================================================
// Picks render
// ===================================================================
const VCLASS = { "winner clear": "v-clear", "inconclusive": "v-inconclusive", "all disqualified": "v-dq", "no winner": "v-none", "no signal": "v-none" };
function renderPicks() {
const table = $("#picksTable"); table.innerHTML = "";
const profs = D.profiles;
const thead = el("thead"); const htr = el("tr");
htr.appendChild(el("th", { class: "txt", text: "benchmark", style: "text-align:left" }));
profs.forEach(p => {
const extra = "Hard gates: " + (p.gates.join(" · ") || "—") + "
Ranks on: " + p.metric +
(p.corpus_profile ? "
Corpus: " + p.corpus_profile : "") +
(p.deployment_constraint ? "
Deploy: " + p.deployment_constraint : "");
htr.appendChild(bindTip(el("th", { html: p.name.replace(/_/g, " ") }), glossTip("profile", extra)));
});
thead.appendChild(htr); table.appendChild(thead);
const tb = el("tbody");
BENCH.forEach(b => {
const tr = el("tr");
tr.appendChild(bindTip(el("th", { text: benchShort(b) }), "" + b + ""));
const row = D.picks[b] || {};
profs.forEach(p => {
const cell = row[p.name];
const td = el("td");
if (cell && cell.pick) {
const c = CANDS[cell.pick];
const wrap = el("div");
const line = el("div", { style: "display:flex;align-items:center;gap:5px;margin-bottom:4px" });
line.appendChild(el("span", { text: c ? modelName(c) : cell.model, style: "font-family:var(--mono);font-size:11.5px" }));
if (c && c.is_neon) line.appendChild(el("span", { class: "badge neon", text: "NEON" }));
wrap.appendChild(line);
const pl = el("div", { style: "display:flex;align-items:center;gap:3px;flex-wrap:wrap;margin-bottom:4px" });
retrieverBadgeEls(cell.retriever).forEach(b => pl.appendChild(b));
if (c && c.reranker && c.reranker !== "none") pl.appendChild(el("span", { class: "cell-sub", text: "· " + c.reranker }));
wrap.appendChild(bindTip(pl, retrieverTip(cell.retriever) + (c && c.reranker !== "none" ? "
" + rerankerTip(c) : "")));
const mvLabel = cell.metric === "generation_acc" ? "gen" : "H@1";
const subParts = [];
const mrrS = num(cell.mrr, "f3"); if (mrrS !== "") subParts.push("MRR " + mrrS);
const mvS = num(cell.metric_val, "f2"); if (mvS !== "") subParts.push(mvLabel + " " + mvS);
const p50S = num(cell.p50, "g0"); if (p50S !== "") subParts.push("p50 " + p50S + "ms");
wrap.appendChild(bindTip(el("span", { class: "verdict " + (VCLASS[cell.verdict] || "v-none"), text: cell.verdict }),
glossTip("verdict") ));
wrap.appendChild(el("span", { class: "cell-sub", text: subParts.join(" · ") }));
td.appendChild(wrap);
} else {
td.appendChild(el("span", { class: "verdict " + (VCLASS[(cell && cell.verdict)] || "v-dq"), text: (cell && cell.verdict) || "—" }));
}
tr.appendChild(td);
});
tb.appendChild(tr);
});
table.appendChild(tb);
}
// ===================================================================
// Models render
// ===================================================================
const modelPageCombo = Combo($("#modelPageCombo"), { options: candOptions(), value: DEFAULT_CAND, width: 240, onChange: v => { S.pageCand = v; render(); } });
S.pageCand = DEFAULT_CAND;
function renderModels() {
const host = $("#modelPage"); host.innerHTML = "";
const id = S.pageCand; const c = CANDS[id];
const rows = (aggByCand[id] || []).slice().sort((a, b) => benchShort(a.benchmark) < benchShort(b.benchmark) ? -1 : 1);
$("#modelPageBadge").innerHTML = c.is_neon ? "NEON.ai model" : (c.is_retrieval_only ? "retrieval baseline" : "");
// aggregate stats
const mean = f => { const vs = rows.map(r => r[f]).filter(v => v != null); return vs.length ? vs.reduce((a, b) => a + b, 0) / vs.length : null; };
let paretoCount = 0; BENCH.forEach(b => { const bt = D.bench_tables[b]; if (bt && bt.pareto.includes(id)) paretoCount++; });
let dqCount = 0; BENCH.forEach(b => { const bt = D.bench_tables[b]; if (bt && bt.dq[id]) dqCount++; });
// left card
const left = el("div", { class: "card" });
left.appendChild(el("h3", { style: "margin:0 0 10px;font-size:14px", text: modelName(c) }));
const retV = el("span", { class: "v", style: "display:flex;flex-wrap:wrap;justify-content:flex-end;gap:3px" });
retrieverBadgeEls(c.retriever).forEach(b => retV.appendChild(b));
left.appendChild(bindTip(el("div", { class: "kv" }, [el("span", { class: "k", text: "retriever" }), retV]), retrieverTip(c.retriever)));
const kvs = [
["reranker", c.reranker],
["model repo", c.model_repo || "—"],
["serving", c.model_adapter || "—"],
["benchmarks", String(rows.length)],
["type", c.is_neon ? "Neon.ai model" : (c.is_retrieval_only ? "retrieval-only" : "external")],
];
kvs.forEach(([k, v]) => left.appendChild(el("div", { class: "kv" }, [el("span", { class: "k", text: k }), el("span", { class: "v", text: v })])));
const stats = el("div", { class: "stat-row", style: "margin-top:14px" });
const stat = (n, l, tipTerm) => { const s = el("div", { class: "stat" }, [el("div", { class: "n", text: n }), bindTip(el("div", { class: "l", text: l }), glossTip(tipTerm))]); stats.appendChild(s); };
stat(num(mean("mrr"), "f3"), "mean MRR", "MRR");
const gm = mean("generation_acc"); stat(gm == null ? "—" : num(gm, "f2"), "mean gen", "gen");
stat(num(mean("p50_retrieval_latency_ms"), "g0"), "p50 ms", "P50");
stat(String(paretoCount), "Pareto ★", "Pareto");
stat(String(dqCount), "DQ count", "DQ");
left.appendChild(stats);
host.appendChild(left);
// right card: metrics across benchmarks
const right = el("div", { class: "card scroll" });
const cols = activeMetricCols(rows);
const table = el("table");
const thead = el("thead"); const htr = el("tr");
htr.appendChild(el("th", { class: "txt", text: "benchmark", style: "text-align:left;position:sticky;top:0;background:var(--bg-elev)" }));
htr.appendChild(bindTip(el("th", { class: "dq-col", html: "DQ", style: "position:sticky;top:0;background:var(--bg-elev)" }), glossTip("DQ")));
cols.forEach(m => htr.appendChild(bindTip(el("th", { html: m.label, style: "position:sticky;top:0;background:var(--bg-elev)" }), glossTip(m.tip, m.higher ? "Higher is better." : "Lower is better."))));
thead.appendChild(htr); table.appendChild(thead);
const ranges = {}; cols.forEach(m => { const vs = rows.map(r => r[m.field]).filter(v => v != null); ranges[m.field] = vs.length ? { min: Math.min(...vs), max: Math.max(...vs) } : null; });
const tb = el("tbody");
rows.forEach(r => {
const bt = D.bench_tables[r.benchmark];
const tr = el("tr");
const star = bt && bt.pareto.includes(id) ? el("span", { class: "star", text: "★ " }) : null;
const tdL = el("td", { class: "txt" }); if (star) tdL.appendChild(star); tdL.appendChild(el("span", { text: benchShort(r.benchmark) }));
tr.appendChild(tdL);
tr.appendChild(dqCell(bt && bt.dq[id]));
cols.forEach(m => { const v = r[m.field]; const td = el("td", { text: mnum(v, m) }); if (ranges[m.field]) td.style.cssText = heatStyle(v, ranges[m.field].min, ranges[m.field].max, m.higher); tr.appendChild(td); });
tb.appendChild(tr);
});
table.appendChild(tb); right.appendChild(table); host.appendChild(right);
}
// ===================================================================
// Metrics render
// ===================================================================
const metricSortSel = $("#metricSortSel");
function fillMetricSort() {
metricSortSel.innerHTML = "";
metricSortSel.appendChild(el("option", { value: "name", text: "Model (A–Z)" }));
METRICS.forEach(m => metricSortSel.appendChild(el("option", { value: m.key, text: m.label })));
metricSortSel.value = S.metricSort;
}
fillMetricSort();
metricSortSel.addEventListener("change", () => { S.metricSort = metricSortSel.value; render(); });
$$("#metricModeSeg button").forEach(b => b.addEventListener("click", () => { S.metricMode = b.dataset.mode; $$("#metricModeSeg button").forEach(x => x.classList.toggle("active", x === b)); render(); }));
$("#metricNeonOnly").addEventListener("change", e => { S.metricNeonOnly = e.target.checked; render(); });
$("#metricHeat").addEventListener("change", e => { S.metricHeat = e.target.checked; render(); });
function renderMetrics() {
const table = $("#metricsTable"); table.innerHTML = "";
const stats = D.metric_stats; // key -> cid -> {wins,losses,mean,count}
let ids = CAND_IDS.slice();
if (S.metricNeonOnly) ids = ids.filter(id => CANDS[id].is_neon);
// sort rows
if (S.metricSort === "name") ids.sort((a, b) => pipeLabel(CANDS[a]) < pipeLabel(CANDS[b]) ? -1 : 1);
else {
const mdef = METRICS.find(m => m.key === S.metricSort);
const st = stats[S.metricSort] || {};
ids.sort((a, b) => {
const sa = st[a], sb = st[b];
const va = S.metricMode === "winloss" ? (sa ? sa.wins - sa.losses : -1e9) : (sa && sa.mean != null ? sa.mean : (mdef.higher ? -1e9 : 1e9));
const vb = S.metricMode === "winloss" ? (sb ? sb.wins - sb.losses : -1e9) : (sb && sb.mean != null ? sb.mean : (mdef.higher ? -1e9 : 1e9));
return S.metricMode === "winloss" ? (vb - va) : ((vb - va) * (mdef.higher ? 1 : -1));
});
}
const thead = el("thead"); const htr = el("tr");
htr.appendChild(el("th", { class: "txt", text: "pipeline", style: "text-align:left;position:sticky;left:0;z-index:6" }));
METRICS.forEach(m => htr.appendChild(bindTip(el("th", { html: m.label }), glossTip(m.tip, m.higher ? "Higher is better." : "Lower is better."))));
thead.appendChild(htr); table.appendChild(thead);
// ranges for mean heat per metric
const ranges = {};
METRICS.forEach(m => { const vs = ids.map(id => (stats[m.key][id] || {}).mean).filter(v => v != null); ranges[m.key] = vs.length ? { min: Math.min(...vs), max: Math.max(...vs) } : null; });
const tb = el("tbody");
ids.forEach(id => {
const c = CANDS[id];
const tr = el("tr", { class: c.is_neon ? "neon" : "" });
const th = el("th", { style: "font-size:11.5px" });
const idLine = el("div", { style: "display:flex;align-items:center;gap:5px;white-space:nowrap" });
idLine.appendChild(el("span", { text: modelName(c), style: "font-family:var(--mono)" }));
if (c.is_neon) idLine.appendChild(el("span", { class: "badge neon", text: "NEON" }));
retrieverBadgeEls(c.retriever).forEach(b => idLine.appendChild(b));
if (c.reranker !== "none") idLine.appendChild(el("span", { class: "cell-sub", text: c.reranker }));
th.appendChild(idLine);
bindTip(th, "" + pipeLabel(c) + "" + (c.model_repo ? "
repo: " + c.model_repo : "") + "
" + retrieverTip(c.retriever));
tr.appendChild(th);
METRICS.forEach(m => {
const s = (stats[m.key] || {})[id];
const td = el("td");
if (!s) { td.textContent = ""; }
else if (S.metricMode === "winloss") {
td.innerHTML = "" + s.wins + " – " + s.losses + "";
const net = s.wins - s.losses;
if (S.metricHeat) td.style.cssText = heatStyle(net, -3, 3, true);
} else {
td.textContent = mnum(s.mean, m);
if (S.metricHeat && ranges[m.key]) td.style.cssText = heatStyle(s.mean, ranges[m.key].min, ranges[m.key].max, m.higher);
}
tr.appendChild(td);
});
tb.appendChild(tr);
});
table.appendChild(tb);
}
// ===================================================================
// Guide render
// ===================================================================
function renderGuide() {
const host = $("#guideGrid"); host.innerHTML = "";
// left: glossary
const left = el("div", { class: "guide-col" });
left.appendChild(el("h3", { text: "Metrics glossary" }));
const gt = el("table", { class: "gloss" });
const order = ["MRR", "H@1", "H@5", "nDCG", "P50", "P95", "build", "gen", "gen ms", "tok/s", "gen $", "$/kq", "par", "shift", "n", "Pareto", "DQ", "verdict"];
order.forEach(k => { if (GLOSS[k]) gt.appendChild(el("tr", null, [el("td", { class: "term", text: k }), el("td", { class: "def", text: GLOSS[k] })])); });
left.appendChild(gt); host.appendChild(left);
// right: profiles + provenance
const right = el("div", { class: "guide-col" });
right.appendChild(el("h3", { text: "Client profiles (hard gates)" }));
D.profiles.forEach(p => {
const box = el("div", { class: "prof" });
box.appendChild(el("h4", { text: p.name.replace(/_/g, " ") + " — ranks on " + p.metric }));
const gates = el("div", { class: "gates" });
(p.gates.length ? p.gates : ["no hard gates"]).forEach(g => gates.appendChild(el("span", { class: "gate", text: g })));
box.appendChild(gates);
const sub = [];
if (p.corpus_profile) sub.push("corpus: " + p.corpus_profile);
if (p.deployment_constraint) sub.push("deploy: " + p.deployment_constraint);
if (sub.length) box.appendChild(el("div", { style: "color:var(--text-faint);font-size:11px;margin-top:6px", text: sub.join(" · ") }));
right.appendChild(box);
});
right.appendChild(el("h3", { text: "Provenance", style: "margin-top:10px" }));
const pv = el("div", { class: "prof" });
const sources = (prov.merged_from || []);
pv.appendChild(el("div", { style: "font-size:11.5px;color:var(--text-dim)", text: "Type: " + (prov.weekly ? "weekly roster sweep" : "sweep") }));
if (prov.merged_at) pv.appendChild(el("div", { style: "font-size:11.5px;color:var(--text-dim)", text: "Merged at: " + prov.merged_at }));
sources.forEach(s => pv.appendChild(el("div", { style: "font-family:var(--mono);font-size:10.5px;color:var(--text-faint);margin-top:3px", text: s })));
right.appendChild(pv);
host.appendChild(right);
}
// ===================================================================
// Theme
// ===================================================================
function applyTheme(t) {
document.documentElement.setAttribute("data-theme", t);
try { localStorage.setItem("nlb-theme", t); } catch (e) {}
paintLegendSwatches(); render();
}
$("#themeBtn").addEventListener("click", () => applyTheme(document.documentElement.getAttribute("data-theme") === "light" ? "dark" : "light"));
let savedTheme = "dark"; try { savedTheme = localStorage.getItem("nlb-theme") || "dark"; } catch (e) {}
const qTheme = new URLSearchParams(location.search).get("theme");
if (qTheme === "light" || qTheme === "dark") savedTheme = qTheme;
document.documentElement.setAttribute("data-theme", savedTheme);
// ===================================================================
// Master render
// ===================================================================
function render() {
if (S.tab === "compare") renderCompare();
else if (S.tab === "picks") renderPicks();
else if (S.tab === "models") renderModels();
else if (S.tab === "metrics") renderMetrics();
else if (S.tab === "guide") renderGuide();
}
paintLegendSwatches();
const initTab = (location.hash || "").replace("#", "");
if (["compare", "picks", "models", "metrics", "guide"].includes(initTab)) setTab(initTab);
else render();
})();