(function (A) { let deferredPrompt = null; let swRegistration = null; A.pwa = { isFileProtocol() { return location.protocol === 'file:'; }, isSupported() { return 'serviceWorker' in navigator && !A.pwa.isFileProtocol(); }, isStandalone() { return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true; }, getPlatform() { const ua = navigator.userAgent; const isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream; const isIPadOS = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; if (isIOS || isIPadOS) return 'ios'; if (/Android/.test(ua)) return 'android'; if (/Chrome|Chromium|Edg/.test(ua)) return 'desktop-chromium'; if (/Firefox/.test(ua)) return 'firefox'; if (/Safari/.test(ua)) return 'desktop-safari'; return 'other'; }, canPromptInstall() { return deferredPrompt !== null; }, async promptInstall() { if (!deferredPrompt) return { outcome: 'unavailable' }; deferredPrompt.prompt(); const choice = await deferredPrompt.userChoice; deferredPrompt = null; return choice; }, async register() { if (!A.pwa.isSupported()) return null; try { swRegistration = await navigator.serviceWorker.register('./sw.js', { scope: './' }); return swRegistration; } catch (err) { console.warn('Service worker registration failed:', err); return null; } } }; window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; document.dispatchEvent(new CustomEvent('pwa:install-available')); }); window.addEventListener('appinstalled', () => { deferredPrompt = null; document.dispatchEvent(new CustomEvent('pwa:installed')); }); })(window.App.Application);