if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/static/js/service-worker.js').catch(() => {}); }); } function initMaterialsSearch() { const input = document.querySelector('[data-search-input="materials"]'); if (!input) return; const items = Array.from(document.querySelectorAll('[data-search-item="materials"]')); const emptyMessage = document.getElementById('materials-empty'); function normalize(value) { return (value || '') .toString() .toLowerCase() .normalize('NFD') .replace(/[̀-ͯ]/g, '') .trim(); } function filterMaterials() { const query = normalize(input.value); let visibleCount = 0; items.forEach((item) => { const text = normalize(item.dataset.searchText || item.textContent); const isVisible = !query || text.includes(query); item.hidden = !isVisible; if (isVisible) visibleCount += 1; }); if (emptyMessage) { emptyMessage.hidden = visibleCount !== 0; } } input.addEventListener('input', filterMaterials); filterMaterials(); } window.addEventListener('DOMContentLoaded', initMaterialsSearch);