(() => { "use strict"; const evidenceData = window.K1412_EVIDENCE; const evidenceList = document.querySelector("#evidence-list"); const evidenceCount = document.querySelector("#evidence-count"); const emptyEvidence = document.querySelector("#empty-evidence"); const searchInput = document.querySelector("#evidence-search"); const expandButton = document.querySelector("#expand-evidence"); const depthButtons = [...document.querySelectorAll("[data-depth]")]; const themeButtons = [...document.querySelectorAll("[data-theme]")]; const depthLabels = { core: "核心证据", support: "旁证", context: "历史背景", }; const themeLabels = { verification: "完成证明", protocol: "协议审计", recovery: "失败恢复", reliability: "风险可靠性", context: "历史背景", }; const state = { query: "", depth: "all", theme: "all", expanded: false, }; function normalize(value) { return String(value || "") .toLocaleLowerCase("zh-CN") .replace(/\s+/g, " ") .trim(); } function searchableText(record) { return normalize( [ record.id, record.title, record.depth, record.theme, record.evidence, record.supports, record.boundary, ].join(" ") ); } function filteredRecords() { if (!evidenceData || !Array.isArray(evidenceData.records)) { return []; } const terms = normalize(state.query).split(" ").filter(Boolean); return evidenceData.records.filter((record) => { if (state.depth !== "all" && record.depth !== state.depth) { return false; } if (state.theme !== "all" && record.theme !== state.theme) { return false; } const haystack = searchableText(record); return terms.every((term) => haystack.includes(term)); }); } function tag(label, className) { const element = document.createElement("span"); element.className = `evidence-tag ${className || ""}`.trim(); element.textContent = label; return element; } function detailColumn(title, text, className = "") { const wrapper = document.createElement("div"); wrapper.className = className; const heading = document.createElement("h4"); heading.textContent = title; const paragraph = document.createElement("p"); paragraph.textContent = text || "本轮未将该论文用于直接论证。"; wrapper.append(heading, paragraph); return wrapper; } function evidenceItem(record) { const details = document.createElement("details"); details.className = "evidence-item"; details.dataset.depth = record.depth; details.open = state.expanded; const summary = document.createElement("summary"); const id = document.createElement("span"); id.className = "evidence-id"; id.textContent = record.id; const heading = document.createElement("div"); heading.className = "evidence-heading"; const title = document.createElement("h3"); title.textContent = record.title; const tags = document.createElement("div"); tags.className = "evidence-tags"; tags.append( tag(depthLabels[record.depth] || record.depth, record.depth), tag(themeLabels[record.theme] || record.theme) ); heading.append(title, tags); const openLabel = document.createElement("span"); openLabel.className = "evidence-open"; openLabel.textContent = details.open ? "收起" : "展开"; summary.append(id, heading, openLabel); details.append(summary); if (record.depth === "context") { const detail = document.createElement("div"); detail.className = "evidence-detail context-detail"; detail.append( detailColumn("本轮位置", record.boundary, "evidence-boundary") ); details.append(detail); } else { const detail = document.createElement("div"); detail.className = "evidence-detail"; detail.append( detailColumn("核过的直接证据", record.evidence), detailColumn("可支持的判断", record.supports), detailColumn("不能外推", record.boundary, "evidence-boundary") ); details.append(detail); } const source = document.createElement("div"); source.className = "evidence-source"; const sourceLink = document.createElement("a"); sourceLink.href = record.url; sourceLink.target = "_blank"; sourceLink.rel = "noreferrer"; sourceLink.textContent = "打开 arXiv 原文"; source.append(sourceLink); details.append(source); details.addEventListener("toggle", () => { openLabel.textContent = details.open ? "收起" : "展开"; }); return details; } function updateFilterButtons(buttons, value, attribute) { buttons.forEach((button) => { const active = button.dataset[attribute] === value; button.classList.toggle("is-active", active); button.setAttribute("aria-pressed", String(active)); }); } function renderEvidence() { if (!evidenceData) { evidenceCount.textContent = "证据数据未载入。"; emptyEvidence.hidden = false; return; } const records = filteredRecords(); const fragment = document.createDocumentFragment(); records.forEach((record) => fragment.append(evidenceItem(record))); evidenceList.replaceChildren(fragment); const counts = evidenceData.counts; evidenceCount.textContent = `显示 ${records.length} / ${counts.pool} 篇` + ` · 核心 ${counts.core} · 旁证 ${counts.support} · 背景 ${counts.context}`; emptyEvidence.hidden = records.length !== 0; expandButton.disabled = records.length === 0; expandButton.textContent = state.expanded ? "收起当前结果" : "展开当前结果"; } depthButtons.forEach((button) => { button.addEventListener("click", () => { state.depth = button.dataset.depth; state.expanded = false; updateFilterButtons(depthButtons, state.depth, "depth"); renderEvidence(); }); }); themeButtons.forEach((button) => { button.addEventListener("click", () => { state.theme = button.dataset.theme; state.expanded = false; updateFilterButtons(themeButtons, state.theme, "theme"); renderEvidence(); }); }); searchInput?.addEventListener("input", (event) => { state.query = event.target.value; state.expanded = false; renderEvidence(); }); expandButton?.addEventListener("click", () => { state.expanded = !state.expanded; document.querySelectorAll(".evidence-item").forEach((item) => { item.open = state.expanded; const label = item.querySelector(".evidence-open"); if (label) { label.textContent = state.expanded ? "收起" : "展开"; } }); expandButton.textContent = state.expanded ? "收起当前结果" : "展开当前结果"; }); function updateReadingProgress() { const documentHeight = document.documentElement.scrollHeight - window.innerHeight; const progress = documentHeight > 0 ? window.scrollY / documentHeight : 0; const bar = document.querySelector("#reading-progress"); if (bar) { bar.style.width = `${Math.min(1, Math.max(0, progress)) * 100}%`; } } let progressFrame = 0; window.addEventListener( "scroll", () => { if (progressFrame) { return; } progressFrame = window.requestAnimationFrame(() => { updateReadingProgress(); progressFrame = 0; }); }, { passive: true } ); updateReadingProgress(); const navAliases = { conclusions: "overview", synthesis: "model", }; const navLinks = [...document.querySelectorAll(".primary-nav a")]; const sections = [...document.querySelectorAll("[data-section]")]; const sectionObserver = new IntersectionObserver( (entries) => { const visible = entries .filter((entry) => entry.isIntersecting) .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; if (!visible) { return; } const targetId = navAliases[visible.target.id] || visible.target.id; navLinks.forEach((link) => { const active = link.getAttribute("href") === `#${targetId}`; link.classList.toggle("is-active", active); if (active) { const nav = link.closest(".primary-nav"); if (nav && nav.scrollWidth > nav.clientWidth) { nav.scrollTo({ left: Math.max(0, link.offsetLeft - nav.clientWidth / 2), behavior: "smooth", }); } } }); }, { rootMargin: "-18% 0px -62% 0px", threshold: [0, 0.08, 0.2], } ); sections.forEach((section) => sectionObserver.observe(section)); renderEvidence(); if (window.location.hash) { window.requestAnimationFrame(() => { window.requestAnimationFrame(() => { document.querySelector(window.location.hash)?.scrollIntoView(); }); }); } })();