1(function () { 2 'use strict'; 3 if (typeof SCC_CONFIG === 'undefined') return; 4 5 var cfg = SCC_CONFIG; 6 var root, banner, modal, reopen; 7 var activated = { functional: false, analytics: false, advertisement: false }; 8 9 function randomId() { 10 if (window.crypto && crypto.getRandomValues) { 11 var a = new Uint32Array(4); crypto.getRandomValues(a); 12 return Array.prototype.map.call(a, function(n){ return n.toString(36); }).join(''); 13 } 14 return 'c' + Date.now().toString(36) + Math.random().toString(36).slice(2, 14); 15 } 16 17 function getCookie(name) { 18 var parts = document.cookie ? document.cookie.split('; ') : []; 19 for (var i = 0; i < parts.length; i++) { 20 var pos = parts[i].indexOf('='); 21 var key = pos > -1 ? parts[i].slice(0, pos) : parts[i]; 22 if (key === name) return decodeURIComponent(parts[i].slice(pos + 1)); 23 } 24 return ''; 25 } 26 27 function readConsent() { 28 try { 29 var raw = getCookie(cfg.cookieName); 30 if (!raw) return null; 31 var data = JSON.parse(raw); 32 if (!data || String(data.version) !== String(cfg.policyVersion)) return null; 33 return data; 34 } catch (e) { return null; } 35 } 36 37 function writeConsent(state, eventType) { 38 var previous = readConsent(); 39 var payload = { 40 id: previous && previous.id ? previous.id : randomId(), 41 necessary: true, 42 functional: !!state.functional, 43 analytics: !!state.analytics, 44 advertisement: !!state.advertisement, 45 version: String(cfg.policyVersion), 46 ts: Math.floor(Date.now() / 1000) 47 }; 48 var maxAge = Math.max(1, Number(cfg.consentDays) || 180) * 86400; 49 var secure = location.protocol === 'https:' ? '; Secure' : ''; 50 document.cookie = cfg.cookieName + '=' + encodeURIComponent(JSON.stringify(payload)) + '; Path=/; Max-Age=' + maxAge + '; SameSite=Lax' + secure; 51 var revoked = !!(previous && ( 52 (previous.functional && !payload.functional) || 53 (previous.analytics && !payload.analytics) || 54 (previous.advertisement && !payload.advertisement) 55 )); 56 applyConsent(payload, previous); 57 sendLog(payload, eventType || 'save'); 58 if (revoked) window.setTimeout(function(){ window.location.reload(); }, 80); 59 return payload; 60 } 61 62 function sendLog(state, eventType) { 63 if (!cfg.logEnabled || !window.fetch) return; 64 var body = new URLSearchParams(); 65 body.set('action', 'scc_log_consent'); 66 body.set('nonce', cfg.nonce); 67 body.set('consent_id', state.id); 68 body.set('policy_version', state.version); 69 body.set('event_type', eventType); 70 body.set('state', JSON.stringify(state)); 71 fetch(cfg.ajaxUrl, { method: 'POST', credentials: 'same-origin', headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}, body: body.toString(), keepalive: true }).catch(function(){}); 72 } 73 74 function updateGoogleConsent(s) { 75 if (!cfg.googleConsent) return; 76 window.dataLayer = window.dataLayer || []; 77 window.gtag = window.gtag || function(){ window.dataLayer.push(arguments); }; 78 window.gtag('consent', 'update', { 79 analytics_storage: s.analytics ? 'granted' : 'denied', 80 ad_storage: s.advertisement ? 'granted' : 'denied', 81 ad_user_data: s.advertisement ? 'granted' : 'denied', 82 ad_personalization: s.advertisement ? 'granted' : 'denied', 83 functionality_storage: s.functional ? 'granted' : 'denied', 84 personalization_storage: s.functional ? 'granted' : 'denied', 85 security_storage: 'granted' 86 }); 87 } 88 89 function deleteCookieByName(name) { 90 var host = location.hostname; 91 var pieces = host.split('.'); 92 var domains = ['', host, '.' + host]; 93 for (var i = 1; i < pieces.length - 1; i++) domains.push('.' + pieces.slice(i).join('.')); 94 domains = domains.filter(function(v, i, a){ return a.indexOf(v) === i; }); 95 var paths = ['/', location.pathname || '/']; 96 domains.forEach(function(domain){ 97 paths.forEach(function(path){ 98 document.cookie = name + '=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=' + path + (domain ? '; Domain=' + domain : '') + '; SameSite=Lax'; 99 }); 100 }); 101 } 102 103 function cleanupCategory(category) { 104 var names = document.cookie ? document.cookie.split('; ').map(function(c){ return c.split('=')[0]; }) : []; 105 var analyticsPrefixes = ['_ga','_gid','_gat','_clck','_clsk','_hj']; 106 var adPrefixes = ['_fbp','_fbc','_gcl','IDE','test_cookie']; 107 var prefixes = category === 'analytics' ? analyticsPrefixes : adPrefixes;
108 names.forEach(function(name){ 109 if (prefixes.some(function(p){ return name.indexOf(p) === 0; })) deleteCookieByName(name); 110 }); 111 } 112 113 function activateBlockedScripts(category) { 114 if (activated[category]) return; 115 var nodes = document.querySelectorAll('script[type="text/plain"][data-scc-category="' + category + '"][data-scc-blocked="1"]'); 116 Array.prototype.forEach.call(nodes, function(old){ 117 if (old.getAttribute('data-scc-activated') === '1') return; 118 var s = document.createElement('script'); 119 Array.prototype.forEach.call(old.attributes, function(attr){ 120 if (['type','data-scc-category','data-scc-blocked','data-scc-activated'].indexOf(attr.name) === -1) s.setAttribute(attr.name, attr.value); 121 }); 122 if (old.textContent) s.text = old.textContent; 123 old.setAttribute('data-scc-activated','1'); 124 old.parentNode.insertBefore(s, old.nextSibling); 125 }); 126 activated[category] = true; 127 } 128 129 function decodeBase64Utf8(value) { 130 try { 131 var binary = window.atob(value || ''); 132 if (window.TextDecoder) { 133 var bytes = new Uint8Array(binary.length); 134 for (var i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i); 135 return new TextDecoder('utf-8').decode(bytes); 136 } 137 return decodeURIComponent(Array.prototype.map.call(binary, function(c){ return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); 138 } catch (e) { return ''; } 139 } 140 141 function executeTemplate(category) { 142 var templates = document.querySelectorAll('template[data-scc-template="' + category + '"]'); 143 Array.prototype.forEach.call(templates, function(tpl){ 144 if (tpl.getAttribute('data-scc-executed') === '1') return; 145 tpl.setAttribute('data-scc-executed','1'); 146 var box = document.createElement('div'); 147 box.innerHTML = decodeBase64Utf8(tpl.getAttribute('data-scc-code')); 148 var scripts = box.querySelectorAll('script'); 149 Array.prototype.forEach.call(scripts, function(old){ 150 var s = document.createElement('script'); 151 Array.prototype.forEach.call(old.attributes, function(a){ s.setAttribute(a.name, a.value); }); 152 if (old.textContent) s.text = old.textContent; 153 old.parentNode.replaceChild(s, old); 154 }); 155 while (box.firstChild) document.body.appendChild(box.firstChild); 156 }); 157 } 158 159 function setupBlockedFrames() { 160 var frames = document.querySelectorAll('iframe[data-scc-blocked-frame="1"]'); 161 Array.prototype.forEach.call(frames, function(frame){ 162 if (frame.getAttribute('data-scc-placeholder') === '1') return; 163 frame.setAttribute('data-scc-placeholder','1'); 164 frame.style.display = 'none'; 165 if (frame.getAttribute('data-scc-category') !== 'functional') return; 166 var p = document.createElement('div'); 167 p.className = 'scc-frame-placeholder'; 168 p.setAttribute('data-scc-frame-placeholder','1'); 169 p.innerHTML = '<p></p><button type="button" class="scc-btn scc-btn-secondary" data-scc-action="settings"></button>'; 170 p.querySelector('p').textContent = cfg.blockedFrameText; 171 p.querySelector('button').textContent = cfg.settingsText; 172 frame.parentNode.insertBefore(p, frame.nextSibling); 173 }); 174 } 175 176 function activateFrames(category) { 177 var frames = document.querySelectorAll('iframe[data-scc-category="' + category + '"][data-scc-src]'); 178 Array.prototype.forEach.call(frames, function(frame){ 179 if (frame.getAttribute('data-scc-restored') === '1') return; 180 frame.src = frame.getAttribute('data-scc-src'); 181 frame.setAttribute('data-scc-restored','1'); 182 frame.style.display = ''; 183 var next = frame.nextElementSibling; 184 if (next && next.hasAttribute('data-scc-frame-placeholder')) next.remove(); 185 }); 186 } 187 188 function activateImages(category) { 189 var images = document.querySelectorAll('img[data-scc-category="' + category + '"][data-scc-src]'); 190 Array.prototype.forEach.call(images, function(img){ 191 if (img.getAttribute('data-scc-restored') === '1') return; 192 img.src = img.getAttribute('data-scc-src'); 193 img.setAttribute('data-scc-restored','1'); 194 }); 195 } 196 197 function applyConsent(s, previous) { 198 updateGoogleConsent(s); 199 ['functional','analytics','advertisement'].forEach(function(category){ 200 if (s[category]) { 201 activateBlockedScripts(category); 202 executeTemplate(category); 203 activateFrames(category); 204 activateImages(category); 205 } else if (previous && previous[category]) { 206 if (category === 'analytics' || category === 'advertisement') cleanupCategory(category); 207 } 208 }); 209 } 210 211 function setCheckboxes(s) { 212 ['functional','analytics','advertisement'].forEach(function(k){ 213 var el = modal && modal.querySelector('input[type="checkbox"][data-scc-category="' + k + '"]'); 214 if (el) el.checked = !!(s && s[k]); 215 }); 216 } 217 218 function openSettings() { 219 var s = readConsent(); 220 setCheckboxes(s || {functional:false,analytics:false,advertisement:false}); 221 if (modal) modal.hidden = false;
222 document.documentElement.classList.add('scc-modal-open'); 223 var first = modal && modal.querySelector('button, input'); if (first) first.focus(); 224 } 225 226 function closeSettings() { 227 if (modal) modal.hidden = true; 228 document.documentElement.classList.remove('scc-modal-open'); 229 } 230 231 function hideBanner() { 232 if (banner) banner.hidden = true; 233 if (reopen) reopen.hidden = false; 234 } 235 236 function rejectAll() { 237 var denied = {functional:false,analytics:false,advertisement:false}; 238 setCheckboxes(denied); 239 writeConsent(denied, 'reject'); 240 hideBanner(); 241 closeSettings(); 242 } 243 244 function saveFromModal() { 245 var s = {}; 246 ['functional','analytics','advertisement'].forEach(function(k){ 247 var el = modal && modal.querySelector('input[type="checkbox"][data-scc-category="' + k + '"]'); s[k] = !!(el && el.checked); 248 }); 249 writeConsent(s, 'save'); hideBanner(); closeSettings(); 250 } 251 252 function init() { 253 root = document.getElementById('scc-root'); 254 banner = document.getElementById('scc-banner'); 255 modal = document.getElementById('scc-modal'); 256 reopen = document.getElementById('scc-reopen'); 257 setupBlockedFrames(); 258 259 var s = readConsent(); 260 if (root) root.hidden = false; 261 if (s) { 262 if (banner) banner.hidden = true; 263 if (reopen) reopen.hidden = false; 264 applyConsent(s, null); 265 } else { 266 if (banner) banner.hidden = false; 267 if (reopen) reopen.hidden = true; 268 } 269 270 document.addEventListener('click', function(e){ 271 var btn = e.target.closest ? e.target.closest('[data-scc-action]') : null; 272 if (!btn) return; 273 var action = btn.getAttribute('data-scc-action'); 274 if (action === 'settings') { e.preventDefault(); openSettings(); } 275 if (action === 'close') { e.preventDefault(); closeSettings(); } 276 if (action === 'accept') { e.preventDefault(); writeConsent({functional:true,analytics:true,advertisement:true}, 'accept'); hideBanner(); closeSettings(); } 277 if (action === 'reject') { e.preventDefault(); e.stopPropagation(); rejectAll(); } 278 if (action === 'save') { e.preventDefault(); saveFromModal(); } 279 }); 280 281 document.addEventListener('keydown', function(e){ if (e.key === 'Escape' && modal && !modal.hidden) closeSettings(); }); 282 } 283 284 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); 285})();
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.