SPB Git forge

spb/admin-ka

Public
41commits 1branches 0releases
172.9 MBsize
maindefault branch
19 days agolast push
JavaScript 65.5% Python 17.8% CSS 13% HTML 3.7%
3.4 KB · 72 lines javascript
Raw Blame History
1/* ka-a.js v2 — analytics first-party Groupe KA (administration-ka.com)2 * Léger, asynchrone, sans cookie tiers, sans fingerprinting, sans contenu saisi.3 * - visitor_id (KA_VID, localStorage) : anonyme, persistant, dédup refresh4 * - session_id (KA_SID) : nouvelle session après 30 min d'inactivité5 * - page view : chargement + navigations SPA (pushState/replaceState/popstate)6 * - heartbeat 25 s : SEULEMENT si l'onglet est visible ET activité < 60 s7 *   (scroll/pointeur/clavier/touch — on note QU'une interaction a eu lieu, jamais son contenu)8 * → un onglet fermé ou inactif disparaît du compteur « en ligne » en ~2 min. */9(function () {10  try {11    if (window.__kaAn2) return; window.__kaAn2 = 1;12    var HOST = 'https://www.administration-ka.com';13    var SITE = window.__kaSite || (document.currentScript && document.currentScript.dataset.site) || '';14    if (!SITE) return;15    var SESS_MS = 30 * 60 * 1000, HB_MS = 25 * 1000, INT_MS = 60 * 1000;1617    function rid() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 8); }18    function lsGet(k) { try { return localStorage.getItem(k); } catch (e) { return null; } }19    function lsSet(k, v) { try { localStorage.setItem(k, v); } catch (e) {} }2021    var vid = lsGet('KA_VID'); if (!vid) { vid = rid(); lsSet('KA_VID', vid); }22    function sid() {23      var now = Date.now(), s = lsGet('KA_SID'), last = +(lsGet('KA_SLAST') || 0);24      if (!s || now - last > SESS_MS) { s = rid(); lsSet('KA_SID', s); }25      lsSet('KA_SLAST', String(now));26      return s;27    }28    var dev = (function () { var w = Math.min(screen.width, screen.height) || innerWidth; return w <= 500 ? 'm' : w <= 900 ? 't' : 'd'; })();2930    function send(ev, withRef) {31      var u = HOST + '/collect?site=' + encodeURIComponent(SITE)32        + '&vid=' + vid + '&sid=' + sid() + '&ev=' + ev33        + '&p=' + encodeURIComponent(location.pathname)34        + '&d=' + dev35        + (withRef && document.referrer && document.referrer.indexOf(location.host) === -136            ? '&r=' + encodeURIComponent(document.referrer.slice(0, 180)) : '')37        + '&t=' + Date.now();38      if (navigator.sendBeacon) { try { navigator.sendBeacon(u); return; } catch (e) {} }39      var i = new Image(); i.src = u;40    }4142    var lastPath = location.pathname;43    function pv() { lastPath = location.pathname; send('pv', true); }4445    // navigation SPA = nouvelle page vue (jamais un heartbeat)46    function hookHistory(fn) {47      var orig = history[fn];48      history[fn] = function () { var r = orig.apply(this, arguments); onNav(); return r; };49    }50    function onNav() { if (location.pathname !== lastPath) setTimeout(pv, 0); }51    hookHistory('pushState'); hookHistory('replaceState');52    addEventListener('popstate', onNav);5354    // présence réelle : interaction récente + onglet visible55    var lastInt = Date.now();56    function bump() { lastInt = Date.now(); }57    ['pointerdown', 'keydown', 'scroll', 'touchstart', 'mousemove'].forEach(function (e) {58      addEventListener(e, bump, { passive: true, capture: true });59    });60    setInterval(function () {61      if (document.visibilityState !== 'visible') return;62      if (Date.now() - lastInt > INT_MS) return;63      send('hb');64    }, HB_MS);65    document.addEventListener('visibilitychange', function () {66      if (document.visibilityState === 'visible') { bump(); send('hb'); }67    });6869    pv();70  } catch (e) {}71})();72