1const initializeNavigationControls = () => { 2 const menuButton = document.querySelector('.menu-toggle'); 3 const nav = document.querySelector('.main-nav'); 4 const siteHeader = document.querySelector('.site-header'); 5 if (!menuButton || !nav || !siteHeader) return; 6 7 menuButton.addEventListener('click', () => { 8 const isOpen = menuButton.getAttribute('aria-expanded') === 'true'; 9 menuButton.setAttribute('aria-expanded', String(!isOpen)); 10 nav.classList.toggle('open', !isOpen); 11 siteHeader.classList.toggle('menu-open', !isOpen); 12 document.body.style.overflow = isOpen ? '' : 'hidden'; 13 }); 14 15 nav.addEventListener('click', event => { 16 const submenuButton = event.target.closest('.has-submenu > button'); 17 if (submenuButton && nav.contains(submenuButton)) { 18 const isExpanded = submenuButton.getAttribute('aria-expanded') === 'true'; 19 nav.querySelectorAll('.has-submenu > button[aria-expanded="true"]').forEach(button => { 20 if (button !== submenuButton) button.setAttribute('aria-expanded', 'false'); 21 }); 22 submenuButton.setAttribute('aria-expanded', String(!isExpanded)); 23 return; 24 } 25 const link = event.target.closest('a'); 26 if (!link || !nav.contains(link)) return; 27 menuButton.setAttribute('aria-expanded', 'false'); 28 nav.classList.remove('open'); 29 siteHeader.classList.remove('menu-open'); 30 document.body.style.overflow = ''; 31 }); 32}; 33 34(window.trofeoNavReady || Promise.resolve()).then(initializeNavigationControls); 35 36const revealObserver = new IntersectionObserver((entries) => { 37 entries.forEach((entry) => { 38 if (entry.isIntersecting) { 39 entry.target.classList.add('visible'); 40 revealObserver.unobserve(entry.target); 41 } 42 }); 43}, { threshold: 0.14 }); 44 45document.querySelectorAll('.reveal').forEach(element => revealObserver.observe(element)); 46 47const formatItalian = value => new Intl.NumberFormat('it-IT').format(value); 48const countObserver = new IntersectionObserver((entries) => { 49 entries.forEach((entry) => { 50 if (!entry.isIntersecting) return; 51 const element = entry.target; 52 const target = Number(element.dataset.count); 53 const duration = 1400; 54 const start = performance.now(); 55 56 const animate = (now) => { 57 const progress = Math.min((now - start) / duration, 1); 58 const eased = 1 - Math.pow(1 - progress, 3); 59 element.textContent = formatItalian(Math.floor(target * eased)); 60 if (progress < 1) requestAnimationFrame(animate); 61 }; 62 requestAnimationFrame(animate); 63 countObserver.unobserve(element); 64 }); 65}, { threshold: .5 }); 66 67document.querySelectorAll('[data-count]').forEach(number => countObserver.observe(number)); 68 69const yearElement = document.getElementById('year'); 70if (yearElement) yearElement.textContent = new Date().getFullYear();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.