1(() => { 2 'use strict'; 3 const toggle = document.querySelector('.antom-menu-toggle'); 4 const nav = document.querySelector('.antom-nav'); 5 if (toggle && nav) { 6 const close = () => { toggle.setAttribute('aria-expanded', 'false'); nav.classList.remove('is-open'); }; 7 toggle.addEventListener('click', () => { const open = toggle.getAttribute('aria-expanded') !== 'true'; toggle.setAttribute('aria-expanded', String(open)); nav.classList.toggle('is-open', open); }); 8 document.addEventListener('keydown', e => { if(e.key === 'Escape' && nav.classList.contains('is-open')) { close(); toggle.focus(); } }); 9 nav.addEventListener('click', e => { if(e.target.closest('a')) close(); }); 10 document.addEventListener('click', e => { if(!nav.contains(e.target) && !toggle.contains(e.target)) close(); }); 11 } 12 document.querySelectorAll('[data-antom-video]').forEach(button => { 13 button.addEventListener('click', () => { 14 const id = button.dataset.antomVideo; 15 if (!/^[A-Za-z0-9_-]{11}$/.test(id)) return; 16 const iframe = document.createElement('iframe'); 17 iframe.src = 'https://www.youtube-nocookie.com/embed/' + id; 18 iframe.title = button.dataset.title || 'æè¡åç»'; 19 iframe.allow = 'encrypted-media; picture-in-picture'; 20 iframe.allowFullscreen = true; iframe.loading = 'lazy'; 21 iframe.referrerPolicy = 'strict-origin-when-cross-origin'; 22 button.replaceWith(iframe); iframe.focus(); 23 }, {once:true}); 24 }); 25})(); 26 27(() => { 28 'use strict'; 29 document.querySelectorAll('[data-antom-hero]').forEach(root => { 30 const slides = Array.from(root.querySelectorAll('[data-hero-slide]')); 31 const controls = root.querySelector('[data-hero-controls]');
32 if (slides.length < 2 || !controls) return; 33 const previous = controls.querySelector('[data-hero-prev]'); 34 const next = controls.querySelector('[data-hero-next]'); 35 const play = controls.querySelector('[data-hero-play]'); 36 const position = controls.querySelector('[data-hero-position]'); 37 const reduced = window.matchMedia('(prefers-reduced-motion: reduce)'); 38 const hover = window.matchMedia('(hover: hover) and (pointer: fine)'); 39 let hovered = false; 40 let current = 0; 41 let paused = root.dataset.autoplay === '0' || reduced.matches; 42 const seconds = Number(root.dataset.interval); 43 const interval = (Number.isFinite(seconds) && seconds >= 3 && seconds <= 15 ? seconds : 5) * 1000; 44 const indicators = Array.from(controls.querySelectorAll('[data-hero-indicator]')); 45 let timer; 46 let animations = []; 47 const finishMotion = () => { animations.forEach(animation => animation.cancel()); animations = []; }; 48 const stopTimer = () => { window.clearTimeout(timer); timer = undefined; }; 49 const updateButton = () => { 50 play.textContent = paused ? play.dataset.textPlay : play.dataset.textPause; 51 play.setAttribute('aria-label', paused ? play.dataset.labelPlay : play.dataset.labelPause); 52 }; 53 const schedule = () => { 54 stopTimer(); 55 if (!paused && !hovered && !document.hidden) timer = window.setTimeout(() => show(current + 1), interval); 56 }; 57 const show = index => { 58 const outgoing = slides[current]; 59 const direction = index < current ? -1 : 1; 60 finishMotion(); 61 current = (index + slides.length) % slides.length; 62 const target = slides[current]; 63 const template = target.querySelector('template[data-hero-image]'); 64 if (template) template.replaceWith(template.content.cloneNode(true)); 65 slides.forEach((slide, i) => { 66 const active = i === current; 67 slide.classList.toggle('is-active', active); 68 slide.inert = !active; 69 if (active) slide.removeAttribute('aria-hidden'); 70 else slide.setAttribute('aria-hidden', 'true'); 71 }); 72 if (target !== outgoing && !reduced.matches && typeof target.animate === 'function') { 73 const timing = {duration: 600, easing: 'cubic-bezier(.22,.61,.36,1)'}; 74 animations = [ 75 outgoing.animate([ 76 {transform: 'translateX(0)', visibility: 'visible'}, 77 {transform: `translateX(${-direction * 100}%)`, visibility: 'visible'} 78 ], timing), 79 target.animate([ 80 {transform: `translateX(${direction * 100}%)`}, 81 {transform: 'translateX(0)'} 82 ], timing) 83 ]; 84 } 85 position.textContent = String(current + 1).padStart(2, '0') + ' / ' + String(slides.length).padStart(2, '0'); 86 indicators.forEach((indicator, i) => { 87 if (i === current) indicator.setAttribute('aria-current', 'true'); 88 else indicator.removeAttribute('aria-current'); 89 }); 90 schedule(); 91 }; 92 const pause = () => { paused = true; stopTimer(); updateButton(); }; 93 previous.addEventListener('click', () => show(current - 1)); 94 next.addEventListener('click', () => show(current + 1)); 95 indicators.forEach((indicator, i) => indicator.addEventListener('click', () => show(i))); 96 play.addEventListener('click', () => { paused = !paused; updateButton(); schedule(); }); 97 // Keep a focused slide link from becoming inert during automatic rotation. 98 root.addEventListener('focusin', event => { if (event.target.closest('[data-hero-slide]')) pause(); }); 99 root.addEventListener('pointerenter', event => { 100 if (!hover.matches || event.pointerType === 'touch') return; 101 hovered = true; stopTimer(); 102 }); 103 const leaveHover = () => { hovered = false; schedule(); }; 104 root.addEventListener('pointerleave', leaveHover); 105 root.addEventListener('pointercancel', leaveHover); 106 hover.addEventListener('change', () => { if (!hover.matches) leaveHover(); }); 107 document.addEventListener('visibilitychange', schedule); 108 reduced.addEventListener('change', () => { if (reduced.matches) { pause(); finishMotion(); } }); 109 controls.hidden = false; 110 updateButton(); 111 schedule(); 112 }); 113})(); 114 115/* Responsive placeholder on the single TOP search input. */ 116(()=>{ 117 const input=document.querySelector('#antom-top-search-input'); 118 if(!input)return; 119 const compact=window.matchMedia('(max-width: 600px)'); 120 const update=()=>{input.placeholder=compact.matches?input.dataset.compactPlaceholder:input.dataset.widePlaceholder;};
121 update(); 122 compact.addEventListener('change',update); 123})(); 124 125/* TOP only. A stable spacer prevents content reflow when the desktop header contracts. */ 126(()=>{ 127 if(!document.body.classList.contains('home')||document.body.classList.contains('antom-follow-disabled'))return; 128 const header=document.querySelector('.antom-header'); 129 if(!header)return; 130 const desktop=window.matchMedia('(min-width: 901px)'); 131 const spacer=document.createElement('div'); 132 spacer.setAttribute('aria-hidden','true'); 133 header.before(spacer); 134 let queued=false; 135 const update=()=>{ 136 queued=false; 137 if(!desktop.matches)return; 138 const utility=header.querySelector('.antom-header-utility'); 139 const focused=utility&&utility.contains(document.activeElement); 140 header.classList.toggle('is-compact',window.scrollY>80&&!focused); 141 }; 142 const measure=()=>{ 143 header.classList.remove('is-compact','antom-header-follow'); 144 spacer.style.height='0px'; 145 if(desktop.matches){ 146 const admin=document.querySelector('#wpadminbar'); 147 const offset=admin?admin.getBoundingClientRect().height:0; 148 header.style.setProperty('--antom-admin-offset',offset+'px'); 149 spacer.style.height=header.getBoundingClientRect().height+'px'; 150 header.classList.add('antom-header-follow'); 151 update(); 152 }else header.style.removeProperty('--antom-admin-offset'); 153 }; 154 window.addEventListener('scroll',()=>{if(!queued){queued=true;window.requestAnimationFrame(update);}},{passive:true}); 155 window.addEventListener('resize',measure); 156 desktop.addEventListener('change',measure); 157 header.addEventListener('focusin',update); 158 header.addEventListener('focusout',()=>window.requestAnimationFrame(update)); 159 const logo=header.querySelector('img'); 160 if(logo&&!logo.complete)logo.addEventListener('load',measure,{once:true}); 161 if(document.fonts)document.fonts.ready.then(measure); 162 measure(); 163})();
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.