1(() => { 2 const config = window.WEB5_CONFIG || {}; 3 const header = document.querySelector('.site-header'); 4 const syncHeaderState = () => { 5 if (header) header.classList.toggle('is-scrolled', window.scrollY > 12); 6 }; 7 syncHeaderState(); 8 window.addEventListener('scroll', syncHeaderState, { passive: true }); 9 10 document.querySelectorAll('[data-link]').forEach((item) => { 11 const key = item.dataset.link; 12 if (config[key]) item.href = config[key]; 13 }); 14 15 document.querySelectorAll('[data-config]').forEach((item) => { 16 const key = item.dataset.config; 17 if (config[key]) item.textContent = config[key]; 18 }); 19 20 const phoneInput = document.getElementById('telefone'); 21 const formatPhone = (value) => { 22 const digits = value.replace(/\D/g, '').slice(0, 11); 23 if (digits.length <= 2) return digits ? `(${digits}` : ''; 24 if (digits.length <= 6) return `(${digits.slice(0, 2)}) ${digits.slice(2)}`; 25 if (digits.length <= 10) { 26 return `(${digits.slice(0, 2)}) ${digits.slice(2, 6)}-${digits.slice(6)}`; 27 } 28 return `(${digits.slice(0, 2)}) ${digits.slice(2, 7)}-${digits.slice(7)}`; 29 }; 30 31 if (phoneInput) { 32 phoneInput.addEventListener('input', () => { 33 phoneInput.value = formatPhone(phoneInput.value); 34 }); 35 } 36 37 const toggle = document.querySelector('.menu-toggle'); 38 const nav = document.querySelector('.nav'); 39 if (toggle && nav) { 40 toggle.addEventListener('click', () => { 41 const isOpen = nav.classList.toggle('open'); 42 toggle.classList.toggle('active', isOpen); 43 toggle.setAttribute('aria-expanded', String(isOpen)); 44 }); 45 nav.querySelectorAll('a').forEach((link) => { 46 link.addEventListener('click', () => { 47 nav.classList.remove('open'); 48 toggle.classList.remove('active'); 49 toggle.setAttribute('aria-expanded', 'false'); 50 }); 51 }); 52 } 53 54 const runCounter = (el) => { 55 const target = Number(el.dataset.counter || 0); 56 const suffix = el.dataset.counterSuffix || ''; 57 const duration = Math.min(2100, Math.max(1200, target * 2.2)); 58 const start = performance.now(); 59 60 const step = (now) => { 61 const progress = Math.min((now - start) / duration, 1); 62 const eased = 1 - Math.pow(1 - progress, 4); 63 const value = Math.round(target * eased); 64 el.textContent = `${value}${suffix}`; 65 if (progress < 1) requestAnimationFrame(step); 66 else el.textContent = `${target}${suffix}`; 67 }; 68 69 requestAnimationFrame(step); 70 }; 71 72 const observer = new IntersectionObserver((entries) => { 73 entries.forEach((entry) => { 74 if (entry.isIntersecting) { 75 entry.target.classList.add('visible'); 76 entry.target.querySelectorAll('[data-counter]').forEach((counter) => { 77 if (!counter.dataset.done) { 78 counter.dataset.done = '1'; 79 runCounter(counter); 80 } 81 }); 82 if (entry.target.matches('[data-counter]') && !entry.target.dataset.done) { 83 entry.target.dataset.done = '1'; 84 runCounter(entry.target); 85 } 86 observer.unobserve(entry.target); 87 } 88 }); 89 }, { threshold: 0.14 }); 90 91 document.querySelectorAll('.reveal, [data-counter]').forEach((el) => observer.observe(el)); 92 93 const form = document.getElementById('contactForm'); 94 if (form) { 95 form.addEventListener('submit', (event) => { 96 event.preventDefault(); 97 if (!form.checkValidity()) { 98 form.reportValidity(); 99 return; 100 } 101 const data = new FormData(form); 102 const nome = data.get('nome') || ''; 103 const telefone = data.get('telefone') || ''; 104 const email = data.get('email') || ''; 105 const interesse = data.get('interesse') || ''; 106 const mensagem = data.get('mensagem') || ''; 107 const texto = `Olá, gostaria de atendimento pela WEB5.\n\nNome: ${nome}\nTelefone: ${telefone}\nE-mail: ${email}\nInteresse: ${interesse}\nMensagem: ${mensagem}`; 108 const whatsappBase = config.whatsapp || '#'; 109 const encoded = encodeURIComponent(texto); 110 const url = whatsappBase.includes('text=') 111 ? whatsappBase.replace(/text=[^&]*/, `text=${encoded}`) 112 : `${whatsappBase}${whatsappBase.includes('?') ? '&' : '?'}text=${encoded}`;
113 window.open(url, '_blank', 'noopener'); 114 form.reset(); 115 }); 116 } 117 118 const year = document.getElementById('year'); 119 if (year) year.textContent = new Date().getFullYear(); 120})();
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.