1/* First-party asynchronous analytics. Never sends form values or full query strings as event data. */ 2(() => { 3 const send = (name, data = {}) => { 4 try { 5 const body = JSON.stringify({ name, url: location.href, referrer: document.referrer, ...data }); 6 fetch('/stats_collect.php', { method: 'POST', credentials: 'same-origin', keepalive: true, 7 headers: { 'Content-Type': 'application/json' }, body }).catch(() => {}); 8 } catch (_) { /* Analytics must not interrupt shopping. */ } 9 }; 10 const meta = name => document.querySelector(`meta[name="${name}"]`)?.content || ''; 11 const page = meta('page_param'), product = Number(meta('page_id')) || 0; 12 send('page_view'); 13 if (page === 'product' && product) send('product_view', { product_id: product }); 14 if (page === 'category') send('category_view', { category_id: String(product) }); 15 if (page === 'search') send('search'); 16 if (document.querySelector('#payment-form')) send('begin_checkout'); 17 setInterval(() => { if (document.visibilityState === 'visible') send('heartbeat'); }, 60000); 18 document.addEventListener('change', e => { 19 if (e.target.matches('[name="size"]')) send('select_size', { product_id: product, size: e.target.value }); 20 if (e.target.matches('[name="sort"], [name="filter"], .filters select')) send('filter'); 21 }); 22 document.addEventListener('click', e => { 23 const item = e.target.closest('.sizes label, .add_wishlist, a, button'); 24 if (!item) return; 25 if (item.matches('.sizes label')) send('select_size', { product_id: product, size: item.querySelector('input')?.value || '' }); 26 else send('click', { action: item.matches('.add_wishlist') ? 'wishlist' : (item.tagName === 'A' ? 'link' : 'button') }); 27 }); 28})();
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.