1(()=>{if(window.channel155Diagnostics)return;const VERSION="20261003-web-diagnostics-v3-surface",KEY="channel155_diagnostic_queue_v1";const uuid=()=>crypto.randomUUID();const pageId=uuid(),started=performance.now(),nativeFetch=window.fetch.bind(window);let queue=[],inflight=0,flushing=false,nextFlush=0,dropped=0;const history=[],routes=new Set(["bootstrap-v3","show-snapshot-v3","chat-feed-v2","chat-message-v2","leaderboard","leaderboard-sync","public-answer-v2","answers-v2","public-vote-v2","votes-v2","demo-package","profile","presence-token","music-show-v2","ghosts-show","songs-show","marketplace-show","news-show","admin/control-state"]);const endpoint=value=>{try{const u=new URL(value,location.href);if(![location.origin,"https://15half.com","https://channel15.base44.app","https://snapshots.15half.com"].includes(u.origin))return null;const p=u.pathname.replace(/^\/(?:functions\/)?v1\//,"");if(routes.has(p))return p;if(/^\/(write|quiz-durable|presence|chat)(\/|$)/.test(u.pathname))return u.pathname.split("/").slice(1,3).join("/")}catch{}return null};function save(){try{sessionStorage.setItem(KEY,JSON.stringify(queue))}catch{}}const fields=new Set("requestId originRequestId interactionId endpoint method ms status attempt delayMs answerSaved accepted recoverOnly sdkCalls sdkWrites sdkFailures inflight readyState networkState videoWidth videoHeight ttfb domMs loadMs fcpMs width height resourceMs dropped count online hidden loader content live shell paused muted stage code kind cache browser platform surface".split(" "));function clean(data){const out={};if(typeof data?.assetHash==="string"&&/^[a-f0-9]{64}$/.test(data.assetHash))out.assetHash=data.assetHash;if(["news-voice-primary","news-voice-standby","news-presenter-video","news-intro-video","audio","video"].includes(data?.mediaRole))out.mediaRole=data.mediaRole;if(Number.isInteger(data?.mediaError)&&data.mediaError>=1&&data.mediaError<=4)out.mediaError=data.mediaError;for(const[k,v]of Object.entries(data||{}))if(fields.has(k)&&(typeof v==="boolean"||typeof v==="number"&&Number.isFinite(v)&&v>=0||typeof v==="string"&&/^[a-zA-Z0-9_./-]{1,100}$/.test(v)))out[k]=v;return out}try{const old=JSON.parse(sessionStorage.getItem(KEY)||"[]");const validId=x=>typeof x==="string"&&/^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(x);if(Array.isArray(old))queue=old.slice(-120).filter(e=>/^[a-z_]{1,30}$/.test(e.event||"")&&validId(e.id)&&validId(e.pageId)).map(e=>({...clean(e),event:e.event,id:e.id,pageId:e.pageId,version:VERSION,at:Number.isFinite(e.at)?e.at:Date.now()}))}catch{}function record(event,data={},send=true){const row={...clean(data),event,id:uuid(),pageId,version:VERSION,at:Date.now()};history.push(row);if(history.length>200)history.shift();if(!send)return;if(queue.length>=120){dropped++;return}queue.push(row);save()}async function flush(){if(flushing||!queue.length||!navigator.onLine||Date.now()<nextFlush)return;flushing=true;const batch=queue.slice(0,25);try{const response=await nativeFetch("https://15half.com/api/diagnostics",{method:"POST",credentials:"omit",headers:{"Content-Type":"text/plain"},body:JSON.stringify({records:batch}),keepalive:true,signal:AbortSignal.timeout(5e3)});if(response.ok&&(await response.json()).accepted===true){queue=queue.filter(e=>!batch.some(b=>b.id===e.id));save();if(dropped){const count=dropped;dropped=0;record("connection",{stage:"diagnostic_queue_overflow",dropped:count})}nextFlush=Date.now()+5e3}else nextFlush=Date.now()+6e4}catch{nextFlush=Date.now()+6e4}finally{flushing=false}}window.channel155Diagnostics=Object.freeze({version:VERSION,pageId,record,flush,snapshot:()=>({version:VERSION,pageId,queued:queue.length,dropped,events:history.slice()})});window.fetch=async(input,init)=>{const url=input instanceof Request?input.url:String(input),route=endpoint(url);if(!route)return nativeFetch(input,init);const method=String(init?.method||(input instanceof Request?input.method:"GET")).toUpperCase();const begin=performance.now(),requestId=uuid();inflight++;let options=init;if(method==="POST"&&new URL(url,location.href).origin===location.origin){const headers=new Headers(init?.headers||(input instanceof Request?input.headers:{}));headers.set("X-Channel-Request-Id",requestId);options={...init,headers}}try{const response=await nativeFetch(input,options),ms=Math.round(performance.now()-begin);record("network",{endpoint:route,method,requestId,originRequestId:response.headers.get("X-Channel-Request-Id"),status:response.status,ms,inflight,cache:response.headers.get("CF-Cache-Status")||"unknown"},!response.ok&&response.status!==304||ms>1500||method!=="GET"||Math.random()<.01);return response}catch(error){record("network",{endpoint:route,method,requestId,status:0,ms:Math.round(performance.now()-begin),inflight,code:error?.name==="TimeoutError"?"timeout":error?.name==="AbortError"?"aborted":"transport",online:navigator.onLine});throw error}finally{inflight--}};function visible(el){if(!el||el.hidden)return false;const r=el.getBoundingClientRect(),style=getComputedStyle(el);return r.width>20&&r.height>20&&style.visibility!=="hidden"&&style.display!=="none"&&Number(style.opacity)!==0}function surface(){const root=document.querySelector(".broadcast"),q=selector=>[...document.querySelectorAll(selector)].some(visible);return{shell:q("header,.channel-header,.broadcast-header"),loader:q("#channel-startup-loader"),live:document.documentElement.classList.contains("is-program-live"),content:q(".web-rerun-home,.web-replay-shell,.broadcast .question-stage.is-active,.broadcast .host-stage.is-active,.broadcast .post-show-stage,.ghosts-game,.ghosts-host-video,.songs-game,.songs-host-video,.music-show,.marketplace-main,.news-main,.standup-s
1how")||Boolean(root?.classList.contains("is-off-air-screen")),hidden:document.hidden,online:navigator.onLine,width:innerWidth,height:innerHeight,ms:Math.round(performance.now()-started)}}const ua=navigator.userAgent;record("startup",{stage:"early_script",browser:/Edg/.test(ua)?"edge":/Chrome/.test(ua)?"chromium":/Safari/.test(ua)?"safari":"other",platform:/Android/.test(ua)?"android":/iPhone|iPad/.test(ua)?"ios":"desktop",...surface()});addEventListener("DOMContentLoaded",()=>{record("startup",{stage:"dom_ready",...surface()});void flush()});addEventListener("load",()=>{const n=performance.getEntriesByType("navigation")[0];record("startup",{stage:"window_load",ttfb:n?.responseStart,domMs:n?.domContentLoadedEventEnd,loadMs:n?.loadEventEnd,...surface()});void flush()});addEventListener("error",e=>{const target=e.target;record(target!==window?"resource_error":"js_error",{kind:target?.tagName?.toLowerCase()||"script",stage:"runtime"});void flush()},true);addEventListener("unhandledrejection",()=>{record("unhandled_rejection",{stage:"runtime"});void flush()});for(const type of["online","offline","pageshow","pagehide"])addEventListener(type,()=>{record("connection",{stage:type,online:navigator.onLine,hidden:document.hidden});void flush()});document.addEventListener("visibilitychange",()=>{record("connection",{stage:"visibility",hidden:document.hidden});void flush()});for(const seconds of[5,15,30,60])setTimeout(()=>{const s=surface();record(!s.content&&!s.hidden?"blank_surface":"surface",{stage:`startup_${seconds}s`,...s});void flush()},seconds*1e3);let mediaWindow=0,mediaCount=0,mediaErrors=0;async function mediaFingerprint(source){try{if(!source||source.length>4096)return;const u=new URL(source,location.href);if(!["https:","http:"].includes(u.protocol)||u.username||u.password)return;const bytes=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(u.origin+u.pathname));return Array.from(new Uint8Array(bytes),b=>b.toString(16).padStart(2,"0")).join("")}catch{}}for(const[type,event]of[["waiting","media_wait"],["stalled","media_wait"],["error","media_error"],["playing","media_ready"]])document.addEventListener(type,e=>{const m=e.target;if(!(m instanceof HTMLMediaElement))return;if(Date.now()-mediaWindow>6e4){mediaWindow=Date.now();mediaCount=0;mediaErrors=0}if(type==="error"?++mediaErrors>6:++mediaCount>12)return;const data={stage:type,kind:m.tagName.toLowerCase(),readyState:m.readyState,networkState:m.networkState,paused:m.paused,muted:m.muted,videoWidth:m.videoWidth||0,videoHeight:m.videoHeight||0,ms:Math.round(performance.now()-started),mediaError:m.error?.code,mediaRole:["news-voice-primary","news-voice-standby","news-presenter-video","news-intro-video"].find(r=>m.classList.contains(r))||m.tagName.toLowerCase()};void mediaFingerprint(m.currentSrc||m.getAttribute("src")).then(assetHash=>record(event,{...data,assetHash}))},true);try{new PerformanceObserver(list=>{for(const e of list.getEntries())record("startup",{stage:"first_paint",fcpMs:e.startTime})}).observe({type:"paint",buffered:true})}catch{}let slowResources=0,longTasks=0;try{new PerformanceObserver(list=>{for(const e of list.getEntries())if(e.duration>2e3&&slowResources++<20)record("startup",{stage:"slow_resource",kind:e.initiatorType||"other",resourceMs:e.duration})}).observe({type:"resource",buffered:true})}catch{}try{new PerformanceObserver(list=>{for(const e of list.getEntries())if(e.duration>250&&longTasks++<10)record("long_task",{ms:e.duration})}).observe({type:"longtask",buffered:true})}catch{}if(window.WebSocket)window.WebSocket=new Proxy(window.WebSocket,{construct(Target,args){const socket=Reflect.construct(Target,args);const begin=performance.now();for(const type of["open","close","error"])socket.addEventListener(type,e=>record("connection",{stage:`socket_${type}`,ms:performance.now()-begin,status:type==="close"?e.code:0}));return socket}});setInterval(()=>{void flush()},15e3)})();
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.