1(function () { 2 const body = document.body; 3 const burger = document.querySelector('[data-burger]'); 4 const nav = document.querySelector('[data-nav]'); 5 const toast = document.querySelector('[data-toast]'); 6 const uploadLinks = document.querySelectorAll('[data-upload-link]'); 7 const revealItems = document.querySelectorAll('.reveal'); 8 9 function closeMenu() { 10 body.classList.remove('nav-open'); 11 if (burger) burger.setAttribute('aria-expanded', 'false'); 12 } 13 14 function showToast(message) { 15 if (!toast) return; 16 toast.textContent = message; 17 toast.classList.add('is-visible'); 18 window.clearTimeout(showToast.timer); 19 showToast.timer = window.setTimeout(() => { 20 toast.classList.remove('is-visible'); 21 }, 3200); 22 } 23 24 if (burger) { 25 burger.addEventListener('click', () => { 26 const isOpen = body.classList.toggle('nav-open'); 27 burger.setAttribute('aria-expanded', String(isOpen)); 28 }); 29 } 30 31 if (nav) { 32 nav.addEventListener('click', (event) => { 33 if (event.target.closest('a')) closeMenu(); 34 }); 35 } 36 37 const cards = document.querySelectorAll('.template-card'); 38 39 if (cards.length > 0) { 40 cards.forEach(card => { 41 card.addEventListener('click', () => { 42 window.location.href = '/app'; 43 }); 44 }); 45 } 46 47 document.addEventListener('click', (event) => { 48 const shot = event.target.closest('.shot'); 49 50 if (!shot) return; 51 52 window.location.href = '/app'; 53 }); 54 55 const accordion = document.querySelector('[data-accordion]'); 56 if (accordion) { 57 accordion.addEventListener('click', (event) => { 58 const button = event.target.closest('button'); 59 if (!button) return; 60 61 const item = button.closest('.faq-item'); 62 const body = item ? item.querySelector('.faq-item__body') : null; 63 const isOpen = button.getAttribute('aria-expanded') === 'true'; 64 65 button.setAttribute('aria-expanded', String(!isOpen)); 66 if (body) body.hidden = isOpen; 67 }); 68 } 69 70 if ('IntersectionObserver' in window) { 71 const observer = new IntersectionObserver((entries) => { 72 entries.forEach((entry) => { 73 if (entry.isIntersecting) { 74 entry.target.classList.add('is-visible'); 75 observer.unobserve(entry.target); 76 } 77 }); 78 }, { threshold: 0.12 }); 79 80 revealItems.forEach((item) => observer.observe(item)); 81 } else { 82 revealItems.forEach((item) => item.classList.add('is-visible')); 83 } 84 85 document.addEventListener('keydown', (event) => { 86 if (event.key === 'Escape') closeMenu(); 87 }); 88}()); 89 90(() => { 91 const timers = new WeakMap(); 92 93 window.PicBloomToast = (message, type = 'info', timeout = 3200) => { 94 const toast = document.querySelector('[data-app-toast], [data-history-toast], [data-toast]'); 95 if (!toast) return; 96 97 toast.textContent = String(message || ''); 98 toast.dataset.type = type; 99 toast.classList.add('is-visible'); 100 101 const previous = timers.get(toast); 102 if (previous) window.clearTimeout(previous); 103 104 const timer = window.setTimeout(() => { 105 toast.classList.remove('is-visible'); 106 delete toast.dataset.type; 107 }, timeout); 108 timers.set(toast, timer); 109 }; 110})();
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.