Download code/docs/site.js from amonshano/echo: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/amonshano/echo/resolve/main/code/docs/site.js
- Command line
-
hf download hf://amonshano/echo/code/docs/site.js
-
curl -L -o site.js https://huggingface.co/amonshano/echo/resolve/main/code/docs/site.js
11.7 kB
| (function () { | |
| "use strict"; | |
| const NAV_OFFSET = 72; | |
| const REDUCED_MOTION = window.matchMedia("(prefers-reduced-motion: reduce)").matches; | |
| const SCROLL_BEHAVIOR = REDUCED_MOTION ? "auto" : "smooth"; | |
| const sectionEls = Array.from(document.querySelectorAll(".section[data-section]")); | |
| const navLinks = Array.from(document.querySelectorAll("[data-nav]")); | |
| const slideDots = Array.from(document.querySelectorAll(".slide-dots button[data-slide]")); | |
| const navToggle = document.getElementById("nav-toggle"); | |
| const navMobile = document.getElementById("nav-menu-mobile"); | |
| const topNav = document.querySelector(".top-nav"); | |
| const progressBar = document.querySelector(".scroll-progress__bar"); | |
| const backTop = document.getElementById("back-top"); | |
| const lightbox = document.getElementById("lightbox"); | |
| const lightboxImg = document.getElementById("lightbox-img"); | |
| const lightboxCaption = document.getElementById("lightbox-caption"); | |
| const lightboxClose = lightbox ? lightbox.querySelector(".lightbox__close") : null; | |
| function setActiveNav(id) { | |
| navLinks.forEach(function (a) { | |
| a.classList.toggle("is-active", a.getAttribute("data-nav") === id); | |
| }); | |
| slideDots.forEach(function (btn) { | |
| btn.classList.toggle("is-active", btn.getAttribute("data-slide") === id); | |
| }); | |
| } | |
| function scrollToSection(id) { | |
| var el = document.getElementById(id); | |
| if (!el) return; | |
| el.scrollIntoView({ behavior: SCROLL_BEHAVIOR, block: "start" }); | |
| setActiveNav(id); | |
| if (navMobile && !navMobile.hidden) { | |
| navToggle.setAttribute("aria-expanded", "false"); | |
| navMobile.hidden = true; | |
| if (topNav) topNav.classList.remove("is-open"); | |
| } | |
| } | |
| function sectionIndex(id) { | |
| return sectionEls.findIndex(function (s) { | |
| return s.getAttribute("data-section") === id; | |
| }); | |
| } | |
| function scrollAdjacent(delta) { | |
| var activeId = null; | |
| sectionEls.forEach(function (s) { | |
| var rect = s.getBoundingClientRect(); | |
| if (rect.top <= NAV_OFFSET + 80 && rect.bottom > NAV_OFFSET + 80) { | |
| activeId = s.getAttribute("data-section"); | |
| } | |
| }); | |
| if (!activeId && sectionEls.length) activeId = sectionEls[0].getAttribute("data-section"); | |
| var idx = sectionIndex(activeId); | |
| if (idx < 0) return; | |
| var next = sectionEls[idx + delta]; | |
| if (next) scrollToSection(next.getAttribute("data-section")); | |
| } | |
| if (sectionEls.length) { | |
| var observer = new IntersectionObserver( | |
| function (entries) { | |
| entries.forEach(function (entry) { | |
| if (entry.isIntersecting) { | |
| setActiveNav(entry.target.getAttribute("data-section")); | |
| } | |
| }); | |
| }, | |
| { root: null, rootMargin: "-" + NAV_OFFSET + "px 0px -50% 0px", threshold: 0.12 } | |
| ); | |
| sectionEls.forEach(function (section) { | |
| observer.observe(section); | |
| }); | |
| } | |
| document.querySelectorAll(".reveal").forEach(function (el) { | |
| var revealObserver = new IntersectionObserver( | |
| function (entries) { | |
| entries.forEach(function (entry) { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add("is-visible"); | |
| revealObserver.unobserve(entry.target); | |
| } | |
| }); | |
| }, | |
| { root: null, rootMargin: "0px 0px -8% 0px", threshold: 0.08 } | |
| ); | |
| if (REDUCED_MOTION) { | |
| el.classList.add("is-visible"); | |
| } else { | |
| revealObserver.observe(el); | |
| } | |
| }); | |
| function updateScrollUI() { | |
| var scrollTop = window.scrollY || document.documentElement.scrollTop; | |
| var docHeight = document.documentElement.scrollHeight - window.innerHeight; | |
| var progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0; | |
| if (progressBar) progressBar.style.width = progress + "%"; | |
| if (topNav) topNav.classList.toggle("is-scrolled", scrollTop > 24); | |
| if (backTop) { | |
| var show = scrollTop > window.innerHeight * 0.6; | |
| backTop.hidden = !show; | |
| backTop.classList.toggle("is-visible", show); | |
| } | |
| } | |
| window.addEventListener("scroll", updateScrollUI, { passive: true }); | |
| updateScrollUI(); | |
| navLinks.forEach(function (a) { | |
| a.addEventListener("click", function (e) { | |
| e.preventDefault(); | |
| scrollToSection(a.getAttribute("data-nav")); | |
| }); | |
| }); | |
| slideDots.forEach(function (btn) { | |
| btn.addEventListener("click", function () { | |
| scrollToSection(btn.getAttribute("data-slide")); | |
| }); | |
| }); | |
| if (navToggle && navMobile) { | |
| navToggle.addEventListener("click", function () { | |
| var open = navMobile.hidden; | |
| navMobile.hidden = !open; | |
| navToggle.setAttribute("aria-expanded", String(open)); | |
| if (topNav) topNav.classList.toggle("is-open", open); | |
| }); | |
| } | |
| if (backTop) { | |
| backTop.addEventListener("click", function () { | |
| scrollToSection("hero"); | |
| }); | |
| } | |
| function openLightbox(img, captionText) { | |
| if (!lightbox || !lightboxImg) return; | |
| lightboxImg.src = img.src; | |
| lightboxImg.alt = img.alt || ""; | |
| if (lightboxCaption) { | |
| lightboxCaption.textContent = captionText || ""; | |
| } | |
| lightbox.hidden = false; | |
| document.body.style.overflow = "hidden"; | |
| if (lightboxClose) lightboxClose.focus(); | |
| } | |
| function closeLightbox() { | |
| if (!lightbox) return; | |
| lightbox.hidden = true; | |
| document.body.style.overflow = ""; | |
| if (lightboxImg) lightboxImg.src = ""; | |
| } | |
| document.querySelectorAll("[data-zoomable]").forEach(function (figure) { | |
| figure.addEventListener("click", function (e) { | |
| if (e.target.closest(".qual-chip, .copy-btn, button, a")) return; | |
| var img = figure.querySelector("img.is-active, img[data-qual-image], img"); | |
| if (!img || !img.src) return; | |
| var cap = figure.querySelector("figcaption"); | |
| var capText = cap ? cap.textContent.replace(/Click to expand/g, "").trim() : ""; | |
| openLightbox(img, capText); | |
| }); | |
| }); | |
| if (lightboxClose) { | |
| lightboxClose.addEventListener("click", closeLightbox); | |
| } | |
| if (lightbox) { | |
| lightbox.addEventListener("click", function (e) { | |
| if (e.target === lightbox) closeLightbox(); | |
| }); | |
| } | |
| document.addEventListener("keydown", function (e) { | |
| if (e.target.closest("input, textarea, pre, [contenteditable]")) return; | |
| if (e.key === "Escape" && lightbox && !lightbox.hidden) { | |
| closeLightbox(); | |
| return; | |
| } | |
| if (e.key === "ArrowDown" || e.key === "PageDown") { | |
| e.preventDefault(); | |
| scrollAdjacent(1); | |
| } else if (e.key === "ArrowUp" || e.key === "PageUp") { | |
| e.preventDefault(); | |
| scrollAdjacent(-1); | |
| } | |
| }); | |
| function animateMetricValue(el, target) { | |
| if (REDUCED_MOTION || !target || target === "—") { | |
| el.textContent = target; | |
| return; | |
| } | |
| var numeric = parseInt(String(target).replace(/,/g, ""), 10); | |
| if (isNaN(numeric)) { | |
| el.textContent = target; | |
| return; | |
| } | |
| var start = 0; | |
| var duration = 700; | |
| var startTime = null; | |
| function step(ts) { | |
| if (!startTime) startTime = ts; | |
| var t = Math.min((ts - startTime) / duration, 1); | |
| var eased = 1 - Math.pow(1 - t, 3); | |
| el.textContent = Math.round(start + (numeric - start) * eased).toLocaleString(); | |
| if (t < 1) requestAnimationFrame(step); | |
| } | |
| requestAnimationFrame(step); | |
| } | |
| function hydrateMetric(card) { | |
| var valueEl = card.querySelector("[data-metric-value]"); | |
| var badgeUrl = card.getAttribute("data-badge-url"); | |
| if (!valueEl || !badgeUrl) return; | |
| fetch(badgeUrl, { cache: "no-store" }) | |
| .then(function (res) { | |
| if (!res.ok) throw new Error("Request failed"); | |
| return res.json(); | |
| }) | |
| .then(function (data) { | |
| var val = data.value || data.message || valueEl.dataset.fallback || "—"; | |
| animateMetricValue(valueEl, val); | |
| }) | |
| .catch(function () { | |
| valueEl.textContent = valueEl.dataset.fallback || "—"; | |
| }); | |
| } | |
| document.querySelectorAll("[data-badge-url]").forEach(function (card) { | |
| var metricObserver = new IntersectionObserver( | |
| function (entries) { | |
| entries.forEach(function (entry) { | |
| if (entry.isIntersecting) { | |
| hydrateMetric(entry.target); | |
| metricObserver.unobserve(entry.target); | |
| } | |
| }); | |
| }, | |
| { threshold: 0.4 } | |
| ); | |
| metricObserver.observe(card); | |
| }); | |
| document.querySelectorAll("[data-qual-viewer]").forEach(function (viewer) { | |
| var image = viewer.querySelector("[data-qual-image]"); | |
| var caption = viewer.querySelector("[data-qual-caption]"); | |
| var chips = viewer.querySelectorAll(".qual-chip"); | |
| chips.forEach(function (chip) { | |
| chip.addEventListener("click", function () { | |
| chips.forEach(function (c) { | |
| c.classList.remove("is-active"); | |
| c.setAttribute("aria-selected", "false"); | |
| }); | |
| chip.classList.add("is-active"); | |
| chip.setAttribute("aria-selected", "true"); | |
| if (!image) return; | |
| var nextSrc = chip.dataset.src; | |
| var nextAlt = chip.dataset.alt || ""; | |
| var nextCaption = chip.dataset.caption || ""; | |
| var currentPath = new URL(image.src, window.location.href).pathname; | |
| if (currentPath.endsWith(nextSrc)) return; | |
| image.classList.add("is-fading"); | |
| var preload = new Image(); | |
| preload.onload = function () { | |
| image.src = nextSrc; | |
| image.alt = nextAlt; | |
| image.classList.remove("is-fading"); | |
| image.classList.add("is-active"); | |
| }; | |
| preload.onerror = function () { | |
| image.classList.remove("is-fading"); | |
| }; | |
| preload.src = nextSrc; | |
| if (caption) { | |
| var hint = (window.EchoI18n && window.EchoI18n.t("zoom.hint")) || "Click to expand"; | |
| caption.innerHTML = nextCaption + ' <span class="zoom-hint">' + hint + "</span>"; | |
| } | |
| }); | |
| }); | |
| }); | |
| function initCiteSwitcher() { | |
| document.querySelectorAll("[data-cite-switcher]").forEach(function (switcher) { | |
| var chips = switcher.querySelectorAll(".cite-chip"); | |
| var panels = switcher.querySelectorAll("[data-cite-panel]"); | |
| chips.forEach(function (chip) { | |
| chip.addEventListener("click", function () { | |
| var key = chip.getAttribute("data-cite"); | |
| chips.forEach(function (c) { | |
| c.classList.remove("is-active"); | |
| c.setAttribute("aria-selected", "false"); | |
| }); | |
| chip.classList.add("is-active"); | |
| chip.setAttribute("aria-selected", "true"); | |
| panels.forEach(function (panel) { | |
| var match = panel.getAttribute("data-cite-panel") === key; | |
| panel.classList.toggle("is-active", match); | |
| panel.hidden = !match; | |
| }); | |
| }); | |
| }); | |
| }); | |
| } | |
| initCiteSwitcher(); | |
| document.querySelectorAll("[data-copy-target]").forEach(function (btn) { | |
| btn.addEventListener("click", function () { | |
| var targetId = btn.getAttribute("data-copy-target"); | |
| var target = document.getElementById(targetId); | |
| if (!target) return; | |
| navigator.clipboard.writeText(target.textContent).then( | |
| function () { | |
| var copied = window.EchoI18n && window.EchoI18n.t("bibtex.copied"); | |
| var failed = window.EchoI18n && window.EchoI18n.t("bibtex.failed"); | |
| var copyLabel = window.EchoI18n && window.EchoI18n.t("bibtex.copy"); | |
| btn.textContent = copied || "Copied"; | |
| btn.classList.add("is-copied"); | |
| setTimeout(function () { | |
| btn.textContent = copyLabel || "Copy"; | |
| btn.classList.remove("is-copied"); | |
| }, 2000); | |
| }, | |
| function () { | |
| btn.textContent = (window.EchoI18n && window.EchoI18n.t("bibtex.failed")) || "Failed"; | |
| } | |
| ); | |
| }); | |
| }); | |
| })(); | |