/* ========================================================================== main.js — Maxx Force landing के सारे scripts एक file में क्रम: 1. Utilities 2. Header की तारीख (+ optional अगला महीना) 3. Offer timer + pack counter 4. FOMO toast (popup "orders") 5. Sticky CTA 6. Scroll-to-top 7. UTM/subid hydration 8. नाम और फ़ोन validation (नाम, +91, blacklist) 9. भेजने से पहले confirm modal 10. Form submit + cooldown + localStorage 11. Counter "X,XXX पुरुष इस महीने" सभी handlers safe हैं: अगर HTML element नहीं है, function चुपचाप कुछ नहीं करेगा (form काम करता रहेगा). ========================================================================== */ (function () { 'use strict'; /* ============================================================ 1. Utilities ============================================================ */ function rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function two(n) { n = Math.max(0, parseInt(n, 10) || 0); return n < 10 ? '0' + n : String(n); } function setText(el, value) { if (!el) return; if (el.tagName === 'INPUT') el.value = value; else el.textContent = value; } function getSession(k) { try { return sessionStorage.getItem(k); } catch (e) { return null; } } function setSession(k, v) { try { sessionStorage.setItem(k, String(v)); } catch (e) {} } function getLocal(k) { try { return localStorage.getItem(k); } catch (e) { return null; } } function setLocal(k, v) { try { localStorage.setItem(k, String(v)); } catch (e) {} } function now() { return Date.now(); } /* ============================================================ 2. Header की तारीख + अगला महीना ============================================================ */ var HI_MONTHS = ['जनवरी','फ़रवरी','मार्च','अप्रैल','मई','जून','जुलाई','अगस्त','सितंबर','अक्टूबर','नवंबर','दिसंबर']; function initHeaderDate() { var d = new Date(); var el = document.getElementById('mxHeaderDate'); if (el) el.textContent = d.getDate() + ' ' + HI_MONTHS[d.getMonth()]; } function initPublishDate() { var el = document.getElementById('newsPublishDate'); if (!el) return; // article recently published लगे, इसलिए random 1-3 दिन पहले var daysAgo = 1 + Math.floor(Math.random() * 3); var d = new Date(); d.setDate(d.getDate() - daysAgo); var dd = d.getDate() < 10 ? '0' + d.getDate() : '' + d.getDate(); var mm = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : '' + (d.getMonth() + 1); var label = daysAgo === 1 ? 'कल' : (daysAgo === 2 ? 'परसों' : daysAgo + ' दिन पहले'); el.textContent = label + ' • ' + dd + '.' + mm + '.' + d.getFullYear(); } function initNextMonth() { var d = new Date(); var nextIdx = (d.getMonth() + 1) % 12; var el = document.getElementById('nextMonth'); if (el) el.innerText = HI_MONTHS[nextIdx]; var curEl = document.getElementById('currentMonth'); if (curEl) curEl.innerText = HI_MONTHS[d.getMonth()]; } // तारीखों के लिए dtime_nums जैसा function "X दिन पहले/आगे" window.dtime_nums = function (d, like_eu) { var t = new Date(); t.setDate(t.getDate() + d + 1); var dayNum = t.getDate() < 10 ? '0' + t.getDate() : '' + t.getDate(); var monthNum = (t.getMonth() + 1) < 10 ? '0' + (t.getMonth() + 1) : '' + (t.getMonth() + 1); if (like_eu === true) document.write(dayNum + '.' + monthNum + '.' + t.getFullYear()); else document.write(monthNum + '.' + dayNum + '.' + t.getFullYear()); }; /* ============================================================ 3. Offer timer + pack stock ============================================================ */ var TIMER_KEY = 'mx_offer_deadline_v10'; var STOCK_KEY = 'mx_pack_stock_v10'; var STOCK_TS_KEY = 'mx_pack_stock_ts_v10'; var MIN_STOCK = 12; var MAX_STOCK = 28; function resetDeadline() { var seconds = (8 + Math.floor(Math.random() * 16)) * 60; var deadline = now() + seconds * 1000; setSession(TIMER_KEY, deadline); return deadline; } var deadline; function renderTimer() { var remain = Math.ceil((deadline - now()) / 1000); if (remain <= 0) { deadline = resetDeadline(); remain = Math.ceil((deadline - now()) / 1000); } var m = Math.floor(remain / 60), s = remain % 60; ['min', 'min2'].forEach(function (id) { setText(document.getElementById(id), two(m)); }); ['sec', 'sec2'].forEach(function (id) { setText(document.getElementById(id), two(s)); }); } function initStock() { var stock = parseInt(getSession(STOCK_KEY), 10); if (!stock || stock < MIN_STOCK || stock > MAX_STOCK) { stock = 17 + Math.floor(Math.random() * 8); setSession(STOCK_KEY, stock); setSession(STOCK_TS_KEY, now()); } return stock; } function getStock() { var stock = initStock(); var ts = parseInt(getSession(STOCK_TS_KEY), 10) || now(); var stepMs = 30000 + Math.floor(Math.random() * 15000); if (now() - ts >= stepMs && stock > MIN_STOCK) { stock -= 1; setSession(STOCK_KEY, stock); setSession(STOCK_TS_KEY, now()); flashStock(); } return stock; } function flashStock() { document.querySelectorAll('.stock-urgency,.nums-prod').forEach(function (w) { w.classList.add('stock-flash'); setTimeout(function () { w.classList.remove('stock-flash'); }, 450); }); } function renderStock() { var count = String(getStock()); document.querySelectorAll('[data-stock-counter], .stock-count, input.nums-inp').forEach(function (el) { setText(el, count); }); } window.numsFF = function () { var stock = getStock(); if (stock > MIN_STOCK) { setSession(STOCK_KEY, stock - 1); setSession(STOCK_TS_KEY, now()); } renderStock(); flashStock(); }; function initOfferTimerAndStock() { deadline = parseInt(getSession(TIMER_KEY), 10); if (!deadline || deadline <= now()) deadline = resetDeadline(); renderTimer(); renderStock(); setInterval(renderTimer, 1000); setInterval(renderStock, 5000); } /* ============================================================ 4. FOMO TOAST (popup "orders") ============================================================ */ var CITIES = [ 'दिल्ली','मुंबई','बेंगलुरु','हैदराबाद','चेन्नई','कोलकाता', 'अहमदाबाद','जयपुर','लखनऊ','पुणे','सूरत','कानपुर', 'नागपुर','इंदौर','भोपाल','पटना','चंडीगढ़','लुधियाना' ]; var CUSTOMER_NAMES = [ 'राहुल','अमित','विकास','संजय','अजय','मनोज','दीपक','प्रकाश', 'रवि','सुनील','अनिल','मोहन','नितिन','राजेश','सुरेश','धर्मेंद्र', 'कुलदीप','हरप्रीत','विनोद','शैलेंद्र','आशीष','संदीप','अभिषेक','तरुण' ]; var orderNumber = rand(280000, 580000); var showCount = 0; var fomoStarted = false; var fomoTimer = null; var toastBoxes = []; var orderForm = null; function getNextOrderNumber() { orderNumber += rand(40, 420); if (orderNumber > 999990) orderNumber = 999990; return String(orderNumber); } function isFormVisible() { if (!orderForm) return false; var rect = orderForm.getBoundingClientRect(); var vh = window.innerHeight || document.documentElement.clientHeight; return rect.top < vh * 0.92 && rect.bottom > vh * 0.08; } function hideAllToasts() { toastBoxes.forEach(function (box) { box.classList.remove('is-visible'); }); } function showFomoToast() { if (!toastBoxes.length) return; hideAllToasts(); var box = toastBoxes[0]; var nameEl = box.querySelector('.wa-name'); var textEl = box.querySelector('.wa-text'); var timeEl = box.querySelector('.wa-time'); var city = (window._userCity && window._userCity.length > 0) ? window._userCity : CITIES[rand(0, CITIES.length - 1)]; var packs = rand(1, 4); var customerName = CUSTOMER_NAMES[rand(0, CUSTOMER_NAMES.length - 1)]; var timeVariants = ['अभी', '1 मिनट पहले', '2 मिनट पहले', '3 मिनट पहले']; var timeText = timeVariants[rand(0, timeVariants.length - 1)]; if (nameEl) nameEl.textContent = customerName + ' ने ऑर्डर किया'; if (textEl) textEl.textContent = 'Horse Fire Capsules • ' + city + ' • ' + packs + ' पैक'; if (timeEl) timeEl.textContent = timeText; box.classList.add('is-visible'); showCount++; setTimeout(function () { box.classList.remove('is-visible'); var nextDelay; if (showCount < 3) nextDelay = rand(12000, 22000); else if (showCount < 6) nextDelay = rand(30000, 55000); else nextDelay = rand(60000, 120000); fomoTimer = setTimeout(showFomoToast, nextDelay); }, 4200); } function startFomoAfterEngagement() { if (fomoStarted) return; if (window.pageYOffset < 300) return; fomoStarted = true; fomoTimer = setTimeout(showFomoToast, rand(4000, 8000)); } /* ============================================================ 5. STICKY CTA ============================================================ */ var stickyCta = null; function updateStickyCta() { if (!stickyCta) return; var shouldShow = window.pageYOffset > 700 && !isFormVisible(); if (shouldShow) stickyCta.classList.add('is-visible'); else stickyCta.classList.remove('is-visible'); } function onScrollOrResize() { startFomoAfterEngagement(); updateStickyCta(); } /* ============================================================ 6. ऊपर scroll ============================================================ */ function initScrollTop() { var btn = document.getElementById('scrollTopBtn'); if (!btn) return; function toggle() { if (window.pageYOffset > 600) btn.classList.add('is-visible'); else btn.classList.remove('is-visible'); } btn.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); }); window.addEventListener('scroll', toggle, { passive: true }); toggle(); } /* ============================================================ 7. UTM/SUBID hydration ============================================================ */ function hydrateUtm() { var params = new URLSearchParams(window.location.search); var keys = ['subid','utm_source','utm_campaign','utm_content','utm_term','utm_medium']; document.querySelectorAll('form').forEach(function (form) { keys.forEach(function (k) { var input = form.querySelector('input[name="' + k + '"]'); if (!input) return; var fromUrl = params.get(k); if (fromUrl) input.value = fromUrl; if (/^\{.*\}$/.test(input.value)) input.value = ''; }); }); } /* ============================================================ 8. Validation + 9. Confirm modal + 10. Submit ============================================================ */ var FORM_SELECTOR = '.order-form-v8'; var STORAGE_KEY = 'mx_submitted_phones_v8'; var LAST_PHONE_KEY = 'mx_last_order_phone_v8'; var COOLDOWN_MS = 10 * 60 * 1000; var SCRIPT_URL = 'https://script.google.com/macros/s/AKfycbwJju7w9nd9VitPz6Rr1dkRjePUfg8NRpj3GYsrWikG0naDsxUr-bLGeitOgMS3muAw/exec'; var THANKYOU_PAGE = 'thankyou.html'; var SUBMITTED_SESSION_KEY = 'adctOfferSubmitted'; function setCookie(name, value, hours) { var d = new Date(); d.setTime(d.getTime() + (hours * 60 * 60 * 1000)); document.cookie = name + '=' + encodeURIComponent(value) + ';expires=' + d.toUTCString() + ';path=/'; } function getCookie(name) { var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); return match ? decodeURIComponent(match[2]) : null; } function markOfferOrderSubmitted() { try { sessionStorage.setItem(SUBMITTED_SESSION_KEY, '1'); } catch(e) {} } function orderSubmittedInSession() { try { return sessionStorage.getItem(SUBMITTED_SESSION_KEY) === '1'; } catch(e) { return false; } } function fetchIP(cb) { try { var r = new XMLHttpRequest(); r.open('GET', 'https://api.ipify.org?format=json', true); r.timeout = 3000; r.onreadystatechange = function() { if (r.readyState === 4) { try { cb((JSON.parse(r.responseText).ip) || 'unknown'); } catch(e) { cb('unknown'); } } }; r.onerror = function() { cb('unknown'); }; r.send(); } catch(e) { cb('unknown'); } } var ERR_NAME = 'कृपया सही नाम दर्ज करें।'; var ERR_PHONE = 'मोबाइल नंबर 10 अंकों का होना चाहिए और 6, 7, 8 या 9 से शुरू होना चाहिए।'; var ERR_FAKE = 'यह नंबर अमान्य है।'; var ERR_18 = 'कृपया 18+ की पुष्टि करें।'; var ERR_ADDRESS = 'पता पूरा भरें।'; var BLACKLIST = [ '0000000000','1111111111','2222222222','3333333333','4444444444', '5555555555','6666666666','7777777777','8888888888','9999999999', '1234567890','0123456789','9876543210','9000000000','0987654321' ]; function onlyDigits(value) { var d = String(value || '').replace(/\D/g, ''); if (d.length > 10) { if (d.length === 12 && d.indexOf('91') === 0) d = d.slice(2); else if (d.length === 11 && d.charAt(0) === '0') d = d.slice(1); else d = d.slice(-10); } return d.slice(0, 10); } function formatPhone(digits) { return digits; } function getDigits(input) { return onlyDigits(input.value); } function setPhoneFields(phoneInput, phoneFull, digits) { phoneInput.value = digits; if (phoneFull) phoneFull.value = digits; } function getMap() { try { return JSON.parse(getLocal(STORAGE_KEY) || '{}'); } catch (e) { return {}; } } function setMap(map) { try { setLocal(STORAGE_KEY, JSON.stringify(map)); } catch (e) {} } function cleanupMap(map) { var t = now(); Object.keys(map).forEach(function (phone) { if (t - map[phone] > COOLDOWN_MS) delete map[phone]; }); return map; } function showError(form, type, message) { var el = form.querySelector('[data-error-for="' + type + '"]'); if (!el) return; el.textContent = message; el.classList.remove('is-visible'); void el.offsetWidth; el.classList.add('is-visible'); } function clearError(form, type) { var el = form.querySelector('[data-error-for="' + type + '"]'); if (!el) return; el.textContent = ''; el.classList.remove('is-visible'); } function validName(value) { var name = String(value || '').trim(); if (name.length < 2) return false; if (/test/i.test(name)) return false; if (/(.)\1\1\1/i.test(name)) return false; if (/^(asd|qwe|zxc|lorem|ipsum|abcd|xyz)/i.test(name)) return false; if (/^[a-z]{1,3}$/i.test(name)) return false; return true; } function validatePhone(digits) { if (!/^[6-9]\d{9}$/.test(digits)) return { ok: false, message: ERR_PHONE }; if (BLACKLIST.indexOf(digits) !== -1) return { ok: false, message: ERR_FAKE }; if (/(\d)\1{7,}/.test(digits)) return { ok: false, message: ERR_FAKE }; return { ok: true, digits: digits, display: '+91' + digits }; } /* ----- Confirm modal ----- */ function showConfirmModal(phoneFormatted, onConfirm, onChange) { var modal = document.getElementById('confirmModal'); if (!modal) { onConfirm(); return; } var phoneEl = modal.querySelector('[data-confirm-phone]'); var btnYes = modal.querySelector('[data-confirm-yes]'); var btnNo = modal.querySelector('[data-confirm-no]'); var btnClose = modal.querySelector('[data-confirm-close]'); if (phoneEl) phoneEl.textContent = phoneFormatted; modal.classList.add('is-visible'); document.body.style.overflow = 'hidden'; function close() { modal.classList.remove('is-visible'); document.body.style.overflow = ''; btnYes && btnYes.removeEventListener('click', onYes); btnNo && btnNo.removeEventListener('click', onNo); btnClose && btnClose.removeEventListener('click', onNo); } function onYes() { close(); onConfirm(); } function onNo() { close(); onChange && onChange(); } btnYes && btnYes.addEventListener('click', onYes); btnNo && btnNo.addEventListener('click', onNo); btnClose && btnClose.addEventListener('click', onNo); } function initForms() { document.querySelectorAll(FORM_SELECTOR).forEach(function (form) { var nameInput = form.querySelector('#name'); var phoneInput = form.querySelector('#phoneNational'); var phoneFull = form.querySelector('#phoneFull'); var botCheck = form.querySelector('#botCheck'); var submitBtn = form.querySelector('button[type="submit"]'); var ageCheck = form.querySelector('#ageConfirm'); var tsRender = form.querySelector('#tsRender'); if (tsRender) tsRender.value = now(); if (!nameInput || !phoneInput || !submitBtn) return; nameInput.addEventListener('input', function () { clearError(form, 'name'); }); phoneInput.addEventListener('input', function () { var digits = getDigits(phoneInput); phoneInput.value = formatPhone(digits); clearError(form, 'phone'); }); phoneInput.addEventListener('keydown', function (event) { var allowed = ['Backspace','Delete','ArrowLeft','ArrowRight','Tab','Home','End']; if (allowed.indexOf(event.key) !== -1 || event.ctrlKey || event.metaKey) return; if (!/^\d$/.test(event.key)) event.preventDefault(); }); phoneInput.addEventListener('paste', function (event) { event.preventDefault(); var text = (event.clipboardData || window.clipboardData).getData('text') || ''; phoneInput.value = formatPhone(onlyDigits(text)); clearError(form, 'phone'); }); if (ageCheck) ageCheck.addEventListener('change', function () { clearError(form, 'age'); }); var addressInput = form.querySelector('#address'); if (addressInput) { addressInput.addEventListener('input', function () { clearError(form, 'address'); }); } form.addEventListener('submit', function (event) { event.preventDefault(); if (submitBtn.disabled) return; clearError(form, 'name'); clearError(form, 'phone'); clearError(form, 'age'); clearError(form, 'address'); // Honeypot if (botCheck && botCheck.value.trim() !== '') { window.location.href = 'success.html'; return; } // 18+ checkbox if (ageCheck && !ageCheck.checked) { showError(form, 'age', ERR_18); return; } // नाम if (!validName(nameInput.value)) { showError(form, 'name', ERR_NAME); nameInput.focus(); return; } // फ़ोन var digits = getDigits(phoneInput); var checked = validatePhone(digits); if (!checked.ok) { showError(form, 'phone', checked.message); phoneInput.focus(); return; } // पता (Address) if (addressInput) { var addressVal = addressInput.value.trim(); var words = addressVal.split(/\s+/).filter(function (w) { return w.length > 0; }); if (words.length < 3) { showError(form, 'address', ERR_ADDRESS); addressInput.focus(); return; } } // Cooldown var tNow = now(); var map = cleanupMap(getMap()); if (map[checked.digits] && tNow - map[checked.digits] < COOLDOWN_MS) { showError(form, 'phone', 'यह नंबर अभी भेजा जा चुका है। 10 मिनट बाद फिर कोशिश करें।'); phoneInput.focus(); setMap(map); return; } // Direct submission (no confirm modal) setPhoneFields(phoneInput, phoneFull, checked.digits); map[checked.digits] = tNow; setMap(map); setLocal(LAST_PHONE_KEY, checked.digits); submitBtn.disabled = true; submitBtn.textContent = 'प्रोसेस हो रहा है...'; try { localStorage.setItem('mx_customer_name', nameInput.value.trim()); } catch(e) {} if (typeof window.submitLeadToGoogleSheets === 'function') { var ipVal = document.getElementById('CustomerIP') ? document.getElementById('CustomerIP').value : 'unknown'; window.submitLeadToGoogleSheets(form, ipVal, 'lead_block_' + ipVal); } else { form.submit(); } }); }); } /* ============================================================ 11. Counter "1,847 पुरुष इस महीने" ============================================================ */ function initMonthlyCounter() { var el = document.getElementById('monthlyOrders'); if (!el) return; var KEY = 'mx_monthly_orders_v2'; var TS_KEY = 'mx_monthly_orders_ts_v2'; var stored = parseInt(getLocal(KEY), 10); if (!stored || stored < 9000 || stored > 18000) { stored = rand(11500, 13500); setLocal(KEY, stored); setLocal(TS_KEY, now()); } var lastTs = parseInt(getLocal(TS_KEY), 10) || now(); // पिछले visit से random rate पर जोड़ते हैं var elapsedMin = Math.floor((now() - lastTs) / 60000); if (elapsedMin > 0) { stored += Math.min(elapsedMin * rand(2, 5), 400); setLocal(KEY, stored); setLocal(TS_KEY, now()); } el.textContent = stored.toLocaleString('en-IN'); // कभी-कभी सामने +1 tick करता है (25-60 सेकंड में) function tick() { stored += 1; setLocal(KEY, stored); setLocal(TS_KEY, now()); el.textContent = stored.toLocaleString('en-IN'); el.classList.add('mc-flash'); setTimeout(function () { el.classList.remove('mc-flash'); }, 600); setTimeout(tick, rand(25000, 60000)); } setTimeout(tick, rand(15000, 30000)); } /* ============================================================ 12. Micro-timer "कॉल 30 मिनट में" ============================================================ */ function initCallTimer() { var el = document.getElementById('callTimer'); if (!el) return; var KEY = 'mx_call_timer_v1'; var deadlineCt = parseInt(getSession(KEY), 10); if (!deadlineCt || deadlineCt <= now()) { deadlineCt = now() + rand(28, 32) * 60 * 1000; setSession(KEY, deadlineCt); } function render() { var remain = Math.max(0, Math.ceil((deadlineCt - now()) / 1000)); var m = Math.floor(remain / 60), s = remain % 60; el.textContent = two(m) + ':' + two(s); if (remain <= 0) { deadlineCt = now() + rand(28, 32) * 60 * 1000; setSession(KEY, deadlineCt); } } render(); setInterval(render, 1000); } /* ============================================================ ?error= parameter handling (api.php redirect के बाद) ============================================================ */ function initErrorFromUrl() { var params = new URLSearchParams(window.location.search); var errCode = params.get('error'); if (!errCode) return; var msgMap = { 'name': 'कृपया अपना सही नाम दर्ज करें (उदाहरण: राहुल, अमित)', 'phone': 'मोबाइल नंबर 10 अंकों का होना चाहिए और 6, 7, 8 या 9 से शुरू होना चाहिए।' }; var msg = msgMap[errCode]; if (!msg) return; var form = document.querySelector('.order-form-v8'); if (!form) return; // error दिखाएँ var el = form.querySelector('[data-error-for="' + errCode + '"]'); if (el) { el.textContent = msg; el.classList.add('is-visible'); } // form तक scroll करें setTimeout(function () { var formEl = document.getElementById('orderFormBorder'); if (formEl) formEl.scrollIntoView({ behavior: 'smooth', block: 'start' }); var input = form.querySelector(errCode === 'phone' ? '#phoneNational' : '#name'); if (input) input.focus(); }, 300); // URL से ?error= साफ़ करें (F5 पर फिर न दिखे) if (window.history && window.history.replaceState) { var clean = window.location.pathname + window.location.hash; window.history.replaceState({}, document.title, clean); } } /* ============================================================ Comments lazy-load (section #comments की images + avatars) Images तभी load होती हैं जब user section के पास आता है, page load पर तुरंत नहीं. ============================================================ */ function initLazyComments() { var section = document.getElementById('comments'); if (!section || !('IntersectionObserver' in window)) return; // section की सारी img को data-src format में बदलते हैं, पहले 2 comments छोड़कर var items = section.querySelectorAll('.comments__item'); items.forEach(function (item, idx) { if (idx < 2) return; // पहले 2 comments eager load होते हैं var imgs = item.querySelectorAll('img'); imgs.forEach(function (img) { if (img.src && !img.dataset.src) { img.dataset.src = img.src; img.removeAttribute('src'); img.style.minHeight = '40px'; img.style.background = '#f0f0f0'; } }); }); // Observer: comment viewport के पास हो तो images load करें var io = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (!entry.isIntersecting) return; var imgs = entry.target.querySelectorAll('img[data-src]'); imgs.forEach(function (img) { img.src = img.dataset.src; img.removeAttribute('data-src'); img.style.minHeight = ''; img.style.background = ''; }); io.unobserve(entry.target); }); }, { rootMargin: '300px 0px' }); items.forEach(function (item, idx) { if (idx >= 2) io.observe(item); }); } /* ============================================================ SERVICE WORKER REGISTRATION (repeat visits के लिए) ============================================================ */ function initServiceWorker() { if (!('serviceWorker' in navigator)) return; // load के बाद register करें ताकि first render block न हो window.addEventListener('load', function () { navigator.serviceWorker.register('sw.js').catch(function () { /* silent */ }); }); } /* ============================================================ Initialization ============================================================ */ document.addEventListener('DOMContentLoaded', function () { initHeaderDate(); initPublishDate(); initNextMonth(); initOfferTimerAndStock(); toastBoxes = Array.prototype.slice.call(document.querySelectorAll('.wr-box-order')); stickyCta = document.querySelector('.sticky-cta'); orderForm = document.querySelector('#orderFormBorder') || document.querySelector('#buyForm') || document.querySelector('#orderFormBorder'); hydrateUtm(); initForms(); initScrollTop(); initMonthlyCounter(); initCallTimer(); initErrorFromUrl(); initLazyComments(); initServiceWorker(); window.addEventListener('scroll', onScrollOrResize, { passive: true }); window.addEventListener('resize', updateStickyCta); document.addEventListener('visibilitychange', function () { if (document.hidden && fomoTimer) clearTimeout(fomoTimer); if (!document.hidden && fomoStarted) fomoTimer = setTimeout(showFomoToast, rand(20000, 45000)); }); onScrollOrResize(); }); })();