1// JavaScript Document 2var $ = jQuery.noConflict(); 3 4 // ââ State ââ 5 let popupShown = false; 6 7 // ââ Open / Close ââ 8 function openPopup() { 9 document.getElementById('overlay').classList.add('active'); 10 document.body.style.overflow = 'hidden'; 11 popupShown = true; 12 } 13 14 function closePopup() { 15 document.getElementById('overlay').classList.remove('active'); 16 document.body.style.overflow = ''; 17 } 18 19 // Click outside to close 20 function handleOverlayClick(e) { 21 if (e.target === document.getElementById('overlay')) closePopup(); 22 } 23 24 // ESC key to close 25 document.addEventListener('keydown', e => { 26 if (e.key === 'Escape') closePopup(); 27 }); 28 29 // ââ EXIT INTENT DETECTION ââ 30 document.addEventListener('mouseleave', function(e) { 31 // Trigger when cursor moves toward top of viewport (leaving the tab) 32 if (e.clientY <= 10 && !popupShown) { 33 openPopup(); 34 } 35 }); 36 37 // Mobile: trigger on scroll back up (exit intent for mobile) 38 let lastScrollY = 0; 39 let scrollUpCount = 0; 40 window.addEventListener('scroll', function() { 41 const currentScrollY = window.scrollY; 42 if (currentScrollY < lastScrollY) { 43 scrollUpCount++; 44 // After scrolling up significantly, show popup 45 if (scrollUpCount > 3 && !popupShown && currentScrollY < 200) { 46 openPopup(); 47 } 48 } else { 49 scrollUpCount = 0; 50 } 51 lastScrollY = currentScrollY; 52 }, { passive: true }); 53 54 // ââ Auto-show on load (for demo only â remove in production) ââ 55 window.addEventListener('DOMContentLoaded', () => { 56 setTimeout(openPopup, 2000); 57 }); 58
59 // ââ Background image fallback chain (multiple Unsplash options) ââ 60 const bgImages = [ 61 'https://images.unsplash.com/photo-1540575467063-178a50c2df87?w=900&q=85&auto=format&fit=crop', 62 'https://images.unsplash.com/photo-1475721027785-f74eccf877e2?w=900&q=85&auto=format&fit=crop', 63 'https://images.unsplash.com/photo-1505373877841-8d25f7d46678?w=900&q=85&auto=format&fit=crop', 64 'https://images.unsplash.com/photo-1492684223066-81342ee5ff30?w=900&q=85&auto=format&fit=crop', 65 ]; 66 let bgIndex = 0; 67 function tryNextImage() { 68 bgIndex++; 69 const img = document.getElementById('main-bg'); 70 if (img && bgIndex < bgImages.length) { 71 img.src = bgImages[bgIndex]; 72 } else if (img) { 73 img.style.display = 'none'; 74 const fb = document.getElementById('crowd-fallback'); 75 if (fb) fb.style.display = 'block'; 76 } 77 }
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.