/* MuDABench viewer — vanilla JS, two tabs: Corpus + Eval. */
(function () {
"use strict";
var $ = function (id) { return document.getElementById(id); };
function esc(s) {
if (s === null || s === undefined) return "";
return String(s)
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """);
}
function fmtVal(v) {
if (v === null || v === undefined) return 'null';
if (v === true) return 'true';
if (v === false) return 'false';
return esc(String(v));
}
function shortId(id) { return id ? String(id).slice(0, 8) : ""; }
var state = {
mode: "corpus",
corpus: [], // all docs
corpusView: [], // filtered docs
corpusIdx: 0,
byId: {}, // id -> corpus doc
questions: [], // all questions
evalView: [], // filtered questions
evalIdx: 0,
};
/* ---------------- data loading ---------------- */
function loadAll() {
return Promise.all([
fetch("corpus_index.json").then(function (r) { return r.json(); }),
fetch("eval.json").then(function (r) { return r.json(); }),
]).then(function (res) {
state.corpus = res[0] || [];
state.questions = res[1] || [];
state.corpus.forEach(function (d) { state.byId[d.id] = d; });
});
}
/* ---------------- corpus tab ---------------- */
function populateCorpusFilters() {
var types = {}, years = {};
state.corpus.forEach(function (d) {
if (d.doctype) types[d.doctype] = true;
if (d.year !== null && d.year !== undefined && d.year !== "") years[d.year] = true;
});
var tf = $("docTypeFilter"), yf = $("yearFilter");
Object.keys(types).sort().forEach(function (t) {
var o = document.createElement("option"); o.value = t; o.textContent = t; tf.appendChild(o);
});
Object.keys(years).sort().forEach(function (y) {
var o = document.createElement("option"); o.value = y; o.textContent = y; yf.appendChild(o);
});
}
function filterCorpus() {
var q = $("corpusFilter").value.trim().toLowerCase();
var typ = $("docTypeFilter").value;
var yr = $("yearFilter").value;
state.corpusView = state.corpus.filter(function (d) {
if (typ && d.doctype !== typ) return false;
if (yr && String(d.year) !== yr) return false;
if (q) {
var hay = (d.title + " " + (d.symbol || "") + " " + (d.id || "")).toLowerCase();
if (hay.indexOf(q) === -1) return false;
}
return true;
});
if (state.corpusIdx >= state.corpusView.length) state.corpusIdx = 0;
rebuildDocSelect();
renderCorpus();
}
function rebuildDocSelect() {
var sel = $("docSelect");
sel.innerHTML = "";
state.corpusView.forEach(function (d, i) {
var o = document.createElement("option");
o.value = String(i);
o.textContent = d.title + " · " + shortId(d.id);
sel.appendChild(o);
});
sel.value = String(state.corpusIdx);
}
function renderCorpus() {
var meta = $("docMetaCard");
var frame = $("pdfFrame");
if (!state.corpusView.length) {
meta.innerHTML = '
No documents match the filter.
';
frame.removeAttribute("src");
$("corpusCounter").textContent = "0 / 0";
return;
}
var d = state.corpusView[state.corpusIdx];
$("docSelect").value = String(state.corpusIdx);
$("corpusCounter").textContent = (state.corpusIdx + 1) + " / " + state.corpusView.length;
var pills = [];
if (d.symbol) pills.push('Symbol: ' + esc(d.symbol) + "");
if (d.year !== null && d.year !== undefined && d.year !== "") pills.push('Year: ' + esc(d.year) + "");
if (d.doctype) pills.push('Type: ' + esc(d.doctype) + "");
pills.push('Cited by ' + (d.n_refs || 0) + " question(s)");
pills.push('' + esc(d.id) + "");
var link = 'open PDF ↗';
var fieldsHtml = "";
if (d.fields && d.fields.length) {
var rows = d.fields.map(function (f) {
var vals = (f.values || []).map(fmtVal).join(", ");
return "| " + esc(f.name) + " | " +
"" + (vals || "") + " | " +
"" + esc(f.desc || "") + " |
";
}).join("");
fieldsHtml =
'' +
"| Field | Value(s) | Description | " +
"
" + rows + "
";
}
var refsHtml = "";
if (d.referenced_by && d.referenced_by.length) {
var refPills = d.referenced_by.map(function (r) {
return '' + esc(shortId(r.qid)) + ' ' + esc(r.dataset) + "";
}).join("");
refsHtml =
'Referenced by ' + d.referenced_by.length +
" question(s)
" + refPills + "
";
}
meta.innerHTML =
"" + esc(d.title) + "
" +
'' + pills.join("") + link + "
" +
fieldsHtml + refsHtml;
// wire ref pills -> jump to that question in the Eval tab
Array.prototype.forEach.call(meta.querySelectorAll(".ref-pill"), function (el) {
el.addEventListener("click", function () {
setMode("eval");
selectQuestion(this.getAttribute("data-ds"), this.getAttribute("data-qid"));
});
});
frame.src = d.pdf;
}
function selectDocById(id) {
// reset corpus filters so the target doc is guaranteed visible
$("corpusFilter").value = "";
$("docTypeFilter").value = "";
$("yearFilter").value = "";
state.corpusView = state.corpus.slice();
var idx = 0;
for (var i = 0; i < state.corpusView.length; i++) {
if (state.corpusView[i].id === id) { idx = i; break; }
}
state.corpusIdx = idx;
rebuildDocSelect();
renderCorpus();
}
/* ---------------- eval tab ---------------- */
function filterEval() {
var q = $("evalSearch").value.trim().toLowerCase();
var ds = $("datasetFilter").value;
state.evalView = state.questions.filter(function (x) {
if (ds && x.dataset !== ds) return false;
if (q) {
var docTitles = (x.docs || []).map(function (d) { return d.title + " " + (d.symbol || ""); }).join(" ");
var hay = [x.question, x.final_answer, x.qid, docTitles].join(" ").toLowerCase();
if (hay.indexOf(q) === -1) return false;
}
return true;
});
if (state.evalIdx >= state.evalView.length) state.evalIdx = 0;
rebuildQSelect();
renderEval();
}
function rebuildQSelect() {
var sel = $("qSelect");
sel.innerHTML = "";
state.evalView.forEach(function (x, i) {
var o = document.createElement("option");
o.value = String(i);
var q = (x.question || "").replace(/\s+/g, " ");
if (q.length > 70) q = q.slice(0, 70) + "…";
o.textContent = "[" + x.dataset + "] " + q;
sel.appendChild(o);
});
sel.value = String(state.evalIdx);
}
function field(lbl, valHtml) {
return '' + esc(lbl) + '
' + valHtml + "
";
}
function renderEval() {
var card = $("evalCard");
if (!state.evalView.length) {
card.innerHTML = 'No questions match the search.
';
$("evalCounter").textContent = "0 / 0";
return;
}
var x = state.evalView[state.evalIdx];
$("qSelect").value = String(state.evalIdx);
$("evalCounter").textContent = (state.evalIdx + 1) + " / " + state.evalView.length;
var badges =
'' + esc(x.qid) + "" +
'' + esc(x.dataset) + "";
// supporting facts (source_answer)
var facts = x.source_answer || [];
var factsHtml = facts.length
? '' + facts.map(function (f) { return "- " + esc(f) + "
"; }).join("") + "
"
: 'none';
// supporting documents
var docs = x.docs || [];
var docsHtml = docs.map(function (d) {
var fields = (d.fields || []).map(function (f) {
return '' + esc(f.name) + '' +
'' + fmtVal(f.value) + "" +
(f.desc ? '' + esc(f.desc) + "" : "") + "
";
}).join("");
return '' +
'
" +
(fields ? '
' + fields + "
" : "") +
"
";
}).join("");
card.innerHTML =
'' + badges + "
" +
"" + esc(x.question) + "
" +
'Final answer (gold)
' +
esc(x.final_answer) + "
" +
field("Supporting facts (source_answer)", factsHtml) +
field("Supporting documents (" + docs.length + ")", docsHtml ||
'none');
// wire doc links -> jump to Corpus tab
Array.prototype.forEach.call(card.querySelectorAll("a.doclink[data-doc-id]"), function (el) {
el.addEventListener("click", function () {
setMode("corpus");
selectDocById(this.getAttribute("data-doc-id"));
});
});
}
function selectQuestion(dataset, qid) {
$("evalSearch").value = "";
$("datasetFilter").value = "";
state.evalView = state.questions.slice();
var idx = 0;
for (var i = 0; i < state.evalView.length; i++) {
if (state.evalView[i].qid === qid && state.evalView[i].dataset === dataset) { idx = i; break; }
}
state.evalIdx = idx;
rebuildQSelect();
renderEval();
}
/* ---------------- mode switching ---------------- */
function setMode(mode) {
state.mode = mode;
$("modeCorpusBtn").classList.toggle("active", mode === "corpus");
$("modeEvalBtn").classList.toggle("active", mode === "eval");
$("corpusControls").style.display = mode === "corpus" ? "" : "none";
$("evalControls").style.display = mode === "eval" ? "" : "none";
$("corpusView").style.display = mode === "corpus" ? "flex" : "none";
$("evalView").style.display = mode === "eval" ? "block" : "none";
}
/* ---------------- wiring ---------------- */
function wire() {
$("modeCorpusBtn").addEventListener("click", function () { setMode("corpus"); });
$("modeEvalBtn").addEventListener("click", function () { setMode("eval"); });
// corpus
$("corpusFilter").addEventListener("input", filterCorpus);
$("docTypeFilter").addEventListener("change", filterCorpus);
$("yearFilter").addEventListener("change", filterCorpus);
$("docSelect").addEventListener("change", function () {
state.corpusIdx = parseInt(this.value, 10) || 0;
renderCorpus();
});
$("corpusPrevBtn").addEventListener("click", function () {
if (state.corpusIdx > 0) { state.corpusIdx--; renderCorpus(); }
});
$("corpusNextBtn").addEventListener("click", function () {
if (state.corpusIdx < state.corpusView.length - 1) { state.corpusIdx++; renderCorpus(); }
});
// eval
$("evalSearchBtn").addEventListener("click", filterEval);
$("evalSearch").addEventListener("keydown", function (e) { if (e.key === "Enter") filterEval(); });
$("evalClearBtn").addEventListener("click", function () {
$("evalSearch").value = ""; $("datasetFilter").value = ""; filterEval();
});
$("datasetFilter").addEventListener("change", filterEval);
$("qSelect").addEventListener("change", function () {
state.evalIdx = parseInt(this.value, 10) || 0;
renderEval();
});
$("evalPrevBtn").addEventListener("click", function () {
if (state.evalIdx > 0) { state.evalIdx--; renderEval(); }
});
$("evalNextBtn").addEventListener("click", function () {
if (state.evalIdx < state.evalView.length - 1) { state.evalIdx++; renderEval(); }
});
// keyboard arrows
document.addEventListener("keydown", function (e) {
var tag = (e.target.tagName || "").toLowerCase();
if (tag === "input" || tag === "select" || tag === "textarea") return;
if (e.key === "ArrowLeft") {
if (state.mode === "corpus") $("corpusPrevBtn").click();
else $("evalPrevBtn").click();
} else if (e.key === "ArrowRight") {
if (state.mode === "corpus") $("corpusNextBtn").click();
else $("evalNextBtn").click();
}
});
}
/* ---------------- boot ---------------- */
loadAll().then(function () {
$("loading").style.display = "none";
$("sidebarFooter").innerHTML =
state.corpus.length + " documents · " + state.questions.length + " questions
" +
'GitHub · ' +
'HF dataset · ' +
'arXiv';
populateCorpusFilters();
wire();
setMode("corpus");
filterCorpus();
filterEval();
}).catch(function (err) {
$("loading").textContent = "Failed to load data: " + err;
});
})();