/* PolHunter embed. One line on a mission site:
plus, where a code may appear, elements with data-ph-slot="0" ... data-ph-slot="N-1".
When a hunter arrives with ?ph= (their own, from their PolHunter board) the token is kept
in sessionStorage for this tab, and after the mission's dwell the code is fetched from
polhunter.com and rendered in ONE of the slots (which one is picked per hunter per day). The
request carries this page's Origin; polhunter.com answers only for the mission's own host and
only after the dwell. Anyone else loading this page sees nothing at all. */
(function () {
var API = 'https://polhunter.com';
try {
// the token arrives in the hash (#ph=) or, for older links, the query (?ph=); it is kept for this tab
var h = new URLSearchParams((location.hash || '').replace(/^#/, '')), q = new URLSearchParams(location.search), t = h.get('ph') || q.get('ph');
if (t) { sessionStorage.setItem('ph.token', t); h.delete('ph'); q.delete('ph'); history.replaceState(null, '', location.pathname + (q.toString() ? '?' + q : '') + (h.toString() ? '#' + h : '')); }
t = sessionStorage.getItem('ph.token'); if (!t) return;
} catch (e) { return; }
// slots: explicit [data-ph-slot="i"] elements, or the i-th match of data-selector (e.g. ".video-card"
// on a training page, ".card" on a programs page), else a fixed badge in the corner
var me = document.currentScript, slots = Number((me && me.getAttribute('data-slots')) || 1) || 1, sel = me && me.getAttribute('data-selector');
function slotEl(i) {
var el = document.querySelector('[data-ph-slot="' + i + '"]'); if (el) return el;
if (sel) { var all = document.querySelectorAll(sel); if (all.length) { var host = all[i % all.length]; var d0 = document.createElement('div'); d0.style.cssText = 'margin:10px 0'; host.appendChild(d0); return d0; } }
var d = document.createElement('div'); d.setAttribute('data-ph-slot', String(i)); d.style.cssText = 'position:fixed;right:16px;bottom:16px;z-index:99999'; document.body.appendChild(d); return d;
}
function render(code, slot) {
var el = slotEl(slot); el.innerHTML = '';
var box = document.createElement('div');
box.setAttribute('role', 'note');
box.style.cssText = 'display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border-radius:14px;background:linear-gradient(135deg,#1a0f3d,#2b1a63);color:#f1eefb;font:600 14px/1.2 system-ui,-apple-system,"Segoe UI",sans-serif;box-shadow:0 8px 30px rgba(130,71,229,.45),0 0 0 1px rgba(255,255,255,.08);letter-spacing:.02em';
box.innerHTML = '
PolHunter code ' + code + '';
el.appendChild(box);
}
var tries = 0, pending = null, done = false;
// phones freeze a background tab's timers: when the hunter comes back to this tab, ask right away
document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible' && !done) { clearTimeout(pending); ask(); } });
function ask() {
tries++; if (tries > 80 || done) return;
fetch(API + '/api/embed/code?t=' + encodeURIComponent(t), { mode: 'cors', credentials: 'omit' }).then(function (r) { return r.json(); }).then(function (r) {
if (r && r.code) { done = true; render(r.code, Number(r.slot) % slots); try { sessionStorage.removeItem('ph.token'); } catch (e) {} return; }
if (r && r.wait) { pending = setTimeout(ask, Math.min(r.wait, 5) * 1000); return; }
// expired / gone / wrong origin: say nothing
}).catch(function () { pending = setTimeout(ask, 6000); });
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ask); else ask();
})();