(() => { // Gradio's built-in Code copy controls have empty accessible names. const labelPanes = () => { for (const [id, label] of [ ["candidate-source", "Candidate C"], ["reference-source", "Reference C"], ["original-assembly", "Original assembly"], ["candidate-assembly", "Candidate assembly"], ]) { const pane = document.getElementById(id); if (!pane) continue; const copy = pane.querySelector("button.icon-button"); if (copy && copy.getAttribute("aria-label") !== `Copy ${label}`) { copy.setAttribute("aria-label", `Copy ${label}`); copy.setAttribute("title", `Copy ${label}`); } const content = pane.querySelector(".cm-content"); if (content && content.getAttribute("aria-label") !== label) { content.setAttribute("aria-label", label); } const scroller = pane.querySelector(".cm-scroller"); if (id !== "candidate-source" && scroller && scroller.tabIndex !== 0) { scroller.tabIndex = 0; scroller.setAttribute("aria-label", `${label} scroll area`); } } }; const colorExamples = () => { for (const button of document.querySelectorAll('[id^="examples-group-"] button.gallery-item')) { const result = button.textContent.trim().match(/^(Agree|Inconclusive|Mismatch|Error) ยท /); if (result) button.dataset.expectedResult = result[1].toLowerCase(); } }; let EditorViewClass; const editorModules = new Map(); const lastHighlights = new Map(); const editorClass = async () => { if (EditorViewClass) return EditorViewClass; // Gradio bundles and exports CodeMirror with its lazy Code component. // Its Code icon has the same filename prefix and may load first. const assets = performance.getEntriesByType("resource").filter(entry => /\/Code-[\w-]+\.js(?:\?|$)/.test(entry.name)); for (const asset of assets) { if (!editorModules.has(asset.name)) { editorModules.set(asset.name, import(asset.name).catch(() => null)); } const module = await editorModules.get(asset.name); const editor = Object.values(module || {}).find(value => typeof value?.findFromDOM === "function"); if (editor) { EditorViewClass = editor; return editor; } } // The editor may still be loading; retry on the next DOM update. return null; }; const highlightWriter = async () => { const candidatePane = document.getElementById("candidate-source"); if (!candidatePane) return; const EditorView = await editorClass(); const candidateView = EditorView?.findFromDOM(candidatePane); const marker = document.querySelector("#mismatch-summary .candidate-writer-location"); const stale = document.querySelector("#verdict .stale"); const current = candidateView && marker && !stale && candidateView.state.doc.toString() === marker.dataset.source; for (const id of ["candidate-source", "original-assembly", "candidate-assembly"]) { const pane = document.getElementById(id); if (!pane) continue; const view = EditorView?.findFromDOM(pane); let lines = []; if (current && view) { if (id === "candidate-source") { lines = marker.dataset.lines.split(",").map(Number) .filter(line => line > 0 && line <= view.state.doc.lines); } else { const side = id === "original-assembly" ? "original" : "candidate"; const instructions = marker.dataset[`${side}Instruction`]?.split(",") || []; if (instructions.length) { view.state.doc.toString().split("\n").forEach((text, index) => { if (instructions.some(instruction => text.trimStart().startsWith(`${instruction}:`))) { lines.push(index + 1); } }); } } } for (const element of pane.querySelectorAll(".cm-line")) { const line = view ? view.state.doc.lineAt(view.posAtDOM(element, 0)).number : 0; const highlighted = lines.includes(line); if (element.classList.contains("memory-writer-line") !== highlighted) { element.classList.toggle("memory-writer-line", highlighted); } } const key = lines.length ? `${lines.join(",")}:${view.state.doc.toString()}` : ""; if (key && key !== lastHighlights.get(id)) { // Scroll without changing the user's selection or keyboard focus. view.dispatch({ effects: EditorView.scrollIntoView(view.state.doc.line(lines[0]).from, { y: "center" }) }); } lastHighlights.set(id, key); } }; const updateWorkbench = () => { labelPanes(); colorExamples(); highlightWriter(); }; updateWorkbench(); new MutationObserver(updateWorkbench).observe(document.body, { childList: true, subtree: true, // CodeMirror can replace a line's classes after layout without inserting // nodes. Reapply the highlight then; unchanged classes are never written. attributes: true, attributeFilter: ["class"], }); })();