|
1 | 1 | <!DOCTYPE html> |
2 | 2 | <html lang="en" class="scroll-smooth"> |
3 | | -<!-- Hidden page‑view ping (no visible counter) --> |
4 | 3 | <script> |
5 | | - (()=>{ |
6 | | - const key = location.pathname.replace(/\/$/, '') || '/'; |
7 | | - const WEBAPP = 'https://script.google.com/macros/s/AKfycbwUzIOAcNR3PD9-NdOg-Ni-N3dcZEKNFBXV_f3Q4bEVSD9m13ZaLsvBy9VefVCnQOIGBg/exec'; |
8 | | - // fire‐and‐forget; ignore the JSON response |
9 | | - fetch(WEBAPP + '?key=' + encodeURIComponent(key), {mode:'cors'}) |
10 | | - .catch(()=>{/* silent */}); |
11 | | - })(); |
| 4 | +!function(){ |
| 5 | + const EXEC='https://script.google.com/macros/s/AKfycbwC-_W7t-hghRH49cI188oDnIVuBbrRcCvE5FsZDma2tOGdPIsRj1FobbFQajGz2EsUIA/exec'; |
| 6 | + const key=(location.pathname.replace(/\/$/,'')||'/'); |
| 7 | +
|
| 8 | + // short hit id to correlate base + geo rows |
| 9 | + const hid = Math.random().toString(36).slice(2,10); |
| 10 | +
|
| 11 | + const base = new URLSearchParams(); |
| 12 | + base.set('key', key); |
| 13 | + base.set('hid', hid); |
| 14 | + base.set('tz', Intl.DateTimeFormat().resolvedOptions().timeZone || ''); |
| 15 | + base.set('lang', navigator.language || ''); |
| 16 | + base.set('ref', document.referrer || ''); |
| 17 | +
|
| 18 | + // Optional: UTM tags |
| 19 | + try{ |
| 20 | + const u=new URL(location.href); |
| 21 | + ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'] |
| 22 | + .forEach(k=>{ const v=u.searchParams.get(k); if(v) base.set(k,v); }); |
| 23 | + }catch(_){} |
| 24 | +
|
| 25 | + const send = (params) => { |
| 26 | + const body = params.toString(); |
| 27 | + if (navigator.sendBeacon) navigator.sendBeacon(EXEC, body); |
| 28 | + else fetch(EXEC, {method:'POST', mode:'no-cors', |
| 29 | + headers:{'Content-Type':'application/x-www-form-urlencoded'}, |
| 30 | + body}).catch(()=>{}); |
| 31 | + }; |
| 32 | +
|
| 33 | + // 1) send counts + basics right away (quiet POST) |
| 34 | + addEventListener('load', ()=> { |
| 35 | + setTimeout(()=> send(base), 300+Math.random()*700); |
| 36 | +
|
| 37 | + // 2) fetch geo (no sampling) and send a log-only enrichment |
| 38 | + fetch('https://get.geojs.io/v1/ip/geo.json') |
| 39 | + .then(r=>r.json()) |
| 40 | + .then(g=>{ |
| 41 | + const p = new URLSearchParams(base); |
| 42 | + p.set('logonly','1'); // IMPORTANT: do not increment again |
| 43 | + p.set('country', g.country || ''); |
| 44 | + p.set('region', g.region || ''); |
| 45 | + p.set('city', g.city || ''); |
| 46 | + send(p); |
| 47 | + }) |
| 48 | + .catch(()=>{/* skip if geo fails */}); |
| 49 | + }); |
| 50 | +}(); |
12 | 51 | </script> |
13 | 52 | <!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "f65726a952f5404f95c3dd044873152c"}'></script><!-- End Cloudflare Web Analytics --> |
14 | 53 | <head> |
|
0 commit comments