import{e as Ae,r as p,gE as _e,gF as Ie,ah as Be,ai as Ve,j as e,f as U,$ as ye,dA as He,d7 as qe,c as le,aB as We,W as Ye,aa as Oe,gG as Xe,V as $,cq as z,x as ze,c8 as Ge,bY as Je,N as me,Z,gH as Qe,Q as xe}from"./index-C4inJ1rU.js";import{C as Q,P as Ke,a as Ue,B as De}from"./PageLayout-CdGXajgM.js";import{useResolveSource as Ze}from"./usePipelineStore-BdsvnjJV.js";import{C as et}from"./chevron-right-CU8UihKL.js";import{R as se,C as ae}from"./Grid-rJkrpDAP.js";import"./node-types-chTBCezS.js";/**
 * @license lucide-react v0.559.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const tt=[["circle",{cx:"9",cy:"12",r:"3",key:"u3jwor"}],["rect",{width:"20",height:"14",x:"2",y:"5",rx:"7",key:"g7kal2"}]],st=Ae("toggle-left",tt);/**
 * @license lucide-react v0.559.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const at=[["circle",{cx:"15",cy:"12",r:"3",key:"1afu0r"}],["rect",{width:"20",height:"14",x:"2",y:"5",rx:"7",key:"g7kal2"}]],nt=Ae("toggle-right",at),ot=/\[RX\] CRC error #(\d+)\s*-\s*RSSI=(-?\d+)dBm,\s*SNR=(-?[\d.]+)dB,\s*SignalRSSI=(-?\d+)dBm,\s*Length=(\d+),\s*NoiseFloor=(-?[\d.]+)dBm,\s*DeviceErrors=(0x[0-9A-Fa-f]+),\s*IRQ=(0x[0-9A-Fa-f]+),\s*RawData=(.+)/;function lt(r,a){const v=ot.exec(r);return v?{timestamp:a,errorNumber:parseInt(v[1],10),rssiDbm:parseInt(v[2],10),snrDb:parseFloat(v[3]),signalRssiDbm:parseInt(v[4],10),payloadLength:parseInt(v[5],10),noiseFloorDbm:parseFloat(v[6]),deviceErrors:v[7],irq:v[8],rawData:v[9].trim()}:null}const rt=1e4;function it(r){if(typeof r=="number")return r>1e12?Math.floor(r/1e3):r;const a=new Date(r).getTime();return isNaN(a)?Math.floor(Date.now()/1e3):Math.floor(a/1e3)}function ve(r){return r.deviceErrors!=="—"&&(r.rssiDbm!==0||r.snrDb!==0)}function ue(r){return r>=-80?"text-sys-green":r>=-100?"text-sys-amber":"text-sys-red"}function fe(r){return r>=5?"text-sys-green":r>=0?"text-sys-amber":"text-sys-red"}function Re(r){return new Date(r*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}function ke(r){return new Date(r*1e3).toLocaleDateString([],{month:"short",day:"numeric"})}function ct(r){if(r.length===0)return{total:0,hasRf:!1,avgRssi:0,avgSnr:0,worstSnr:0,avgNoiseFloor:0,errorsPerHour:0,uniqueDeviceErrors:new Set};const a=r.filter(ve);let v=0,g=0,c=0,R=1/0;const D=new Set;for(const i of a)v+=i.rssiDbm,g+=i.snrDb,c+=i.noiseFloorDbm,i.snrDb<R&&(R=i.snrDb),i.deviceErrors!=="0x0000"&&i.deviceErrors!=="—"&&D.add(i.deviceErrors);const y=r.length,f=a.length,u=[...r].sort((i,m)=>i.timestamp-m.timestamp),o=u.length>=2?(u[u.length-1].timestamp-u[0].timestamp)/3600:0;return{total:y,hasRf:f>0,avgRssi:f>0?v/f:0,avgSnr:f>0?g/f:0,worstSnr:R===1/0?0:R,avgNoiseFloor:f>0?c/f:0,errorsPerHour:o>0?y/o:0,uniqueDeviceErrors:D}}const dt=p.memo(function({entry:a,isFirst:v}){const[g,c]=p.useState(!1);return e.jsxs("div",{className:le("group transition-base",!v&&"border-t border-edge-subtle/40"),children:[e.jsxs("button",{type:"button",onClick:()=>c(R=>!R),className:"w-full text-left py-2 px-3 hover:bg-subtle-fill/50 transition-base flex items-center gap-2 min-w-0",children:[g?e.jsx(We,{className:"w-3 h-3 text-fg-muted shrink-0"}):e.jsx(et,{className:"w-3 h-3 text-fg-muted shrink-0"}),e.jsx("span",{className:"type-data-xs text-fg-muted w-14 shrink-0 tabular-nums",children:Re(a.timestamp)}),e.jsxs("span",{className:"type-data-xs text-sys-red w-10 shrink-0 tabular-nums",children:["#",a.errorNumber]}),ve(a)?e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:le("type-data-xs w-16 shrink-0 tabular-nums",ue(a.rssiDbm)),children:[a.rssiDbm," dBm"]}),e.jsxs("span",{className:le("type-data-xs w-14 shrink-0 tabular-nums",fe(a.snrDb)),children:[a.snrDb.toFixed(1)," dB"]}),e.jsxs("span",{className:"type-data-xs text-fg-secondary w-10 shrink-0 tabular-nums",children:[a.payloadLength,"B"]}),e.jsxs("span",{className:"type-data-xs text-fg-muted w-20 shrink-0 tabular-nums hidden sm:inline",children:["NF ",a.noiseFloorDbm.toFixed(1)]}),a.deviceErrors!=="0x0000"&&a.deviceErrors!=="—"&&e.jsxs(ye,{color:"red",className:"hidden md:inline-flex",children:["ERR ",a.deviceErrors]})]}):e.jsx("span",{className:"type-data-xs text-fg-muted italic",children:"timestamp only — no RF diagnostics"})]}),g&&e.jsx("div",{className:"px-3 pb-2.5 pt-0.5 ml-5 space-y-1.5",children:ve(a)?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-x-4 gap-y-1",children:[e.jsx(K,{label:"RSSI",value:`${a.rssiDbm} dBm`,color:ue(a.rssiDbm)}),e.jsx(K,{label:"SNR",value:`${a.snrDb.toFixed(1)} dB`,color:fe(a.snrDb)}),e.jsx(K,{label:"Signal RSSI",value:`${a.signalRssiDbm} dBm`,color:ue(a.signalRssiDbm)}),e.jsx(K,{label:"Noise Floor",value:`${a.noiseFloorDbm.toFixed(1)} dBm`}),e.jsx(K,{label:"Payload Length",value:`${a.payloadLength} bytes`}),e.jsx(K,{label:"Device Errors",value:a.deviceErrors,color:a.deviceErrors!=="0x0000"?"text-sys-red":void 0}),e.jsx(K,{label:"IRQ Flags",value:a.irq}),e.jsx(K,{label:"Date",value:ke(a.timestamp)})]}),a.rawData&&a.rawData!=="(read failed)"&&e.jsxs("div",{className:"mt-1.5",children:[e.jsx("p",{className:"type-micro text-fg-muted mb-0.5",children:"RAW DATA"}),e.jsx("pre",{className:"type-data-xs text-fg-secondary bg-subtle-fill/50 radius-badge p-2 overflow-x-auto whitespace-pre-wrap break-all max-h-20",children:a.rawData})]}),a.rawData==="(read failed)"&&e.jsx("p",{className:"type-data-xs text-sys-amber italic",children:"Buffer read failed"})]}):e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1",children:[e.jsx(K,{label:"Date",value:ke(a.timestamp)}),e.jsx(K,{label:"Time",value:Re(a.timestamp)})]})})]})});function K({label:r,value:a,color:v}){return e.jsxs("div",{children:[e.jsx("p",{className:"type-micro text-fg-muted",children:r}),e.jsx("p",{className:le("type-data-xs",v??"text-fg-secondary"),children:a})]})}function ht(){const[r,a]=p.useState([]),[v,g]=p.useState(!0),[c,R]=p.useState("none"),[D,y]=p.useState(0),f=p.useRef(null),u=p.useCallback(async()=>{var m,b,S;try{const j=await _e(24);if(j.success&&((m=j.data)!=null&&m.entries)&&j.data.entries.length>0){a(j.data.entries),R("journalctl"),g(!1),y(Date.now());return}}catch{}try{const j=await Ie();if(j!=null&&j.logs){const s=[];for(const x of j.logs){if(!((b=x.message)!=null&&b.includes("CRC error")))continue;const n=it(x.timestamp),t=lt(x.message,n);t&&s.push(t)}if(s.length>0){s.sort((x,n)=>n.timestamp-x.timestamp),a(s),R("logs"),g(!1),y(Date.now());return}}}catch{}try{const[j,s]=await Promise.all([Be(24),Ve(24)]);if(j.success&&((S=j.data)!=null&&S.history)&&j.data.history.length>0){const x=j.data.history.map((n,t)=>({timestamp:n.timestamp,errorNumber:t+1,rssiDbm:0,snrDb:0,signalRssiDbm:0,payloadLength:0,noiseFloorDbm:0,deviceErrors:"—",irq:"—",rawData:""}));x.sort((n,t)=>t.timestamp-n.timestamp),a(x),R("history"),g(!1),y(Date.now());return}if(s.success&&s.data&&s.data.count>0){const x=s.data.newest_timestamp??Math.floor(Date.now()/1e3);a([{timestamp:x,errorNumber:s.data.count,rssiDbm:0,snrDb:0,signalRssiDbm:0,payloadLength:0,noiseFloorDbm:0,deviceErrors:"—",irq:"—",rawData:""}]),R("history"),g(!1),y(Date.now());return}}catch{}a([]),R("none"),g(!1),y(Date.now())},[]);p.useEffect(()=>(u(),f.current=setInterval(u,rt),()=>{f.current&&clearInterval(f.current)}),[u]);const o=p.useMemo(()=>ct(r),[r]),i=p.useMemo(()=>[...r].sort((m,b)=>b.timestamp-m.timestamp),[r]);return e.jsxs(Q,{children:[e.jsx(U,{title:"CRC Error Log",icon:e.jsx(qe,{className:"icon-sm"}),actions:e.jsxs("div",{className:"flex items-center gap-2",children:[c!=="none"&&e.jsx(ye,{color:"zinc",className:"hidden sm:inline-flex",children:c==="journalctl"?"journalctl":c==="logs"?"memory":"history"}),e.jsxs(ye,{color:o.total>0?"red":"green",children:[o.total," error",o.total!==1?"s":""]}),e.jsx("button",{type:"button",onClick:u,className:"p-1 radius-inner hover:bg-subtle-fill transition-base text-fg-muted hover:text-fg-primary",title:"Refresh CRC logs",children:e.jsx(He,{className:"w-3.5 h-3.5"})})]})}),o.total>0&&e.jsxs("div",{className:le("grid gap-2 mb-3",o.hasRf?"grid-cols-2 sm:grid-cols-3 lg:grid-cols-6":"grid-cols-2 sm:grid-cols-3"),children:[e.jsx(oe,{label:"Total",value:o.total.toString()}),e.jsx(oe,{label:"Rate",value:o.errorsPerHour>0?`${o.errorsPerHour.toFixed(1)}/hr`:"—"}),o.hasRf&&e.jsxs(e.Fragment,{children:[e.jsx(oe,{label:"Avg RSSI",value:`${o.avgRssi.toFixed(0)} dBm`,color:ue(o.avgRssi)}),e.jsx(oe,{label:"Avg SNR",value:`${o.avgSnr.toFixed(1)} dB`,color:fe(o.avgSnr)}),e.jsx(oe,{label:"Worst SNR",value:`${o.worstSnr.toFixed(1)} dB`,color:fe(o.worstSnr)}),e.jsx(oe,{label:"Avg NF",value:`${o.avgNoiseFloor.toFixed(1)} dBm`})]})]}),v?e.jsx("div",{className:"flex items-center justify-center py-8 text-fg-muted type-data-xs",children:"Loading CRC logs…"}):r.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-8 gap-1.5",children:[e.jsx("p",{className:"text-fg-muted type-data-sm",children:"No CRC errors detected"}),e.jsx("p",{className:"text-fg-muted/60 type-data-xs",children:"CRC errors appear when corrupted packets are received by the SX1262"})]}):e.jsx("div",{className:"surface-inner radius-inner overflow-hidden max-h-80 overflow-y-auto",children:i.map((m,b)=>e.jsx(dt,{entry:m,isFirst:b===0},`${m.timestamp}-${m.errorNumber}`))}),D>0&&e.jsxs("p",{className:"type-data-xs text-fg-muted/50 mt-2 text-right",children:["Last updated ",new Date(D).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})]})]})}function oe({label:r,value:a,color:v}){return e.jsxs("div",{className:"surface-inner radius-inner p-2",children:[e.jsx("p",{className:"type-micro text-fg-muted",children:r}),e.jsx("p",{className:le("type-data-sm tabular-nums",v??"text-fg-primary"),children:a})]})}const ne=300,Le=288,Se=.2,W=32,O=20,be=30;function Pe(r){return new Date(r*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})}function we(r){if(r.length===0)return[];const a=r.length,v=Math.max(1,Math.floor(a/6)),g=[];for(let c=0;c<a;c+=v)g.push({label:Pe(r[c].ts),pos:(c+.5)/a*100});return g}let he=null,Ce=0;function pe(){const r=performance.now();return he&&r-Ce<1e3||(he=getComputedStyle(document.documentElement).getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',Ce=r),he}function re(){return document.documentElement.dataset.mode!=="light"}function ee(){return re()?Z[50]:Z[950]}function ut(r){const a=r/1e3;return parseFloat(a.toFixed(3)).toString()}function je(r){const a=r.type??r.payload_type??-1;return a===z.ACK||a===z.RESPONSE||a===z.TXT_MSG||a===z.GRP_TXT||a===z.GRP_DATA||a===z.RAW_CUSTOM}function ft(r){const a=r.type??r.payload_type??-1;return a===z.ADVERT||a===z.REQ||a===z.TRACE||a===z.PATH||a===z.ANON_REQ||a===z.CONTROL||a===z.MULTIPART}function mt(r){return r.is_duplicate||r.drop_reason!==null}const Me="Messages, replies, and data your mesh is actually delivering — the traffic users care about",Ne="Routing and discovery overhead the mesh needs to function — high ratios mean the network spends more effort maintaining itself than delivering messages";function xt(r){var s,x;if(r.length===0)return{efficiency:[],jitter:[],reliability:[]};const a=Math.floor(Date.now()/1e3),v=a-Le*ne,g=new Map,c=new Map,R=new Map,D=new Map,y=new Map,f=new Map;for(let n=v;n<a;n+=ne)g.set(n,{v:0,o:0,e:0}),c.set(n,[]),R.set(n,0),D.set(n,0),y.set(n,0),f.set(n,0);for(const n of r){if(n.timestamp<v)continue;const t=v+Math.floor((n.timestamp-v)/ne)*ne;if(t>=a)continue;const l=g.get(t);if(l&&(je(n)?l.v++:ft(n)&&l.o++,mt(n)&&l.e++),n.lbt_backoff_delays_ms){const w=c.get(t);if(w)try{const C=JSON.parse(n.lbt_backoff_delays_ms);if(Array.isArray(C))for(const h of C)typeof h=="number"&&!isNaN(h)&&w.push(h)}catch{}}n.lbt_attempts!==void 0&&n.lbt_attempts>0&&(y.set(t,(y.get(t)??0)+1),n.lbt_attempts>1&&f.set(t,(f.get(t)??0)+1));const N=n.type??n.payload_type??-1;if(N===z.REQ||N===z.ANON_REQ){const w=R.get(t);w!==void 0&&R.set(t,w+1)}if(N===z.ACK){const w=D.get(t);w!==void 0&&D.set(t,w+1)}}const u=[];for(const[n,{v:t,o:l,e:N}]of g){const w=t+l+N;u.push({ts:n,value:t,overhead:l,error:N,efficiency:w>0?t/w:null,ema:null})}u.sort((n,t)=>n.ts-t.ts);let o=null;for(const n of u)if(n.efficiency!==null){const t=1-n.efficiency;o=o===null?t:Se*t+(1-Se)*o,n.ema=o}const i=[];for(const[n,t]of c){if(t.length===0){i.push({ts:n,mean:0,median:0,stddev:0,min:0,max:0,q25:0,q75:0,sampleCount:0,cv:0,skewness:0,skewnessVelocity:0});continue}t.sort((T,A)=>T-A);const l=t.length,N=t.reduce((T,A)=>T+A,0)/l,w=t.reduce((T,A)=>T+(A-N)**2,0)/Math.max(l-1,1),C=Math.sqrt(w);let h=0;for(const T of t)h+=(T-N)**3;h/=l;const L=C>0?h/(C*C*C):0;i.push({ts:n,mean:N,median:t[Math.floor(l*.5)],stddev:C,min:t[0],max:t[l-1],q25:t[Math.floor(l*.25)],q75:t[Math.floor(l*.75)],sampleCount:l,cv:N>0?C/N:0,skewness:L,skewnessVelocity:0})}i.sort((n,t)=>n.ts-t.ts);let m=-1;for(let n=0;n<i.length;n++)if(i[n].sampleCount!==0){if(m>=0){const t=i[n].ts-i[m].ts;t>0&&(i[n].skewnessVelocity=(i[n].skewness-i[m].skewness)/t)}m=n}const b=[...R.entries()].sort((n,t)=>n[0]-t[0]),S=[...D.entries()].sort((n,t)=>n[0]-t[0]),j=[];for(let n=0;n<b.length;n++){const t=b[n][0],l=b[n][1],N=(((s=S[n])==null?void 0:s[1])??0)+(((x=S[n+1])==null?void 0:x[1])??0),w=y.get(t)??0,C=f.get(t)??0,h=w>0?C/w:null,L=l>0?Math.min(N/l,1):null;let T=0,A=0,M=0;if(L!==null){T=L;const k=1-L;h!==null&&h>0?(M=k*h,A=k*(1-h)):A=k}j.push({ts:t,reqCount:l,ackCount:N,reliability:L,lbtRetryRate:h,successFrac:T,lostFrac:A,blockedFrac:M})}return{efficiency:u,jitter:i,reliability:j}}function pt(r,a,v,g){const c=r+a;if(v>=.85)return g<.5?{label:"Healthy Backhaul",description:"Low failure rate with stable RF environment",colorVar:"var(--sys-green)",colorClass:"text-sys-green"}:{label:"Stable — Elevated Jitter",description:`Reliability ${(v*100).toFixed(0)}% is healthy but CV=${g.toFixed(2)} indicates RF variability`,colorVar:"var(--sys-teal)",colorClass:"text-sys-teal"};if(c<1)return{label:"Insufficient Data",description:"Not enough REQ/ACK pairs to classify failure mode",colorVar:"var(--sys-blue)",colorClass:"text-sys-blue"};const R=r/c;return R>.6?{label:"Local RF Congestion",description:`LBT blocking ${Math.round(R*100)}% of failures — radio can't find clear air`,colorVar:"var(--sys-red)",colorClass:"text-sys-red"}:R<.3?{label:"Remote Node Deafness",description:`${Math.round((1-R)*100)}% of failures from RF loss — sent but not acknowledged`,colorVar:"var(--sys-amber)",colorClass:"text-sys-amber"}:{label:"Mixed Failure Mode",description:`Both LBT blocking (${Math.round(r)}) and RF loss (${Math.round(a)}) contributing`,colorVar:"var(--sys-amber)",colorClass:"text-sys-amber"}}const gt=p.memo(function({buckets:a,logScale:v,onHoverIdx:g}){const c=p.useRef(null),R=p.useRef(null),D=p.useRef(a),y=p.useRef(v);D.current=a,y.current=v;const f=p.useRef(g);f.current=g;const u=p.useMemo(()=>[0,.25,.5,.75,1].map(m=>({label:`${Math.round(m*100)}%`,pos:(1-m)*100})),[]),o=p.useMemo(()=>we(a),[a.length]),i=p.useMemo(()=>{const m=a.map(S=>S.ts),b=a.map(()=>1);return[m,b]},[a.length]);return p.useEffect(()=>{const m=c.current;if(!m||a.length===0)return;const b=me(()=>{const j=m.getBoundingClientRect(),s=Math.floor(j.width)||400,x=Math.floor(j.height)||200,n=new xe({width:s,height:x,padding:[0,0,0,0],cursor:{show:!0,sync:{key:"signal-lab"},x:!0,y:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{setCursor:[t=>{if(f.current){const l=t.cursor.idx??null;f.current(l)}}],draw:[t=>{const l=t.ctx,{left:N,top:w,width:C,height:h}=t.bbox,L=devicePixelRatio||1,T=D.current,A=y.current,M=T.length;if(M===0||C<=0||h<=0)return;if(l.save(),t.cursor.idx!=null&&t.cursor.idx>=0&&t.cursor.idx<M){const F=C/M;l.fillStyle=ee(),l.globalAlpha=.08,l.fillRect(N+t.cursor.idx*F,w,F,h),l.globalAlpha=1}let k=1;for(const F of T){const E=F.value+F.overhead+F.error;E>k&&(k=E)}const B=w+h/2,_=h/2,I=C/M,Y=ee(),V=F=>A?F<=0?0:Math.log10(1+F)/Math.log10(1+k):F/k;for(let F=0;F<M;F++){const E=V(T[F].value);if(E<=0)continue;const H=E*_;l.fillStyle=$.green,l.fillRect(N+F*I,B-H,I,H)}for(let F=0;F<M;F++){const E=V(T[F].overhead);if(E<=0)continue;const H=E*_;l.fillStyle=$.amber,l.fillRect(N+F*I,B,I,H)}for(let F=0;F<M;F++){const E=V(T[F].overhead),H=V(T[F].error);if(H<=0)continue;const J=E*_,d=H*_;l.fillStyle=$.red,l.fillRect(N+F*I,B+J,I,Math.min(d,_-J))}l.strokeStyle=Y,l.globalAlpha=.35,l.lineWidth=1*L,l.setLineDash([4*L,4*L]),l.beginPath(),l.moveTo(N,Math.round(B)+.5),l.lineTo(N+C,Math.round(B)+.5),l.stroke(),l.setLineDash([]),l.globalAlpha=1,l.strokeStyle=re()?Z[300]:Z[700],l.lineWidth=1.5*L,l.lineCap="round",l.lineJoin="round",l.beginPath();let G=!1;for(let F=0;F<M;F++){if(T[F].ema===null){G=!1;continue}const E=N+F*I+I/2,H=w+h*(1-T[F].ema);G?l.lineTo(E,H):(l.moveTo(E,H),G=!0)}l.stroke(),l.restore()}]}},i,m);R.current=n}),S=new ResizeObserver(j=>{const s=j[0];if(!s||!R.current)return;const{width:x,height:n}=s.contentRect;x>0&&n>0&&R.current.setSize({width:Math.floor(x),height:Math.floor(n)})});return S.observe(m),()=>{var j;b(),S.disconnect(),(j=R.current)==null||j.destroy(),R.current=null}},[i]),p.useEffect(()=>{var m;(m=R.current)==null||m.redraw()},[a,v]),a.length===0?e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data"}):e.jsxs("div",{className:"w-full h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 min-h-0 relative",children:[e.jsx("div",{className:"absolute top-0 left-0",style:{width:W,bottom:O},"aria-hidden":"true",children:u.map((m,b)=>e.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${m.pos}%`,transform:m.pos<=1?"none":m.pos>=99?"translateY(-100%)":"translateY(-50%)",right:0},children:m.label},b))}),e.jsx("div",{ref:c,className:"absolute overflow-hidden radius-inner depth-stroke-inset bg-chart-inner",style:{left:W,right:0,top:0,bottom:O}}),e.jsx("div",{className:"absolute left-0 right-0 bottom-0 pointer-events-none",style:{left:W,height:O},"aria-hidden":"true",children:o.map((m,b)=>e.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${m.pos}%`,transform:b===0?"none":b===o.length-1?"translateX(-100%)":"translateX(-50%)"},children:m.label},b))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-0.5 shrink-0 pt-1",style:{paddingLeft:W},children:[e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:Me,children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.green}}),"Value ▲"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:Ne,children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.amber}}),"Overhead ▼"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Wasted airtime — duplicated or dropped packets. Spikes here mean RF collisions or routing loops.",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.red}}),"Error ▼"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Smoothed trend line — rising means overhead or errors are growing, falling means your mesh is getting more efficient",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:"var(--fg-secondary)"}}),"Trend"]})]})]})}),$e=p.memo(function({buckets:a}){const v=p.useRef(null),g=p.useRef(null),c=p.useRef(a);c.current=a;const{cvMax:R,skewMax:D}=p.useMemo(()=>{let i=1,m=1;for(const b of a)b.sampleCount!==0&&(b.cv>i&&(i=b.cv),Math.abs(b.skewness)>m&&(m=Math.abs(b.skewness)));return{cvMax:Math.ceil(i*2)/2,skewMax:Math.ceil(m*2)/2}},[a]),y=p.useMemo(()=>[0,.25,.5,.75,1].map(i=>({label:(R*i).toFixed(1),pos:(1-i)*100})),[R]),f=p.useMemo(()=>[{label:`+${D.toFixed(1)}`,pos:0},{label:"0",pos:50},{label:`−${D.toFixed(1)}`,pos:100}],[D]),u=p.useMemo(()=>we(a),[a.length]),o=p.useMemo(()=>{const i=a.map(b=>b.ts),m=a.map(()=>1);return[i,m]},[a.length]);return p.useEffect(()=>{const i=v.current;if(!i||a.length===0)return;const m=me(()=>{const S=i.getBoundingClientRect(),j=Math.floor(S.width)||400,s=Math.floor(S.height)||200,x=new xe({width:j,height:s,padding:[0,0,0,0],cursor:{show:!0,sync:{key:"signal-lab"},x:!0,y:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[n=>{const t=n.ctx,{left:l,top:N,width:w,height:C}=n.bbox,h=devicePixelRatio||1,L=c.current,T=L.length;if(T===0||w<=0||C<=0)return;if(t.save(),n.cursor.idx!=null&&n.cursor.idx>=0&&n.cursor.idx<T){const d=w/T;t.fillStyle=ee(),t.globalAlpha=.08,t.fillRect(l+n.cursor.idx*d,N,d,C),t.globalAlpha=1}let A=1;for(const d of L)d.sampleCount>0&&d.cv>A&&(A=d.cv);A=Math.ceil(A*2)/2;const M=w/T,k=M>4*h?1:0,B=ee();for(let d=0;d<T;d++){const P=L[d];if(P.sampleCount===0)continue;const q=P.cv,X=Math.min(q/A,1)*C,te=l+d*M;t.fillStyle=q<.5?$.teal:q<1?$.amber:$.red,t.globalAlpha=q<.5?1:.5,t.fillRect(te+k,N+C-X,M-k*2,X),t.globalAlpha=1}const _=re()?Z[200]:Z[700],I=N+C,Y=[];let V=[];for(let d=0;d<T;d++){const P=L[d];if(P.sampleCount===0||P.median<=0||P.mean<=0){V.length>0&&(Y.push(V),V=[]);continue}const q=Math.abs(P.median-P.mean)/Math.max(P.mean,1),X=Math.min(q/A,1)*C;V.push({x:l+d*M+M/2,deltaY:I-X})}V.length>0&&Y.push(V),t.lineCap="round",t.lineJoin="round";for(const d of Y){if(d.length===1){t.fillStyle=_,t.beginPath(),t.arc(d[0].x,d[0].deltaY,1.5*h,0,Math.PI*2),t.fill();continue}t.fillStyle=_,t.globalAlpha=.2,t.beginPath(),t.moveTo(d[0].x,d[0].deltaY);for(let P=1;P<d.length;P++)t.lineTo(d[P].x,d[P].deltaY);t.lineTo(d[d.length-1].x,I),t.lineTo(d[0].x,I),t.closePath(),t.fill(),t.globalAlpha=1,t.strokeStyle=_,t.lineWidth=1*h,t.beginPath(),t.moveTo(d[0].x,d[0].deltaY);for(let P=1;P<d.length;P++)t.lineTo(d[P].x,d[P].deltaY);t.stroke()}t.lineCap="butt",t.lineJoin="miter";const G=d=>N+C*(1-Math.min(d/A,1));if(t.lineWidth=1*h,t.setLineDash([4*h,4*h]),.5<=A){t.strokeStyle=$.teal,t.globalAlpha=.4,t.beginPath();const d=Math.round(G(.5))+.5;t.moveTo(l,d),t.lineTo(l+w,d),t.stroke()}if(1<=A){t.strokeStyle=$.red,t.globalAlpha=.4,t.beginPath();const d=Math.round(G(1))+.5;t.moveTo(l,d),t.lineTo(l+w,d),t.stroke()}t.setLineDash([]),t.globalAlpha=1,t.strokeStyle=B,t.globalAlpha=.12,t.lineWidth=1*h,t.setLineDash([4*h,4*h]);for(const d of[.25,.5,.75]){const P=Math.round(N+C*(1-d))+.5;t.beginPath(),t.moveTo(l,P),t.lineTo(l+w,P),t.stroke()}t.setLineDash([]),t.globalAlpha=1;let F=1;for(const d of L)d.sampleCount>0&&(F=Math.max(F,Math.abs(d.skewness)));F=Math.ceil(F*2)/2;const E=d=>N+C*(.5-d/(2*F));t.strokeStyle=$.indigo,t.globalAlpha=.25,t.lineWidth=1*h,t.setLineDash([2*h,2*h]);const H=Math.round(E(0))+.5;t.beginPath(),t.moveTo(l,H),t.lineTo(l+w,H),t.stroke(),t.setLineDash([]),t.globalAlpha=1,t.strokeStyle=$.indigo,t.lineWidth=1.5*h,t.lineCap="round",t.lineJoin="round";let J=!1;for(let d=0;d<T;d++){const P=L[d];if(P.sampleCount===0){J&&(t.stroke(),J=!1);continue}const q=l+d*M+M/2,X=E(P.skewness);J?t.lineTo(q,X):(t.beginPath(),t.moveTo(q,X),J=!0)}J&&t.stroke(),t.lineCap="butt",t.lineJoin="miter",t.restore()}]}},o,i);g.current=x}),b=new ResizeObserver(S=>{const j=S[0];if(!j||!g.current)return;const{width:s,height:x}=j.contentRect;s>0&&x>0&&g.current.setSize({width:Math.floor(s),height:Math.floor(x)})});return b.observe(i),()=>{var S;m(),b.disconnect(),(S=g.current)==null||S.destroy(),g.current=null}},[o]),p.useEffect(()=>{var i;(i=g.current)==null||i.redraw()},[a]),a.length===0?e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No LBT data"}):e.jsxs("div",{className:"w-full h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 min-h-0 relative",children:[e.jsx("div",{className:"absolute top-0 left-0",style:{width:W,bottom:O},"aria-hidden":"true",children:y.map((i,m)=>e.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${i.pos}%`,transform:i.pos<=1?"none":i.pos>=99?"translateY(-100%)":"translateY(-50%)",right:0},children:i.label},m))}),e.jsx("div",{ref:v,className:"absolute overflow-hidden radius-inner depth-stroke-inset bg-chart-inner",style:{left:W,right:be,top:0,bottom:O}}),e.jsx("div",{className:"absolute top-0 right-0",style:{width:be,bottom:O},"aria-hidden":"true",children:f.map((i,m)=>e.jsx("span",{className:"type-data-xs pl-1",style:{position:"absolute",top:`${i.pos}%`,transform:i.pos<=1?"none":i.pos>=99?"translateY(-100%)":"translateY(-50%)",left:0,color:$.indigo},children:i.label},m))}),e.jsx("div",{className:"absolute left-0 right-0 bottom-0 pointer-events-none",style:{left:W,right:be,height:O},"aria-hidden":"true",children:u.map((i,m)=>e.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${i.pos}%`,transform:m===0?"none":m===u.length-1?"translateX(-100%)":"translateX(-50%)"},children:i.label},m))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-0.5 shrink-0 pt-1",style:{paddingLeft:W},children:[e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Channel access is predictable — your network isn't congested and nodes can transmit when they need to",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.teal}}),"Stable"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Some contention on the channel — nodes occasionally wait longer to transmit. Watch for a worsening trend.",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.amber}}),"Moderate"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Heavy channel congestion — nodes are fighting for airtime. Consider reducing duty cycle, spreading traffic, or adding repeaters.",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.red}}),"Volatile"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Gap between typical and average wait times — a large gap means a few extreme delays are pulling the average up",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:"var(--fg-secondary)"}}),"Median–Mean"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs",style:{color:$.indigo},title:"Delay distribution shape — positive (above zero) means occasional long waits from traffic bursts, negative means delays are capped and predictable",children:[e.jsx("span",{className:"w-3 h-0.5 rounded-xs shrink-0",style:{background:$.indigo}}),"γ₁ Skewness"]})]})]})}),bt=p.memo(function({buckets:a}){const v=p.useRef(null),g=p.useRef(null),c=p.useRef(a);c.current=a;const R=p.useMemo(()=>[0,.25,.5,.75,1].map(f=>({label:`${Math.round(f*100)}%`,pos:(1-f)*100})),[]),D=p.useMemo(()=>we(a),[a.length]),y=p.useMemo(()=>{const f=a.map(o=>o.ts),u=a.map(()=>1);return[f,u]},[a.length]);return p.useEffect(()=>{const f=v.current;if(!f||a.length===0)return;const u=me(()=>{const i=f.getBoundingClientRect(),m=Math.floor(i.width)||400,b=Math.floor(i.height)||200,S=new xe({width:m,height:b,padding:[0,0,0,0],cursor:{show:!0,sync:{key:"signal-lab"},x:!0,y:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[j=>{const s=j.ctx,{left:x,top:n,width:t,height:l}=j.bbox,N=devicePixelRatio||1,w=c.current,C=w.length;if(C===0||t<=0||l<=0)return;if(s.save(),j.cursor.idx!=null&&j.cursor.idx>=0&&j.cursor.idx<C){const k=t/C;s.fillStyle=ee(),s.globalAlpha=.08,s.fillRect(x+j.cursor.idx*k,n,k,l),s.globalAlpha=1}const h=t/C,L=pe(),T=ee();for(let k=0;k<C;k++){const B=w[k];if(B.reliability===null)continue;const _=x+k*h,I=B.successFrac*l;s.fillStyle=$.green,s.fillRect(_,n+l-I,h,I);const Y=B.lostFrac*l;s.fillStyle=$.amber,s.fillRect(_,n+l-I-Y,h,Y);const V=B.blockedFrac*l;s.fillStyle=$.red,s.fillRect(_,n+l-I-Y-V,h,V)}const M=n+l*(1-.85);s.strokeStyle=T,s.globalAlpha=.4,s.lineWidth=1*N,s.setLineDash([6*N,3*N]),s.beginPath(),s.moveTo(x,Math.round(M)+.5),s.lineTo(x+t,Math.round(M)+.5),s.stroke(),s.setLineDash([]),s.globalAlpha=1,s.strokeStyle=T,s.globalAlpha=.12,s.lineWidth=1*N,s.setLineDash([4*N,4*N]);for(const k of[.25,.5,.75]){const B=Math.round(n+l*(1-k))+.5;s.beginPath(),s.moveTo(x,B),s.lineTo(x+t,B),s.stroke()}s.setLineDash([]),s.globalAlpha=1,s.font=`bold ${10*N}px ${L}`,s.fillStyle=T,s.globalAlpha=.65,s.textBaseline="bottom",s.textAlign="right",s.fillText("85%",x+t-4*N,M-2*N),s.globalAlpha=1,s.restore()}]}},y,f);g.current=S}),o=new ResizeObserver(i=>{const m=i[0];if(!m||!g.current)return;const{width:b,height:S}=m.contentRect;b>0&&S>0&&g.current.setSize({width:Math.floor(b),height:Math.floor(S)})});return o.observe(f),()=>{var i;u(),o.disconnect(),(i=g.current)==null||i.destroy(),g.current=null}},[y]),p.useEffect(()=>{var f;(f=g.current)==null||f.redraw()},[a]),a.length===0?e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data"}):e.jsxs("div",{className:"w-full h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 min-h-0 relative",children:[e.jsx("div",{className:"absolute top-0 left-0",style:{width:W,bottom:O},"aria-hidden":"true",children:R.map((f,u)=>e.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${f.pos}%`,transform:f.pos<=1?"none":f.pos>=99?"translateY(-100%)":"translateY(-50%)",right:0},children:f.label},u))}),e.jsx("div",{ref:v,className:"absolute overflow-hidden radius-inner depth-stroke-inset bg-chart-inner",style:{left:W,right:0,top:0,bottom:O}}),e.jsx("div",{className:"absolute left-0 right-0 bottom-0 pointer-events-none",style:{left:W,height:O},"aria-hidden":"true",children:D.map((f,u)=>e.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${f.pos}%`,transform:u===0?"none":u===D.length-1?"translateX(-100%)":"translateX(-50%)"},children:f.label},u))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-0.5 shrink-0 pt-1",style:{paddingLeft:W},children:[e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Messages that made it through and were acknowledged — the healthy portion of your mesh traffic",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.green}}),"Success"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Messages sent but never acknowledged — lost to RF interference, distance, or obstacles. Persistent losses suggest a weak link.",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.amber}}),"Lost"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Couldn't even transmit because the channel was busy — sign of local congestion or a nearby heavy transmitter",children:[e.jsx("span",{className:"w-3 h-3 rounded-xs shrink-0",style:{background:$.red}}),"Blocked"]})]})]})}),Te=3e4,Fe=p.memo(function({buckets:a,hoveredIdx:v}){const g=p.useRef(null),c=p.useRef(a),R=p.useRef(v),D=p.useRef(performance.now()),y=p.useRef(0);c.current=a,R.current=v,p.useEffect(()=>{D.current=performance.now()},[a]);const{cvMax:f,skewMax:u}=p.useMemo(()=>{let b=1,S=1;for(const j of a)j.sampleCount!==0&&(j.cv>b&&(b=j.cv),Math.abs(j.skewness)>S&&(S=Math.abs(j.skewness)));return{cvMax:Math.ceil(b*2)/2,skewMax:Math.ceil(S*2)/2}},[a]),o=p.useMemo(()=>[{label:`+${u.toFixed(1)}`,pos:0},{label:"0",pos:50},{label:`−${u.toFixed(1)}`,pos:100}],[u]),i=p.useMemo(()=>[{label:"0",pos:0},{label:(f/2).toFixed(1),pos:50},{label:f.toFixed(1),pos:100}],[f]);return p.useEffect(()=>{if(!g.current)return;function S(){const j=g.current;if(!j)return;const s=j.getContext("2d");if(!s)return;const x=j.getBoundingClientRect(),n=devicePixelRatio||1,t=Math.floor(x.width*n),l=Math.floor(x.height*n);if(t<=0||l<=0)return;(j.width!==t||j.height!==l)&&(j.width=t,j.height=l),s.clearRect(0,0,t,l),s.save();const N=c.current,w=ee(),C=pe(),h=4*n,L=h,T=h,A=t-2*h,M=l-2*h;if(A<=0||M<=0){s.restore();return}let k=1,B=1;for(const d of N)d.sampleCount!==0&&(d.cv>k&&(k=d.cv),Math.abs(d.skewness)>B&&(B=Math.abs(d.skewness)));k=Math.ceil(k*2)/2,B=Math.ceil(B*2)/2;const _=d=>L+d/k*A,I=d=>T+M*(.5-d/(2*B));s.strokeStyle=w,s.globalAlpha=.08,s.lineWidth=1*n,s.setLineDash([3*n,3*n]);for(const d of[.25,.5,.75]){const P=Math.round(L+d*A)+.5;s.beginPath(),s.moveTo(P,T),s.lineTo(P,T+M),s.stroke()}for(const d of[.25,.75]){const P=Math.round(T+d*M)+.5;s.beginPath(),s.moveTo(L,P),s.lineTo(L+A,P),s.stroke()}s.setLineDash([]),s.globalAlpha=1;const Y=Math.round(I(0))+.5;s.strokeStyle=$.indigo,s.globalAlpha=.3,s.lineWidth=1*n,s.beginPath(),s.moveTo(L,Y),s.lineTo(L+A,Y),s.stroke(),s.globalAlpha=1,s.font=`${9*n}px ${C}`,s.fillStyle=w,s.globalAlpha=.1,s.textAlign="center",s.textBaseline="middle",s.fillText("Stable",L+A*.25,I(0)),s.fillText("Burst Mode",L+A*.75,T+M*.2),s.fillText("Saturated",L+A*.75,T+M*.8),s.globalAlpha=1;const V=[];for(let d=0;d<N.length;d++){const P=N[d];P.sampleCount!==0&&V.push({idx:d,cv:P.cv,sk:P.skewness})}const G=performance.now()-D.current,F=Math.max(.08,Math.min(1,1-G/Te)),E=3*n;for(let d=0;d<V.length;d++){const P=V[d],q=_(P.cv),X=I(P.sk),te=d===V.length-1;s.fillStyle=P.cv<.5?$.teal:P.cv<1?$.amber:$.red,s.globalAlpha=te?F:.08,s.beginPath(),s.arc(q,X,E,0,Math.PI*2),s.fill()}s.globalAlpha=1;const H=V.slice(-5);if(H.length>1){s.strokeStyle=w,s.globalAlpha=.45,s.lineWidth=1.5*n,s.lineCap="round",s.lineJoin="round",s.beginPath(),s.moveTo(_(H[0].cv),I(H[0].sk));for(let de=1;de<H.length;de++)s.lineTo(_(H[de].cv),I(H[de].sk));s.stroke();const d=H[H.length-1],P=H[H.length-2],q=_(d.cv),X=I(d.sk),te=_(P.cv),ge=I(P.sk),ie=Math.atan2(X-ge,q-te),ce=6*n;s.fillStyle=w,s.beginPath(),s.moveTo(q,X),s.lineTo(q-ce*Math.cos(ie-Math.PI/6),X-ce*Math.sin(ie-Math.PI/6)),s.lineTo(q-ce*Math.cos(ie+Math.PI/6),X-ce*Math.sin(ie+Math.PI/6)),s.closePath(),s.fill(),s.globalAlpha=1,s.lineCap="butt",s.lineJoin="miter"}const J=R.current;if(J!==null){const d=N[J];d&&d.sampleCount>0&&(s.strokeStyle=w,s.lineWidth=2*n,s.beginPath(),s.arc(_(d.cv),I(d.skewness),E+3*n,0,Math.PI*2),s.stroke())}s.restore(),G<Te&&(y.current=requestAnimationFrame(S))}return S(),()=>{y.current&&cancelAnimationFrame(y.current)}},[a,v]),a.some(b=>b.sampleCount>0)?e.jsxs("div",{className:"w-full h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 min-h-0 relative",children:[e.jsx("div",{className:"absolute top-0 left-0",style:{width:W,bottom:O},"aria-hidden":"true",children:o.map((b,S)=>e.jsx("span",{className:"type-data-xs text-right pr-1.5",style:{position:"absolute",top:`${b.pos}%`,transform:b.pos<=1?"none":b.pos>=99?"translateY(-100%)":"translateY(-50%)",right:0,color:$.indigo},children:b.label},S))}),e.jsx("canvas",{ref:g,className:"absolute block radius-inner depth-stroke-inset bg-chart-inner",style:{left:W,right:0,top:0,bottom:O,width:`calc(100% - ${W}px)`,height:`calc(100% - ${O}px)`}}),e.jsx("div",{className:"absolute left-0 right-0 bottom-0 pointer-events-none",style:{left:W,height:O},"aria-hidden":"true",children:i.map((b,S)=>e.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${b.pos}%`,transform:S===0?"none":S===i.length-1?"translateX(-100%)":"translateX(-50%)"},children:b.label},S))})]}),e.jsx("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-0.5 shrink-0 pt-1 type-data-xs text-fg-secondary",style:{paddingLeft:W},children:"X: CV \\u00b7 Y: \\u03b3\\u2081 \\u00b7 Trail: last 5"})]}):e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No LBT data"})}),yt=p.memo(function({value:a,maxValue:v,theoreticalMax:g,collisionThreshold:c,label:R}){const D=p.useRef(null),y=p.useRef({value:a,maxValue:v,theoreticalMax:g,collisionThreshold:c,label:R});y.current={value:a,maxValue:v,theoreticalMax:g,collisionThreshold:c,label:R};const f=p.useCallback(()=>{const u=D.current;if(!u)return;const o=u.getContext("2d");if(!o)return;const i=u.getBoundingClientRect();if(i.width===0||i.height===0)return;const m=devicePixelRatio||1;u.width=Math.floor(i.width*m),u.height=Math.floor(i.height*m);const b=u.width,S=u.height,j=pe(),s=ee(),{value:x,maxValue:n,theoreticalMax:t,collisionThreshold:l,label:N}=y.current,w=Math.min(b,S)/180;o.clearRect(0,0,b,S);const C=b/2,h=S*.52,L=Math.min(C-8*w,h-8*w),T=L*.72,A=Math.PI*.75,M=Math.PI*.25+Math.PI,k=M-A,B=n>0?Math.min(x/n,1):0,_=A+B*k;o.beginPath(),o.arc(C,h,L,A,M),o.arc(C,h,T,M,A,!0),o.closePath(),o.fillStyle=re()?Z[800]:Z[200],o.fill();const I=l&&n>0?Math.min(l/n,.95):.5,Y=t&&n>0?Math.min(t/n,.99):.85,V=o.createConicGradient(A,C,h);if(V.addColorStop(0,$.green),V.addColorStop(I*.8,$.green),V.addColorStop(I,$.amber),V.addColorStop(Y,$.red),V.addColorStop(1,$.red),o.beginPath(),o.arc(C,h,L,A,_),o.arc(C,h,T,_,A,!0),o.closePath(),o.fillStyle=V,o.fill(),l&&l>0&&n>0){const F=Math.min(l/n,1),E=A+F*k;o.strokeStyle=$.amber,o.globalAlpha=.6,o.lineWidth=Math.max(1,1.5*w),o.beginPath(),o.moveTo(C+Math.cos(E)*(T-1*w),h+Math.sin(E)*(T-1*w)),o.lineTo(C+Math.cos(E)*(L+1*w),h+Math.sin(E)*(L+1*w)),o.stroke(),o.globalAlpha=1}if(t>0&&n>0){const F=Math.min(t/n,1),E=A+F*k;o.beginPath(),o.arc(C,h,L,A,E),o.arc(C,h,T,E,A,!0),o.closePath(),o.fillStyle=s,o.globalAlpha=.07,o.fill(),o.globalAlpha=1,o.strokeStyle=$.red,o.globalAlpha=.5,o.lineWidth=Math.max(1,1.5*w),o.beginPath(),o.moveTo(C+Math.cos(E)*(T-2*w),h+Math.sin(E)*(T-2*w)),o.lineTo(C+Math.cos(E)*(L+2*w),h+Math.sin(E)*(L+2*w)),o.stroke(),o.globalAlpha=1}o.fillStyle=s,o.textAlign="center",o.textBaseline="middle",o.font=`bold ${Math.round(20*w)}px ${j}`,o.fillText(`${(x*1e3).toFixed(1)}`,C,h-4*w),o.font=`${Math.round(7.5*w)}px ${j}`,o.globalAlpha=.6,o.fillText("×10⁻³",C,h+10*w),o.globalAlpha=1,o.font=`bold ${Math.round(9*w)}px ${j}`,o.fillText(N,C,h+L+12*w);const G=t>0?x/t*100:0;o.font=`${Math.round(8*w)}px ${j}`,o.globalAlpha=.55,o.fillText(`${G.toFixed(0)}% cap`,C,h+L+24*w),o.globalAlpha=1},[]);return p.useEffect(()=>{f()},[a,v,g,c,R,f]),p.useEffect(()=>{const u=D.current;if(!u)return;const o=new ResizeObserver(()=>f());return o.observe(u),()=>o.disconnect()},[f]),e.jsx("canvas",{ref:D,className:"w-full h-full"})});function vt({efficiency:r,jitter:a,reliability:v,packets:g}){const c=r.reduce((M,k)=>M+k.value,0),R=r.reduce((M,k)=>M+k.overhead,0),D=r.reduce((M,k)=>M+k.error,0),y=c+R+D,f=y>0?c/y:0,u=a.filter(M=>M.sampleCount>0),o=u.length>0?u.reduce((M,k)=>M+k.cv,0)/u.length:0,i=u.reduce((M,k)=>Math.max(M,k.cv),0),m=v.reduce((M,k)=>M+k.reqCount,0),b=v.reduce((M,k)=>M+k.ackCount,0),S=m>0?Math.min(b/m,1):1,j=v.reduce((M,k)=>M+k.blockedFrac*k.reqCount,0),s=v.reduce((M,k)=>M+k.lostFrac*k.reqCount,0),x=pt(j,s,S,o),n=S>=.85?Ge:Je,t=g.length>=2?(g[g.length-1].timestamp-g[0].timestamp)/3600:0,l=t>0?Math.round(g.length/t):0,N=u.length>0?u[u.length-1]:null,w=(N==null?void 0:N.skewness)??0,C=(N==null?void 0:N.skewnessVelocity)??0,h=Math.abs(w),L=w>.1?"Right-skew (burst)":w<-.1?"Left-skew (saturated)":"Symmetric",T=Math.abs(C)<.01?"→":C>0?"↗":"↘",A=[{label:"Network Efficiency",value:`${(f*100).toFixed(1)}%`,color:f>.5?"text-sys-green":f>.3?"text-sys-amber":"text-sys-red",sub:`${c.toLocaleString()} value / ${y.toLocaleString()} total`},{label:"LBT Stability (CV)",value:o.toFixed(2),color:o<.5?"text-sys-teal":o<1?"text-sys-amber":"text-sys-red",sub:`peak ${i.toFixed(2)} · ${o<.5?"Stable":o<1?"Moderate":"Volatile"}`},{label:"Path Reliability",value:`${(S*100).toFixed(1)}%`,color:S>.85?"text-sys-green":S>.7?"text-sys-amber":"text-sys-red",sub:`${Math.round(j)} blocked · ${Math.round(s)} lost · ${b} ACK`},{label:"Throughput",value:`${l.toLocaleString()} /hr`,color:"text-fg-primary",sub:`${g.length.toLocaleString()} in ${t>0?`${t.toFixed(1)}h`:"—"} window`},{label:"Skewness (γ₁)",value:`${w>=0?"+":""}${w.toFixed(2)} ${T}`,color:h<.3?"text-sys-teal":h<1?"text-sys-indigo":"text-sys-red",sub:L}];return e.jsxs("div",{children:[e.jsxs("div",{className:"surface-inner radius-inner px-3 py-2.5 mb-3 flex items-start gap-2.5",style:{borderLeft:`3px solid ${x.colorVar}`},children:[e.jsx(n,{className:`w-4 h-4 shrink-0 mt-0.5 ${x.colorClass}`}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:`type-label font-semibold ${x.colorClass}`,children:x.label}),e.jsx("p",{className:"type-data-xs text-fg-muted mt-0.5",children:x.description})]})]}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3",children:A.map(M=>e.jsxs("div",{className:"surface-inner radius-inner p-3",children:[e.jsx("p",{className:"type-micro text-fg-muted truncate",children:M.label}),e.jsx("p",{className:`type-data-xl ${M.color}`,children:M.value}),e.jsx("p",{className:"type-data-xs text-fg-muted",children:M.sub})]},M.label))})]})}function Ee({talkers:r}){if(r.length===0)return e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted type-data-xs",children:"No source data"});const a=r.reduce((c,R)=>Math.max(c,R.total),1),g=re()?Z[700]:Z[300];return e.jsx("div",{className:"flex flex-col h-full min-w-0 overflow-hidden",children:e.jsx("div",{className:"flex-1 min-h-0 gap-y-0.5",style:{display:"grid",gridTemplateColumns:"0.75rem 4.5rem 1fr auto",alignItems:"center",columnGap:"0.375rem"},children:r.map((c,R)=>{const D=a>0?c.total/a*100:0,y=c.total>0?c.value/c.total*100:0,f=`${c.name||c.hash.slice(0,8)}: ${c.value} useful messages + ${c.tax} overhead packets = ${c.total} total. ${c.taxPct.toFixed(0)}% of this node's traffic is infrastructure overhead`;return e.jsxs("div",{title:f,className:"col-span-full grid gap-y-0.5 cursor-default",style:{gridTemplateColumns:"subgrid",alignItems:"center"},children:[e.jsx("span",{className:"type-data-xs text-fg-muted text-right",children:R+1}),e.jsx("span",{className:"type-data-xs text-fg-secondary truncate",children:c.name||c.hash.slice(0,8)}),e.jsx("div",{className:"min-w-0",children:e.jsxs("div",{className:"h-2 radius-badge overflow-hidden flex relative",style:{width:`${D}%`,minWidth:4},children:[e.jsx("div",{className:"h-full",style:{width:`${y}%`,background:$.blue}}),e.jsx("div",{className:"absolute top-0 h-full",style:{left:`${y}%`,width:"1.5px",background:g}}),e.jsx("div",{className:"h-full flex-1",style:{background:$.indigo}})]})}),e.jsxs("span",{className:"data-box data-box-compact",style:{"--data-box-color":"var(--fg-muted)"},children:[c.taxPct.toFixed(0),"%"]})]},c.hash)})})})}function wt(r,a){return p.useMemo(()=>{var x,n,t,l;const v=ze(a),g=v.spreadingFactor,c=v.bandwidthHz,R=v.codingRate;let D=0,y=0;if(r.length>=2){y=r[r.length-1].timestamp-r[0].timestamp;for(const N of r)D+=N.length??N.payload_length??32}const f=g*(4/R)/Math.pow(2,g),u=.27,o=.2,i=((n=(x=a==null?void 0:a.config)==null?void 0:x.duty_cycle)==null?void 0:n.max_airtime_percent)??100,m=((l=(t=a==null?void 0:a.config)==null?void 0:t.duty_cycle)==null?void 0:l.enforcement_enabled)!==!1?Math.min(1,i/100):1,b=f*Math.min(u,m),S=f*Math.min(o,m);if(y<=0)return{value:0,maxValue:b*1.3,theoreticalSe:b,collisionSe:S};const s=D*8/y/c;return{value:s,maxValue:Math.max(b*1.3,s*1.2),theoreticalSe:b,collisionSe:S}},[r,a])}function jt(r){var D;if(r.length<2)return[];const a=Math.floor(Date.now()/1e3),v=a-Le*ne,g=new Map;for(let y=v;y<a;y+=ne)g.set(y,[]);for(const y of r){if(y.timestamp<v)continue;const f=v+Math.floor((y.timestamp-v)/ne)*ne;f>=a||(D=g.get(f))==null||D.push(y.timestamp)}const c=[];for(const[y,f]of g){if(f.length<2){c.push({ts:y,mean:0,median:0,stddev:0,min:0,max:0,q25:0,q75:0,sampleCount:0,cv:0,skewness:0,skewnessVelocity:0});continue}f.sort((s,x)=>s-x);const u=[];for(let s=1;s<f.length;s++)u.push(f[s]-f[s-1]);u.sort((s,x)=>s-x);const o=u.length,i=u.reduce((s,x)=>s+x,0)/o,m=u.reduce((s,x)=>s+(x-i)**2,0)/Math.max(o-1,1),b=Math.sqrt(m);let S=0;for(const s of u)S+=(s-i)**3;S/=o;const j=b>0?S/(b*b*b):0;c.push({ts:y,mean:i,median:u[Math.floor(o*.5)],stddev:b,min:u[0],max:u[o-1],q25:u[Math.floor(o*.25)],q75:u[Math.floor(o*.75)],sampleCount:o,cv:i>0?b/i:0,skewness:j,skewnessVelocity:0})}c.sort((y,f)=>y.ts-f.ts);let R=-1;for(let y=0;y<c.length;y++)if(c[y].sampleCount!==0){if(R>=0){const f=c[y].ts-c[R].ts;f>0&&(c[y].skewnessVelocity=(c[y].skewness-c[R].skewness)/f)}R=y}return c}const Mt=p.memo(function({packets:a}){const v=p.useRef(null),g=p.useRef(null),c=p.useMemo(()=>a.filter(s=>s.rssi<0),[a]),R=p.useRef(c);R.current=c;const{rssiMin:D,rssiMax:y,snrMin:f,snrMax:u,medianRssi:o,medianSnr:i}=p.useMemo(()=>{if(c.length===0)return{rssiMin:-130,rssiMax:-30,snrMin:-20,snrMax:15,medianRssi:0,medianSnr:0};const s=c.map(n=>n.rssi).sort((n,t)=>n-t),x=c.map(n=>n.snr).sort((n,t)=>n-t);return{rssiMin:Math.min(s[0],-130),rssiMax:Math.max(s[s.length-1],-30),snrMin:Math.min(x[0],-20),snrMax:Math.max(x[x.length-1],15),medianRssi:s[Math.floor(s.length/2)],medianSnr:x[Math.floor(x.length/2)]}},[c]),m=p.useRef({rssiMin:D,rssiMax:y,snrMin:f,snrMax:u,medianRssi:o,medianSnr:i});m.current={rssiMin:D,rssiMax:y,snrMin:f,snrMax:u,medianRssi:o,medianSnr:i};const b=p.useMemo(()=>{const s=y-D;return[0,.25,.5,.75,1].map(x=>({label:`${Math.round(y-x*s)}`,pos:x*100}))},[D,y]),S=p.useMemo(()=>{if(c.length===0)return[];const s=c[0].timestamp,x=c[c.length-1].timestamp;return[0,.25,.5,.75,1].map(n=>({label:Pe(s+n*(x-s)),pos:n*100}))},[c]),j=p.useMemo(()=>{const s=c.map(n=>n.timestamp),x=c.map(()=>1);return[s,x]},[c.length]);return p.useEffect(()=>{const s=v.current;if(!s||c.length===0)return;const x=me(()=>{const t=s.getBoundingClientRect(),l=Math.floor(t.width)||400,N=Math.floor(t.height)||200,w=new xe({width:l,height:N,padding:[0,0,0,0],cursor:{show:!0,x:!0,y:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[C=>{const h=C.ctx,{left:L,top:T,width:A,height:M}=C.bbox,k=devicePixelRatio||1,B=R.current;if(B.length===0||A<=0||M<=0)return;const _=m.current;h.save();const I=ee();h.strokeStyle=I,h.globalAlpha=.1,h.lineWidth=1*k,h.setLineDash([4*k,4*k]);for(const P of[.25,.5,.75]){const q=Math.round(T+M*P)+.5;h.beginPath(),h.moveTo(L,q),h.lineTo(L+A,q),h.stroke()}h.setLineDash([]),h.globalAlpha=1;const Y=B[0].timestamp,G=B[B.length-1].timestamp-Y||1,F=_.rssiMax-_.rssiMin||1,E=_.snrMax-_.snrMin||1,H=Math.max(2,Math.min(4,200/Math.sqrt(B.length)))*k;for(const P of B){const q=L+(P.timestamp-Y)/G*A,X=T+(_.rssiMax-P.rssi)/F*M,te=Math.max(0,Math.min(1,(P.snr-_.snrMin)/E)),ge=te<.33?$.red:te<.66?$.amber:$.teal;h.fillStyle=ge,h.globalAlpha=.7,h.beginPath(),h.arc(q,X,H,0,Math.PI*2),h.fill()}h.globalAlpha=1;const J=pe();h.font=`${10*k}px ${J}`,h.textAlign="right",h.textBaseline="top",h.fillStyle=I,h.globalAlpha=.7;const d=6*k;h.fillText(`RSSI ${_.medianRssi} dBm`,L+A-d,T+d),h.fillText(`SNR ${_.medianSnr.toFixed(1)} dB`,L+A-d,T+d+14*k),h.fillText(`n=${B.length}`,L+A-d,T+d+28*k),h.globalAlpha=1,h.restore()}]}},j,s);g.current=w}),n=new ResizeObserver(t=>{const l=t[0];if(!l||!g.current)return;const{width:N,height:w}=l.contentRect;N>0&&w>0&&g.current.setSize({width:Math.floor(N),height:Math.floor(w)})});return n.observe(s),()=>{var t;x(),n.disconnect(),(t=g.current)==null||t.destroy(),g.current=null}},[j]),p.useEffect(()=>{var s;(s=g.current)==null||s.redraw()},[c]),c.length===0?e.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted type-data-xs",children:"No RF data from observer"}):e.jsxs("div",{className:"w-full h-full flex flex-col",children:[e.jsxs("div",{className:"flex-1 min-h-0 relative",children:[e.jsx("div",{className:"absolute top-0 left-0",style:{width:W,bottom:O},"aria-hidden":"true",children:b.map((s,x)=>e.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${s.pos}%`,transform:s.pos<=1?"none":s.pos>=99?"translateY(-100%)":"translateY(-50%)",right:0},children:s.label},x))}),e.jsx("div",{ref:v,className:"absolute overflow-hidden radius-inner depth-stroke-inset bg-chart-inner",style:{left:W,right:0,top:0,bottom:O}}),e.jsx("div",{className:"absolute left-0 right-0 bottom-0 pointer-events-none",style:{left:W,height:O},"aria-hidden":"true",children:S.map((s,x)=>e.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${s.pos}%`,transform:x===0?"none":x===S.length-1?"translateX(-100%)":"translateX(-50%)"},children:s.label},x))})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-0.5 shrink-0 pt-1",style:{paddingLeft:W},children:[e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Strong signal — packets arrived clearly above the noise floor, reliable decoding expected",children:[e.jsx("span",{className:"w-2 h-2 rounded-full shrink-0",style:{background:$.teal}}),"High SNR"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Moderate signal — decoding should work but there's less margin for interference or fading",children:[e.jsx("span",{className:"w-2 h-2 rounded-full shrink-0",style:{background:$.amber}}),"Mid SNR"]}),e.jsxs("span",{className:"flex items-center gap-1.5 type-data-xs text-fg-secondary",title:"Weak signal — packets barely above the noise floor, expect higher error rates and missed frames",children:[e.jsx("span",{className:"w-2 h-2 rounded-full shrink-0",style:{background:$.red}}),"Low SNR"]})]})]})});function Nt({packets:r}){const a=Qe(),v=Ze(),g=p.useMemo(()=>a?r.filter(D=>D._mqttSource):[],[r,a]),c=p.useMemo(()=>jt(g),[g]),R=p.useMemo(()=>{var f;const D=new Map;for(const u of g){const o=v(u),i=o.hash||u.src_hash||(u._advertSender?u._advertSender.slice(0,16):null)||((f=u.packet_hash)==null?void 0:f.slice(0,8));if(!i)continue;let m=D.get(i);m||(m={value:0,tax:0,name:null},D.set(i,m)),je(u)?m.value++:m.tax++,m.name||(m.name=o.name||u._advertName||null)}const y=[];for(const[u,o]of D){const i=o.value+o.tax;y.push({hash:u,name:o.name,value:o.value,tax:o.tax,total:i,taxPct:i>0?o.tax/i*100:0})}return y.sort((u,o)=>o.tax-u.tax),y.slice(0,5)},[g,v]);return!a||g.length===0?null:e.jsxs(De,{children:[e.jsx(se,{template:"auto",children:e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:"type-micro text-fg-primary",children:"MQTT OBSERVER"}),e.jsxs("span",{className:"data-box data-box-compact data-box-outlined",style:{"--data-box-accent":"var(--sys-teal)"},children:[g.length.toLocaleString()," pkts"]})]})}),e.jsxs(se,{template:"panel",children:[e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"Arrival Stability (CV)"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx($e,{buckets:c})})]})}),e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"Observer RF"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(Mt,{packets:g})})]})})]}),e.jsxs(se,{template:"panel",children:[e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{children:[e.jsx(U,{title:"MQTT Top Taxers",actions:e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsxs("span",{className:"flex items-center gap-1 type-data-xs text-fg-muted",title:Me,children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full inline-block",style:{background:$.blue}}),"Value"]}),e.jsxs("span",{className:"flex items-center gap-1 type-data-xs text-fg-muted",title:Ne,children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full inline-block",style:{background:$.indigo}}),"Tax"]})]})}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:e.jsx(Ee,{talkers:R})})]})}),e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"IAT Phase Space"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(Fe,{buckets:c,hoveredIdx:null})})]})})]})]})}function Dt(){var m,b,S,j;const r=Ye(),a=Oe(),[v,g]=p.useState(!1),[c,R]=p.useState(null),{efficiency:D,jitter:y,reliability:f}=p.useMemo(()=>xt(r),[r]),u=wt(r,a),o=p.useMemo(()=>{const s=new Map;for(const n of r){const t=n.src_hash;if(!t)continue;let l=s.get(t);l||(l={value:0,tax:0,name:null},s.set(t,l)),je(n)?l.value++:l.tax++,!l.name&&n._advertName&&(l.name=n._advertName)}const x=[];for(const[n,t]of s){const l=t.value+t.tax;x.push({hash:n,name:t.name,value:t.value,tax:t.tax,total:l,taxPct:l>0?t.tax/l*100:0})}return x.sort((n,t)=>t.tax-n.tax),x.slice(0,5)},[r]),i=p.useCallback(()=>g(s=>!s),[]);return e.jsxs(Ke,{children:[e.jsx(Ue,{title:"Signal Lab",icon:e.jsx(Xe,{}),controls:e.jsxs("button",{onClick:i,className:`flex items-center gap-1.5 px-3 py-1.5 radius-inner
                       surface-control transition-base type-data-xs text-fg-secondary`,title:"Switch to log scale to see low-traffic periods more clearly — useful when a few busy buckets dominate the chart",children:[v?e.jsx(nt,{className:"w-4 h-4 text-sys-blue"}):e.jsx(st,{className:"w-4 h-4"}),"Log₁₀"]})}),e.jsxs(De,{children:[e.jsx(se,{template:"auto",children:e.jsx(Q,{children:e.jsx(vt,{efficiency:D,jitter:y,reliability:f,packets:r})})}),e.jsx(se,{template:"auto",children:e.jsx(ht,{})}),e.jsx(se,{template:"hero",children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"Traffic Balance"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(gt,{buckets:D,logScale:v,onHoverIdx:R})})]})}),e.jsxs(se,{template:"panel",children:[e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"LBT Stability (CV)"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx($e,{buckets:y})})]})}),e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"Path Reliability (Rₚ)"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(bt,{buckets:f})})]})})]}),e.jsxs(se,{template:"panel",children:[e.jsx(ae,{span:12,md:6,children:e.jsxs(Q,{skeletonType:"chart",children:[e.jsx(U,{title:"Phase Space Map"}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(Fe,{buckets:y,hoveredIdx:c})})]})}),e.jsx(ae,{span:12,md:6,children:e.jsxs("div",{className:"h-full flex flex-col gap-3",children:[e.jsx(Q,{compact:!0,className:"!h-auto shrink-0",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-16 sm:w-20 aspect-square shrink-0",children:e.jsx(yt,{value:u.value,maxValue:u.maxValue,theoreticalMax:u.theoreticalSe,collisionThreshold:u.collisionSe,label:`SF${((b=(m=a==null?void 0:a.config)==null?void 0:m.radio)==null?void 0:b.spreading_factor)??7} / ${ut(((j=(S=a==null?void 0:a.config)==null?void 0:S.radio)==null?void 0:j.bandwidth)??125e3)}kHz`})}),e.jsxs("div",{className:"flex-1 min-w-0",title:"How much of the available channel your mesh is using. Amber zone (~20%) = collisions start degrading throughput. Red zone (~27%) = practical ceiling for a shared LoRa channel. Below amber = healthy headroom.",children:[e.jsx("p",{className:"type-micro mb-0.5",children:"RX UTILIZATION"}),e.jsx("p",{className:"type-data-xs text-fg-muted mb-1 hidden sm:block",children:"Channel capacity (Sₑ)"}),e.jsxs("div",{className:"flex items-baseline gap-1.5",children:[e.jsx("span",{className:"type-data-lg text-fg-primary",children:(u.value*1e3).toFixed(1)}),e.jsx("span",{className:"type-data-xs text-fg-muted",children:"×10⁻³ bit/s/Hz"})]})]})]})}),e.jsxs(Q,{className:"flex-1 min-h-0",children:[e.jsx(U,{title:"Top Taxers",actions:e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsxs("span",{className:"flex items-center gap-1 type-data-xs text-fg-muted",title:Me,children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full inline-block",style:{background:$.blue}}),"Value"]}),e.jsxs("span",{className:"flex items-center gap-1 type-data-xs text-fg-muted",title:Ne,children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full inline-block",style:{background:$.indigo}}),"Tax"]})]})}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:e.jsx(Ee,{talkers:o})})]})]})})]})]}),e.jsx(Nt,{packets:r})]})}export{Dt as default};
