// CyberMax game service worker: the game works offline after the first visit. Cache-first for the game's own files, // network-first for the page itself (so updates arrive), never caches API calls or other sites. (c) 2026 CyberMax. const GAME = 'pathmoor'; const CACHE = `cmx-${GAME}-4b226fa7a1`; const FILES = ["index.html", "cmx.js", "core.js", "fun.css", "funpass.js", "game.js", "icon-192.png", "icon-512.png", "icon-maskable.png", "icon.svg", "index.html", "manifest.webmanifest", "style.css"]; self.addEventListener('install', (e) => { e.waitUntil(caches.open(CACHE).then((c) => c.addAll(FILES)).then(() => self.skipWaiting())); }); self.addEventListener('activate', (e) => { e.waitUntil(caches.keys().then((keys) => Promise.all(keys.filter((k) => k.startsWith(`cmx-${GAME}-`) && k !== CACHE).map((k) => caches.delete(k)))).then(() => self.clients.claim())); }); self.addEventListener('fetch', (e) => { const u = new URL(e.request.url); if (e.request.method !== 'GET' || u.origin !== location.origin || !u.pathname.startsWith(new URL(self.registration.scope).pathname)) return; if (e.request.mode === 'navigate') { e.respondWith(fetch(e.request).then((r) => { const c = r.clone(); caches.open(CACHE).then((x) => x.put(u.pathname, c)); return r; }) .catch(() => caches.match(u.pathname).then((r) => r || caches.match('index.html')))); return; } e.respondWith(caches.match(e.request, { ignoreSearch: true }).then((r) => r || fetch(e.request).then((res) => { if (res.ok) { const c = res.clone(); caches.open(CACHE).then((x) => x.put(e.request, c)); } return res; }))); });