1<!doctype html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <!-- Google tag (gtag.js) -->
vendor: 68 bytes, lines 5-6
5 6 <script async src="https://www.googletagmanager.com/gtag/js?id=
6G-5XRNJJF51K
vendor: 16 bytes, lines 6-7
6"></script> 7
7<script> 8 window.dataLayer = window.dataLayer || []; 9 function gtag(){dataLayer.push(arguments);} 10 gtag('js', new Date()); 11 var isNativeApp = typeof window.Capacitor !== 'undefined' || navigator.userAgent.indexOf('CapacitorApp') > -1 || window.location.protocol === 'capacitor:'; 12 gtag('config', 'G-5XRNJJF51K', { 13 'app_platform': isNativeApp ? 'ios_native' : 'web', 14 'custom_map': { 'dimension1': 'app_platform' } 15 }); 16 </script>
16 17 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no, maximum-scale=1.0" /> 18 19 <style> 20 /* Minimal fallback - theme gradient applied by inline script below */ 21 /* CRITICAL: Dark background prevents white flash on iOS during any reload */ 22 /* Also covers Dynamic Island / safe area with solid color */ 23 html, body { 24 margin: 0; 25 padding: 0; 26 min-height: 100vh; 27 min-height: 100dvh; 28 background: #000; 29 background-color: #000; 30 } 31 /* Ensure the safe-area behind Dynamic Island is always dark */ 32 html { 33 background-color: var(--loader-bg, #000) !important; 34 } 35 </style> 36 37 <title>MATCHDAY by Pickleball Inc. - Get Scores. Make Predictions.</title> 38 <meta name="description" content="Track Live Scores. Get Player Alerts. Make Predictions."> 39 <meta name="author" content="PBScores" /> 40 41 <!-- PWA and Mobile App Meta Tags --> 42 <!-- Will be updated dynamically by themeColorManager.ts based on selected theme --> 43 <meta name="theme-color" content="#000000" /> 44 <meta name="apple-mobile-web-app-capable" content="yes" /> 45 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> 46 <meta name="apple-mobile-web-app-title" content="MATCHDAY by Pickleball Inc." /> 47 <link rel="apple-touch-icon" href="/pblfg-2026-logo-6.webp"> 48 49 <!-- Preload the app logo: it is the LCP candidate on the initial route 50 (header brand + loading splash) so kicking it off in <head> shaves 51 300-800ms off first paint on slow connections. --> 52 <link rel="preload" as="image" href="/pblfg-2026-logo-6.webp" fetchpriority="high" /> 53 54 <!-- Browser compatibility check --> 55
55<script> 56 (function() { 57 // Check for critical features 58 var hasRequiredFeatures = 59 typeof Promise !== 'undefined' && 60 typeof fetch !== 'undefined' && 61 typeof localStorage !== 'undefined' && 62 typeof Object.assign !== 'undefined'; 63 64 if (!hasRequiredFeatures) { 65 document.addEventListener('DOMContentLoaded', function() { 66 document.body.innerHTML = '<div style="padding: 20px; font-family: sans-serif; max-width: 600px; margin: 0 auto;"><h1>Browser Not Supported</h1><p>Your browser is missing features required to run this app. Please update to a modern browser like Chrome, Safari, Firefox, or Edge.</p></div>'; 67 }); 68 } 69 })(); 70 </script>
70 71 72 <!-- Open Graph / Facebook --> 73 <meta property="og:type" content="website" /> 74 <meta property="og:url" content="https://pblfg.com/" /> 75 76 77 <meta property="og:image" content="https://storage.googleapis.com/gpt-engineer-file-uploads/WJrVyGkoLCPJdlPU9ic4HC8kja82/social-images/social-1774734549287-sharecard.webp"> 78 <meta property="og:image:secure_url" content="https://pblfg.com/sharecard.png" /> 79 <meta property="og:image:width" content="1200" /> 80 <meta property="og:image:height" content="630" /> 81 <meta property="og:image:alt" content="MATCHDAY - Real-Time Pickleball Scores" /> 82 83 <!-- Twitter --> 84 <meta name="twitter:card" content="summary_large_image" /> 85 <meta name="twitter:url" content="https://pblfg.com/" /> 86 <meta name="twitter:domain" content="pblfg.com" /> 87 <meta name="twitter:image" content="https://storage.googleapis.com/gpt-engineer-file-uploads/WJrVyGkoLCPJdlPU9ic4HC8kja82/social-images/social-1774734549287-sharecard.webp"> 88 <meta name="twitter:image:alt" content="MATCHDAY - Real-Time Pickleball Scores" /> 89 90 91 <!-- Preload remote-hosted fonts (Lovable Cloud) â kept out of the iOS bundle to avoid Apple ITMS-90853 --> 92 <link rel="preconnect" href="https://grwhdhnlafqrcmiuqhhi.supabase.co" crossorigin> 93 <link rel="preconnect" href="https://cdn.fontshare.com" crossorigin> 94 <link rel="preload" href="https://cdn.fontshare.com/wf/D2VP4PR6KFISH7CFEZQBVDPHE6XGGZWX/KE6JJBLOTZ2VLNFBKAZFXUVCHRYC6XSF/JFA5HRDFNHFTHIDA47YRUKD32JZ4ME6V.woff2" as="font" type="font/woff2" crossorigin> 95 <link rel="preload" href="https://cdn.fontshare.com/wf/ATKS7EHYU4PKFTXRA4UFAHPY7XS75QMY/OYTCFLQCR7FVKK7FIO7TCJPY4YG22I3S/GKSURDSYOFIC3Y6F5SMWSENDSAB2YMKC.woff2" as="font" type="font/woff2" crossorigin> 96 <link rel="preload" href="https://grwhdhnlafqrcmiuqhhi.supabase.co/storage/v1/object/public/app-fonts/PressStart2P-Regular.woff2" as="font" type="font/woff2" crossorigin> 97 98 <!-- Handwritten fonts for Pick 'Em --> 99 <link rel="preconnect" href="https://fonts.googleapis.com"> 100 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 101 <link href="https://fonts.googleapis.com/css2?family=Fredericka+the+Great&family=Kalam:wght@700&family=Permanent+Marker&family=Rock+Salt&display=swap" rel="stylesheet"> 102 103 <!-- Favicon is set on line 26 --> 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 <link rel="icon" type="image/webp" href="/pblfg-2026-logo-6.webp"> 165 <link rel="preload" as="image" href="/pblfg-2026-logo-6.webp" fetchpriority="high"> 166 167 168 169 170 <meta property="og:title" content="MATCHDAY by Pickleball Inc. - Get Scores. Make Predictions."> 171 <meta name="twitter:title" content="MATCHDAY by Pickleball Inc. - Get Scores. Make Predictions."> 172 <meta property="og:description" content="Track Live Scores. Get Player Alerts. Make Predictions."> 173 <meta name="twitter:description" content="Track Live Scores. Get Player Alerts. Make Predictions."> 174
174<script type="module" crossorigin src="/assets/index-BgCZMvjj.js"></script>
174 175 <link rel="modulepreload" crossorigin href="/assets/capacitor-DSpR9wll.js"> 176 <link rel="modulepreload" crossorigin href="/assets/react-vendor-Q2BSRknM.js"> 177 <link rel="modulepreload" crossorigin href="/assets/supabase-DoZmW4Yf.js"> 178 <link rel="modulepreload" crossorigin href="/assets/ui-radix-DzQ_orwq.js"> 179 <link rel="modulepreload" crossorigin href="/assets/lucide-Ckh7y__x.js"> 180 <link rel="modulepreload" crossorigin href="/assets/query-BLOP9k_M.js"> 181 <link rel="modulepreload" crossorigin href="/assets/date-utils-DaNoSKVa.js"> 182 <link rel="stylesheet" crossorigin href="/assets/index-C5lWRha4.css"> 183<link rel="manifest" href="/manifest.webmanifest">
183<script defer src="/~flock.js" data-proxy-url="/~api/analytics"></script>
183</head> 184 185 <body> 186
186<script> 187 // Apply theme gradient IMMEDIATELY before any content renders 188 (function() { 189 // Default to midnight-blue so native/web startup stays dark before app state loads 190 const theme = localStorage.getItem('theme') || 'midnight-blue'; 191 192 // Theme loader backgrounds - must match themeColorManager.ts 193 const themeGradients = { 194 'midnight-blue': 'hsl(220 50% 4%)', 195 'pickleball-dark': 'hsl(135 50% 1%)', 196 'pro-midnight': 'hsl(260 50% 6%)', 197 'xmas': 'hsl(350 40% 6%)', 198 'pure-void': 'hsl(210 20% 5%)', 199 'crimson-abyss': 'hsl(0 42% 4%)', 200 'burnt-sienna': 'hsl(18 45% 3%)', 201 'purple-haze': 'hsl(260 50% 6%)', 202 'electric-teal': 'hsl(185 55% 1%)', 203 'neon-rose': 'hsl(335 55% 4%)', 204 'ocean-breeze': 'hsl(195 100% 98%)', 205 'original-refined': 'hsl(0 0% 100%)', 206 'championship-gold': 'hsl(0 0% 100%)', 207 'pearl-mist': 'hsl(0 0% 100%)', 208 'sunset-rally': 'hsl(30 30% 97%)', 209 'carbon-fiber': 'hsl(0 0% 12%)' 210 }; 211 212 // Fallback to midnight-blue if theme not found 213 const bgGradient = themeGradients[theme] || themeGradients['midnight-blue']; 214 215 // Set data-theme attribute for CSS variables 216 document.documentElement.setAttribute('data-theme', theme); 217 218 // Single source-of-truth for ALL pre-content loader phases 219 document.documentElement.style.setProperty('--loader-bg', bgGradient); 220 window.__loaderBg = bgGradient; 221 222 // Apply background to both html and body for full coverage 223 document.documentElement.style.background = 'var(--loader-bg)'; 224 document.body.style.background = 'var(--loader-bg)'; 225 document.body.style.margin = '0'; 226 document.body.style.padding = '0'; 227 228 // Root stays transparent (React paints its own backgrounds) 229 const initialLoader = document.getElementById('root'); 230 if (initialLoader) { 231 initialLoader.style.background = 'transparent'; 232 } 233 })(); 234 235 // Apply logo based on saved app icon preference 236 (function() { 237 const appIcon = localStorage.getItem('app_icon') || 'default'; 238 const logoMap = { 239 'default': '/pblfg-2026-logo-6.webp', 240 'retro': '/retro-logo.png', 241 'winter': '/winter-logo.png', 242 'holiday': '/winter-logo.png' // Legacy alias 243 }; 244 window.__appLogoSrc = logoMap[appIcon] || '/pblfg-2026-logo-6.webp'; 245 })(); 246 </script>
246 247 <!-- Portal container for fixed elements - TRUE SIBLING to #root --> 248 <div id="fixed-portal" style="position: fixed !important; bottom: 0 !important; left: 0 !important; right: 0 !important; z-index: 9999 !important; transform: none !important; will-change: auto !important; contain: layout style !important; isolation: isolate !important; pointer-events: none;"></div> 249 250 <!-- Static loading screen shown before React loads (keep OUTSIDE #root so React doesn't wipe it) --> 251 <div id="initial-loader"> 252 <img id="loader-logo" src="/pblfg-2026-logo-6.webp" alt="MATCHDAY" onerror="this.onerror=null; this.src='/pblfg-2026-logo-6.webp';" /> 253 <!-- Status text removed - logo pulse is sufficient --> 254 <!-- Recovery UI - hidden initially, shown on timeout --> 255 <div id="loader-recovery" style="display: none; flex-direction: column; align-items: center; gap: 12px; margin-top: 24px; padding: 0 24px;"> 256 <p style="color: rgba(255,255,255,0.65); font-size: 14px; font-family: sans-serif; margin: 0 0 4px 0; text-align: center;">Taking longer than expected.<br/>Tap Retry, or Reset if Retry doesn't help.</p> 257 <button id="loader-retry-btn" style="padding: 12px 24px; background: rgba(59,130,246,0.85); color: white; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; min-width: 200px; cursor: pointer;">Retry</button> 258 <button id="loader-reset-btn" style="padding: 10px 24px; background: transparent; color: rgba(255,255,255,0.7); border: 1px solid rgba(255,255,255,0.25); border-radius: 8px; font-size: 14px; font-weight: 500; min-width: 200px; cursor: pointer;">Reset App Data</button> 259 </div> 260
260<script> 261 document.getElementById('loader-retry-btn')?.addEventListener('click', async function() { 262 this.textContent = 'Retrying...'; 263 this.disabled = true; 264 try { window.__pblfgBootBeacon && window.__pblfgBootBeacon('User tapped Retry', {}); } catch(e) {} 265 try { 266 if ('serviceWorker' in navigator) { 267 var regs = await navigator.serviceWorker.getRegistrations(); 268 await Promise.all(regs.map(function(r) { return r.unregister(); })); 269 } 270 if ('caches' in window) { 271 var names = await caches.keys(); 272 await Promise.all(names.map(function(n) { return caches.delete(n); })); 273 } 274 sessionStorage.clear(); 275 } catch(e) { console.error('Recovery cleanup failed:', e); } 276 window.location.reload(); 277 }); 278 document.getElementById('loader-reset-btn')?.addEventListener('click', async function() { 279 this.textContent = 'Resetting...'; 280 this.disabled = true; 281 try { window.__pblfgBootBeacon && window.__pblfgBootBeacon('User tapped Reset App Data', {}); } catch(e) {} 282 // Preserve essentials so users aren't logged out by a recovery wipe. 283 // Mirrors storageHealthManager.nuclearCleanup(): theme + auth session + 284 // preserve-auth flag. Auth key matches AUTH_STORAGE_KEY in 285 // src/utils/sessionPersistence.ts â keep these two in sync. 286 var theme = null, authToken = null, preserveAuthFlag = null; 287 try { theme = localStorage.getItem('theme'); } catch(e) {} 288 try { authToken = localStorage.getItem('sb-grwhdhnlafqrcmiuqhhi-auth-token'); } catch(e) {} 289 try { preserveAuthFlag = localStorage.getItem('pbpulse_preserve_auth_on_cleanup'); } catch(e) {} 290 // Honor the kill switch: if an admin disabled preservation, drop the token. 291 if (preserveAuthFlag === 'false') { authToken = null; } 292 try { localStorage.clear(); } catch(e) {} 293 try { sessionStorage.clear(); } catch(e) {} 294 if (theme) { try { localStorage.setItem('theme', theme); } catch(e) {} } 295 if (authToken) { try { localStorage.setItem('sb-grwhdhnlafqrcmiuqhhi-auth-token', authToken); } catch(e) {} } 296 if (preserveAuthFlag !== null) { try { localStorage.setItem('pbpulse_preserve_auth_on_cleanup', preserveAuthFlag); } catch(e) {} } 297 try { 298 if ('serviceWorker' in navigator) { 299 var regs = await navigator.serviceWorker.getRegistrations(); 300 await Promise.all(regs.map(function(r) { return r.unregister(); })); 301 } 302 if ('caches' in window) { 303 var names = await caches.keys(); 304 await Promise.all(names.map(function(n) { return caches.delete(n); })); 305 } 306 // IndexedDB wipe â the layer ordinary "clear cache" misses and a top 307 // suspect for the WebView "must reinstall" failure mode. 308 if (window.indexedDB && indexedDB.databases) { 309 try { 310 var dbs = await indexedDB.databases(); 311 await Promise.all((dbs || []).map(function(d) { 312 return new Promise(function(res){ 313 try { var r = indexedDB.deleteDatabase(d.name); r.onsuccess = r.onerror = r.onblocked = function(){ res(); }; } 314 catch(e) { res(); } 315 }); 316 })); 317 } catch(e) {} 318 } 319 } catch(e) { console.error('Reset failed:', e); } 320 window.location.reload(); 321 }); 322 </script>
322 323
323<script> 324 // Only swap the loader logo when a custom app icon is selected, and 325 // decode it off-screen first. Assigning a new (uncached) src directly 326 // blanks the image for a frame or two â that is the "flash of 327 // emptiness, then the logo pops back" on cold start. 328 (function () { 329 var el = document.getElementById('loader-logo'); 330 var want = window.__appLogoSrc || '/pblfg-2026-logo-6.webp'; 331 if (!el || !want || want === '/pblfg-2026-logo-6.webp') return; 332 var pre = new Image(); 333 pre.onload = function () { el.src = want; }; 334 pre.src = want; 335 })(); 336 337 // Track UI readiness at the HTML level so the native splash overlay can 338 // be lifted at the right moment (see setupReactMountListener in 339 // CustomBridgeViewController.swift) even if it asks late. 340 window.addEventListener('pblfg-ui-ready', function () { 341 window.__PBLFG_UI_READY__ = true; 342 }); 343 </script>
343 344 345 </div> 346 347 <div id="root"></div> 348 349 <style> 350 #root { 351 background: transparent; 352 } 353 354 #initial-loader { 355 position: fixed; 356 inset: 0; 357 display: flex; 358 flex-direction: column; 359 align-items: center; 360 justify-content: center; 361 gap: 1rem; 362 z-index: 9999; 363 background: var(--loader-bg, #000); 364 } 365 366 #loader-logo { 367 width: 100px; 368 height: 100px; 369 position: relative; 370 z-index: 9999; 371 } 372 373 /* When refreshing, hide the big logo - React will show bouncing pickleball */ 374 #initial-loader.is-refreshing #loader-logo { 375 display: none; 376 } 377 378 /* Already-booted-this-session: skip the splash entirely so in-session 379 reloads and same-tab navigations don't gate content behind the splash. */ 380 html.pblfg-booted #initial-loader { 381 display: none !important; 382 } 383 384 @keyframes pulse { 385 0%, 100% { 386 opacity: 1; 387 } 388 50% { 389 opacity: 0.5; 390 } 391 } 392 </style> 393 394
394<script> 395 // Already booted this session? Skip the splash entirely â the React app 396 // will paint its own skeletons. Restores fast in-session navigation so 397 // only true cold boot pays the splash-gating cost. 398 try { 399 if (sessionStorage.getItem('pblfg_booted') === '1') { 400 document.documentElement.classList.add('pblfg-booted'); 401 } 402 } catch (e) { /* ignore */ } 403 404 // Check if this is a refresh (not first load) - hide the logo loader 405 if (sessionStorage.getItem('pblfg_refreshing') === 'true') { 406 document.getElementById('initial-loader')?.classList.add('is-refreshing'); 407 } 408 409 // âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 410 // HTML-level boot watchdog 411 // 412 // Runs OUTSIDE the React/JS bundle so it works even if the bundle never 413 // loads (the actual "must reinstall" failure mode). Steps: 414 // ⢠If React never mounts, beacon the failure and keep the clean loader. 415 // Do NOT show a Retry panel automatically: iOS can snapshot that panel 416 // while backgrounded and then flash it on the next cold start even when 417 // the app is about to load normally. 418 // âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 419 (function setupBootWatchdog() { 420 var startedAt = Date.now(); 421 var WATCHDOG_MS = 15000; 422 // Track whether the page was ever hidden (backgrounded) during the boot 423 // window. iOS suspends the WebView's JS runloop when the app is 424 // backgrounded; if our setTimeout was queued before suspension and 425 // fires hours later on resume, it produces a false "React never 426 // mounted" beacon. We use this flag â plus an elapsed-time sanity 427 // check â to suppress those false positives. 428 var wasHiddenDuringBoot = (typeof document !== 'undefined' && document.visibilityState === 'hidden'); 429 try { 430 document.addEventListener('visibilitychange', function () { 431 if (document.visibilityState === 'hidden') wasHiddenDuringBoot = true; 432 }, { passive: true }); 433 } catch (e) { /* no-op */ } 434 435 function reactMounted() { 436 var root = document.getElementById('root'); 437 return !!(root && root.children && root.children.length > 0); 438 } 439 440 // If React mounts after the recovery UI was already shown, hide it 441 // immediately so users never see a flash of "Retry" on a slow cold boot. 442 try { 443 window.addEventListener('pblfg-react-mounted', function () { 444 var recovery = document.getElementById('loader-recovery'); 445 if (recovery) recovery.style.display = 'none'; 446 }, { once: true }); 447 } catch (e) { /* no-op */ } 448 449 // iOS WKWebView snapshot defense: iOS captures whatever is on screen 450 // when the app is backgrounded and replays it as the launch image on 451 // the next cold start. If the Retry UI was ever visible at suspend 452 // time, every future launch will flash that snapshot for a split 453 // second before React paints. Force the recovery UI hidden on every 454 // background/foreground transition so the snapshot is always clean. 455 try { 456 var hideRecovery = function () { 457 var recovery = document.getElementById('loader-recovery'); 458 if (recovery) recovery.style.display = 'none'; 459 }; 460 document.addEventListener('visibilitychange', function () { 461 if (document.visibilityState === 'hidden') hideRecovery(); 462 }, { passive: true }); 463 window.addEventListener('pagehide', hideRecovery, { passive: true }); 464 window.addEventListener('pageshow', hideRecovery, { passive: true }); 465 } catch (e) { /* no-op */ } 466 467 function beacon(message, extra) { 468 try { 469 var apiKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imdyd2hkaG5sYWZxcmNtaXVxaGhpIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjI2NDk4NjMsImV4cCI6MjA3ODIyNTg2M30.AS7_JF_qguIDtEEtN6YhNrACYmEzw_UdufeXVK1vXjg'; 470 var ua = navigator.userAgent || ''; 471 var platform = /Android/i.test(ua) ? 'android' : (/iPhone|iPad|iPod/i.test(ua) ? 'ios' : 'web'); 472 fetch('https://grwhdhnlafqrcmiuqhhi.supabase.co/rest/v1/error_analytics', { 473 method: 'POST', 474 headers: { 475 'Content-Type': 'application/json', 476 'apikey': apiKey, 477 'Authorization': 'Bearer ' + apiKey, 478 'Prefer': 'return=minimal' 479 }, 480 body: JSON.stringify({
481 error_message: ('[BOOT-WATCHDOG:' + platform + '] ' + message).substring(0, 2000), 482 error_stack: JSON.stringify(extra || {}).substring(0, 4000), 483 context: 'html-boot-watchdog', 484 page_path: '/', 485 is_native_app: /wv\)/.test(ua) || /Capacitor/i.test(ua), 486 user_agent: ua.substring(0, 500) 487 }) 488 }).catch(function(){}); 489 } catch (e) { /* never throw from a crash reporter */ } 490 } 491 // Expose for main.tsx to reuse (avoids duplicate beacon code). 492 window.__pblfgBootBeacon = beacon; 493 494 setTimeout(function () { 495 if (reactMounted() || window.__REACT_MOUNTED__) return; 496 497 var elapsed = Date.now() - startedAt; 498 499 // Suppress false positives from iOS WebView suspension: if the page 500 // was hidden during the boot window OR the timer fired noticeably 501 // late (runloop was paused), this isn't a real "React never mounted" 502 // failure â the JS thread was simply suspended and just resumed. 503 if (wasHiddenDuringBoot || document.visibilityState === 'hidden' || elapsed > WATCHDOG_MS + 4000) { 504 return; 505 } 506 507 // Final mount re-check after a short grace window â React often 508 // hydrates within a few hundred ms of the watchdog firing on slow 509 // cold boots, and showing the Retry UI for that brief sliver is the 510 // "flash of retry screen" users see. 511 setTimeout(function () { 512 if (reactMounted() || window.__REACT_MOUNTED__) return; 513 514 // Snapshot what we can about why React never mounted. 515 var snapshot = { 516 elapsed: Date.now() - startedAt, 517 hasFixedPortal: !!document.getElementById('fixed-portal'), 518 hasInitialLoader: !!document.getElementById('initial-loader'), 519 mainScriptPresent: !!document.querySelector('script[src*="main.tsx"], script[src*="assets/index"]'), 520 sessionRefreshing: (function(){ try { return sessionStorage.getItem('pblfg_refreshing'); } catch(e){ return 'na'; } })(), 521 failureCount: (function(){ try { return localStorage.getItem('pbpulse_boot_failure_count') || '0'; } catch(e){ return 'na'; } })(), 522 firstInstall: (function(){ try { return localStorage.getItem('pbpulse_first_install_completed') !== '1' ? 'yes' : 'no'; } catch(e){ return 'na'; } })(), 523 online: navigator.onLine, 524 userAgent: (navigator.userAgent || '').substring(0, 200) 525 }; 526 beacon('React never mounted within ' + WATCHDOG_MS + 'ms', snapshot); 527 528 // Keep the splash/loader clean. A visible Retry UI here is the source 529 // of the cold-start flash; actual native/web watchdogs can still 530 // reload or recover without presenting a stale snapshot to the user. 531 var recovery = document.getElementById('loader-recovery'); 532 if (recovery) recovery.style.display = 'none'; 533 }, 2500); 534 }, WATCHDOG_MS); 535 })(); 536 </script>
536 537 538 </body> 539</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.