// Based on https://codeberg.org/daudix/duckquill/issues/101#issuecomment-2377169 let searchSetup = false; let fuse; async function initIndex() { if (searchSetup) return; const url = document.getElementById("search-index").textContent; const response = await fetch(url); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const options = { includeScore: false, includeMatches: true, ignoreLocation: true, threshold: 0.15, keys: [ { name: "title", weight: 3 }, { name: "description", weight: 2 }, { name: "body", weight: 1 } ] }; fuse = new Fuse(await response.json(), options); searchSetup = true; console.log("Search index initialized successfully"); } function toggleSearch() { initIndex(); const searchBar = document.getElementById("search-bar"); const searchContainer = document.getElementById("search-container"); const searchResults = document.getElementById("search-results"); searchContainer.classList.toggle("active"); searchBar.toggleAttribute("disabled"); searchBar.focus(); } function debounce(actual_fn, wait) { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => { actual_fn(...args); }, wait); }; }; function initSearch() { const searchBar = document.getElementById("search-bar"); const searchResults = document.getElementById("search-results"); const searchContainer = document.getElementById("search-container"); const MAX_ITEMS = 10; const MAX_RESULTS = 4; let currentTerm = ""; searchBar.addEventListener("keyup", (e) => { const searchVal = searchBar.value.trim(); const results = fuse.search(searchVal, { limit: MAX_ITEMS }); let html = ""; for (const result of results) { html += makeTeaser(result, searchVal); } searchResults.innerHTML = html; if (html) { searchResults.style.display = "flex"; } else { searchResults.style.display = "none"; } }); function makeTeaser(result, searchVal) { const TEASER_SIZE = 20; let output = `