"use strict"; const tabs = [...document.querySelectorAll('[role="tab"]')]; function selectTab(tab) { tabs.forEach(item => { const selected = item === tab; item.setAttribute("aria-selected", String(selected)); item.tabIndex = selected ? 0 : -1; document.getElementById(item.getAttribute("aria-controls")).hidden = !selected; }); if (tab.id === "pdf-tab") { const viewer = document.getElementById("pdf-viewer"); if (!viewer.hasAttribute("src")) viewer.src = viewer.dataset.src; } } tabs.forEach((tab, index) => { tab.addEventListener("click", () => selectTab(tab)); tab.addEventListener("keydown", event => { if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return; event.preventDefault(); const next = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : tabs[(index + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length]; selectTab(next); next.focus(); }); }); const search = document.getElementById("search"); const status = document.getElementById("search-status"); const clear = document.getElementById("clear-search"); const sections = [...document.querySelectorAll(".paper-section")]; const links = [...document.querySelectorAll(".contents nav a")]; const original = new Map(sections.map(section => [section, section.innerHTML])); const plain = new Map(sections.map(section => [section, section.textContent.toLocaleLowerCase()])); function filterSections() { const query = search.value.trim().toLocaleLowerCase(); let count = 0; sections.forEach(section => { section.innerHTML = original.get(section); const matches = !query || plain.get(section).includes(query); section.hidden = !matches; const link = links.find(item => item.getAttribute("href") === `#${section.id}`); if (link) link.hidden = !matches; if (!matches) return; count++; if (!query) return; const walker = document.createTreeWalker(section, NodeFilter.SHOW_TEXT); const nodes = []; while (walker.nextNode()) nodes.push(walker.currentNode); nodes.forEach(node => { const value = node.textContent; const lower = value.toLocaleLowerCase(); let start = 0, position = lower.indexOf(query); if (position < 0) return; const fragment = document.createDocumentFragment(); while (position >= 0) { fragment.append(document.createTextNode(value.slice(start, position))); const mark = document.createElement("mark"); mark.textContent = value.slice(position, position + query.length); fragment.append(mark); start = position + query.length; position = lower.indexOf(query, start); } fragment.append(document.createTextNode(value.slice(start))); node.replaceWith(fragment); }); }); status.textContent = query ? `${count} of ${sections.length} sections match` : `${sections.length} sections`; clear.hidden = !query; document.getElementById("no-results").hidden = count > 0; } search.addEventListener("input", filterSections); clear.addEventListener("click", () => { search.value = ""; filterSections(); search.focus(); }); links.forEach(link => link.addEventListener("click", () => { links.forEach(item => item.classList.toggle("active", item === link)); })); document.querySelector('.provenance-link').addEventListener('click', () => selectTab(tabs[0]));