1(function () { 2 'use strict'; 3 4 var params = new URLSearchParams(window.location.search); 5 var debugMode = params.get('ga_debug') === '1' || window.sessionStorage.getItem('tg_ga_debug') === '1'; 6 7 if (params.get('ga_debug') === '1') { 8 try { window.sessionStorage.setItem('tg_ga_debug', '1'); } catch (e) {} 9 } 10 if (params.get('ga_debug') === '0') { 11 try { window.sessionStorage.removeItem('tg_ga_debug'); } catch (e) {} 12 debugMode = false; 13 } 14 15 function readCookies() { 16 var out = {}; 17 document.cookie.split(';').forEach(function (c) { 18 var idx = c.indexOf('='); 19 if (idx < 0) return; 20 var k = c.slice(0, idx).trim(); 21 var v = c.slice(idx + 1).trim(); 22 if (/^(_ga|_gid|_gat|OptanonConsent|OptanonAlertBoxClosed|FPID|FPLC|_gcl_)/.test(k)) { 23 out[k] = v; 24 } 25 }); 26 return out; 27 } 28 29 function decodeGl(gl) { 30 if (!gl) return null; 31 try { 32 var parts = gl.split('*'); 33 return { raw: gl, version: parts[0], payloadCount: parts.length }; 34 } catch (e) { return { raw: gl, parseError: String(e) }; } 35 } 36 37 function snapshot(label) { 38 var gl = new URLSearchParams(window.location.search).get('_gl'); 39 var dl = window.dataLayer ? window.dataLayer.slice(-10) : null; 40 var consent = null; 41 try { 42 var optCookie = readCookies().OptanonConsent; 43 if (optCookie) { 44 var groups = decodeURIComponent(optCookie).match(/groups=([^&]+)/); 45 consent = groups ? groups[1] : optCookie.slice(0, 120); 46 } 47 } catch (e) {} 48 49 var payload = { 50 label: label, 51 url: window.location.href, 52 host: window.location.hostname, 53 referrer: document.referrer || '(none)', 54 _gl: decodeGl(gl), 55 cookies: readCookies(), 56 consentGroups: consent, 57 dataLayerTail: dl, 58 gtagPresent: typeof window.gtag === 'function', 59 gtmContainers: (window.google_tag_manager ? Object.keys(window.google_tag_manager).filter(function (k) { return /^GTM-/.test(k); }) : []), 60 timestamp: new Date().toISOString() 61 }; 62 63 console.groupCollapsed('%c[GA4-DEBUG] ' + label, 'color:#c00;font-weight:bold'); 64 console.log(payload); 65 console.groupEnd(); 66 return payload; 67 } 68 69 function installClickProbe() { 70 document.addEventListener('click', function (e) { 71 var a = e.target && e.target.closest ? e.target.closest('a[href]') : null; 72 if (!a) return; 73 var href = a.getAttribute('href'); 74 var abs; 75 try { abs = new URL(href, window.location.href); } catch (err) { return; } 76 var sameHost = abs.hostname === window.location.hostname; 77 var crossTaylor = /(^|\.)taylorguitars\.com$/.test(abs.hostname) && !sameHost; 78 console.groupCollapsed('%c[GA4-DEBUG] click', 'color:#06c'); 79 console.log({ 80 href: href, 81 resolved: abs.href, 82 targetHost: abs.hostname, 83 sameHost: sameHost, 84 crossDomainTaylor: crossTaylor, 85 willLikelyDecorate: crossTaylor || /shop\.taylorguitars\.com$/.test(abs.hostname), 86 elementText: (a.textContent || '').trim().slice(0, 80), 87 elementId: a.id || null, 88 elementClass: a.className || null, 89 isLogo: !!a.closest('.site-logo, .logo, [class*="logo"]') 90 }); 91 console.groupEnd(); 92 }, true); 93 } 94 95 function installHistoryProbe() { 96 var origReplace = history.replaceState; 97 var origPush = history.pushState; 98 history.replaceState = function () { 99 console.log('[GA4-DEBUG] history.replaceState', arguments[2], 'from', window.location.href); 100 return origReplace.apply(this, arguments); 101 }; 102 history.pushState = function () { 103 console.log('[GA4-DEBUG] history.pushState', arguments[2], 'from', window.location.href); 104 return origPush.apply(this, arguments); 105 }; 106 } 107 108 function cleanupGlParam() { 109 var currentParams = new URLSearchParams(window.location.search); 110 if (!currentParams.has('_gl')) return; 111 if (debugMode) return; 112 113 currentParams.delete('_gl'); 114 var qs = currentParams.toString(); 115 var newUrl = window.location.pathname + (qs ? '?' + qs : '') + window.location.hash; 116 try { 117 window.history.replaceState(window.history.state, document.title, newUrl); 118 } catch (e) {} 119 } 120 121 if (debugMode) { 122 snapshot('initial'); 123 installClickProbe(); 124 installHistoryProbe(); 125 window.addEventListener('load', function () { setTimeout(function () { snapshot('window.load+1s'); }, 1000); }); 126 window.tgGaDebug = { snapshot: snapshot, off: function () { try { sessionStorage.removeItem('tg_ga_debug'); } catch (e) {} console.log('[GA4-DEBUG] disabled for next page load'); } }; 127 console.log('%c[GA4-DEBUG] active. Call tgGaDebug.snapshot() any time. tgGaDebug.off() to disable.', 'color:#c00'); 128 } 129 130 if (window.location.search.indexOf('_gl=') !== -1) { 131 if (document.readyState === 'complete') { 132 setTimeout(cleanupGlParam, 2500); 133 } else { 134 window.addEventListener('load', function () { setTimeout(cleanupGlParam, 2500); }); 135 } 136 } 137})();
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.