Files
tvapp2/dist/assets/HistoryMetricsScreen-DAcDrLQC.js
2026-06-11 16:40:21 -04:00

2 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{v as ls,C as k,J as M,D as as,r,o as s,u as v,h as K,X as z,e as ns,N as l,z as g,t as c,y as U,_ as V,F as y,K as S,s as is,j as rs,i as D,q,n as f,H as i,p as ds,f as X}from"./index-CQPQcDLN.js";const us={class:"col",style:{gap:"18px"}},vs={class:"card",style:{display:"flex","align-items":"center",gap:"12px",padding:"14px"}},cs={class:"stats"},fs={class:"card stat"},hs={class:"val"},ps={class:"delta"},gs={class:"card stat"},ms={class:"val"},_s={class:"delta"},ys={class:"card stat"},bs={class:"card stat"},xs={class:"delta"},ws={style:{display:"grid","grid-template-columns":"1.5fr 1fr",gap:"14px"}},ks={class:"card"},Ms={class:"row",style:{"margin-bottom":"10px"}},zs={class:"buf-bars"},Ss=["title"],Cs={class:"card"},$s={class:"col",style:{gap:"10px"}},As={style:{flex:"1","min-width":"0"}},Is={style:{"font-size":"var(--fs-sm)","font-weight":"500","white-space":"nowrap",overflow:"hidden","text-overflow":"ellipsis"}},Bs={class:"muted",style:{"font-size":"var(--fs-xs)"}},Ns={style:{"min-width":"50px","text-align":"right"}},Vs={class:"hm-grid"},Fs={class:"card flush hm-list"},Es={class:"toolbar"},Ls={class:"tbl"},Ps=["onClick"],Rs={class:"row",style:{gap:"8px"}},Ts={style:{"min-width":"0"}},Ds={style:{"font-weight":"500","white-space":"nowrap",overflow:"hidden","text-overflow":"ellipsis","max-width":"140px"}},qs={class:"mono muted",style:{"font-size":"10px"}},Os={class:"mono",style:{"font-size":"11px"}},Gs={class:"muted",style:{"font-size":"10px","margin-top":"2px"}},Hs={class:"muted mono"},Ws={class:"mono"},js={class:"row",style:{gap:"4px"}},Qs={class:"muted mono",style:{"font-size":"10px"}},Js=["data-health"],Ks={class:"card flush hm-detail"},Us={class:"card-hd",style:{padding:"14px var(--pad-card)"}},Xs={style:{"min-width":"0",flex:"1"}},Ys={style:{"font-weight":"600","font-size":"14px"}},Zs={class:"mono muted",style:{"font-size":"11px","margin-top":"2px"}},st=["data-health"],tt={style:{padding:"16px var(--pad-card) 0",display:"grid","grid-template-columns":"repeat(3, 1fr)",gap:"10px"}},et={class:"metric",style:{background:"var(--bg-2)"}},ot={class:"val",style:{fontSize:"17px"}},lt={class:"sub"},at={class:"metric",style:{background:"var(--bg-2)"}},nt={class:"val",style:{fontSize:"17px"}},it={class:"sub"},rt={class:"metric",style:{background:"var(--bg-2)"}},dt={class:"sub"},ut={style:{padding:"16px var(--pad-card)"}},vt={class:"kv-list",style:{"grid-template-columns":"120px 1fr"}},ct={class:"v mono"},ft={class:"v"},ht={class:"v"},pt={class:"v mono"},gt={class:"v mono"},mt={class:"v"},_t={class:"v mono"},yt={key:1,style:{color:"var(--text-3)"}},bt={class:"v"},xt={style:{padding:"0 var(--pad-card) 16px"}},wt={class:"row",style:{"margin-bottom":"8px"}},kt={class:"muted mono",style:{"font-size":"11px"}},Mt={class:"buf-timeline"},zt={key:0,class:"buf-timeline-empty"},St=["title"],Ct={key:0,class:"col",style:{gap:"6px","margin-top":"12px"}},$t={class:"mono",style:{width:"50px",color:"var(--text-1)"}},At={key:0,class:"muted mono",style:{"font-size":"11px"}},It={key:1,class:"empty"},Vt=ls({__name:"HistoryMetricsScreen",setup(Bt){const O=(()=>{const o=[{ip:"82.14.221.47",region:"GB · London",client:"VLC / Linux"},{ip:"192.81.45.12",region:"DE · Frankfurt",client:"Tivimate / Android TV"},{ip:"104.18.92.5",region:"NL · Amsterdam",client:"OTT Navigator / FireTV"},{ip:"176.58.103.9",region:"GB · Manchester",client:"Kodi 21"},{ip:"78.143.211.4",region:"FR · Paris",client:"IPTV Smarters / iOS"},{ip:"10.0.4.118",region:"Local · LAN",client:"ffmpeg / probe"},{ip:"165.225.18.4",region:"US · Ashburn",client:"Plex / NVIDIA Shield"},{ip:"203.0.113.91",region:"IE · Dublin",client:"VLC / macOS"},{ip:"51.15.88.142",region:"FR · Paris",client:"Jellyfin / FireTV"}];let t=99;const e=()=>(t=t*1664525+1013904223>>>0,t/4294967296),n=[];for(let u=0;u<28;u++){const p=k[u%k.length],m=o[Math.floor(e()*o.length)],B=Math.floor(e()*60*26),P=4+Math.floor(e()*180),_=Math.floor(e()*18),R=Math.floor(e()*350),N=3+e()*6,J=_*(200+Math.floor(e()*1800)),T=Math.max(0,Math.min(100,100-_*4-(J/100|0))),os=T<55?"bad":T<80?"warn":"good";n.push({id:"s-"+u,channelId:p.id,ip:m.ip,region:m.region,client:m.client,startedAgo:B,duration:P,buffers:_,rebuffMs:J,dropped:R,avgBitrate:+N.toFixed(1),resolution:p.res,codec:"H.264",score:T,health:os,ended:e()>.25})}return n.sort((u,p)=>u.startedAgo-p.startedAgo)})();function G(o){if(o<1)return"now";if(o<60)return o+"m ago";const t=Math.floor(o/60),e=o%60;return t<24?`${t}h ${e?e+"m":""}`.trim()+" ago":Math.floor(t/24)+"d ago"}function x(o){if(o<1e3)return o+"ms";const t=o/1e3;if(t<60)return t.toFixed(1)+"s";const e=Math.floor(t/60),n=Math.round(t%60);return`${e}m ${n}s`}function C(o){if(o<60)return o+"m";const t=Math.floor(o/60),e=o%60;return`${t}h ${e?e+"m":""}`.trim()}const H=M("24h"),w=M(""),$=M("all"),F=M(O[0].id),d=f(()=>O.filter(o=>{const t=k.find(e=>e.id===o.channelId);return!(w.value&&!t.tvg_name.toLowerCase().includes(w.value.toLowerCase())&&!o.ip.includes(w.value)||$.value!=="all"&&o.health!==$.value)})),A=f(()=>d.value.reduce((o,t)=>o+t.duration,0)),W=f(()=>d.value.reduce((o,t)=>o+t.buffers,0)),j=f(()=>d.value.reduce((o,t)=>o+t.rebuffMs,0)),E=f(()=>A.value?j.value/1e3/(A.value*60)*100:0),Y=f(()=>new Set(d.value.map(o=>o.ip)).size),Z=f(()=>new Set(d.value.map(o=>o.channelId)).size),Q=f(()=>d.value.length?Math.round(d.value.reduce((o,t)=>o+t.score,0)/d.value.length):0),I=f(()=>{const o=Array(24).fill(0);return d.value.forEach(t=>{const e=Math.min(23,Math.floor(t.startedAgo/60));o[23-e]+=t.buffers}),o}),ss=f(()=>{const o={};return d.value.forEach(t=>{const e=t.channelId;o[e]||(o[e]={ch:k.find(n=>n.id===e),sessions:0,buffers:0,scores:[]}),o[e].sessions++,o[e].buffers+=t.buffers,o[e].scores.push(t.score)}),Object.values(o).map(t=>({...t,avgScore:Math.round(t.scores.reduce((e,n)=>e+n,0)/t.scores.length)})).sort((t,e)=>t.avgScore-e.avgScore).slice(0,5)}),a=f(()=>d.value.find(o=>o.id===F.value)||d.value[0]);function h(o){return k.find(t=>t.id===o.channelId)}const L=M(!1);as(()=>requestAnimationFrame(()=>L.value=!0));function ts(o,t){const e=Math.max(1,...I.value),n=o/e,u=n*100,p=(.88-n*.33).toFixed(3),m=(.1+n*.07).toFixed(3),B=`oklch(${p} ${m} 220)`,P=1500,_=520,R=(P-_)/Math.max(1,I.value.length-1),N=t*R;return{height:L.value?u+"%":"0%",background:B,boxShadow:o>0&&L.value?`0 0 8px ${B}`:"none",transition:`height ${_}ms cubic-bezier(.2,.8,.2,1) ${N}ms, box-shadow 240ms ease ${N+_-100}ms`}}const b=f(()=>{if(!a.value)return[];let o=a.value.id.charCodeAt(2)+9;const t=()=>(o=o*1664525+1013904223>>>0,o/4294967296),e=[];for(let n=0;n<a.value.buffers;n++){const u=Math.floor(t()*a.value.duration),p=200+Math.floor(t()*1600),m=["upstream stall","client buffer underrun","bitrate dip","network jitter"][Math.floor(t()*4)];e.push({at:u,dur:p,cause:m})}return e.sort((n,u)=>n.at-u.at)});function es(o){return o==="good"?"var(--good)":o==="warn"?"var(--warn)":o==="bad"?"var(--bad)":"var(--text-0)"}return(o,t)=>(i(),r("div",us,[s("div",vs,[v(X,{name:"file",size:18}),t[4]||(t[4]=s("div",null,[s("div",{style:{"font-weight":"600","font-size":"15px"}},"Streaming history & metrics"),s("div",{class:"muted",style:{"font-size":"var(--fs-xs)","margin-top":"2px"}}," Past viewer sessions across all channels — identify channels with frequent rebuffering or playback issues. ")],-1)),t[5]||(t[5]=s("span",{class:"spacer"},null,-1)),v(K,{value:H.value,onChange:t[0]||(t[0]=e=>H.value=e),options:[{value:"1h",label:"1h"},{value:"24h",label:"24h"},{value:"7d",label:"7d"},{value:"30d",label:"30d"}]},null,8,["value"]),v(ns,{variant:"ghost",icon:"upload"},{default:z(()=>[...t[3]||(t[3]=[c("Export",-1)])]),_:1})]),s("div",cs,[s("div",fs,[t[6]||(t[6]=s("div",{class:"lbl"},"Sessions",-1)),s("div",hs,l(d.value.length),1),s("div",ps,l(Z.value)+" channels · "+l(Y.value)+" unique IPs",1)]),s("div",gs,[t[7]||(t[7]=s("div",{class:"lbl"},"Watch time",-1)),s("div",ms,l(C(A.value)),1),s("div",_s,"avg "+l(d.value.length?Math.round(A.value/d.value.length):0)+"m / session",1)]),s("div",ys,[t[9]||(t[9]=s("div",{class:"lbl"},"Rebuffer ratio",-1)),s("div",{class:"val",style:g(E.value>1.5?{color:"var(--warn)"}:void 0)},[c(l(E.value.toFixed(2)),1),t[8]||(t[8]=s("span",{style:{"font-size":"14px",color:"var(--text-2)","font-weight":"500"}},"%",-1))],4),s("div",{class:U(["delta",{bad:E.value>1.5}])},l(W.value)+" buffer events · "+l(x(j.value))+" total ",3)]),s("div",bs,[t[11]||(t[11]=s("div",{class:"lbl"},"QoE score",-1)),s("div",{class:"val",style:g({color:Q.value<70?"var(--warn)":"var(--good)"})},[c(l(Q.value),1),t[10]||(t[10]=s("span",{style:{"font-size":"14px",color:"var(--text-2)","font-weight":"500"}}," / 100",-1))],4),s("div",xs,l(d.value.filter(e=>e.health==="bad").length)+" problem sessions",1)])]),s("div",ws,[s("div",ks,[s("div",Ms,[t[12]||(t[12]=s("div",{style:{"font-weight":"600","font-size":"14px"}},"Buffer events · last 24h",-1)),t[13]||(t[13]=s("span",{class:"spacer"},null,-1)),v(V,{tone:"warn"},{default:z(()=>[c(l(W.value)+" total",1)]),_:1}),v(V,null,{default:z(()=>[c(l(Math.max(...I.value))+" peak / hour",1)]),_:1})]),s("div",null,[s("div",zs,[(i(!0),r(y,null,S(I.value,(e,n)=>(i(),r("div",{key:n,class:"buf-bar-wrap",title:`${23-n}h ago: ${e} buffer events`},[s("div",{class:"buf-bar",style:g(ts(e,n))},null,4)],8,Ss))),128))]),t[14]||(t[14]=is('<div class="row" style="justify-content:space-between;margin-top:6px;font-size:10px;color:var(--text-3);"><span class="mono">24h</span><span class="mono">18h</span><span class="mono">12h</span><span class="mono">6h</span><span class="mono">now</span></div>',1))])]),s("div",Cs,[t[15]||(t[15]=s("div",{class:"row",style:{"margin-bottom":"10px"}},[s("div",{style:{"font-weight":"600","font-size":"14px"}},"Problem channels"),s("span",{class:"spacer"}),s("span",{class:"muted",style:{"font-size":"var(--fs-xs)"}},"by QoE score")],-1)),s("div",$s,[(i(!0),r(y,null,S(ss.value,e=>(i(),r("div",{key:e.ch.id,class:"row",style:{gap:"10px"}},[v(D,{ch:e.ch},null,8,["ch"]),s("div",As,[s("div",Is,l(e.ch.tvg_name),1),s("div",Bs,l(e.sessions)+" sessions · "+l(e.buffers)+" buffers",1)]),s("div",Ns,[s("span",{class:"mono",style:g({fontWeight:600,fontSize:"14px",color:e.avgScore<60?"var(--bad)":e.avgScore<80?"var(--warn)":"var(--good)"})},l(e.avgScore),5)])]))),128))])])]),s("div",Vs,[s("div",Fs,[s("div",Es,[v(rs,{value:w.value,onChange:t[1]||(t[1]=e=>w.value=e),placeholder:"Channel or IP",width:200},null,8,["value"]),t[16]||(t[16]=s("span",{class:"spacer"},null,-1)),v(K,{value:$.value,onChange:t[2]||(t[2]=e=>$.value=e),options:[{value:"all",label:"All"},{value:"good",label:"Good"},{value:"warn",label:"Warn"},{value:"bad",label:"Bad"}]},null,8,["value"])]),s("table",Ls,[t[19]||(t[19]=s("thead",null,[s("tr",null,[s("th",null,"Channel"),s("th",null,"IP / Region"),s("th",null,"Started"),s("th",null,"Duration"),s("th",null,"Buffers"),s("th",null,"QoE")])],-1)),s("tbody",null,[(i(!0),r(y,null,S(d.value,e=>(i(),r("tr",{key:e.id,class:U({selected:F.value===e.id}),onClick:n=>F.value=e.id},[s("td",null,[s("div",Rs,[v(D,{ch:h(e)},null,8,["ch"]),s("div",Ts,[s("div",Ds,l(h(e).tvg_name),1),s("div",qs,"#"+l(h(e).channel),1)])])]),s("td",null,[s("div",Os,l(e.ip),1),s("div",Gs,l(e.region),1)]),s("td",Hs,l(G(e.startedAgo)),1),s("td",Ws,[c(l(C(e.duration))+" ",1),e.ended?q("",!0):(i(),ds(V,{key:0,tone:"cyan",style:{"margin-left":"6px"}},{default:z(()=>[...t[17]||(t[17]=[c("live",-1)])]),_:1}))]),s("td",null,[s("div",js,[s("span",{class:"mono",style:g({fontWeight:600,color:e.buffers>6?"var(--warn)":"var(--text-1)"})},l(e.buffers),5),s("span",Qs,"· "+l(x(e.rebuffMs)),1)])]),s("td",null,[s("div",{class:"qoe-pill","data-health":e.health},[t[18]||(t[18]=s("span",{class:"dot"},null,-1)),c(l(e.score),1)],8,Js)])],10,Ps))),128))])])]),s("div",Ks,[a.value?(i(),r(y,{key:0},[s("div",Us,[v(D,{ch:h(a.value)},null,8,["ch"]),s("div",Xs,[s("div",Ys,l(h(a.value).tvg_name),1),s("div",Zs,"#"+l(h(a.value).channel)+" · session "+l(a.value.id),1)]),s("div",{class:"qoe-pill","data-health":a.value.health,style:{"font-size":"13px",padding:"4px 12px"}},[t[20]||(t[20]=s("span",{class:"dot"},null,-1)),c("QoE "+l(a.value.score),1)],8,st)]),s("div",tt,[s("div",et,[t[21]||(t[21]=s("div",{class:"lbl"},"Duration",-1)),s("div",ot,l(C(a.value.duration)),1),s("div",lt,"started "+l(G(a.value.startedAgo)),1)]),s("div",at,[t[22]||(t[22]=s("div",{class:"lbl"},"Avg bitrate",-1)),s("div",nt,l(a.value.avgBitrate)+" Mbps",1),s("div",it,l(a.value.resolution)+" · "+l(a.value.codec),1)]),s("div",rt,[t[23]||(t[23]=s("div",{class:"lbl"},"Rebuffer",-1)),s("div",{class:"val",style:g({color:es(a.value.buffers>6?"warn":"good"),fontSize:"17px"})},l(x(a.value.rebuffMs)),5),s("div",dt,l(a.value.buffers)+" events · "+l(a.value.dropped)+" drops",1)])]),s("div",ut,[s("div",vt,[t[24]||(t[24]=s("div",{class:"k"},"Client IP",-1)),s("div",ct,l(a.value.ip),1),t[25]||(t[25]=s("div",{class:"k"},"Region",-1)),s("div",ft,l(a.value.region),1),t[26]||(t[26]=s("div",{class:"k"},"Player",-1)),s("div",ht,l(a.value.client),1),t[27]||(t[27]=s("div",{class:"k"},"Resolution",-1)),s("div",pt,l(a.value.resolution)+" · "+l(a.value.codec),1),t[28]||(t[28]=s("div",{class:"k"},"Channel #",-1)),s("div",gt,"#"+l(h(a.value).channel),1),t[29]||(t[29]=s("div",{class:"k"},"Group",-1)),s("div",mt,l(h(a.value).group),1),t[30]||(t[30]=s("div",{class:"k"},"TVG-ID",-1)),s("div",_t,[h(a.value).tvg_id?(i(),r(y,{key:0},[c(l(h(a.value).tvg_id),1)],64)):(i(),r("span",yt,"—"))]),t[31]||(t[31]=s("div",{class:"k"},"Source",-1)),s("div",bt,[v(V,{tone:"cyan"},{default:z(()=>[c(l(h(a.value).source),1)]),_:1})])])]),s("div",xt,[s("div",wt,[t[32]||(t[32]=s("div",{style:{"font-size":"var(--fs-sm)","font-weight":"600"}},"Buffering timeline",-1)),t[33]||(t[33]=s("span",{class:"spacer"},null,-1)),s("span",kt,"0 → "+l(C(a.value.duration)),1)]),s("div",Mt,[b.value.length===0?(i(),r("div",zt,[v(X,{name:"check",size:12}),t[34]||(t[34]=c(" No buffer events ",-1))])):(i(!0),r(y,{key:1},S(b.value,(e,n)=>(i(),r("div",{key:n,class:"buf-event",style:g({left:e.at/a.value.duration*100+"%",width:Math.max(2,e.dur/6e4/a.value.duration*100)+"%"}),title:`${x(e.dur)} stall at ${e.at}m — ${e.cause}`},null,12,St))),128))]),b.value.length>0?(i(),r("div",Ct,[(i(!0),r(y,null,S(b.value.slice(0,6),(e,n)=>(i(),r("div",{key:n,class:"row",style:{"font-size":"var(--fs-xs)",color:"var(--text-2)"}},[s("span",$t,"+"+l(e.at)+"m",1),s("span",{class:"mono",style:g({width:"70px",color:e.dur>1e3?"var(--warn)":"var(--text-1)"})},l(x(e.dur)),5),s("span",null,l(e.cause),1)]))),128)),b.value.length>6?(i(),r("span",At,"+ "+l(b.value.length-6)+" more",1)):q("",!0)])):q("",!0)])],64)):(i(),r("div",It,[...t[35]||(t[35]=[s("h3",null,"No session",-1)])]))])])]))}});export{Vt as default};