// strip.js - shared plumbing for every GLiNER 2.5 demo page. // 1. __sign shim: private HF Spaces sign the iframe URL; Safari/incognito block // the third-party cookie, so carry the token on same-origin API requests. // 2. readiness poll: drives the model strip (loading -> preparing -> ready). // 3. fetchConfig(): title/subtitle/examples, so the page is data-driven. (() => { const sign = new URLSearchParams(location.search).get("__sign"); if (!sign) return; const orig = self.fetch.bind(self); self.fetch = (input, init) => { try { const u = new URL(typeof input === "string" ? input : input.url, location.href); if (u.origin === location.origin && !u.searchParams.has("__sign")) { u.searchParams.set("__sign", sign); input = u.toString(); } } catch (e) { /* non-URL input: pass through */ } return orig(input, init); }; })(); function stripSet(message, tone, pct) { const strip = document.getElementById("model-strip"); const pill = document.getElementById("status-pill"); const status = document.getElementById("status"); if (!strip || !status) return; // demo page removed the strip; nothing to update status.textContent = message; strip.className = `model-strip is-${tone}`; if (pill) pill.className = `status-pill is-${tone}`; if (pct != null) { const bar = document.getElementById("load-progress"); if (bar) bar.style.width = `${pct}%`; } } async function waitForServer() { stripSet("Connecting", "loading", 12); for (let attempt = 0; attempt < 300; attempt++) { try { const r = await fetch("api/ready", { cache: "no-store" }); if (r.ok && (await r.json()).ready) return true; } catch (e) { /* still starting */ } stripSet("Warming up", "loading", Math.min(92, 12 + attempt * 4)); await new Promise((r) => setTimeout(r, 1000)); } return false; } async function fetchConfig() { const r = await fetch("api/config", { cache: "no-store" }); return r.json(); }