1(function () { 2 'use strict'; 3 var SITEKEY = '0x4AAAAAADiVOynXw_ZhYDP0'; 4 var EXCLUDED = /^\/(login|get-started|account|quiz)(\.html)?\/?$/; 5 var MIN_DELAY = 20000, TIME_TRIGGER = 75000, RETRY = 20000, DISMISS_MS = 7 * 864e5; 6 var BTN = 'Get deal alerts'; 7 var MAIL = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/></svg>'; 8 var CHECK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>'; 9 var CSS = '.ccnl{position:fixed;right:24px;bottom:24px;width:360px;max-width:calc(100vw - 48px);box-sizing:border-box;background:#fff;border:1px solid var(--border,#E2E8F0);border-radius:var(--r-lg,20px);box-shadow:0 16px 48px rgba(7,30,74,.25);padding:24px;z-index:2100;font-family:inherit;color:var(--text-dark,#1A1A2E);opacity:0;transform:translateY(24px);transition:transform .35s cubic-bezier(.2,.8,.2,1),opacity .35s cubic-bezier(.2,.8,.2,1)}' + 10 '.ccnl.ccnl-in{opacity:1;transform:none}' + 11 '.ccnl-x{position:absolute;top:10px;right:10px;width:32px;height:32px;border:0;background:none;border-radius:50%;color:var(--text-light,#718096);font:inherit;font-size:22px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}' + 12 '.ccnl-x:hover{background:var(--bg-light,#F7F9FC);color:var(--text-dark,#1A1A2E)}' + 13 '.ccnl-eyebrow{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--primary,#0B2D6B);margin:0 0 10px}' + 14 '.ccnl-eyebrow svg{width:16px;height:16px;flex-shrink:0;color:var(--accent-gold,#F5A623)}' + 15 '.ccnl h3{font-size:19px;font-weight:800;letter-spacing:-.3px;line-height:1.25;margin:0 0 8px;color:var(--primary,#0B2D6B)}' + 16 '.ccnl-main>p{font-size:14px;line-height:1.55;color:var(--text-gray,#4A5568);margin:0 0 16px}' + 17 '.ccnl input{width:100%;box-sizing:border-box;height:44px;padding:0 14px;border:1.5px solid var(--border,#E2E8F0);border-radius:10px;font:inherit;font-size:15px;color:inherit;outline:none;background:#fff}' + 18 '.ccnl input:focus{border-color:var(--accent,#1E7FD4);box-shadow:0 0 0 3px rgba(30,127,212,.18)}' + 19 '.ccnl-err{display:none;color:#DC2626;font-size:13px;margin:6px 0 0}.ccnl-err.on{display:block}' + 20 '.ccnl-ts{margin-top:10px}.ccnl-ts:empty{margin:0}' + 21 '.ccnl-btn{width:100%;height:46px;margin-top:12px;border:0;border-radius:10px;background:var(--accent,#1E7FD4);color:#fff;font:inherit;font-size:15px;font-weight:700;cursor:pointer;transition:background .2s,transform .2s}' + 22 '.ccnl-btn:hover{background:var(--accent-light,#4BA3F0);transform:translateY(-1px)}.ccnl-btn:disabled{opacity:.7;cursor:default;transform:none}' + 23 '.ccnl-ok{display:flex;align-items:center;gap:12px;font-size:15px;font-weight:600;color:var(--primary,#0B2D6B);padding:6px 0}' + 24 '.ccnl-ok svg{width:36px;height:36px;flex-shrink:0;color:var(--accent,#1E7FD4)}' + 25 '@media (max-width:640px){.ccnl{left:12px;right:12px;bottom:12px;width:auto;max-width:none;padding:18px 16px 16px}.ccnl-eyebrow{display:none}.ccnl h3{font-size:17px;padding-right:28px}.ccnl p{font-size:13px;margin-bottom:12px}.ccnl-x{width:40px;height:40px;top:4px;right:4px}}' + 26 '@media (prefers-reduced-motion:reduce){.ccnl{transition:none;transform:none}}'; 27 var HTML = '<button class="ccnl-x" type="button" aria-label="Close">×</button>' + 28 '<div class="ccnl-main"><div class="ccnl-eyebrow">' + MAIL + 'Deal alerts</div>' + 29 '<h3 id="ccnl-title">Never miss a big sign-up bonus</h3>' + 30 '<p>An alert when a welcome bonus jumps, plus a monthly roundup of our top picks. Free, no spam, unsubscribe anytime.</p>' + 31 '<form novalidate><input type="email" name="email" autocomplete="email" inputmode="email" placeholder="[email protected]" aria-label="Email address" required>' + 32 '<p class="ccnl-err" aria-live="polite"></p><div class="ccnl-ts"></div>' + 33 '<button class="ccnl-btn" type="submit">' + BTN + '</button></form></div>'; 34 35 var root = null, widgetId = null, token = '', tsDead = false;
36 37 function ls(k) { try { return localStorage.getItem(k); } catch (e) { return null; } } 38 function ss(k) { try { return sessionStorage.getItem(k); } catch (e) { return null; } } 39 function setLs(k, v) { try { localStorage.setItem(k, v); } catch (e) {} } 40 function setSs(k, v) { try { sessionStorage.setItem(k, v); } catch (e) {} } 41 function track(name, params) { 42 if (typeof gtag !== 'function') return; 43 params = params || {}; 44 var src = ss('cc_src'); 45 if (src) params.src = src; 46 gtag('event', name, params); 47 } 48 49 function eligible() { 50 if (ls('cc_subscribed') || ss('cc_nl_shown')) return false; 51 var d = +ls('cc_nl_dismissed'); 52 if (d && Date.now() - d < DISMISS_MS) return false; 53 if (window.innerWidth < 320 || EXCLUDED.test(location.pathname)) return false; 54 try { 55 var u = JSON.parse(ls('cc_user') || 'null'); 56 if (u && (u.newsletter || u.subscribed)) return false; 57 } catch (e) {} 58 return true; 59 } 60 function inlineFormVisible() { 61 var el = document.getElementById('newsletter-wrap') || document.getElementById('guides-nl-wrap'); 62 if (!el) return false; 63 var r = el.getBoundingClientRect(); 64 return r.height > 0 && r.bottom > 0 && r.top < window.innerHeight; 65 } 66 67 function loadTurnstile(cb) { 68 if (window.turnstile) return cb(); 69 if (!document.querySelector('script[src*="challenges.cloudflare.com/turnstile"]')) { 70 var s = document.createElement('script'); 71 s.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; 72 s.async = true; 73 document.head.appendChild(s); 74 } 75 var tries = 0, iv = setInterval(function () { 76 if (window.turnstile) { clearInterval(iv); cb(); } 77 else if (++tries > 100) { clearInterval(iv); tsDead = true; } 78 }, 100); 79 } 80 function renderTurnstile() { 81 if (!root) return; 82 var opts = { 83 sitekey: SITEKEY, appearance: 'interaction-only', size: 'flexible', 84 callback: function (t) { token = t; }, 85 'expired-callback': function () { token = ''; }, 86 'error-callback': function () { token = ''; tsDead = true; } 87 }; 88 var el = root.querySelector('.ccnl-ts'); 89 try { widgetId = window.turnstile.render(el, opts); } 90 catch (e) { opts.size = 'normal'; try { widgetId = window.turnstile.render(el, opts); } catch (e2) {} } 91 } 92 function tsCall(fn) { 93 if (widgetId === null || !window.turnstile || !window.turnstile[fn]) return null; 94 try { return window.turnstile[fn](widgetId); } catch (e) { return null; } 95 } 96 97 function showError(msg) { 98 var el = root.querySelector('.ccnl-err'); 99 el.textContent = msg; 100 el.classList.add('on'); 101 } 102 function submit(e) { 103 e.preventDefault(); 104 var input = root.querySelector('input'), email = input.value.trim(); 105 root.querySelector('.ccnl-err').classList.remove('on'); 106 if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { showError('Enter a valid email address.'); input.focus(); return; } 107 if (!token) token = tsCall('getResponse') || ''; 108 if (!token && tsDead) { showError('Verification unavailable â please use the newsletter form on our homepage.'); root.querySelector('.ccnl-btn').disabled = true; return; } 109 if (!token) { showError('Verifying youâre human⦠try again in a second.'); tsCall('execute'); return; } 110 var btn = root.querySelector('.ccnl-btn'); 111 btn.disabled = true; 112 btn.textContent = 'Subscribingâ¦'; 113 fetch('/api/subscribe', { 114 method: 'POST', headers: { 'Content-Type': 'application/json' }, 115 body: JSON.stringify({ email: email, cfToken: token }) 116 }).then(function (r) { return r.json(); }).then(function (d) { 117 if (!root) return; 118 if (d.status !== 'subscribed') throw new Error('bad response'); 119 setLs('cc_subscribed', email); 120 track('newsletter_signup', { source: 'popup', page_path: location.pathname }); 121 root.querySelector('.ccnl-main').innerHTML = '<div class="ccnl-ok" role="status">' + CHECK + 'Youâre in. Watch your inbox.</div>'; 122 setTimeout(function () { close(false); }, 4000); 123 }).catch(function () { 124 if (!root) return; 125 showError('Something went wrong â please try again.'); 126 btn.disabled = false;
127 btn.textContent = BTN; 128 token = ''; 129 tsCall('reset'); 130 }); 131 } 132 133 function onKey(e) { if (e.key === 'Escape') close(true); } 134 function open(trigger) { 135 if (root) return; 136 if (!document.getElementById('ccnl-css')) { 137 var st = document.createElement('style'); 138 st.id = 'ccnl-css'; 139 st.textContent = CSS; 140 document.head.appendChild(st); 141 } 142 root = document.createElement('div'); 143 root.className = 'ccnl'; 144 root.setAttribute('role', 'dialog'); 145 root.setAttribute('aria-labelledby', 'ccnl-title'); 146 root.innerHTML = HTML; 147 document.body.appendChild(root); 148 root.querySelector('.ccnl-x').addEventListener('click', function () { close(true); }); 149 root.querySelector('form').addEventListener('submit', submit); 150 document.addEventListener('keydown', onKey); 151 setSs('cc_nl_shown', '1'); 152 loadTurnstile(renderTurnstile); 153 requestAnimationFrame(function () { requestAnimationFrame(function () { root && root.classList.add('ccnl-in'); }); }); 154 track('nl_popup_show', { trigger: trigger }); 155 } 156 function close(dismissed) { 157 if (!root) return; 158 var el = root; 159 root = null; 160 el.classList.remove('ccnl-in'); 161 document.removeEventListener('keydown', onKey); 162 setTimeout(function () { el.parentNode && el.parentNode.removeChild(el); }, 400); 163 tsCall('remove'); 164 widgetId = null; 165 token = ''; 166 if (dismissed) { setLs('cc_nl_dismissed', String(Date.now())); track('nl_popup_dismiss'); } 167 } 168 169 function arm() { 170 if (!eligible()) return; 171 var start = Date.now(), fired = false, timer = null, visibleMs = 0, since = Date.now(); 172 var fine = window.matchMedia && matchMedia('(pointer: fine)').matches; 173 function attempt(trigger) { 174 if (!eligible()) return; 175 var cb = document.getElementById('cookie-banner'), a = document.activeElement; 176 var busy = (cb && cb.offsetHeight > 0) || (a && /^(INPUT|TEXTAREA|SELECT)$/.test(a.tagName)) || inlineFormVisible(); 177 if (busy) { setTimeout(function () { attempt(trigger); }, RETRY); return; } 178 open(trigger); 179 } 180 function fire(trigger) { 181 if (fired || Date.now() - start < MIN_DELAY) return; 182 fired = true; 183 clearTimeout(timer); 184 window.removeEventListener('scroll', onScroll); 185 document.removeEventListener('mouseleave', onLeave); 186 document.removeEventListener('visibilitychange', onVis); 187 attempt(trigger); 188 } 189 function onScroll() { 190 var h = document.documentElement.scrollHeight - window.innerHeight; 191 if (h > 0 && window.scrollY / h >= 0.55) fire('scroll'); 192 } 193 function onLeave(e) { if (e.clientY <= 0) fire('exit'); } 194 function onVis() { 195 if (document.visibilityState === 'visible') { 196 since = Date.now(); 197 timer = setTimeout(function () { fire('time'); }, TIME_TRIGGER - visibleMs); 198 } else { 199 visibleMs += Date.now() - since; 200 clearTimeout(timer); 201 } 202 } 203 window.addEventListener('scroll', onScroll, { passive: true }); 204 if (fine) document.addEventListener('mouseleave', onLeave); 205 document.addEventListener('visibilitychange', onVis); 206 if (document.visibilityState === 'visible') onVis(); 207 setTimeout(onScroll, MIN_DELAY); 208 } 209 210 window.ccNewsletter = { open: function (trigger) { open(trigger || 'manual'); }, close: function () { close(true); } }; 211 arm(); 212})();
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.