From c8c3f164ee5d7ec0c1b1eaafc1f56efb7cf07ef4 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Fri, 27 Feb 2026 07:48:08 +0000 Subject: [PATCH] Sync build v0.9.286 Automated sync from private repository. Commit: fad7f9633de61427bfc2c672b7ddecaa0952d717 --- frontend/dist/VERSION | 2 +- ...ilterPanel-DfkXd7UH.js => AnalyzerFilterPanel-o1lp_Gs8.js} | 2 +- ...{AnimatedNumber-Dx2y1t97.js => AnimatedNumber-DACuG-ay.js} | 2 +- .../assets/{ChatBubble-BkCCRzh5.js => ChatBubble-OmHlf-X1.js} | 2 +- ...erModal-B2vZL8RO.js => CollisionExplorerModal-BUHEIiWh.js} | 2 +- .../{Configuration-BqjgQq_Y.js => Configuration-CobIQjJB.js} | 2 +- .../{ConfirmModal-XwU3yUZY.js => ConfirmModal-B6Rz8ROW.js} | 2 +- .../assets/{Contacts-Dlk8XXyy.js => Contacts-CcN2zB34.js} | 4 ++-- ...apMapLibre-CSieXgJu.js => ContactsMapMapLibre-BtIfp876.js} | 2 +- .../assets/{Dashboard-CyVZY-Lj.js => Dashboard-Bbh9RnDT.js} | 2 +- ...nalysisModal-Ca6cBH6E.js => DeepAnalysisModal-L9EkN490.js} | 2 +- .../{KeycapButton-B1_-eSeA.js => KeycapButton-DdWNfiky.js} | 2 +- frontend/dist/assets/{Login-AaBhF2Vi.js => Login-DV-gJNAt.js} | 2 +- frontend/dist/assets/{Logs-0I5VPDkH.js => Logs-CVA2ZaR8.js} | 2 +- .../assets/{MeshGraph-DIhPFkau.js => MeshGraph-BfYUTS82.js} | 2 +- ...mationCard-68hFKJ-B.js => NodeInformationCard-tOZNdmfP.js} | 2 +- .../assets/{PacketList-BfWkNwPj.js => PacketList-BJFBF77t.js} | 4 ++-- ...tObservatory-ChFmVrLE.js => PacketObservatory-DF8DSfgt.js} | 4 ++-- .../dist/assets/{Packets-BgwWZIr7.js => Packets-DNzcKpej.js} | 2 +- .../assets/{PageLayout-QhCLxU34.js => PageLayout-BWMUVZgC.js} | 2 +- ...athMapMapLibre-Copwhk_5.js => PathMapMapLibre-_vG9wINu.js} | 2 +- .../assets/{RoomServer-COraO77j.js => RoomServer-BvhmmII2.js} | 2 +- .../assets/{Sessions-C8xhZKXf.js => Sessions-DBjQm7_J.js} | 2 +- ...ignalIndicator-fAt1Aewy.js => SignalIndicator-Bdj3-1hL.js} | 2 +- .../assets/{Statistics-CvVaUNEa.js => Statistics-DEmWOGLC.js} | 2 +- .../dist/assets/{System-ClKsjWUq.js => System-RKAKlnZ6.js} | 2 +- .../assets/{Terminal-Bhtd_bQn.js => Terminal-DKt0bGFF.js} | 2 +- ...eRangeStepper-B5GfHny9.js => TimeRangeStepper-CsLZzi5t.js} | 2 +- .../assets/{chat-utils-DbM_TyxC.js => chat-utils-mqGCinix.js} | 2 +- ...mer-registry-KuOoZhsq.js => consumer-registry-BUFl6buY.js} | 2 +- .../dist/assets/{index-B2A_8ldG.css => index-BawBpZYt.css} | 2 +- frontend/dist/assets/{index-D7i6lQrq.js => index-CkRTgHHA.js} | 4 ++-- .../{link-scoring-oriFkjrN.js => link-scoring-C0BjaK96.js} | 2 +- .../dist/assets/{listbox-BG13Q7Di.js => listbox-DrzA7Ewq.js} | 2 +- .../assets/{node-types-CiI69Tya.js => node-types-DRVunROD.js} | 2 +- ...load-decoders-DjZO58V7.js => payload-decoders-_TRhCJrs.js} | 2 +- frontend/dist/assets/{ping-5xLx9WS1.js => ping-DPgnsJJf.js} | 2 +- .../assets/{primitives-YN2ynYwE.js => primitives-Bgn6Ik6L.js} | 2 +- .../dist/assets/{system-Circh3O5.js => system-OS35JnnX.js} | 2 +- ...seMapViewStore-1yyjXCM8.js => useMapViewStore-sFZdb1_p.js} | 2 +- ...PipelineStore-D3dOwDkO.js => usePipelineStore-CLEA3Bev.js} | 4 ++-- frontend/dist/index.html | 4 ++-- frontend/package.json | 2 +- 43 files changed, 49 insertions(+), 49 deletions(-) rename frontend/dist/assets/{AnalyzerFilterPanel-DfkXd7UH.js => AnalyzerFilterPanel-o1lp_Gs8.js} (99%) rename frontend/dist/assets/{AnimatedNumber-Dx2y1t97.js => AnimatedNumber-DACuG-ay.js} (89%) rename frontend/dist/assets/{ChatBubble-BkCCRzh5.js => ChatBubble-OmHlf-X1.js} (96%) rename frontend/dist/assets/{CollisionExplorerModal-B2vZL8RO.js => CollisionExplorerModal-BUHEIiWh.js} (99%) rename frontend/dist/assets/{Configuration-BqjgQq_Y.js => Configuration-CobIQjJB.js} (99%) rename frontend/dist/assets/{ConfirmModal-XwU3yUZY.js => ConfirmModal-B6Rz8ROW.js} (92%) rename frontend/dist/assets/{Contacts-Dlk8XXyy.js => Contacts-CcN2zB34.js} (94%) rename frontend/dist/assets/{ContactsMapMapLibre-CSieXgJu.js => ContactsMapMapLibre-BtIfp876.js} (99%) rename frontend/dist/assets/{Dashboard-CyVZY-Lj.js => Dashboard-Bbh9RnDT.js} (98%) rename frontend/dist/assets/{DeepAnalysisModal-Ca6cBH6E.js => DeepAnalysisModal-L9EkN490.js} (99%) rename frontend/dist/assets/{KeycapButton-B1_-eSeA.js => KeycapButton-DdWNfiky.js} (98%) rename frontend/dist/assets/{Login-AaBhF2Vi.js => Login-DV-gJNAt.js} (99%) rename frontend/dist/assets/{Logs-0I5VPDkH.js => Logs-CVA2ZaR8.js} (95%) rename frontend/dist/assets/{MeshGraph-DIhPFkau.js => MeshGraph-BfYUTS82.js} (99%) rename frontend/dist/assets/{NodeInformationCard-68hFKJ-B.js => NodeInformationCard-tOZNdmfP.js} (93%) rename frontend/dist/assets/{PacketList-BfWkNwPj.js => PacketList-BJFBF77t.js} (99%) rename frontend/dist/assets/{PacketObservatory-ChFmVrLE.js => PacketObservatory-DF8DSfgt.js} (99%) rename frontend/dist/assets/{Packets-BgwWZIr7.js => Packets-DNzcKpej.js} (93%) rename frontend/dist/assets/{PageLayout-QhCLxU34.js => PageLayout-BWMUVZgC.js} (93%) rename frontend/dist/assets/{PathMapMapLibre-Copwhk_5.js => PathMapMapLibre-_vG9wINu.js} (99%) rename frontend/dist/assets/{RoomServer-COraO77j.js => RoomServer-BvhmmII2.js} (98%) rename frontend/dist/assets/{Sessions-C8xhZKXf.js => Sessions-DBjQm7_J.js} (98%) rename frontend/dist/assets/{SignalIndicator-fAt1Aewy.js => SignalIndicator-Bdj3-1hL.js} (98%) rename frontend/dist/assets/{Statistics-CvVaUNEa.js => Statistics-DEmWOGLC.js} (99%) rename frontend/dist/assets/{System-ClKsjWUq.js => System-RKAKlnZ6.js} (99%) rename frontend/dist/assets/{Terminal-Bhtd_bQn.js => Terminal-DKt0bGFF.js} (99%) rename frontend/dist/assets/{TimeRangeStepper-B5GfHny9.js => TimeRangeStepper-CsLZzi5t.js} (97%) rename frontend/dist/assets/{chat-utils-DbM_TyxC.js => chat-utils-mqGCinix.js} (94%) rename frontend/dist/assets/{consumer-registry-KuOoZhsq.js => consumer-registry-BUFl6buY.js} (93%) rename frontend/dist/assets/{index-B2A_8ldG.css => index-BawBpZYt.css} (90%) rename frontend/dist/assets/{index-D7i6lQrq.js => index-CkRTgHHA.js} (77%) rename frontend/dist/assets/{link-scoring-oriFkjrN.js => link-scoring-C0BjaK96.js} (94%) rename frontend/dist/assets/{listbox-BG13Q7Di.js => listbox-DrzA7Ewq.js} (96%) rename frontend/dist/assets/{node-types-CiI69Tya.js => node-types-DRVunROD.js} (94%) rename frontend/dist/assets/{payload-decoders-DjZO58V7.js => payload-decoders-_TRhCJrs.js} (99%) rename frontend/dist/assets/{ping-5xLx9WS1.js => ping-DPgnsJJf.js} (94%) rename frontend/dist/assets/{primitives-YN2ynYwE.js => primitives-Bgn6Ik6L.js} (98%) rename frontend/dist/assets/{system-Circh3O5.js => system-OS35JnnX.js} (91%) rename frontend/dist/assets/{useMapViewStore-1yyjXCM8.js => useMapViewStore-sFZdb1_p.js} (93%) rename frontend/dist/assets/{usePipelineStore-D3dOwDkO.js => usePipelineStore-CLEA3Bev.js} (98%) diff --git a/frontend/dist/VERSION b/frontend/dist/VERSION index e122be0c..3e444d46 100644 --- a/frontend/dist/VERSION +++ b/frontend/dist/VERSION @@ -1 +1 @@ -0.9.285 +0.9.286 diff --git a/frontend/dist/assets/AnalyzerFilterPanel-DfkXd7UH.js b/frontend/dist/assets/AnalyzerFilterPanel-o1lp_Gs8.js similarity index 99% rename from frontend/dist/assets/AnalyzerFilterPanel-DfkXd7UH.js rename to frontend/dist/assets/AnalyzerFilterPanel-o1lp_Gs8.js index af3e23ee..11b8d770 100644 --- a/frontend/dist/assets/AnalyzerFilterPanel-DfkXd7UH.js +++ b/frontend/dist/assets/AnalyzerFilterPanel-o1lp_Gs8.js @@ -1 +1 @@ -import{H as e,B as t}from"./index-D7i6lQrq.js";import{r as n,j as s}from"./vendor-react-alRNW2nb.js";import{c as a}from"./node-types-CiI69Tya.js";import{aI as r,aJ as o,Y as l,X as i,R as d,at as c,j as u,a2 as m,au as h}from"./vendor-icons-TO0PZKGR.js";function p(){return{timeStart:null,timeEnd:null,deviceTypes:new Set,nodeIds:new Set,disabledNodeIds:new Set,nodeFilterMode:"source"}}function b(t,n,s,a){const r=function(t,n){const{timeStart:s,timeEnd:a,deviceTypes:r,nodeIds:o,disabledNodeIds:l,nodeFilterMode:i}=t,d=null!==s||null!==a,c=r.size>0;let u;if(l.size>0){u=new Set;for(const e of o)l.has(e)||u.add(e)}else u=o;const m=u.size>0;let h=null;if(m){h=new Set;for(const t of u)h.add(e(t))}return{hasTime:d,hasDevice:c,hasNode:m,tStart:s??n.start,tEnd:a??n.end,deviceTypes:r,effectiveNodeIds:u,nodeIdPrefixes:h,nodeFilterMode:i,needsDisambiguation:c||m}}(n,a);return r.hasTime||r.hasDevice||r.hasNode?t.filter(t=>function(t,n,s){if(n.hasTime&&(t.timestampn.tEnd))return!1;if(n.needsDisambiguation){const a=s(t);if(n.hasDevice&&!n.deviceTypes.has(a.type))return!1;if(n.hasNode)if("observed"===n.nodeFilterMode){let s=!1;if(a.hash&&n.effectiveNodeIds.has(a.hash)&&(s=!0),!s&&t.dst_hash&&(n.effectiveNodeIds.has(t.dst_hash)||n.nodeIdPrefixes.has(e(t.dst_hash)))&&(s=!0),!s){const e=t.forwarded_path??t.original_path;if(e&&Array.isArray(e))for(const t of e){const e=String(t).toUpperCase();if(n.nodeIdPrefixes.has(e)){s=!0;break}}}if(!s)return!1}else if(!a.hash||!n.effectiveNodeIds.has(a.hash))return!1}return!0}(t,r,s)):t}function x(e,t){const n=new Date(1e3*e),s=e=>e.toString().padStart(2,"0"),a=`${s(n.getHours())}:${s(n.getMinutes())}`;return t<24?a:`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][n.getMonth()]} ${n.getDate()} ${a}`}const f=[{type:"repeater",label:"Repeater",icon:d,buttonColor:"primary",iconColor:"text-sys-blue",hoverClass:"hover:border-sys-blue hover:text-sys-blue hover:!bg-transparent"},{type:"companion",label:"Companion",icon:c,buttonColor:"indigo",iconColor:"text-sys-indigo",hoverClass:"hover:border-sys-indigo hover:text-sys-indigo hover:!bg-transparent"},{type:"room_server",label:"Room",icon:u,buttonColor:"purple",iconColor:"text-sys-purple",hoverClass:"hover:border-sys-purple hover:text-sys-purple hover:!bg-transparent"},{type:"unknown",label:"Unknown",icon:m,buttonColor:"zinc",iconColor:"text-zinc-400",hoverClass:"hover:border-zinc-400 hover:text-zinc-400 hover:!bg-transparent"}],v=60,g=.005;function y({min:e,max:t,valueStart:a,valueEnd:r,onChange:o}){const l=n.useRef(null),[i,d]=n.useState(null),c=n.useRef({valueStart:a,valueEnd:r,min:e,max:t});c.current={valueStart:a,valueEnd:r,min:e,max:t};const u=n.useRef({offset:0,width:0}),m=t-e||1,h=m/3600,p=a??e,b=r??t,f=(p-e)/m*100,y=(b-e)/m*100,w=null!==a||null!==r,N=n.useCallback(e=>{const t=l.current.getBoundingClientRect(),n=Math.max(0,Math.min(1,(e-t.left)/t.width)),{min:s,max:a}=c.current;return Math.round(s+n*(a-s||1))},[]),j=n.useCallback((e,t)=>{t.preventDefault(),t.stopPropagation();const n=t.currentTarget;n.setPointerCapture(t.pointerId),d(e);const s=t=>{const n=N(t.clientX),{valueStart:s,valueEnd:a,min:r,max:l}=c.current,i=l-r||1;if("start"===e){const e=Math.min(n,(a??l)-v);o(e<=r+i*g?null:e,a)}else{const e=Math.max(n,(s??r)+v);o(s,e>=l-i*g?null:e)}},a=()=>{d(null),n.removeEventListener("pointermove",s),n.removeEventListener("pointerup",a),n.removeEventListener("pointercancel",a)};n.addEventListener("pointermove",s),n.addEventListener("pointerup",a),n.addEventListener("pointercancel",a)},[N,o]),C=n.useCallback(e=>{e.preventDefault(),e.stopPropagation();const t=e.currentTarget;t.setPointerCapture(e.pointerId),d("range");const n=c.current.valueStart??c.current.min,s=c.current.valueEnd??c.current.max;u.current={offset:N(e.clientX)-n,width:s-n};const a=e=>{const t=N(e.clientX),{min:n,max:s}=c.current,{offset:a,width:r}=u.current;let l=t-a;l=Math.max(n,Math.min(s-r,l));const i=l+r;o(Math.round(l)<=n?null:Math.round(l),Math.round(i)>=s?null:Math.round(i))},r=()=>{d(null),t.removeEventListener("pointermove",a),t.removeEventListener("pointerup",r),t.removeEventListener("pointercancel",r)};t.addEventListener("pointermove",a),t.addEventListener("pointerup",r),t.addEventListener("pointercancel",r)},[N,o]),k=n.useCallback(e=>{const t=N(e.clientX),{valueStart:n,valueEnd:s,min:a,max:r}=c.current,l=r-a||1,i=n??a,d=s??r;if(Math.abs(t-i)<=Math.abs(t-d)){const e=Math.min(t,d-v);o(e<=a+l*g?null:e,s)}else{const e=Math.max(t,i+v);o(n,e>=r-l*g?null:e)}},[N,o]),S=n.useCallback(()=>o(null,null),[o]),M=n.useCallback((e,t)=>{const n="ArrowRight"===t.key||"ArrowUp"===t.key?1:"ArrowLeft"===t.key||"ArrowDown"===t.key?-1:0;if(!n)return;t.preventDefault();const s=(t.shiftKey?.1:.01)*m,{valueStart:a,valueEnd:r,min:l,max:i}=c.current,d=i-l||1;if("start"===e){const e=Math.max(l,Math.min((a??l)+n*s,(r??i)-v));o(e<=l+d*g?null:e,r)}else{const e=Math.min(i,Math.max((r??i)+n*s,(a??l)+v));o(a,e>=i-d*g?null:e)}},[m,o]),I=e=>{const t=i===e;return["absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-1 h-4 rounded-full","before:content-[''] before:absolute before:-inset-x-3 before:-inset-y-1","touch-none outline-none",t?"cursor-grabbing":"cursor-ew-resize",t?"bg-sys-blue shadow-[0_0_8px_var(--sys-blue)] scale-x-150 z-20":("start"===e?null!==a:null!==r)?"bg-sys-blue shadow-[0_0_4px_var(--sys-blue)] hover:shadow-[0_0_8px_var(--sys-blue)] hover:scale-x-150 z-10":"bg-edge-subtle hover:bg-fg-muted hover:scale-x-150 z-10",t?"":"transition-[transform,box-shadow,background-color] duration-150 ease-out","focus-visible:ring-2 focus-visible:ring-sys-blue/50"].filter(Boolean).join(" ")};return s.jsxs("div",{className:"flex flex-col gap-0.5 min-w-[160px] sm:min-w-[220px]",children:[s.jsxs("div",{className:"flex items-center justify-between type-data-xs text-fg-muted tabular-nums select-none",children:[s.jsx("span",{className:w&&null!==a?"text-sys-blue":"",children:x(p,h)}),s.jsx("span",{className:w&&null!==r?"text-sys-blue":"",children:x(b,h)})]}),s.jsxs("div",{ref:l,className:"relative h-5 select-none",onPointerDown:k,onDoubleClick:S,children:[s.jsx("div",{className:"absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full bg-white/[0.06] pointer-events-none"}),w?s.jsx("div",{className:["group/band absolute inset-y-0 touch-none","range"===i?"cursor-grabbing":"cursor-grab"].join(" "),style:{left:`${f}%`,right:100-y+"%"},onPointerDown:C,children:s.jsx("div",{className:["absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full pointer-events-none transition-colors","range"===i?"bg-sys-blue/40":"bg-sys-blue/25 group-hover/band:bg-sys-blue/35"].join(" ")})}):s.jsx("div",{className:"absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full bg-white/[0.04] pointer-events-none"}),s.jsx("div",{role:"slider",tabIndex:0,"aria-label":"Range start","aria-valuenow":p,className:I("start"),style:{left:`${f}%`},onPointerDown:e=>j("start",e),onKeyDown:e=>M("start",e)}),s.jsx("div",{role:"slider",tabIndex:0,"aria-label":"Range end","aria-valuenow":b,className:I("end"),style:{left:`${y}%`},onPointerDown:e=>j("end",e),onKeyDown:e=>M("end",e)})]})]})}function w({parentStartTs:e,parentEndTs:d,neighbors:c,filter:u,onChange:m,scatterDotSize:p,onScatterDotSizeChange:b,scatterOpacity:x,onScatterOpacityChange:v}){const[g,w]=n.useState(""),[j,C]=n.useState(!1),k=n.useRef(null);n.useEffect(()=>{function e(e){k.current&&!k.current.contains(e.target)&&C(!1)}if(j)return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[j]);const S=n.useMemo(()=>Object.entries(c).map(([e,t])=>{const n=a(t);return{hash:e,name:t.name??t.node_name??e.slice(0,8),type:n.type,label:n.label}}).sort((e,t)=>e.name.localeCompare(t.name)),[c]),M=n.useMemo(()=>{if(!g)return S;const e=g.toLowerCase();return S.filter(t=>t.name.toLowerCase().includes(e)||t.hash.toLowerCase().includes(e))},[S,g]),I=null!==u.timeStart||null!==u.timeEnd||u.deviceTypes.size>0||u.nodeIds.size>0,E=n.useCallback((e,t)=>{m({...u,timeStart:e,timeEnd:t})},[u,m]),D=n.useCallback(e=>{const t=new Set(u.deviceTypes);t.has(e)?t.delete(e):t.add(e),m({...u,deviceTypes:t})},[u,m]),z=n.useCallback(e=>{const t=new Set(u.nodeIds);t.has(e)?t.delete(e):t.add(e),m({...u,nodeIds:t}),w("")},[u,m]),L=n.useCallback(e=>{const t=new Set(u.nodeIds);t.delete(e);const n=new Set(u.disabledNodeIds);n.delete(e),m({...u,nodeIds:t,disabledNodeIds:n})},[u,m]),T=n.useCallback(e=>{const t=new Set(u.disabledNodeIds);t.has(e)?t.delete(e):t.add(e),m({...u,disabledNodeIds:t})},[u,m]),_=n.useCallback(()=>{m({...u,nodeFilterMode:"source"===u.nodeFilterMode?"observed":"source"})},[u,m]),F=n.useCallback(()=>{m({timeStart:null,timeEnd:null,deviceTypes:new Set,nodeIds:new Set,disabledNodeIds:new Set,nodeFilterMode:"source"}),w("")},[m]),P=n.useMemo(()=>{const e=new Map;for(const t of u.nodeIds){const n=c[t];e.set(t,(null==n?void 0:n.name)??(null==n?void 0:n.node_name)??t.slice(0,8))}return e},[u.nodeIds,c]),R=!(!b||!v);return s.jsxs("div",{className:"flex flex-col gap-2 card-padding",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[R&&s.jsxs(s.Fragment,{children:[s.jsx(N,{icon:s.jsx(r,{className:"w-3 h-3"}),label:"Size",value:p??.8,onChange:b,min:.3,max:3,step:.1,format:e=>e.toFixed(1)}),s.jsx(N,{icon:s.jsx(o,{className:"w-3 h-3"}),label:"Opacity",value:x??50,onChange:v,min:5,max:100,step:5,format:e=>`${Math.round(e)}%`}),s.jsx("div",{className:"w-px h-4 bg-edge-subtle shrink-0 hidden sm:block"})]}),s.jsx("div",{className:"flex items-center gap-1.5 text-fg-muted shrink-0",children:s.jsx(l,{className:"w-3.5 h-3.5"})}),s.jsx("div",{className:"flex-1 min-w-[120px]",children:s.jsx(y,{min:e,max:d,valueStart:u.timeStart,valueEnd:u.timeEnd,onChange:E})}),I&&s.jsxs("button",{type:"button",onClick:F,className:"flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs text-fg-muted hover:text-fg-primary border border-edge-subtle hover:border-fg-muted/40 transition-colors shrink-0",title:"Clear all filters",children:[s.jsx(i,{className:"w-3 h-3"}),s.jsx("span",{className:"hidden sm:inline",children:"Clear"})]})]}),s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.jsx("div",{className:"flex items-center gap-1.5 overflow-x-auto pb-0.5 -mb-0.5 shrink-0",children:f.map(({type:e,label:n,icon:a,buttonColor:r,iconColor:o,hoverClass:l})=>{const i=u.deviceTypes.has(e);return s.jsxs(t,{color:i?r:"zinc",outline:!i,className:`!h-8 !py-0 ${i?"":l}`,onClick:()=>D(e),title:`Filter by ${n}`,children:[s.jsx(a,{"data-slot":"icon",className:i?"":o}),s.jsx("span",{className:"hidden sm:inline "+(i?"":"text-fg-muted"),children:n})]},e)})}),s.jsx("div",{className:"w-px h-4 bg-edge-subtle shrink-0 hidden md:block"}),s.jsxs("div",{className:"relative flex items-center gap-1.5 flex-1 min-w-[120px] sm:min-w-[180px] h-8 px-2 rounded-md border border-edge-subtle bg-white/[0.03] transition-colors focus-within:border-sys-blue",ref:k,children:[s.jsx(h,{className:"w-3 h-3 text-fg-muted/50 shrink-0"}),s.jsx("input",{type:"text",className:"flex-1 min-w-[60px] type-data-xs py-0.5 bg-transparent text-fg-secondary placeholder:text-fg-muted/40 border-none focus:outline-none",placeholder:"Search nodes...",value:g,onChange:e=>{w(e.target.value),C(!0)},onFocus:()=>C(!0)}),j&&M.length>0&&s.jsx("div",{className:"absolute top-full left-0 right-0 mt-1 z-[200] surface-popover border border-edge-subtle radius-inner max-h-48 overflow-y-auto",children:M.slice(0,20).map(e=>{const t=u.nodeIds.has(e.hash);return s.jsxs("button",{type:"button",onClick:()=>z(e.hash),className:`\n w-full flex items-center gap-2 px-2.5 py-1.5 type-data-xs text-left transition-colors\n ${t?"bg-sys-indigo/15 text-sys-indigo":"text-fg-secondary hover:bg-subtle-fill"}\n `,children:[s.jsx("span",{className:"flex-1 truncate",children:e.name}),s.jsx("span",{className:"text-fg-muted type-data-xs shrink-0",children:e.label})]},e.hash)})})]})]}),u.nodeIds.size>0&&s.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[Array.from(u.nodeIds).map(e=>{const t=u.disabledNodeIds.has(e);return s.jsxs("span",{role:"button",tabIndex:0,onClick:()=>T(e),onKeyDown:t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),T(e))},className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs border transition-colors select-none "+(t?"bg-zinc-500/10 text-fg-muted border-edge-subtle cursor-pointer hover:bg-zinc-500/15":"bg-sys-indigo/15 text-sys-indigo border-sys-indigo/25 cursor-pointer hover:bg-sys-indigo/25"),title:e,children:[P.get(e)??e.slice(0,8),s.jsx("button",{type:"button",onClick:t=>{t.stopPropagation(),L(e)},className:"hover:text-fg-primary transition-colors -mr-0.5",title:"Remove from filter",children:s.jsx(i,{className:"w-3 h-3"})})]},e)}),s.jsx("button",{type:"button",onClick:_,className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs border transition-colors "+("observed"===u.nodeFilterMode?"bg-sys-blue/15 text-sys-blue border-sys-blue/25 hover:bg-sys-blue/25":"bg-white/[0.04] text-fg-muted border-edge-subtle hover:text-fg-secondary hover:border-fg-muted/40"),title:"source"===u.nodeFilterMode?"Source Only — showing packets sent by selected node(s)":"Total Observed — showing all packets where selected node(s) appear (source, path, or destination)",children:"source"===u.nodeFilterMode?"Source Only":"Total Observed"})]})]})}const N=n.memo(function({icon:e,label:t,value:n,onChange:a,min:r,max:o,step:l,format:i}){return s.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[s.jsxs("div",{className:"flex items-center gap-1.5 text-fg-muted shrink-0",children:[e,s.jsx("span",{className:"type-data-xs font-medium hidden sm:inline",children:t})]}),s.jsx("input",{type:"range",min:r,max:o,step:l,value:n,onChange:e=>a(parseFloat(e.target.value)),className:"flex-1 h-1 min-w-[60px] bg-subtle-fill rounded appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-2.5 [&::-webkit-slider-thumb]:h-2.5 [&::-webkit-slider-thumb]:bg-sys-blue [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:cursor-pointer"}),s.jsx("span",{className:"type-data-xs text-fg-secondary tabular-nums shrink-0 w-8 text-right",children:i?i(n):n})]})});export{w as A,b as a,p as c}; +import{H as e,B as t}from"./index-CkRTgHHA.js";import{r as n,j as s}from"./vendor-react-alRNW2nb.js";import{c as a}from"./node-types-DRVunROD.js";import{aI as r,aJ as o,Y as l,X as i,R as d,at as c,j as u,a2 as m,au as h}from"./vendor-icons-TO0PZKGR.js";function p(){return{timeStart:null,timeEnd:null,deviceTypes:new Set,nodeIds:new Set,disabledNodeIds:new Set,nodeFilterMode:"source"}}function b(t,n,s,a){const r=function(t,n){const{timeStart:s,timeEnd:a,deviceTypes:r,nodeIds:o,disabledNodeIds:l,nodeFilterMode:i}=t,d=null!==s||null!==a,c=r.size>0;let u;if(l.size>0){u=new Set;for(const e of o)l.has(e)||u.add(e)}else u=o;const m=u.size>0;let h=null;if(m){h=new Set;for(const t of u)h.add(e(t))}return{hasTime:d,hasDevice:c,hasNode:m,tStart:s??n.start,tEnd:a??n.end,deviceTypes:r,effectiveNodeIds:u,nodeIdPrefixes:h,nodeFilterMode:i,needsDisambiguation:c||m}}(n,a);return r.hasTime||r.hasDevice||r.hasNode?t.filter(t=>function(t,n,s){if(n.hasTime&&(t.timestampn.tEnd))return!1;if(n.needsDisambiguation){const a=s(t);if(n.hasDevice&&!n.deviceTypes.has(a.type))return!1;if(n.hasNode)if("observed"===n.nodeFilterMode){let s=!1;if(a.hash&&n.effectiveNodeIds.has(a.hash)&&(s=!0),!s&&t.dst_hash&&(n.effectiveNodeIds.has(t.dst_hash)||n.nodeIdPrefixes.has(e(t.dst_hash)))&&(s=!0),!s){const e=t.forwarded_path??t.original_path;if(e&&Array.isArray(e))for(const t of e){const e=String(t).toUpperCase();if(n.nodeIdPrefixes.has(e)){s=!0;break}}}if(!s)return!1}else if(!a.hash||!n.effectiveNodeIds.has(a.hash))return!1}return!0}(t,r,s)):t}function x(e,t){const n=new Date(1e3*e),s=e=>e.toString().padStart(2,"0"),a=`${s(n.getHours())}:${s(n.getMinutes())}`;return t<24?a:`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][n.getMonth()]} ${n.getDate()} ${a}`}const f=[{type:"repeater",label:"Repeater",icon:d,buttonColor:"primary",iconColor:"text-sys-blue",hoverClass:"hover:border-sys-blue hover:text-sys-blue hover:!bg-transparent"},{type:"companion",label:"Companion",icon:c,buttonColor:"indigo",iconColor:"text-sys-indigo",hoverClass:"hover:border-sys-indigo hover:text-sys-indigo hover:!bg-transparent"},{type:"room_server",label:"Room",icon:u,buttonColor:"purple",iconColor:"text-sys-purple",hoverClass:"hover:border-sys-purple hover:text-sys-purple hover:!bg-transparent"},{type:"unknown",label:"Unknown",icon:m,buttonColor:"zinc",iconColor:"text-zinc-400",hoverClass:"hover:border-zinc-400 hover:text-zinc-400 hover:!bg-transparent"}],v=60,g=.005;function y({min:e,max:t,valueStart:a,valueEnd:r,onChange:o}){const l=n.useRef(null),[i,d]=n.useState(null),c=n.useRef({valueStart:a,valueEnd:r,min:e,max:t});c.current={valueStart:a,valueEnd:r,min:e,max:t};const u=n.useRef({offset:0,width:0}),m=t-e||1,h=m/3600,p=a??e,b=r??t,f=(p-e)/m*100,y=(b-e)/m*100,w=null!==a||null!==r,N=n.useCallback(e=>{const t=l.current.getBoundingClientRect(),n=Math.max(0,Math.min(1,(e-t.left)/t.width)),{min:s,max:a}=c.current;return Math.round(s+n*(a-s||1))},[]),j=n.useCallback((e,t)=>{t.preventDefault(),t.stopPropagation();const n=t.currentTarget;n.setPointerCapture(t.pointerId),d(e);const s=t=>{const n=N(t.clientX),{valueStart:s,valueEnd:a,min:r,max:l}=c.current,i=l-r||1;if("start"===e){const e=Math.min(n,(a??l)-v);o(e<=r+i*g?null:e,a)}else{const e=Math.max(n,(s??r)+v);o(s,e>=l-i*g?null:e)}},a=()=>{d(null),n.removeEventListener("pointermove",s),n.removeEventListener("pointerup",a),n.removeEventListener("pointercancel",a)};n.addEventListener("pointermove",s),n.addEventListener("pointerup",a),n.addEventListener("pointercancel",a)},[N,o]),C=n.useCallback(e=>{e.preventDefault(),e.stopPropagation();const t=e.currentTarget;t.setPointerCapture(e.pointerId),d("range");const n=c.current.valueStart??c.current.min,s=c.current.valueEnd??c.current.max;u.current={offset:N(e.clientX)-n,width:s-n};const a=e=>{const t=N(e.clientX),{min:n,max:s}=c.current,{offset:a,width:r}=u.current;let l=t-a;l=Math.max(n,Math.min(s-r,l));const i=l+r;o(Math.round(l)<=n?null:Math.round(l),Math.round(i)>=s?null:Math.round(i))},r=()=>{d(null),t.removeEventListener("pointermove",a),t.removeEventListener("pointerup",r),t.removeEventListener("pointercancel",r)};t.addEventListener("pointermove",a),t.addEventListener("pointerup",r),t.addEventListener("pointercancel",r)},[N,o]),k=n.useCallback(e=>{const t=N(e.clientX),{valueStart:n,valueEnd:s,min:a,max:r}=c.current,l=r-a||1,i=n??a,d=s??r;if(Math.abs(t-i)<=Math.abs(t-d)){const e=Math.min(t,d-v);o(e<=a+l*g?null:e,s)}else{const e=Math.max(t,i+v);o(n,e>=r-l*g?null:e)}},[N,o]),S=n.useCallback(()=>o(null,null),[o]),M=n.useCallback((e,t)=>{const n="ArrowRight"===t.key||"ArrowUp"===t.key?1:"ArrowLeft"===t.key||"ArrowDown"===t.key?-1:0;if(!n)return;t.preventDefault();const s=(t.shiftKey?.1:.01)*m,{valueStart:a,valueEnd:r,min:l,max:i}=c.current,d=i-l||1;if("start"===e){const e=Math.max(l,Math.min((a??l)+n*s,(r??i)-v));o(e<=l+d*g?null:e,r)}else{const e=Math.min(i,Math.max((r??i)+n*s,(a??l)+v));o(a,e>=i-d*g?null:e)}},[m,o]),I=e=>{const t=i===e;return["absolute top-1/2 -translate-y-1/2 -translate-x-1/2 w-1 h-4 rounded-full","before:content-[''] before:absolute before:-inset-x-3 before:-inset-y-1","touch-none outline-none",t?"cursor-grabbing":"cursor-ew-resize",t?"bg-sys-blue shadow-[0_0_8px_var(--sys-blue)] scale-x-150 z-20":("start"===e?null!==a:null!==r)?"bg-sys-blue shadow-[0_0_4px_var(--sys-blue)] hover:shadow-[0_0_8px_var(--sys-blue)] hover:scale-x-150 z-10":"bg-edge-subtle hover:bg-fg-muted hover:scale-x-150 z-10",t?"":"transition-[transform,box-shadow,background-color] duration-150 ease-out","focus-visible:ring-2 focus-visible:ring-sys-blue/50"].filter(Boolean).join(" ")};return s.jsxs("div",{className:"flex flex-col gap-0.5 min-w-[160px] sm:min-w-[220px]",children:[s.jsxs("div",{className:"flex items-center justify-between type-data-xs text-fg-muted tabular-nums select-none",children:[s.jsx("span",{className:w&&null!==a?"text-sys-blue":"",children:x(p,h)}),s.jsx("span",{className:w&&null!==r?"text-sys-blue":"",children:x(b,h)})]}),s.jsxs("div",{ref:l,className:"relative h-5 select-none",onPointerDown:k,onDoubleClick:S,children:[s.jsx("div",{className:"absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full bg-white/[0.06] pointer-events-none"}),w?s.jsx("div",{className:["group/band absolute inset-y-0 touch-none","range"===i?"cursor-grabbing":"cursor-grab"].join(" "),style:{left:`${f}%`,right:100-y+"%"},onPointerDown:C,children:s.jsx("div",{className:["absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full pointer-events-none transition-colors","range"===i?"bg-sys-blue/40":"bg-sys-blue/25 group-hover/band:bg-sys-blue/35"].join(" ")})}):s.jsx("div",{className:"absolute inset-x-0 top-1/2 -translate-y-1/2 h-1.5 rounded-full bg-white/[0.04] pointer-events-none"}),s.jsx("div",{role:"slider",tabIndex:0,"aria-label":"Range start","aria-valuenow":p,className:I("start"),style:{left:`${f}%`},onPointerDown:e=>j("start",e),onKeyDown:e=>M("start",e)}),s.jsx("div",{role:"slider",tabIndex:0,"aria-label":"Range end","aria-valuenow":b,className:I("end"),style:{left:`${y}%`},onPointerDown:e=>j("end",e),onKeyDown:e=>M("end",e)})]})]})}function w({parentStartTs:e,parentEndTs:d,neighbors:c,filter:u,onChange:m,scatterDotSize:p,onScatterDotSizeChange:b,scatterOpacity:x,onScatterOpacityChange:v}){const[g,w]=n.useState(""),[j,C]=n.useState(!1),k=n.useRef(null);n.useEffect(()=>{function e(e){k.current&&!k.current.contains(e.target)&&C(!1)}if(j)return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[j]);const S=n.useMemo(()=>Object.entries(c).map(([e,t])=>{const n=a(t);return{hash:e,name:t.name??t.node_name??e.slice(0,8),type:n.type,label:n.label}}).sort((e,t)=>e.name.localeCompare(t.name)),[c]),M=n.useMemo(()=>{if(!g)return S;const e=g.toLowerCase();return S.filter(t=>t.name.toLowerCase().includes(e)||t.hash.toLowerCase().includes(e))},[S,g]),I=null!==u.timeStart||null!==u.timeEnd||u.deviceTypes.size>0||u.nodeIds.size>0,E=n.useCallback((e,t)=>{m({...u,timeStart:e,timeEnd:t})},[u,m]),D=n.useCallback(e=>{const t=new Set(u.deviceTypes);t.has(e)?t.delete(e):t.add(e),m({...u,deviceTypes:t})},[u,m]),z=n.useCallback(e=>{const t=new Set(u.nodeIds);t.has(e)?t.delete(e):t.add(e),m({...u,nodeIds:t}),w("")},[u,m]),L=n.useCallback(e=>{const t=new Set(u.nodeIds);t.delete(e);const n=new Set(u.disabledNodeIds);n.delete(e),m({...u,nodeIds:t,disabledNodeIds:n})},[u,m]),T=n.useCallback(e=>{const t=new Set(u.disabledNodeIds);t.has(e)?t.delete(e):t.add(e),m({...u,disabledNodeIds:t})},[u,m]),_=n.useCallback(()=>{m({...u,nodeFilterMode:"source"===u.nodeFilterMode?"observed":"source"})},[u,m]),F=n.useCallback(()=>{m({timeStart:null,timeEnd:null,deviceTypes:new Set,nodeIds:new Set,disabledNodeIds:new Set,nodeFilterMode:"source"}),w("")},[m]),P=n.useMemo(()=>{const e=new Map;for(const t of u.nodeIds){const n=c[t];e.set(t,(null==n?void 0:n.name)??(null==n?void 0:n.node_name)??t.slice(0,8))}return e},[u.nodeIds,c]),R=!(!b||!v);return s.jsxs("div",{className:"flex flex-col gap-2 card-padding",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[R&&s.jsxs(s.Fragment,{children:[s.jsx(N,{icon:s.jsx(r,{className:"w-3 h-3"}),label:"Size",value:p??.8,onChange:b,min:.3,max:3,step:.1,format:e=>e.toFixed(1)}),s.jsx(N,{icon:s.jsx(o,{className:"w-3 h-3"}),label:"Opacity",value:x??50,onChange:v,min:5,max:100,step:5,format:e=>`${Math.round(e)}%`}),s.jsx("div",{className:"w-px h-4 bg-edge-subtle shrink-0 hidden sm:block"})]}),s.jsx("div",{className:"flex items-center gap-1.5 text-fg-muted shrink-0",children:s.jsx(l,{className:"w-3.5 h-3.5"})}),s.jsx("div",{className:"flex-1 min-w-[120px]",children:s.jsx(y,{min:e,max:d,valueStart:u.timeStart,valueEnd:u.timeEnd,onChange:E})}),I&&s.jsxs("button",{type:"button",onClick:F,className:"flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs text-fg-muted hover:text-fg-primary border border-edge-subtle hover:border-fg-muted/40 transition-colors shrink-0",title:"Clear all filters",children:[s.jsx(i,{className:"w-3 h-3"}),s.jsx("span",{className:"hidden sm:inline",children:"Clear"})]})]}),s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[s.jsx("div",{className:"flex items-center gap-1.5 overflow-x-auto pb-0.5 -mb-0.5 shrink-0",children:f.map(({type:e,label:n,icon:a,buttonColor:r,iconColor:o,hoverClass:l})=>{const i=u.deviceTypes.has(e);return s.jsxs(t,{color:i?r:"zinc",outline:!i,className:`!h-8 !py-0 ${i?"":l}`,onClick:()=>D(e),title:`Filter by ${n}`,children:[s.jsx(a,{"data-slot":"icon",className:i?"":o}),s.jsx("span",{className:"hidden sm:inline "+(i?"":"text-fg-muted"),children:n})]},e)})}),s.jsx("div",{className:"w-px h-4 bg-edge-subtle shrink-0 hidden md:block"}),s.jsxs("div",{className:"relative flex items-center gap-1.5 flex-1 min-w-[120px] sm:min-w-[180px] h-8 px-2 rounded-md border border-edge-subtle bg-white/[0.03] transition-colors focus-within:border-sys-blue",ref:k,children:[s.jsx(h,{className:"w-3 h-3 text-fg-muted/50 shrink-0"}),s.jsx("input",{type:"text",className:"flex-1 min-w-[60px] type-data-xs py-0.5 bg-transparent text-fg-secondary placeholder:text-fg-muted/40 border-none focus:outline-none",placeholder:"Search nodes...",value:g,onChange:e=>{w(e.target.value),C(!0)},onFocus:()=>C(!0)}),j&&M.length>0&&s.jsx("div",{className:"absolute top-full left-0 right-0 mt-1 z-[200] surface-popover border border-edge-subtle radius-inner max-h-48 overflow-y-auto",children:M.slice(0,20).map(e=>{const t=u.nodeIds.has(e.hash);return s.jsxs("button",{type:"button",onClick:()=>z(e.hash),className:`\n w-full flex items-center gap-2 px-2.5 py-1.5 type-data-xs text-left transition-colors\n ${t?"bg-sys-indigo/15 text-sys-indigo":"text-fg-secondary hover:bg-subtle-fill"}\n `,children:[s.jsx("span",{className:"flex-1 truncate",children:e.name}),s.jsx("span",{className:"text-fg-muted type-data-xs shrink-0",children:e.label})]},e.hash)})})]})]}),u.nodeIds.size>0&&s.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[Array.from(u.nodeIds).map(e=>{const t=u.disabledNodeIds.has(e);return s.jsxs("span",{role:"button",tabIndex:0,onClick:()=>T(e),onKeyDown:t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),T(e))},className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs border transition-colors select-none "+(t?"bg-zinc-500/10 text-fg-muted border-edge-subtle cursor-pointer hover:bg-zinc-500/15":"bg-sys-indigo/15 text-sys-indigo border-sys-indigo/25 cursor-pointer hover:bg-sys-indigo/25"),title:e,children:[P.get(e)??e.slice(0,8),s.jsx("button",{type:"button",onClick:t=>{t.stopPropagation(),L(e)},className:"hover:text-fg-primary transition-colors -mr-0.5",title:"Remove from filter",children:s.jsx(i,{className:"w-3 h-3"})})]},e)}),s.jsx("button",{type:"button",onClick:_,className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-full type-data-xs border transition-colors "+("observed"===u.nodeFilterMode?"bg-sys-blue/15 text-sys-blue border-sys-blue/25 hover:bg-sys-blue/25":"bg-white/[0.04] text-fg-muted border-edge-subtle hover:text-fg-secondary hover:border-fg-muted/40"),title:"source"===u.nodeFilterMode?"Source Only — showing packets sent by selected node(s)":"Total Observed — showing all packets where selected node(s) appear (source, path, or destination)",children:"source"===u.nodeFilterMode?"Source Only":"Total Observed"})]})]})}const N=n.memo(function({icon:e,label:t,value:n,onChange:a,min:r,max:o,step:l,format:i}){return s.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[s.jsxs("div",{className:"flex items-center gap-1.5 text-fg-muted shrink-0",children:[e,s.jsx("span",{className:"type-data-xs font-medium hidden sm:inline",children:t})]}),s.jsx("input",{type:"range",min:r,max:o,step:l,value:n,onChange:e=>a(parseFloat(e.target.value)),className:"flex-1 h-1 min-w-[60px] bg-subtle-fill rounded appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-2.5 [&::-webkit-slider-thumb]:h-2.5 [&::-webkit-slider-thumb]:bg-sys-blue [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:cursor-pointer"}),s.jsx("span",{className:"type-data-xs text-fg-secondary tabular-nums shrink-0 w-8 text-right",children:i?i(n):n})]})});export{w as A,b as a,p as c}; diff --git a/frontend/dist/assets/AnimatedNumber-Dx2y1t97.js b/frontend/dist/assets/AnimatedNumber-DACuG-ay.js similarity index 89% rename from frontend/dist/assets/AnimatedNumber-Dx2y1t97.js rename to frontend/dist/assets/AnimatedNumber-DACuG-ay.js index 83beccd7..85d99bf5 100644 --- a/frontend/dist/assets/AnimatedNumber-Dx2y1t97.js +++ b/frontend/dist/assets/AnimatedNumber-DACuG-ay.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{a as r}from"./vendor-motion-DNp0Qg4F.js";import{a$ as o,b0 as t}from"./index-D7i6lQrq.js";const a=e.memo(function({value:a,format:i,prefix:n,suffix:f,className:m,priority:c="medium"}){const[u,d]=e.useState(!1),[l,p]=e.useState(a);e.useEffect(()=>o(()=>{d(!0),p(0)},c),[c]),e.useEffect(()=>{u&&p(a)},[u,a]);const x=`${n??""}${a.toLocaleString(void 0,i)}${f??""}`;return u?s.jsx(r,{className:`${m??""} overflow-hidden`,format:i,prefix:n,suffix:f,transition:t.numberTicker,children:l}):s.jsx("span",{className:m,children:x})});export{a as A}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{a as r}from"./vendor-motion-DNp0Qg4F.js";import{a$ as o,b0 as t}from"./index-CkRTgHHA.js";const a=e.memo(function({value:a,format:i,prefix:n,suffix:f,className:m,priority:c="medium"}){const[u,d]=e.useState(!1),[l,p]=e.useState(a);e.useEffect(()=>o(()=>{d(!0),p(0)},c),[c]),e.useEffect(()=>{u&&p(a)},[u,a]);const x=`${n??""}${a.toLocaleString(void 0,i)}${f??""}`;return u?s.jsx(r,{className:`${m??""} overflow-hidden`,format:i,prefix:n,suffix:f,transition:t.numberTicker,children:l}):s.jsx("span",{className:m,children:x})});export{a as A}; diff --git a/frontend/dist/assets/ChatBubble-BkCCRzh5.js b/frontend/dist/assets/ChatBubble-OmHlf-X1.js similarity index 96% rename from frontend/dist/assets/ChatBubble-BkCCRzh5.js rename to frontend/dist/assets/ChatBubble-OmHlf-X1.js index b52b5e2c..99dc9a51 100644 --- a/frontend/dist/assets/ChatBubble-BkCCRzh5.js +++ b/frontend/dist/assets/ChatBubble-OmHlf-X1.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{e as a,g as l,a as r,b as i,f as n}from"./chat-utils-DbM_TyxC.js";const c=e.memo(function({senderName:e,text:c,timestamp:d,nameAccessory:m,bubbleAccessory:x,className:o}){const{emoji:u,cleanName:f}=a(e),p=l(f),g=r(e);return s.jsxs("div",{className:t("group flex items-start gap-3 w-full",o),children:[s.jsxs("div",{className:"flex-shrink-0 w-9 flex flex-col items-center gap-1",children:[s.jsx("div",{className:t("w-9 h-9 rounded-full flex items-center justify-center","shadow-md ring-1 ring-edge-subtle",u?"text-lg":"text-white text-[13px] font-bold tracking-tight"),style:{backgroundColor:p},children:u||g}),s.jsx("span",{className:"text-xs text-fg-muted tabular-nums h-4 leading-4",children:i(d)})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 h-5 mb-1",children:[s.jsx("span",{className:"text-[13px] font-medium truncate",style:{color:p,lineHeight:"20px"},children:f}),m]}),s.jsxs("div",{className:"flex items-end gap-1.5",children:[s.jsx("div",{className:t("inline-block px-3.5 py-2.5 max-w-full","rounded-2xl rounded-tl-md","bg-[#007AFF]"),children:s.jsx("p",{className:"text-sm text-white leading-relaxed tracking-wide whitespace-pre-wrap break-words",children:n(c)})}),x]})]})]})});function d({text:e}){return s.jsx("div",{className:"flex justify-center my-1",children:s.jsx("span",{className:t("px-3 py-1 rounded-full","bg-subtle-fill text-[11px] text-fg-muted/80 font-medium","ring-1 ring-edge-subtle"),children:e})})}export{c as C,d as S}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{e as a,g as l,a as r,b as i,f as n}from"./chat-utils-mqGCinix.js";const c=e.memo(function({senderName:e,text:c,timestamp:d,nameAccessory:m,bubbleAccessory:x,className:o}){const{emoji:u,cleanName:f}=a(e),p=l(f),g=r(e);return s.jsxs("div",{className:t("group flex items-start gap-3 w-full",o),children:[s.jsxs("div",{className:"flex-shrink-0 w-9 flex flex-col items-center gap-1",children:[s.jsx("div",{className:t("w-9 h-9 rounded-full flex items-center justify-center","shadow-md ring-1 ring-edge-subtle",u?"text-lg":"text-white text-[13px] font-bold tracking-tight"),style:{backgroundColor:p},children:u||g}),s.jsx("span",{className:"text-xs text-fg-muted tabular-nums h-4 leading-4",children:i(d)})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 h-5 mb-1",children:[s.jsx("span",{className:"text-[13px] font-medium truncate",style:{color:p,lineHeight:"20px"},children:f}),m]}),s.jsxs("div",{className:"flex items-end gap-1.5",children:[s.jsx("div",{className:t("inline-block px-3.5 py-2.5 max-w-full","rounded-2xl rounded-tl-md","bg-[#007AFF]"),children:s.jsx("p",{className:"text-sm text-white leading-relaxed tracking-wide whitespace-pre-wrap break-words",children:n(c)})}),x]})]})]})});function d({text:e}){return s.jsx("div",{className:"flex justify-center my-1",children:s.jsx("span",{className:t("px-3 py-1 rounded-full","bg-subtle-fill text-[11px] text-fg-muted/80 font-medium","ring-1 ring-edge-subtle"),children:e})})}export{c as C,d as S}; diff --git a/frontend/dist/assets/CollisionExplorerModal-B2vZL8RO.js b/frontend/dist/assets/CollisionExplorerModal-BUHEIiWh.js similarity index 99% rename from frontend/dist/assets/CollisionExplorerModal-B2vZL8RO.js rename to frontend/dist/assets/CollisionExplorerModal-BUHEIiWh.js index 86a500f5..7c234400 100644 --- a/frontend/dist/assets/CollisionExplorerModal-B2vZL8RO.js +++ b/frontend/dist/assets/CollisionExplorerModal-BUHEIiWh.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{M as t,S as a,L as i,a as n}from"./maplibre-gl-BwLPRSIs.js";import{c as l}from"./vendor-core-FtpmsTnh.js";import{p as o,al as r,r as d,Y as c,_ as u,ab as h,h as m}from"./index-D7i6lQrq.js";import{u as x,B as p}from"./BasemapLayer-CSqjQAiA.js";import{a3 as g,a1 as f,aj as v,a as b,o as j,j as y,at as N}from"./vendor-icons-TO0PZKGR.js";const w={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"};function H({node:t,isHovered:a,onHover:i}){const[n,o]=e.useState(!1),r=e.useCallback(e=>{var s,a;e.stopPropagation(),s=t.hash,(null==(a=navigator.clipboard)?void 0:a.writeText)&&navigator.clipboard.writeText(s).catch(()=>{}),o(!0),setTimeout(()=>o(!1),2e3)},[t.hash]),d=t.contactType.toLowerCase(),c=d.includes("room")||d.includes("server");let u=v,h="text-sys-blue";return c?(u=y,h="text-signal-fair"):"companion"===d||"client"===d?(u=N,h="text-fg-muted"):t.isNeighbor&&(h="text-sys-green"),s.jsxs("div",{className:l("flex items-center gap-3 px-3 py-2.5 radius-inner transition-base cursor-pointer",a?"bg-sys-blue/10":"hover:bg-subtle-fill"),onMouseEnter:()=>i(t.hash),onMouseLeave:()=>i(null),children:[s.jsx(u,{className:l("w-4 h-4 flex-shrink-0",h)}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"type-label text-fg-primary truncate",children:t.name}),t.isNeighbor&&s.jsx(m,{color:"green",compact:!0,children:"NBR"}),t.isRepeater&&s.jsx(m,{color:"zinc",compact:!0,children:"RPT"}),t.isHub&&s.jsx(m,{color:"indigo",compact:!0,children:"HUB"})]}),s.jsxs("button",{onClick:r,className:l("mt-1 inline-flex items-center gap-1 type-data-xs px-1.5 py-0.5 rounded","border transition-all cursor-pointer",n?"border-sys-green/50 bg-sys-green/10 text-sys-green":"border-edge-subtle bg-subtle/50 text-fg-muted hover:border-edge-strong"),title:`Copy: ${t.hash}`,children:[t.hash.slice(0,12),"…",n?s.jsx(b,{className:"w-2.5 h-2.5"}):s.jsx(j,{className:"w-2.5 h-2.5 opacity-50"})]})]})]})}function C({nodes:o,hoveredHash:r,onHover:d}){const c=x(),u=e.useRef(null),g=h(),[v,b]=e.useState(!1),j=e.useMemo(()=>o.filter(e=>null!=e.latitude&&null!=e.longitude&&(0!==e.latitude||0!==e.longitude)),[o]),y=e.useMemo(()=>{if(0===j.length)return null;let e=1/0,s=-1/0,t=1/0,a=-1/0;for(const i of j)e=Math.min(e,i.longitude),s=Math.max(s,i.longitude),t=Math.min(t,i.latitude),a=Math.max(a,i.latitude);if(a-t<.01){const e=(a+t)/2;t=e-.005,a=e+.005}if(s-e<.01){const t=(s+e)/2;e=t-.005,s=t+.005}return[[e,t],[s,a]]},[j]),N=e.useMemo(()=>y?{longitude:(y[0][0]+y[1][0])/2,latitude:(y[0][1]+y[1][1])/2}:{longitude:0,latitude:0},[y]),H=e.useMemo(()=>{if(j.length<2)return null;const e=[];for(let s=0;s{var e;const s=null==(e=u.current)?void 0:e.getMap();s&&y?(s.fitBounds(y,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:13,duration:0}),setTimeout(()=>b(!0),50)):b(!0)},[y]),M=g&&v;return 0===j.length?s.jsx("div",{className:"h-full flex items-center justify-center bg-subtle/30 radius-inner",children:s.jsxs("div",{className:"text-center text-fg-secondary p-4",children:[s.jsx(f,{className:"w-8 h-8 mx-auto mb-2 opacity-40"}),s.jsx("p",{className:"text-sm",children:"No location data available"})]})}):s.jsxs("div",{className:"h-full w-full relative radius-inner overflow-hidden bg-elevated",children:[s.jsx("div",{className:l("absolute inset-0 flex items-center justify-center z-10","transition-opacity duration-200 pointer-events-none",M?"opacity-0":"opacity-100 bg-elevated"),children:s.jsx("div",{className:"w-5 h-5 border-2 border-text-muted/30 border-t-text-muted rounded-full animate-spin"})}),s.jsx("div",{className:l("h-full w-full transition-opacity duration-200",M?"opacity-100":"opacity-0"),children:s.jsxs(t,{ref:u,initialViewState:{longitude:N.longitude,latitude:N.latitude,zoom:10},style:{height:"100%",width:"100%"},mapStyle:w,attributionControl:!1,onLoad:C,children:[s.jsx(p,{mode:c}),H&&s.jsx(a,{id:"collision-edges",type:"geojson",data:H,children:s.jsx(i,{id:"collision-edges-line",type:"line",paint:{"line-color":"#3B3F4A","line-width":2,"line-opacity":.8},layout:{"line-cap":"round","line-join":"round"}})}),j.map(e=>{const t=e.hash===r,a=e.hash.startsWith("0x")?e.hash.slice(2,4).toUpperCase():e.hash.slice(0,2).toUpperCase();return s.jsx(n,{longitude:e.longitude,latitude:e.latitude,anchor:"center",children:s.jsx("div",{className:"cursor-pointer transition-all duration-150",onMouseEnter:()=>d(e.hash),onMouseLeave:()=>d(null),style:{pointerEvents:"auto"},children:s.jsxs(m,{color:"amber",filled:!0,className:"type-data-xs shadow-lg",children:[a,t&&s.jsx("span",{className:"ml-1 opacity-75 font-sans",children:e.name})]})})},e.hash)})]})})]})}const M=e.memo(function({isOpen:t,prefix:a,candidateHashes:i,onClose:n}){const l=o(),h=r(),m=d(),[x,p]=e.useState(null),f=e.useMemo(()=>new Set(m.map(e=>e.hash)),[m]),v=(null==l?void 0:l.neighbors)??{},b=e.useMemo(()=>i.map(e=>{var s;const t=(e=>v[e]?v[e]:!e.startsWith("0x")&&v["0x"+e]?v["0x"+e]:e.startsWith("0x")&&v[e.slice(2)]?v[e.slice(2)]:void 0)(e);return{hash:e,name:(null==t?void 0:t.node_name)||(null==t?void 0:t.name)||`Unknown (${e.slice(0,8)}…)`,contactType:(null==t?void 0:t.contact_type)||"",isRepeater:(null==t?void 0:t.is_repeater)||"repeater"===(null==(s=null==t?void 0:t.contact_type)?void 0:s.toLowerCase())||!1,isNeighbor:f.has(e)||f.has("0x"+e)||f.has(e.replace(/^0x/,"")),isHub:h.has(e),latitude:null==t?void 0:t.latitude,longitude:null==t?void 0:t.longitude}}).sort((e,s)=>e.isNeighbor!==s.isNeighbor?e.isNeighbor?-1:1:e.isHub!==s.isHub?e.isHub?-1:1:e.name.localeCompare(s.name)),[i,v,f,h]),j=e.useMemo(()=>b.some(e=>null!=e.latitude&&null!=e.longitude&&(0!==e.latitude||0!==e.longitude)),[b]),y=e.useCallback(e=>{p(e)},[]),N=j?"4xl":"lg";return t?s.jsxs(c,{open:t,onClose:n,size:N,motionPlus:!0,className:j?"sm:h-[500px] sm:max-h-[600px]":"",children:[s.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-edge-subtle",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx("div",{className:"p-2 radius-inner bg-signal-fair/10",children:s.jsx(g,{className:"w-5 h-5 text-signal-fair"})}),s.jsxs("div",{children:[s.jsxs("div",{className:"type-micro",children:["Prefix Collision: ",s.jsx("span",{className:"font-mono text-sys-blue",children:a})]}),s.jsxs("p",{className:"text-xs text-fg-secondary",children:[b.length," nodes share this prefix"]})]})]}),s.jsx("button",{onClick:n,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),s.jsx("button",{onClick:n,className:"hidden sm:flex items-center justify-center p-2 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-subtle","aria-label":"Close",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),s.jsxs(u,{className:"p-0 overflow-hidden flex-1 flex flex-col min-h-0",children:[s.jsxs("div",{className:"sm:hidden flex-1 overflow-y-auto",children:[j&&s.jsx("div",{className:"h-64 p-2 border-b border-edge-subtle",children:s.jsx(C,{nodes:b,hoveredHash:x,onHover:y})}),s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})]}),j?s.jsxs("div",{className:"hidden sm:grid sm:grid-cols-[280px_minmax(400px,1fr)] flex-1 overflow-hidden sm:min-w-[700px]",children:[s.jsx("div",{className:"overflow-y-auto border-r border-edge-subtle",children:s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})}),s.jsx("div",{className:"overflow-hidden p-2",children:s.jsx(C,{nodes:b,hoveredHash:x,onHover:y})})]}):s.jsx("div",{className:"hidden sm:block flex-1 overflow-y-auto",children:s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})})]})]}):null});export{M as C}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{M as t,S as a,L as i,a as n}from"./maplibre-gl-BwLPRSIs.js";import{c as l}from"./vendor-core-FtpmsTnh.js";import{p as o,al as r,r as d,Y as c,_ as u,ab as h,h as m}from"./index-CkRTgHHA.js";import{u as x,B as p}from"./BasemapLayer-CSqjQAiA.js";import{a3 as g,a1 as f,aj as v,a as b,o as j,j as y,at as N}from"./vendor-icons-TO0PZKGR.js";const w={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"};function H({node:t,isHovered:a,onHover:i}){const[n,o]=e.useState(!1),r=e.useCallback(e=>{var s,a;e.stopPropagation(),s=t.hash,(null==(a=navigator.clipboard)?void 0:a.writeText)&&navigator.clipboard.writeText(s).catch(()=>{}),o(!0),setTimeout(()=>o(!1),2e3)},[t.hash]),d=t.contactType.toLowerCase(),c=d.includes("room")||d.includes("server");let u=v,h="text-sys-blue";return c?(u=y,h="text-signal-fair"):"companion"===d||"client"===d?(u=N,h="text-fg-muted"):t.isNeighbor&&(h="text-sys-green"),s.jsxs("div",{className:l("flex items-center gap-3 px-3 py-2.5 radius-inner transition-base cursor-pointer",a?"bg-sys-blue/10":"hover:bg-subtle-fill"),onMouseEnter:()=>i(t.hash),onMouseLeave:()=>i(null),children:[s.jsx(u,{className:l("w-4 h-4 flex-shrink-0",h)}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"type-label text-fg-primary truncate",children:t.name}),t.isNeighbor&&s.jsx(m,{color:"green",compact:!0,children:"NBR"}),t.isRepeater&&s.jsx(m,{color:"zinc",compact:!0,children:"RPT"}),t.isHub&&s.jsx(m,{color:"indigo",compact:!0,children:"HUB"})]}),s.jsxs("button",{onClick:r,className:l("mt-1 inline-flex items-center gap-1 type-data-xs px-1.5 py-0.5 rounded","border transition-all cursor-pointer",n?"border-sys-green/50 bg-sys-green/10 text-sys-green":"border-edge-subtle bg-subtle/50 text-fg-muted hover:border-edge-strong"),title:`Copy: ${t.hash}`,children:[t.hash.slice(0,12),"…",n?s.jsx(b,{className:"w-2.5 h-2.5"}):s.jsx(j,{className:"w-2.5 h-2.5 opacity-50"})]})]})]})}function C({nodes:o,hoveredHash:r,onHover:d}){const c=x(),u=e.useRef(null),g=h(),[v,b]=e.useState(!1),j=e.useMemo(()=>o.filter(e=>null!=e.latitude&&null!=e.longitude&&(0!==e.latitude||0!==e.longitude)),[o]),y=e.useMemo(()=>{if(0===j.length)return null;let e=1/0,s=-1/0,t=1/0,a=-1/0;for(const i of j)e=Math.min(e,i.longitude),s=Math.max(s,i.longitude),t=Math.min(t,i.latitude),a=Math.max(a,i.latitude);if(a-t<.01){const e=(a+t)/2;t=e-.005,a=e+.005}if(s-e<.01){const t=(s+e)/2;e=t-.005,s=t+.005}return[[e,t],[s,a]]},[j]),N=e.useMemo(()=>y?{longitude:(y[0][0]+y[1][0])/2,latitude:(y[0][1]+y[1][1])/2}:{longitude:0,latitude:0},[y]),H=e.useMemo(()=>{if(j.length<2)return null;const e=[];for(let s=0;s{var e;const s=null==(e=u.current)?void 0:e.getMap();s&&y?(s.fitBounds(y,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:13,duration:0}),setTimeout(()=>b(!0),50)):b(!0)},[y]),M=g&&v;return 0===j.length?s.jsx("div",{className:"h-full flex items-center justify-center bg-subtle/30 radius-inner",children:s.jsxs("div",{className:"text-center text-fg-secondary p-4",children:[s.jsx(f,{className:"w-8 h-8 mx-auto mb-2 opacity-40"}),s.jsx("p",{className:"text-sm",children:"No location data available"})]})}):s.jsxs("div",{className:"h-full w-full relative radius-inner overflow-hidden bg-elevated",children:[s.jsx("div",{className:l("absolute inset-0 flex items-center justify-center z-10","transition-opacity duration-200 pointer-events-none",M?"opacity-0":"opacity-100 bg-elevated"),children:s.jsx("div",{className:"w-5 h-5 border-2 border-text-muted/30 border-t-text-muted rounded-full animate-spin"})}),s.jsx("div",{className:l("h-full w-full transition-opacity duration-200",M?"opacity-100":"opacity-0"),children:s.jsxs(t,{ref:u,initialViewState:{longitude:N.longitude,latitude:N.latitude,zoom:10},style:{height:"100%",width:"100%"},mapStyle:w,attributionControl:!1,onLoad:C,children:[s.jsx(p,{mode:c}),H&&s.jsx(a,{id:"collision-edges",type:"geojson",data:H,children:s.jsx(i,{id:"collision-edges-line",type:"line",paint:{"line-color":"#3B3F4A","line-width":2,"line-opacity":.8},layout:{"line-cap":"round","line-join":"round"}})}),j.map(e=>{const t=e.hash===r,a=e.hash.startsWith("0x")?e.hash.slice(2,4).toUpperCase():e.hash.slice(0,2).toUpperCase();return s.jsx(n,{longitude:e.longitude,latitude:e.latitude,anchor:"center",children:s.jsx("div",{className:"cursor-pointer transition-all duration-150",onMouseEnter:()=>d(e.hash),onMouseLeave:()=>d(null),style:{pointerEvents:"auto"},children:s.jsxs(m,{color:"amber",filled:!0,className:"type-data-xs shadow-lg",children:[a,t&&s.jsx("span",{className:"ml-1 opacity-75 font-sans",children:e.name})]})})},e.hash)})]})})]})}const M=e.memo(function({isOpen:t,prefix:a,candidateHashes:i,onClose:n}){const l=o(),h=r(),m=d(),[x,p]=e.useState(null),f=e.useMemo(()=>new Set(m.map(e=>e.hash)),[m]),v=(null==l?void 0:l.neighbors)??{},b=e.useMemo(()=>i.map(e=>{var s;const t=(e=>v[e]?v[e]:!e.startsWith("0x")&&v["0x"+e]?v["0x"+e]:e.startsWith("0x")&&v[e.slice(2)]?v[e.slice(2)]:void 0)(e);return{hash:e,name:(null==t?void 0:t.node_name)||(null==t?void 0:t.name)||`Unknown (${e.slice(0,8)}…)`,contactType:(null==t?void 0:t.contact_type)||"",isRepeater:(null==t?void 0:t.is_repeater)||"repeater"===(null==(s=null==t?void 0:t.contact_type)?void 0:s.toLowerCase())||!1,isNeighbor:f.has(e)||f.has("0x"+e)||f.has(e.replace(/^0x/,"")),isHub:h.has(e),latitude:null==t?void 0:t.latitude,longitude:null==t?void 0:t.longitude}}).sort((e,s)=>e.isNeighbor!==s.isNeighbor?e.isNeighbor?-1:1:e.isHub!==s.isHub?e.isHub?-1:1:e.name.localeCompare(s.name)),[i,v,f,h]),j=e.useMemo(()=>b.some(e=>null!=e.latitude&&null!=e.longitude&&(0!==e.latitude||0!==e.longitude)),[b]),y=e.useCallback(e=>{p(e)},[]),N=j?"4xl":"lg";return t?s.jsxs(c,{open:t,onClose:n,size:N,motionPlus:!0,className:j?"sm:h-[500px] sm:max-h-[600px]":"",children:[s.jsxs("div",{className:"flex items-center justify-between px-4 py-3 border-b border-edge-subtle",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx("div",{className:"p-2 radius-inner bg-signal-fair/10",children:s.jsx(g,{className:"w-5 h-5 text-signal-fair"})}),s.jsxs("div",{children:[s.jsxs("div",{className:"type-micro",children:["Prefix Collision: ",s.jsx("span",{className:"font-mono text-sys-blue",children:a})]}),s.jsxs("p",{className:"text-xs text-fg-secondary",children:[b.length," nodes share this prefix"]})]})]}),s.jsx("button",{onClick:n,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),s.jsx("button",{onClick:n,className:"hidden sm:flex items-center justify-center p-2 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-subtle","aria-label":"Close",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),s.jsxs(u,{className:"p-0 overflow-hidden flex-1 flex flex-col min-h-0",children:[s.jsxs("div",{className:"sm:hidden flex-1 overflow-y-auto",children:[j&&s.jsx("div",{className:"h-64 p-2 border-b border-edge-subtle",children:s.jsx(C,{nodes:b,hoveredHash:x,onHover:y})}),s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})]}),j?s.jsxs("div",{className:"hidden sm:grid sm:grid-cols-[280px_minmax(400px,1fr)] flex-1 overflow-hidden sm:min-w-[700px]",children:[s.jsx("div",{className:"overflow-y-auto border-r border-edge-subtle",children:s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})}),s.jsx("div",{className:"overflow-hidden p-2",children:s.jsx(C,{nodes:b,hoveredHash:x,onHover:y})})]}):s.jsx("div",{className:"hidden sm:block flex-1 overflow-y-auto",children:s.jsx("div",{className:"p-2",children:b.map(e=>s.jsx(H,{node:e,isHovered:x===e.hash,onHover:y},e.hash))})})]})]}):null});export{M as C}; diff --git a/frontend/dist/assets/Configuration-BqjgQq_Y.js b/frontend/dist/assets/Configuration-CobIQjJB.js similarity index 99% rename from frontend/dist/assets/Configuration-BqjgQq_Y.js rename to frontend/dist/assets/Configuration-CobIQjJB.js index 0f61fa42..24125cd7 100644 --- a/frontend/dist/assets/Configuration-BqjgQq_Y.js +++ b/frontend/dist/assets/Configuration-CobIQjJB.js @@ -1,2 +1,2 @@ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-fonts-CRZaZSFf.js","assets/vendor-fonts-hkYiuhFD.css"])))=>i.map(i=>d[i]); -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{bM as a,bN as l,bO as n,T as r,bP as i,q as o,av as c,k as d,bQ as u,bR as m,B as x,bS as p,I as h}from"./index-D7i6lQrq.js";import{g as y,a as f,c as g,r as b,s as j,b as v,u as N,d as w}from"./system-Circh3O5.js";import{C as k}from"./ConfirmModal-XwU3yUZY.js";import{_ as C}from"./cosmograph-DqYT4sUA.js";import{L as S,a as _,X as F,b3 as T,C as E,d as P,c as R,b4 as D,as as I,I as L,k as A,n as z,b5 as M,R as K,b6 as V,b7 as O,b8 as $,b9 as H,a9 as q,ba as B,a3 as U,aX as X,o as G,D as W,bb as J}from"./vendor-icons-TO0PZKGR.js";import{N as Y}from"./NodeInformationCard-68hFKJ-B.js";import{i as Q,g as Z,s as ee,a as se,k as te}from"./keycap-sfx-Bpx9zhkt.js";import{C as ae,P as le,a as ne,B as re}from"./PageLayout-QhCLxU34.js";import{R as ie,C as oe}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./DataBox-DpDXI-WX.js";const ce=1500,de="h-[38px]",ue="h-[32px]",me="px-3",xe="px-2.5",pe="rounded-lg";function he({label:a,value:l,editValue:n,onSave:r,type:i="text",suffix:o,placeholder:c,readOnly:d=!1,layout:u="stacked",min:m,max:x,step:p,maxLength:h,description:y,className:f}){const[g,b]=e.useState(!1),[j,v]=e.useState(""),[N,w]=e.useState("idle"),k=e.useRef(null),C=e.useRef(!0),E=e.useRef(null),P=!d&&!!r;e.useEffect(()=>(C.current=!0,()=>{C.current=!1,E.current&&clearTimeout(E.current)}),[]);const R=e.useCallback(()=>{P&&(v(n??l),b(!0),w("idle"),requestAnimationFrame(()=>{var e;return null==(e=k.current)?void 0:e.select()}))},[P,n,l]),D=e.useCallback(()=>{b(!1),v(""),w("idle")},[]),I=e.useCallback(async()=>{if(r&&"loading"!==N)if(j!==(n??l)){E.current&&clearTimeout(E.current),w("loading");try{if(await r(j),!C.current)return;w("success"),b(!1),E.current=setTimeout(()=>{C.current&&w("idle")},ce)}catch{if(!C.current)return;w("error"),E.current=setTimeout(()=>{C.current&&w("idle")},ce)}}else D()},[r,j,n,l,D,N]),L=e.useCallback(e=>{"Enter"===e.key?(e.preventDefault(),I()):"Escape"===e.key&&(e.preventDefault(),D())},[I,D]);return"inline"===u?s.jsxs("div",{className:t("group flex items-center justify-between gap-3",f),children:[s.jsx("label",{className:"type-label text-fg-muted truncate",children:a}),g?s.jsxs("div",{className:t(ue,pe,xe,"flex items-center transition-all","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20","min-w-[100px]"),children:[s.jsx("input",{ref:k,type:i,value:j,onChange:e=>v(e.target.value),onKeyDown:L,placeholder:c,min:m,max:x,step:p,maxLength:h,disabled:"loading"===N,className:t("bg-transparent text-fg-primary focus:outline-none type-data flex-1 min-w-0",o?"w-12 text-right":"w-full")}),o&&s.jsx("span",{className:"text-fg-muted type-data ml-1 shrink-0",children:o}),s.jsx("div",{className:"flex items-center gap-0.5 ml-2 shrink-0",children:"loading"===N?s.jsx(S,{className:"w-3.5 h-3.5 text-fg-muted animate-spin"}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:I,className:"p-0.5 rounded hover:bg-sys-green/15 text-sys-green transition-colors",title:"Save (Enter)",children:s.jsx(_,{className:"w-3 h-3"})}),s.jsx("button",{onClick:D,className:"p-0.5 rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",title:"Cancel (Esc)",children:s.jsx(F,{className:"w-3 h-3"})})]})})]}):s.jsxs("div",{className:t(ue,pe,xe,"flex items-center justify-end transition-all min-w-[80px]","bg-input-bg border border-input-border",P&&"cursor-pointer hover:border-edge-strong"),onClick:P?R:void 0,children:[s.jsx("span",{className:"type-data text-fg-primary",children:l}),"success"===N&&s.jsx(_,{className:"w-3 h-3 text-sys-green ml-1.5 shrink-0"}),"error"===N&&s.jsx(F,{className:"w-3 h-3 text-sys-red ml-1.5 shrink-0"}),"idle"===N&&P&&s.jsx(T,{className:"w-3 h-3 text-fg-muted ml-1.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0"})]})]}):s.jsxs("div",{className:t("group",f),children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:a}),g?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:t(de,pe,me,"flex items-center transition-all","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20"),children:[s.jsx("input",{ref:k,type:i,value:j,onChange:e=>v(e.target.value),onKeyDown:L,placeholder:c,min:m,max:x,step:p,maxLength:h,disabled:"loading"===N,className:"w-full bg-transparent text-fg-primary focus:outline-none type-data flex-1 min-w-0"}),o&&s.jsx("span",{className:"text-fg-muted type-data ml-1 shrink-0",children:o}),s.jsx("div",{className:"flex items-center gap-0.5 ml-2 shrink-0",children:"loading"===N?s.jsx(S,{className:"w-3.5 h-3.5 text-fg-muted animate-spin"}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:I,className:"p-1 rounded hover:bg-sys-green/15 text-sys-green transition-colors",title:"Save (Enter)",children:s.jsx(_,{className:"w-3.5 h-3.5"})}),s.jsx("button",{onClick:D,className:"p-1 rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",title:"Cancel (Esc)",children:s.jsx(F,{className:"w-3.5 h-3.5"})})]})})]}),y&&s.jsx("p",{className:"type-data-xs text-fg-muted mt-1 ml-3",children:y})]}):s.jsxs("div",{className:t(de,pe,me,"flex items-center transition-all","bg-input-bg border border-input-border",P&&"cursor-pointer hover:border-edge-strong"),onClick:P?R:void 0,children:[s.jsx("span",{className:"type-data text-fg-primary flex-1 whitespace-nowrap",children:l}),"success"===N&&s.jsx(_,{className:"w-3.5 h-3.5 text-sys-green shrink-0"}),"error"===N&&s.jsx(F,{className:"w-3.5 h-3.5 text-sys-red shrink-0"}),"idle"===N&&P&&s.jsx(T,{className:"w-3.5 h-3.5 text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0"})]})]})}function ye({label:a,value:l,editValue:n,options:r,onSave:i,readOnly:o=!1,layout:c="stacked",className:d}){const[u,m]=e.useState(!1),[x,p]=e.useState(""),[h,y]=e.useState("idle"),f=e.useRef(null),g=e.useRef(!0),b=e.useRef(null),j=!o&&!!i;e.useEffect(()=>(g.current=!0,()=>{g.current=!1,b.current&&clearTimeout(b.current)}),[]);const v=e.useCallback(()=>{j&&(p(String(n)),m(!0),y("idle"),requestAnimationFrame(()=>{var e;return null==(e=f.current)?void 0:e.focus()}))},[j,n]),N=e.useCallback(()=>{m(!1),p(""),y("idle")},[]),w=e.useCallback(async()=>{if(i&&"loading"!==h)if(x!==String(n)){b.current&&clearTimeout(b.current),y("loading");try{if(await i(x),!g.current)return;y("success"),m(!1),b.current=setTimeout(()=>{g.current&&y("idle")},ce)}catch{if(!g.current)return;y("error"),b.current=setTimeout(()=>{g.current&&y("idle")},ce)}}else N()},[i,x,n,N,h]),k=e.useCallback(e=>{"Escape"===e.key&&(e.preventDefault(),N())},[N]),C="inline"===c,T=C?ue:de,P=C?xe:me,R=s.jsxs("div",{className:t(T,pe,P,"flex items-center transition-all relative","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20",C&&"min-w-[100px]"),children:[s.jsx("select",{ref:f,value:x,onChange:e=>p(e.target.value),onKeyDown:k,disabled:"loading"===h,className:t("bg-transparent text-fg-primary focus:outline-none appearance-none cursor-pointer type-data flex-1 min-w-0","pr-6"),children:r.map(e=>s.jsx("option",{value:e.value,children:e.label},String(e.value)))}),s.jsx(E,{className:"absolute right-auto w-3.5 h-3.5 text-fg-muted pointer-events-none",style:{right:"loading"===h?"2rem":"3.5rem"}}),s.jsx("div",{className:"flex items-center gap-0.5 ml-1 shrink-0",children:"loading"===h?s.jsx(S,{className:t("text-fg-muted animate-spin",C?"w-3 h-3":"w-3.5 h-3.5")}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:w,className:t("rounded hover:bg-sys-green/15 text-sys-green transition-colors",C?"p-0.5":"p-1"),title:"Save",children:s.jsx(_,{className:C?"w-3 h-3":"w-3.5 h-3.5"})}),s.jsx("button",{onClick:N,className:t("rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",C?"p-0.5":"p-1"),title:"Cancel (Esc)",children:s.jsx(F,{className:C?"w-3 h-3":"w-3.5 h-3.5"})})]})})]}),D=s.jsxs("div",{className:t(T,pe,P,"flex items-center transition-all","bg-input-bg border border-input-border",j&&"cursor-pointer hover:border-edge-strong",C?"justify-end min-w-[80px]":""),onClick:j?v:void 0,children:[s.jsx("span",{className:t("type-data text-fg-primary",!C&&"flex-1"),children:l}),"success"===h&&s.jsx(_,{className:t("text-sys-green shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")}),"error"===h&&s.jsx(F,{className:t("text-sys-red shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")}),"idle"===h&&j&&s.jsx(E,{className:t("text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")})]});return C?s.jsxs("div",{className:t("group flex items-center justify-between",d),children:[s.jsx("label",{className:"type-label text-fg-muted shrink-0",children:a}),u?R:D]}):s.jsxs("div",{className:t("group",d),children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:a}),u?R:D]})}async function fe(e){return a("/api/update_web_config",{method:"POST",body:JSON.stringify(e)})}e.memo(function(){const{theme:e}=l(),{themeId:t}=e,a=n.find(e=>e.meta.id===t)??n[0];return s.jsx("div",{className:"h-10 flex items-center justify-center",children:s.jsx("span",{className:"font-medium transition-all duration-300 leading-none text-center text-fg-secondary",style:{fontFamily:"Inter, system-ui, sans-serif",fontSize:"clamp(0.75rem, 0.6rem + 1.5vw, 1.1rem)",letterSpacing:"-0.02em"},children:a.meta.name})})});const ge=e.memo(function({compact:e=!1}){const{theme:a,setTheme:r}=l(),{themeId:i}=a;return s.jsx("div",{className:t("grid grid-cols-2 gap-2",e?"w-full min-w-0 self-stretch":"w-full"),children:[...n].reverse().map(a=>{const l=i===a.meta.id,n=a.meta.isDark;return s.jsxs("button",{type:"button",title:a.meta.name,className:t("flex flex-row items-stretch radius-inner transition-all duration-200 ease-out overflow-hidden cursor-pointer",e&&"h-6",l?"ring-2 ring-sys-blue scale-[1.02]":"opacity-70 hover:opacity-100"),onClick:()=>r(a.meta.id),children:[s.jsx("div",{className:t("flex-1 h-full",n?"bg-[#18181b]":"bg-[#EFF0F1]")}),s.jsx("div",{className:"flex flex-col h-full",children:a.display.palette.map((e,t)=>s.jsx("div",{className:"flex flex-1",children:e.map((e,t)=>s.jsx("div",{className:"w-2 h-full",style:{backgroundColor:e}},t))},t))})]},a.meta.id)})})});let be=!1,je=null;const ve=e.memo(function(){const{theme:t,setTheme:a}=l(),{themeId:n}=t,i="breeze dark"===n,o=e.useCallback(e=>{a(e?"breeze dark":"breeze light")},[a]);return s.jsx(r,{enabled:i,onChange:o,label:s.jsxs(s.Fragment,{children:["Dark Mode: ",i?s.jsx(P,{className:"w-3.5 h-3.5 text-sys-blue inline"}):s.jsx(R,{className:"w-3.5 h-3.5 text-[#e8a517] inline"})]}),tooltip:"Switch between dark and light mode",size:"md"})}),Ne=e.memo(function({layout:t="horizontal"}){return e.useEffect(()=>{!async function(){be||je||(je=(async()=>{try{await Promise.all([C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.l),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.a),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.b),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.c),__vite__mapDeps([0,1]))]),be=!0}catch(e){console.warn("Failed to load theme fonts:",e)}})())}()},[]),"toggle-only"===t?s.jsx(ve,{}):"thumbnails-only"===t?s.jsx(ge,{}):"vertical"===t?s.jsxs("div",{className:"flex flex-col items-start gap-3",children:[s.jsx(ve,{}),s.jsx(ge,{})]}):s.jsxs("div",{className:"flex items-stretch gap-4",children:[s.jsx("div",{className:"flex-shrink-0 flex items-start",children:s.jsx(ve,{})}),s.jsx(ge,{compact:!0})]})}),we=2e3;function ke(s,t,a){const[l,n]=e.useState("idle"),[r,i]=e.useState(null),o=e.useRef(!0),c=e.useRef(null),d=e.useRef(null),u=e.useRef(!1),m=e.useRef("idle"),x=e.useRef(s),p=e.useRef(t),h=e.useRef(a);return m.current=l,x.current=s,p.current=t,h.current=a,e.useEffect(()=>(o.current=!0,()=>{o.current=!1,c.current&&clearTimeout(c.current),d.current&&clearTimeout(d.current)}),[]),{enabled:null!==r?r:s,status:l,toggle:e.useCallback(async e=>{if("loading"===m.current)return;const s=x.current;c.current&&clearTimeout(c.current),d.current&&clearTimeout(d.current),u.current=!1,i(e),n("loading"),c.current=setTimeout(()=>{!u.current&&o.current&&(i(s),n("error"),d.current=setTimeout(()=>{o.current&&(n("idle"),i(null))},we))},1e4);try{if(await p.current(e),u.current=!0,c.current&&clearTimeout(c.current),!o.current)return;n("success"),d.current=setTimeout(()=>{var e;o.current&&(n("idle"),i(null),null==(e=h.current)||e.call(h))},we)}catch{if(u.current=!0,c.current&&clearTimeout(c.current),!o.current)return;i(s),n("error"),d.current=setTimeout(()=>{o.current&&(n("idle"),i(null))},we)}},[])}}function Ce(){const{latitude:a,longitude:l,enabled:n,setLocation:r,enable:c,disable:d,clear:u}=i(),[m,x]=e.useState(!1),[p,h]=e.useState(""),[y,f]=e.useState(""),[g,b]=e.useState("idle"),[j,v]=e.useState(null),N=e.useRef(null),w=e.useRef(null),k=e.useRef(!0);e.useEffect(()=>(k.current=!0,()=>{k.current=!1,w.current&&clearTimeout(w.current)}),[]);const C=()=>{x(!1),v(null)};e.useEffect(()=>{if(!m)return;const e=e=>{"loading"!==g&&N.current&&!N.current.contains(e.target)&&C()};return document.addEventListener("mouseup",e),()=>document.removeEventListener("mouseup",e)},[m,g]);const E=null!==a&&null!==l;return s.jsx(ae,{children:s.jsxs("div",{ref:N,children:[s.jsxs("div",{className:"flex items-center justify-between mb-4",children:[s.jsx(o,{icon:s.jsx(D,{}),title:"Stealth"}),s.jsxs("div",{className:"flex items-center gap-1",children:[E&&!m&&s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:()=>{n?d():c()},className:t("relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2 mr-2",n?"bg-toggle-on border-toggle-on":"bg-toggle-off border-edge-subtle"),title:n?"Disable stealth location":"Enable stealth location",children:s.jsx("span",{className:t("inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg",n?"translate-x-5":"translate-x-0.5")})}),s.jsx("button",{onClick:()=>{u(),x(!1)},className:"p-2 rounded-lg transition-colors text-fg-muted hover:text-sys-red hover:bg-sys-red/10",title:"Clear stealth location",children:s.jsx(I,{className:"w-4 h-4"})})]}),m?s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:C,disabled:"loading"===g,className:t("p-2 rounded-lg transition-colors","loading"===g?"text-fg-muted cursor-not-allowed":"text-fg-muted hover:text-sys-red hover:bg-sys-red/10"),title:"Cancel",children:s.jsx(F,{className:"w-4 h-4"})}),s.jsx("button",{onClick:()=>{if("loading"===g)return;w.current&&clearTimeout(w.current);const e=((e,s)=>{const t=parseFloat(e),a=parseFloat(s);return isNaN(t)||isNaN(a)?"Please enter valid numbers":t<-90||t>90?"Latitude must be between -90 and 90":a<-180||a>180?"Longitude must be between -180 and 180":0===t&&0===a?"Coordinates (0, 0) are invalid":null})(p,y);if(e)return void v(e);b("loading"),v(null);const s=parseFloat(p),t=parseFloat(y);r(s,t),n||c(),b("success"),w.current=setTimeout(()=>{k.current&&(b("idle"),x(!1))},1e3)},disabled:"loading"===g,className:t("p-2 rounded-lg transition-colors","loading"===g?"text-sys-blue cursor-wait":"success"===g?"text-sys-green":"error"===g?"text-sys-red":"text-sys-green hover:bg-sys-green/10"),title:"Save",children:"loading"===g?s.jsx(S,{className:"w-4 h-4 animate-spin"}):"success"===g?s.jsx(_,{className:"w-4 h-4"}):"error"===g?s.jsx(F,{className:"w-4 h-4"}):s.jsx(_,{className:"w-4 h-4"})})]}):s.jsx("button",{onClick:()=>{h((null==a?void 0:a.toFixed(6))??""),f((null==l?void 0:l.toFixed(6))??""),v(null),x(!0)},className:"p-2 rounded-lg transition-colors text-fg-muted hover:text-fg-primary hover:bg-subtle",title:E?"Edit stealth location":"Set stealth location",children:s.jsx(T,{className:"w-4 h-4"})})]})]}),s.jsx("div",{className:"bg-sys-cyan/5 rounded-xl p-3 mb-4",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(L,{className:"w-4 h-4 text-sys-cyan flex-shrink-0 mt-0.5"}),s.jsxs("p",{className:"type-body-sm text-fg-muted",children:[s.jsx("span",{className:"text-fg-secondary",children:"Stealth mode"})," allows you to appear on the map and in topology analysis without broadcasting your location. Coordinates are stored locally in your browser only — ",s.jsx("span",{className:"text-sys-cyan",children:"never sent to config.yaml or the mesh"}),"."]})]})}),j&&s.jsx("div",{className:"text-xs mb-3 px-2 py-1.5 rounded-md text-sys-red bg-sys-red/10",children:j}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:m?"Latitude (°)":"Latitude"}),s.jsx("div",{className:t("h-[38px] rounded-full px-4 flex items-center transition-colors","bg-subtle-fill"),children:m?s.jsx("input",{type:"number",value:p,onChange:e=>h(e.target.value),step:"0.000001",min:"-90",max:"90",placeholder:"e.g. 34.052234",className:"w-full bg-transparent text-fg-primary focus:outline-none type-data placeholder:text-fg-muted/50"}):s.jsx("span",{className:t("type-data",E&&n?"text-fg-primary":"text-fg-muted"),children:E?a.toFixed(6):"Not set"})})]}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:m?"Longitude (°)":"Longitude"}),s.jsx("div",{className:t("h-[38px] rounded-full px-4 flex items-center transition-colors","bg-subtle-fill"),children:m?s.jsx("input",{type:"number",value:y,onChange:e=>f(e.target.value),step:"0.000001",min:"-180",max:"180",placeholder:"e.g. -118.243685",className:"w-full bg-transparent text-fg-primary focus:outline-none type-data placeholder:text-fg-muted/50"}):s.jsx("span",{className:t("type-data",E&&n?"text-fg-primary":"text-fg-muted"),children:E?l.toFixed(6):"Not set"})})]})]}),E&&!m&&s.jsx("div",{className:"mt-3 pt-3 border-t border-edge-subtle",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:t("w-2 h-2 rounded-full",n?"bg-sys-green":"bg-fg-muted")}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:n?"Stealth location active — you appear on maps with these coordinates":"Stealth location disabled — coordinates saved but not in use"})]})})]})})}const Se=[{value:7.8,label:"7.8 kHz"},{value:10.4,label:"10.4 kHz"},{value:15.6,label:"15.6 kHz"},{value:20.8,label:"20.8 kHz"},{value:31.25,label:"31.25 kHz"},{value:41.7,label:"41.7 kHz"},{value:62.5,label:"62.5 kHz"},{value:125,label:"125 kHz"},{value:250,label:"250 kHz"},{value:500,label:"500 kHz"}],_e=[5,6,7,8,9,10,11,12],Fe=[{value:5,label:"4/5"},{value:6,label:"4/6"},{value:7,label:"4/7"},{value:8,label:"4/8"}],Te="radioConfig";function Ee(e){if(!e)return"Never";const s=Date.now()-1e3*e,t=Math.floor(s/6e4),a=Math.floor(s/36e5),l=Math.floor(s/864e5);return t<1?"Just now":t<60?`${t}m ago`:a<24?`${a}h ago`:l<365?`${l}d ago`:`${Math.floor(l/365)}y ago`}function Pe({node:e,level:a,expandedKeys:l,selectedKeyId:n,globalFloodPolicy:r,onSelect:i,onToggle:o}){const c=l.has(e.id),d=n===e.id,u=e.children&&e.children.length>0,m="allow"===r;return s.jsxs("div",{children:[s.jsxs("div",{className:t("flex items-center gap-2 h-[36px] px-3 rounded-full cursor-pointer transition-colors",d?"bg-sys-blue/15":"hover:bg-subtle-fill",m&&"opacity-50 cursor-not-allowed"),style:{marginLeft:16*a+"px"},onClick:()=>!m&&i(e.id),children:[u?s.jsx("button",{onClick:s=>{s.stopPropagation(),o(e.id)},className:"p-1 hover:bg-subtle-fill-hover rounded-full transition-colors",children:s.jsx(W,{className:t("w-3.5 h-3.5 text-fg-muted transition-transform",c&&"rotate-90")})}):s.jsx("span",{className:"w-5"}),s.jsx(J,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),s.jsx("span",{className:"type-data text-fg-primary flex-1 truncate",children:e.name}),s.jsx("span",{className:"type-data-xs text-fg-muted hidden sm:inline",title:e.last_used?new Date(1e3*e.last_used).toLocaleString():void 0,children:Ee(e.last_used)}),s.jsx("span",{className:t("type-data-xs px-2 py-0.5 rounded-full","allow"===e.floodPolicy?"bg-sys-green/15 text-sys-green":"bg-sys-red/15 text-sys-red"),children:"allow"===e.floodPolicy?"Allow":"Deny"})]}),u&&c&&s.jsx("div",{children:e.children.map(e=>s.jsx(Pe,{node:e,level:a+1,expandedKeys:l,selectedKeyId:n,globalFloodPolicy:r,onSelect:i,onToggle:o},e.id))})]})}function Re(){const[a,l]=e.useState(Q),[n,i]=e.useState(Z),[o,c]=e.useState(!1),d=e.useCallback(e=>{l(e),ee(e)},[]),u=e.useCallback(e=>{const s=parseFloat(e.target.value);i(s),se(s)},[]),m=e.useCallback(async()=>{o||(c(!0),await te(),c(!1))},[o]);return s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsx(r,{enabled:a,onChange:d,label:s.jsxs(s.Fragment,{children:["Sound: ",s.jsx("span",{className:a?"text-sys-green":"text-sys-red",children:a?"On":"Off"})]}),tooltip:"Enable or disable UI sound effects and haptic audio feedback",size:"md"}),s.jsx(x,{color:"primary",outline:!0,onClick:m,disabled:!a||o,className:"w-16 justify-center",children:o?"…":"Test"})]}),s.jsxs("div",{className:t("flex items-center gap-3",!a&&"opacity-40 pointer-events-none"),children:[s.jsx("span",{className:"type-label text-fg-muted w-14 shrink-0",children:"Volume"}),s.jsx("input",{type:"range",min:0,max:1,step:.05,value:n,onChange:u,className:"flex-1 accent-sys-blue h-1.5 cursor-pointer"}),s.jsxs("span",{className:"data-box w-16 justify-center",children:[Math.round(100*n),"%"]})]})]})}function De(){var l,n,i,C,F,T;const{stats:E,setMode:P,clearModeMutation:R,setDutyCycleConfig:D,clearDutyCycleMutation:W,fetchStats:J,startMutation:Q,clearMutation:Z}=c(),ee=null==(l=null==E?void 0:E.config)?void 0:l.radio,se=null==(n=null==E?void 0:E.config)?void 0:n.repeater,te=null==(i=null==E?void 0:E.config)?void 0:i.duty_cycle,ce=(null==E?void 0:E.node_name)||(null==(C=null==E?void 0:E.config)?void 0:C.node_name)||"Unknown Node",de=(null==se?void 0:se.mode)??"forward",ue=(null==te?void 0:te.enforcement_enabled)??!1,me=null==(F=null==E?void 0:E.config)?void 0:F.delays,xe=e.useRef(!0);e.useEffect(()=>(xe.current=!0,()=>{xe.current=!1}),[]);const pe=null==(T=null==E?void 0:E.config)?void 0:T.web,[ge,be]=e.useState([]),[je,ve]=e.useState(!1),[we,Ee]=e.useState(null),[De,Ie]=e.useState(!1),[Le,Ae]=e.useState(""),[ze,Me]=e.useState(null),[Ke,Ve]=e.useState(!1),[Oe,$e]=e.useState(null),[He,qe]=e.useState(!1),[Be,Ue]=e.useState(!1),[Xe,Ge]=e.useState(!1),[We,Je]=e.useState([]),[Ye,Qe]=e.useState(!1),[Ze,es]=e.useState(null),[ss,ts]=e.useState(()=>"allow"===localStorage.getItem("pymc:globalFloodPolicy")?"allow":"deny"),as=e.useCallback(e=>{ts(e),localStorage.setItem("pymc:globalFloodPolicy",e)},[]),[ls,ns]=e.useState(!1),[rs,is]=e.useState(null),[os,cs]=e.useState(new Set),[ds,us]=e.useState(!1),[ms,xs]=e.useState(!1),[ps,hs]=e.useState(!1),[ys,fs]=e.useState(null),[gs,bs]=e.useState(null),[js,vs]=e.useState(""),[Ns,ws]=e.useState("allow"),[ks,Cs]=e.useState(!1),[Ss,_s]=e.useState(!0),[Fs,Ts]=e.useState(!1),[Es,Ps]=e.useState(!0),[Rs,Ds]=e.useState("idle"),[Is,Ls]=e.useState(!1),[As,zs]=e.useState(!1),Ms=e.useCallback(()=>{const e=null==me?void 0:me.tx_delay_factor;return e&&"object"==typeof e&&"parsedValue"in e?e.parsedValue??1:"number"==typeof e?e:1},[me]),Ks=e.useCallback(()=>{const e=null==me?void 0:me.direct_tx_delay_factor;return"number"==typeof e?e:.5},[me]),Vs=e.useCallback(()=>{const e=null==te?void 0:te.max_airtime_percent;return"number"==typeof e?e:e&&"object"==typeof e&&"parsedValue"in e?e.parsedValue??6:6},[te]),Os=ke("forward"===de,async e=>{await P(e?"forward":"monitor")},R),$s=ke(ue,async e=>{await D({max_airtime_percent:Vs(),enforcement_enabled:e})},W),Hs=ke((null==pe?void 0:pe.cors_enabled)??!1,async e=>{var s;const t=await fe({web:{cors_enabled:e}});if(!t.success&&!(null==(s=t.data)?void 0:s.persisted))throw new Error("CORS update failed");await J()}),qs=e.useCallback(async e=>{Q(Te);try{const s=await d(e);if(!s.success)throw new Error(s.error||"Failed to save");await J({force:!0}).catch(()=>{})}finally{Z(Te)}},[Q,Z,J]);e.useEffect(()=>{(async()=>{Ps(!0);try{const e=await g();e.success&&e.data?Ts(e.data.exists):Ts(!1);const s=null==pe?void 0:pe.web_path;_s(!s||""===s)}catch{Ts(!1)}finally{Ps(!1)}})()},[null==pe?void 0:pe.web_path]);const Bs=async e=>{var s;if("loading"!==Rs){Ds("loading");try{const t=await fe({web:{web_path:e?null:"/opt/pymc_console/web/html"}});if(!xe.current)return;t.success||(null==(s=t.data)?void 0:s.persisted)?(_s(e),Ds("success"),Ls(!0),setTimeout(()=>{xe.current&&Ds("idle")},2e3)):(Ds("error"),setTimeout(()=>{xe.current&&Ds("idle")},2e3))}catch{if(!xe.current)return;Ds("error"),setTimeout(()=>{xe.current&&Ds("idle")},2e3)}}},Us=e.useCallback(async()=>{ve(!0),Ee(null);try{const e=await async function(){return a("/auth/tokens")}();be(e.tokens||[])}catch(e){Ee(e instanceof Error?e.message:"Failed to fetch tokens")}finally{ve(!1)}},[]);e.useEffect(()=>{Us()},[Us]);const Xs=async()=>{if(Le.trim()){qe(!0),Ee(null);try{const e=await async function(e){return a("/auth/tokens",{method:"POST",body:JSON.stringify({name:e})})}(Le.trim());Me(e.token||null),Ie(!1),Ve(!0),Ae(""),await Us()}catch(e){Ee(e instanceof Error?e.message:"Failed to create token")}finally{qe(!1)}}else Ee("Token name is required")},Gs=e=>e?new Date(1e3*e).toLocaleString():"Never",Ws=e.useCallback(e=>{const s=new Map,t=[];return e.forEach(e=>{const t={id:e.id,name:e.name,floodPolicy:e.flood_policy,transport_key:e.transport_key,last_used:e.last_used,parent_id:e.parent_id,children:[]};s.set(e.id,t)}),s.forEach(e=>{e.parent_id&&s.has(e.parent_id)?s.get(e.parent_id).children.push(e):t.push(e)}),t},[]),Js=e.useCallback(async()=>{Qe(!0),es(null);try{const e=await y();if(e.success&&e.data){const s=Ws(e.data);Je(s),is(e=>{if(null===e)return null;const t=s=>{for(const a of s){if(a.id===e)return!0;if(a.children&&t(a.children))return!0}return!1};return t(s)?e:null})}else es(e.error||"Failed to load transport keys")}catch(e){es(e instanceof Error?e.message:"Unknown error occurred")}finally{Qe(!1)}},[Ws]);e.useEffect(()=>{Js(),f().then(e=>{e.success&&e.data&&as(e.data.global_flood_allow?"allow":"deny")}).catch(()=>{})},[Js]);const Ys=e.useCallback((e,s)=>{for(const t of e){if(t.id===s)return t;if(t.children){const e=Ys(t.children,s);if(e)return e}}return null},[]),Qs=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);return null==e?void 0:e.name},[rs,We,Ys]),Zs=e.useCallback(e=>{cs(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t})},[]),et=async()=>{if(js.trim()){Cs(!0),es(null);try{const e=await v({name:js.trim(),flood_policy:Ns,parent_id:rs??void 0});e.success?(await Js(),us(!1),vs(""),ws("allow")):es(e.error||"Failed to add transport key")}catch(e){es(e instanceof Error?e.message:"Failed to add transport key")}finally{Cs(!1)}}else es("Key name is required")},st=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);e&&(fs({...e}),xs(!0))},[rs,We,Ys]);e.useEffect(()=>{const e=e=>{"Escape"===e.key&&(ds&&(us(!1),vs(""),ws("allow")),ms&&(xs(!1),fs(null)),ps&&(hs(!1),bs(null)),De&&(Ie(!1),Ae("")),Ke&&(Ve(!1),Me(null)))};if(ds||ms||ps||De||Ke)return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[ds,ms,ps,De,Ke]);const tt=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);e&&(bs(e),hs(!0))},[rs,We,Ys]);return s.jsxs(le,{children:[s.jsx(ne,{title:"Configuration",icon:s.jsx(A,{})}),s.jsxs(re,{children:[s.jsxs(ie,{template:"standard",children:[s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(z,{}),title:"Repeater Settings"}),se?s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsx("div",{className:"col-span-2",children:s.jsx(he,{label:"Node Name",value:ce,onSave:async e=>qs({node_name:e}),placeholder:"Enter node name",maxLength:50})}),s.jsx(he,{label:"Latitude",value:0!==se.latitude?se.latitude.toFixed(6):"Not set",editValue:String(se.latitude),type:"number",suffix:"°",step:1e-6,min:-90,max:90,onSave:async e=>qs({latitude:parseFloat(e)})}),s.jsx(he,{label:"Longitude",value:0!==se.longitude?se.longitude.toFixed(6):"Not set",editValue:String(se.longitude),type:"number",suffix:"°",step:1e-6,min:-180,max:180,onSave:async e=>qs({longitude:parseFloat(e)})}),s.jsx(he,{label:"Advert Interval",value:se.send_advert_interval_hours>0?`${se.send_advert_interval_hours}h`:"Disabled",editValue:String(se.send_advert_interval_hours),type:"number",suffix:"hours",min:0,max:48,description:"0 = disabled, 3-48 hours",onSave:async e=>qs({flood_advert_interval_hours:parseInt(e,10)})}),s.jsx(he,{label:"Score-based TX",value:se.use_score_for_tx?"Enabled":"Disabled",readOnly:!0})]}):s.jsx("p",{className:"text-fg-muted",children:"Loading repeater settings..."})]})}),s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(M,{}),title:"Radio Configuration"}),ee?s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsx(he,{label:"Frequency",value:u(ee.frequency),editValue:(ee.frequency/1e6).toFixed(3),type:"number",suffix:"MHz",step:.001,min:400,max:930,onSave:async e=>qs({frequency_mhz:parseFloat(e)})}),s.jsx(he,{label:"TX Power",value:`${ee.tx_power} dBm`,editValue:String(ee.tx_power),type:"number",suffix:"dBm",min:2,max:30,onSave:async e=>qs({tx_power:parseInt(e,10)})}),s.jsx(ye,{label:"Bandwidth",value:m(ee.bandwidth),editValue:ee.bandwidth/1e3,options:Se,onSave:async e=>qs({bandwidth_khz:parseFloat(e)})}),s.jsx(ye,{label:"Spreading Factor",value:`SF${ee.spreading_factor}`,editValue:ee.spreading_factor,options:_e.map(e=>({value:e,label:`SF${e}`})),onSave:async e=>qs({spreading_factor:parseInt(e,10)})}),s.jsx(ye,{label:"Coding Rate",value:`4/${ee.coding_rate}`,editValue:ee.coding_rate,options:Fe,onSave:async e=>qs({coding_rate:parseInt(e,10)})}),s.jsx(he,{label:"Preamble",value:`${ee.preamble_length} symbols`,readOnly:!0})]}):s.jsx("p",{className:"text-fg-muted",children:"Loading radio configuration..."})]})})]}),s.jsxs(ie,{template:"standard",children:[s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(K,{}),title:"Operating Mode"}),s.jsx("p",{className:"type-label text-fg-muted mb-3",children:"Control how the repeater handles packets"}),s.jsxs("div",{className:"flex flex-col lg:flex-row gap-4",children:[s.jsxs("div",{className:"flex-1 space-y-4",children:[s.jsx(r,{enabled:Os.enabled,onChange:Os.toggle,label:"Repeat",tooltip:"Toggles repeater or monitor mode. In monitor mode, the repeater will not repeat packets from the mesh.",status:Os.status,size:"md"}),s.jsx(r,{enabled:$s.enabled,onChange:$s.toggle,label:"Duty Cycle",tooltip:"Limit transmission time to comply with airtime utilization regulations",status:$s.status,size:"md"}),s.jsx(he,{label:"Max Airtime",layout:"inline",value:`${Vs().toFixed(1)}%`,editValue:String(Vs()),type:"number",suffix:"%",step:.5,min:.1,max:100,onSave:async e=>{await D({max_airtime_percent:parseFloat(e),enforcement_enabled:ue}),W()}})]}),s.jsx("div",{className:"hidden lg:block w-px bg-border-subtle"}),s.jsxs("div",{className:"flex-1 pt-4 lg:pt-0 border-t lg:border-t-0 border-edge-subtle",children:[s.jsx("label",{className:"type-label text-fg-muted block mb-3",children:"TX Delays"}),s.jsxs("div",{className:"space-y-3",children:[s.jsx(he,{label:"Flood",layout:"inline",value:`${Ms().toFixed(2)}x`,editValue:String(Ms()),type:"number",suffix:"x",step:.1,min:0,max:5,onSave:async e=>qs({tx_delay_factor:parseFloat(e)})}),s.jsx(he,{label:"Direct",layout:"inline",value:`${Ks().toFixed(2)}s`,editValue:String(Ks()),type:"number",suffix:"s",step:.1,min:0,max:5,onSave:async e=>qs({direct_tx_delay_factor:parseFloat(e)})})]})]})]})]})}),s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(A,{}),title:"App Settings"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:"Appearance and web server options."}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(r,{enabled:Hs.enabled,onChange:Hs.toggle,label:"Enable CORS",tooltip:"Allow cross-origin API access",status:Hs.status,size:"md"}),s.jsx("div",{children:s.jsx(Ne,{})}),s.jsx(Re,{})]})]})})]}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4",children:[s.jsx(o,{icon:s.jsx(V,{}),title:"Regions Transport Keys",subtitle:"Manage regional key hierarchy for flood control"}),s.jsxs("div",{className:"flex gap-2 flex-wrap",children:[s.jsxs(x,{color:"primary",outline:!0,onClick:()=>us(!0),disabled:"allow"===ss,children:[s.jsx(O,{"data-slot":"icon"}),"Add"]}),s.jsx(x,{color:"primary",outline:!0,onClick:st,disabled:!rs||"allow"===ss,children:"Edit"}),s.jsx(x,{color:"danger",outline:!0,onClick:tt,disabled:!rs||"allow"===ss,children:"Delete"})]})]}),s.jsx("div",{className:"bg-subtle-fill radius-inner p-4 mb-4",children:s.jsx(r,{enabled:"deny"===ss,onChange:e=>(async e=>{ns(!0),es(null);try{const s=await j("allow"===e);s.success?as(e):es(s.error||"Failed to update global flood policy")}catch(s){es(s instanceof Error?s.message:"Failed to update global flood policy")}finally{ns(!1)}})(e?"deny":"allow"),label:s.jsxs(s.Fragment,{children:["Require Transport Keys: ",s.jsx("span",{className:"deny"===ss?"text-sys-green":"text-sys-red",children:"deny"===ss?"On":"Off"})]}),tooltip:"When enabled, only packets with matching transport keys are forwarded. When disabled, all packets flood freely.",status:ls?"loading":"idle",disabled:ls,dangerOff:!0,size:"md",className:"flex-row-reverse justify-between w-full"})}),Ze&&s.jsx("div",{className:"type-body-sm mb-3 px-3 py-2 rounded-full text-sys-red bg-sys-red/10",children:Ze}),s.jsx("div",{className:"bg-subtle-fill radius-inner p-4 min-h-[120px]",children:Ye?s.jsxs("div",{className:"flex items-center justify-center py-6",children:[s.jsx(S,{className:"w-5 h-5 animate-spin text-sys-blue mr-2"}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:"Loading transport keys..."})]}):0===We.length?s.jsxs("div",{className:"text-center py-6",children:[s.jsx("div",{className:"w-12 h-12 rounded-full bg-subtle-fill mx-auto mb-3 flex items-center justify-center",children:s.jsx(V,{className:"w-6 h-6 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No transport keys found"}),s.jsx("p",{className:"type-body-sm text-fg-muted/70 mt-1",children:"Add your first transport key to get started"})]}):s.jsx("div",{className:"space-y-1",children:We.map(e=>s.jsx(Pe,{node:e,level:0,expandedKeys:os,selectedKeyId:rs,globalFloodPolicy:ss,onSelect:is,onToggle:Zs},e.id))})})]})}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4",children:[s.jsx(o,{icon:s.jsx($,{}),title:"API Tokens",subtitle:"Manage API tokens for machine-to-machine authentication"}),s.jsxs(x,{color:"primary",outline:!0,onClick:()=>Ie(!0),children:[s.jsx(O,{"data-slot":"icon"}),"Create Token"]})]}),s.jsx("div",{className:"bg-sys-cyan/5 radius-inner p-4 mb-4",children:s.jsxs("div",{className:"flex gap-3",children:[s.jsx("div",{className:"w-8 h-8 rounded-full bg-sys-cyan/20 flex items-center justify-center flex-shrink-0",children:s.jsx(L,{className:"w-4 h-4 text-sys-cyan"})}),s.jsxs("div",{className:"type-body-sm text-fg-muted",children:[s.jsxs("p",{children:[s.jsx("span",{className:"text-fg-secondary",children:"API tokens"})," are used for machine-to-machine authentication. Include the token in the ",s.jsx("code",{className:"type-code bg-sys-cyan/20 px-1.5 py-0.5 rounded-full text-sys-cyan",children:"X-API-Key"})," header when making API requests."]}),s.jsx("p",{className:"mt-1 text-fg-muted/70",children:"Tokens are only shown once at creation. Store them securely."})]})]})}),we&&s.jsx("div",{className:"type-body-sm mb-3 px-3 py-2 rounded-full text-sys-red bg-sys-red/10",children:we}),je&&0===ge.length?s.jsxs("div",{className:"flex items-center justify-center py-6",children:[s.jsx(S,{className:"w-5 h-5 animate-spin text-sys-blue mr-2"}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:"Loading tokens..."})]}):ge.length>0?s.jsx("div",{className:"space-y-2",children:ge.map(e=>s.jsx("div",{className:"bg-subtle-fill hover:bg-subtle-fill-strong radius-inner p-4 transition-base",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex items-center gap-3 flex-1 min-w-0",children:[s.jsx("div",{className:"w-10 h-10 rounded-full bg-sys-blue/10 flex items-center justify-center flex-shrink-0",children:s.jsx($,{className:"w-5 h-5 text-sys-blue"})}),s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsx("h3",{className:"type-body text-fg-primary font-medium truncate",children:e.name}),s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-0.5",children:[s.jsxs("span",{className:"type-data-sm text-fg-muted truncate",children:["Created: ",Gs(e.created_at)]}),s.jsxs("span",{className:"type-data-sm text-fg-muted truncate",children:["Last used: ",Gs(e.last_used)]})]})]})]}),s.jsxs(x,{color:"danger",outline:!0,onClick:()=>$e({id:e.id,name:e.name}),disabled:Be,children:[s.jsx(I,{"data-slot":"icon"}),"Revoke"]})]})},e.id))}):s.jsxs("div",{className:"bg-subtle-fill radius-inner p-6 text-center",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx($,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("h3",{className:"type-body text-fg-primary font-medium mb-1",children:"No API Tokens"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:"Create a token to enable API access"}),s.jsx(x,{color:"primary",outline:!0,onClick:()=>Ie(!0),children:"Create Your First Token"})]})]})}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(H,{}),title:"Web Frontend",subtitle:"Choose which web interface to use",className:"mb-4"}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"space-y-3",children:[s.jsxs("label",{className:t("flex items-start gap-3 p-4 bg-subtle-fill radius-card border-2 cursor-pointer transition-base",Ss?"border-sys-blue bg-sys-blue/5":"border-transparent hover:border-sys-blue/30","loading"===Rs&&"opacity-50 pointer-events-none"),children:[s.jsx("input",{type:"radio",name:"frontend",checked:Ss,onChange:()=>Bs(!0),disabled:"loading"===Rs,className:"mt-1 h-4 w-4 text-sys-blue focus:ring-sys-blue focus:ring-offset-bg-elevated"}),s.jsxs("div",{className:"flex-1",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("div",{className:"type-body text-fg-primary font-medium",children:"Default Frontend"}),s.jsx("a",{href:"https://github.com/rightup/pyMC_Repeater",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),className:"type-data-xs bg-sys-cyan/15 text-sys-cyan px-2.5 py-0.5 rounded-full font-medium hover:bg-sys-cyan/25 transition-colors",children:"@RightUp"})]}),s.jsx("div",{className:"type-body-sm text-fg-muted mt-1",children:"Built-in pyMC Repeater web interface"}),s.jsx("div",{className:"type-data-xs text-fg-muted/60 mt-1",children:"/opt/pymc_repeater/repeater/web/html"})]})]}),s.jsxs("label",{className:t("flex items-start gap-3 p-4 bg-subtle-fill radius-card border-2 cursor-pointer transition-base",Ss?"border-transparent hover:border-sys-blue/30":"border-sys-blue bg-sys-blue/5","loading"===Rs&&"opacity-50 pointer-events-none"),children:[s.jsx("input",{type:"radio",name:"frontend",checked:!Ss,onChange:()=>Bs(!1),disabled:"loading"===Rs,className:"mt-1 h-4 w-4 text-sys-blue focus:ring-sys-blue focus:ring-offset-bg-elevated"}),s.jsxs("div",{className:"flex-1",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("div",{className:"type-body text-fg-primary font-medium",children:"PyMC Console"}),s.jsx("span",{className:"type-data-xs bg-sys-indigo/15 text-sys-indigo px-2.5 py-0.5 rounded-full font-medium",children:"@Treehouse ⚡"})]}),s.jsx("div",{className:"type-body-sm text-fg-muted mt-1",children:"Alternative web interface for pyMC Repeater"}),s.jsx("div",{className:"type-data-xs text-fg-muted/60 mt-1",children:"/opt/pymc_console/web/html"})]})]})]}),!Es&&s.jsx("div",{className:t("bg-subtle-fill radius-card p-4",Fs?"border border-sys-green/20":"border border-sys-cyan/20"),children:s.jsxs("div",{className:"flex items-start gap-3",children:[s.jsx("div",{className:t("w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0",Fs?"bg-sys-green/20":"bg-sys-cyan/20"),children:Fs?s.jsx(q,{className:"w-4 h-4 text-sys-green"}):s.jsx(L,{className:"w-4 h-4 text-sys-cyan"})}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"type-body text-fg-primary font-medium",children:Fs?"PyMC Console has been detected":"PyMC Console Not Installed"}),Fs?s.jsxs("p",{className:"type-body-sm text-fg-muted mt-1",children:["PyMC Console is installed at ",s.jsx("code",{className:"type-code bg-sys-green/10 px-1.5 py-0.5 rounded-full text-sys-green",children:"/opt/pymc_console/web/html"})]}):s.jsxs(s.Fragment,{children:[s.jsxs("p",{className:"type-body-sm text-fg-muted mt-1 mb-3",children:["PyMC Console must be installed at ",s.jsx("code",{className:"type-code bg-sys-cyan/10 px-1.5 py-0.5 rounded-full text-sys-cyan",children:"/opt/pymc_console/web/html"})," before selecting this option."]}),s.jsxs(x,{color:"primary",outline:!0,href:"https://github.com/dmduran12/pymc_console-dist",children:[s.jsx(B,{"data-slot":"icon"}),"PyMC Console Install Instructions"]})]})]})]})}),Is&&s.jsx("div",{className:"bg-subtle-fill radius-card p-4 border border-sys-indigo/30",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex items-start gap-3 flex-1",children:[s.jsx("div",{className:"w-8 h-8 rounded-full bg-sys-indigo/20 flex items-center justify-center flex-shrink-0",children:s.jsx(U,{className:"w-4 h-4 text-sys-indigo"})}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"type-body text-fg-primary font-medium",children:"Service restart required"}),s.jsx("p",{className:"type-body-sm text-fg-muted mt-1",children:"Web frontend changes will take effect after restarting the pymc-repeater service."})]})]}),s.jsx(x,{color:"warning",outline:!0,onClick:async()=>{if(!As){zs(!0);try{await b(),Ls(!1),setTimeout(()=>{window.location.reload()},2e3)}catch{Ls(!1),setTimeout(()=>{window.location.reload()},3e3)}}},disabled:As,children:As?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Restarting..."]}):s.jsxs(s.Fragment,{children:[s.jsx(X,{"data-slot":"icon"}),"Restart Now"]})})]})})]})]})}),E&&s.jsx(ie,{template:"auto",children:s.jsx(Y,{nodeName:ce,repeaterVersion:E.version,coreVersion:E.core_version,localHash:E.local_hash,publicKey:E.public_key})}),E&&(0===(null==se?void 0:se.latitude)||!(null==se?void 0:se.latitude))&&(0===(null==se?void 0:se.longitude)||!(null==se?void 0:se.longitude))&&s.jsx(ie,{template:"auto",children:s.jsx(Ce,{})})]}),De&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&Ie(!1),role:"dialog","aria-modal":"true","aria-labelledby":"create-token-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"create-token-modal-title",className:"type-micro mb-4",children:"Create API Token"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(p,{label:"Token Name",type:"text",value:Le,onChange:e=>Ae(e.target.value),placeholder:"e.g., Production Server, CI/CD Pipeline",description:"Give your token a descriptive name to identify its purpose",onKeyDown:e=>"Enter"===e.key&&Xs(),autoFocus:!0}),s.jsxs("div",{className:"flex justify-end gap-3 mt-6",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{Ie(!1),Ae(""),Ee(null)},disabled:He,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:Xs,disabled:He||!Le.trim(),children:He?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Creating..."]}):"Create Token"})]})]})]})}),Ke&&ze&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&Ve(!1),role:"dialog","aria-modal":"true","aria-labelledby":"show-token-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-lg w-full",children:[s.jsx("h3",{id:"show-token-modal-title",className:"type-micro mb-4",children:"Token Created Successfully"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx("div",{className:"bg-sys-indigo/10 border border-sys-indigo/30 radius-inner p-3",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(U,{className:"w-4 h-4 text-sys-indigo flex-shrink-0 mt-0.5"}),s.jsxs("div",{className:"text-sm text-fg-secondary",children:[s.jsx("strong",{children:"Save this token now!"})," For security reasons, it will not be shown again."]})]})}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-primary block mb-1.5",children:"Your API Token"}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx(h,{value:ze,readOnly:!0,className:"flex-1 font-mono"}),s.jsxs(x,{color:"primary",outline:!0,onClick:()=>{ze&&(navigator.clipboard.writeText(ze),Ge(!0),setTimeout(()=>Ge(!1),2e3))},children:[Xe?s.jsx(_,{"data-slot":"icon",className:"text-sys-green"}):s.jsx(G,{"data-slot":"icon"}),Xe?"Copied!":"Copy"]})]})]}),s.jsxs("div",{className:"bg-sys-cyan/10 border border-sys-cyan/30 radius-inner p-3",children:[s.jsx("p",{className:"text-sm text-fg-secondary mb-2",children:s.jsx("strong",{children:"Usage Example:"})}),s.jsxs("code",{className:"block bg-sys-cyan/20 px-3 py-2 rounded type-code text-sys-cyan overflow-x-auto",children:['curl -H "X-API-Key: ',ze.slice(0,12),'..." ',window.location.origin,"/api/stats"]})]}),s.jsx("div",{className:"flex justify-end mt-6",children:s.jsx(x,{color:"primary",onClick:()=>{Ve(!1),Me(null)},children:"Done"})})]})]})}),s.jsx(k,{isOpen:!!Oe,title:"Revoke API Token",message:`Are you sure you want to revoke the token '${null==Oe?void 0:Oe.name}'? This action cannot be undone.`,confirmLabel:Be?"Revoking...":"Revoke",cancelLabel:"Cancel",variant:"danger",onConfirm:async()=>{if(Oe){Ue(!0),Ee(null);try{await async function(e){return a(`/auth/tokens/${e}`,{method:"DELETE"})}(Oe.id),await Us(),$e(null)}catch(e){Ee(e instanceof Error?e.message:"Failed to revoke token")}finally{Ue(!1)}}},onCancel:()=>$e(null)}),ds&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&us(!1),role:"dialog","aria-modal":"true","aria-labelledby":"add-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"add-key-modal-title",className:"type-micro mb-4",children:"Add Transport Key"}),s.jsxs("div",{className:"space-y-4",children:[rs&&s.jsxs("div",{className:"bg-sys-cyan/10 border border-sys-cyan/30 radius-inner p-3 text-sm text-fg-secondary",children:["Adding as child of: ",s.jsx("strong",{className:"text-fg-primary",children:Qs()})]}),s.jsx(p,{label:"Key Name",type:"text",value:js,onChange:e=>vs(e.target.value),placeholder:"e.g., Region Name, Group Key",onKeyDown:e=>"Enter"===e.key&&et(),autoFocus:!0}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Flood Policy"}),s.jsxs("div",{className:"toggle-group w-full",children:[s.jsx("button",{onClick:()=>ws("deny"),className:t("toggle-group-item flex-1","deny"===Ns&&"active !text-sys-red"),children:"Deny"}),s.jsx("button",{onClick:()=>ws("allow"),className:t("toggle-group-item flex-1","allow"===Ns&&"active !text-sys-green"),children:"Allow"})]})]}),s.jsxs("div",{className:"flex justify-end gap-3 mt-6",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{us(!1),vs(""),ws("allow")},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:et,disabled:ks||!js.trim(),children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Adding..."]}):"Add Key"})]})]})]})}),ms&&ys&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&xs(!1),role:"dialog","aria-modal":"true","aria-labelledby":"edit-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"edit-key-modal-title",className:"type-micro mb-4",children:"Edit Transport Key"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(p,{label:"Key Name",type:"text",value:ys.name,onChange:e=>fs({...ys,name:e.target.value}),autoFocus:!0}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Flood Policy"}),s.jsxs("div",{className:"toggle-group w-full",children:[s.jsx("button",{onClick:()=>fs({...ys,floodPolicy:"deny"}),className:t("toggle-group-item flex-1","deny"===ys.floodPolicy&&"active !text-sys-red"),children:"Deny"}),s.jsx("button",{onClick:()=>fs({...ys,floodPolicy:"allow"}),className:t("toggle-group-item flex-1","allow"===ys.floodPolicy&&"active !text-sys-green"),children:"Allow"})]})]}),ys.transport_key&&s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Transport Key"}),s.jsx("code",{className:"block bg-input-bg px-3 py-2 radius-inner border border-input-border type-code text-fg-muted overflow-x-auto",children:ys.transport_key})]}),s.jsxs("div",{className:"flex justify-between gap-3 mt-6",children:[s.jsx(x,{color:"danger",outline:!0,onClick:()=>{xs(!1),bs(ys),hs(!0),fs(null)},disabled:ks,children:"Delete"}),s.jsxs("div",{className:"flex gap-3",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{xs(!1),fs(null)},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:async()=>{if(ys){Cs(!0),es(null);try{const e=await N(ys.id,{name:ys.name,flood_policy:ys.floodPolicy});e.success?(await Js(),xs(!1),fs(null)):es(e.error||"Failed to update transport key")}catch(e){es(e instanceof Error?e.message:"Failed to update transport key")}finally{Cs(!1)}}},disabled:ks||!ys.name.trim(),children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Saving..."]}):"Save"})]})]})]})]})}),ps&&gs&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&hs(!1),role:"dialog","aria-modal":"true","aria-labelledby":"delete-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"delete-key-modal-title",className:"type-micro mb-4",children:"Delete Transport Key"}),s.jsxs("p",{className:"text-fg-secondary mb-4",children:["Are you sure you want to delete ",s.jsxs("strong",{className:"text-fg-primary",children:["'",gs.name,"'"]}),"?"]}),gs.children&&gs.children.length>0&&s.jsx("div",{className:"bg-sys-indigo/10 border border-sys-indigo/30 radius-inner p-3 mb-4",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(U,{className:"w-4 h-4 text-sys-indigo flex-shrink-0 mt-0.5"}),s.jsxs("div",{className:"text-sm text-fg-secondary",children:["This key has ",gs.children.length," child key(s). Deleting will also remove all children."]})]})}),s.jsxs("div",{className:"flex justify-end gap-3",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{hs(!1),bs(null)},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"danger",onClick:async()=>{if(gs){Cs(!0),es(null);try{const e=await w(gs.id);e.success?(await Js(),hs(!1),bs(null),is(null)):es(e.error||"Failed to delete transport key")}catch(e){es(e instanceof Error?e.message:"Failed to delete transport key")}finally{Cs(!1)}}},disabled:ks,children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Deleting..."]}):"Delete"})]})]})})]})}export{De as default}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{bM as a,bN as l,bO as n,T as r,bP as i,q as o,av as c,k as d,bQ as u,bR as m,B as x,bS as p,I as h}from"./index-CkRTgHHA.js";import{g as y,a as f,c as g,r as b,s as j,b as v,u as N,d as w}from"./system-OS35JnnX.js";import{C as k}from"./ConfirmModal-B6Rz8ROW.js";import{_ as C}from"./cosmograph-DqYT4sUA.js";import{L as S,a as _,X as F,b3 as T,C as E,d as P,c as R,b4 as D,as as I,I as L,k as A,n as z,b5 as M,R as K,b6 as V,b7 as O,b8 as $,b9 as H,a9 as q,ba as B,a3 as U,aX as X,o as G,D as W,bb as J}from"./vendor-icons-TO0PZKGR.js";import{N as Y}from"./NodeInformationCard-tOZNdmfP.js";import{i as Q,g as Z,s as ee,a as se,k as te}from"./keycap-sfx-Bpx9zhkt.js";import{C as ae,P as le,a as ne,B as re}from"./PageLayout-BWMUVZgC.js";import{R as ie,C as oe}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./DataBox-DpDXI-WX.js";const ce=1500,de="h-[38px]",ue="h-[32px]",me="px-3",xe="px-2.5",pe="rounded-lg";function he({label:a,value:l,editValue:n,onSave:r,type:i="text",suffix:o,placeholder:c,readOnly:d=!1,layout:u="stacked",min:m,max:x,step:p,maxLength:h,description:y,className:f}){const[g,b]=e.useState(!1),[j,v]=e.useState(""),[N,w]=e.useState("idle"),k=e.useRef(null),C=e.useRef(!0),E=e.useRef(null),P=!d&&!!r;e.useEffect(()=>(C.current=!0,()=>{C.current=!1,E.current&&clearTimeout(E.current)}),[]);const R=e.useCallback(()=>{P&&(v(n??l),b(!0),w("idle"),requestAnimationFrame(()=>{var e;return null==(e=k.current)?void 0:e.select()}))},[P,n,l]),D=e.useCallback(()=>{b(!1),v(""),w("idle")},[]),I=e.useCallback(async()=>{if(r&&"loading"!==N)if(j!==(n??l)){E.current&&clearTimeout(E.current),w("loading");try{if(await r(j),!C.current)return;w("success"),b(!1),E.current=setTimeout(()=>{C.current&&w("idle")},ce)}catch{if(!C.current)return;w("error"),E.current=setTimeout(()=>{C.current&&w("idle")},ce)}}else D()},[r,j,n,l,D,N]),L=e.useCallback(e=>{"Enter"===e.key?(e.preventDefault(),I()):"Escape"===e.key&&(e.preventDefault(),D())},[I,D]);return"inline"===u?s.jsxs("div",{className:t("group flex items-center justify-between gap-3",f),children:[s.jsx("label",{className:"type-label text-fg-muted truncate",children:a}),g?s.jsxs("div",{className:t(ue,pe,xe,"flex items-center transition-all","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20","min-w-[100px]"),children:[s.jsx("input",{ref:k,type:i,value:j,onChange:e=>v(e.target.value),onKeyDown:L,placeholder:c,min:m,max:x,step:p,maxLength:h,disabled:"loading"===N,className:t("bg-transparent text-fg-primary focus:outline-none type-data flex-1 min-w-0",o?"w-12 text-right":"w-full")}),o&&s.jsx("span",{className:"text-fg-muted type-data ml-1 shrink-0",children:o}),s.jsx("div",{className:"flex items-center gap-0.5 ml-2 shrink-0",children:"loading"===N?s.jsx(S,{className:"w-3.5 h-3.5 text-fg-muted animate-spin"}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:I,className:"p-0.5 rounded hover:bg-sys-green/15 text-sys-green transition-colors",title:"Save (Enter)",children:s.jsx(_,{className:"w-3 h-3"})}),s.jsx("button",{onClick:D,className:"p-0.5 rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",title:"Cancel (Esc)",children:s.jsx(F,{className:"w-3 h-3"})})]})})]}):s.jsxs("div",{className:t(ue,pe,xe,"flex items-center justify-end transition-all min-w-[80px]","bg-input-bg border border-input-border",P&&"cursor-pointer hover:border-edge-strong"),onClick:P?R:void 0,children:[s.jsx("span",{className:"type-data text-fg-primary",children:l}),"success"===N&&s.jsx(_,{className:"w-3 h-3 text-sys-green ml-1.5 shrink-0"}),"error"===N&&s.jsx(F,{className:"w-3 h-3 text-sys-red ml-1.5 shrink-0"}),"idle"===N&&P&&s.jsx(T,{className:"w-3 h-3 text-fg-muted ml-1.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0"})]})]}):s.jsxs("div",{className:t("group",f),children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:a}),g?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:t(de,pe,me,"flex items-center transition-all","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20"),children:[s.jsx("input",{ref:k,type:i,value:j,onChange:e=>v(e.target.value),onKeyDown:L,placeholder:c,min:m,max:x,step:p,maxLength:h,disabled:"loading"===N,className:"w-full bg-transparent text-fg-primary focus:outline-none type-data flex-1 min-w-0"}),o&&s.jsx("span",{className:"text-fg-muted type-data ml-1 shrink-0",children:o}),s.jsx("div",{className:"flex items-center gap-0.5 ml-2 shrink-0",children:"loading"===N?s.jsx(S,{className:"w-3.5 h-3.5 text-fg-muted animate-spin"}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:I,className:"p-1 rounded hover:bg-sys-green/15 text-sys-green transition-colors",title:"Save (Enter)",children:s.jsx(_,{className:"w-3.5 h-3.5"})}),s.jsx("button",{onClick:D,className:"p-1 rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",title:"Cancel (Esc)",children:s.jsx(F,{className:"w-3.5 h-3.5"})})]})})]}),y&&s.jsx("p",{className:"type-data-xs text-fg-muted mt-1 ml-3",children:y})]}):s.jsxs("div",{className:t(de,pe,me,"flex items-center transition-all","bg-input-bg border border-input-border",P&&"cursor-pointer hover:border-edge-strong"),onClick:P?R:void 0,children:[s.jsx("span",{className:"type-data text-fg-primary flex-1 whitespace-nowrap",children:l}),"success"===N&&s.jsx(_,{className:"w-3.5 h-3.5 text-sys-green shrink-0"}),"error"===N&&s.jsx(F,{className:"w-3.5 h-3.5 text-sys-red shrink-0"}),"idle"===N&&P&&s.jsx(T,{className:"w-3.5 h-3.5 text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0"})]})]})}function ye({label:a,value:l,editValue:n,options:r,onSave:i,readOnly:o=!1,layout:c="stacked",className:d}){const[u,m]=e.useState(!1),[x,p]=e.useState(""),[h,y]=e.useState("idle"),f=e.useRef(null),g=e.useRef(!0),b=e.useRef(null),j=!o&&!!i;e.useEffect(()=>(g.current=!0,()=>{g.current=!1,b.current&&clearTimeout(b.current)}),[]);const v=e.useCallback(()=>{j&&(p(String(n)),m(!0),y("idle"),requestAnimationFrame(()=>{var e;return null==(e=f.current)?void 0:e.focus()}))},[j,n]),N=e.useCallback(()=>{m(!1),p(""),y("idle")},[]),w=e.useCallback(async()=>{if(i&&"loading"!==h)if(x!==String(n)){b.current&&clearTimeout(b.current),y("loading");try{if(await i(x),!g.current)return;y("success"),m(!1),b.current=setTimeout(()=>{g.current&&y("idle")},ce)}catch{if(!g.current)return;y("error"),b.current=setTimeout(()=>{g.current&&y("idle")},ce)}}else N()},[i,x,n,N,h]),k=e.useCallback(e=>{"Escape"===e.key&&(e.preventDefault(),N())},[N]),C="inline"===c,T=C?ue:de,P=C?xe:me,R=s.jsxs("div",{className:t(T,pe,P,"flex items-center transition-all relative","bg-transparent border border-sys-blue/50 ring-1 ring-sys-blue/20",C&&"min-w-[100px]"),children:[s.jsx("select",{ref:f,value:x,onChange:e=>p(e.target.value),onKeyDown:k,disabled:"loading"===h,className:t("bg-transparent text-fg-primary focus:outline-none appearance-none cursor-pointer type-data flex-1 min-w-0","pr-6"),children:r.map(e=>s.jsx("option",{value:e.value,children:e.label},String(e.value)))}),s.jsx(E,{className:"absolute right-auto w-3.5 h-3.5 text-fg-muted pointer-events-none",style:{right:"loading"===h?"2rem":"3.5rem"}}),s.jsx("div",{className:"flex items-center gap-0.5 ml-1 shrink-0",children:"loading"===h?s.jsx(S,{className:t("text-fg-muted animate-spin",C?"w-3 h-3":"w-3.5 h-3.5")}):s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:w,className:t("rounded hover:bg-sys-green/15 text-sys-green transition-colors",C?"p-0.5":"p-1"),title:"Save",children:s.jsx(_,{className:C?"w-3 h-3":"w-3.5 h-3.5"})}),s.jsx("button",{onClick:N,className:t("rounded hover:bg-sys-red/15 text-fg-muted hover:text-sys-red transition-colors",C?"p-0.5":"p-1"),title:"Cancel (Esc)",children:s.jsx(F,{className:C?"w-3 h-3":"w-3.5 h-3.5"})})]})})]}),D=s.jsxs("div",{className:t(T,pe,P,"flex items-center transition-all","bg-input-bg border border-input-border",j&&"cursor-pointer hover:border-edge-strong",C?"justify-end min-w-[80px]":""),onClick:j?v:void 0,children:[s.jsx("span",{className:t("type-data text-fg-primary",!C&&"flex-1"),children:l}),"success"===h&&s.jsx(_,{className:t("text-sys-green shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")}),"error"===h&&s.jsx(F,{className:t("text-sys-red shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")}),"idle"===h&&j&&s.jsx(E,{className:t("text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity shrink-0",C?"w-3 h-3 ml-1.5":"w-3.5 h-3.5")})]});return C?s.jsxs("div",{className:t("group flex items-center justify-between",d),children:[s.jsx("label",{className:"type-label text-fg-muted shrink-0",children:a}),u?R:D]}):s.jsxs("div",{className:t("group",d),children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:a}),u?R:D]})}async function fe(e){return a("/api/update_web_config",{method:"POST",body:JSON.stringify(e)})}e.memo(function(){const{theme:e}=l(),{themeId:t}=e,a=n.find(e=>e.meta.id===t)??n[0];return s.jsx("div",{className:"h-10 flex items-center justify-center",children:s.jsx("span",{className:"font-medium transition-all duration-300 leading-none text-center text-fg-secondary",style:{fontFamily:"Inter, system-ui, sans-serif",fontSize:"clamp(0.75rem, 0.6rem + 1.5vw, 1.1rem)",letterSpacing:"-0.02em"},children:a.meta.name})})});const ge=e.memo(function({compact:e=!1}){const{theme:a,setTheme:r}=l(),{themeId:i}=a;return s.jsx("div",{className:t("grid grid-cols-2 gap-2",e?"w-full min-w-0 self-stretch":"w-full"),children:[...n].reverse().map(a=>{const l=i===a.meta.id,n=a.meta.isDark;return s.jsxs("button",{type:"button",title:a.meta.name,className:t("flex flex-row items-stretch radius-inner transition-all duration-200 ease-out overflow-hidden cursor-pointer",e&&"h-6",l?"ring-2 ring-sys-blue scale-[1.02]":"opacity-70 hover:opacity-100"),onClick:()=>r(a.meta.id),children:[s.jsx("div",{className:t("flex-1 h-full",n?"bg-[#18181b]":"bg-[#EFF0F1]")}),s.jsx("div",{className:"flex flex-col h-full",children:a.display.palette.map((e,t)=>s.jsx("div",{className:"flex flex-1",children:e.map((e,t)=>s.jsx("div",{className:"w-2 h-full",style:{backgroundColor:e}},t))},t))})]},a.meta.id)})})});let be=!1,je=null;const ve=e.memo(function(){const{theme:t,setTheme:a}=l(),{themeId:n}=t,i="breeze dark"===n,o=e.useCallback(e=>{a(e?"breeze dark":"breeze light")},[a]);return s.jsx(r,{enabled:i,onChange:o,label:s.jsxs(s.Fragment,{children:["Dark Mode: ",i?s.jsx(P,{className:"w-3.5 h-3.5 text-sys-blue inline"}):s.jsx(R,{className:"w-3.5 h-3.5 text-[#e8a517] inline"})]}),tooltip:"Switch between dark and light mode",size:"md"})}),Ne=e.memo(function({layout:t="horizontal"}){return e.useEffect(()=>{!async function(){be||je||(je=(async()=>{try{await Promise.all([C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.l),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.a),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.b),__vite__mapDeps([0,1])),C(()=>import("./vendor-fonts-CRZaZSFf.js").then(e=>e.c),__vite__mapDeps([0,1]))]),be=!0}catch(e){console.warn("Failed to load theme fonts:",e)}})())}()},[]),"toggle-only"===t?s.jsx(ve,{}):"thumbnails-only"===t?s.jsx(ge,{}):"vertical"===t?s.jsxs("div",{className:"flex flex-col items-start gap-3",children:[s.jsx(ve,{}),s.jsx(ge,{})]}):s.jsxs("div",{className:"flex items-stretch gap-4",children:[s.jsx("div",{className:"flex-shrink-0 flex items-start",children:s.jsx(ve,{})}),s.jsx(ge,{compact:!0})]})}),we=2e3;function ke(s,t,a){const[l,n]=e.useState("idle"),[r,i]=e.useState(null),o=e.useRef(!0),c=e.useRef(null),d=e.useRef(null),u=e.useRef(!1),m=e.useRef("idle"),x=e.useRef(s),p=e.useRef(t),h=e.useRef(a);return m.current=l,x.current=s,p.current=t,h.current=a,e.useEffect(()=>(o.current=!0,()=>{o.current=!1,c.current&&clearTimeout(c.current),d.current&&clearTimeout(d.current)}),[]),{enabled:null!==r?r:s,status:l,toggle:e.useCallback(async e=>{if("loading"===m.current)return;const s=x.current;c.current&&clearTimeout(c.current),d.current&&clearTimeout(d.current),u.current=!1,i(e),n("loading"),c.current=setTimeout(()=>{!u.current&&o.current&&(i(s),n("error"),d.current=setTimeout(()=>{o.current&&(n("idle"),i(null))},we))},1e4);try{if(await p.current(e),u.current=!0,c.current&&clearTimeout(c.current),!o.current)return;n("success"),d.current=setTimeout(()=>{var e;o.current&&(n("idle"),i(null),null==(e=h.current)||e.call(h))},we)}catch{if(u.current=!0,c.current&&clearTimeout(c.current),!o.current)return;i(s),n("error"),d.current=setTimeout(()=>{o.current&&(n("idle"),i(null))},we)}},[])}}function Ce(){const{latitude:a,longitude:l,enabled:n,setLocation:r,enable:c,disable:d,clear:u}=i(),[m,x]=e.useState(!1),[p,h]=e.useState(""),[y,f]=e.useState(""),[g,b]=e.useState("idle"),[j,v]=e.useState(null),N=e.useRef(null),w=e.useRef(null),k=e.useRef(!0);e.useEffect(()=>(k.current=!0,()=>{k.current=!1,w.current&&clearTimeout(w.current)}),[]);const C=()=>{x(!1),v(null)};e.useEffect(()=>{if(!m)return;const e=e=>{"loading"!==g&&N.current&&!N.current.contains(e.target)&&C()};return document.addEventListener("mouseup",e),()=>document.removeEventListener("mouseup",e)},[m,g]);const E=null!==a&&null!==l;return s.jsx(ae,{children:s.jsxs("div",{ref:N,children:[s.jsxs("div",{className:"flex items-center justify-between mb-4",children:[s.jsx(o,{icon:s.jsx(D,{}),title:"Stealth"}),s.jsxs("div",{className:"flex items-center gap-1",children:[E&&!m&&s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:()=>{n?d():c()},className:t("relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2 mr-2",n?"bg-toggle-on border-toggle-on":"bg-toggle-off border-edge-subtle"),title:n?"Disable stealth location":"Enable stealth location",children:s.jsx("span",{className:t("inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg",n?"translate-x-5":"translate-x-0.5")})}),s.jsx("button",{onClick:()=>{u(),x(!1)},className:"p-2 rounded-lg transition-colors text-fg-muted hover:text-sys-red hover:bg-sys-red/10",title:"Clear stealth location",children:s.jsx(I,{className:"w-4 h-4"})})]}),m?s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:C,disabled:"loading"===g,className:t("p-2 rounded-lg transition-colors","loading"===g?"text-fg-muted cursor-not-allowed":"text-fg-muted hover:text-sys-red hover:bg-sys-red/10"),title:"Cancel",children:s.jsx(F,{className:"w-4 h-4"})}),s.jsx("button",{onClick:()=>{if("loading"===g)return;w.current&&clearTimeout(w.current);const e=((e,s)=>{const t=parseFloat(e),a=parseFloat(s);return isNaN(t)||isNaN(a)?"Please enter valid numbers":t<-90||t>90?"Latitude must be between -90 and 90":a<-180||a>180?"Longitude must be between -180 and 180":0===t&&0===a?"Coordinates (0, 0) are invalid":null})(p,y);if(e)return void v(e);b("loading"),v(null);const s=parseFloat(p),t=parseFloat(y);r(s,t),n||c(),b("success"),w.current=setTimeout(()=>{k.current&&(b("idle"),x(!1))},1e3)},disabled:"loading"===g,className:t("p-2 rounded-lg transition-colors","loading"===g?"text-sys-blue cursor-wait":"success"===g?"text-sys-green":"error"===g?"text-sys-red":"text-sys-green hover:bg-sys-green/10"),title:"Save",children:"loading"===g?s.jsx(S,{className:"w-4 h-4 animate-spin"}):"success"===g?s.jsx(_,{className:"w-4 h-4"}):"error"===g?s.jsx(F,{className:"w-4 h-4"}):s.jsx(_,{className:"w-4 h-4"})})]}):s.jsx("button",{onClick:()=>{h((null==a?void 0:a.toFixed(6))??""),f((null==l?void 0:l.toFixed(6))??""),v(null),x(!0)},className:"p-2 rounded-lg transition-colors text-fg-muted hover:text-fg-primary hover:bg-subtle",title:E?"Edit stealth location":"Set stealth location",children:s.jsx(T,{className:"w-4 h-4"})})]})]}),s.jsx("div",{className:"bg-sys-cyan/5 rounded-xl p-3 mb-4",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(L,{className:"w-4 h-4 text-sys-cyan flex-shrink-0 mt-0.5"}),s.jsxs("p",{className:"type-body-sm text-fg-muted",children:[s.jsx("span",{className:"text-fg-secondary",children:"Stealth mode"})," allows you to appear on the map and in topology analysis without broadcasting your location. Coordinates are stored locally in your browser only — ",s.jsx("span",{className:"text-sys-cyan",children:"never sent to config.yaml or the mesh"}),"."]})]})}),j&&s.jsx("div",{className:"text-xs mb-3 px-2 py-1.5 rounded-md text-sys-red bg-sys-red/10",children:j}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:m?"Latitude (°)":"Latitude"}),s.jsx("div",{className:t("h-[38px] rounded-full px-4 flex items-center transition-colors","bg-subtle-fill"),children:m?s.jsx("input",{type:"number",value:p,onChange:e=>h(e.target.value),step:"0.000001",min:"-90",max:"90",placeholder:"e.g. 34.052234",className:"w-full bg-transparent text-fg-primary focus:outline-none type-data placeholder:text-fg-muted/50"}):s.jsx("span",{className:t("type-data",E&&n?"text-fg-primary":"text-fg-muted"),children:E?a.toFixed(6):"Not set"})})]}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-1",children:m?"Longitude (°)":"Longitude"}),s.jsx("div",{className:t("h-[38px] rounded-full px-4 flex items-center transition-colors","bg-subtle-fill"),children:m?s.jsx("input",{type:"number",value:y,onChange:e=>f(e.target.value),step:"0.000001",min:"-180",max:"180",placeholder:"e.g. -118.243685",className:"w-full bg-transparent text-fg-primary focus:outline-none type-data placeholder:text-fg-muted/50"}):s.jsx("span",{className:t("type-data",E&&n?"text-fg-primary":"text-fg-muted"),children:E?l.toFixed(6):"Not set"})})]})]}),E&&!m&&s.jsx("div",{className:"mt-3 pt-3 border-t border-edge-subtle",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:t("w-2 h-2 rounded-full",n?"bg-sys-green":"bg-fg-muted")}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:n?"Stealth location active — you appear on maps with these coordinates":"Stealth location disabled — coordinates saved but not in use"})]})})]})})}const Se=[{value:7.8,label:"7.8 kHz"},{value:10.4,label:"10.4 kHz"},{value:15.6,label:"15.6 kHz"},{value:20.8,label:"20.8 kHz"},{value:31.25,label:"31.25 kHz"},{value:41.7,label:"41.7 kHz"},{value:62.5,label:"62.5 kHz"},{value:125,label:"125 kHz"},{value:250,label:"250 kHz"},{value:500,label:"500 kHz"}],_e=[5,6,7,8,9,10,11,12],Fe=[{value:5,label:"4/5"},{value:6,label:"4/6"},{value:7,label:"4/7"},{value:8,label:"4/8"}],Te="radioConfig";function Ee(e){if(!e)return"Never";const s=Date.now()-1e3*e,t=Math.floor(s/6e4),a=Math.floor(s/36e5),l=Math.floor(s/864e5);return t<1?"Just now":t<60?`${t}m ago`:a<24?`${a}h ago`:l<365?`${l}d ago`:`${Math.floor(l/365)}y ago`}function Pe({node:e,level:a,expandedKeys:l,selectedKeyId:n,globalFloodPolicy:r,onSelect:i,onToggle:o}){const c=l.has(e.id),d=n===e.id,u=e.children&&e.children.length>0,m="allow"===r;return s.jsxs("div",{children:[s.jsxs("div",{className:t("flex items-center gap-2 h-[36px] px-3 rounded-full cursor-pointer transition-colors",d?"bg-sys-blue/15":"hover:bg-subtle-fill",m&&"opacity-50 cursor-not-allowed"),style:{marginLeft:16*a+"px"},onClick:()=>!m&&i(e.id),children:[u?s.jsx("button",{onClick:s=>{s.stopPropagation(),o(e.id)},className:"p-1 hover:bg-subtle-fill-hover rounded-full transition-colors",children:s.jsx(W,{className:t("w-3.5 h-3.5 text-fg-muted transition-transform",c&&"rotate-90")})}):s.jsx("span",{className:"w-5"}),s.jsx(J,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),s.jsx("span",{className:"type-data text-fg-primary flex-1 truncate",children:e.name}),s.jsx("span",{className:"type-data-xs text-fg-muted hidden sm:inline",title:e.last_used?new Date(1e3*e.last_used).toLocaleString():void 0,children:Ee(e.last_used)}),s.jsx("span",{className:t("type-data-xs px-2 py-0.5 rounded-full","allow"===e.floodPolicy?"bg-sys-green/15 text-sys-green":"bg-sys-red/15 text-sys-red"),children:"allow"===e.floodPolicy?"Allow":"Deny"})]}),u&&c&&s.jsx("div",{children:e.children.map(e=>s.jsx(Pe,{node:e,level:a+1,expandedKeys:l,selectedKeyId:n,globalFloodPolicy:r,onSelect:i,onToggle:o},e.id))})]})}function Re(){const[a,l]=e.useState(Q),[n,i]=e.useState(Z),[o,c]=e.useState(!1),d=e.useCallback(e=>{l(e),ee(e)},[]),u=e.useCallback(e=>{const s=parseFloat(e.target.value);i(s),se(s)},[]),m=e.useCallback(async()=>{o||(c(!0),await te(),c(!1))},[o]);return s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsx(r,{enabled:a,onChange:d,label:s.jsxs(s.Fragment,{children:["Sound: ",s.jsx("span",{className:a?"text-sys-green":"text-sys-red",children:a?"On":"Off"})]}),tooltip:"Enable or disable UI sound effects and haptic audio feedback",size:"md"}),s.jsx(x,{color:"primary",outline:!0,onClick:m,disabled:!a||o,className:"w-16 justify-center",children:o?"…":"Test"})]}),s.jsxs("div",{className:t("flex items-center gap-3",!a&&"opacity-40 pointer-events-none"),children:[s.jsx("span",{className:"type-label text-fg-muted w-14 shrink-0",children:"Volume"}),s.jsx("input",{type:"range",min:0,max:1,step:.05,value:n,onChange:u,className:"flex-1 accent-sys-blue h-1.5 cursor-pointer"}),s.jsxs("span",{className:"data-box w-16 justify-center",children:[Math.round(100*n),"%"]})]})]})}function De(){var l,n,i,C,F,T;const{stats:E,setMode:P,clearModeMutation:R,setDutyCycleConfig:D,clearDutyCycleMutation:W,fetchStats:J,startMutation:Q,clearMutation:Z}=c(),ee=null==(l=null==E?void 0:E.config)?void 0:l.radio,se=null==(n=null==E?void 0:E.config)?void 0:n.repeater,te=null==(i=null==E?void 0:E.config)?void 0:i.duty_cycle,ce=(null==E?void 0:E.node_name)||(null==(C=null==E?void 0:E.config)?void 0:C.node_name)||"Unknown Node",de=(null==se?void 0:se.mode)??"forward",ue=(null==te?void 0:te.enforcement_enabled)??!1,me=null==(F=null==E?void 0:E.config)?void 0:F.delays,xe=e.useRef(!0);e.useEffect(()=>(xe.current=!0,()=>{xe.current=!1}),[]);const pe=null==(T=null==E?void 0:E.config)?void 0:T.web,[ge,be]=e.useState([]),[je,ve]=e.useState(!1),[we,Ee]=e.useState(null),[De,Ie]=e.useState(!1),[Le,Ae]=e.useState(""),[ze,Me]=e.useState(null),[Ke,Ve]=e.useState(!1),[Oe,$e]=e.useState(null),[He,qe]=e.useState(!1),[Be,Ue]=e.useState(!1),[Xe,Ge]=e.useState(!1),[We,Je]=e.useState([]),[Ye,Qe]=e.useState(!1),[Ze,es]=e.useState(null),[ss,ts]=e.useState(()=>"allow"===localStorage.getItem("pymc:globalFloodPolicy")?"allow":"deny"),as=e.useCallback(e=>{ts(e),localStorage.setItem("pymc:globalFloodPolicy",e)},[]),[ls,ns]=e.useState(!1),[rs,is]=e.useState(null),[os,cs]=e.useState(new Set),[ds,us]=e.useState(!1),[ms,xs]=e.useState(!1),[ps,hs]=e.useState(!1),[ys,fs]=e.useState(null),[gs,bs]=e.useState(null),[js,vs]=e.useState(""),[Ns,ws]=e.useState("allow"),[ks,Cs]=e.useState(!1),[Ss,_s]=e.useState(!0),[Fs,Ts]=e.useState(!1),[Es,Ps]=e.useState(!0),[Rs,Ds]=e.useState("idle"),[Is,Ls]=e.useState(!1),[As,zs]=e.useState(!1),Ms=e.useCallback(()=>{const e=null==me?void 0:me.tx_delay_factor;return e&&"object"==typeof e&&"parsedValue"in e?e.parsedValue??1:"number"==typeof e?e:1},[me]),Ks=e.useCallback(()=>{const e=null==me?void 0:me.direct_tx_delay_factor;return"number"==typeof e?e:.5},[me]),Vs=e.useCallback(()=>{const e=null==te?void 0:te.max_airtime_percent;return"number"==typeof e?e:e&&"object"==typeof e&&"parsedValue"in e?e.parsedValue??6:6},[te]),Os=ke("forward"===de,async e=>{await P(e?"forward":"monitor")},R),$s=ke(ue,async e=>{await D({max_airtime_percent:Vs(),enforcement_enabled:e})},W),Hs=ke((null==pe?void 0:pe.cors_enabled)??!1,async e=>{var s;const t=await fe({web:{cors_enabled:e}});if(!t.success&&!(null==(s=t.data)?void 0:s.persisted))throw new Error("CORS update failed");await J()}),qs=e.useCallback(async e=>{Q(Te);try{const s=await d(e);if(!s.success)throw new Error(s.error||"Failed to save");await J({force:!0}).catch(()=>{})}finally{Z(Te)}},[Q,Z,J]);e.useEffect(()=>{(async()=>{Ps(!0);try{const e=await g();e.success&&e.data?Ts(e.data.exists):Ts(!1);const s=null==pe?void 0:pe.web_path;_s(!s||""===s)}catch{Ts(!1)}finally{Ps(!1)}})()},[null==pe?void 0:pe.web_path]);const Bs=async e=>{var s;if("loading"!==Rs){Ds("loading");try{const t=await fe({web:{web_path:e?null:"/opt/pymc_console/web/html"}});if(!xe.current)return;t.success||(null==(s=t.data)?void 0:s.persisted)?(_s(e),Ds("success"),Ls(!0),setTimeout(()=>{xe.current&&Ds("idle")},2e3)):(Ds("error"),setTimeout(()=>{xe.current&&Ds("idle")},2e3))}catch{if(!xe.current)return;Ds("error"),setTimeout(()=>{xe.current&&Ds("idle")},2e3)}}},Us=e.useCallback(async()=>{ve(!0),Ee(null);try{const e=await async function(){return a("/auth/tokens")}();be(e.tokens||[])}catch(e){Ee(e instanceof Error?e.message:"Failed to fetch tokens")}finally{ve(!1)}},[]);e.useEffect(()=>{Us()},[Us]);const Xs=async()=>{if(Le.trim()){qe(!0),Ee(null);try{const e=await async function(e){return a("/auth/tokens",{method:"POST",body:JSON.stringify({name:e})})}(Le.trim());Me(e.token||null),Ie(!1),Ve(!0),Ae(""),await Us()}catch(e){Ee(e instanceof Error?e.message:"Failed to create token")}finally{qe(!1)}}else Ee("Token name is required")},Gs=e=>e?new Date(1e3*e).toLocaleString():"Never",Ws=e.useCallback(e=>{const s=new Map,t=[];return e.forEach(e=>{const t={id:e.id,name:e.name,floodPolicy:e.flood_policy,transport_key:e.transport_key,last_used:e.last_used,parent_id:e.parent_id,children:[]};s.set(e.id,t)}),s.forEach(e=>{e.parent_id&&s.has(e.parent_id)?s.get(e.parent_id).children.push(e):t.push(e)}),t},[]),Js=e.useCallback(async()=>{Qe(!0),es(null);try{const e=await y();if(e.success&&e.data){const s=Ws(e.data);Je(s),is(e=>{if(null===e)return null;const t=s=>{for(const a of s){if(a.id===e)return!0;if(a.children&&t(a.children))return!0}return!1};return t(s)?e:null})}else es(e.error||"Failed to load transport keys")}catch(e){es(e instanceof Error?e.message:"Unknown error occurred")}finally{Qe(!1)}},[Ws]);e.useEffect(()=>{Js(),f().then(e=>{e.success&&e.data&&as(e.data.global_flood_allow?"allow":"deny")}).catch(()=>{})},[Js]);const Ys=e.useCallback((e,s)=>{for(const t of e){if(t.id===s)return t;if(t.children){const e=Ys(t.children,s);if(e)return e}}return null},[]),Qs=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);return null==e?void 0:e.name},[rs,We,Ys]),Zs=e.useCallback(e=>{cs(s=>{const t=new Set(s);return t.has(e)?t.delete(e):t.add(e),t})},[]),et=async()=>{if(js.trim()){Cs(!0),es(null);try{const e=await v({name:js.trim(),flood_policy:Ns,parent_id:rs??void 0});e.success?(await Js(),us(!1),vs(""),ws("allow")):es(e.error||"Failed to add transport key")}catch(e){es(e instanceof Error?e.message:"Failed to add transport key")}finally{Cs(!1)}}else es("Key name is required")},st=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);e&&(fs({...e}),xs(!0))},[rs,We,Ys]);e.useEffect(()=>{const e=e=>{"Escape"===e.key&&(ds&&(us(!1),vs(""),ws("allow")),ms&&(xs(!1),fs(null)),ps&&(hs(!1),bs(null)),De&&(Ie(!1),Ae("")),Ke&&(Ve(!1),Me(null)))};if(ds||ms||ps||De||Ke)return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[ds,ms,ps,De,Ke]);const tt=e.useCallback(()=>{if(!rs)return;const e=Ys(We,rs);e&&(bs(e),hs(!0))},[rs,We,Ys]);return s.jsxs(le,{children:[s.jsx(ne,{title:"Configuration",icon:s.jsx(A,{})}),s.jsxs(re,{children:[s.jsxs(ie,{template:"standard",children:[s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(z,{}),title:"Repeater Settings"}),se?s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsx("div",{className:"col-span-2",children:s.jsx(he,{label:"Node Name",value:ce,onSave:async e=>qs({node_name:e}),placeholder:"Enter node name",maxLength:50})}),s.jsx(he,{label:"Latitude",value:0!==se.latitude?se.latitude.toFixed(6):"Not set",editValue:String(se.latitude),type:"number",suffix:"°",step:1e-6,min:-90,max:90,onSave:async e=>qs({latitude:parseFloat(e)})}),s.jsx(he,{label:"Longitude",value:0!==se.longitude?se.longitude.toFixed(6):"Not set",editValue:String(se.longitude),type:"number",suffix:"°",step:1e-6,min:-180,max:180,onSave:async e=>qs({longitude:parseFloat(e)})}),s.jsx(he,{label:"Advert Interval",value:se.send_advert_interval_hours>0?`${se.send_advert_interval_hours}h`:"Disabled",editValue:String(se.send_advert_interval_hours),type:"number",suffix:"hours",min:0,max:48,description:"0 = disabled, 3-48 hours",onSave:async e=>qs({flood_advert_interval_hours:parseInt(e,10)})}),s.jsx(he,{label:"Score-based TX",value:se.use_score_for_tx?"Enabled":"Disabled",readOnly:!0})]}):s.jsx("p",{className:"text-fg-muted",children:"Loading repeater settings..."})]})}),s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(M,{}),title:"Radio Configuration"}),ee?s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsx(he,{label:"Frequency",value:u(ee.frequency),editValue:(ee.frequency/1e6).toFixed(3),type:"number",suffix:"MHz",step:.001,min:400,max:930,onSave:async e=>qs({frequency_mhz:parseFloat(e)})}),s.jsx(he,{label:"TX Power",value:`${ee.tx_power} dBm`,editValue:String(ee.tx_power),type:"number",suffix:"dBm",min:2,max:30,onSave:async e=>qs({tx_power:parseInt(e,10)})}),s.jsx(ye,{label:"Bandwidth",value:m(ee.bandwidth),editValue:ee.bandwidth/1e3,options:Se,onSave:async e=>qs({bandwidth_khz:parseFloat(e)})}),s.jsx(ye,{label:"Spreading Factor",value:`SF${ee.spreading_factor}`,editValue:ee.spreading_factor,options:_e.map(e=>({value:e,label:`SF${e}`})),onSave:async e=>qs({spreading_factor:parseInt(e,10)})}),s.jsx(ye,{label:"Coding Rate",value:`4/${ee.coding_rate}`,editValue:ee.coding_rate,options:Fe,onSave:async e=>qs({coding_rate:parseInt(e,10)})}),s.jsx(he,{label:"Preamble",value:`${ee.preamble_length} symbols`,readOnly:!0})]}):s.jsx("p",{className:"text-fg-muted",children:"Loading radio configuration..."})]})})]}),s.jsxs(ie,{template:"standard",children:[s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(K,{}),title:"Operating Mode"}),s.jsx("p",{className:"type-label text-fg-muted mb-3",children:"Control how the repeater handles packets"}),s.jsxs("div",{className:"flex flex-col lg:flex-row gap-4",children:[s.jsxs("div",{className:"flex-1 space-y-4",children:[s.jsx(r,{enabled:Os.enabled,onChange:Os.toggle,label:"Repeat",tooltip:"Toggles repeater or monitor mode. In monitor mode, the repeater will not repeat packets from the mesh.",status:Os.status,size:"md"}),s.jsx(r,{enabled:$s.enabled,onChange:$s.toggle,label:"Duty Cycle",tooltip:"Limit transmission time to comply with airtime utilization regulations",status:$s.status,size:"md"}),s.jsx(he,{label:"Max Airtime",layout:"inline",value:`${Vs().toFixed(1)}%`,editValue:String(Vs()),type:"number",suffix:"%",step:.5,min:.1,max:100,onSave:async e=>{await D({max_airtime_percent:parseFloat(e),enforcement_enabled:ue}),W()}})]}),s.jsx("div",{className:"hidden lg:block w-px bg-border-subtle"}),s.jsxs("div",{className:"flex-1 pt-4 lg:pt-0 border-t lg:border-t-0 border-edge-subtle",children:[s.jsx("label",{className:"type-label text-fg-muted block mb-3",children:"TX Delays"}),s.jsxs("div",{className:"space-y-3",children:[s.jsx(he,{label:"Flood",layout:"inline",value:`${Ms().toFixed(2)}x`,editValue:String(Ms()),type:"number",suffix:"x",step:.1,min:0,max:5,onSave:async e=>qs({tx_delay_factor:parseFloat(e)})}),s.jsx(he,{label:"Direct",layout:"inline",value:`${Ks().toFixed(2)}s`,editValue:String(Ks()),type:"number",suffix:"s",step:.1,min:0,max:5,onSave:async e=>qs({direct_tx_delay_factor:parseFloat(e)})})]})]})]})]})}),s.jsx(oe,{span:12,md:6,children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(A,{}),title:"App Settings"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:"Appearance and web server options."}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(r,{enabled:Hs.enabled,onChange:Hs.toggle,label:"Enable CORS",tooltip:"Allow cross-origin API access",status:Hs.status,size:"md"}),s.jsx("div",{children:s.jsx(Ne,{})}),s.jsx(Re,{})]})]})})]}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4",children:[s.jsx(o,{icon:s.jsx(V,{}),title:"Regions Transport Keys",subtitle:"Manage regional key hierarchy for flood control"}),s.jsxs("div",{className:"flex gap-2 flex-wrap",children:[s.jsxs(x,{color:"primary",outline:!0,onClick:()=>us(!0),disabled:"allow"===ss,children:[s.jsx(O,{"data-slot":"icon"}),"Add"]}),s.jsx(x,{color:"primary",outline:!0,onClick:st,disabled:!rs||"allow"===ss,children:"Edit"}),s.jsx(x,{color:"danger",outline:!0,onClick:tt,disabled:!rs||"allow"===ss,children:"Delete"})]})]}),s.jsx("div",{className:"bg-subtle-fill radius-inner p-4 mb-4",children:s.jsx(r,{enabled:"deny"===ss,onChange:e=>(async e=>{ns(!0),es(null);try{const s=await j("allow"===e);s.success?as(e):es(s.error||"Failed to update global flood policy")}catch(s){es(s instanceof Error?s.message:"Failed to update global flood policy")}finally{ns(!1)}})(e?"deny":"allow"),label:s.jsxs(s.Fragment,{children:["Require Transport Keys: ",s.jsx("span",{className:"deny"===ss?"text-sys-green":"text-sys-red",children:"deny"===ss?"On":"Off"})]}),tooltip:"When enabled, only packets with matching transport keys are forwarded. When disabled, all packets flood freely.",status:ls?"loading":"idle",disabled:ls,dangerOff:!0,size:"md",className:"flex-row-reverse justify-between w-full"})}),Ze&&s.jsx("div",{className:"type-body-sm mb-3 px-3 py-2 rounded-full text-sys-red bg-sys-red/10",children:Ze}),s.jsx("div",{className:"bg-subtle-fill radius-inner p-4 min-h-[120px]",children:Ye?s.jsxs("div",{className:"flex items-center justify-center py-6",children:[s.jsx(S,{className:"w-5 h-5 animate-spin text-sys-blue mr-2"}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:"Loading transport keys..."})]}):0===We.length?s.jsxs("div",{className:"text-center py-6",children:[s.jsx("div",{className:"w-12 h-12 rounded-full bg-subtle-fill mx-auto mb-3 flex items-center justify-center",children:s.jsx(V,{className:"w-6 h-6 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No transport keys found"}),s.jsx("p",{className:"type-body-sm text-fg-muted/70 mt-1",children:"Add your first transport key to get started"})]}):s.jsx("div",{className:"space-y-1",children:We.map(e=>s.jsx(Pe,{node:e,level:0,expandedKeys:os,selectedKeyId:rs,globalFloodPolicy:ss,onSelect:is,onToggle:Zs},e.id))})})]})}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4",children:[s.jsx(o,{icon:s.jsx($,{}),title:"API Tokens",subtitle:"Manage API tokens for machine-to-machine authentication"}),s.jsxs(x,{color:"primary",outline:!0,onClick:()=>Ie(!0),children:[s.jsx(O,{"data-slot":"icon"}),"Create Token"]})]}),s.jsx("div",{className:"bg-sys-cyan/5 radius-inner p-4 mb-4",children:s.jsxs("div",{className:"flex gap-3",children:[s.jsx("div",{className:"w-8 h-8 rounded-full bg-sys-cyan/20 flex items-center justify-center flex-shrink-0",children:s.jsx(L,{className:"w-4 h-4 text-sys-cyan"})}),s.jsxs("div",{className:"type-body-sm text-fg-muted",children:[s.jsxs("p",{children:[s.jsx("span",{className:"text-fg-secondary",children:"API tokens"})," are used for machine-to-machine authentication. Include the token in the ",s.jsx("code",{className:"type-code bg-sys-cyan/20 px-1.5 py-0.5 rounded-full text-sys-cyan",children:"X-API-Key"})," header when making API requests."]}),s.jsx("p",{className:"mt-1 text-fg-muted/70",children:"Tokens are only shown once at creation. Store them securely."})]})]})}),we&&s.jsx("div",{className:"type-body-sm mb-3 px-3 py-2 rounded-full text-sys-red bg-sys-red/10",children:we}),je&&0===ge.length?s.jsxs("div",{className:"flex items-center justify-center py-6",children:[s.jsx(S,{className:"w-5 h-5 animate-spin text-sys-blue mr-2"}),s.jsx("span",{className:"type-body-sm text-fg-muted",children:"Loading tokens..."})]}):ge.length>0?s.jsx("div",{className:"space-y-2",children:ge.map(e=>s.jsx("div",{className:"bg-subtle-fill hover:bg-subtle-fill-strong radius-inner p-4 transition-base",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex items-center gap-3 flex-1 min-w-0",children:[s.jsx("div",{className:"w-10 h-10 rounded-full bg-sys-blue/10 flex items-center justify-center flex-shrink-0",children:s.jsx($,{className:"w-5 h-5 text-sys-blue"})}),s.jsxs("div",{className:"min-w-0 flex-1",children:[s.jsx("h3",{className:"type-body text-fg-primary font-medium truncate",children:e.name}),s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-0.5",children:[s.jsxs("span",{className:"type-data-sm text-fg-muted truncate",children:["Created: ",Gs(e.created_at)]}),s.jsxs("span",{className:"type-data-sm text-fg-muted truncate",children:["Last used: ",Gs(e.last_used)]})]})]})]}),s.jsxs(x,{color:"danger",outline:!0,onClick:()=>$e({id:e.id,name:e.name}),disabled:Be,children:[s.jsx(I,{"data-slot":"icon"}),"Revoke"]})]})},e.id))}):s.jsxs("div",{className:"bg-subtle-fill radius-inner p-6 text-center",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx($,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("h3",{className:"type-body text-fg-primary font-medium mb-1",children:"No API Tokens"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:"Create a token to enable API access"}),s.jsx(x,{color:"primary",outline:!0,onClick:()=>Ie(!0),children:"Create Your First Token"})]})]})}),s.jsx(ie,{template:"auto",children:s.jsxs(ae,{neomorphic:!0,children:[s.jsx(o,{icon:s.jsx(H,{}),title:"Web Frontend",subtitle:"Choose which web interface to use",className:"mb-4"}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"space-y-3",children:[s.jsxs("label",{className:t("flex items-start gap-3 p-4 bg-subtle-fill radius-card border-2 cursor-pointer transition-base",Ss?"border-sys-blue bg-sys-blue/5":"border-transparent hover:border-sys-blue/30","loading"===Rs&&"opacity-50 pointer-events-none"),children:[s.jsx("input",{type:"radio",name:"frontend",checked:Ss,onChange:()=>Bs(!0),disabled:"loading"===Rs,className:"mt-1 h-4 w-4 text-sys-blue focus:ring-sys-blue focus:ring-offset-bg-elevated"}),s.jsxs("div",{className:"flex-1",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("div",{className:"type-body text-fg-primary font-medium",children:"Default Frontend"}),s.jsx("a",{href:"https://github.com/rightup/pyMC_Repeater",target:"_blank",rel:"noopener noreferrer",onClick:e=>e.stopPropagation(),className:"type-data-xs bg-sys-cyan/15 text-sys-cyan px-2.5 py-0.5 rounded-full font-medium hover:bg-sys-cyan/25 transition-colors",children:"@RightUp"})]}),s.jsx("div",{className:"type-body-sm text-fg-muted mt-1",children:"Built-in pyMC Repeater web interface"}),s.jsx("div",{className:"type-data-xs text-fg-muted/60 mt-1",children:"/opt/pymc_repeater/repeater/web/html"})]})]}),s.jsxs("label",{className:t("flex items-start gap-3 p-4 bg-subtle-fill radius-card border-2 cursor-pointer transition-base",Ss?"border-transparent hover:border-sys-blue/30":"border-sys-blue bg-sys-blue/5","loading"===Rs&&"opacity-50 pointer-events-none"),children:[s.jsx("input",{type:"radio",name:"frontend",checked:!Ss,onChange:()=>Bs(!1),disabled:"loading"===Rs,className:"mt-1 h-4 w-4 text-sys-blue focus:ring-sys-blue focus:ring-offset-bg-elevated"}),s.jsxs("div",{className:"flex-1",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx("div",{className:"type-body text-fg-primary font-medium",children:"PyMC Console"}),s.jsx("span",{className:"type-data-xs bg-sys-indigo/15 text-sys-indigo px-2.5 py-0.5 rounded-full font-medium",children:"@Treehouse ⚡"})]}),s.jsx("div",{className:"type-body-sm text-fg-muted mt-1",children:"Alternative web interface for pyMC Repeater"}),s.jsx("div",{className:"type-data-xs text-fg-muted/60 mt-1",children:"/opt/pymc_console/web/html"})]})]})]}),!Es&&s.jsx("div",{className:t("bg-subtle-fill radius-card p-4",Fs?"border border-sys-green/20":"border border-sys-cyan/20"),children:s.jsxs("div",{className:"flex items-start gap-3",children:[s.jsx("div",{className:t("w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0",Fs?"bg-sys-green/20":"bg-sys-cyan/20"),children:Fs?s.jsx(q,{className:"w-4 h-4 text-sys-green"}):s.jsx(L,{className:"w-4 h-4 text-sys-cyan"})}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"type-body text-fg-primary font-medium",children:Fs?"PyMC Console has been detected":"PyMC Console Not Installed"}),Fs?s.jsxs("p",{className:"type-body-sm text-fg-muted mt-1",children:["PyMC Console is installed at ",s.jsx("code",{className:"type-code bg-sys-green/10 px-1.5 py-0.5 rounded-full text-sys-green",children:"/opt/pymc_console/web/html"})]}):s.jsxs(s.Fragment,{children:[s.jsxs("p",{className:"type-body-sm text-fg-muted mt-1 mb-3",children:["PyMC Console must be installed at ",s.jsx("code",{className:"type-code bg-sys-cyan/10 px-1.5 py-0.5 rounded-full text-sys-cyan",children:"/opt/pymc_console/web/html"})," before selecting this option."]}),s.jsxs(x,{color:"primary",outline:!0,href:"https://github.com/dmduran12/pymc_console-dist",children:[s.jsx(B,{"data-slot":"icon"}),"PyMC Console Install Instructions"]})]})]})]})}),Is&&s.jsx("div",{className:"bg-subtle-fill radius-card p-4 border border-sys-indigo/30",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex items-start gap-3 flex-1",children:[s.jsx("div",{className:"w-8 h-8 rounded-full bg-sys-indigo/20 flex items-center justify-center flex-shrink-0",children:s.jsx(U,{className:"w-4 h-4 text-sys-indigo"})}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"type-body text-fg-primary font-medium",children:"Service restart required"}),s.jsx("p",{className:"type-body-sm text-fg-muted mt-1",children:"Web frontend changes will take effect after restarting the pymc-repeater service."})]})]}),s.jsx(x,{color:"warning",outline:!0,onClick:async()=>{if(!As){zs(!0);try{await b(),Ls(!1),setTimeout(()=>{window.location.reload()},2e3)}catch{Ls(!1),setTimeout(()=>{window.location.reload()},3e3)}}},disabled:As,children:As?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Restarting..."]}):s.jsxs(s.Fragment,{children:[s.jsx(X,{"data-slot":"icon"}),"Restart Now"]})})]})})]})]})}),E&&s.jsx(ie,{template:"auto",children:s.jsx(Y,{nodeName:ce,repeaterVersion:E.version,coreVersion:E.core_version,localHash:E.local_hash,publicKey:E.public_key})}),E&&(0===(null==se?void 0:se.latitude)||!(null==se?void 0:se.latitude))&&(0===(null==se?void 0:se.longitude)||!(null==se?void 0:se.longitude))&&s.jsx(ie,{template:"auto",children:s.jsx(Ce,{})})]}),De&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&Ie(!1),role:"dialog","aria-modal":"true","aria-labelledby":"create-token-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"create-token-modal-title",className:"type-micro mb-4",children:"Create API Token"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(p,{label:"Token Name",type:"text",value:Le,onChange:e=>Ae(e.target.value),placeholder:"e.g., Production Server, CI/CD Pipeline",description:"Give your token a descriptive name to identify its purpose",onKeyDown:e=>"Enter"===e.key&&Xs(),autoFocus:!0}),s.jsxs("div",{className:"flex justify-end gap-3 mt-6",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{Ie(!1),Ae(""),Ee(null)},disabled:He,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:Xs,disabled:He||!Le.trim(),children:He?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Creating..."]}):"Create Token"})]})]})]})}),Ke&&ze&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&Ve(!1),role:"dialog","aria-modal":"true","aria-labelledby":"show-token-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-lg w-full",children:[s.jsx("h3",{id:"show-token-modal-title",className:"type-micro mb-4",children:"Token Created Successfully"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx("div",{className:"bg-sys-indigo/10 border border-sys-indigo/30 radius-inner p-3",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(U,{className:"w-4 h-4 text-sys-indigo flex-shrink-0 mt-0.5"}),s.jsxs("div",{className:"text-sm text-fg-secondary",children:[s.jsx("strong",{children:"Save this token now!"})," For security reasons, it will not be shown again."]})]})}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-primary block mb-1.5",children:"Your API Token"}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx(h,{value:ze,readOnly:!0,className:"flex-1 font-mono"}),s.jsxs(x,{color:"primary",outline:!0,onClick:()=>{ze&&(navigator.clipboard.writeText(ze),Ge(!0),setTimeout(()=>Ge(!1),2e3))},children:[Xe?s.jsx(_,{"data-slot":"icon",className:"text-sys-green"}):s.jsx(G,{"data-slot":"icon"}),Xe?"Copied!":"Copy"]})]})]}),s.jsxs("div",{className:"bg-sys-cyan/10 border border-sys-cyan/30 radius-inner p-3",children:[s.jsx("p",{className:"text-sm text-fg-secondary mb-2",children:s.jsx("strong",{children:"Usage Example:"})}),s.jsxs("code",{className:"block bg-sys-cyan/20 px-3 py-2 rounded type-code text-sys-cyan overflow-x-auto",children:['curl -H "X-API-Key: ',ze.slice(0,12),'..." ',window.location.origin,"/api/stats"]})]}),s.jsx("div",{className:"flex justify-end mt-6",children:s.jsx(x,{color:"primary",onClick:()=>{Ve(!1),Me(null)},children:"Done"})})]})]})}),s.jsx(k,{isOpen:!!Oe,title:"Revoke API Token",message:`Are you sure you want to revoke the token '${null==Oe?void 0:Oe.name}'? This action cannot be undone.`,confirmLabel:Be?"Revoking...":"Revoke",cancelLabel:"Cancel",variant:"danger",onConfirm:async()=>{if(Oe){Ue(!0),Ee(null);try{await async function(e){return a(`/auth/tokens/${e}`,{method:"DELETE"})}(Oe.id),await Us(),$e(null)}catch(e){Ee(e instanceof Error?e.message:"Failed to revoke token")}finally{Ue(!1)}}},onCancel:()=>$e(null)}),ds&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&us(!1),role:"dialog","aria-modal":"true","aria-labelledby":"add-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"add-key-modal-title",className:"type-micro mb-4",children:"Add Transport Key"}),s.jsxs("div",{className:"space-y-4",children:[rs&&s.jsxs("div",{className:"bg-sys-cyan/10 border border-sys-cyan/30 radius-inner p-3 text-sm text-fg-secondary",children:["Adding as child of: ",s.jsx("strong",{className:"text-fg-primary",children:Qs()})]}),s.jsx(p,{label:"Key Name",type:"text",value:js,onChange:e=>vs(e.target.value),placeholder:"e.g., Region Name, Group Key",onKeyDown:e=>"Enter"===e.key&&et(),autoFocus:!0}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Flood Policy"}),s.jsxs("div",{className:"toggle-group w-full",children:[s.jsx("button",{onClick:()=>ws("deny"),className:t("toggle-group-item flex-1","deny"===Ns&&"active !text-sys-red"),children:"Deny"}),s.jsx("button",{onClick:()=>ws("allow"),className:t("toggle-group-item flex-1","allow"===Ns&&"active !text-sys-green"),children:"Allow"})]})]}),s.jsxs("div",{className:"flex justify-end gap-3 mt-6",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{us(!1),vs(""),ws("allow")},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:et,disabled:ks||!js.trim(),children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Adding..."]}):"Add Key"})]})]})]})}),ms&&ys&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&xs(!1),role:"dialog","aria-modal":"true","aria-labelledby":"edit-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"edit-key-modal-title",className:"type-micro mb-4",children:"Edit Transport Key"}),s.jsxs("div",{className:"space-y-4",children:[s.jsx(p,{label:"Key Name",type:"text",value:ys.name,onChange:e=>fs({...ys,name:e.target.value}),autoFocus:!0}),s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Flood Policy"}),s.jsxs("div",{className:"toggle-group w-full",children:[s.jsx("button",{onClick:()=>fs({...ys,floodPolicy:"deny"}),className:t("toggle-group-item flex-1","deny"===ys.floodPolicy&&"active !text-sys-red"),children:"Deny"}),s.jsx("button",{onClick:()=>fs({...ys,floodPolicy:"allow"}),className:t("toggle-group-item flex-1","allow"===ys.floodPolicy&&"active !text-sys-green"),children:"Allow"})]})]}),ys.transport_key&&s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Transport Key"}),s.jsx("code",{className:"block bg-input-bg px-3 py-2 radius-inner border border-input-border type-code text-fg-muted overflow-x-auto",children:ys.transport_key})]}),s.jsxs("div",{className:"flex justify-between gap-3 mt-6",children:[s.jsx(x,{color:"danger",outline:!0,onClick:()=>{xs(!1),bs(ys),hs(!0),fs(null)},disabled:ks,children:"Delete"}),s.jsxs("div",{className:"flex gap-3",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{xs(!1),fs(null)},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"primary",onClick:async()=>{if(ys){Cs(!0),es(null);try{const e=await N(ys.id,{name:ys.name,flood_policy:ys.floodPolicy});e.success?(await Js(),xs(!1),fs(null)):es(e.error||"Failed to update transport key")}catch(e){es(e instanceof Error?e.message:"Failed to update transport key")}finally{Cs(!1)}}},disabled:ks||!ys.name.trim(),children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Saving..."]}):"Save"})]})]})]})]})}),ps&&gs&&s.jsx("div",{className:"fixed inset-0 z-[10010] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm",onClick:e=>e.target===e.currentTarget&&hs(!1),role:"dialog","aria-modal":"true","aria-labelledby":"delete-key-modal-title",children:s.jsxs("div",{className:"surface-modal radius-card p-6 max-w-md w-full",children:[s.jsx("h3",{id:"delete-key-modal-title",className:"type-micro mb-4",children:"Delete Transport Key"}),s.jsxs("p",{className:"text-fg-secondary mb-4",children:["Are you sure you want to delete ",s.jsxs("strong",{className:"text-fg-primary",children:["'",gs.name,"'"]}),"?"]}),gs.children&&gs.children.length>0&&s.jsx("div",{className:"bg-sys-indigo/10 border border-sys-indigo/30 radius-inner p-3 mb-4",children:s.jsxs("div",{className:"flex gap-2",children:[s.jsx(U,{className:"w-4 h-4 text-sys-indigo flex-shrink-0 mt-0.5"}),s.jsxs("div",{className:"text-sm text-fg-secondary",children:["This key has ",gs.children.length," child key(s). Deleting will also remove all children."]})]})}),s.jsxs("div",{className:"flex justify-end gap-3",children:[s.jsx(x,{color:"muted",outline:!0,onClick:()=>{hs(!1),bs(null)},disabled:ks,children:"Cancel"}),s.jsx(x,{color:"danger",onClick:async()=>{if(gs){Cs(!0),es(null);try{const e=await w(gs.id);e.success?(await Js(),hs(!1),bs(null),is(null)):es(e.error||"Failed to delete transport key")}catch(e){es(e instanceof Error?e.message:"Failed to delete transport key")}finally{Cs(!1)}}},disabled:ks,children:ks?s.jsxs(s.Fragment,{children:[s.jsx(S,{"data-slot":"icon",className:"animate-spin"}),"Deleting..."]}):"Delete"})]})]})})]})}export{De as default}; diff --git a/frontend/dist/assets/ConfirmModal-XwU3yUZY.js b/frontend/dist/assets/ConfirmModal-B6Rz8ROW.js similarity index 92% rename from frontend/dist/assets/ConfirmModal-XwU3yUZY.js rename to frontend/dist/assets/ConfirmModal-B6Rz8ROW.js index 96395774..a92e4d10 100644 --- a/frontend/dist/assets/ConfirmModal-XwU3yUZY.js +++ b/frontend/dist/assets/ConfirmModal-B6Rz8ROW.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as n}from"./vendor-core-FtpmsTnh.js";import{Y as a,bG as r,_ as o,bT as i,B as l}from"./index-D7i6lQrq.js";import{a3 as t}from"./vendor-icons-TO0PZKGR.js";const c={danger:"text-sys-red",warning:"text-sys-indigo",default:"text-sys-blue"},m={danger:"danger",warning:"warning",default:"primary"},d=e.memo(function({isOpen:e,title:d="Confirm",message:x,confirmLabel:f="Confirm",cancelLabel:j="Cancel",variant:C="default",onConfirm:g,onCancel:p}){return s.jsxs(a,{open:e,onClose:p,size:"sm",children:[s.jsx(r,{icon:s.jsx(t,{className:n("w-5 h-5",c[C])}),title:d,onClose:p}),s.jsx(o,{children:s.jsx("p",{className:"text-sm text-fg-secondary",children:x})}),s.jsxs(i,{children:[s.jsx(l,{color:"muted",onClick:p,className:"flex-1",children:j}),s.jsx(l,{color:m[C],onClick:g,className:"flex-1",children:f})]})]})});export{d as C}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as n}from"./vendor-core-FtpmsTnh.js";import{Y as a,bG as r,_ as o,bT as i,B as l}from"./index-CkRTgHHA.js";import{a3 as t}from"./vendor-icons-TO0PZKGR.js";const c={danger:"text-sys-red",warning:"text-sys-indigo",default:"text-sys-blue"},m={danger:"danger",warning:"warning",default:"primary"},d=e.memo(function({isOpen:e,title:d="Confirm",message:x,confirmLabel:f="Confirm",cancelLabel:j="Cancel",variant:C="default",onConfirm:g,onCancel:p}){return s.jsxs(a,{open:e,onClose:p,size:"sm",children:[s.jsx(r,{icon:s.jsx(t,{className:n("w-5 h-5",c[C])}),title:d,onClose:p}),s.jsx(o,{children:s.jsx("p",{className:"text-sm text-fg-secondary",children:x})}),s.jsxs(i,{children:[s.jsx(l,{color:"muted",onClick:p,className:"flex-1",children:j}),s.jsx(l,{color:m[C],onClick:g,className:"flex-1",children:f})]})]})});export{d as C}; diff --git a/frontend/dist/assets/Contacts-Dlk8XXyy.js b/frontend/dist/assets/Contacts-CcN2zB34.js similarity index 94% rename from frontend/dist/assets/Contacts-Dlk8XXyy.js rename to frontend/dist/assets/Contacts-CcN2zB34.js index 49bc97c7..d8c06df9 100644 --- a/frontend/dist/assets/Contacts-Dlk8XXyy.js +++ b/frontend/dist/assets/Contacts-CcN2zB34.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ContactsMapMapLibre-CSieXgJu.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/consumer-registry-KuOoZhsq.js","assets/index-D7i6lQrq.js","assets/vendor-charts-C916_-gs.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/link-scoring-oriFkjrN.js","assets/ConfirmModal-XwU3yUZY.js","assets/DeepAnalysisModal-Ca6cBH6E.js","assets/geo-utils-DJn8DnxF.js","assets/useMapViewStore-1yyjXCM8.js","assets/BasemapLayer-CSqjQAiA.js","assets/vendor-geo-2MTwbTwv.js","assets/node-types-CiI69Tya.js","assets/easing-GXZYrvDD.js","assets/badge-colors-BxLppqaF.js","assets/LightSparkline-BAD3v4m9.js","assets/ping-5xLx9WS1.js","assets/PageLayout-QhCLxU34.js","assets/listbox-BG13Q7Di.js","assets/TimeRangeStepper-B5GfHny9.js","assets/chat-utils-DbM_TyxC.js","assets/SignalIndicator-fAt1Aewy.js","assets/CollisionExplorerModal-B2vZL8RO.js","assets/DataBox-DpDXI-WX.js","assets/maplibre-gl-B1CfjdFi.css","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-B2A_8ldG.css","assets/ContactsMapMapLibre-BwWOEply.css"])))=>i.map(i=>d[i]); -import{j as e,r as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{as as a,at as n,H as l,V as r,au as i,h as c,av as o,t as d,aw as m,ax as x,ay as h,r as u,az as p,aA as g,aB as f,v as j,W as b,D as N,aC as v,aD as y,e as w,I as k}from"./index-D7i6lQrq.js";import{p as C}from"./ping-5xLx9WS1.js";import{c as S}from"./node-types-CiI69Tya.js";import{P as M,a as R,B as P}from"./PageLayout-QhCLxU34.js";import{L,a as $}from"./listbox-BG13Q7Di.js";import{T as _}from"./TimeRangeStepper-B5GfHny9.js";import{_ as F}from"./cosmograph-DqYT4sUA.js";import{u as z,e as E,f as I,r as H}from"./consumer-registry-KuOoZhsq.js";import{e as T,g as O,a as D}from"./chat-utils-DbM_TyxC.js";import{a as V}from"./SignalIndicator-fAt1Aewy.js";import{C as U}from"./CollisionExplorerModal-B2vZL8RO.js";import{ah as B,a as A,ai as W,j as G,aj as q,R as K,a2 as J,ak as Q,al as X,A as Y,am as Z,T as ee,an as se,ao as te,ap as ae,aq as ne,a7 as le,L as re,ar as ie,as as ce,U as oe,at as de,a1 as me,X as xe,au as he,av as ue,a5 as pe,aw as ge}from"./vendor-icons-TO0PZKGR.js";import{D as fe}from"./DataBox-DpDXI-WX.js";import{C as je}from"./badge-colors-BxLppqaF.js";import{C as be}from"./ConfirmModal-XwU3yUZY.js";class Ne extends s.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var s;return this.state.hasError?e.jsx("div",{className:"map-container-16-9 flex items-center justify-center rounded-2xl surface-base",role:"alert","aria-live":"assertive",children:e.jsxs("div",{className:"text-center text-fg-muted p-4",children:[e.jsx("p",{className:"text-lg mb-2",children:"Map failed to load"}),e.jsx("p",{className:"text-sm text-fg-muted",children:(null==(s=this.state.error)?void 0:s.message)||"Unknown error"}),e.jsx("p",{className:"text-xs text-fg-muted mt-2",children:"Try refreshing the page or check your browser's WebGL support."})]})}):this.props.children}}const ve=s.lazy(()=>F(()=>import("./ContactsMapMapLibre-CSieXgJu.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34])));function ye({neighbors:t,localNode:a,localHash:n,onRemoveNode:l,selectedNodeHash:r,onNodeSelected:i,highlightedEdgeKey:c,highlightedGhost:o}){return e.jsx(Ne,{children:e.jsx(s.Suspense,{fallback:e.jsx("div",{className:"map-container-16-9 flex items-center justify-center rounded-2xl surface-base",role:"status","aria-live":"polite","aria-label":"Loading map",children:e.jsxs("div",{className:"text-fg-muted flex items-center gap-3",children:[e.jsx("div",{className:"w-5 h-5 border-2 border-sys-blue border-t-transparent rounded-full animate-spin","aria-hidden":"true"}),e.jsx("span",{children:"Loading map..."})]})}),children:e.jsx(ve,{neighbors:t,localNode:a,localHash:n,onRemoveNode:l,selectedNodeHash:r,onNodeSelected:i,highlightedEdgeKey:c,highlightedGhost:o})})})}const we=s.memo(function({hash:t,className:r="",size:i="sm",collisionInfo:c,isViterbiResolved:o}){const d=a(),m=n(),[x,h]=s.useState(!1),u=s.useMemo(()=>l(t),[t]),p=s.useMemo(()=>void 0!==c?c:u?d.find(e=>e.prefix===u)??null:null,[u,d,c]),g=o??(m.totalPaths>0&&m.avgPathConfidence>=.7),f=s.useCallback(e=>{e.preventDefault(),e.stopPropagation(),h(!0)},[]),j=s.useCallback(()=>{h(!1)},[]);if(!p)return null;const b="sm"===i?"w-3.5 h-3.5":"w-4 h-4",N=g?"text-sys-cyan hover:text-sys-cyan hover:bg-sys-cyan/10 focus:ring-sys-cyan/50":"text-signal-fair hover:text-sys-indigo hover:bg-signal-fair/10 focus:ring-signal-fair/50",v=g?`Prefix conflict resolved by Viterbi HMM (${(100*m.avgPathConfidence).toFixed(0)}% confidence)`:`Prefix conflict: ${p.candidateCount} nodes share prefix "${u}"`;return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:f,className:`inline-flex items-center justify-center p-0.5 rounded focus:outline-none focus:ring-2 transition-colors cursor-pointer touch-manipulation ${N} ${r}`,title:v,"aria-label":`View prefix conflict for ${u}${g?" (Viterbi resolved)":""}`,children:g?e.jsxs("span",{className:"relative",children:[e.jsx(B,{className:b}),e.jsx(A,{className:"absolute -bottom-0.5 -right-0.5 w-2 h-2 text-sys-green"})]}):e.jsx(W,{className:b})}),e.jsx(U,{isOpen:x,prefix:p.prefix,candidateHashes:p.candidateHashes,onClose:j})]})}),ke=[{target:"Contacts",fn:"name",minStage:1,when:E},{target:"Contacts",fn:"traceLinks.directed",minStage:2,when:I}];H(ke);const Ce=s.memo(function({hash:s,contact:t,isHub:a,isNeighbor:n,distance:l,centrality:o,sparklineData:d,neighborSignal:m,collisionInfo:x,isViterbiResolved:h,isPinging:u,isPingingThis:p,pingResult:g,pingError:f,gatewayInfo:j,lastForwarderPrefix:b,isMobile:N,pathStability:v,onRowClick:y,onPing:w,onRemove:k}){z(ke);const C=t.latitude&&t.longitude&&0!==t.latitude&&0!==t.longitude,M=t.node_name||t.name||"Unknown",R=n&&m,P=S(t),{isRepeater:L,isCompanion:$,isRoomServer:_,isClient:F,label:E}=P,I=n?`${E} — Direct RF contact (zero-hop neighbor)`:`${E} — Flood routing (multi-hop via mesh)`,H=t.first_seen?r(t.first_seen).replace(/ ago$/i," old"):null;return e.jsxs("div",{className:`contacts-grid-row ${a?"bg-sys-amber/5 border-l-2 border-l-sys-amber":""} ${C?"cursor-pointer hover:bg-subtle-fill":""}`,onClick:()=>y(s),children:[e.jsxs("div",{className:"contacts-col-node flex items-center gap-2 min-w-0",children:[R&&null!==(null==m?void 0:m.avgSnr)?e.jsx("div",{className:`w-2 h-2 rounded-full flex-shrink-0 self-center ${i(m.avgSnr)}`}):e.jsx("div",{className:"w-2 flex-shrink-0"}),e.jsx("div",{className:"w-6 h-6 flex items-center justify-center flex-shrink-0",title:I,children:(()=>{if(_&&L)return e.jsxs("div",{className:"relative w-5 h-5",children:[e.jsx(G,{className:"w-5 h-5 absolute inset-0 text-sys-pink"}),e.jsx(q,{className:"w-2.5 h-2.5 absolute -bottom-0.5 -right-0.5 text-sys-teal"})]});if(_)return e.jsx(G,{className:"w-5 h-5 text-sys-pink"});if(L)return e.jsx("div",{className:"w-5 h-5 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:e.jsx(K,{className:"w-3.5 h-3.5 text-sys-blue"})});if(($||F)&&"Unknown"!==M){const{emoji:s,cleanName:t}=T(M);return e.jsx("div",{className:"w-6 h-6 rounded-full flex items-center justify-center",style:{backgroundColor:O(t)},children:s?e.jsx("span",{className:"text-sm leading-none",children:s}):e.jsx("span",{className:"text-white text-[9px] font-bold tracking-tighter",children:D(M)})})}return e.jsx("div",{className:"w-6 h-6 rounded-full flex items-center justify-center bg-zinc-500/20",children:e.jsx(J,{className:"w-3.5 h-3.5 text-sys-amber"})})})()}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 overflow-hidden",children:[e.jsx("span",{className:"roster-title truncate",title:M,children:M}),n&&e.jsx(c,{color:je.neighbor,compact:!0,className:"flex-shrink-0",children:"NBR"}),a&&e.jsxs(c,{color:je.hub,compact:!0,className:"flex items-center gap-1 flex-shrink-0",children:[e.jsx(Q,{className:"w-3 h-3"}),"HUB"]}),L&&e.jsx(c,{color:je.repeater,compact:!0,className:"flex-shrink-0",children:"RPT"}),_&&e.jsx(c,{color:je.room,compact:!0,className:"flex-shrink-0",children:"ROOM"}),$&&e.jsx(c,{color:je.companion,compact:!0,className:"flex-shrink-0",children:"COMP"}),F&&e.jsx(c,{color:je.client,compact:!0,className:"flex-shrink-0",children:"CLIENT"}),N&&e.jsxs(c,{color:"cyan",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx(X,{className:"w-2.5 h-2.5"}),"MOBILE"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 mt-0.5",children:[e.jsx(fe,{copy:!0,size:"compact",truncate:[8,6],children:s}),e.jsx(we,{hash:s,collisionInfo:x,isViterbiResolved:h}),!n&&j&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`Via ${j.name||j.prefix} (${j.hopCount} hop${1!==j.hopCount?"s":""})`,children:[e.jsx(Y,{className:"w-2.5 h-2.5"}),e.jsx("span",{className:"font-mono",children:j.prefix}),j.hopCount>1&&e.jsxs("span",{className:"opacity-60",children:["+",j.hopCount-1]})]}),b&&!n&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`Last forwarded by ${b}`,children:[e.jsx(Z,{className:"w-2.5 h-2.5"}),e.jsx("span",{className:"font-mono",children:b})]}),null!=v&&0!==v&&e.jsx(c,{color:v>0?"green":"amber",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:v>0?"Path stability improving":"Path stability declining",children:v>0?e.jsx(ee,{className:"w-2.5 h-2.5"}):e.jsx(se,{className:"w-2.5 h-2.5"})}),d.length>0&&(()=>{const s=d.reduce((e,s)=>e+s.count,0);if(0===s)return null;const t=s/24;return e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`${s} packets in last 24h (~${t.toFixed(1)}/hr)`,children:[e.jsx(te,{className:"w-2.5 h-2.5"}),e.jsxs("span",{children:[t<1?"<1":t.toFixed(0),"/hr"]})]})})(),H&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0 opacity-70",title:`First discovered ${H}`,children:[e.jsx(ae,{className:"w-2.5 h-2.5"}),e.jsx("span",{children:H})]})]})]})]}),e.jsxs("div",{className:"contacts-col-signal flex items-center justify-end gap-2",children:[R&&null!==(null==m?void 0:m.avgRssi)&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(V,{rssi:m.avgRssi,className:"w-3.5 h-3.5"}),e.jsx("span",{className:"type-data-xs text-fg-muted",children:Math.round(m.avgRssi)})]}),R&&null!==(null==m?void 0:m.avgSnr)&&e.jsxs("span",{className:"type-data-xs text-fg-muted",children:[m.avgSnr.toFixed(1)," dB"]})]}),e.jsx("div",{className:"contacts-col-distance flex items-center justify-end gap-1 text-fg-muted",children:null!=l&&e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"w-3 h-3"}),e.jsx("span",{className:"type-data-xs",children:(U=l,U<1e3?`${Math.round(U)}m`:`${(U/1e3).toFixed(1)}km`)})]})}),e.jsx("div",{className:"contacts-col-centrality flex items-center justify-end gap-1",children:o>0&&e.jsxs(e.Fragment,{children:[e.jsx(le,{className:"w-3 h-3 text-sys-indigo"}),e.jsxs("span",{className:"type-data-xs text-fg-muted",children:[(100*o).toFixed(0),"%"]})]})}),e.jsx("div",{className:"contacts-col-seen flex items-center justify-end",children:e.jsx("span",{className:"type-data-xs text-fg-primary whitespace-nowrap",children:t.last_seen?r(t.last_seen):"—"})}),e.jsxs("div",{className:"contacts-col-actions flex items-center justify-end gap-1",children:[n&&e.jsx(e.Fragment,{children:g?e.jsxs("div",{className:"flex items-center gap-1 text-sys-green",title:`RTT: ${g.rtt_ms.toFixed(0)}ms`,children:[e.jsx(A,{className:"w-3.5 h-3.5"}),e.jsxs("span",{className:"type-data-xs hidden sm:inline",children:[g.snr_db.toFixed(1),"dB"]})]}):f?e.jsx("span",{className:"text-sys-red text-xs",title:f,children:"✗"}):e.jsx("button",{onClick:e=>w(s,e),disabled:u,className:"p-1 sm:p-1.5 radius-inner text-fg-muted/50 hover:text-sys-blue hover:bg-sys-blue/10 transition-base disabled:opacity-50 disabled:cursor-not-allowed",title:"Ping neighbor for updated signal info",children:p?e.jsx(re,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4 animate-spin"}):e.jsx(ie,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4"})})}),e.jsx("button",{onClick:e=>{e.stopPropagation(),k(s,M)},className:"p-1 sm:p-1.5 radius-inner text-fg-muted/50 hover:text-sys-red hover:bg-sys-red/10 transition-base",title:"Remove contact",children:e.jsx(ce,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4"})})]})]});var U}),Se=[],Me=[{field:"lastHeard",icon:pe,label:"Recent"},{field:"distance",icon:ne,label:"Distance"},{field:"centrality",icon:le,label:"Centrality"}];function Re(e,s){const{color:a="primary",border:n=!1}=s??{};return t("flex items-center gap-1.5 px-2 py-1.5 text-sm radius-inner transition-base",e?"success"===a?"bg-sys-green/20 text-sys-green":"bg-sys-blue/20 text-sys-blue":"text-fg-muted hover:text-fg-secondary hover-bg",n&&(e?"success"===a?"border border-sys-green/30":"border border-sys-blue/30":"border border-transparent"))}function Pe(e,s,t,a){const n=(t-e)*Math.PI/180,l=(a-s)*Math.PI/180,r=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(t*Math.PI/180)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))*6371e3}const Le=Object.freeze(Object.defineProperty({__proto__:null,default:function(){const{stats:r}=o(),i=d(),c=m(),F=x(),z=h(),E=u(),I=p(),H=g(),T=f(),O=j(),D=b(),V=N[O],U=a(),B=n(),W=v(),q=B.totalPaths>0&&B.avgPathConfidence>=.7,Q=s.useMemo(()=>{const e=new Map;for(const s of U)e.set(s.prefix,s);return e},[U]),[X,Y]=s.useState(null),[Z,ee]=s.useState("lastHeard"),[se,te]=s.useState("desc"),[ae,ne]=s.useState(""),[le,ie]=s.useState(!1),[ce,pe]=s.useState(new Set),[fe,je]=s.useState(!1),[Ne,ve]=s.useState(null),[we,ke]=s.useState(null),[Le,$e]=s.useState(new Map),[_e,Fe]=s.useState(new Map),[ze,Ee]=s.useState(25),[Ie,He]=s.useState(25),Te=s.useRef(null),Oe=s.useMemo(()=>(null==r?void 0:r.neighbors)??{},[null==r?void 0:r.neighbors]),De=s.useMemo(()=>{const e=Date.now()/1e3-60*V.minutes;return Object.fromEntries(Object.entries(Oe).filter(([s,t])=>!i.has(s)&&(t.last_seen??0)>=e))},[Oe,i,V.minutes]),Ve=y(),Ue=null==r?void 0:r.local_hash,Be=s.useMemo(()=>{const e=new Map;if(!Ue||0===I.size)return e;for(const[s,t]of I)if(s.endsWith(`→${Ue}`)&&t.hops.length>1){const a=s.split("→")[0],n=t.hops[t.hops.length-1];e.set(a,n)}return e},[I,Ue]),Ae=s.useMemo(()=>{const e=new Map;if(!(null==Ve?void 0:Ve.latitude)||!(null==Ve?void 0:Ve.longitude))return e;for(const[s,t]of Object.entries(De))t.latitude&&t.longitude&&0!==t.latitude&&0!==t.longitude?e.set(s,Pe(Ve.latitude,Ve.longitude,t.latitude,t.longitude)):e.set(s,null);return e},[De,Ve]),{neighborHashSet:We,neighborSignalMap:Ge}=s.useMemo(()=>{const e=new Set,s=new Map;for(const t of E)e.add(t.hash),s.set(t.hash,{avgRssi:t.avgRssi,avgSnr:t.avgSnr});return{neighborHashSet:e,neighborSignalMap:s}},[E]),qe=s.useMemo(()=>{const e=ae.toLowerCase().trim(),s="neighbor"===e||"neighbors"===e,t=le||s,a=ce.size>0;return Object.fromEntries(Object.entries(De).filter(([n,r])=>{if(a){const e=function(e){return function(e){switch(e){case"room_server":return"room";case"repeater":return"repeater";case"companion":case"unknown":return"companion"}}(S(e).type)}(r);if(!ce.has(e))return!1}if(t&&!We.has(n))return!1;if(s)return!0;if(!e)return!0;const i=(r.node_name||r.name||"").toLowerCase(),c=l(n).toLowerCase();return i.includes(e)||c.includes(e)||n.toLowerCase().includes(e)}))},[De,ae,le,We,ce]),Ke=s.useMemo(()=>{const e=Object.entries(qe),s=ae.toLowerCase().trim(),t=2===s.length&&/^[0-9a-f]{2}$/i.test(s);return e.sort(([e,a],[n,r])=>{if(t){const t=l(e).toLowerCase(),a=l(n).toLowerCase(),r=t===s,i=a===s;if(r&&!i)return-1;if(i&&!r)return 1}let i=0;switch(Z){case"lastHeard":i=(a.last_seen||0)-(r.last_seen||0);break;case"distance":{const s=Ae.get(e)??null,t=Ae.get(n)??null;i=null===s&&null===t?0:null===s?1:null===t?-1:s-t;break}case"centrality":i=(z.get(e)||0)-(z.get(n)||0)}return"desc"===se?-i:i})},[qe,Z,se,Ae,z,ae]),Je=s.useMemo(()=>{let e=0,s=0,t=0,a=0,n=0;for(const[,l]of Ke){const r=S(l),i=l.latitude&&l.longitude&&0!==l.latitude&&0!==l.longitude;switch(r.type){case"room_server":t++;break;case"repeater":s++;break;case"companion":e++;break;case"unknown":n++}i&&a++}return{companions:e,repeaters:s,roomServers:t,total:Ke.length,withLocation:a,unknown:n}},[Ke]),Qe=s.useMemo(()=>new Set(F),[F]),Xe=s.useMemo(()=>0===ze?Ke:Ke.slice(0,Ie),[Ke,Ie,ze]);s.useEffect(()=>{He(ze||Ke.length)},[Z,se,ae,le,ce,ze,Ke.length]),s.useEffect(()=>{const e=e=>{e.target.closest("[data-dropdown]")||je(!1)};return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[]),s.useEffect(()=>{if(0===ze)return;const e=new IntersectionObserver(e=>{e[0].isIntersecting&&IeMath.min(e+ze,Ke.length))},{threshold:.1,rootMargin:"100px"});return Te.current&&e.observe(Te.current),()=>e.disconnect()},[ze,Ie,Ke.length]);const Ye=s.useCallback(e=>{Ee(e),He(e||Ke.length)},[Ke.length]),Ze=s.useCallback(e=>{Z===e?te(e=>"desc"===e?"asc":"desc"):(ee(e),te("desc"))},[Z]),es=s.useCallback(e=>{const s=De[e];(null==s?void 0:s.latitude)&&(null==s?void 0:s.longitude)&&0!==s.latitude&&0!==s.longitude&&ve(e)},[De]),ss=s.useCallback(()=>{ve(null)},[]),ts=s.useCallback((e,s)=>{Y({hash:e,name:s})},[]),as=s.useCallback(async(e,s)=>{if(s.stopPropagation(),!we){ke(e),$e(s=>{const t=new Map(s);return t.delete(e),t}),Fe(s=>{const t=new Map(s);return t.delete(e),t});try{const s=e.startsWith("0x")?e.slice(0,4):`0x${e.slice(0,2)}`,t=await C(s,30);t.success&&t.data?($e(s=>new Map(s).set(e,t.data)),setTimeout(()=>{$e(s=>{const t=new Map(s);return t.delete(e),t})},1e4)):(Fe(s=>new Map(s).set(e,t.error||"Ping failed")),setTimeout(()=>{Fe(s=>{const t=new Map(s);return t.delete(e),t})},5e3))}catch(t){const s=t instanceof Error?t.message:"Ping failed";Fe(t=>new Map(t).set(e,s)),setTimeout(()=>{Fe(s=>{const t=new Map(s);return t.delete(e),t})},5e3)}finally{ke(null)}}},[we]);return e.jsxs(M,{children:[e.jsx(R,{title:"Contacts",icon:e.jsx(oe,{}),controls:e.jsxs("div",{className:"flex items-center gap-3 sm:gap-5",children:[e.jsxs("div",{className:"hidden sm:flex items-center gap-4",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-fg-muted",children:"Total:"}),e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${Je.total} discovered node${1!==Je.total?"s":""} on the mesh network`,children:[e.jsx(oe,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:Je.total})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-fg-muted",children:"Types:"}),Je.repeaters>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Repeaters",children:[e.jsx(K,{className:"w-3.5 h-3.5 text-sys-blue"}),e.jsx("span",{children:Je.repeaters})]}),Je.companions>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Companions",children:[e.jsx(de,{className:"w-3.5 h-3.5 text-fg-muted"}),e.jsx("span",{children:Je.companions})]}),Je.roomServers>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Room Servers",children:[e.jsx(G,{className:"w-3.5 h-3.5 text-sys-pink"}),e.jsx("span",{children:Je.roomServers})]}),Je.withLocation>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"With GPS location",children:[e.jsx(me,{className:"w-3.5 h-3.5 text-sys-green"}),e.jsx("span",{children:Je.withLocation})]}),Je.unknown>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Unknown type",children:[e.jsx(J,{className:"w-3.5 h-3.5 text-sys-amber"}),e.jsx("span",{children:Je.unknown})]})]})]}),e.jsxs("div",{className:"flex sm:hidden items-center gap-1.5",children:[e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(oe,{className:"w-3 h-3 text-fg-secondary"}),e.jsx("span",{children:Je.total})]}),Je.repeaters>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(K,{className:"w-3 h-3 text-sys-blue"}),e.jsx("span",{children:Je.repeaters})]}),Je.companions>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(de,{className:"w-3 h-3 text-fg-muted"}),e.jsx("span",{children:Je.companions})]}),Je.roomServers>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(G,{className:"w-3 h-3 text-sys-pink"}),e.jsx("span",{children:Je.roomServers})]}),e.jsx(_,{ranges:N,selectedIndex:O,onSelect:D,size:"sm"})]}),e.jsx("div",{className:"hidden sm:block",children:e.jsx(_,{ranges:N,selectedIndex:O,onSelect:D})})]})}),e.jsxs(P,{children:[T?e.jsx(ye,{neighbors:De,localNode:Ve??void 0,localHash:Ue,onRemoveNode:c,selectedNodeHash:Ne,onNodeSelected:ss}):e.jsx("div",{className:"surface-base radius-card aspect-video flex items-center justify-center",children:e.jsxs("div",{className:"flex flex-col items-center gap-3",children:[e.jsx("div",{className:"w-6 h-6 border-2 border-sys-blue border-t-transparent rounded-full animate-spin"}),e.jsx("span",{className:"text-sm text-fg-muted",children:"Loading map..."})]})}),e.jsx(w,{noPadding:!0,children:T?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2.5 border-b border-edge-subtle",children:[e.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title flex-shrink-0",children:e.jsx(oe,{})}),e.jsx("span",{className:"type-micro flex-shrink-0 mr-auto hidden sm:block",children:"Discovered Contacts"}),e.jsx(k,{type:"search",size:"sm",value:ae,onChange:e=>ne(e.target.value),placeholder:"Search...",leadingIcon:e.jsx(he,{className:"w-3.5 h-3.5"}),trailingIcon:ae?e.jsx("button",{onClick:()=>{ne(""),"neighbor"!==ae.toLowerCase().trim()&&"neighbors"!==ae.toLowerCase().trim()||ie(!1)},className:"text-fg-muted hover:text-fg-secondary",children:e.jsx(xe,{className:"w-3 h-3"})}):void 0,className:"w-24 sm:w-32 xl:w-44","aria-label":"Search contacts"}),e.jsx("div",{className:"h-4 w-px bg-border-subtle flex-shrink-0"}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[e.jsxs("div",{className:"relative","data-dropdown":!0,children:[e.jsxs("button",{onClick:()=>je(!fe),className:Re(ce.size>0,{border:!0}),title:"Filter by contact type",children:[e.jsx(ue,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:"Filter"}),ce.size>0&&e.jsx("span",{className:"tabular-nums text-xs bg-sys-blue/30 px-1 rounded",children:ce.size})]}),fe&&e.jsxs("div",{className:"absolute right-0 top-full mt-1 z-50 surface-elevated radius-inner py-1 min-w-[140px]",children:[[{key:"repeater",label:"Repeaters"},{key:"companion",label:"Companions"},{key:"room",label:"Rooms"}].map(({key:s,label:a})=>e.jsxs("button",{onClick:()=>{pe(e=>{const t=new Set(e);return t.has(s)?t.delete(s):t.add(s),t})},className:"w-full px-3 py-1.5 text-sm text-left hover-bg transition-base flex items-center gap-2",children:[e.jsx("span",{className:t("w-4 h-4 flex items-center justify-center radius-badge border",ce.has(s)?"bg-sys-blue border-sys-blue text-white":"border-edge-subtle"),children:ce.has(s)&&e.jsx(A,{className:"w-3 h-3"})}),e.jsx("span",{className:ce.has(s)?"text-fg-primary":"text-fg-secondary",children:a})]},s)),ce.size>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"border-t border-edge-subtle my-1"}),e.jsx("button",{onClick:()=>pe(new Set),className:"w-full px-3 py-1.5 text-sm text-left text-fg-muted hover:text-fg-secondary hover-bg transition-base",children:"Clear filters"})]})]})]}),We.size>0&&e.jsxs("button",{onClick:()=>ie(!le),className:Re(le,{color:"success",border:!0}),title:le?"Show all contacts":"Show only MeshCore neighbors (direct RF contact)",children:[e.jsx(K,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:"Neighbors"})]})]}),e.jsx("div",{className:"h-4 w-px bg-border-subtle flex-shrink-0"}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[Me.map(({field:s,icon:a,label:n})=>e.jsxs("button",{onClick:()=>Ze(s),className:Re(Z===s),title:`Sort by ${n.toLowerCase()}`,children:[e.jsx(a,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:n}),Z===s&&e.jsx(ge,{className:t("w-3 h-3","asc"===se&&"rotate-180")})]},s)),e.jsx("div",{className:"h-4 w-px bg-border-subtle"}),e.jsxs(L,{value:ze,onChange:Ye,className:"w-auto min-w-[50px] [&_button]:py-1 [&_button]:px-2 [&_button]:text-xs [&_button]:min-h-0","aria-label":"Items per page",children:[e.jsx($,{value:25,children:"25"}),e.jsx($,{value:50,children:"50"}),e.jsx($,{value:100,children:"100"}),e.jsx($,{value:0,children:"All"})]})]})]}),Ke.length>0?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"hidden sm:grid contacts-grid-header border-b border-edge-subtle/50 px-3 py-2 type-micro text-fg-muted",children:[e.jsx("div",{className:"contacts-col-node",children:"Node"}),e.jsx("div",{className:"contacts-col-signal text-right",children:"Signal"}),e.jsx("div",{className:"contacts-col-distance text-right",children:"Distance"}),e.jsx("div",{className:"contacts-col-centrality text-right",children:"Centrality"}),e.jsx("div",{className:"contacts-col-seen text-right",children:"Last Seen"}),e.jsx("div",{className:"contacts-col-actions"})]}),e.jsx("div",{className:"divide-y divide-edge-subtle/30",children:Xe.map(([s,t])=>{const a=l(s),n=Qe.has(s),r=We.has(s),i=Ae.get(s)??null,c=z.get(s)||0,o=r?Ge.get(s):void 0,d=a?Q.get(a)??null:null,m=W.get(s)??Se;let x=null;if(!r&&Ue&&I.size>0){const e=`${s}→${Ue}`,t=I.get(e);if(t&&t.hops.length>0){const e=t.hops[0],s=Object.keys(Oe).find(s=>s.toUpperCase().startsWith(e.toUpperCase())),a=s?Oe[s]:null;x={prefix:e,name:(null==a?void 0:a.node_name)??(null==a?void 0:a.name)??null,hopCount:t.hopCount}}}const h=H.has(s),u=Be.get(s)??null;return e.jsx(Ce,{hash:s,contact:t,isHub:n,isNeighbor:r,distance:i,centrality:c,sparklineData:m,neighborSignal:o,collisionInfo:d,isViterbiResolved:q,isPinging:null!==we,isPingingThis:we===s,pingResult:Le.get(s),pingError:_e.get(s),gatewayInfo:x,lastForwarderPrefix:u,isMobile:h,onRowClick:es,onPing:as,onRemove:ts},s)})}),ze>0&&Ie0&&IeHe(e=>Math.min(e+ze,Ke.length)),className:"text-sys-blue hover:text-sys-blue/80 transition-base",children:"Load more"})]})]}):e.jsxs("div",{className:"roster-empty",children:[e.jsx(oe,{className:"roster-empty-icon"}),e.jsx("div",{className:"type-label text-fg-secondary",children:"No Contacts Discovered"}),e.jsx("div",{className:"type-data-xs text-fg-muted mt-1",children:"Contacts will appear here as they advertise on the mesh network."})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-4 border-b border-edge-subtle",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-4 h-4 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-32 h-4 rounded bg-elevated animate-pulse"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-16 h-6 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-24 h-6 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-16 h-6 rounded bg-elevated animate-pulse"})]})]}),e.jsx("div",{className:"px-3 py-3 space-y-3",children:[...Array(5)].map((s,t)=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-5 h-5 rounded bg-elevated animate-pulse"}),e.jsxs("div",{className:"flex-1 space-y-1.5",children:[e.jsx("div",{className:"h-4 w-32 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"h-3 w-24 rounded bg-elevated animate-pulse"})]}),e.jsx("div",{className:"w-12 h-4 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-16 h-4 rounded bg-elevated animate-pulse"})]},t))})]})})]}),e.jsx(be,{isOpen:!!X,title:"Remove Contact",message:`Are you sure you would like to remove ${(null==X?void 0:X.name)||"this contact"}?`,confirmLabel:"Remove",cancelLabel:"Cancel",variant:"danger",onConfirm:()=>{X&&c(X.hash),Y(null)},onCancel:()=>Y(null)})]})}},Symbol.toStringTag,{value:"Module"}));export{Le as C,we as P}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ContactsMapMapLibre-BtIfp876.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/consumer-registry-BUFl6buY.js","assets/index-CkRTgHHA.js","assets/vendor-charts-C916_-gs.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/link-scoring-C0BjaK96.js","assets/ConfirmModal-B6Rz8ROW.js","assets/DeepAnalysisModal-L9EkN490.js","assets/geo-utils-DJn8DnxF.js","assets/useMapViewStore-sFZdb1_p.js","assets/BasemapLayer-CSqjQAiA.js","assets/vendor-geo-2MTwbTwv.js","assets/node-types-DRVunROD.js","assets/easing-GXZYrvDD.js","assets/badge-colors-BxLppqaF.js","assets/LightSparkline-BAD3v4m9.js","assets/ping-DPgnsJJf.js","assets/PageLayout-BWMUVZgC.js","assets/listbox-DrzA7Ewq.js","assets/TimeRangeStepper-CsLZzi5t.js","assets/chat-utils-mqGCinix.js","assets/SignalIndicator-Bdj3-1hL.js","assets/CollisionExplorerModal-BUHEIiWh.js","assets/DataBox-DpDXI-WX.js","assets/maplibre-gl-B1CfjdFi.css","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-BawBpZYt.css","assets/ContactsMapMapLibre-BwWOEply.css"])))=>i.map(i=>d[i]); +import{j as e,r as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{as as a,at as n,H as l,V as r,au as i,h as c,av as o,t as d,aw as m,ax as x,ay as h,r as u,az as p,aA as g,aB as f,v as j,W as b,D as N,aC as v,aD as y,e as w,I as k}from"./index-CkRTgHHA.js";import{p as C}from"./ping-DPgnsJJf.js";import{c as S}from"./node-types-DRVunROD.js";import{P as M,a as R,B as P}from"./PageLayout-BWMUVZgC.js";import{L,a as $}from"./listbox-DrzA7Ewq.js";import{T as _}from"./TimeRangeStepper-CsLZzi5t.js";import{_ as F}from"./cosmograph-DqYT4sUA.js";import{u as z,e as E,f as I,r as H}from"./consumer-registry-BUFl6buY.js";import{e as T,g as O,a as D}from"./chat-utils-mqGCinix.js";import{a as V}from"./SignalIndicator-Bdj3-1hL.js";import{C as U}from"./CollisionExplorerModal-BUHEIiWh.js";import{ah as B,a as A,ai as W,j as G,aj as q,R as K,a2 as J,ak as Q,al as X,A as Y,am as Z,T as ee,an as se,ao as te,ap as ae,aq as ne,a7 as le,L as re,ar as ie,as as ce,U as oe,at as de,a1 as me,X as xe,au as he,av as ue,a5 as pe,aw as ge}from"./vendor-icons-TO0PZKGR.js";import{D as fe}from"./DataBox-DpDXI-WX.js";import{C as je}from"./badge-colors-BxLppqaF.js";import{C as be}from"./ConfirmModal-B6Rz8ROW.js";class Ne extends s.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var s;return this.state.hasError?e.jsx("div",{className:"map-container-16-9 flex items-center justify-center rounded-2xl surface-base",role:"alert","aria-live":"assertive",children:e.jsxs("div",{className:"text-center text-fg-muted p-4",children:[e.jsx("p",{className:"text-lg mb-2",children:"Map failed to load"}),e.jsx("p",{className:"text-sm text-fg-muted",children:(null==(s=this.state.error)?void 0:s.message)||"Unknown error"}),e.jsx("p",{className:"text-xs text-fg-muted mt-2",children:"Try refreshing the page or check your browser's WebGL support."})]})}):this.props.children}}const ve=s.lazy(()=>F(()=>import("./ContactsMapMapLibre-BtIfp876.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34])));function ye({neighbors:t,localNode:a,localHash:n,onRemoveNode:l,selectedNodeHash:r,onNodeSelected:i,highlightedEdgeKey:c,highlightedGhost:o}){return e.jsx(Ne,{children:e.jsx(s.Suspense,{fallback:e.jsx("div",{className:"map-container-16-9 flex items-center justify-center rounded-2xl surface-base",role:"status","aria-live":"polite","aria-label":"Loading map",children:e.jsxs("div",{className:"text-fg-muted flex items-center gap-3",children:[e.jsx("div",{className:"w-5 h-5 border-2 border-sys-blue border-t-transparent rounded-full animate-spin","aria-hidden":"true"}),e.jsx("span",{children:"Loading map..."})]})}),children:e.jsx(ve,{neighbors:t,localNode:a,localHash:n,onRemoveNode:l,selectedNodeHash:r,onNodeSelected:i,highlightedEdgeKey:c,highlightedGhost:o})})})}const we=s.memo(function({hash:t,className:r="",size:i="sm",collisionInfo:c,isViterbiResolved:o}){const d=a(),m=n(),[x,h]=s.useState(!1),u=s.useMemo(()=>l(t),[t]),p=s.useMemo(()=>void 0!==c?c:u?d.find(e=>e.prefix===u)??null:null,[u,d,c]),g=o??(m.totalPaths>0&&m.avgPathConfidence>=.7),f=s.useCallback(e=>{e.preventDefault(),e.stopPropagation(),h(!0)},[]),j=s.useCallback(()=>{h(!1)},[]);if(!p)return null;const b="sm"===i?"w-3.5 h-3.5":"w-4 h-4",N=g?"text-sys-cyan hover:text-sys-cyan hover:bg-sys-cyan/10 focus:ring-sys-cyan/50":"text-signal-fair hover:text-sys-indigo hover:bg-signal-fair/10 focus:ring-signal-fair/50",v=g?`Prefix conflict resolved by Viterbi HMM (${(100*m.avgPathConfidence).toFixed(0)}% confidence)`:`Prefix conflict: ${p.candidateCount} nodes share prefix "${u}"`;return e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:f,className:`inline-flex items-center justify-center p-0.5 rounded focus:outline-none focus:ring-2 transition-colors cursor-pointer touch-manipulation ${N} ${r}`,title:v,"aria-label":`View prefix conflict for ${u}${g?" (Viterbi resolved)":""}`,children:g?e.jsxs("span",{className:"relative",children:[e.jsx(B,{className:b}),e.jsx(A,{className:"absolute -bottom-0.5 -right-0.5 w-2 h-2 text-sys-green"})]}):e.jsx(W,{className:b})}),e.jsx(U,{isOpen:x,prefix:p.prefix,candidateHashes:p.candidateHashes,onClose:j})]})}),ke=[{target:"Contacts",fn:"name",minStage:1,when:E},{target:"Contacts",fn:"traceLinks.directed",minStage:2,when:I}];H(ke);const Ce=s.memo(function({hash:s,contact:t,isHub:a,isNeighbor:n,distance:l,centrality:o,sparklineData:d,neighborSignal:m,collisionInfo:x,isViterbiResolved:h,isPinging:u,isPingingThis:p,pingResult:g,pingError:f,gatewayInfo:j,lastForwarderPrefix:b,isMobile:N,pathStability:v,onRowClick:y,onPing:w,onRemove:k}){z(ke);const C=t.latitude&&t.longitude&&0!==t.latitude&&0!==t.longitude,M=t.node_name||t.name||"Unknown",R=n&&m,P=S(t),{isRepeater:L,isCompanion:$,isRoomServer:_,isClient:F,label:E}=P,I=n?`${E} — Direct RF contact (zero-hop neighbor)`:`${E} — Flood routing (multi-hop via mesh)`,H=t.first_seen?r(t.first_seen).replace(/ ago$/i," old"):null;return e.jsxs("div",{className:`contacts-grid-row ${a?"bg-sys-amber/5 border-l-2 border-l-sys-amber":""} ${C?"cursor-pointer hover:bg-subtle-fill":""}`,onClick:()=>y(s),children:[e.jsxs("div",{className:"contacts-col-node flex items-center gap-2 min-w-0",children:[R&&null!==(null==m?void 0:m.avgSnr)?e.jsx("div",{className:`w-2 h-2 rounded-full flex-shrink-0 self-center ${i(m.avgSnr)}`}):e.jsx("div",{className:"w-2 flex-shrink-0"}),e.jsx("div",{className:"w-6 h-6 flex items-center justify-center flex-shrink-0",title:I,children:(()=>{if(_&&L)return e.jsxs("div",{className:"relative w-5 h-5",children:[e.jsx(G,{className:"w-5 h-5 absolute inset-0 text-sys-pink"}),e.jsx(q,{className:"w-2.5 h-2.5 absolute -bottom-0.5 -right-0.5 text-sys-teal"})]});if(_)return e.jsx(G,{className:"w-5 h-5 text-sys-pink"});if(L)return e.jsx("div",{className:"w-5 h-5 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:e.jsx(K,{className:"w-3.5 h-3.5 text-sys-blue"})});if(($||F)&&"Unknown"!==M){const{emoji:s,cleanName:t}=T(M);return e.jsx("div",{className:"w-6 h-6 rounded-full flex items-center justify-center",style:{backgroundColor:O(t)},children:s?e.jsx("span",{className:"text-sm leading-none",children:s}):e.jsx("span",{className:"text-white text-[9px] font-bold tracking-tighter",children:D(M)})})}return e.jsx("div",{className:"w-6 h-6 rounded-full flex items-center justify-center bg-zinc-500/20",children:e.jsx(J,{className:"w-3.5 h-3.5 text-sys-amber"})})})()}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 overflow-hidden",children:[e.jsx("span",{className:"roster-title truncate",title:M,children:M}),n&&e.jsx(c,{color:je.neighbor,compact:!0,className:"flex-shrink-0",children:"NBR"}),a&&e.jsxs(c,{color:je.hub,compact:!0,className:"flex items-center gap-1 flex-shrink-0",children:[e.jsx(Q,{className:"w-3 h-3"}),"HUB"]}),L&&e.jsx(c,{color:je.repeater,compact:!0,className:"flex-shrink-0",children:"RPT"}),_&&e.jsx(c,{color:je.room,compact:!0,className:"flex-shrink-0",children:"ROOM"}),$&&e.jsx(c,{color:je.companion,compact:!0,className:"flex-shrink-0",children:"COMP"}),F&&e.jsx(c,{color:je.client,compact:!0,className:"flex-shrink-0",children:"CLIENT"}),N&&e.jsxs(c,{color:"cyan",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx(X,{className:"w-2.5 h-2.5"}),"MOBILE"]})]}),e.jsxs("div",{className:"flex items-center gap-1.5 mt-0.5",children:[e.jsx(fe,{copy:!0,size:"compact",truncate:[8,6],children:s}),e.jsx(we,{hash:s,collisionInfo:x,isViterbiResolved:h}),!n&&j&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`Via ${j.name||j.prefix} (${j.hopCount} hop${1!==j.hopCount?"s":""})`,children:[e.jsx(Y,{className:"w-2.5 h-2.5"}),e.jsx("span",{className:"font-mono",children:j.prefix}),j.hopCount>1&&e.jsxs("span",{className:"opacity-60",children:["+",j.hopCount-1]})]}),b&&!n&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`Last forwarded by ${b}`,children:[e.jsx(Z,{className:"w-2.5 h-2.5"}),e.jsx("span",{className:"font-mono",children:b})]}),null!=v&&0!==v&&e.jsx(c,{color:v>0?"green":"amber",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:v>0?"Path stability improving":"Path stability declining",children:v>0?e.jsx(ee,{className:"w-2.5 h-2.5"}):e.jsx(se,{className:"w-2.5 h-2.5"})}),d.length>0&&(()=>{const s=d.reduce((e,s)=>e+s.count,0);if(0===s)return null;const t=s/24;return e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0",title:`${s} packets in last 24h (~${t.toFixed(1)}/hr)`,children:[e.jsx(te,{className:"w-2.5 h-2.5"}),e.jsxs("span",{children:[t<1?"<1":t.toFixed(0),"/hr"]})]})})(),H&&e.jsxs(c,{color:"zinc",compact:!0,className:"flex items-center gap-0.5 flex-shrink-0 opacity-70",title:`First discovered ${H}`,children:[e.jsx(ae,{className:"w-2.5 h-2.5"}),e.jsx("span",{children:H})]})]})]})]}),e.jsxs("div",{className:"contacts-col-signal flex items-center justify-end gap-2",children:[R&&null!==(null==m?void 0:m.avgRssi)&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(V,{rssi:m.avgRssi,className:"w-3.5 h-3.5"}),e.jsx("span",{className:"type-data-xs text-fg-muted",children:Math.round(m.avgRssi)})]}),R&&null!==(null==m?void 0:m.avgSnr)&&e.jsxs("span",{className:"type-data-xs text-fg-muted",children:[m.avgSnr.toFixed(1)," dB"]})]}),e.jsx("div",{className:"contacts-col-distance flex items-center justify-end gap-1 text-fg-muted",children:null!=l&&e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"w-3 h-3"}),e.jsx("span",{className:"type-data-xs",children:(U=l,U<1e3?`${Math.round(U)}m`:`${(U/1e3).toFixed(1)}km`)})]})}),e.jsx("div",{className:"contacts-col-centrality flex items-center justify-end gap-1",children:o>0&&e.jsxs(e.Fragment,{children:[e.jsx(le,{className:"w-3 h-3 text-sys-indigo"}),e.jsxs("span",{className:"type-data-xs text-fg-muted",children:[(100*o).toFixed(0),"%"]})]})}),e.jsx("div",{className:"contacts-col-seen flex items-center justify-end",children:e.jsx("span",{className:"type-data-xs text-fg-primary whitespace-nowrap",children:t.last_seen?r(t.last_seen):"—"})}),e.jsxs("div",{className:"contacts-col-actions flex items-center justify-end gap-1",children:[n&&e.jsx(e.Fragment,{children:g?e.jsxs("div",{className:"flex items-center gap-1 text-sys-green",title:`RTT: ${g.rtt_ms.toFixed(0)}ms`,children:[e.jsx(A,{className:"w-3.5 h-3.5"}),e.jsxs("span",{className:"type-data-xs hidden sm:inline",children:[g.snr_db.toFixed(1),"dB"]})]}):f?e.jsx("span",{className:"text-sys-red text-xs",title:f,children:"✗"}):e.jsx("button",{onClick:e=>w(s,e),disabled:u,className:"p-1 sm:p-1.5 radius-inner text-fg-muted/50 hover:text-sys-blue hover:bg-sys-blue/10 transition-base disabled:opacity-50 disabled:cursor-not-allowed",title:"Ping neighbor for updated signal info",children:p?e.jsx(re,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4 animate-spin"}):e.jsx(ie,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4"})})}),e.jsx("button",{onClick:e=>{e.stopPropagation(),k(s,M)},className:"p-1 sm:p-1.5 radius-inner text-fg-muted/50 hover:text-sys-red hover:bg-sys-red/10 transition-base",title:"Remove contact",children:e.jsx(ce,{className:"w-3.5 h-3.5 sm:w-4 sm:h-4"})})]})]});var U}),Se=[],Me=[{field:"lastHeard",icon:pe,label:"Recent"},{field:"distance",icon:ne,label:"Distance"},{field:"centrality",icon:le,label:"Centrality"}];function Re(e,s){const{color:a="primary",border:n=!1}=s??{};return t("flex items-center gap-1.5 px-2 py-1.5 text-sm radius-inner transition-base",e?"success"===a?"bg-sys-green/20 text-sys-green":"bg-sys-blue/20 text-sys-blue":"text-fg-muted hover:text-fg-secondary hover-bg",n&&(e?"success"===a?"border border-sys-green/30":"border border-sys-blue/30":"border border-transparent"))}function Pe(e,s,t,a){const n=(t-e)*Math.PI/180,l=(a-s)*Math.PI/180,r=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(t*Math.PI/180)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))*6371e3}const Le=Object.freeze(Object.defineProperty({__proto__:null,default:function(){const{stats:r}=o(),i=d(),c=m(),F=x(),z=h(),E=u(),I=p(),H=g(),T=f(),O=j(),D=b(),V=N[O],U=a(),B=n(),W=v(),q=B.totalPaths>0&&B.avgPathConfidence>=.7,Q=s.useMemo(()=>{const e=new Map;for(const s of U)e.set(s.prefix,s);return e},[U]),[X,Y]=s.useState(null),[Z,ee]=s.useState("lastHeard"),[se,te]=s.useState("desc"),[ae,ne]=s.useState(""),[le,ie]=s.useState(!1),[ce,pe]=s.useState(new Set),[fe,je]=s.useState(!1),[Ne,ve]=s.useState(null),[we,ke]=s.useState(null),[Le,$e]=s.useState(new Map),[_e,Fe]=s.useState(new Map),[ze,Ee]=s.useState(25),[Ie,He]=s.useState(25),Te=s.useRef(null),Oe=s.useMemo(()=>(null==r?void 0:r.neighbors)??{},[null==r?void 0:r.neighbors]),De=s.useMemo(()=>{const e=Date.now()/1e3-60*V.minutes;return Object.fromEntries(Object.entries(Oe).filter(([s,t])=>!i.has(s)&&(t.last_seen??0)>=e))},[Oe,i,V.minutes]),Ve=y(),Ue=null==r?void 0:r.local_hash,Be=s.useMemo(()=>{const e=new Map;if(!Ue||0===I.size)return e;for(const[s,t]of I)if(s.endsWith(`→${Ue}`)&&t.hops.length>1){const a=s.split("→")[0],n=t.hops[t.hops.length-1];e.set(a,n)}return e},[I,Ue]),Ae=s.useMemo(()=>{const e=new Map;if(!(null==Ve?void 0:Ve.latitude)||!(null==Ve?void 0:Ve.longitude))return e;for(const[s,t]of Object.entries(De))t.latitude&&t.longitude&&0!==t.latitude&&0!==t.longitude?e.set(s,Pe(Ve.latitude,Ve.longitude,t.latitude,t.longitude)):e.set(s,null);return e},[De,Ve]),{neighborHashSet:We,neighborSignalMap:Ge}=s.useMemo(()=>{const e=new Set,s=new Map;for(const t of E)e.add(t.hash),s.set(t.hash,{avgRssi:t.avgRssi,avgSnr:t.avgSnr});return{neighborHashSet:e,neighborSignalMap:s}},[E]),qe=s.useMemo(()=>{const e=ae.toLowerCase().trim(),s="neighbor"===e||"neighbors"===e,t=le||s,a=ce.size>0;return Object.fromEntries(Object.entries(De).filter(([n,r])=>{if(a){const e=function(e){return function(e){switch(e){case"room_server":return"room";case"repeater":return"repeater";case"companion":case"unknown":return"companion"}}(S(e).type)}(r);if(!ce.has(e))return!1}if(t&&!We.has(n))return!1;if(s)return!0;if(!e)return!0;const i=(r.node_name||r.name||"").toLowerCase(),c=l(n).toLowerCase();return i.includes(e)||c.includes(e)||n.toLowerCase().includes(e)}))},[De,ae,le,We,ce]),Ke=s.useMemo(()=>{const e=Object.entries(qe),s=ae.toLowerCase().trim(),t=2===s.length&&/^[0-9a-f]{2}$/i.test(s);return e.sort(([e,a],[n,r])=>{if(t){const t=l(e).toLowerCase(),a=l(n).toLowerCase(),r=t===s,i=a===s;if(r&&!i)return-1;if(i&&!r)return 1}let i=0;switch(Z){case"lastHeard":i=(a.last_seen||0)-(r.last_seen||0);break;case"distance":{const s=Ae.get(e)??null,t=Ae.get(n)??null;i=null===s&&null===t?0:null===s?1:null===t?-1:s-t;break}case"centrality":i=(z.get(e)||0)-(z.get(n)||0)}return"desc"===se?-i:i})},[qe,Z,se,Ae,z,ae]),Je=s.useMemo(()=>{let e=0,s=0,t=0,a=0,n=0;for(const[,l]of Ke){const r=S(l),i=l.latitude&&l.longitude&&0!==l.latitude&&0!==l.longitude;switch(r.type){case"room_server":t++;break;case"repeater":s++;break;case"companion":e++;break;case"unknown":n++}i&&a++}return{companions:e,repeaters:s,roomServers:t,total:Ke.length,withLocation:a,unknown:n}},[Ke]),Qe=s.useMemo(()=>new Set(F),[F]),Xe=s.useMemo(()=>0===ze?Ke:Ke.slice(0,Ie),[Ke,Ie,ze]);s.useEffect(()=>{He(ze||Ke.length)},[Z,se,ae,le,ce,ze,Ke.length]),s.useEffect(()=>{const e=e=>{e.target.closest("[data-dropdown]")||je(!1)};return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[]),s.useEffect(()=>{if(0===ze)return;const e=new IntersectionObserver(e=>{e[0].isIntersecting&&IeMath.min(e+ze,Ke.length))},{threshold:.1,rootMargin:"100px"});return Te.current&&e.observe(Te.current),()=>e.disconnect()},[ze,Ie,Ke.length]);const Ye=s.useCallback(e=>{Ee(e),He(e||Ke.length)},[Ke.length]),Ze=s.useCallback(e=>{Z===e?te(e=>"desc"===e?"asc":"desc"):(ee(e),te("desc"))},[Z]),es=s.useCallback(e=>{const s=De[e];(null==s?void 0:s.latitude)&&(null==s?void 0:s.longitude)&&0!==s.latitude&&0!==s.longitude&&ve(e)},[De]),ss=s.useCallback(()=>{ve(null)},[]),ts=s.useCallback((e,s)=>{Y({hash:e,name:s})},[]),as=s.useCallback(async(e,s)=>{if(s.stopPropagation(),!we){ke(e),$e(s=>{const t=new Map(s);return t.delete(e),t}),Fe(s=>{const t=new Map(s);return t.delete(e),t});try{const s=e.startsWith("0x")?e.slice(0,4):`0x${e.slice(0,2)}`,t=await C(s,30);t.success&&t.data?($e(s=>new Map(s).set(e,t.data)),setTimeout(()=>{$e(s=>{const t=new Map(s);return t.delete(e),t})},1e4)):(Fe(s=>new Map(s).set(e,t.error||"Ping failed")),setTimeout(()=>{Fe(s=>{const t=new Map(s);return t.delete(e),t})},5e3))}catch(t){const s=t instanceof Error?t.message:"Ping failed";Fe(t=>new Map(t).set(e,s)),setTimeout(()=>{Fe(s=>{const t=new Map(s);return t.delete(e),t})},5e3)}finally{ke(null)}}},[we]);return e.jsxs(M,{children:[e.jsx(R,{title:"Contacts",icon:e.jsx(oe,{}),controls:e.jsxs("div",{className:"flex items-center gap-3 sm:gap-5",children:[e.jsxs("div",{className:"hidden sm:flex items-center gap-4",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-fg-muted",children:"Total:"}),e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${Je.total} discovered node${1!==Je.total?"s":""} on the mesh network`,children:[e.jsx(oe,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:Je.total})]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs text-fg-muted",children:"Types:"}),Je.repeaters>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Repeaters",children:[e.jsx(K,{className:"w-3.5 h-3.5 text-sys-blue"}),e.jsx("span",{children:Je.repeaters})]}),Je.companions>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Companions",children:[e.jsx(de,{className:"w-3.5 h-3.5 text-fg-muted"}),e.jsx("span",{children:Je.companions})]}),Je.roomServers>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Room Servers",children:[e.jsx(G,{className:"w-3.5 h-3.5 text-sys-pink"}),e.jsx("span",{children:Je.roomServers})]}),Je.withLocation>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"With GPS location",children:[e.jsx(me,{className:"w-3.5 h-3.5 text-sys-green"}),e.jsx("span",{children:Je.withLocation})]}),Je.unknown>0&&e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:"Unknown type",children:[e.jsx(J,{className:"w-3.5 h-3.5 text-sys-amber"}),e.jsx("span",{children:Je.unknown})]})]})]}),e.jsxs("div",{className:"flex sm:hidden items-center gap-1.5",children:[e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(oe,{className:"w-3 h-3 text-fg-secondary"}),e.jsx("span",{children:Je.total})]}),Je.repeaters>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(K,{className:"w-3 h-3 text-sys-blue"}),e.jsx("span",{children:Je.repeaters})]}),Je.companions>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(de,{className:"w-3 h-3 text-fg-muted"}),e.jsx("span",{children:Je.companions})]}),Je.roomServers>0&&e.jsxs("span",{className:"data-box !px-1.5 !py-0.5 !text-[10px] flex items-center gap-1",children:[e.jsx(G,{className:"w-3 h-3 text-sys-pink"}),e.jsx("span",{children:Je.roomServers})]}),e.jsx(_,{ranges:N,selectedIndex:O,onSelect:D,size:"sm"})]}),e.jsx("div",{className:"hidden sm:block",children:e.jsx(_,{ranges:N,selectedIndex:O,onSelect:D})})]})}),e.jsxs(P,{children:[T?e.jsx(ye,{neighbors:De,localNode:Ve??void 0,localHash:Ue,onRemoveNode:c,selectedNodeHash:Ne,onNodeSelected:ss}):e.jsx("div",{className:"surface-base radius-card aspect-video flex items-center justify-center",children:e.jsxs("div",{className:"flex flex-col items-center gap-3",children:[e.jsx("div",{className:"w-6 h-6 border-2 border-sys-blue border-t-transparent rounded-full animate-spin"}),e.jsx("span",{className:"text-sm text-fg-muted",children:"Loading map..."})]})}),e.jsx(w,{noPadding:!0,children:T?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2.5 border-b border-edge-subtle",children:[e.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title flex-shrink-0",children:e.jsx(oe,{})}),e.jsx("span",{className:"type-micro flex-shrink-0 mr-auto hidden sm:block",children:"Discovered Contacts"}),e.jsx(k,{type:"search",size:"sm",value:ae,onChange:e=>ne(e.target.value),placeholder:"Search...",leadingIcon:e.jsx(he,{className:"w-3.5 h-3.5"}),trailingIcon:ae?e.jsx("button",{onClick:()=>{ne(""),"neighbor"!==ae.toLowerCase().trim()&&"neighbors"!==ae.toLowerCase().trim()||ie(!1)},className:"text-fg-muted hover:text-fg-secondary",children:e.jsx(xe,{className:"w-3 h-3"})}):void 0,className:"w-24 sm:w-32 xl:w-44","aria-label":"Search contacts"}),e.jsx("div",{className:"h-4 w-px bg-border-subtle flex-shrink-0"}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[e.jsxs("div",{className:"relative","data-dropdown":!0,children:[e.jsxs("button",{onClick:()=>je(!fe),className:Re(ce.size>0,{border:!0}),title:"Filter by contact type",children:[e.jsx(ue,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:"Filter"}),ce.size>0&&e.jsx("span",{className:"tabular-nums text-xs bg-sys-blue/30 px-1 rounded",children:ce.size})]}),fe&&e.jsxs("div",{className:"absolute right-0 top-full mt-1 z-50 surface-elevated radius-inner py-1 min-w-[140px]",children:[[{key:"repeater",label:"Repeaters"},{key:"companion",label:"Companions"},{key:"room",label:"Rooms"}].map(({key:s,label:a})=>e.jsxs("button",{onClick:()=>{pe(e=>{const t=new Set(e);return t.has(s)?t.delete(s):t.add(s),t})},className:"w-full px-3 py-1.5 text-sm text-left hover-bg transition-base flex items-center gap-2",children:[e.jsx("span",{className:t("w-4 h-4 flex items-center justify-center radius-badge border",ce.has(s)?"bg-sys-blue border-sys-blue text-white":"border-edge-subtle"),children:ce.has(s)&&e.jsx(A,{className:"w-3 h-3"})}),e.jsx("span",{className:ce.has(s)?"text-fg-primary":"text-fg-secondary",children:a})]},s)),ce.size>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"border-t border-edge-subtle my-1"}),e.jsx("button",{onClick:()=>pe(new Set),className:"w-full px-3 py-1.5 text-sm text-left text-fg-muted hover:text-fg-secondary hover-bg transition-base",children:"Clear filters"})]})]})]}),We.size>0&&e.jsxs("button",{onClick:()=>ie(!le),className:Re(le,{color:"success",border:!0}),title:le?"Show all contacts":"Show only MeshCore neighbors (direct RF contact)",children:[e.jsx(K,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:"Neighbors"})]})]}),e.jsx("div",{className:"h-4 w-px bg-border-subtle flex-shrink-0"}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[Me.map(({field:s,icon:a,label:n})=>e.jsxs("button",{onClick:()=>Ze(s),className:Re(Z===s),title:`Sort by ${n.toLowerCase()}`,children:[e.jsx(a,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"hidden xl:inline",children:n}),Z===s&&e.jsx(ge,{className:t("w-3 h-3","asc"===se&&"rotate-180")})]},s)),e.jsx("div",{className:"h-4 w-px bg-border-subtle"}),e.jsxs(L,{value:ze,onChange:Ye,className:"w-auto min-w-[50px] [&_button]:py-1 [&_button]:px-2 [&_button]:text-xs [&_button]:min-h-0","aria-label":"Items per page",children:[e.jsx($,{value:25,children:"25"}),e.jsx($,{value:50,children:"50"}),e.jsx($,{value:100,children:"100"}),e.jsx($,{value:0,children:"All"})]})]})]}),Ke.length>0?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"hidden sm:grid contacts-grid-header border-b border-edge-subtle/50 px-3 py-2 type-micro text-fg-muted",children:[e.jsx("div",{className:"contacts-col-node",children:"Node"}),e.jsx("div",{className:"contacts-col-signal text-right",children:"Signal"}),e.jsx("div",{className:"contacts-col-distance text-right",children:"Distance"}),e.jsx("div",{className:"contacts-col-centrality text-right",children:"Centrality"}),e.jsx("div",{className:"contacts-col-seen text-right",children:"Last Seen"}),e.jsx("div",{className:"contacts-col-actions"})]}),e.jsx("div",{className:"divide-y divide-edge-subtle/30",children:Xe.map(([s,t])=>{const a=l(s),n=Qe.has(s),r=We.has(s),i=Ae.get(s)??null,c=z.get(s)||0,o=r?Ge.get(s):void 0,d=a?Q.get(a)??null:null,m=W.get(s)??Se;let x=null;if(!r&&Ue&&I.size>0){const e=`${s}→${Ue}`,t=I.get(e);if(t&&t.hops.length>0){const e=t.hops[0],s=Object.keys(Oe).find(s=>s.toUpperCase().startsWith(e.toUpperCase())),a=s?Oe[s]:null;x={prefix:e,name:(null==a?void 0:a.node_name)??(null==a?void 0:a.name)??null,hopCount:t.hopCount}}}const h=H.has(s),u=Be.get(s)??null;return e.jsx(Ce,{hash:s,contact:t,isHub:n,isNeighbor:r,distance:i,centrality:c,sparklineData:m,neighborSignal:o,collisionInfo:d,isViterbiResolved:q,isPinging:null!==we,isPingingThis:we===s,pingResult:Le.get(s),pingError:_e.get(s),gatewayInfo:x,lastForwarderPrefix:u,isMobile:h,onRowClick:es,onPing:as,onRemove:ts},s)})}),ze>0&&Ie0&&IeHe(e=>Math.min(e+ze,Ke.length)),className:"text-sys-blue hover:text-sys-blue/80 transition-base",children:"Load more"})]})]}):e.jsxs("div",{className:"roster-empty",children:[e.jsx(oe,{className:"roster-empty-icon"}),e.jsx("div",{className:"type-label text-fg-secondary",children:"No Contacts Discovered"}),e.jsx("div",{className:"type-data-xs text-fg-muted mt-1",children:"Contacts will appear here as they advertise on the mesh network."})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-4 border-b border-edge-subtle",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-4 h-4 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-32 h-4 rounded bg-elevated animate-pulse"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-16 h-6 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-24 h-6 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-16 h-6 rounded bg-elevated animate-pulse"})]})]}),e.jsx("div",{className:"px-3 py-3 space-y-3",children:[...Array(5)].map((s,t)=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-5 h-5 rounded bg-elevated animate-pulse"}),e.jsxs("div",{className:"flex-1 space-y-1.5",children:[e.jsx("div",{className:"h-4 w-32 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"h-3 w-24 rounded bg-elevated animate-pulse"})]}),e.jsx("div",{className:"w-12 h-4 rounded bg-elevated animate-pulse"}),e.jsx("div",{className:"w-16 h-4 rounded bg-elevated animate-pulse"})]},t))})]})})]}),e.jsx(be,{isOpen:!!X,title:"Remove Contact",message:`Are you sure you would like to remove ${(null==X?void 0:X.name)||"this contact"}?`,confirmLabel:"Remove",cancelLabel:"Cancel",variant:"danger",onConfirm:()=>{X&&c(X.hash),Y(null)},onCancel:()=>Y(null)})]})}},Symbol.toStringTag,{value:"Module"}));export{Le as C,we as P}; diff --git a/frontend/dist/assets/ContactsMapMapLibre-CSieXgJu.js b/frontend/dist/assets/ContactsMapMapLibre-BtIfp876.js similarity index 99% rename from frontend/dist/assets/ContactsMapMapLibre-CSieXgJu.js rename to frontend/dist/assets/ContactsMapMapLibre-BtIfp876.js index 66b947c9..a5dc5af3 100644 --- a/frontend/dist/assets/ContactsMapMapLibre-CSieXgJu.js +++ b/frontend/dist/assets/ContactsMapMapLibre-BtIfp876.js @@ -1 +1 @@ -import{r as e,j as t,a as o}from"./vendor-react-alRNW2nb.js";import{u as n,S as r,L as s,P as a,M as i,b as l}from"./maplibre-gl-BwLPRSIs.js";import{u as c,r as u,e as d,f as m,g as h}from"./consumer-registry-KuOoZhsq.js";import{L as g,c as p}from"./link-scoring-oriFkjrN.js";import{G as f,dd as x,bb as y,Z as b,de as v,df as j,dg as w,an as N,at as C,J as k,b as M,B as S,ap as F,Y as R,_ as T,dh as L,m as E,p as B,ba as D,di as H,V as $,a6 as A,a8 as P,ar as z,ca as I,dj as q,dk as O,cs as W,H as _,aF as U,dl as K,dm as V,a1 as Z,h as G,dn as J,ag as Y,db as Q,ai as X,b3 as ee,r as te,dp as oe,cm as ne,dq as re}from"./index-D7i6lQrq.js";import{C as se}from"./ConfirmModal-XwU3yUZY.js";import{g as ae,a as ie,b as le,D as ce}from"./DeepAnalysisModal-Ca6cBH6E.js";import{c as ue,a as de,p as me,e as he}from"./vendor-core-FtpmsTnh.js";import{j as ge,K as pe,bo as fe,aX as xe,ah as ye,C as be,W as ve,Y as je,bp as we,d as Ne,c as Ce,bq as ke,aS as Me,aL as Se,b7 as Fe,b as Re,aG as Te,br as Le,L as Ee,bs as Be,Z as De,bt as He,R as $e,X as Ae,aM as Pe,as as ze,aR as Ie,bu as qe,bh as Oe,bv as We,bw as _e,a as Ue,a5 as Ke,aK as Ve,U as Ze,bx as Ge,D as Je,o as Ye,an as Qe,T as Xe,aq as et,a1 as tt,by as ot}from"./vendor-icons-TO0PZKGR.js";import{m as nt,A as rt,b as st}from"./vendor-motion-DNp0Qg4F.js";import{A as at,D as it,u as lt}from"./useMapViewStore-1yyjXCM8.js";import{u as ct,a as ut,B as dt}from"./BasemapLayer-CSqjQAiA.js";import{l as mt,c as ht,a as gt}from"./vendor-geo-2MTwbTwv.js";import{c as pt}from"./node-types-CiI69Tya.js";import{a as ft,b as xt,c as yt}from"./easing-GXZYrvDD.js";import{H as bt,C as vt,N as jt,a as wt}from"./badge-colors-BxLppqaF.js";import{L as Nt}from"./LightSparkline-BAD3v4m9.js";import{P as Ct}from"./Contacts-Dlk8XXyy.js";import{c as kt}from"./geo-utils-DJn8DnxF.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";import"./ping-5xLx9WS1.js";import"./PageLayout-QhCLxU34.js";import"./listbox-BG13Q7Di.js";import"./TimeRangeStepper-B5GfHny9.js";import"./chat-utils-DbM_TyxC.js";import"./SignalIndicator-fAt1Aewy.js";import"./CollisionExplorerModal-B2vZL8RO.js";import"./DataBox-DpDXI-WX.js";function Mt(e,t){const o=Math.max(5,Math.min(e,300)),n=Math.log(5),r=Math.log(300);return 1+(Math.log(o)-n)/(r-n)*5}function St(){const t=f();return e.useMemo(()=>x.getPackets(),[t])}const Ft={textPrimary:b[900],textSecondary:"#4A4A4A",textMuted:b[500],border:"rgba(0, 0, 0, 0.12)",hoverBg:"rgba(0, 0, 0, 0.06)",disabledText:"rgba(0, 0, 0, 0.25)"},Rt={nodeFill:y.blue,nodeStroke:"rgba(255,255,255,0.9)",nodeColor:y.indigo,localColor:y.amber,hubColor:y.purple,gatewayColor:y.indigo,mobileColor:y.orange,roomServerColor:y.pink,neighborColor:y.amber,edges:{rest:b[700],restBright:b[600],restDim:b[800],hoverDirect:"#6FBCBD",hoverLoop:"#8B7BAD",hoverStandard:b[400],hoverNeighbor:y.amber,neighborRest:b[500],neighborHover:y.amber,highlight:"#FFD700"},edgeOpacity:.82};function Tt(){if("undefined"==typeof window)return Rt;const e=v(),t=j();return{nodeFill:e.nodeFill,nodeStroke:e.nodeStroke,nodeColor:Rt.nodeColor,localColor:e.localColor,hubColor:e.hubColor,gatewayColor:e.gatewayColor,mobileColor:e.mobileColor,roomServerColor:e.roomColor,neighborColor:e.neighborColor,edges:{rest:t.rest,restBright:t.restBright,restDim:t.restDim,hoverDirect:t.hoverDirect,hoverLoop:t.hoverLoop,hoverStandard:t.hoverStandard,hoverNeighbor:t.hoverNeighbor,neighborRest:Rt.edges.neighborRest,neighborHover:Rt.edges.neighborHover,highlight:t.highlight},edgeOpacity:Rt.edgeOpacity}}const Lt=2e3,Et=M.snappy,Bt=Ft,Dt=e.createContext("dark"),Ht=()=>e.useContext(Dt);function $t({color:e,ring:o}){return t.jsx("span",{className:"shrink-0 rounded-full","aria-hidden":"true",style:{width:14,height:14,backgroundColor:o?"transparent":e,border:o?`4px solid ${e}`:void 0,boxSizing:"border-box"}})}function At({color:e,pattern:o="solid"}){return t.jsx("svg",{className:"shrink-0","aria-hidden":"true",width:18,height:6,viewBox:"0 0 18 6",children:t.jsx("line",{x1:0,y1:3,x2:18,y2:3,stroke:e,strokeWidth:3,strokeLinecap:"round",strokeDasharray:"dashed"===o?"5,3":"dotted"===o?"2,3":void 0})})}function Pt({indicator:e,label:o,tooltip:n}){const r="light"===Ht();return t.jsxs("div",{className:"flex items-center gap-1.5",children:[e,t.jsx("span",{className:ue(!r&&"text-fg-secondary"),style:r?{color:Bt.textSecondary}:void 0,children:o}),n&&t.jsx(k,{content:n,delay:200,children:t.jsx("span",{className:ue("cursor-help text-[11px] opacity-75 hover:opacity-100 transition-opacity",!r&&"text-fg-muted"),style:r?{color:Bt.textMuted}:void 0,children:"ⓘ"})})]})}function zt({title:e,tooltip:o,isOpen:n,onToggle:r,showDivider:s,children:a}){const i="light"===Ht(),l=function(e){return`legend-section-${e.toLowerCase().replace(/\s+/g,"-")}`}(e);return t.jsxs("div",{className:s?"mt-2 pt-2 border-t":"",style:s?{borderColor:i?Bt.border:"var(--map-ui-border)"}:void 0,children:[t.jsxs("button",{type:"button",onClick:r,"aria-expanded":n,"aria-controls":l,className:ue("group w-full flex items-center justify-between py-1 min-h-[44px] sm:min-h-0 font-medium transition-colors",!i&&"text-fg-secondary hover:text-fg-primary"),style:i?{color:Bt.textSecondary}:void 0,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[e,t.jsx(k,{content:o,delay:200,children:t.jsx("span",{className:ue("cursor-help text-[11px] opacity-75 group-hover:opacity-100 transition-opacity",!i&&"text-fg-muted"),style:i?{color:Bt.textMuted}:void 0,children:"ⓘ"})})]}),t.jsx(nt.span,{animate:{rotate:n?0:-90},transition:{duration:.15},"aria-hidden":"true",children:t.jsx(be,{className:"w-3 h-3",style:i?{color:Bt.textMuted}:{color:"var(--fg-muted)"}})})]}),t.jsx(rt,{initial:!1,children:n&&t.jsx(nt.div,{id:l,role:"region","aria-label":e,initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:Et,className:"overflow-hidden",children:t.jsx("div",{className:"flex flex-col gap-1 pt-1.5",children:a})})})]})}function It({label:e,value:o,color:n}){const r="light"===Ht();return t.jsxs("div",{className:ue("flex justify-between tabular-nums",!r&&"text-fg-muted"),style:r?{color:Bt.textMuted}:void 0,children:[t.jsx("span",{children:e}),t.jsx("span",{style:n?{color:n}:r?{color:Bt.textSecondary}:{color:"var(--fg-secondary)"},children:o})]})}function qt({icon:e,color:o,title:n,subtitle:r}){const s="light"===Ht();return t.jsx("div",{className:"mt-1.5 pt-1.5 border-t",style:{borderColor:s?Bt.border:"var(--map-ui-border)"},children:t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"shrink-0",style:{color:o},children:e}),t.jsxs("div",{className:"flex flex-col min-w-0",children:[t.jsx("span",{className:"font-medium truncate",style:{color:o},children:n}),t.jsx("span",{className:ue("text-[10px] leading-tight",!s&&"text-fg-muted"),style:s?{color:Bt.textMuted}:void 0,children:r})]})]})})}function Ot({showTopology:o,validatedPolylineCount:n,filteredNeighborCount:r,hasLocalNode:s,meshTopology:a,zeroHopNeighbors:i,neighborsWithLocation:l,basemapMode:c="dark"}){const u=w(),d=N(),m=C(),h=d.filter(e=>e.isLikelyReal).length,p=function(e){let t=0;for(const o of e.txDelayRecommendations.values())"backbone"===o.networkRole&&t++;return t}(a),f=i.size>0,[x,y]=e.useState(!0),[b,v]=e.useState(!0),[j,k]=e.useState(!0);return t.jsx(Dt.Provider,{value:c,children:t.jsxs("div",{className:"map-control-surface p-2.5 text-xs",children:[t.jsxs(zt,{title:"Nodes",tooltip:"Node type shown by shape + color. Yellow = direct RF neighbor.",isOpen:x,onToggle:()=>y(e=>!e),children:[t.jsx(Pt,{indicator:t.jsx($t,{color:u.nodeFill}),label:"Node",tooltip:"Standard mesh node. Repeater, client, or companion device."}),t.jsx(Pt,{indicator:t.jsx($t,{color:u.hubColor}),label:"Hub",tooltip:"Network hub (≥10% of last-hop traffic)."}),(M=l,M.some(([,e])=>{var t;const o=null==(t=e.contact_type)?void 0:t.toLowerCase();return"room server"===o||"room_server"===o||"room"===o||"server"===o})&&t.jsx(Pt,{indicator:t.jsx(ge,{className:"w-3 h-3 shrink-0",style:{color:u.roomColor},strokeWidth:2.5}),label:"Room",tooltip:"Room Server identity for client sync."})),t.jsx(Pt,{indicator:t.jsx(pe,{className:"w-3 h-3 shrink-0",style:{color:u.localColor},strokeWidth:2.5}),label:"Local",tooltip:"Your repeater running pyMC_Repeater."}),f&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.neighborColor}),label:"Neighbor",tooltip:"Zero-hop direct RF contact."}),a.gatewayNodes.length>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.gatewayColor}),label:"Gateway",tooltip:"Significant forwarder (7-10% traffic)."}),p>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.hubColor}),label:"Backbone",tooltip:"Critical relay with high centrality."}),a.mobileNodes.length>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.mobileColor,ring:!0}),label:"Mobile",tooltip:"Volatile node that appears/disappears."}),h>0&&t.jsx(Pt,{indicator:t.jsx(fe,{className:"w-3 h-3 shrink-0",style:{color:u.ghostColor},strokeWidth:2.5}),label:`Ghost (${h})`,tooltip:"Unknown repeater from Viterbi analysis."})]}),f&&t.jsxs(zt,{title:"Link Quality",tooltip:"Neighbor edge colors based on bidirectional balance.",isOpen:b,onToggle:()=>v(e=>!e),showDivider:!0,children:[t.jsx(Pt,{indicator:t.jsx(At,{color:g.YELLOW,pattern:"solid"}),label:"2-Way",tooltip:"33-67% balanced. Ideal bidirectional link."}),t.jsx(Pt,{indicator:t.jsx(At,{color:g.GREEN,pattern:"dashed"}),label:"Listener",tooltip:">67% listener. They hear us well."}),t.jsx(Pt,{indicator:t.jsx(At,{color:g.RED,pattern:"dotted"}),label:"Loud",tooltip:"<33% listener. They route more to us."})]}),o&&n>0&&t.jsxs(zt,{title:"Topology",tooltip:"Links with 5+ validations. Thickness = strength.",isOpen:j,onToggle:()=>k(e=>!e),showDivider:!0,children:[t.jsx(It,{label:"Nodes",value:r+(s?1:0)}),a.hubNodes.length>0&&t.jsx(It,{label:"Hubs",value:a.hubNodes.length,color:Rt.hubColor}),a.loops.length>0&&t.jsx(qt,{icon:t.jsx(xe,{className:"w-3 h-3"}),color:Rt.edges.hoverLoop,title:`${a.loops.length} ${1===a.loops.length?"Loop":"Loops"}`,subtitle:"Redundant paths"}),m.totalPaths>0&&t.jsx(qt,{icon:t.jsx(ye,{className:"w-3 h-3"}),color:u.ghostColor,title:`${m.totalPaths.toLocaleString()} Viterbi`,subtitle:"HMM decoded paths"})]})]})});var M}const Wt={repeater:"blue",companion:"cyan",room_server:"pink",hubs:"indigo",direct:"green"},_t={repeater:"Repeaters",companion:"Companions",room_server:"Rooms",hubs:"Hubs",direct:"Direct"},Ut={repeater:"Repeater nodes (mesh relays)",companion:"Companion devices (clients)",room_server:"Room server nodes",hubs:"Hub nodes and their connections",direct:"Zero-hop (direct RF) neighbors"},Kt=["repeater","companion","room_server"],Vt=["hubs","direct"],Zt="!p-2.5 sm:!p-1.5 !rounded-md min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 shrink-0 flex items-center justify-center",Gt="!p-2.5 sm:!p-1.5 !rounded-none min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 shrink-0 flex items-center justify-center";function Jt({mapRef:o,showNeighborLines:n,onToggleNeighborLines:r,hasNeighborPolylines:s,nodeFilters:a,onToggleFilter:i,onToggleAll:l,filterCounts:c,showCoverage:u,onToggleCoverage:d,showMinCut:m=!1,onToggleMinCut:h,hasMinCutData:g=!1,show3DTerrain:p,onToggle3DTerrain:f,basemapMode:x,onToggleBasemap:y,isFullscreen:b,onToggleFullscreen:v,showLinkQuality:j=!1,onToggleLinkQuality:w,hasTraceLinks:N=!1}){const[C,k]=e.useState(()=>!("undefined"!=typeof window&&window.innerWidth<640)),M="w-4 h-4",R="light"===x?"#525252":"var(--fg-secondary)",T=a.length>=at.length;return t.jsx(t.Fragment,{children:t.jsxs("div",{className:"absolute top-3 right-3 z-[600] flex flex-col gap-2 sm:top-4 sm:right-4 max-w-[calc(100vw-1.5rem)] sm:max-w-none pr-[env(safe-area-inset-right)]",children:[t.jsxs("div",{className:"map-control-surface flex flex-nowrap items-center gap-0.5 sm:gap-1 p-1 overflow-hidden",children:[s&&t.jsx(S,{plain:!0,color:n?"warning":"muted",onClick:r,title:n?"Hide edge lines":"Show edge lines","aria-label":n?"Hide edge lines":"Show edge lines","aria-pressed":n,className:Zt,"data-tint":n?"warning":void 0,children:t.jsx(ve,{className:M})}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>k(e=>!e),title:C?"Hide node filters":"Show node filters","aria-label":C?"Collapse node filters":"Expand node filters","aria-expanded":C,className:Zt,children:t.jsx(je,{className:M})}),t.jsx(rt,{initial:!1,children:C&&t.jsxs(nt.div,{className:"flex items-center gap-0.5 flex-nowrap overflow-x-auto scrollbar-none max-w-[50vw] sm:max-w-none sm:overflow-visible",role:"group","aria-label":"Node type filters",initial:{width:0,opacity:0},animate:{width:"auto",opacity:1},exit:{width:0,opacity:0},transition:{duration:.2,ease:[.4,0,.2,1]},children:[t.jsx(F,{color:T?"green":"zinc",customColor:T?void 0:R,onClick:l,title:"Show all nodes","aria-pressed":T,"aria-label":"Show all node types",className:"shrink-0",children:"All"}),Kt.map(e=>{const o=c[e];if(0===o)return null;const n=!T&&a.includes(e);return t.jsx(F,{color:n?Wt[e]:"zinc",customColor:n?void 0:R,onClick:()=>i(e),title:Ut[e],"aria-pressed":n,"aria-label":`${_t[e]} (${o})`,className:"shrink-0",children:_t[e]},e)}),Vt.some(e=>c[e]>0)&&t.jsx("span",{className:"mx-0.5 h-3 w-px bg-[var(--map-ui-border,var(--edge-subtle))] hidden sm:block shrink-0","aria-hidden":"true"}),Vt.map(e=>{const o=c[e];if(0===o)return null;const n=!T&&a.includes(e);return t.jsx(F,{color:n?Wt[e]:"zinc",customColor:n?void 0:R,onClick:()=>i(e),title:Ut[e],"aria-pressed":n,"aria-label":`${_t[e]} (${o})`,className:"shrink-0",children:_t[e]},e)})]})}),g&&h&&t.jsx(S,{plain:!0,color:m?"primary":"muted",onClick:h,title:m?"Hide community partition":"Show community partition","aria-label":m?"Hide community partition":"Show community partition","aria-pressed":m,className:Zt,"data-tint":m?"primary":void 0,children:t.jsx(we,{className:M})}),t.jsx(S,{plain:!0,color:"light"===x?"primary":"muted",onClick:y,title:"light"===x?"Switch to dark map":"Switch to light map","aria-label":"light"===x?"Switch to dark map":"Switch to light map","aria-pressed":"light"===x,className:Zt,"data-tint":"light"===x?"primary":void 0,children:"light"===x?t.jsx(Ne,{className:M}):t.jsx(Ce,{className:M})}),t.jsx(S,{plain:!0,color:p?"success":"muted",onClick:f,title:p?"Disable 3D terrain":"Enable 3D terrain","aria-label":p?"Disable 3D terrain":"Enable 3D terrain","aria-pressed":p,className:Zt,"data-tint":p?"success":void 0,children:t.jsx(ke,{className:M})}),t.jsx(S,{plain:!0,color:"muted",onClick:v,title:b?"Exit fullscreen":"Fullscreen","aria-label":b?"Exit fullscreen":"Enter fullscreen","aria-pressed":b,className:Zt,children:b?t.jsx(Me,{className:M}):t.jsx(Se,{className:M})})]}),t.jsxs("div",{className:"map-control-surface flex flex-col items-stretch !overflow-hidden self-end !p-0",children:[t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e,t;null==(t=null==(e=o.current)?void 0:e.getMap())||t.zoomIn()},title:"Zoom in","aria-label":"Zoom in",className:Gt,children:t.jsx(Fe,{className:M})}),t.jsx("div",{className:"h-px bg-border-subtle","aria-hidden":"true"}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e,t;null==(t=null==(e=o.current)?void 0:e.getMap())||t.zoomOut()},title:"Zoom out","aria-label":"Zoom out",className:Gt,children:t.jsx(Re,{className:M})}),t.jsx("div",{className:"h-px bg-border-subtle","aria-hidden":"true"}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e;const t=null==(e=o.current)?void 0:e.getMap();t&&t.easeTo({bearing:0,pitch:0,duration:300})},title:"Reset bearing to north","aria-label":"Reset bearing to north",className:Gt,children:t.jsx(Te,{className:M})})]}),N&&w&&t.jsx("div",{className:"map-control-surface flex flex-col items-stretch !overflow-hidden self-end !p-0",children:t.jsx(S,{plain:!0,color:j?"success":"muted",onClick:w,title:j?"Hide link quality overlay":"Show link quality overlay","aria-label":j?"Hide link quality overlay":"Show link quality overlay","aria-pressed":j,className:Gt,"data-tint":j?"success":void 0,children:t.jsx(Le,{className:M})})})]})})}const Yt={text:Ft.textSecondary,activeText:"#16A34A",activeBg:"rgba(220, 252, 231, 1)"},Qt="DeepAnalysis";function Xt(){return"abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())]}function eo({isActive:o,hasAnalyzed:n,isLoading:r,onClick:s,basemapMode:a="dark"}){const i="light"===a,l=i?Yt.text:void 0,c=i?Yt.activeText:"#4ADE80",[u,d]=e.useState(!1),[m,h]=e.useState(Qt),g=e.useRef(!1),p=e.useRef(null),[f]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)}),x=u&&!o&&!r&&f;e.useEffect(()=>{if(u&&!o&&!r&&!g.current){g.current=!0;const e=performance.now(),t=o=>{const n=o-e,r=Math.min(n/700,1),s=Math.floor(12*r);let a="";for(let e=0;e<12;e++)a+=e{p.current&&cancelAnimationFrame(p.current)}},[u,o,r]);const y=r?"Analyzing...":m,b=r?"Analyzing packet history":n?o?"Hide topology edges":"Show topology edges":"Load full packet history and build topology";return t.jsxs("button",{onClick:s,onMouseEnter:()=>f&&d(!0),onMouseLeave:()=>f&&d(!1),onPointerEnter:()=>f&&d(!0),onPointerLeave:()=>f&&d(!1),disabled:r,className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base "+(r?"cursor-wait":""),style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:i?Yt.activeBg:"rgba(10, 26, 10, 1)"}},title:b,"aria-label":b,"aria-pressed":o,children:[r?t.jsx(Ee,{className:"w-3.5 h-3.5 shrink-0 animate-spin",style:{color:c}}):t.jsx(Be,{className:"w-3.5 h-3.5 shrink-0 transition-colors "+(o?"":"text-fg-secondary"),style:{...o&&{color:c},...x&&{color:c},...!o&&!x&&l&&{color:l}}}),t.jsx("span",{className:o?"":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:"ui-monospace, SFMono-Regular, monospace",fontSize:"0.6875rem",fontWeight:o||x?700:500,letterSpacing:"-0.01em",lineHeight:1,...o&&{color:c},...x&&{color:c},...!o&&!x&&l&&{color:l}},children:y})]})}const to=y.teal,oo={text:Ft.textSecondary,activeTeal:"#0D7377",activeBg:"rgba(204, 251, 241, 1)"};function no({isActive:o,onClick:n,basemapMode:r="dark"}){const s="light"===r,a=s?oo.text:void 0,i=s?oo.activeTeal:to,[l,c]=e.useState(!1),[u,d]=e.useState(0),m=e.useRef(!1),h=e.useRef(null),[g,p]=e.useState(0),f=e.useRef(!1),[x]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)}),y=l&&!o&&x;e.useEffect(()=>{y&&!f.current&&(f.current=!0,p(1),setTimeout(()=>p(2),100),setTimeout(()=>p(3),200)),l||(f.current=!1,p(0))},[y,l]),e.useEffect(()=>{if(l&&!o&&!m.current){m.current=!0;const e=performance.now(),t=o=>{const n=o-e,r=Math.min(n/400,1);d(r),r<1&&(h.current=requestAnimationFrame(t))};h.current=requestAnimationFrame(t)}return l||(h.current&&(cancelAnimationFrame(h.current),h.current=null),m.current=!1,d(0)),()=>{h.current&&cancelAnimationFrame(h.current)}},[l,o]);const b=e=>{if(o)return i;if(!y)return a;const t=11*u;return e>=t-2&&ex&&c(!0),onMouseLeave:()=>x&&c(!1),onPointerEnter:()=>x&&c(!0),onPointerLeave:()=>x&&c(!1),className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base",style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:s?oo.activeBg:"rgba(10, 36, 32, 1)"}},title:o?"Disable live packet tracing (reduces CPU usage)":"Enable live packet tracing","aria-label":v,"aria-pressed":o,children:[t.jsx(De,{className:"w-3.5 h-3.5 shrink-0 "+(o?"":"text-fg-secondary"),fill:1===g?"#FFFFFF":3===g?i:"none",stroke:1===g||2===g?"#FFFFFF":o||y?i:a||"currentColor",style:{transition:"fill 0.05s, stroke 0.05s"}}),t.jsx("span",{className:o?"":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:"ui-monospace, SFMono-Regular, monospace",fontSize:"0.6875rem",fontWeight:o||y?700:500,letterSpacing:"-0.01em",lineHeight:1},children:"LiveTrace".split("").map((e,o)=>t.jsx("span",{style:{color:b(o)||void 0},children:e},o))})]})}const ro={text:Ft.textSecondary,activeBg:"rgba(254, 243, 199, 1)",disabledText:Ft.disabledText},so="#fe8019";function ao({isActive:o,onClick:n,brightness:r=.7,onBrightnessChange:s,basemapMode:a="dark"}){const i="light"===a,l=i?ro.text:void 0,[c,u]=e.useState(!1),[d,m]=e.useState(!1),[h]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)});e.useEffect(()=>{if(!c||o)return;const e=requestAnimationFrame(()=>m(!0)),t=setTimeout(()=>m(!1),80);return()=>{cancelAnimationFrame(e),clearTimeout(t)}},[c,o]);const g=Math.max(.01,Math.min(1,r)),p=g<.999,f=g>.011,x=c&&!o&&h,y=o?"Configure wardriving coverage":"Show wardriving coverage";return t.jsxs("button",{onClick:n,onMouseEnter:()=>h&&u(!0),onMouseLeave:()=>h&&u(!1),onPointerEnter:()=>h&&u(!0),onPointerLeave:()=>h&&u(!1),className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base",style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:i?ro.activeBg:"rgba(26, 20, 8, 1)"}},title:y,"aria-label":y,"aria-pressed":o,children:[t.jsx(He,{className:"w-3.5 h-3.5 shrink-0 transition-colors "+(o?"text-sys-amber":"text-fg-secondary"),style:x?{color:so}:!o&&l?{color:l}:void 0}),t.jsx("span",{className:o?"text-sys-amber":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:o||x?"'Wardrive', serif":"ui-monospace, SFMono-Regular, monospace",fontSize:o||x?"0.75rem":"0.6875rem",fontWeight:500,letterSpacing:"-0.01em",lineHeight:1,transition:"none",transform:o?"scale(1.45)":x?`scale(${d?1.595:1.45})`:void 0,transformOrigin:"left center",...x?{color:so}:!o&&l?{color:l}:{}},children:"Wardrive"}),o&&s&&t.jsxs("div",{className:"ml-auto flex items-center gap-0.5",children:[t.jsx("button",{onClick:e=>{e.stopPropagation();const t=Math.max(.01,g-.2);null==s||s(t)},disabled:!f,className:"p-1 sm:p-0.5 min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center rounded transition-colors "+(f?"text-sys-amber hover:bg-[var(--map-ui-hover,var(--elevated))] active:bg-[var(--map-ui-active,var(--subtle))]":"cursor-not-allowed"),style:f?void 0:{color:i?ro.disabledText:"rgba(251, 191, 36, 0.3)"},title:`Decrease opacity (${Math.round(100*g)}%)`,"aria-label":`Decrease opacity, currently ${Math.round(100*g)}%`,children:t.jsx(Ne,{className:"w-3.5 h-3.5"})}),t.jsx("button",{onClick:e=>{e.stopPropagation();const t=Math.min(1,g+.2);null==s||s(t)},disabled:!p,className:"p-1 sm:p-0.5 min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center rounded transition-colors "+(p?"text-sys-amber hover:bg-[var(--map-ui-hover,var(--elevated))] active:bg-[var(--map-ui-active,var(--subtle))]":"cursor-not-allowed"),style:p?void 0:{color:i?ro.disabledText:"rgba(251, 191, 36, 0.3)"},title:`Increase opacity (${Math.round(100*g)}%)`,"aria-label":`Increase opacity, currently ${Math.round(100*g)}%`,children:t.jsx(Ce,{className:"w-3.5 h-3.5"})})]})]})}function io(e){let t=!0,o=-90,n=90,r=-180,s=180;for(const a of e.toLowerCase()){const e="0123456789bcdefghjkmnpqrstuvwxyz".indexOf(a);if(-1!==e)for(let a=4;a>=0;a--){const i=e>>a&1;if(t){const e=(r+s)/2;i?r=e:s=e}else{const e=(o+n)/2;i?o=e:n=e}t=!t}}return{lat:(o+n)/2,lon:(r+s)/2}}function lo(e){return Math.exp(-e*Math.LN2/7)}const co="pymc-wardriving-url",uo="pymc-wardriving-enabled",mo="pymc-wardriving-brightness";function ho(e){"undefined"!=typeof localStorage&&(e?localStorage.setItem(co,e):localStorage.removeItem(co))}function go(e){"undefined"!=typeof localStorage&&localStorage.setItem(uo,String(e))}function po(){if("undefined"==typeof localStorage)return.7;const e=localStorage.getItem(mo);if(e){const t=parseFloat(e);if(!isNaN(t)&&t>=.01&&t<=1)return t}return.7}function fo(e,t=null){if(null!==e){const o=(Math.max(-12,Math.min(12,e))+12)/24;return null!==t?.8*o+(Math.max(-120,Math.min(-50,t))+120)/70*.2:o}return null!==t?(Math.max(-120,Math.min(-50,t))+120)/70:.5}const xo=de((e,t)=>({status:"idle",isVisible:"undefined"!=typeof localStorage&&"true"===localStorage.getItem(uo),coveragePoints:[],repeaters:[],error:null,stats:{coverageCount:0,repeaterCount:0,lastUpdated:null},url:"undefined"==typeof localStorage?"":localStorage.getItem(co)||"",brightness:po(),isModalOpen:!1,openModal:()=>e({isModalOpen:!0}),closeModal:()=>e({isModalOpen:!1}),setUrl:t=>e({url:t}),setBrightness:t=>{const o=Math.max(.01,Math.min(1,t));!function(e){if("undefined"==typeof localStorage)return;const t=Math.max(.01,Math.min(1,e));localStorage.setItem(mo,String(t))}(o),e({brightness:o})},toggleVisibility:()=>{const o=!t().isVisible;go(o),e({isVisible:o})},setVisible:t=>{go(t),e({isVisible:t})},loadCoverage:async t=>{if(!t.trim())return e({error:"Please enter a URL",status:"error"}),!1;try{new URL(t.trim())}catch{return e({error:"Invalid URL format",status:"error"}),!1}e({error:null,status:"connecting"});try{e({status:"loading"});const o=await async function(e){const t=`${e.replace(/\/+$/,"").replace(/\/get-nodes$/,"").replace(/\/get-samples$/,"")}/get-samples`,o=await async function(e,t={},o=8e3){const n=new AbortController,r=setTimeout(()=>n.abort(),o);try{return await fetch(e,{...t,signal:n.signal})}catch(s){if(s instanceof Error&&"AbortError"===s.name)throw new Error(`Connection timed out after ${o/1e3}s`);throw s}finally{clearTimeout(r)}}(t,{headers:{Accept:"application/json"}});if(!o.ok)throw new Error(`Failed to fetch precise samples: ${o.status}`);return o.json()}(t.trim());if(!o||"object"!=typeof o)throw new Error("Invalid response from server");if(!Array.isArray(o.keys))throw new Error("No sample data found in response");e({status:"processing"});const n=function(e){var t;const o=[];for(const n of e.keys){if(!n.observed)continue;const{lat:e,lon:r}=io(n.hash),s=parseInt(n.time,10),a=isNaN(s)?30:(Date.now()-s)/864e5,i=lo(a),l=fo(n.snr,n.rssi)*(.3+.7*i);o.push({lat:e,lon:r,successRate:n.observed?1:0,weight:l,totalSamples:1,ageDays:a,geohash:n.hash,repeaters:(null==(t=n.path)?void 0:t.map(e=>e.toLowerCase()))||[]})}return o}(o);if(0===n.length)throw new Error("No valid coverage points found");return e({coveragePoints:n,repeaters:[],stats:{coverageCount:n.length,repeaterCount:0,lastUpdated:new Date},status:"success",isVisible:!0,url:t.trim()}),ho(t.trim()),go(!0),!0}catch(o){const t=o instanceof Error?o.message:"Failed to load coverage data";let n=t;return t.includes("timed out")?n="Connection timed out. Server may be unreachable or slow.":t.includes("Failed to fetch")||t.includes("NetworkError")?n="Could not connect to server. Check the URL and try again.":t.includes("CORS")?n="Server does not allow cross-origin requests.":t.includes("404")?n="Coverage endpoint not found. Check the URL.":(t.includes("ERR_NAME_NOT_RESOLVED")||t.includes("DNS"))&&(n="Server not found. Check the URL for typos."),e({error:n,status:"error"}),!1}},clearCoverage:()=>{e({coveragePoints:[],repeaters:[],stats:{coverageCount:0,repeaterCount:0,lastUpdated:null},status:"idle",error:null,isVisible:!1,url:""}),ho(""),go(!1)}})),yo={bg:"#F8F8F8",bgSubtle:"#F0F0F0",bgElevated:"#FFFFFF",bgInput:"#FFFFFF",border:"rgba(0, 0, 0, 0.12)",borderStrong:"rgba(0, 0, 0, 0.20)",borderFocus:"#3B82F6",text:"#1A1A1A",textSecondary:"#4A4A4A",textMuted:"#737373",success:"#059669",successBg:"#ECFDF5",successBorder:"#A7F3D0",error:"#DC2626",errorBg:"#FEF2F2",errorBorder:"#FECACA",info:"#2563EB",infoBg:"#EFF6FF",infoBorder:"#BFDBFE",warning:"#D97706",warningBg:"#FFFBEB",warningBorder:"#FDE68A",primary:"#F59E0B",hoverBg:"rgba(0, 0, 0, 0.04)",sliderTrack:"#E5E7EB",sliderThumb:"#F59E0B"},bo={bg:"var(--surface)",bgSubtle:"var(--subtle)",bgElevated:"var(--elevated)",bgInput:"var(--subtle)",border:"var(--edge-subtle)",borderStrong:"var(--edge-strong)",borderFocus:"var(--sys-blue)",text:"var(--fg-primary)",textSecondary:"var(--fg-secondary)",textMuted:"var(--fg-muted)",success:"var(--sys-green)",successBg:"rgba(74, 222, 128, 0.1)",successBorder:"rgba(74, 222, 128, 0.3)",error:"var(--sys-red)",errorBg:"rgba(239, 68, 68, 0.1)",errorBorder:"rgba(239, 68, 68, 0.3)",info:"var(--sys-indigo)",infoBg:"rgba(249, 210, 111, 0.1)",infoBorder:"rgba(249, 210, 111, 0.3)",warning:"var(--sys-indigo)",warningBg:"rgba(249, 210, 111, 0.1)",warningBorder:"rgba(249, 210, 111, 0.3)",primary:"var(--sys-indigo)",hoverBg:"var(--hover-tint)",sliderTrack:"var(--elevated)",sliderThumb:"var(--sys-indigo)"},vo=e.createContext({theme:bo,isLight:!1});function jo(){return e.useContext(vo)}function wo({status:o,hasData:n}){const{theme:r,isLight:s}=jo(),a=e.useMemo(()=>"connecting"===o||"loading"===o||"processing"===o?{icon:t.jsx(Ee,{className:"w-3.5 h-3.5 animate-spin"}),label:"connecting"===o?"Connecting...":"loading"===o?"Loading...":"Processing...",color:r.warning,bg:r.warningBg}:"error"===o?{icon:t.jsx(qe,{className:"w-3.5 h-3.5"}),label:"Disconnected",color:r.error,bg:r.errorBg}:n?{icon:t.jsx(Oe,{className:"w-3.5 h-3.5"}),label:"Connected",color:r.success,bg:r.successBg}:{icon:t.jsx($e,{className:"w-3.5 h-3.5"}),label:"Ready",color:r.textMuted,bg:s?"rgba(0,0,0,0.04)":"rgba(255,255,255,0.04)"},[o,n,r,s]);return t.jsxs(nt.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium",style:{backgroundColor:a.bg,color:a.color},children:[a.icon,t.jsx("span",{children:a.label})]},a.label)}function No({status:o}){const{theme:n}=jo(),r=e.useMemo(()=>{switch(o){case"connecting":return 25;case"loading":return 60;case"processing":return 90;default:return 0}},[o]);return 0===r?null:t.jsx(nt.div,{initial:{opacity:0,scaleY:0},animate:{opacity:1,scaleY:1},exit:{opacity:0,scaleY:0},className:"h-1 rounded-full overflow-hidden origin-top",style:{backgroundColor:n.sliderTrack},children:t.jsx(nt.div,{className:"h-full rounded-full",style:{backgroundColor:n.primary},initial:{width:0},animate:{width:`${r}%`},transition:{duration:.4,ease:"easeOut"}})})}function Co({variant:o,title:n,description:r,onDismiss:s}){const{theme:a}=jo(),i=e.useMemo(()=>{switch(o){case"success":return{icon:t.jsx(Ue,{className:"w-4 h-4"}),color:a.success,bg:a.successBg,border:a.successBorder};case"error":return{icon:t.jsx(_e,{className:"w-4 h-4"}),color:a.error,bg:a.errorBg,border:a.errorBorder};case"info":return{icon:t.jsx(We,{className:"w-4 h-4"}),color:a.info,bg:a.infoBg,border:a.infoBorder}}},[o,a]);return t.jsxs(nt.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},exit:{opacity:0,y:-8},transition:M.snappy,className:"flex items-start gap-3 p-3 rounded-lg border",style:{backgroundColor:i.bg,borderColor:i.border,color:i.color},children:[t.jsx("div",{className:"shrink-0 mt-0.5",children:i.icon}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("p",{className:"text-sm font-medium",children:n}),r&&t.jsx("p",{className:"text-xs mt-0.5 opacity-80",children:r})]}),s&&t.jsx("button",{onClick:s,className:"shrink-0 p-1 rounded hover:bg-black/10 transition-colors","aria-label":"Dismiss",children:t.jsx(Ae,{className:"w-3.5 h-3.5"})})]})}function ko({value:o,onChange:n,onSubmit:r,disabled:s}){const{theme:a,isLight:i}=jo(),[l,c]=e.useState(!1);return t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("label",{className:"block text-sm font-medium",style:{color:a.textSecondary},children:"Coverage Server URL"}),t.jsxs("div",{className:"relative",children:[t.jsx("input",{type:"url",value:o,onChange:e=>n(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||s||(e.preventDefault(),r())},onFocus:()=>c(!0),onBlur:()=>c(!1),placeholder:"https://coverage.wcmesh.com",disabled:s,className:ue("w-full pl-3 pr-10 py-2.5 rounded-lg border text-sm transition-all duration-150","focus:outline-none",s&&"opacity-50 cursor-not-allowed"),style:{backgroundColor:a.bgInput,borderColor:l?a.borderFocus:a.border,color:a.text,boxShadow:l?"0 0 0 3px "+(i?"rgba(59, 130, 246, 0.15)":"rgba(139, 92, 246, 0.15)"):"none"}}),o&&!s&&t.jsx("button",{onClick:()=>n(""),className:"absolute right-2.5 top-1/2 -translate-y-1/2 p-1 rounded transition-colors",style:{color:a.textMuted},onMouseEnter:e=>e.currentTarget.style.color=a.text,onMouseLeave:e=>e.currentTarget.style.color=a.textMuted,"aria-label":"Clear URL",children:t.jsx(Ae,{className:"w-4 h-4"})})]}),t.jsx("p",{className:"text-xs",style:{color:a.textMuted},children:"Press Enter to connect, or use the Connect button below"})]})}function Mo({value:e,onChange:o}){const{theme:n,isLight:r}=jo(),s=Math.round(100*e);return t.jsx(nt.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},transition:M.gentle,className:"overflow-hidden",children:t.jsx("div",{className:"p-3 rounded-lg border",style:{backgroundColor:n.bgSubtle,borderColor:n.border},children:t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsxs("div",{className:"relative w-4 h-4",children:[t.jsx(Ne,{className:"w-4 h-4 absolute inset-0 transition-opacity",style:{color:n.textMuted,opacity:e<.5?1:0}}),t.jsx(Ce,{className:"w-4 h-4 absolute inset-0 transition-opacity",style:{color:n.primary,opacity:e>=.5?1:0}})]}),t.jsxs("div",{className:"flex-1",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[t.jsx("span",{className:"text-xs font-medium",style:{color:n.textSecondary},children:"Layer Opacity"}),t.jsxs("span",{className:"text-xs font-mono tabular-nums px-1.5 py-0.5 rounded",style:{color:n.text,backgroundColor:r?"rgba(0,0,0,0.06)":"rgba(255,255,255,0.06)"},children:[s,"%"]})]}),t.jsx("input",{type:"range",min:5,max:100,value:s,onChange:e=>o(Number(e.target.value)/100),className:ue("w-full h-2 rounded-full appearance-none cursor-pointer","[&::-webkit-slider-thumb]:appearance-none","[&::-webkit-slider-thumb]:w-4","[&::-webkit-slider-thumb]:h-4","[&::-webkit-slider-thumb]:rounded-full","[&::-webkit-slider-thumb]:cursor-pointer","[&::-webkit-slider-thumb]:transition-transform","[&::-webkit-slider-thumb]:hover:scale-110","[&::-webkit-slider-thumb]:shadow-lg","[&::-moz-range-thumb]:appearance-none","[&::-moz-range-thumb]:w-4","[&::-moz-range-thumb]:h-4","[&::-moz-range-thumb]:rounded-full","[&::-moz-range-thumb]:border-0","[&::-moz-range-thumb]:cursor-pointer"),style:{background:`linear-gradient(to right, ${n.primary} ${s}%, ${n.sliderTrack} ${s}%)`,"--thumb-color":n.sliderThumb}}),t.jsx("style",{children:`\n input[type="range"]::-webkit-slider-thumb {\n background-color: ${n.sliderThumb};\n }\n input[type="range"]::-moz-range-thumb {\n background-color: ${n.sliderThumb};\n }\n `})]})]})})})}function So({coverageCount:e,repeaterCount:o,lastUpdated:n}){const{theme:r}=jo();return t.jsxs("div",{className:"grid grid-cols-3 gap-2 p-3 rounded-lg border",style:{backgroundColor:r.bgSubtle,borderColor:r.border},children:[t.jsxs("div",{className:"text-center",children:[t.jsx(it,{value:e,format:{useGrouping:!0,maximumFractionDigits:0},className:"text-lg font-semibold tabular-nums block",style:{color:r.text}}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Points"})]}),t.jsxs("div",{className:"text-center border-x",style:{borderColor:r.border},children:[t.jsx(it,{value:o,format:{useGrouping:!0,maximumFractionDigits:0},className:"text-lg font-semibold tabular-nums block",style:{color:r.text}}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Repeaters"})]}),t.jsxs("div",{className:"text-center",children:[t.jsxs("div",{className:"flex items-center justify-center gap-1",children:[t.jsx(Ke,{className:"w-3.5 h-3.5",style:{color:r.textMuted}}),t.jsx("span",{className:"text-lg font-semibold tabular-nums",style:{color:r.text},children:n?n.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"—"})]}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Updated"})]})]})}function Fo({icon:o,label:n,onClick:r,disabled:s,variant:a="default",active:i}){const{theme:l,isLight:c}=jo(),u=e.useMemo(()=>"danger"===a?{text:l.error,hoverBg:c?"rgba(220, 38, 38, 0.08)":"rgba(239, 68, 68, 0.15)"}:{text:i?l.primary:l.textSecondary,hoverBg:l.hoverBg},[a,i,l,c]);return t.jsxs("button",{onClick:r,disabled:s,className:ue("flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-sm font-medium transition-colors",s&&"opacity-50 cursor-not-allowed"),style:{color:u.text},onMouseEnter:e=>!s&&(e.currentTarget.style.backgroundColor=u.hoverBg),onMouseLeave:e=>e.currentTarget.style.backgroundColor="transparent",children:[o,t.jsx("span",{children:n})]})}function Ro(){const o=ct(),n="light"===o,r=n?yo:bo,{isModalOpen:s,closeModal:a,status:i,isVisible:l,stats:c,error:u,url:d,brightness:m,loadCoverage:h,clearCoverage:g,toggleVisibility:p,setUrl:f,setBrightness:x}=xo(),y="connecting"===i||"loading"===i||"processing"===i,b=c.coverageCount>0,[v,j]=e.useState(!0),[w,N]=e.useState(d);e.useEffect(()=>{N(d)},[d]),e.useEffect(()=>{"error"===i&&j(!0)},[i]);const C=e.useCallback(async()=>{await h(w)},[w,h]),k=e.useCallback(()=>{N(""),g()},[g]),F=e.useCallback(e=>{N(e),f(e)},[f]),L=e.useCallback(()=>{y||a()},[y,a]),E=w.trim().length>0&&!y;return t.jsx(vo.Provider,{value:{theme:r,isLight:n},children:t.jsxs(R,{open:s,onClose:L,size:"md",bottomSheet:!0,basemapMode:o,children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b",style:{borderColor:r.border},children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:"p-2 rounded-lg",style:{backgroundColor:r.bgSubtle,color:r.primary},children:t.jsx($e,{className:"w-5 h-5"})}),t.jsxs("div",{children:[t.jsx("h2",{className:"type-micro",style:{color:r.text},children:"Wardriving Coverage"}),t.jsx("p",{className:"text-xs",style:{color:r.textMuted},children:"RF coverage heatmap overlay"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(wo,{status:i,hasData:b}),!y&&t.jsxs(t.Fragment,{children:[t.jsx("button",{onClick:L,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium transition-base radius-inner active:bg-subtle-fill",style:{color:r.primary},children:"Done"}),t.jsx("button",{onClick:L,className:"hidden sm:flex items-center justify-center p-2 rounded-lg transition-colors",style:{color:r.textMuted},onMouseEnter:e=>{e.currentTarget.style.color=r.text,e.currentTarget.style.backgroundColor=r.hoverBg},onMouseLeave:e=>{e.currentTarget.style.color=r.textMuted,e.currentTarget.style.backgroundColor="transparent"},"aria-label":"Close",children:t.jsx(Ae,{className:"w-5 h-5"})})]})]})]}),t.jsx(rt,{children:y&&t.jsx(No,{status:i})}),t.jsxs(T,{className:"space-y-4",children:[t.jsx(ko,{value:w,onChange:F,onSubmit:C,disabled:y}),t.jsx(rt,{children:"error"===i&&u&&v&&t.jsx(Co,{variant:"error",title:"Connection Failed",description:u,onDismiss:()=>j(!1)})}),t.jsx(rt,{children:"success"===i&&b&&t.jsx(Co,{variant:"success",title:"Coverage Data Loaded",description:"Adjust opacity below, then close to view on map"})}),t.jsx(rt,{children:b&&!y&&t.jsx(nt.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},exit:{opacity:0,y:8},transition:M.snappy,children:t.jsx(So,{coverageCount:c.coverageCount,repeaterCount:c.repeaterCount,lastUpdated:c.lastUpdated})})}),t.jsx(rt,{children:b&&!y&&t.jsx(Mo,{value:m,onChange:x})})]}),t.jsxs("div",{className:"flex items-center justify-between p-4 border-t",style:{borderColor:r.border},children:[t.jsx("div",{className:"flex items-center gap-1",children:t.jsx(rt,{children:b&&t.jsxs(nt.div,{initial:{opacity:0,x:-10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:M.snappy,className:"flex items-center gap-1",children:[t.jsx(Fo,{icon:l?t.jsx(Pe,{className:"w-4 h-4"}):t.jsx(ye,{className:"w-4 h-4"}),label:l?"Hide":"Show",onClick:p,disabled:y,active:l}),t.jsx(Fo,{icon:t.jsx(ze,{className:"w-4 h-4"}),label:"Clear",onClick:k,disabled:y,variant:"danger"})]})})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(S,{plain:!0,color:"muted",onClick:L,disabled:y,children:b?"Done":"Cancel"}),t.jsx(S,{color:"warning",onClick:C,disabled:!E,children:y?t.jsxs(t.Fragment,{children:[t.jsx(Ee,{"data-slot":"icon",className:"animate-spin"}),"connecting"===i?"Connecting...":"loading"===i?"Loading...":"Processing..."]}):b?t.jsxs(t.Fragment,{children:[t.jsx(xe,{"data-slot":"icon"}),"Refresh"]}):t.jsxs(t.Fragment,{children:[t.jsx(Ie,{"data-slot":"icon"}),"Connect"]})})]})]})]})})}const To={bandwidth:.07,threshold:.1,opacity:1,strokeWidth:4.5},Lo={...Ft,trackBg:Ft.border};function Eo({label:e,value:o,min:n,max:r,step:s,unit:a,formatValue:i,onChange:l,isLightMode:c}){const u=i?i(o):o.toFixed(2);return t.jsxs("div",{className:"flex items-center gap-2 sm:gap-2",children:[t.jsx("span",{className:"text-xs font-medium w-14 sm:w-16 shrink-0",style:c?{color:Lo.textSecondary}:{color:"var(--fg-secondary)"},children:e}),t.jsx("input",{type:"range",min:n,max:r,step:s,value:o,onChange:e=>l(parseFloat(e.target.value)),className:"flex-1 h-1.5 rounded-full appearance-none cursor-pointer\n [&::-webkit-slider-thumb]:appearance-none\n [&::-webkit-slider-thumb]:w-3.5\n [&::-webkit-slider-thumb]:h-3.5\n [&::-webkit-slider-thumb]:rounded-full\n [&::-webkit-slider-thumb]:bg-sys-indigo\n [&::-webkit-slider-thumb]:cursor-pointer\n [&::-webkit-slider-thumb]:transition-transform\n [&::-webkit-slider-thumb]:hover:scale-110\n [&::-webkit-slider-thumb]:shadow-md",style:c?{backgroundColor:Lo.trackBg}:{backgroundColor:"var(--elevated)"}}),t.jsxs("span",{className:"text-xs font-mono tabular-nums w-12 sm:w-14 text-right shrink-0",style:c?{color:Lo.textPrimary}:{color:"var(--fg-muted)"},children:[u,a&&t.jsx("span",{className:"ml-0.5 opacity-70",style:c?{color:Lo.textMuted}:void 0,children:a})]})]})}function Bo({icon:e,label:o,value:n,subtext:r,isLightMode:s}){return t.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 py-0.5 sm:py-1",children:[t.jsx("div",{style:s?{color:Lo.textMuted}:{color:"var(--fg-muted)"},children:e}),t.jsx("div",{className:"flex-1 min-w-0",children:t.jsx("div",{className:"text-[10px] sm:text-xs truncate",style:s?{color:Lo.textSecondary}:{color:"var(--fg-secondary)"},children:o})}),t.jsxs("div",{className:"text-right",children:[t.jsx("div",{className:"text-xs font-mono tabular-nums",style:s?{color:Lo.textPrimary}:{color:"var(--fg-primary)"},children:n}),r&&t.jsx("div",{className:"text-[9px] leading-tight opacity-70",style:s?{color:Lo.textMuted}:{color:"var(--fg-muted)"},children:r})]})]})}function Do({visible:o,onClose:n,settings:r,onSettingsChange:s,partition:a,totalNodes:i,basemapMode:l="dark"}){const c=st(),u=e.useRef(null),d="light"===l,m=e.useMemo(()=>{if(!a)return{numCommunities:0,avgCommunitySize:0,minCommunitySize:0,maxCommunitySize:0,fiedlerValue:0,modularity:0,coveragePercent:0};const e=Array.from(a.communities.values()).map(e=>e.length),t=e.reduce((e,t)=>e+t,0);return{numCommunities:a.numCommunities,avgCommunitySize:e.length>0?Math.round(t/e.length):0,minCommunitySize:e.length>0?Math.min(...e):0,maxCommunitySize:e.length>0?Math.max(...e):0,fiedlerValue:a.fiedlerValue,modularity:0,coveragePercent:i>0?Math.round(t/i*100):0}},[a,i]),h=(e,t)=>{s({...r,[e]:t})},g=(111*r.bandwidth).toFixed(1);return t.jsx("div",{ref:u,className:"absolute inset-0 z-[600] pointer-events-none",children:t.jsx(rt,{children:o&&t.jsx(nt.div,{drag:!0,dragControls:c,dragConstraints:u,dragElastic:.1,dragMomentum:!1,initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},transition:M.smooth,className:"\n absolute pointer-events-auto\n /* Mobile: bottom sheet style, full width with margins */\n bottom-2 left-2 right-2\n /* sm+: floating panel in bottom-right */\n sm:bottom-16 sm:left-auto sm:right-3 sm:w-64\n /* md+: slightly wider */\n md:w-72\n ",style:{touchAction:"none"},children:t.jsxs("div",{className:"\n map-control-surface rounded-lg overflow-hidden shadow-lg\n /* Mobile: limit height, allow scroll */\n max-h-[45vh] sm:max-h-[calc(100vh-180px)] overflow-y-auto\n /* iOS momentum scrolling */\n overscroll-contain\n ",children:[t.jsxs("div",{className:"\n flex items-center justify-between \n px-3 py-2 sm:px-2.5 sm:py-1.5 \n border-b \n cursor-grab active:cursor-grabbing\n /* Larger touch target on mobile */\n min-h-[44px] sm:min-h-0\n ",style:d?{borderColor:Lo.border}:void 0,onPointerDown:e=>c.start(e),children:[t.jsxs("div",{className:"flex items-center gap-2 sm:gap-1.5",children:[t.jsx(Ve,{className:"w-4 h-4 sm:w-3 sm:h-3",style:d?{color:Lo.textMuted}:void 0}),t.jsx(we,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5 text-sys-blue"}),t.jsx("span",{className:"text-sm sm:text-xs font-medium",style:d?{color:Lo.textPrimary}:void 0,children:"Partition"})]}),t.jsx(S,{plain:!0,color:"muted",onClick:n,className:"!p-1.5 sm:!p-0.5 !rounded min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center","aria-label":"Close toolbox",children:t.jsx(Ae,{className:"w-4 h-4 sm:w-3 sm:h-3"})})]}),t.jsx("div",{className:"px-3 py-2 sm:px-2.5 sm:py-1.5 border-b",style:d?{borderColor:Lo.border}:void 0,children:t.jsxs("div",{className:"grid grid-cols-2 gap-x-4 sm:gap-x-3 gap-y-1 sm:gap-y-0.5",children:[t.jsx(Bo,{icon:t.jsx(we,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Communities",value:m.numCommunities,isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ze,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Avg Size",value:m.avgCommunitySize,subtext:`${m.minCommunitySize}–${m.maxCommunitySize}`,isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ge,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Fiedler λ₂",value:m.fiedlerValue.toFixed(3),isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ze,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Coverage",value:`${m.coveragePercent}%`,subtext:`of ${i}`,isLightMode:d})]})}),t.jsx("div",{className:"px-3 py-2 sm:px-2.5 sm:py-1.5",children:t.jsxs("div",{className:"space-y-3 sm:space-y-1.5",children:[t.jsx(Eo,{label:"Bandwidth",value:r.bandwidth,min:.01,max:.15,step:.005,formatValue:()=>g,unit:"km",onChange:e=>h("bandwidth",e),isLightMode:d}),t.jsx(Eo,{label:"Threshold",value:r.threshold,min:.05,max:.5,step:.01,formatValue:e=>`${Math.round(100*(1-e))}%`,unit:"cov",onChange:e=>h("threshold",e),isLightMode:d}),t.jsx(Eo,{label:"Opacity",value:r.opacity,min:.1,max:1,step:.05,formatValue:e=>`${Math.round(100*e)}%`,onChange:e=>h("opacity",e),isLightMode:d}),t.jsx(Eo,{label:"Stroke",value:r.strokeWidth,min:0,max:5,step:.5,unit:"px",formatValue:e=>e.toFixed(1),onChange:e=>h("strokeWidth",e),isLightMode:d})]})})]})})})})}const Ho={excellent:"text-signal-excellent",good:"text-signal-good",fair:"text-signal-fair",poor:"text-signal-poor",critical:"text-signal-critical"};function $o(e,t){return Ho[I(e,t)]}const Ao={backgroundColor:"var(--map-ui-hover, var(--elevated))",color:"var(--map-ui-text, var(--fg-primary))",boxShadow:"inset 0 0 0 1px var(--map-ui-border-strong, var(--edge-strong))"},Po={backgroundColor:"var(--map-ui-bg, var(--body))",color:"var(--map-ui-text, var(--fg-primary))",boxShadow:"0 1px 4px rgba(0,0,0,0.15), inset 0 0 0 1px var(--map-ui-border, var(--edge-subtle))"};function zo({prefix:n,name:r}){const s=e.useRef(null),[a,i]=e.useState(!1),[l,c]=e.useState({top:0,left:0});return t.jsxs(t.Fragment,{children:[t.jsx("span",{ref:s,className:"inline-flex items-center px-1.5 py-0.5 rounded font-mono text-[10px] font-semibold transition-opacity hover:opacity-80 cursor-default",style:Ao,onMouseEnter:()=>{if(!r||!s.current)return;const e=s.current.getBoundingClientRect();c({top:e.top-4,left:e.left+e.width/2}),i(!0)},onMouseLeave:()=>i(!1),children:n}),r&&a&&o.createPortal(t.jsx("span",{className:"fixed z-[9999] pointer-events-none -translate-x-1/2 -translate-y-full whitespace-nowrap rounded px-1.5 py-0.5 text-[10px] font-medium",style:{...Po,top:l.top,left:l.left},children:r}),document.body)]})}function Io(e){if(e._tracePathHashes)return e._tracePathHashes;if(e.payload&&e.payload.length>=20){const t=e.payload.slice(18),o=[];for(let e=0;e0?o:null}return null}function qo(e,t){return e.src_hash?[e.src_hash.replace(/^0x/i,"").slice(0,2).toUpperCase(),...t.map(e=>e.toUpperCase())]:t.map(e=>e.toUpperCase())}function Oo(e){switch(e){case"improving":return t.jsx(Xe,{className:"w-3 h-3 text-sys-green"});case"degrading":return t.jsx(Qe,{className:"w-3 h-3 text-sys-red"});case"stable":return t.jsx(Re,{className:"w-3 h-3 text-fg-muted"});default:return null}}const Wo={backgroundColor:"var(--map-ui-stripe)"};function _o({label:e,value:o,unit:n,color:r,tooltip:s}){return t.jsxs("div",{className:"flex items-center justify-between gap-2 py-[3px] "+(s?"cursor-help":""),title:s,children:[t.jsx("span",{className:"type-data-xs text-fg-muted",children:e}),t.jsxs("span",{className:`data-box data-box-compact ${r||""}`,children:[o,n&&t.jsx("span",{className:"text-fg-muted ml-0.5",children:n})]})]})}function Uo({stats:e,direction:o,sf:n,noiseFloor:r}){if(!e)return t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"flex items-center justify-between mb-1.5",children:t.jsx("p",{className:"type-data-xs text-fg-secondary font-medium",children:o})}),t.jsx("p",{className:"type-data-xs text-fg-muted italic px-1.5",children:"No data"})]});const s=e.max-e.min,a=e.median-e.mean,i=q(n),l=e.mean-i,c=I(e.mean,n),u=[`Mean SNR: ${e.mean.toFixed(1)} dB (${c}) from ${e.count} measurement${1!==e.count?"s":""}`,`Variability: ±${e.stdDev.toFixed(1)} dB`,"",`Link budget (SF${n}, 3.5 dBi omni):`,` Demod threshold: ${i.toFixed(1)} dB`,` SNR margin: ${l>=0?"+":""}${l.toFixed(1)} dB`];return null!=r&&u.push(` Noise floor: ${r} dBm`),t.jsxs("div",{className:"min-w-0",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[t.jsx("p",{className:"type-data-xs text-fg-secondary font-medium",children:o}),t.jsxs("span",{className:"type-data-xs text-fg-muted tabular-nums",title:`${e.count} measurement${1!==e.count?"s":""}`,children:["n=",e.count]})]}),t.jsx(_o,{label:"Mean",value:e.mean.toFixed(1),unit:"dB",color:$o(e.mean,n),tooltip:u.join("\n")}),t.jsx(_o,{label:"Median",value:e.median.toFixed(1),unit:"dB",tooltip:"Middle value — less affected by unusual readings than the average."+(Math.abs(a)>=.15?`\nDiffers from mean by ${a>0?"+":""}${a.toFixed(1)} dB`:"")}),t.jsx(_o,{label:"Range",value:`${e.min.toFixed(1)}–${e.max.toFixed(1)}`,unit:"dB",tooltip:`Best to worst signal observed. Total spread: ${s.toFixed(1)} dB.`})]})}function Ko({pair:o,onClose:n,prefixToName:r}){var s,a,i,l,c,u,d,m,h,g,p,f;const x=L(),y=E(),b=B(),v=D(),[j,w]=e.useState(null),N=(null==(a=null==(s=null==b?void 0:b.config)?void 0:s.radio)?void 0:a.spreading_factor)??H,C=e.useMemo(()=>{const e=`${o.nodeA.hash}>${o.nodeB.hash}`,t=`${o.nodeB.hash}>${o.nodeA.hash}`;return{forward:x.get(e)??null,reverse:x.get(t)??null}},[x,o.nodeA.hash,o.nodeB.hash]),k=e.useMemo(()=>y&&0!==y.length?function(e,t,o,n=15){const r=[],s=t.toUpperCase(),a=o.toUpperCase();for(const i of e){if((i.type??i.payload_type)!==z.TRACE)continue;const e=Io(i);if(!e||e.length<1)continue;const t=qo(i,e);if(!(t.length<2)){for(let e=0;e=n)break}}return r}(y,o.nodeA.prefix,o.nodeB.prefix):[],[y,o.nodeA.prefix,o.nodeB.prefix]),M=o.nodeA.name||(null==r?void 0:r.get(o.nodeA.prefix.toUpperCase()))||null,F=o.nodeB.name||(null==r?void 0:r.get(o.nodeB.prefix.toUpperCase()))||null,R=(null==(i=C.forward)?void 0:i.trend)??(null==(l=C.reverse)?void 0:l.trend)??"insufficient",T=Math.max((null==(c=C.forward)?void 0:c.lastSeen)??0,(null==(u=C.reverse)?void 0:u.lastSeen)??0),I=((null==(d=C.forward)?void 0:d.uniqueTraceCount)??0)+((null==(m=C.reverse)?void 0:m.uniqueTraceCount)??0),q="insufficient"===R?"Not enough data to determine trend (need at least 4 measurements).":"Whether signal quality is getting better or worse over time.\nCompares older measurements to newer ones.",O=(null==(h=C.forward)?void 0:h.uniqueTraceCount)??0,W=(null==(g=C.reverse)?void 0:g.uniqueTraceCount)??0,_=["Number of trace packets that traveled through this link.",`${o.nodeA.prefix}→${o.nodeB.prefix}: ${O}`,`${o.nodeB.prefix}→${o.nodeA.prefix}: ${W}`].join("\n");return t.jsx("div",{className:"\n absolute z-[700] overflow-hidden\n /* Mobile: full-width bottom sheet with breathing room */\n bottom-2 left-2 right-2\n /* sm+: right-aligned floating panel */\n sm:bottom-16 sm:left-auto sm:right-4 sm:w-[280px]\n ",children:t.jsxs("div",{className:"\n map-control-surface flex flex-col\n /* Mobile: cap at 45vh so map stays visible */\n max-h-[45vh]\n /* sm+: taller allowance */\n sm:max-h-[420px]\n ",children:[t.jsxs("div",{className:"flex items-center justify-between gap-2 px-3 py-2 sm:py-2 min-h-[44px] sm:min-h-0 border-b border-edge-subtle",children:[t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx(Le,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5 text-sys-green shrink-0"}),t.jsx(zo,{prefix:o.nodeA.prefix,name:M}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"↔"}),t.jsx(zo,{prefix:o.nodeB.prefix,name:F})]}),t.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[T>0&&t.jsx("span",{className:"type-data-xs text-fg-muted",title:A(T),children:$(T)}),t.jsx(S,{plain:!0,color:"muted",onClick:n,className:"!p-1.5 sm:!p-0.5 !rounded-md min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center",children:t.jsx(Ae,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5"})})]})]}),t.jsxs("div",{className:"px-3 py-2.5 border-b border-edge-subtle",children:[t.jsxs("div",{className:"space-y-1.5 mb-2",children:[t.jsxs("div",{className:"flex items-center justify-between cursor-help",title:`${o.nodeA.prefix}→${o.nodeB.prefix}: mean of ${(null==(p=o.aToB)?void 0:p.count)??0} measurements`,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx(zo,{prefix:o.nodeA.prefix,name:M}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"→"}),t.jsx(zo,{prefix:o.nodeB.prefix,name:F})]}),o.aToB?t.jsxs("span",{className:`type-data-sm tabular-nums font-semibold ${$o(o.aToB.mean,N)}`,children:[o.aToB.mean.toFixed(1),t.jsx("span",{className:"text-fg-muted font-normal ml-0.5",children:"dB"})]}):t.jsx("span",{className:"type-data-sm text-fg-muted",children:"—"})]}),t.jsxs("div",{className:"flex items-center justify-between cursor-help",title:`${o.nodeB.prefix}→${o.nodeA.prefix}: mean of ${(null==(f=o.bToA)?void 0:f.count)??0} measurements`,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx(zo,{prefix:o.nodeB.prefix,name:F}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"→"}),t.jsx(zo,{prefix:o.nodeA.prefix,name:M})]}),o.bToA?t.jsxs("span",{className:`type-data-sm tabular-nums font-semibold ${$o(o.bToA.mean,N)}`,children:[o.bToA.mean.toFixed(1),t.jsx("span",{className:"text-fg-muted font-normal ml-0.5",children:"dB"})]}):t.jsx("span",{className:"type-data-sm text-fg-muted",children:"—"})]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-0 -mx-3 border-t border-edge-subtle",children:[t.jsx("div",{className:"px-3 pt-2 pb-1 border-r border-edge-subtle",children:t.jsx(Uo,{stats:o.aToB,direction:`${o.nodeA.prefix}→${o.nodeB.prefix}`,sf:N,noiseFloor:v})}),t.jsx("div",{className:"px-3 pt-2 pb-1",children:t.jsx(Uo,{stats:o.bToA,direction:`${o.nodeB.prefix}→${o.nodeA.prefix}`,sf:N,noiseFloor:v})})]})]}),t.jsxs("div",{className:"px-3 py-1.5 border-b border-edge-subtle",children:["insufficient"!==R&&t.jsxs("div",{className:"flex items-center justify-between gap-2 py-[3px] cursor-help",title:q,children:[t.jsx("span",{className:"type-data-xs text-fg-muted",children:"Trend"}),t.jsx("span",{className:"data-box data-box-compact",children:t.jsxs("span",{className:"flex items-center gap-1",children:[Oo(R),t.jsx("span",{className:"text-fg-secondary capitalize",children:R})]})})]}),I>0&&t.jsx(_o,{label:"Unique traces",value:I.toString(),tooltip:_})]}),k.length>0&&t.jsxs("div",{className:"px-3 py-2 flex-1 min-h-0 flex flex-col",children:[t.jsxs("p",{className:"type-micro text-fg-secondary mb-1 shrink-0",children:["Source packets (",k.length,")"]}),t.jsx("div",{className:"overflow-y-auto flex-1 min-h-0 overscroll-contain",style:{scrollbarGutter:"stable"},children:k.map((e,o)=>{const n=Io(e),s=n?qo(e,n):null,a=s?Math.max(0,s.length-1):0,i=s?s.map(e=>(null==r?void 0:r.get(e))??e).join(" → "):null,l=j===o,c=e.id??`${e.packet_hash}-${e.timestamp}`;return t.jsxs("div",{className:"rounded-sm",style:o%2==1?Wo:void 0,children:[t.jsxs("button",{onClick:()=>w(l?null:o),className:"flex items-center gap-1.5 py-[3px] px-1 w-full text-left text-[10px] font-mono text-fg-secondary hover:text-fg-primary transition-colors group",children:[l?t.jsx(be,{className:"w-2.5 h-2.5 text-fg-muted shrink-0"}):t.jsx(Je,{className:"w-2.5 h-2.5 text-fg-muted shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"}),t.jsx("span",{className:"text-fg-muted w-[52px] shrink-0",children:A(e.timestamp)}),i?t.jsx("span",{className:"text-fg-secondary truncate min-w-0",title:s.join(" → "),children:i}):t.jsx("span",{className:"text-fg-muted truncate min-w-0 italic",children:"path n/a"}),t.jsxs("span",{className:"text-fg-muted shrink-0",children:[a,"h"]}),null!=e.snr&&t.jsx("span",{className:`shrink-0 tabular-nums ${$o(e.snr,N)}`,children:e.snr.toFixed(1)})]}),l&&t.jsxs("div",{className:"mb-1 mt-0.5 mx-1 pl-2 border-l border-edge-subtle space-y-0.5 text-[10px]",children:[null!=e.rssi&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"RSSI"}),t.jsxs("span",{className:"font-mono tabular-nums text-fg-secondary",children:[e.rssi," dBm"]})]}),null!=e.snr&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"SNR"}),t.jsxs("span",{className:`font-mono tabular-nums ${$o(e.snr,N)}`,children:[e.snr.toFixed(1)," dB"]})]}),t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Route"}),t.jsx("span",{className:"font-mono text-fg-secondary",children:P(e.route??e.route_type)})]}),e.packet_hash&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Hash"}),t.jsxs("button",{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.packet_hash)},className:"flex items-center gap-1 font-mono text-fg-secondary hover:text-fg-primary transition-colors",title:"Copy packet hash",children:[t.jsx("span",{className:"truncate max-w-[120px]",children:e.packet_hash}),t.jsx(Ye,{className:"w-2.5 h-2.5 text-fg-muted shrink-0"})]})]}),e.src_hash&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Source"}),t.jsx("span",{className:"font-mono text-fg-secondary truncate max-w-[140px]",title:e.src_hash,children:e.src_hash})]}),s&&s.length>0&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Path"}),t.jsx("span",{className:"font-mono text-fg-secondary truncate max-w-[140px]",title:s.join(" → "),children:s.join(" → ")})]})]})]},c)})})]})]})})}const Vo={getItem:e=>{try{return localStorage.getItem(e)}catch{return null}},setItem:(e,t)=>{try{localStorage.setItem(e,t)}catch{}},removeItem:e=>{try{localStorage.removeItem(e)}catch{}}},Zo=de()(me(e=>({isEnabled:!1,toggle:()=>e(e=>({isEnabled:!e.isEnabled})),setEnabled:t=>e({isEnabled:t})}),{name:"pymc-live-trace",storage:he(()=>Vo)})),Go="wardriving-hexagons",Jo="wardriving-hexagons-fill",Yo=[[15,5,30,255],[35,10,55,255],[55,15,75,255],[75,20,90,255],[95,25,100,255],[115,30,105,255],[135,35,100,255],[155,45,90,255],[175,55,75,255],[195,70,60,255],[210,90,50,255],[225,110,45,255],[235,135,45,255],[245,160,50,255],[250,185,60,255],[252,205,80,255],[254,225,105,255],[255,240,135,255],[255,248,170,255],[255,252,200,255],[255,254,225,255],[255,255,240,255],[255,255,250,255],[255,255,255,255]],Qo=[[60,20,120,255],[80,30,140,255],[100,40,160,255],[120,50,170,255],[140,60,175,255],[160,70,175,255],[180,60,150,255],[200,55,120,255],[215,55,90,255],[230,65,60,255],[240,80,40,255],[250,100,30,255],[255,130,30,255],[255,155,35,255],[255,175,40,255],[255,195,50,255],[255,210,60,255],[255,225,70,255],[255,200,40,255],[255,185,30,255],[255,170,20,255],[245,155,15,255],[235,140,10,255],[225,125,5,255]];function Xo(e){return`rgb(${e[0]}, ${e[1]}, ${e[2]})`}function en(e,t,o,n){const r=o-t;if(r<.001)return Xo(n[12]);const s=(a=Math.max(0,Math.min(1,(e-t)/r)))<.15?a/.15*.1:a>.85?.9+(a-.85)/.15*.1:.1+(a-.15)/.7*.8;var a;return Xo(n[Math.min(23,Math.floor(24*s))])}function tn({coveragePoints:o,visible:r,terrainEnabled:s=!1,brightness:a=.7,basemapMode:i="dark"}){const{current:l}=n(),[c,u]=e.useState(null);e.useEffect(()=>{const e=()=>{var e;const t=null==(e=null==l?void 0:l.getMap)?void 0:e.call(l);t&&!c&&u(t)};e();const t=setInterval(e,50),o=setTimeout(()=>clearInterval(t),5e3);return()=>{clearInterval(t),clearTimeout(o)}},[l,c]);const[d,m]=e.useState(null),[h,g]=e.useState(!1),p=e.useRef({aborted:!1}),f=e.useRef(0),x=e.useRef(i),y=function(t){const[o,n]=e.useState(t);return e.useEffect(()=>{const e=setTimeout(()=>n(t),300);return()=>clearTimeout(e)},[t,300]),o}(o),b=e.useMemo(()=>function(e="dark"){var t;if("light"===e)return Qo;const o=O();return 24===o.length&&0!==(null==(t=o[0])?void 0:t[0])?o:Yo}(i),[i]);e.useEffect(()=>{if(!y||!Array.isArray(y)||0===y.length)return void queueMicrotask(()=>{m(null),f.current=0});const e=x.current!==i;if(y.length===f.current&&d&&!e)return;f.current=y.length,x.current=i,p.current.aborted=!0,p.current={aborted:!1};const t=p.current;g(!0);const{cells:o,minQuality:n,maxQuality:r}=function(e){const t=new Map;for(const s of e){if("number"!=typeof s.lat||"number"!=typeof s.lon||isNaN(s.lat)||isNaN(s.lon))continue;const e=mt(s.lat,s.lon,8),o=t.get(e),n=s.weight;o?(o.count++,o.qualitySum+=n):t.set(e,{count:1,qualitySum:n})}const o=[];let n=1/0,r=-1/0;for(const[s,a]of t.entries()){const e=a.qualitySum/a.count;o.push({hexId:s,count:a.count,avgQuality:e}),n=Math.min(n,e),r=Math.max(r,e)}return{cells:o,minQuality:o.length>0?n:0,maxQuality:o.length>0?r:0}}(y);if(0===o.length)return m(null),void g(!1);if(o.length<500){const e=function(e,t,o,n){const r=[];for(const s of e){const e=ht(s.hexId).map(([e,t])=>[t,e]);e.push(e[0]);const a=en(s.avgQuality,t,o,n);r.push({type:"Feature",properties:{color:a,quality:s.avgQuality,count:s.count},geometry:{type:"Polygon",coordinates:[e]}})}return{type:"FeatureCollection",features:r}}(o,n,r,b);return void(t.aborted||(m(e),g(!1)))}return async function(e,t,o,n,r){const s=[];let a=0;for(;a[t,e]);i.push(i[0]);const l=en(r.avgQuality,t,o,n);s.push({type:"Feature",properties:{color:l,quality:r.avgQuality,count:r.count},geometry:{type:"Polygon",coordinates:[i]}})}arequestAnimationFrame(e))}return{type:"FeatureCollection",features:s}}(o,n,r,b,t).then(e=>{!t.aborted&&e&&m(e)}).finally(()=>{t.aborted||g(!1)}),()=>{t.aborted=!0}},[y,b]),e.useEffect(()=>{if(!c)return;const e=()=>{var e,t;try{const o=c.getLayer(Jo),n=c.getSource(Go);if(r&&d&&d.features.length>0){if(n?c.getSource(Go).setData(d):c.addSource(Go,{type:"geojson",data:d}),!o){const o=c.getLayer("topology-weak-edges-native"),n=null==(t=null==(e=c.getStyle())?void 0:e.layers)?void 0:t.find(e=>"symbol"===e.type),r=o?"topology-weak-edges-native":null==n?void 0:n.id;c.addLayer({id:Jo,type:"fill",source:Go,paint:{"fill-color":["get","color"],"fill-opacity":a}},r)}}else o&&c.removeLayer(Jo),n&&c.removeSource(Go)}catch(o){console.warn("[WardrivingHexLayerMapLibre] Layer update error:",o)}};c.isStyleLoaded()?e():c.once("style.load",e)},[c,r,d,s]),e.useEffect(()=>{if(c&&r)try{c.getLayer(Jo)&&c.setPaintProperty(Jo,"fill-opacity",a)}catch{}},[c,a,r]),e.useEffect(()=>()=>{if(c)try{c.getLayer(Jo)&&c.removeLayer(Jo),c.getSource(Go)&&c.removeSource(Go)}catch{}},[c]);const v=(null==d?void 0:d.features.length)??0;return v>0&&r?t.jsx("div",{"data-testid":"wardriving-hexlayer-maplibre-active","data-point-count":(null==o?void 0:o.length)||0,"data-cell-count":v,"data-terrain-enabled":s,"data-is-processing":h,style:{display:"none"}}):null}const on="https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",nn="terrarium",rn="terrain-dem",sn="hillshade-dem",an="terrain-hillshade";function ln({enabled:t,exaggeration:o=4}){const{current:r}=n(),[s,a]=e.useState(null),i=e.useRef(null);return e.useEffect(()=>{const e=()=>{var e;const t=null==(e=null==r?void 0:r.getMap)?void 0:e.call(r);t&&!s&&a(t)};e();const t=setInterval(e,50),o=setTimeout(()=>clearInterval(t),5e3);return()=>{clearInterval(t),clearTimeout(o)}},[r,s]),e.useEffect(()=>{if(!s)return;let e=!0;const t=()=>{var t,o;if(e)try{if(s.getSource(sn)||s.addSource(sn,{type:"raster-dem",tiles:[on],encoding:nn,tileSize:256,maxzoom:14}),!s.getLayer(an)){const e=null==(o=null==(t=s.getStyle())?void 0:t.layers)?void 0:o.find(e=>"symbol"===e.type);s.addLayer({id:an,type:"hillshade",source:sn,paint:{"hillshade-shadow-color":"rgba(10, 10, 10, 0.6)","hillshade-highlight-color":"rgba(245, 240, 230, 0.4)","hillshade-accent-color":"rgba(90, 75, 65, 0.3)","hillshade-illumination-direction":315,"hillshade-exaggeration":.35}},null==e?void 0:e.id)}s.getSource(rn)||s.addSource(rn,{type:"raster-dem",tiles:[on],encoding:nn,tileSize:256,maxzoom:14})}catch(n){console.error("[TerrainLayer] Source/layer setup error:",n)}};return s.isStyleLoaded()?t():(s.once("style.load",t),s.once("load",()=>{e&&!s.getSource(sn)&&t()})),()=>{e=!1}},[s]),e.useEffect(()=>{if(!s)return;let e=!0,n=!1;const r=()=>{if(e&&s.getSource(rn))try{t?(s.setCenterClampedToGround(!1),s.setTerrain({source:rn,exaggeration:o}),s.setMaxPitch(70),!n&&s.getPitch()<30&&!s.isMoving()&&(n=!0,null!==i.current&&clearTimeout(i.current),i.current=window.setTimeout(()=>{i.current=null,e&&!s.isMoving()&&s.getPitch()<30&&s.easeTo({pitch:45,duration:1e3})},200))):(s.setTerrain(null),s.setCenterClampedToGround(!0),s.getPitch()>0&&!s.isMoving()&&s.easeTo({pitch:0,duration:800}),s.setMaxPitch(60))}catch(r){console.error("[TerrainLayer] Terrain state error:",r)}};if(s.isStyleLoaded()&&s.getSource(rn))r();else{const e=()=>{s.getSource(rn)&&r()};s.once("idle",e)}return()=>{e=!1,null!==i.current&&(clearTimeout(i.current),i.current=null)}},[s,t,o]),e.useEffect(()=>()=>{var e;try{(null==(e=null==s?void 0:s.getStyle)?void 0:e.call(s))&&s.isStyleLoaded()&&(s.setTerrain(null),s.getLayer(an)&&s.removeLayer(an),s.getSource(sn)&&s.removeSource(sn),s.getSource(rn)&&s.removeSource(rn))}catch{}},[s]),null}const cn=.03,un=.1,dn=2;function mn(e,t=3){if(e.length<3||t<=0)return e;let o=e;for(let n=0;n0&&e.push([e[0][0],e[0][1]]),o=e}return o}function hn(e,t={}){const o=function(e,t={}){if(e.length<3)return{coordinates:[],valid:!1};const{bandwidth:o=cn,threshold:n=un,cellSize:r=dn}=t,s=function(e,t){let o=1/0,n=-1/0,r=1/0,s=-1/0;for(const[a,i]of e)an&&(n=a),is&&(s=i);return o-=t,n+=t,r-=t,s+=t,{minX:o,minY:r,maxX:n,maxY:s,width:n-o,height:s-r}}(e,.02),a=Math.ceil(s.width/(o/2)),i=Math.ceil(s.height/(o/2)),l=Math.min(1,200/Math.max(a,i)),c=Math.max(10,Math.ceil(a*l)),u=Math.max(10,Math.ceil(i*l)),d=e=>e/c*s.width+s.minX,m=e=>e/u*s.height+s.minY,h=o/s.width*c;try{const t=gt().x(e=>(e[0]-s.minX)/s.width*c).y(e=>(e[1]-s.minY)/s.height*u).size([c,u]).bandwidth(Math.max(5,h)).cellSize(r)(e);if(0===t.length)return{coordinates:[],valid:!1};const o=Math.max(...t.map(e=>e.value))*n;let a=t[0],i=1/0;for(const e of t){const t=Math.abs(e.value-o);t0){const t=e[0],o=e[e.length-1];t[0]===o[0]&&t[1]===o[1]||e.push([t[0],t[1]])}if(e.length>=4){const o=mn(e);t.push(o)}}t.length>0&&l.push(t)}const g=[];for(const e of l)for(const t of e)g.push(t);return{coordinates:l,valid:l.length>0}}catch(g){return console.warn("[KDE Contour] Failed to generate contour:",g),{coordinates:[],valid:!1}}}(e,t);return o.valid&&0!==o.coordinates.length?1===o.coordinates.length?{type:"Polygon",coordinates:o.coordinates[0]}:{type:"MultiPolygon",coordinates:o.coordinates}:null}function gn(e,t,o){return(t[0]-e[0])*(o[1]-e[1])-(t[1]-e[1])*(o[0]-e[0])}function pn(e,t,o,n,r){const s=r*r,a=s*r;return[.5*(2*t[0]+(-e[0]+o[0])*r+(2*e[0]-5*t[0]+4*o[0]-n[0])*s+(-e[0]+3*t[0]-3*o[0]+n[0])*a),.5*(2*t[1]+(-e[1]+o[1])*r+(2*e[1]-5*t[1]+4*o[1]-n[1])*s+(-e[1]+3*t[1]-3*o[1]+n[1])*a)]}function fn(e){let t=function(e){if(e.length<3)return e;const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]),o=[];for(const r of t){for(;o.length>=2&&gn(o[o.length-2],o[o.length-1],r)<=0;)o.pop();o.push(r)}const n=[];for(let r=t.length-1;r>=0;r--){const e=t[r];for(;n.length>=2&&gn(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}return o.pop(),n.pop(),o.concat(n)}(e);if(t.length<3)return null;t=function(e){if(e.length<3)return e;let t=0,o=0;for(const[n,r]of e)t+=n,o+=r;return t/=e.length,o/=e.length,e.map(([e,n])=>{const r=e-t,s=n-o,a=Math.sqrt(r*r+s*s);if(a<1e-4)return[e,n];const i=(a+.008)/a;return[t+r*i,o+s*i]})}(t);const o=function(e){if(e.length<3)return e;const t=[],o=e.length;for(let n=0;no?function(e,t,o,n){const r=[];for(const[s,a]of e.communities){const e=[];for(const o of a){const n=t.get(o);n&&e.push([n[1],n[0]])}if(e.length<3)continue;let i=hn(e,{bandwidth:o,threshold:n});i||(i=fn(e)),i&&r.push({type:"Feature",properties:{community:s,color:ie(s),borderColor:ae(s),nodeCount:a.length},geometry:i})}return{type:"FeatureCollection",features:r}}(o,n,l,c):{type:"FeatureCollection",features:[]},[o,n,l,c]),m=a?i:0,h={"fill-color":["get","color"],"fill-opacity":m},g={"line-color":["get","borderColor"],"line-width":u,"line-opacity":m};return t.jsxs(r,{id:"mincut-partition",type:"geojson",data:d,children:[t.jsx(s,{id:"mincut-partition-fill",type:"fill",paint:h}),t.jsx(s,{id:"mincut-partition-stroke",type:"line",paint:g})]})}function yn(e,t=!1,o=!1,n=!1,r=.7,s){const a=j(s);return n?r>=.75?a.restBright:a.rest:r>=.85?a.rest:a.restDim}function bn(e){return[e[1],e[0]]}function vn(e,t,o,n=12){const[r,s]=e,[a,i]=t,l=[];for(let c=0;c<=n;c++){const e=c/n,t=s+(i-s)*e,u=r+(a-r)*e,d=4*o*e*(1-e);l.push([t,u,d])}return l}function jn(e,t,o,n,r,s,a,i,l,c,u,d="dark"){const m=Tt(),h=[];let g=1/0,p=-1/0;const f=[];for(const y of e){const e=.7*(y.edge.avgConfidence??(t?.7:.5))+y.edge.certainCount/Math.max(a,1)*.3+(t?.5:0);f.push({polyline:y,brightnessScore:e}),g=Math.min(g,e),p=Math.max(p,e)}if(0===f.length)return{type:"FeatureCollection",features:[]};const x=p-g||1;f.sort((e,t)=>e.brightnessScore-t.brightnessScore);for(const{polyline:y,brightnessScore:b}of f){const{from:e,to:a,edge:p}=y,f=o.get(p.key)??0;if(f<=0)continue;const v=i.has(p.key),j=l.has(p.key),w=p.avgConfidence??(t?.7:.5),N=c===p.key,C=u[p.fromHash],k=u[p.toHash],M=(null==C?void 0:C.node_name)||(null==C?void 0:C.name)||p.fromHash.slice(0,8),S=(null==k?void 0:k.node_name)||(null==k?void 0:k.name)||p.toHash.slice(0,8),F=[e[0]+(a[0]-e[0])*f,e[1]+(a[1]-e[1])*f];let R,T,L,E;if(t){const e=s.get(p.key)??Mt(p.certainCount),t=r.get(p.key)??e;R=t+(e-t)*n,N?R=Math.max(1.6*R,4.5):j&&(R*=1.3)}else R=1.5;if(T=N?m.edges.highlight:yn(0,p.isDirectPathEdge??!1,v,j,w,d),L=N?m.edges.highlight:p.isDirectPathEdge?m.edges.hoverDirect:v?m.edges.hoverLoop:m.edges.hoverStandard,t){const e=Math.min(1.5*f,1)*m.edgeOpacity;E=j?1.15*e:e}else E=(.3+.3*w)*f;N&&(E=.95);const B=(b-g)/x;h.push({type:"Feature",properties:{key:p.key,baseColor:T,hoverColor:L,baseWidth:R,baseOpacity:E,brightnessScore:B,isLoopEdge:v,isBackbone:j,isDirectPath:p.isDirectPathEdge??!1,isHubConnection:p.isHubConnection??!1,isZeroHop:p.isZeroHop??!1,isValidated:t,certainCount:p.certainCount,confidence:w,symmetryRatio:p.symmetryRatio??1,dominantDirection:p.dominantDirection??"balanced",fromName:M,toName:S,fromHash:p.fromHash,toHash:p.toHash},geometry:{type:"LineString",coordinates:[bn(e),bn(F)]}})}return{type:"FeatureCollection",features:h}}function wn(e,t){const o=Tt(),n=[];let r=0;for(const s of e){const e=t.get(s.hash);e&&e.blendedScore>r&&(r=e.blendedScore)}for(const s of e){const{from:e,to:a,hash:i,neighbor:l,lastHopData:c}=s,u=`neighbor-${i}`,d=(null==c?void 0:c.avgRssi)??l.rssi??null,m=(null==c?void 0:c.avgSnr)??l.snr??null,h=(null==c?void 0:c.count)??0,g=(null==c?void 0:c.confidence)??1,p=t.get(i),f=(null==p?void 0:p.listenerScore)??0,x=(null==p?void 0:p.loudScore)??0,y=(null==p?void 0:p.blendedScore)??0,b=r>0?y/r:0,v=s.rxAdvertCount??0,j=s.txProxyCount??0,w=v+j,N=w>0?(j-v)/w:0,C=vn(e,a,150,8);n.push({type:"Feature",properties:{key:u,hash:i,name:l.node_name||l.name||i.slice(0,8),prefix:i.slice(2,4).toUpperCase(),color:o.neighborColor,width:2.5,opacity:.85,rssi:d,snr:m,packetCount:h,confidence:g,hasAvgRssi:void 0!==(null==c?void 0:c.avgRssi),hasAvgSnr:void 0!==(null==c?void 0:c.avgSnr),isNeighborEdge:!0,listenerScore:f,loudScore:x,blendedScore:y,trafficWeight:b,linkAsymmetry:N,rxAdvertCount:v,txProxyCount:j},geometry:{type:"LineString",coordinates:C}})}return{type:"FeatureCollection",features:n}}function Nn(e,t){if(e<240)return.5;if(e<480)return 1;const o=(e-480)/(t-480);return Math.max(0,.33*(1-o))}function Cn(e,t,o){const n=o?_(o):null,r=[];for(const s of e){if(n&&s.toUpperCase()===n){o&&r.push(o);continue}const e=t.get(s.toUpperCase());e&&r.push(e)}return r}const kn="edge-blink-source",Mn="edge-blink-layer",Sn=1e3,Fn=1e3,Rn=y.teal,Tn="node-markers-layer";function Ln(e){return e<0||e>=Sn?0:1-e/Sn}function En(e){if(e<0)return 0;if(e>=Fn)return 0;const t=e/Fn;return Math.pow(1-t,3)}function Bn(e){return[e[1],e[0]]}const Dn=[{target:"Sparklines",fn:"sparklines",minStage:2}];u(Dn);const Hn=e.memo(function({nodeHash:e,width:o=60,height:n=20,color:r,showArea:s=!0,showTooltip:a=!1,className:i=""}){c(Dn);const l=K(e),u=V(),d=!Z().backgroundLoadComplete||u,m="number"==typeof o?o:60;return t.jsx(Nt,{data:l,width:m,height:n,color:r,isLoading:d,className:i})});function $n(e){const t=new Date(1e3*e);return`${(t.getMonth()+1).toString().padStart(2,"0")}/${t.getDate().toString().padStart(2,"0")}`}function An({txDelayRec:o,onRemove:n}){const[r,s]=e.useState(!1),a=o.floodFactor??o.txDelayFactor,i=o.directFactor??o.directTxDelayFactor;return t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsxs("button",{onClick:async()=>{const e=`set txdelay ${a.toFixed(1)}\nset direct.txdelay ${i.toFixed(1)}`;try{await navigator.clipboard.writeText(e),s(!0),setTimeout(()=>s(!1),1500)}catch(t){const o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select();try{document.execCommand("copy"),s(!0),setTimeout(()=>s(!1),1500)}catch{console.error("Failed to copy")}document.body.removeChild(o)}},className:"flex items-center gap-2 flex-1 py-1 px-1.5 bg-sys-amber/5 hover:bg-sys-amber/10 rounded transition-colors group",title:"Click to copy CLI commands",children:[t.jsx(ot,{className:"w-3 h-3 text-sys-amber shrink-0"}),t.jsx("span",{className:"text-fg-muted",children:"TxDelay"}),t.jsxs("div",{className:"flex gap-2",children:[t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"text-fg-muted",children:"F"}),t.jsxs("span",{className:"data-box data-box-compact text-sys-amber",children:["×",a.toFixed(1)]})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"text-fg-muted",children:"D"}),t.jsxs("span",{className:"data-box data-box-compact text-sys-amber",children:["×",i.toFixed(1)]})]})]}),r?t.jsx(Ue,{className:"w-3 h-3 text-sys-green ml-auto"}):t.jsx(Ye,{className:"w-3 h-3 text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity ml-auto"})]}),n&&t.jsx("button",{onClick:n,className:"p-1 text-fg-secondary hover:text-sys-red hover:bg-sys-red/10 rounded transition-colors",title:"Remove from contacts",children:t.jsx(ze,{className:"w-3.5 h-3.5"})})]})}function Pn({hash:o,hashPrefix:n,name:r,isHub:s,isGateway:a,isBackbone:i,isZeroHop:l,isMobile:c,isRoomServer:u,isStale:d,lastSeenTimestamp:m,centrality:h,affinity:g,meanSnr:p,meanRssi:f,neighbor:x,onRemove:y,txDelayRec:b}){const[v,j]=e.useState(!1),w=l?"Direct":(null==g?void 0:g.typicalHopPosition)?`${g.typicalHopPosition}-hop`:null,N=b&&!b.insufficientData;return t.jsxs("div",{className:"w-[240px] pr-2",children:[t.jsx("div",{className:"text-[14px] font-semibold text-fg-primary leading-tight truncate mb-1",children:r}),t.jsxs("div",{className:"flex items-center gap-1 flex-wrap mb-1.5",children:[t.jsx("code",{className:"type-data-xs text-fg-secondary bg-data-box-bg border border-data-box-border px-1 py-0.5 rounded",children:n}),t.jsx("button",{onClick:async()=>{try{await navigator.clipboard.writeText(o),j(!0),setTimeout(()=>j(!1),1500)}catch(e){console.error("Failed to copy hash:",e);const t=document.createElement("textarea");t.value=o,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();try{document.execCommand("copy"),j(!0),setTimeout(()=>j(!1),1500)}catch{console.error("Fallback copy also failed")}document.body.removeChild(t)}},className:"p-0.5 hover:bg-subtle-fill-hover rounded transition-colors",title:"Copy full hash",children:v?t.jsx(Ue,{className:"w-3 h-3 text-sys-green"}):t.jsx(Ye,{className:"w-3 h-3 text-fg-secondary"})}),t.jsx(Ct,{hash:o,size:"sm"}),w&&t.jsx(G,{color:l?bt.direct:bt.multihop,compact:!0,children:w}),x.is_repeater&&t.jsx(G,{color:vt.repeater,compact:!0,children:"Rptr"}),s&&t.jsx(G,{color:vt.hub,compact:!0,title:"Hub: ≥10% of last-hop traffic",children:"Hub"}),a&&!s&&t.jsx(G,{color:vt.gateway,compact:!0,title:"Gateway: 7-10% of last-hop traffic",children:"Gate"}),i&&t.jsx(G,{color:vt.backbone,compact:!0,title:"Backbone",children:"Bone"}),c&&t.jsx(G,{color:vt.mobile,compact:!0,children:"Mobile"}),u&&t.jsx(G,{color:vt.room,compact:!0,children:"Room"}),d&&m&&t.jsxs(G,{compact:!0,title:"Neighbor not heard in 7+ days",children:["Idle ",$n(m)]})]}),t.jsxs("div",{className:"flex items-center gap-2 text-xs text-fg-secondary mb-1.5",children:[t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(Ke,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsx("span",{className:"font-mono",children:$(x.last_seen)})]}),(null==g?void 0:g.distanceMeters)&&t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(et,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsx("span",{className:"font-mono font-semibold text-fg-primary",children:(C=g.distanceMeters,null===C?"—":C<1e3?`${Math.round(C)}m`:`${(C/1e3).toFixed(1)}km`)})]}),x.latitude&&x.longitude&&0!==x.latitude&&0!==x.longitude&&t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(tt,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsxs("span",{className:"font-mono text-fg-muted",children:[x.latitude.toFixed(2),", ",x.longitude.toFixed(2)]})]})]}),t.jsx("div",{className:"mb-1.5",style:{width:224},children:t.jsx(Hn,{nodeHash:o,width:224,height:26,showArea:!0,showTooltip:!0})}),t.jsxs("div",{className:"flex gap-3 text-xs mb-1.5",children:[t.jsxs("div",{className:"flex-1 space-y-1",children:[t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Packets"}),t.jsx("span",{className:"data-box data-box-compact",children:(null==g?void 0:g.frequency)||0})]}),l&&void 0!==p&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"SNR"}),t.jsxs("span",{className:"data-box data-box-compact",children:[p.toFixed(1)," dB"]})]}),N&&b.networkRole&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Role"}),t.jsx(G,{color:jt[b.networkRole],compact:!0,title:{hub:"Hub: High-connectivity node that bridges many paths",backbone:"Backbone: Critical relay with high traffic",relay:"Relay: Standard forwarding node",edge:"Edge: Peripheral node"}[b.networkRole],children:b.networkRole})]})]}),t.jsxs("div",{className:"flex-1 space-y-1",children:[t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Adverts"}),t.jsx("span",{className:"data-box data-box-compact",children:x.advert_count||0})]}),l&&void 0!==f&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"RSSI"}),t.jsxs("span",{className:"data-box data-box-compact",children:[Math.round(f)," dBm"]})]}),N&&b.dataConfidence&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Data"}),t.jsx(G,{color:wt[b.dataConfidence],compact:!0,title:{high:"1000+ packets",medium:"500-999 packets",low:"100-499 packets",insufficient:"Insufficient data"}[b.dataConfidence],children:b.dataConfidence})]})]}),!N&&y&&t.jsx("button",{onClick:y,className:"p-1 self-start text-fg-secondary hover:text-sys-red hover:bg-sys-red/10 rounded transition-colors",title:"Remove from contacts",children:t.jsx(ze,{className:"w-3.5 h-3.5"})})]}),N&&t.jsx(An,{txDelayRec:b,onRemove:y})]});var C}const zn="node-markers-native",In="node-markers-layer",qn="node-markers-layer-local",On="marker-standard",Wn="marker-standard-neighbor",_n="marker-hub",Un="marker-hub-neighbor",Kn="marker-gateway",Vn="marker-gateway-neighbor",Zn="marker-mobile",Gn="marker-mobile-neighbor",Jn="marker-room-server",Yn="marker-room-server-neighbor",Qn="marker-local",Xn="marker-stale-5day",er="marker-stale-10day",tr="marker-blink-black",or="marker-blink-black-local",nr="marker-blink",rr="marker-blink-local",sr={tier1:b[500],tier2:b[700]};function ar(e){if(!e)return 0;const t=(Date.now()-1e3*e)/864e5;return t>=10?2:t>=5?1:0}function ir(e){var t;const o=null==(t=e.contact_type)?void 0:t.toLowerCase();return"room server"===o||"room_server"===o||"room"===o||"server"===o}function lr(e){return e.startsWith("0x")?e.slice(2,4).toUpperCase():e.slice(0,2).toUpperCase()}function cr({neighborsWithLocation:o,localNode:i,localHash:l,zeroHopNeighbors:c,lastHopNeighborMap:u,meshTopology:d,hoveredMarker:m,onMarkerHover:h,getNodeOpacity:g,shouldShowNode:p,onRequestRemove:f,openPopupId:x,onOpenPopup:y,onClosePopup:b,onNodeClick:j,blinkingNodes:w}){const{current:N}=n(),C=e.useRef(!1),[k,M]=e.useState(!1);e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t)return;const o=()=>{try{!function(e){const t=v(),o=(e,t,o=0,n=!1)=>{const r=document.createElement("canvas");r.width=32,r.height=32;const s=r.getContext("2d",n?{colorSpace:"display-p3"}:void 0),a=14-o/2;return s.beginPath(),s.arc(16,16,a,0,2*Math.PI),s.fillStyle=e,s.fill(),t&&o>0&&(s.strokeStyle=t,s.lineWidth=2*o,s.stroke()),s.shadowColor="rgba(0,0,0,0.3)",s.shadowBlur=4,s.shadowOffsetY=2,{data:s.getImageData(0,0,32,32),pixelRatio:2}},n=(e,t=!1)=>{const o=document.createElement("canvas");o.width=48,o.height=48;const n=o.getContext("2d",t?{colorSpace:"display-p3"}:void 0),r=24*.35*2;return n.strokeStyle=e,n.lineWidth=5,n.lineCap="round",n.lineJoin="round",n.beginPath(),n.moveTo(24-r,24),n.lineTo(24,24-r),n.lineTo(40.8,24),n.stroke(),n.beginPath(),n.moveTo(24-.7*r,24),n.lineTo(24-.7*r,35.76),n.lineTo(35.76,35.76),n.lineTo(35.76,24),n.stroke(),n.beginPath(),n.moveTo(20.64,35.76),n.lineTo(20.64,27.36),n.lineTo(27.36,27.36),n.lineTo(27.36,35.76),n.stroke(),{data:n.getImageData(0,0,48,48),pixelRatio:2}},r=(e,t)=>{const o=document.createElement("canvas");o.width=48,o.height=48;const n=o.getContext("2d"),r=24*.35*2;return n.strokeStyle=e,n.lineWidth=5,n.lineCap="round",n.lineJoin="round",t&&(n.fillStyle=t),n.beginPath(),n.roundRect(24-r,24-.6*r,1.6*r,1.2*r,6),t&&n.fill(),n.stroke(),n.beginPath(),n.moveTo(18.96,34.08),n.lineTo(24-.6*r,40.8),n.lineTo(24,34.08),n.stroke(),{data:n.getImageData(0,0,48,48),pixelRatio:2}},s="#00FF00",a={[On]:o(t.nodeFill),[Wn]:o(t.neighborColor),[_n]:o(t.hubColor),[Un]:o(t.neighborColor),[Kn]:o(t.gatewayColor),[Vn]:o(t.neighborColor),[Zn]:o("transparent",t.mobileColor,2.5),[Gn]:o(t.neighborColor),[Jn]:r(t.roomColor),[Yn]:r(t.neighborColor,"#1a1a1c"),[Qn]:n(t.localColor),[Xn]:o(sr.tier1),[er]:o(sr.tier2),[tr]:o("#000000"),[or]:n("#000000"),[nr]:o(s,void 0,0,!0),[rr]:n(s,!0)};for(const[i,l]of Object.entries(a))try{e.hasImage(i)&&e.removeImage(i),e.addImage(i,l.data,{pixelRatio:l.pixelRatio})}catch{}}(t),C.current=!0,k||M(!0)}catch(e){console.warn("Failed to load node marker icons:",e)}};t.isStyleLoaded()?o():t.once("style.load",o);const n=()=>{t.hasImage(On)||o()};t.on("styledata",n);const r=()=>{C.current=!1,o()},s=new MutationObserver(e=>{for(const t of e)if("data-theme"===t.attributeName){setTimeout(r,100);break}});s.observe(document.documentElement,{attributes:!0});const a=document.querySelector("[data-basemap]");let i=null;return a&&(i=new MutationObserver(e=>{for(const t of e)if("data-basemap"===t.attributeName){setTimeout(r,100);break}}),i.observe(a,{attributes:!0})),()=>{t.off("styledata",n),s.disconnect(),null==i||i.disconnect()}},[N,k]);const S=e.useMemo(()=>{var e;const t=[],n=[...o].sort(([e,t],[o,n])=>{const r=(e,t)=>{var o;return ir(t)?5e3:c.has(e)?3e3:d.hubNodes.includes(e)?2e3:(null==(o=d.gatewayNodes)?void 0:o.includes(e))?1e3:0};return r(e,t)-r(o,n)});for(const[o,r]of n){if(!r.latitude||!r.longitude)continue;if(l&&((l.startsWith("0x")?l.slice(2,4).toLowerCase():l.slice(0,2).toLowerCase())===(o.startsWith("0x")?o.slice(2,4).toLowerCase():o.slice(0,2).toLowerCase())||o===l))continue;const n=p(o),s=g(o,n);if(s<=.01)continue;const a=c.has(o),i=d.hubNodes.includes(o),m=(null==(e=d.gatewayNodes)?void 0:e.includes(o))??!1,h=d.mobileNodes.includes(o),f=ir(r),x=d.centrality.get(o)||0,y=u.get(o),b=r.last_seen||(null==y?void 0:y.lastSeen),v=ar(b),j=v>0;let w=s;2===v?w=Math.min(s,.25):1===v&&(w=Math.min(s,.5));let N="standard";f?N="roomServer":i?N="hub":m?N="gateway":h&&(N="mobile");const C=d.fullAffinity.get(o),k=d.txDelayRecommendations.get(o);t.push({type:"Feature",geometry:{type:"Point",coordinates:[r.longitude,r.latitude]},properties:{hash:o,name:r.node_name||r.name||"Unknown",hashPrefix:lr(o),iconType:N,isNeighbor:a,isHub:i,isGateway:m,isMobile:h,isRoomServer:f,isStale:j,staleTier:v,isZeroHop:a,opacity:w,blinkIntensity:0,lastSeenTimestamp:b,centrality:x,neighborJson:JSON.stringify(r),affinityJson:C?JSON.stringify(C):void 0,txDelayRecJson:k?JSON.stringify(k):void 0,meanSnr:(null==y?void 0:y.avgSnr)??void 0,meanRssi:(null==y?void 0:y.avgRssi)??void 0}})}return{type:"FeatureCollection",features:t}},[o,l,c,u,d,g,p]),F=e.useMemo(()=>(null==i?void 0:i.latitude)&&(null==i?void 0:i.longitude)?{type:"FeatureCollection",features:[{type:"Feature",geometry:{type:"Point",coordinates:[i.longitude,i.latitude]},properties:{hash:"local",name:i.name,hashPrefix:l?lr(l):"",iconType:"local",isNeighbor:!1,isHub:!1,isGateway:!1,isMobile:!1,isRoomServer:!1,isStale:!1,staleTier:0,isZeroHop:!1,opacity:1,blinkIntensity:0,centrality:0}}]}:{type:"FeatureCollection",features:[]},[i,l]),R=e.useCallback(e=>{var t;if(!e.features||0===e.features.length)return;const o=null==(t=e.features[0].properties)?void 0:t.hash;o&&(y&&y(o),j&&"local"!==o&&j(o))},[y,j]),T=e.useCallback(e=>{var t,o;if(!e.features||0===e.features.length)return;const n=null==(t=null==N?void 0:N.getMap)?void 0:t.call(N);n&&(n.getCanvas().style.cursor="pointer");const r=null==(o=e.features[0].properties)?void 0:o.hash;r&&h(r)},[N,h]),L=e.useCallback(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);t&&(t.getCanvas().style.cursor=""),h(null)},[N,h]);e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t||!k)return;const o=[In,qn];for(const n of o)t.on("click",n,R),t.on("mouseenter",n,T),t.on("mouseleave",n,L);return()=>{for(const e of o)t.off("click",e,R),t.off("mouseenter",e,T),t.off("mouseleave",e,L)}},[N,k,R,T,L]);const E=e.useRef(S),B=e.useRef(F);e.useEffect(()=>{E.current=S,B.current=F},[S,F]),e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t||!k||!w||0===w.size)return;const o=t.getSource(zn),n=t.getSource(`${zn}-local`);if(o||n){if(o){const e=E.current;let t=!1;const n=e.features.map(e=>{const o=w.get(e.properties.hash)??0;return o!==e.properties.blinkIntensity?(t=!0,{...e,properties:{...e.properties,blinkIntensity:o}}):e});t&&o.setData({type:"FeatureCollection",features:n})}if(n&&l){const e=w.get(l)??0,t=B.current;t.features.length>0&&t.features[0].properties.blinkIntensity!==e&&n.setData({type:"FeatureCollection",features:[{...t.features[0],properties:{...t.features[0].properties,blinkIntensity:e}}]})}}},[N,k,w,l]);const D=e.useMemo(()=>{if(!x)return null;if("local"===x&&i)return{longitude:i.longitude,latitude:i.latitude,isLocal:!0,name:i.name,hash:l};const e=S.features.find(e=>e.properties.hash===x);if(!e)return null;const t=e.properties,o=t.txDelayRecJson?JSON.parse(t.txDelayRecJson):void 0;return{longitude:e.geometry.coordinates[0],latitude:e.geometry.coordinates[1],isLocal:!1,hash:t.hash,hashPrefix:t.hashPrefix,name:t.name,isHub:t.isHub,isGateway:t.isGateway,isBackbone:"backbone"===(null==o?void 0:o.networkRole),isZeroHop:t.isZeroHop,isMobile:t.isMobile,isRoomServer:t.isRoomServer,isStale:t.isStale,lastSeenTimestamp:t.lastSeenTimestamp,centrality:t.centrality,neighbor:t.neighborJson?JSON.parse(t.neighborJson):void 0,affinity:t.affinityJson?JSON.parse(t.affinityJson):void 0,txDelayRec:o,meanSnr:t.meanSnr,meanRssi:t.meanRssi}},[x,i,l,S]);if(!k)return null;const H=v(),$=["case",[">",["get","blinkIntensity"],.66],nr,[">",["get","blinkIntensity"],.33],tr,["==",["get","staleTier"],2],er,["==",["get","staleTier"],1],Xn,["==",["get","iconType"],"roomServer"],["case",["get","isNeighbor"],Yn,Jn],["==",["get","iconType"],"hub"],["case",["get","isNeighbor"],Un,_n],["==",["get","iconType"],"gateway"],["case",["get","isNeighbor"],Vn,Kn],["==",["get","iconType"],"mobile"],["case",["get","isNeighbor"],Gn,Zn],["case",["get","isNeighbor"],Wn,On]],A=["interpolate",["linear"],["zoom"],6,.25,10,1];return t.jsxs(t.Fragment,{children:[t.jsx(r,{id:zn,type:"geojson",data:S,children:t.jsx(s,{id:In,type:"symbol",layout:{"icon-image":$,"icon-size":A,"icon-allow-overlap":!0,"icon-ignore-placement":!0,"symbol-sort-key":["get","opacity"]},paint:{"icon-opacity":["get","opacity"]}})}),t.jsx(r,{id:`${zn}-local`,type:"geojson",data:F,children:t.jsx(s,{id:qn,type:"symbol",layout:{"icon-image":["case",[">",["get","blinkIntensity"],.66],rr,[">",["get","blinkIntensity"],.33],or,Qn],"icon-size":A,"icon-allow-overlap":!0,"icon-ignore-placement":!0},paint:{"icon-opacity":1}})}),D&&b&&t.jsx(a,{longitude:D.longitude,latitude:D.latitude,offset:{center:[0,0],top:[0,12],"top-left":[6,12],"top-right":[-6,12],bottom:[0,-12],"bottom-left":[6,-12],"bottom-right":[-6,-12],left:[12,0],right:[-12,0]},maxWidth:"280px",closeOnClick:!0,onClose:b,className:"maplibre-popup",children:D.isLocal?t.jsxs("div",{className:"text-sm",children:[t.jsx("strong",{className:"text-base",children:D.name}),D.hash&&t.jsx("span",{className:"ml-2 font-mono text-xs text-fg-muted surface-badge px-1.5 py-0.5 rounded",children:lr(D.hash)}),t.jsx("br",{}),t.jsx("span",{style:{color:H.localColor},className:"font-medium",children:"This Node (Local)"}),t.jsx("br",{}),i&&t.jsxs("span",{className:"text-xs text-fg-muted",children:[i.latitude.toFixed(5),", ",i.longitude.toFixed(5)]})]}):D.neighbor&&D.hash?t.jsx(Pn,{hash:D.hash,hashPrefix:D.hashPrefix,name:D.name,isHub:D.isHub,isGateway:D.isGateway,isBackbone:D.isBackbone,isZeroHop:D.isZeroHop,isMobile:D.isMobile,isRoomServer:D.isRoomServer,isStale:D.isStale,lastSeenTimestamp:D.lastSeenTimestamp,centrality:D.centrality,affinity:D.affinity,meanSnr:D.meanSnr,meanRssi:D.meanRssi,neighbor:D.neighbor,txDelayRec:D.txDelayRec,onRemove:f?()=>f(D.hash,D.name):void 0}):null})]})}const ur=[In,qn],dr="topology-validated-edges-native",mr="topology-weak-edges-native",hr="neighbor-edges-native",gr="topology-weak-edges-native",pr="topology-validated-edges-native",fr="neighbor-edges-native",xr={type:"FeatureCollection",features:[]},yr={"line-cap":"round","line-join":"round"},br={"line-color":"transparent","line-width":16,"line-opacity":0};function vr({showTopology:o,isExiting:a,hoveredEdgeKey:i,highlightedLoopEdges:l,highlightedFocusEdges:c,onEdgeHover:u,onLoopHover:d,loops:m=[],neighborNames:h={},opacityBias:p=.5,widthMultiplier:f=1,trafficFilter:x=0,showNeighborLines:y=!0,disableHover:b=!1}){const{current:v}=n(),j=o||a,w=!0,N=y?"visible":"none",C=b||a,k=e.useRef(null),M=e.useRef(C),S=e.useRef(new Map),F=e.useRef(h),R=e.useRef(d);e.useLayoutEffect(()=>{M.current=C,F.current=h,R.current=d});const T=e.useMemo(()=>function(e){const t=new Map;for(const o of e)for(const e of o.edgeKeys){const n=t.get(e)??[];n.push(o),t.set(e,n)}return t}(m),[m]);e.useLayoutEffect(()=>{S.current=T},[T]);const L=e.useCallback(e=>{var t,o;if(M.current)return;if(!e.features||0===e.features.length)return;const n=e.features[0].properties;if(!(null==n?void 0:n.key))return;const r=n.key;if(r!==k.current){k.current=r;const s=!0===n.isNeighborEdge||"true"===n.isNeighborEdge,a=!0===n.isLoopEdge||"true"===n.isLoopEdge;if(s){const o={key:r,fromName:"Local",toName:n.name,certainCount:Number(n.packetCount)||0,confidence:1,isBackbone:!1,isLoopEdge:!1,isDirectPath:!0,isZeroHop:!0,symmetryRatio:1,dominantDirection:"balanced",isHubConnection:!1};u(r,[e.lngLat.lng,e.lngLat.lat],o),null==(t=R.current)||t.call(R,null)}else if(a&&R.current){const t=S.current.get(r)??[];if(t.length>0){const o=new Set;for(const e of t)for(const t of e.edgeKeys)o.add(t);const n={loops:t,highlightedEdgeKeys:o,hoveredEdgeKey:r,nodeNames:t[0].nodes.map(e=>F.current[e]||e.substring(0,4))};R.current(n,[e.lngLat.lng,e.lngLat.lat]),u(r)}else{const t={key:r,fromName:n.fromName,toName:n.toName,certainCount:Number(n.certainCount),confidence:Number(n.confidence),isBackbone:!0===n.isBackbone||"true"===n.isBackbone,isLoopEdge:!0,isDirectPath:!0===n.isDirectPath||"true"===n.isDirectPath,isZeroHop:!0===n.isZeroHop||"true"===n.isZeroHop,symmetryRatio:Number(n.symmetryRatio),dominantDirection:n.dominantDirection,isHubConnection:!0===n.isHubConnection||"true"===n.isHubConnection};u(r,[e.lngLat.lng,e.lngLat.lat],t)}}else{const t={key:r,fromName:n.fromName,toName:n.toName,certainCount:Number(n.certainCount),confidence:Number(n.confidence),isBackbone:!0===n.isBackbone||"true"===n.isBackbone,isLoopEdge:a,isDirectPath:!0===n.isDirectPath||"true"===n.isDirectPath,isZeroHop:!0===n.isZeroHop||"true"===n.isZeroHop,symmetryRatio:Number(n.symmetryRatio),dominantDirection:n.dominantDirection,isHubConnection:!0===n.isHubConnection||"true"===n.isHubConnection};u(r,[e.lngLat.lng,e.lngLat.lat],t),null==(o=R.current)||o.call(R,null)}}},[u]),E=e.useCallback(()=>{var e;null!==k.current&&(k.current=null,u(null),null==(e=R.current)||e.call(R,null))},[u]);e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t||!j)return;const o="topology-validated-edges-hitarea-native",n=()=>{try{return t.getStyle()&&t.getLayer(o)}catch{return!1}},r=()=>!!n()&&(t.on("mousemove",o,L),t.on("mouseleave",o,E),!0);if(!r()){const e=()=>{r()&&t.off("styledata",e)};return t.on("styledata",e),()=>{try{t.off("styledata",e),n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}}return()=>{try{n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}},[v,j,L,E]),e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t||!y)return;const o="neighbor-edges-hitarea-native",n=()=>{try{return t.getStyle()&&t.getLayer(o)}catch{return!1}},r=()=>!!n()&&(t.on("mousemove",o,L),t.on("mouseleave",o,E),!0);if(!r()){const e=()=>{r()&&t.off("styledata",e)};return t.on("styledata",e),()=>{try{t.off("styledata",e),n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}}return()=>{try{n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}},[v,w,y,L,E]),e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t)return;let o=null;const n=(e,o)=>{try{if(t.getLayer(e)&&t.getLayer(o))return t.moveLayer(e,o),!0}catch{}return!1},r=()=>{try{if(!t.getLayer("node-markers-layer"))return;n(fr,"node-markers-layer"),n("neighbor-edges-hitarea-native",fr),(n(pr,"neighbor-edges-hitarea-native")||n(pr,"node-markers-layer"))&&n("topology-validated-edges-hitarea-native",pr),n(gr,"topology-validated-edges-hitarea-native")}catch{}},s=()=>{o&&clearTimeout(o),o=setTimeout(r,50)},a=setTimeout(r,100);t.on("styledata",s);const i=e=>{(e.sourceId===dr||e.sourceId===mr||e.sourceId===hr)&&s()};return t.on("sourcedata",i),()=>{clearTimeout(a),o&&clearTimeout(o);try{t.off("styledata",s),t.off("sourcedata",i)}catch{}}},[v,j,w,y]);const B=C?null:i,D=function(e,t,o,n,r,s){const a=Tt(),i=null!==e,l=r&&r.size>0,c=s&&s.size>0,u=l?Array.from(r):[],d=c?Array.from(s):[],m=t<=0?["get","baseColor"]:["case",[">=",["get","brightnessScore"],1-.5*t],"#FFFFFF",["get","baseColor"]],h=t<=0?1:["max",.1,["+",1,["*",t,3,["-",["get","brightnessScore"],.5]]]],g=l?["in",["get","key"],["literal",u]]:c?["in",["get","key"],["literal",d]]:!!i&&["==",["get","key"],e],p=i||l||c,f=a.edges.hoverLoop,x=a.edges.highlight;return{"line-color":p?["case",g,l?f:c?x:["get","hoverColor"],m]:m,"line-width":p?["case",g,["max",["*",["get","baseWidth"],o,1.3],3.5],["*",["get","baseWidth"],o]]:["*",["get","baseWidth"],o],"line-opacity":["case",["<",["get","brightnessScore"],n],0,p?["case",g,["min",["*",["get","baseOpacity"],1.25],1],["*",["get","baseOpacity"],h,.35]]:["*",["get","baseOpacity"],h]]}}(B,p,f,x,C?null:l,c??null),H=function(e){const t=null!==e,{YELLOW:o,GREEN:n,RED:r,GRAY:s}=g,a=["to-number",["get","listenerScore"],0],i=["to-number",["get","loudScore"],0],l=["/",a,["max",["+",a,i],1]],c=["*",["+",.2,["*",["to-number",["get","trafficWeight"],0],.8]],8];return{"line-color":["case",["all",["==",a,0],["==",i,0]],s,[">=",l,.97],n,["<=",l,.03],r,["interpolate",["linear"],l,.03,r,.5,o,.97,n]],"line-width":["interpolate",["linear"],["zoom"],6,t?["case",["==",["get","key"],e],["max",["*",c,.25],1.25],["*",c,.25]]:["*",c,.25],10,t?["case",["==",["get","key"],e],["max",c,5],c]:c],"line-opacity":t?["case",["==",["get","key"],e],1,.35]:.9}}(B);return t.jsxs(t.Fragment,{children:[j&&t.jsx(r,{id:mr,type:"geojson",data:xr,children:t.jsx(s,{id:gr,type:"line",paint:D,layout:{...yr,visibility:N}})}),j&&t.jsxs(r,{id:dr,type:"geojson",data:xr,children:[t.jsx(s,{id:"topology-validated-edges-hitarea-native",type:"line",paint:br,layout:{...yr,visibility:N}}),t.jsx(s,{id:pr,type:"line",paint:D,layout:{...yr,visibility:N}})]}),t.jsxs(r,{id:hr,type:"geojson",data:xr,children:[t.jsx(s,{id:"neighbor-edges-hitarea-native",type:"line",paint:br,layout:{...yr,visibility:N}}),t.jsx(s,{id:fr,type:"line",paint:H,layout:{...yr,visibility:N}})]})]})}const jr=["topology-validated-edges-hitarea-native","topology-validated-edges-native","topology-weak-edges-native","neighbor-edges-hitarea-native","neighbor-edges-native"];function wr({targetHash:t,nodeCoordinates:o,onComplete:r}){const{current:s}=n(),a=e.useRef(null);return e.useEffect(()=>{if(!s||!t||t===a.current)return;const e=o.get(t);if(!e)return;const n=s.getMap();n.isMoving()&&n.stop(),a.current=t;const[i,l]=e;s.flyTo({center:[l,i],zoom:10,duration:2500,essential:!0}),setTimeout(()=>{null==r||r()},2600)},[t,o,s,r]),null}function Nr({highlightedEdgeKey:t,validatedPolylines:o,weakPolylines:r,onEnsureTopology:s}){const{current:a}=n(),i=e.useRef(null);return e.useEffect(()=>{if(!a||!t)return;if(t===i.current)return;i.current=t,s();const e=o.find(e=>e.edge.key===t)||r.find(e=>e.edge.key===t);if(!e)return;if(a.getMap().isMoving())return;const n=(e.from[0]+e.to[0])/2,l=(e.from[1]+e.to[1])/2,c=a.getZoom(),u=Math.max(c,11);a.easeTo({center:[l,n],zoom:u,duration:500})},[t,o,r,a,s]),null}const Cr="link-quality-edges",kr="link-quality-edges-hitarea",Mr={type:"FeatureCollection",features:[]};function Sr(e,t){return eQ(),[]),g=e.useMemo(()=>o&&0!==u.length&&0!==d.size?function(e,t,o,n,r){const s=[];for(const a of e){if(o&&a.nodeA.hash!==o&&a.nodeB.hash!==o)continue;const e=t.get(a.nodeA.hash),i=t.get(a.nodeB.hash);if(!e||!i)continue;const l=n[X(a.composite.mean,r)]||"#888888",c=2+2*a.confidence,u=Sr(a.nodeA.hash,a.nodeB.hash);s.push({type:"Feature",geometry:{type:"LineString",coordinates:[[e[1],e[0]],[i[1],i[0]]]},properties:{key:u,color:l,width:c,quality:a.quality,compositeMeanSnr:a.composite.mean,confidence:a.confidence,fromHash:a.nodeA.hash,toHash:a.nodeB.hash,fromPrefix:a.nodeA.prefix,toPrefix:a.nodeB.prefix,fromName:a.nodeA.name||a.nodeA.prefix,toName:a.nodeB.name||a.nodeB.prefix,asymmetryDb:a.asymmetryDb}})}return{type:"FeatureCollection",features:s}}(u,a,i,h,m):Mr,[o,u,d.size,a,i,h,m]);e.useEffect(()=>{if(!c)return;const e=c.getMap();if(e)try{const t=e.getSource(Cr);t&&"setData"in t&&(t.setData(g),e.triggerRepaint())}catch{}},[g,c]);const p=o?"visible":"none";return t.jsxs(r,{id:Cr,type:"geojson",data:Mr,children:[t.jsx(s,{id:"link-quality-edges-layer",type:"line",layout:{...Fr,visibility:p},paint:Rr}),t.jsx(s,{id:kr,type:"line",layout:{...Fr,visibility:p},paint:Tr})]})}function Er(e,t,o,n=64){const r=[],s=o/6371e3*(180/Math.PI),a=s/Math.cos(t*Math.PI/180);for(let i=0;i<=n;i++){const o=i/n*2*Math.PI,l=e+a*Math.cos(o),c=t+s*Math.sin(o);r.push([l,c])}return{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[r]}}}function Br({ghost:o,neighborCoordinates:a,onHighlightedNeighborsChange:i}){const{current:l}=n(),c=e.useRef(null),u=e.useRef(null),d=e.useMemo(()=>o?new Set(o.commonNeighbors):new Set,[o]);e.useEffect(()=>{null==i||i(d)},[d,i]);const m=e.useMemo(()=>{if(!(null==o?void 0:o.commonNeighbors)||o.commonNeighbors.length<2)return 8e3;let e=0;const t=[];for(const n of o.commonNeighbors){const e=a.get(n);e&&t.push(e)}o.estimatedLocation&&t.push([o.estimatedLocation.lat,o.estimatedLocation.lon]);for(let o=0;oe&&(e=r)}return Math.max(e,2e3)},[o,a]),h=e.useMemo(()=>{if(!(null==o?void 0:o.estimatedLocation))return{type:"FeatureCollection",features:[]};const{lat:e,lon:t,uncertaintyM:n}=o.estimatedLocation,r=.5*m,s=n>0?n:2e3;return{type:"FeatureCollection",features:[Er(t,e,Math.max(500,Math.min(s,r)))]}},[o,m]);if(e.useEffect(()=>{if(!l)return;const e=l.getMap();if(o&&o.prefix!==u.current){if(u.current=o.prefix,!c.current&&e.getZoom()>3){const t=e.getCenter();c.current={center:[t.lng,t.lat],zoom:e.getZoom(),pitch:e.getPitch(),bearing:e.getBearing()}}const t=[];for(const e of o.commonNeighbors){const o=a.get(e);o&&t.push([o[1],o[0]])}if(o.estimatedLocation&&t.push([o.estimatedLocation.lon,o.estimatedLocation.lat]),t.length>0){const n=()=>{var r;if(e.isMoving())setTimeout(n,100);else if(1===t.length)l.flyTo({center:t[0],zoom:13,duration:1500});else{let e=1/0,n=-1/0,s=1/0,a=-1/0;for(const[o,r]of t)e=Math.min(e,o),n=Math.max(n,o),s=Math.min(s,r),a=Math.max(a,r);if(null==(r=o.estimatedLocation)?void 0:r.uncertaintyM){const t=o.estimatedLocation.uncertaintyM/111e3;e-=t,n+=t,s-=t,a+=t}l.fitBounds([[e,s],[n,a]],{padding:{top:60,bottom:60,left:60,right:60},maxZoom:14,duration:1500})}};setTimeout(n,50)}}if(!o&&null!==u.current&&(u.current=null,c.current)){const t=c.current,o=()=>{e.isMoving()?setTimeout(o,100):(l.flyTo({center:t.center,zoom:t.zoom,pitch:t.pitch,bearing:t.bearing,duration:1e3}),c.current=null)};setTimeout(o,50)}},[o,l,a]),!(null==o?void 0:o.estimatedLocation))return null;return t.jsx(r,{id:"ghost-uncertainty-circle",type:"geojson",data:h,children:t.jsx(s,{id:"ghost-uncertainty-fill",type:"fill",paint:{"fill-color":"rgba(167, 139, 250, 0.15)","fill-opacity":.8}})})}const Dr=[{target:"Map",fn:"gps",minStage:1,when:d},{target:"Map",fn:"_advertNodeType",minStage:1,when:d},{target:"Topology",fn:"traceHops",minStage:1,when:m},{target:"Topology",fn:"path.entries",minStage:1,when:h},{target:"Topology",fn:"traceSrc",minStage:1,when:m}];u(Dr);const Hr={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"},$r={longitude:0,latitude:0,zoom:2};function Ar({data:e}){const o=e.subtitle&&"loop"===e.type,n=e.subtitle&&"loop"!==e.type;return t.jsxs("div",{className:"w-[540px]",children:[t.jsxs("div",{className:"flex items-center justify-between h-5",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.title.icon&&t.jsx("span",{className:`${e.title.color} text-base leading-none flex-shrink-0`,children:e.title.icon}),t.jsx("span",{className:`${e.title.color} font-semibold text-[13px] truncate`,children:e.title.text}),n&&t.jsx("span",{className:`${e.subtitle.color} text-[11px] flex-shrink-0`,children:e.subtitle.text})]}),e.badges.length>0&&t.jsx("div",{className:"flex items-center gap-2 flex-shrink-0 ml-3",children:e.badges.map((e,o)=>t.jsx("span",{className:`${e.color} text-[11px] font-medium`,children:e.text},o))})]}),o&&t.jsx("div",{className:"h-4 mt-0.5 overflow-hidden",children:t.jsx("span",{className:"type-data-xs text-fg-muted truncate block",children:e.subtitle.text})}),t.jsx("div",{className:`flex items-center gap-4 h-4 ${o?"mt-1":"mt-1.5"} text-[11px]`,children:e.stats.map((e,o)=>t.jsxs("span",{className:"whitespace-nowrap",children:[t.jsx("span",{className:`font-mono tabular-nums font-semibold ${e.color??"text-fg-primary"}`,children:e.value}),t.jsx("span",{className:"text-fg-muted ml-1",children:e.label}),e.unit&&t.jsx("span",{className:"text-fg-muted/50 ml-0.5",children:e.unit})]},o))})]})}function Pr({neighbors:o,localNode:n,localHash:r,onRemoveNode:s,selectedNodeHash:a,onNodeSelected:u,highlightedEdgeKey:d,highlightedGhost:m}){c(Dr);const h=e.useRef(null),g=ee(),f=te(),x=Z(),y=oe(),b=ne(),v=J(),[j,w]=e.useState(!1),N=lt(e=>e.viewState),C=lt(e=>e.toggles),k=lt(e=>e.hasAnalyzed),M=lt(e=>e.setViewState),S=lt(e=>e.setToggle),F=lt(e=>e.setHasAnalyzed),R=lt(e=>e.modalMapOpen),T=re(e=>e.preloadFromNodes),L=re(e=>e.isLoading),E=re(e=>e.terrainGrid),B=r??y,D=e.useMemo(()=>{const e=[];for(const[,t]of Object.entries(o))t.latitude&&t.longitude&&e.push([t.latitude,t.longitude]);return e},[o]),H=e.useMemo(()=>function(e,t){let o=[...e];if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&o.push([t.latitude,t.longitude]),0===o.length)return null;if(1===o.length){const[e,t]=o[0];return{longitude:t,latitude:e,zoom:14}}o=function(e,t){if(e.length<=2)return e;let o,n;if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude))o=t.latitude,n=t.longitude;else{let t=0,r=0;for(const[o,n]of e)t+=o,r+=n;o=t/e.length,n=r/e.length}const r=e.map(([e,t])=>{return{pos:[e,t],dist:(r=o,s=n,a=e,i=t,kt(r,s,a,i)/1e3)};var r,s,a,i});r.sort((e,t)=>e.dist-t.dist);const s=r[Math.floor(r.length/2)].dist,a=Math.max(3*s,50),i=r.filter(e=>e.dist<=a).map(e=>e.pos);return i.length<.5*e.length?e:i}(o,t);let n=1/0,r=-1/0,s=1/0,a=-1/0;for(const[h,g]of o)n=Math.min(n,g),r=Math.max(r,g),s=Math.min(s,h),a=Math.max(a,h);const i=(n+r)/2,l=(s+a)/2,c=a-s,u=r-n,d=Math.max(c,u);let m=16;return d>0&&(m=Math.floor(Math.log2(360/d*1.2)),m=Math.max(1,Math.min(14,m))),m=Math.min(m+1,12),{longitude:i,latitude:l,zoom:m}}(D,n),[D,n]),[$,A]=e.useState(()=>N??H??$r),P=e.useCallback(e=>{A(e),queueMicrotask(()=>M(e))},[M]),z=e.useRef(!!N);e.useEffect(()=>{z.current||!H||N?N&&setTimeout(()=>w(!0),50):(A(H),queueMicrotask(()=>M(H)),z.current=!0,setTimeout(()=>w(!0),50))},[H,N,M]);const[I,q]=e.useState(!1),[O,K]=e.useState(()=>!(C.showTopology&&!x.topologyLoadComplete)&&C.showTopology),[V,G]=e.useState(C.showNeighborLines),[Y,Q]=e.useState(!1),[X,ae]=e.useState(C.showMinCut),[ie,ue]=e.useState(To),[de,me]=e.useState(C.show3DTerrain),[he,ge]=e.useState(C.showLinkQuality),[pe,fe]=e.useState(()=>C.nodeFilters.length>0?C.nodeFilters:[...at]),xe=e.useCallback(e=>{K(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showTopology",o)),o})},[S]),ye=e.useCallback(e=>{G(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showNeighborLines",o)),o})},[S]),be=e.useCallback(e=>{ae(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showMinCut",o)),o})},[S]),ve=e.useCallback(e=>{me(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("show3DTerrain",o)),o})},[S]),je=e.useCallback(e=>{ge(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showLinkQuality",o)),o})},[S]),we=e.useCallback(e=>{fe(e),queueMicrotask(()=>S("nodeFilters",e))},[S]),[Ne,Ce]=e.useState(null),[ke,Me]=e.useState(null),[Se,Fe]=e.useState(null),[Re,Te]=e.useState(null),[Le]=e.useState(0),[Ee]=e.useState(.5),[Be]=e.useState(0),[De,He]=e.useState(null),[$e,Ae]=e.useState(""),[Pe,ze]=e.useState(!1),[Ie,qe]=e.useState(!1),[Oe,We]=e.useState(()=>!(k&&!x.topologyLoadComplete)&&k);e.useEffect(()=>{if(x.topologyLoadComplete)return;const e=k&&!Oe,t=C.showTopology&&!O;(e||t)&&queueMicrotask(()=>{e&&F(!1),t&&S("showTopology",!1)})},[k,C.showTopology,x.topologyLoadComplete,Oe,O,F,S]);const _e=e.useCallback(e=>{We(e),queueMicrotask(()=>F(e))},[F]),[Ue,Ke]=e.useState(null),Ve=e.useCallback(e=>Ke(e),[]),Ze=e.useCallback(()=>Ke(null),[]),[,Ge]=e.useState(new Set),Je=xo(e=>e.coveragePoints),Ye=xo(e=>e.isVisible),Qe=xo(e=>e.brightness),Xe=xo(e=>e.openModal),et=Zo(e=>e.isEnabled),tt=Zo(e=>e.toggle),ot=ct(),nt=ut(),rt=e.useRef(!1);e.useEffect(()=>{Je.length>0&&Ye&&!rt.current&&(ye(!1),rt.current=!0)},[Je.length,Ye]);const st=e.useRef(null);e.useEffect(()=>{if(a&&a!==st.current){st.current=a;const e=setTimeout(()=>{Ke(a)},1250);return()=>clearTimeout(e)}},[a]);const[it,mt]=e.useState(null),[ht,gt]=e.useState(null),bt=e.useCallback((e,t,o)=>{Me(e),e&&t&&o?mt({longitude:t[0],latitude:t[1],type:"topology",properties:{key:o.key,fromName:o.fromName,toName:o.toName,certainCount:o.certainCount,confidence:o.confidence,isBackbone:o.isBackbone,isLoopEdge:o.isLoopEdge,isDirectPath:o.isDirectPath,isHubConnection:o.isHubConnection,symmetryRatio:o.symmetryRatio,dominantDirection:o.dominantDirection}}):e||mt(null)},[]),vt=e.useCallback((e,t)=>{gt(e),e&&mt(null)},[]),jt=e.useMemo(()=>{var e;if(!O)return null;if(!Ne)return null;if(ke)return null;const t=g.loops;if(0===t.length)return null;const n=function(e,t,o){const n=function(e,t){return t.filter(t=>t.nodes.includes(e)).sort((e,t)=>t.avgCertainCount-e.avgCertainCount)}(e,t),r=new Set,s=[];for(const a of n)for(const e of a.edgeKeys)if(!r.has(e)){r.add(e);const t=o.get(e);s.push({key:e,certainCount:(null==t?void 0:t.certainCount)??0})}return s.sort((e,t)=>t.certainCount-e.certainCount),{loops:n,highlightedEdgeKeys:r,sortedEdges:s}}(Ne,t,g.edgeMap);if(0===n.loops.length)return null;const r=n.loops[0].nodes.map(e=>{var t,n;return e===B?"You":(null==(t=o[e])?void 0:t.node_name)||(null==(n=o[e])?void 0:n.name)||e.substring(0,4)});return{loops:n.loops,highlightedEdgeKeys:n.highlightedEdgeKeys,hoveredEdgeKey:(null==(e=n.sortedEdges[0])?void 0:e.key)||"",nodeNames:r}},[O,Ne,ke,g.loops,g.edgeMap,o,B]);e.useEffect(()=>{ke||gt(jt)},[jt,ke]);const wt=e.useMemo(()=>{const e={};for(const[t,n]of Object.entries(o))e[t]=n.node_name||n.name||t.substring(0,4);return B&&(e[B]="You"),e},[o,B]),Nt=e.useMemo(()=>{const e=new Map;for(const[t,n]of Object.entries(o)){const o=t.slice(0,2).toUpperCase(),r=n.node_name||n.name||o;e.set(o,r)}return B&&e.set(B.slice(0,2).toUpperCase(),"You"),e},[o,B]),Ct=e.useMemo(()=>Object.entries(o).filter(([,e])=>e.latitude&&e.longitude),[o]),Ft=e.useMemo(()=>{const e=new Map;B&&(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude)&&e.set(B,[n.latitude,n.longitude]);for(const[t,o]of Ct)o.latitude&&o.longitude&&e.set(t,[o.latitude,o.longitude]);return e},[B,n,Ct]),Rt=e.useMemo(()=>{const e=new Map;for(const t of f)"expired"!==t.status&&e.set(t.hash,{hash:t.hash,prefix:t.prefix,count:t.count,avgRssi:t.avgRssi,avgSnr:t.avgSnr,lastSeen:t.lastSeen,confidence:1,status:t.status});return e},[f]),Tt=e.useMemo(()=>{var e,t;const n=new Set;for(const r of Rt.keys())(null==(e=o[r])?void 0:e.latitude)&&(null==(t=o[r])?void 0:t.longitude)&&n.add(r);return n},[Rt,o]),Et=St(),Bt=e.useMemo(()=>{if(0===Tt.size||!B)return new Map;if(0===Et.length)return new Map;const e=_(B);return p(Et,Tt,e).scores},[Tt,B,Et]),Dt=e.useCallback(e=>!!(B&&(e.fromHash===B&&Tt.has(e.toHash)||e.toHash===B&&Tt.has(e.fromHash))),[B,Tt]),Ht=e.useMemo(()=>{var e,t;if(0===f.length||!B)return[];if(x.backgroundLoadComplete)return[];const n=[];for(const r of f){if("expired"===r.status)continue;if(!(null==(e=o[r.hash])?void 0:e.latitude)||!(null==(t=o[r.hash])?void 0:t.longitude))continue;const s=[B,r.hash].sort(),a=`${s[0]}~${s[1]}`;n.push({fromHash:B,toHash:r.hash,key:a,packetCount:r.count,avgConfidence:1,strength:.8,avgRecency:1,hopDistanceFromLocal:0,isHubConnection:!1,isCertain:!0,certainCount:r.count,isLoopEdge:!1,forwardCount:r.count,reverseCount:0,symmetryRatio:0,dominantDirection:"forward",floodCount:r.count,directCount:0,isDirectPathEdge:!1,isZeroHop:!0,avgRssi:r.avgRssi,avgSnr:r.avgSnr})}return n},[f,B,x.backgroundLoadComplete,o]),$t=e.useMemo(()=>{const e=[];if(Ht.length>0&&!x.backgroundLoadComplete){for(const t of Ht){const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e}for(const t of g.validatedEdges){if(Dt(t))continue;const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e},[g.validatedEdges,Ft,Dt,Ht,x.backgroundLoadComplete]),At=e.useMemo(()=>{const e=[];for(const t of g.weakEdges){if(Dt(t))continue;const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e},[g.weakEdges,Ft,Dt]),Pt=e.useMemo(()=>{if(!(null==n?void 0:n.latitude)||!(null==n?void 0:n.longitude))return[];const e=[],t=[n.latitude,n.longitude],r=new Map;for(const o of g.lastHopNeighbors)r.set(o.hash,o.count);const s=new Map;for(const o of f)s.set(o.hash,o.count);for(const n of Tt){const a=o[n];if(!(null==a?void 0:a.latitude)||!(null==a?void 0:a.longitude))continue;const i=s.get(n),l=r.get(n);e.push({from:t,to:[a.latitude,a.longitude],hash:n,neighbor:a,lastHopData:Rt.get(n)??null,rxAdvertCount:i,txProxyCount:l})}return e},[n,Tt,o,Rt,g.lastHopNeighbors,f]),zt=e.useMemo(()=>new Set(g.loopEdgeKeys),[g.loopEdgeKeys]),It=e.useMemo(()=>new Set(g.backboneEdges),[g.backboneEdges]),qt=e.useMemo(()=>{if(!Se)return null;const e=g.validatedEdges.filter(e=>e.fromHash===Se||e.toHash===Se);if(0===e.length)return null;const t=[...e].sort((e,t)=>t.certainCount-e.certainCount),o=Math.max(1,Math.ceil(.2*t.length)),n=t.slice(0,o);return new Set(n.map(e=>e.key))},[Se,g.validatedEdges]),Wt=e.useMemo(()=>{let e=0;if(Ht.length>0&&!x.backgroundLoadComplete){for(const t of Ht)t.certainCount>e&&(e=t.certainCount);return e||1}for(const t of g.validatedEdges)t.certainCount>e&&(e=t.certainCount);return e||1},[g.validatedEdges,Ht,x.backgroundLoadComplete]),_t=e.useMemo(()=>{if(0===g.validatedEdges.length)return null;const e=new Set;for(const n of g.validatedEdges)e.add(n.fromHash),e.add(n.toHash);const t=Array.from(e).filter(e=>Ft.has(e)).sort();if(t.length<3)return null;const o=new Map;for(const n of t){const e=Ft.get(n);e&&o.set(n,e)}return le(g.validatedEdges,t,o,g.edgeBetweenness)},[g.validatedEdges,Ft,g.edgeBetweenness]),Ut=e.useCallback(()=>{be(e=>{const t=!e;if(t&&_t&&h.current){const e=h.current.getMap();if(!e)return t;let o=1/0,n=-1/0,r=1/0,s=-1/0,a=!1;for(const[,t]of _t.communities)for(const e of t){const t=Ft.get(e);if(t){const[e,i]=t;r=Math.min(r,e),s=Math.max(s,e),o=Math.min(o,i),n=Math.max(n,i),a=!0}}a&&e.fitBounds([[o,r],[n,s]],{padding:{top:60,bottom:100,left:60,right:320},duration:800,maxZoom:14})}return t})},[_t,Ft]),Kt=e.useRef(null);e.useLayoutEffect(()=>{var e,t;Kt.current=(null==(t=null==(e=h.current)?void 0:e.getMap)?void 0:t.call(e))??null});const Vt=St();!function({map:t,nodeCoordinates:o,packets:n,localHash:r,neighbors:s,meshTopology:a,enabled:i=!0}){const l=e.useRef(null),c=t&&"current"in t?t.current:t;e.useEffect(()=>{l.current=c},[c]);const u=e.useRef(!1),d=e.useRef(null),m=e.useRef([]),h=e.useRef(0),g=e.useRef(!1),[p,f]=e.useState(!1),x=e.useRef(null),y=e.useRef([]),b=e.useRef(new Map),v=e.useRef(o);e.useEffect(()=>{v.current=o},[o]),e.useEffect(()=>{b.current=function(e,t){const o=new Map;for(const n of Object.keys(e)){const e=_(n);o.has(e)||o.set(e,n)}if(t){const e=_(t);o.set(e,t)}return o}(s,r)},[s,r]),e.useEffect(()=>{if(!i){x.current&&(clearTimeout(x.current),x.current=null),y.current=[],null!==d.current&&(cancelAnimationFrame(d.current),d.current=null),m.current=[];const e=l.current;if(e&&u.current){const t=e.getSource(kn);t&&t.setData({type:"FeatureCollection",features:[]})}g.current=!1,h.current=0}},[i]),e.useEffect(()=>{const e=c;if(!e)return;let t=null,o=!1;const n=()=>{if(!o&&!u.current)try{e.getLayer(Mn)&&e.removeLayer(Mn),e.getSource(kn)&&e.removeSource(kn),e.addSource(kn,{type:"geojson",data:{type:"FeatureCollection",features:[]}});const o=e.getLayer(Tn)?Tn:void 0;e.addLayer({id:Mn,type:"line",source:kn,layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":["case",["any",["==",["get","isSpeculative"],!0],["==",["get","isSpeculative"],"true"]],"#8B7BAD",Rn],"line-width":["case",["any",["==",["get","isSpeculative"],!0],["==",["get","isSpeculative"],"true"]],1.875,2.5],"line-opacity":["*",["get","opacityMult"],["interpolate",["linear"],["get","intensity"],0,0,.1,.8,.5,1,1,1]]}},o),u.current=!0,f(!0),t&&(clearInterval(t),t=null)}catch{}};return e.isStyleLoaded()&&n(),e.once("style.load",()=>{n()}),u.current||(t=setInterval(()=>{u.current?t&&clearInterval(t):n()},100),setTimeout(()=>{t&&(clearInterval(t),t=null)},5e3)),()=>{o=!0,t&&clearInterval(t),null!==d.current&&(cancelAnimationFrame(d.current),d.current=null);const e=l.current;if(e&&u.current){try{e.getLayer(Mn)&&e.removeLayer(Mn),e.getSource(kn)&&e.removeSource(kn)}catch{}u.current=!1,f(!1)}}},[c]);const j=e.useRef(()=>{});e.useEffect(()=>{j.current=()=>{const e=l.current;if(!e)return;const t=e.getSource(kn);if(!t)return;const o=performance.now(),n=m.current,r=[],s=[];for(const a of n){const e=o-a.startTime-a.delay;if(e<(a.isSpeculative?Fn:Sn)){s.push(a);const t=a.isSpeculative?En(e):Ln(e);t>0&&r.push({type:"Feature",properties:{intensity:t,opacityMult:a.isSpeculative?.5:1,isSpeculative:a.isSpeculative??!1},geometry:{type:"LineString",coordinates:[a.fromCoord,a.toCoord]}})}}t.setData({type:"FeatureCollection",features:r}),m.current=s,s.length>0?d.current=requestAnimationFrame(()=>j.current()):d.current=null}},[]);const w=e.useCallback(()=>{const e=l.current;e&&function(e){if(!e.getLayer(Mn))return;const t=e.getLayer(Tn)?Tn:void 0;try{e.moveLayer(Mn,t)}catch{}}(e),null===d.current&&(d.current=requestAnimationFrame(()=>j.current()))},[]),N=e.useCallback(()=>{if(!l.current||!u.current)return;const e=y.current;if(y.current=[],x.current=null,0===e.length)return;const t=b.current,o=v.current;if(0===t.size)return;const n=performance.now();let s=0,i=!1;const c=new Set;for(const l of e){const e=W(l,r);if(!e||e.original.length<2)continue;const u=e.original;let d=0,h=null;for(let r=0;r0){e.sort((e,t)=>t.confidence-e.confidence);const t=Math.max(1,Math.ceil(.25*e.length)),r=e.slice(0,t),a=s+150*d;for(const{edgeKey:e,otherHash:s}of r){const t=o.get(h),r=o.get(s);m.current.push({edgeKey:e,fromCoord:Bn(t),toCoord:Bn(r),startTime:n,delay:a,isSpeculative:!0}),c.add(e),i=!0}}}d>0&&(s+=150*d*.5)}i&&w()},[r,a,w]);e.useEffect(()=>{const e=l.current;if(!i)return;if(!e)return;if(!p)return;if(0===n.length)return;const t=Date.now(),o=h.current;if(!g.current){g.current=!0;const e=(t-3e4)/1e3,o=n.filter(t=>(t.timestamp??0)>=e);let r=0;for(const t of n){const e=t.timestamp??0;e>r&&(r=e)}if(h.current=r,o.length>0){o.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0));const e=o.slice(-20);y.current.push(...e),N()}return}const r=n.filter(e=>(e.timestamp??0)>o);if(0===r.length)return;let s=0;for(const n of r){const e=n.timestamp??0;e>s&&(s=e)}h.current=s,y.current.push(...r),x.current&&clearTimeout(x.current),x.current=setTimeout(N,175)},[i,n,N,p]),e.useEffect(()=>()=>{x.current&&clearTimeout(x.current)},[])}({map:Kt,nodeCoordinates:Ft,packets:Vt,localHash:B,neighbors:o,meshTopology:g,enabled:et});const{isExiting:Zt,isAnimating:Gt,resetAnimationState:Yt}=function({map:t,showTopology:o,validatedPolylines:n,weakPolylines:r,maxCertainCount:s,loopEdgeKeys:a,backboneEdgeKeys:i,highlightedEdgeKey:l,neighbors:c,validatedSourceId:u,weakSourceId:d,neighborPolylines:m=[],showNeighborLines:h=!0,neighborSourceId:g,neighborLinkScores:p=new Map,basemapMode:f}){const x=e.useRef(null);e.useEffect(()=>{const e=t&&"current"in t?t.current:t;x.current=e});const y=e.useRef(new Map),b=e.useRef(1),v=e.useRef(new Map),j=e.useRef(new Map),w=e.useRef(!1),N=e.useRef(null),C=e.useRef(o),k=e.useRef(new Set),M=e.useRef(""),S=e.useRef(new Map),F=e.useRef(""),R=e.useRef(""),T=e.useRef(""),L=e.useRef(n),E=e.useRef(r),B=e.useRef(s),D=e.useRef(a),H=e.useRef(i),$=e.useRef(l),A=e.useRef(c),P=e.useRef(m),z=e.useRef(h),I=e.useRef(p),q=e.useRef(f);e.useEffect(()=>{L.current=n,E.current=r,B.current=s,D.current=a,H.current=i,$.current=l,A.current=c,P.current=m,z.current=h,I.current=p,q.current=f},[n,r,s,a,i,l,c,m,h,p,f]);const O=e.useCallback((e=!1)=>{var t,o,n,r,s,a,i,l,c,m;const h=x.current;if(!h)return;const p=h.getSource(u),f=h.getSource(d),w=h.getSource(g);if(p){const s=jn(L.current,!0,y.current,b.current,v.current,j.current,B.current,D.current,H.current,$.current,A.current,q.current),a=`${s.features.length}:${(null==(o=null==(t=s.features[0])?void 0:t.properties)?void 0:o.key)??""}:${(null==(r=null==(n=s.features[s.features.length-1])?void 0:n.properties)?void 0:r.key)??""}:${Array.from(y.current.values()).reduce((e,t)=>e+t,0).toFixed(2)}`;(e||a!==F.current)&&(p.setData(s),F.current=a)}if(f){const t=jn(E.current,!1,y.current,b.current,v.current,j.current,B.current,D.current,H.current,$.current,A.current,q.current),o=`${t.features.length}:${(null==(a=null==(s=t.features[0])?void 0:s.properties)?void 0:a.key)??""}:${(null==(l=null==(i=t.features[t.features.length-1])?void 0:i.properties)?void 0:l.key)??""}`;(e||o!==R.current)&&(f.setData(t),R.current=o)}if(w&&P.current.length>0){const t=wn(P.current,I.current),o=`${t.features.length}:${(null==(m=null==(c=t.features[0])?void 0:c.properties)?void 0:m.hash)??""}`;(e||o!==T.current)&&(w.setData(t),T.current=o)}},[u,d,g]),W=e.useCallback(()=>{N.current&&(cancelAnimationFrame(N.current),N.current=null),y.current=new Map,b.current=1,v.current=new Map,j.current=new Map,w.current=!1,k.current=new Set,M.current="",S.current=new Map},[]);e.useEffect(()=>{const e=C.current,t=o;if(C.current=o,x.current){if(N.current&&(cancelAnimationFrame(N.current),N.current=null),e&&!t&&!w.current){w.current=!0;const e=new Map(y.current);let t=null;const o=n=>{t||(t=n);const r=n-t,s=Math.min(r/500,1),a=ft(s);for(const[t,o]of e)y.current.set(t,o*(1-a));O(!0),s<1?N.current=requestAnimationFrame(o):(w.current=!1,y.current=new Map,k.current=new Set,M.current="",v.current=new Map,j.current=new Map,N.current=null,O(!0))};N.current=requestAnimationFrame(o)}!e&&t&&(y.current=new Map,k.current=new Set,M.current="")}},[o,O]),e.useEffect(()=>{const e=x.current;if(!o||w.current||!e)return;const t=[...n,...r],s=t.map(e=>`${e.edge.key}:${e.edge.certainCount}`).sort().join(","),a=0===k.current.size,i=""!==M.current&&M.current!==s;if(!a&&!i)return void O();const l=[],c=[];for(const{edge:o}of t)k.current.has(o.key)?c.push(o.key):l.push(o.key);i&&c.length>0&&(v.current=new Map(S.current),b.current=0),j.current=new Map;for(const{edge:o}of n){const e=Mt(o.certainCount);j.current.set(o.key,e)}for(const o of l)y.current.set(o,0);for(const o of c)y.current.has(o)||y.current.set(o,1);if(l.length>0||i&&c.length>0){N.current&&(cancelAnimationFrame(N.current),N.current=null);let e=null;const t=Math.min(100,Lt/Math.max(l.length,1)/2),o=n=>{e||(e=n);const r=n-e;for(let e=0;e0){const e=Math.min(r/Lt,1);b.current=xt(e)}O(!0);const s=Lt+(l.length-1)*t;N.current=r{const e=x.current;if(!e||!g)return;const t=()=>{const t=e.getSource(g);if(!t)return!1;if(m.length>0){const e=wn(m,p);t.setData(e)}else t.setData({type:"FeatureCollection",features:[]});return!0};if(t())return;const o=n=>{n.sourceId===g&&t()&&e.off("sourcedata",o)};e.on("sourcedata",o);const n=()=>{t()&&(e.off("styledata",n),e.off("sourcedata",o))};return e.on("styledata",n),()=>{e.off("sourcedata",o),e.off("styledata",n)}},[g,m,p]);const _=e.useRef(f);return e.useEffect(()=>{f!==_.current&&(_.current=f,F.current="",R.current="",T.current="",O(!0))},[f,O]),e.useEffect(()=>()=>{N.current&&(cancelAnimationFrame(N.current),N.current=null)},[]),{isExiting:w.current,isAnimating:null!==N.current,resetAnimationState:W,weightAnimProgress:b.current,animStartWeights:v.current,animTargetWeights:j.current}}({map:Kt,showTopology:O,validatedPolylines:$t,weakPolylines:At,maxCertainCount:Wt,loopEdgeKeys:zt,backboneEdgeKeys:It,highlightedEdgeKey:d,neighbors:o,validatedSourceId:dr,weakSourceId:mr,neighborPolylines:Pt,showNeighborLines:V,neighborSourceId:hr,neighborLinkScores:Bt,basemapMode:ot}),Qt=e.useMemo(()=>{const e=new Set;for(const t of g.hubNodes){e.add(t);for(const o of g.validatedEdges)o.fromHash===t&&e.add(o.toHash),o.toHash===t&&e.add(o.fromHash)}return e},[g.hubNodes,g.validatedEdges]),Xt=e.useMemo(()=>{const e=new Set;if(!r)return e;for(const t of g.validatedEdges)t.fromHash===r&&e.add(t.toHash),t.toHash===r&&e.add(t.fromHash);return e},[r,g.validatedEdges]),to=e.useMemo(()=>{const e=new Map;for(const[t,o]of Ct)e.set(t,pt(o).type);return e},[Ct]),oo=e.useMemo(()=>{let e=0,t=0,o=0;for(const[,n]of to)"repeater"===n?e++:"companion"===n||"unknown"===n?t++:"room_server"===n&&o++;return{repeater:e,companion:t,room_server:o,hubs:g.hubNodes.length,direct:Tt.size}},[to,g.hubNodes.length,Tt.size]),ro=e.useMemo(()=>new Set(pe),[pe]),{getNodeOpacity:so}=function({activeFilters:t,neighborHashes:o,hubConnectedNodes:n,directNodeSet:r,localConnectedNodes:s,nodeTypeMap:a,showTopology:i}){const[l,c]=e.useState(new Map),u=e.useMemo(()=>[...t].sort().join(","),[t]),d=e.useRef(u),m=e.useRef(!1),h=e.useRef(new Map),g=e.useRef(null),p=e.useRef(n),f=e.useRef(r),x=e.useRef(s),y=e.useRef(a),b=e.useRef(i);return e.useEffect(()=>{p.current=n,f.current=r,x.current=s,y.current=a,b.current=i},[n,r,s,a,i]),e.useEffect(()=>{const e=d.current,n=u;if(d.current=u,e===n)return;g.current&&(cancelAnimationFrame(g.current),g.current=null);const r=new Set(e?e.split(",").filter(Boolean):[]),s=t,a=p.current,i=f.current,l=y.current;for(const t of o)h.current.has(t)||h.current.set(t,Math.random());const x=(e,t)=>{if(0===t.size)return!1;const o=l.get(e)??"unknown";return!!(t.has("repeater")&&"repeater"===o||t.has("companion")&&("companion"===o||"unknown"===o)||t.has("room_server")&&"room_server"===o||t.has("direct")&&i.has(e)||t.has("hubs")&&a.has(e))},b=[];for(const t of o){const e=x(t,r),o=x(t,s);e!==o&&b.push({hash:t,startOpacity:e?1:0,targetOpacity:o?1:0})}if(0===b.length)return;m.current=!0,c(e=>{const t=new Map(e);for(const{hash:o,startOpacity:n}of b)t.set(o,n);return t});const v=b;let j=null;const w=e=>{j||(j=e);const t=e-j;let o=!0;c(()=>{const e=new Map;for(const{hash:n,startOpacity:r,targetOpacity:s}of v){const a=250*(h.current.get(n)??0),i=Math.max(0,t-a),l=Math.min(i/500,1),c=r+(s-r)*xt(l);e.set(n,c),l<1&&(o=!1)}return e}),t<750&&!o?g.current=requestAnimationFrame(w):(g.current=null,m.current=!1,c(new Map))};return g.current=requestAnimationFrame(w),()=>{g.current&&(cancelAnimationFrame(g.current),g.current=null),m.current=!1}},[u,t,o]),{nodeOpacities:l,getNodeOpacity:(e,t)=>m.current&&l.has(e)?l.get(e):t?1:0}}({activeFilters:ro,neighborHashes:Ct.map(([e])=>e),hubConnectedNodes:Qt,directNodeSet:Tt,localConnectedNodes:Xt,nodeTypeMap:to,showTopology:O}),{blinkingNodes:io,blinkColor:lo}=function({neighbors:t,localHash:o,enabled:n=!0}){const[r,s]=e.useState(new Map),a=St(),i=e.useRef(a);e.useEffect(()=>{i.current=a},[a]);const l=e.useRef(0),c=e.useRef(null),u=e.useRef(new Map),d=e.useRef(new Map);e.useEffect(()=>{d.current=function(e){const t=new Map;for(const o of Object.keys(e)){const e=_(o);t.has(e)||t.set(e,o)}return t}(t)},[t]);const m=e.useRef(null);return e.useEffect(()=>{m.current=()=>{const e=performance.now(),t=u.current;if(0===t.size)return c.current=null,void s(new Map);const o=new Map,n=[];for(const[r,{startTime:s,staggerDelay:a}]of t){const t=e-s-a;if(t<0);else if(t>=750)n.push(r);else{const e=Nn(t,750);e>0&&o.set(r,e)}}for(const r of n)t.delete(r);s(o),t.size>0&&m.current?c.current=requestAnimationFrame(m.current):c.current=null}},[]),e.useEffect(()=>{if(!n)return;const e=i.current;if(0===e.length)return;const t=l.current,r=e.filter(e=>(e.timestamp??0)>t);if(0===t){const t=e.reduce((e,t)=>Math.max(e,t.timestamp??0),0);return void(l.current=t)}if(0===r.length)return;const s=r.reduce((e,t)=>Math.max(e,t.timestamp??0),0);l.current=s;const a=performance.now();let h=0;for(const n of r){const e=W(n,o);if(!e||0===e.original.length)continue;const t=Cn(e.original,d.current,o);if(0===t.length)continue;const r=375;for(let o=0;o()=>{null!==c.current&&(cancelAnimationFrame(c.current),c.current=null)},[]),{blinkingNodes:r,blinkColor:"#00FF00"}}({neighbors:o,localHash:r,enabled:et}),co=e.useCallback(e=>{if(0===ro.size)return!1;const t=to.get(e)??"unknown";return!!(ro.has("repeater")&&"repeater"===t||ro.has("companion")&&("companion"===t||"unknown"===t)||ro.has("room_server")&&"room_server"===t||ro.has("direct")&&Tt.has(e)||ro.has("hubs")&&Qt.has(e))},[ro,to,Tt,Qt]),uo=e.useCallback(()=>{qe(!0),ze(!0)},[]),mo=e.useCallback(()=>{Oe?xe(e=>!e):uo()},[Oe,uo]),ho=e.useCallback(e=>{P(e.viewState),(e.viewState.pitch??0)>10&&!de&&ve(!0)},[de]),go=e.useCallback(()=>{q(e=>{var t,o,n,r,s,a,i;const l=!e,c=null==(n=null==(o=null==(t=h.current)?void 0:t.getContainer())?void 0:o.closest(".map-container-fullscreen, .map-container-16-9"))?void 0:n.parentElement;return l?c&&document.fullscreenEnabled?null==(r=c.requestFullscreen)||r.call(c).catch(()=>{}):c&&document.webkitFullscreenEnabled&&(null==(s=c.webkitRequestFullscreen)||s.call(c)):document.fullscreenElement?null==(a=document.exitFullscreen)||a.call(document).catch(()=>{}):document.webkitFullscreenElement&&(null==(i=document.webkitExitFullscreen)||i.call(document)),l})},[]),po=e.useCallback(()=>{const e=pe.length>=at.length;we(e?[]:[...at])},[pe,we]),fo=e.useCallback(e=>{pe.length>=at.length?we([e]):pe.includes(e)?we(pe.filter(t=>t!==e)):we([...pe,e])},[pe,we]),yo=e.useCallback(()=>{ye(e=>!e)},[]),bo=e.useCallback(()=>{Q(e=>!e)},[]),vo=e.useCallback(()=>{je(e=>{const t=!e;return t||Te(null),t})},[]),jo=e.useCallback(()=>{ve(e=>{const t=!e;if(h.current){const e=h.current.getMap();e&&e.stop()}if(t&&h.current){const e=h.current.getMap();e&&e.easeTo({pitch:45,duration:1500,easing:ft})}if(!t&&h.current){const e=h.current.getMap();e&&e.easeTo({pitch:0,bearing:0,duration:800,easing:yt})}return t})},[]),wo=e.useCallback(()=>{O||xe(!0)},[O]),No=e.useCallback((e,t)=>{He(e),Ae(t)},[]),Co=e.useCallback(()=>{De&&s&&s(De),He(null),Ae("")},[De,s]),ko=e.useMemo(()=>[...jr,...ur,...he?[kr]:[]],[he]),Mo=e.useRef(!1);e.useEffect(()=>{Mo.current="ontouchstart"in window||navigator.maxTouchPoints>0},[]);const So=e.useCallback(e=>{if(he&&e.features&&e.features.length>0){const t=e.features.find(e=>{var t;return(null==(t=e.layer)?void 0:t.id)===kr});if(null==t?void 0:t.properties){const{fromHash:e,toHash:o}=t.properties;if(e&&o){const t=v.find(t=>t.nodeA.hash===e&&t.nodeB.hash===o||t.nodeA.hash===o&&t.nodeB.hash===e);if(t)return void Te(t)}}}e.features&&0!==e.features.length||(Mo.current&&it&&(mt(null),Me(null)),Se&&Fe(null),Re&&Te(null))},[it,Se,he,v,Re]),Fo=e.useCallback(e=>{Fe(t=>t===e?null:e),Te(null)},[]),Lo=e.useCallback(e=>{var t,o,n;if(!e.features||0===e.features.length)return;if(e.features.some(e=>{var t,o;return null==(o=null==(t=e.layer)?void 0:t.id)?void 0:o.startsWith("node-markers-")}))return void(ke&&(Me(null),mt(null)));if(he&&e.features.some(e=>{var t;return(null==(t=e.layer)?void 0:t.id)===kr})){try{(null==(t=h.current)?void 0:t.getCanvas())&&(h.current.getCanvas().style.cursor="pointer")}catch{}return}const r=e.features.find(e=>{var t;const o=null==(t=e.layer)?void 0:t.id;return(null==o?void 0:o.startsWith("topology-"))||(null==o?void 0:o.startsWith("neighbor-"))});if(!r)return;const s=null==(o=r.layer)?void 0:o.id,a=r.properties;if(!(null==a?void 0:a.key))return;const i=null==s?void 0:s.startsWith("topology-"),l=null==s?void 0:s.startsWith("neighbor-");if(i||l){const t=a.key.replace(/-loop[12]$/,"");Me(t),e.lngLat&&mt({longitude:e.lngLat.lng,latitude:e.lngLat.lat,type:i?"topology":"neighbor",properties:a})}try{(null==(n=h.current)?void 0:n.getCanvas())&&(h.current.getCanvas().style.cursor="pointer")}catch{}},[ke,he]),Eo=e.useCallback(()=>{var e;Me(null),mt(null);try{(null==(e=h.current)?void 0:e.getCanvas())&&(h.current.getCanvas().style.cursor="")}catch{}},[]),Bo=I?"map-container-fullscreen":"map-container-16-9",Ho=D.length>0||(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude),$o=!j||!Ho,Ao=Ho;return t.jsxs("div",{className:`relative ${Bo} ${I?"":"rounded-2xl overflow-hidden"}`,role:"application","aria-label":"Mesh network contacts map","aria-describedby":"map-instructions","data-basemap":ot,children:[t.jsx("span",{id:"map-instructions",className:"sr-only",children:"Interactive map showing mesh network contacts. Use mouse or touch to pan and zoom. Press Tab to navigate map controls. Press Escape to exit fullscreen mode."}),$o&&t.jsx("div",{className:"absolute inset-0 z-50 surface-base rounded-2xl flex items-center justify-center","aria-hidden":"true",children:t.jsxs("div",{className:"flex flex-col items-center gap-3",children:[t.jsx("div",{className:"w-6 h-6 border-2 border-sys-blue border-t-transparent rounded-full animate-spin"}),t.jsx("span",{className:"text-sm text-fg-muted",children:"Loading map..."})]})}),Ao&&t.jsx("div",{className:`relative w-full h-full ${I?"":"rounded-[1.125rem] overflow-hidden"} ${$o?"opacity-0":"opacity-100 transition-opacity duration-300"}`,style:R?{visibility:"hidden"}:void 0,children:t.jsxs(i,{ref:h,...$,onMove:ho,mapStyle:Hr,style:{width:"100%",height:"100%"},attributionControl:!1,interactiveLayerIds:ko,onMouseMove:Lo,onMouseLeave:Eo,onClick:So,onError:e=>{console.error("MapLibre error:",e.error)},onIdle:()=>{if(!E&&!L&&h.current){const e=h.current.getMap();if(e){const t=Object.values(o).filter(e=>e.latitude&&e.longitude).map(e=>({latitude:e.latitude,longitude:e.longitude}));(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude)&&t.push({latitude:n.latitude,longitude:n.longitude}),t.length>0&&T(t,e)}}},children:[t.jsx(l,{position:"bottom-right"}),t.jsx(dt,{mode:ot}),t.jsx(ln,{enabled:de,exaggeration:4}),t.jsx(tn,{coveragePoints:Je,visible:Je.length>0&&Ye,terrainEnabled:de,brightness:Qe,basemapMode:ot}),t.jsx(xn,{partition:_t,nodeCoordinates:Ft,visible:X&&Oe,opacity:ie.opacity,bandwidth:ie.bandwidth,threshold:ie.threshold,strokeWidth:ie.strokeWidth}),t.jsx(vr,{showTopology:O,isExiting:Zt,hoveredEdgeKey:ke,highlightedLoopEdges:null==ht?void 0:ht.highlightedEdgeKeys,highlightedFocusEdges:qt,onEdgeHover:bt,onLoopHover:vt,loops:g.loops,neighborNames:wt,opacityBias:Le,widthMultiplier:Ee,trafficFilter:Be,showNeighborLines:V,disableHover:Gt||Ie}),t.jsx(Lr,{visible:he,nodeCoordinates:Ft,focusedNodeHash:Se,basemapMode:ot}),a&&t.jsx(wr,{targetHash:a,nodeCoordinates:Ft,onComplete:u}),d&&t.jsx(Nr,{highlightedEdgeKey:d,validatedPolylines:$t,weakPolylines:At,onEnsureTopology:wo}),t.jsx(Br,{ghost:m??null,neighborCoordinates:Ft,onHighlightedNeighborsChange:Ge}),t.jsx(cr,{neighborsWithLocation:Ct,localNode:n,localHash:r,zeroHopNeighbors:Tt,lastHopNeighborMap:Rt,meshTopology:g,hoveredMarker:Ne,onMarkerHover:Ce,getNodeOpacity:so,shouldShowNode:co,onRequestRemove:s?No:void 0,openPopupId:Ue,onOpenPopup:Ve,onClosePopup:Ze,onNodeClick:Fo,blinkingNodes:io,blinkColor:lo})]})}),(()=>{const e=function(e,t,o,n){var r;if(t){const e=t.loops[0],o=t.loops.length,n=[{label:"hops",value:e.size},{label:"seen",value:e.minCertainCount}],r=[];return e.includesLocal&&r.push({text:"★ Includes your node",color:"text-sys-amber"}),o>1&&r.push({text:`+${o-1} overlapping`,color:"text-sys-indigo/70"}),{type:"loop",title:{icon:"⟳",text:"Redundant Path"+(o>1?"s":""),color:"text-sys-indigo"},subtitle:{text:`${t.nodeNames.join(" → ")} → ${t.nodeNames[0]}`,color:"text-fg-secondary",mono:!0},stats:n,badges:r}}if("neighbor"===(null==e?void 0:e.type)){const t=e.properties,o=[];void 0!==t.rssi&&null!==t.rssi&&o.push({label:"RSSI",value:`${Math.round(t.rssi)} dBm`,unit:t.hasAvgRssi?"avg":void 0}),void 0!==t.snr&&null!==t.snr&&o.push({label:"SNR",value:`${Number(t.snr).toFixed(1)} dB`,unit:t.hasAvgSnr?"avg":void 0});const n=t.listenerScore??0,r=t.loudScore??0,s=n>0||r>0;return s&&(o.push({label:"listener",value:n,color:"text-sys-green"}),o.push({label:"loud",value:r,color:"text-sys-red"})),void 0===t.packetCount||s||o.push({label:"packets",value:Number(t.packetCount).toLocaleString()}),{type:"neighbor",title:{icon:"●",text:t.prefix?`${t.name} (${t.prefix})`:t.name,color:"text-sys-amber"},subtitle:{text:"Direct RF Neighbor",color:"text-sys-amber/70"},stats:o,badges:[]}}if("topology"===(null==e?void 0:e.type)){const t=e.properties,s=o>0?Number(t.certainCount)/o:0,a=[{label:"validations",value:t.certainCount},{label:"of max traffic",value:`${Math.round(100*s)}%`},{label:"confidence",value:`${Math.round(100*Number(t.confidence))}%`}];if(void 0!==t.symmetryRatio&&t.symmetryRatio<1){const e="forward"===t.dominantDirection?"→":"reverse"===t.dominantDirection?"←":"↔";a.push({label:"symmetric",value:`${e} ${Math.round(100*t.symmetryRatio)}%`,color:"text-fg-muted"})}const i=null==(r=null==n?void 0:n.get(t.key))?void 0:r.traceQuality;if(null==i?void 0:i.composite){const e=i.composite;a.push({label:"trace SNR",value:`${e.mean.toFixed(1)} dB`,unit:`n=${e.count}`,color:e.mean>=10?"text-sys-green":e.mean>=0?"text-sys-amber":"text-sys-red"}),null!=i.asymmetryDb&&i.asymmetryDb>1&&a.push({label:"asymmetry",value:`${i.asymmetryDb.toFixed(1)} dB`,color:i.asymmetryDb>5?"text-sys-red":"text-sys-amber"})}const l=[];if(t.isBackbone&&l.push({text:"Backbone",color:"text-zinc-300"}),t.isLoopEdge&&l.push({text:"Redundant",color:"text-sys-indigo"}),t.isDirectPath&&l.push({text:"Direct Path",color:"text-sys-teal"}),i){const e="excellent"===i.quality||"good"===i.quality?"text-sys-green":"fair"===i.quality?"text-sys-amber":"poor"===i.quality||"critical"===i.quality?"text-sys-red":"text-fg-muted";"unknown"!==i.quality&&l.push({text:`TRACE ${i.quality}`,color:e})}return{type:"topology",title:{icon:"",text:`${t.fromName} ↔ ${t.toName}`,color:"text-fg-primary"},stats:a,badges:l}}return null}(it?{type:it.type,properties:it.properties}:null,ht,Wt,g.edgeMap);return e&&t.jsx("div",{className:"map-edge-tooltip",children:t.jsx("div",{className:"map-control-surface map-edge-tooltip-inner",children:t.jsx(Ar,{data:e})})})})(),t.jsx(Jt,{mapRef:h,showNeighborLines:V,onToggleNeighborLines:yo,hasNeighborPolylines:Pt.length>0,nodeFilters:pe,onToggleFilter:fo,onToggleAll:po,filterCounts:oo,showCoverage:Y,onToggleCoverage:bo,showMinCut:X,onToggleMinCut:Ut,hasMinCutData:Oe&&null!==_t&&_t.numCommunities>1,show3DTerrain:de,onToggle3DTerrain:jo,basemapMode:ot,onToggleBasemap:nt,isFullscreen:I,onToggleFullscreen:go,showLinkQuality:he,onToggleLinkQuality:vo,hasTraceLinks:b}),he&&Re&&t.jsx(Ko,{pair:Re,onClose:()=>Te(null),prefixToName:Nt}),t.jsxs("div",{className:"map-legend-stack",children:[t.jsxs("div",{className:"map-tool-row",children:[t.jsx(eo,{isActive:O,hasAnalyzed:Oe,isLoading:Ie,onClick:mo,basemapMode:ot}),t.jsx(no,{isActive:et,onClick:tt,basemapMode:ot}),t.jsx(ao,{isActive:Je.length>0&&Ye,onClick:Xe,basemapMode:ot})]}),t.jsx(Ot,{showTopology:O,validatedPolylineCount:$t.length,filteredNeighborCount:Ct.length,hasLocalNode:!(!(null==n?void 0:n.latitude)||!(null==n?void 0:n.longitude)),meshTopology:g,zeroHopNeighbors:Tt,neighborsWithLocation:Ct,basemapMode:ot})]}),t.jsx(se,{isOpen:null!==De,onCancel:()=>He(null),onConfirm:Co,title:"Remove Node?",message:`Remove "${$e}" from the contacts list? This will hide the node until it sends a new packet.`,confirmLabel:"Remove",cancelLabel:"Cancel",variant:"danger"}),t.jsx(ce,{isOpen:Pe,onClose:()=>{ze(!1),qe(!1),Yt(),_e(!0),setTimeout(()=>xe(!0),150)}}),t.jsx(Ro,{}),t.jsx(Do,{visible:X&&Oe,onClose:()=>be(!1),settings:ie,onSettingsChange:ue,partition:_t,totalNodes:Object.keys(o).length,basemapMode:ot})]})}export{Pr as default}; +import{r as e,j as t,a as o}from"./vendor-react-alRNW2nb.js";import{u as n,S as r,L as s,P as a,M as i,b as l}from"./maplibre-gl-BwLPRSIs.js";import{u as c,r as u,e as d,f as m,g as h}from"./consumer-registry-BUFl6buY.js";import{L as g,c as p}from"./link-scoring-C0BjaK96.js";import{G as f,dd as x,bb as y,Z as b,de as v,df as j,dg as w,an as N,at as C,J as k,b as M,B as S,ap as F,Y as R,_ as T,dh as L,m as E,p as B,ba as D,di as H,V as $,a6 as A,a8 as P,ar as z,ca as I,dj as q,dk as O,cs as W,H as _,aF as U,dl as K,dm as V,a1 as Z,h as G,dn as J,ag as Y,db as Q,ai as X,b3 as ee,r as te,dp as oe,cm as ne,dq as re}from"./index-CkRTgHHA.js";import{C as se}from"./ConfirmModal-B6Rz8ROW.js";import{g as ae,a as ie,b as le,D as ce}from"./DeepAnalysisModal-L9EkN490.js";import{c as ue,a as de,p as me,e as he}from"./vendor-core-FtpmsTnh.js";import{j as ge,K as pe,bo as fe,aX as xe,ah as ye,C as be,W as ve,Y as je,bp as we,d as Ne,c as Ce,bq as ke,aS as Me,aL as Se,b7 as Fe,b as Re,aG as Te,br as Le,L as Ee,bs as Be,Z as De,bt as He,R as $e,X as Ae,aM as Pe,as as ze,aR as Ie,bu as qe,bh as Oe,bv as We,bw as _e,a as Ue,a5 as Ke,aK as Ve,U as Ze,bx as Ge,D as Je,o as Ye,an as Qe,T as Xe,aq as et,a1 as tt,by as ot}from"./vendor-icons-TO0PZKGR.js";import{m as nt,A as rt,b as st}from"./vendor-motion-DNp0Qg4F.js";import{A as at,D as it,u as lt}from"./useMapViewStore-sFZdb1_p.js";import{u as ct,a as ut,B as dt}from"./BasemapLayer-CSqjQAiA.js";import{l as mt,c as ht,a as gt}from"./vendor-geo-2MTwbTwv.js";import{c as pt}from"./node-types-DRVunROD.js";import{a as ft,b as xt,c as yt}from"./easing-GXZYrvDD.js";import{H as bt,C as vt,N as jt,a as wt}from"./badge-colors-BxLppqaF.js";import{L as Nt}from"./LightSparkline-BAD3v4m9.js";import{P as Ct}from"./Contacts-CcN2zB34.js";import{c as kt}from"./geo-utils-DJn8DnxF.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";import"./ping-DPgnsJJf.js";import"./PageLayout-BWMUVZgC.js";import"./listbox-DrzA7Ewq.js";import"./TimeRangeStepper-CsLZzi5t.js";import"./chat-utils-mqGCinix.js";import"./SignalIndicator-Bdj3-1hL.js";import"./CollisionExplorerModal-BUHEIiWh.js";import"./DataBox-DpDXI-WX.js";function Mt(e,t){const o=Math.max(5,Math.min(e,300)),n=Math.log(5),r=Math.log(300);return 1+(Math.log(o)-n)/(r-n)*5}function St(){const t=f();return e.useMemo(()=>x.getPackets(),[t])}const Ft={textPrimary:b[900],textSecondary:"#4A4A4A",textMuted:b[500],border:"rgba(0, 0, 0, 0.12)",hoverBg:"rgba(0, 0, 0, 0.06)",disabledText:"rgba(0, 0, 0, 0.25)"},Rt={nodeFill:y.blue,nodeStroke:"rgba(255,255,255,0.9)",nodeColor:y.indigo,localColor:y.amber,hubColor:y.purple,gatewayColor:y.indigo,mobileColor:y.orange,roomServerColor:y.pink,neighborColor:y.amber,edges:{rest:b[700],restBright:b[600],restDim:b[800],hoverDirect:"#6FBCBD",hoverLoop:"#8B7BAD",hoverStandard:b[400],hoverNeighbor:y.amber,neighborRest:b[500],neighborHover:y.amber,highlight:"#FFD700"},edgeOpacity:.82};function Tt(){if("undefined"==typeof window)return Rt;const e=v(),t=j();return{nodeFill:e.nodeFill,nodeStroke:e.nodeStroke,nodeColor:Rt.nodeColor,localColor:e.localColor,hubColor:e.hubColor,gatewayColor:e.gatewayColor,mobileColor:e.mobileColor,roomServerColor:e.roomColor,neighborColor:e.neighborColor,edges:{rest:t.rest,restBright:t.restBright,restDim:t.restDim,hoverDirect:t.hoverDirect,hoverLoop:t.hoverLoop,hoverStandard:t.hoverStandard,hoverNeighbor:t.hoverNeighbor,neighborRest:Rt.edges.neighborRest,neighborHover:Rt.edges.neighborHover,highlight:t.highlight},edgeOpacity:Rt.edgeOpacity}}const Lt=2e3,Et=M.snappy,Bt=Ft,Dt=e.createContext("dark"),Ht=()=>e.useContext(Dt);function $t({color:e,ring:o}){return t.jsx("span",{className:"shrink-0 rounded-full","aria-hidden":"true",style:{width:14,height:14,backgroundColor:o?"transparent":e,border:o?`4px solid ${e}`:void 0,boxSizing:"border-box"}})}function At({color:e,pattern:o="solid"}){return t.jsx("svg",{className:"shrink-0","aria-hidden":"true",width:18,height:6,viewBox:"0 0 18 6",children:t.jsx("line",{x1:0,y1:3,x2:18,y2:3,stroke:e,strokeWidth:3,strokeLinecap:"round",strokeDasharray:"dashed"===o?"5,3":"dotted"===o?"2,3":void 0})})}function Pt({indicator:e,label:o,tooltip:n}){const r="light"===Ht();return t.jsxs("div",{className:"flex items-center gap-1.5",children:[e,t.jsx("span",{className:ue(!r&&"text-fg-secondary"),style:r?{color:Bt.textSecondary}:void 0,children:o}),n&&t.jsx(k,{content:n,delay:200,children:t.jsx("span",{className:ue("cursor-help text-[11px] opacity-75 hover:opacity-100 transition-opacity",!r&&"text-fg-muted"),style:r?{color:Bt.textMuted}:void 0,children:"ⓘ"})})]})}function zt({title:e,tooltip:o,isOpen:n,onToggle:r,showDivider:s,children:a}){const i="light"===Ht(),l=function(e){return`legend-section-${e.toLowerCase().replace(/\s+/g,"-")}`}(e);return t.jsxs("div",{className:s?"mt-2 pt-2 border-t":"",style:s?{borderColor:i?Bt.border:"var(--map-ui-border)"}:void 0,children:[t.jsxs("button",{type:"button",onClick:r,"aria-expanded":n,"aria-controls":l,className:ue("group w-full flex items-center justify-between py-1 min-h-[44px] sm:min-h-0 font-medium transition-colors",!i&&"text-fg-secondary hover:text-fg-primary"),style:i?{color:Bt.textSecondary}:void 0,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[e,t.jsx(k,{content:o,delay:200,children:t.jsx("span",{className:ue("cursor-help text-[11px] opacity-75 group-hover:opacity-100 transition-opacity",!i&&"text-fg-muted"),style:i?{color:Bt.textMuted}:void 0,children:"ⓘ"})})]}),t.jsx(nt.span,{animate:{rotate:n?0:-90},transition:{duration:.15},"aria-hidden":"true",children:t.jsx(be,{className:"w-3 h-3",style:i?{color:Bt.textMuted}:{color:"var(--fg-muted)"}})})]}),t.jsx(rt,{initial:!1,children:n&&t.jsx(nt.div,{id:l,role:"region","aria-label":e,initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:Et,className:"overflow-hidden",children:t.jsx("div",{className:"flex flex-col gap-1 pt-1.5",children:a})})})]})}function It({label:e,value:o,color:n}){const r="light"===Ht();return t.jsxs("div",{className:ue("flex justify-between tabular-nums",!r&&"text-fg-muted"),style:r?{color:Bt.textMuted}:void 0,children:[t.jsx("span",{children:e}),t.jsx("span",{style:n?{color:n}:r?{color:Bt.textSecondary}:{color:"var(--fg-secondary)"},children:o})]})}function qt({icon:e,color:o,title:n,subtitle:r}){const s="light"===Ht();return t.jsx("div",{className:"mt-1.5 pt-1.5 border-t",style:{borderColor:s?Bt.border:"var(--map-ui-border)"},children:t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"shrink-0",style:{color:o},children:e}),t.jsxs("div",{className:"flex flex-col min-w-0",children:[t.jsx("span",{className:"font-medium truncate",style:{color:o},children:n}),t.jsx("span",{className:ue("text-[10px] leading-tight",!s&&"text-fg-muted"),style:s?{color:Bt.textMuted}:void 0,children:r})]})]})})}function Ot({showTopology:o,validatedPolylineCount:n,filteredNeighborCount:r,hasLocalNode:s,meshTopology:a,zeroHopNeighbors:i,neighborsWithLocation:l,basemapMode:c="dark"}){const u=w(),d=N(),m=C(),h=d.filter(e=>e.isLikelyReal).length,p=function(e){let t=0;for(const o of e.txDelayRecommendations.values())"backbone"===o.networkRole&&t++;return t}(a),f=i.size>0,[x,y]=e.useState(!0),[b,v]=e.useState(!0),[j,k]=e.useState(!0);return t.jsx(Dt.Provider,{value:c,children:t.jsxs("div",{className:"map-control-surface p-2.5 text-xs",children:[t.jsxs(zt,{title:"Nodes",tooltip:"Node type shown by shape + color. Yellow = direct RF neighbor.",isOpen:x,onToggle:()=>y(e=>!e),children:[t.jsx(Pt,{indicator:t.jsx($t,{color:u.nodeFill}),label:"Node",tooltip:"Standard mesh node. Repeater, client, or companion device."}),t.jsx(Pt,{indicator:t.jsx($t,{color:u.hubColor}),label:"Hub",tooltip:"Network hub (≥10% of last-hop traffic)."}),(M=l,M.some(([,e])=>{var t;const o=null==(t=e.contact_type)?void 0:t.toLowerCase();return"room server"===o||"room_server"===o||"room"===o||"server"===o})&&t.jsx(Pt,{indicator:t.jsx(ge,{className:"w-3 h-3 shrink-0",style:{color:u.roomColor},strokeWidth:2.5}),label:"Room",tooltip:"Room Server identity for client sync."})),t.jsx(Pt,{indicator:t.jsx(pe,{className:"w-3 h-3 shrink-0",style:{color:u.localColor},strokeWidth:2.5}),label:"Local",tooltip:"Your repeater running pyMC_Repeater."}),f&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.neighborColor}),label:"Neighbor",tooltip:"Zero-hop direct RF contact."}),a.gatewayNodes.length>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.gatewayColor}),label:"Gateway",tooltip:"Significant forwarder (7-10% traffic)."}),p>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.hubColor}),label:"Backbone",tooltip:"Critical relay with high centrality."}),a.mobileNodes.length>0&&t.jsx(Pt,{indicator:t.jsx($t,{color:u.mobileColor,ring:!0}),label:"Mobile",tooltip:"Volatile node that appears/disappears."}),h>0&&t.jsx(Pt,{indicator:t.jsx(fe,{className:"w-3 h-3 shrink-0",style:{color:u.ghostColor},strokeWidth:2.5}),label:`Ghost (${h})`,tooltip:"Unknown repeater from Viterbi analysis."})]}),f&&t.jsxs(zt,{title:"Link Quality",tooltip:"Neighbor edge colors based on bidirectional balance.",isOpen:b,onToggle:()=>v(e=>!e),showDivider:!0,children:[t.jsx(Pt,{indicator:t.jsx(At,{color:g.YELLOW,pattern:"solid"}),label:"2-Way",tooltip:"33-67% balanced. Ideal bidirectional link."}),t.jsx(Pt,{indicator:t.jsx(At,{color:g.GREEN,pattern:"dashed"}),label:"Listener",tooltip:">67% listener. They hear us well."}),t.jsx(Pt,{indicator:t.jsx(At,{color:g.RED,pattern:"dotted"}),label:"Loud",tooltip:"<33% listener. They route more to us."})]}),o&&n>0&&t.jsxs(zt,{title:"Topology",tooltip:"Links with 5+ validations. Thickness = strength.",isOpen:j,onToggle:()=>k(e=>!e),showDivider:!0,children:[t.jsx(It,{label:"Nodes",value:r+(s?1:0)}),a.hubNodes.length>0&&t.jsx(It,{label:"Hubs",value:a.hubNodes.length,color:Rt.hubColor}),a.loops.length>0&&t.jsx(qt,{icon:t.jsx(xe,{className:"w-3 h-3"}),color:Rt.edges.hoverLoop,title:`${a.loops.length} ${1===a.loops.length?"Loop":"Loops"}`,subtitle:"Redundant paths"}),m.totalPaths>0&&t.jsx(qt,{icon:t.jsx(ye,{className:"w-3 h-3"}),color:u.ghostColor,title:`${m.totalPaths.toLocaleString()} Viterbi`,subtitle:"HMM decoded paths"})]})]})});var M}const Wt={repeater:"blue",companion:"cyan",room_server:"pink",hubs:"indigo",direct:"green"},_t={repeater:"Repeaters",companion:"Companions",room_server:"Rooms",hubs:"Hubs",direct:"Direct"},Ut={repeater:"Repeater nodes (mesh relays)",companion:"Companion devices (clients)",room_server:"Room server nodes",hubs:"Hub nodes and their connections",direct:"Zero-hop (direct RF) neighbors"},Kt=["repeater","companion","room_server"],Vt=["hubs","direct"],Zt="!p-2.5 sm:!p-1.5 !rounded-md min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 shrink-0 flex items-center justify-center",Gt="!p-2.5 sm:!p-1.5 !rounded-none min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 shrink-0 flex items-center justify-center";function Jt({mapRef:o,showNeighborLines:n,onToggleNeighborLines:r,hasNeighborPolylines:s,nodeFilters:a,onToggleFilter:i,onToggleAll:l,filterCounts:c,showCoverage:u,onToggleCoverage:d,showMinCut:m=!1,onToggleMinCut:h,hasMinCutData:g=!1,show3DTerrain:p,onToggle3DTerrain:f,basemapMode:x,onToggleBasemap:y,isFullscreen:b,onToggleFullscreen:v,showLinkQuality:j=!1,onToggleLinkQuality:w,hasTraceLinks:N=!1}){const[C,k]=e.useState(()=>!("undefined"!=typeof window&&window.innerWidth<640)),M="w-4 h-4",R="light"===x?"#525252":"var(--fg-secondary)",T=a.length>=at.length;return t.jsx(t.Fragment,{children:t.jsxs("div",{className:"absolute top-3 right-3 z-[600] flex flex-col gap-2 sm:top-4 sm:right-4 max-w-[calc(100vw-1.5rem)] sm:max-w-none pr-[env(safe-area-inset-right)]",children:[t.jsxs("div",{className:"map-control-surface flex flex-nowrap items-center gap-0.5 sm:gap-1 p-1 overflow-hidden",children:[s&&t.jsx(S,{plain:!0,color:n?"warning":"muted",onClick:r,title:n?"Hide edge lines":"Show edge lines","aria-label":n?"Hide edge lines":"Show edge lines","aria-pressed":n,className:Zt,"data-tint":n?"warning":void 0,children:t.jsx(ve,{className:M})}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>k(e=>!e),title:C?"Hide node filters":"Show node filters","aria-label":C?"Collapse node filters":"Expand node filters","aria-expanded":C,className:Zt,children:t.jsx(je,{className:M})}),t.jsx(rt,{initial:!1,children:C&&t.jsxs(nt.div,{className:"flex items-center gap-0.5 flex-nowrap overflow-x-auto scrollbar-none max-w-[50vw] sm:max-w-none sm:overflow-visible",role:"group","aria-label":"Node type filters",initial:{width:0,opacity:0},animate:{width:"auto",opacity:1},exit:{width:0,opacity:0},transition:{duration:.2,ease:[.4,0,.2,1]},children:[t.jsx(F,{color:T?"green":"zinc",customColor:T?void 0:R,onClick:l,title:"Show all nodes","aria-pressed":T,"aria-label":"Show all node types",className:"shrink-0",children:"All"}),Kt.map(e=>{const o=c[e];if(0===o)return null;const n=!T&&a.includes(e);return t.jsx(F,{color:n?Wt[e]:"zinc",customColor:n?void 0:R,onClick:()=>i(e),title:Ut[e],"aria-pressed":n,"aria-label":`${_t[e]} (${o})`,className:"shrink-0",children:_t[e]},e)}),Vt.some(e=>c[e]>0)&&t.jsx("span",{className:"mx-0.5 h-3 w-px bg-[var(--map-ui-border,var(--edge-subtle))] hidden sm:block shrink-0","aria-hidden":"true"}),Vt.map(e=>{const o=c[e];if(0===o)return null;const n=!T&&a.includes(e);return t.jsx(F,{color:n?Wt[e]:"zinc",customColor:n?void 0:R,onClick:()=>i(e),title:Ut[e],"aria-pressed":n,"aria-label":`${_t[e]} (${o})`,className:"shrink-0",children:_t[e]},e)})]})}),g&&h&&t.jsx(S,{plain:!0,color:m?"primary":"muted",onClick:h,title:m?"Hide community partition":"Show community partition","aria-label":m?"Hide community partition":"Show community partition","aria-pressed":m,className:Zt,"data-tint":m?"primary":void 0,children:t.jsx(we,{className:M})}),t.jsx(S,{plain:!0,color:"light"===x?"primary":"muted",onClick:y,title:"light"===x?"Switch to dark map":"Switch to light map","aria-label":"light"===x?"Switch to dark map":"Switch to light map","aria-pressed":"light"===x,className:Zt,"data-tint":"light"===x?"primary":void 0,children:"light"===x?t.jsx(Ne,{className:M}):t.jsx(Ce,{className:M})}),t.jsx(S,{plain:!0,color:p?"success":"muted",onClick:f,title:p?"Disable 3D terrain":"Enable 3D terrain","aria-label":p?"Disable 3D terrain":"Enable 3D terrain","aria-pressed":p,className:Zt,"data-tint":p?"success":void 0,children:t.jsx(ke,{className:M})}),t.jsx(S,{plain:!0,color:"muted",onClick:v,title:b?"Exit fullscreen":"Fullscreen","aria-label":b?"Exit fullscreen":"Enter fullscreen","aria-pressed":b,className:Zt,children:b?t.jsx(Me,{className:M}):t.jsx(Se,{className:M})})]}),t.jsxs("div",{className:"map-control-surface flex flex-col items-stretch !overflow-hidden self-end !p-0",children:[t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e,t;null==(t=null==(e=o.current)?void 0:e.getMap())||t.zoomIn()},title:"Zoom in","aria-label":"Zoom in",className:Gt,children:t.jsx(Fe,{className:M})}),t.jsx("div",{className:"h-px bg-border-subtle","aria-hidden":"true"}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e,t;null==(t=null==(e=o.current)?void 0:e.getMap())||t.zoomOut()},title:"Zoom out","aria-label":"Zoom out",className:Gt,children:t.jsx(Re,{className:M})}),t.jsx("div",{className:"h-px bg-border-subtle","aria-hidden":"true"}),t.jsx(S,{plain:!0,color:"muted",onClick:()=>{var e;const t=null==(e=o.current)?void 0:e.getMap();t&&t.easeTo({bearing:0,pitch:0,duration:300})},title:"Reset bearing to north","aria-label":"Reset bearing to north",className:Gt,children:t.jsx(Te,{className:M})})]}),N&&w&&t.jsx("div",{className:"map-control-surface flex flex-col items-stretch !overflow-hidden self-end !p-0",children:t.jsx(S,{plain:!0,color:j?"success":"muted",onClick:w,title:j?"Hide link quality overlay":"Show link quality overlay","aria-label":j?"Hide link quality overlay":"Show link quality overlay","aria-pressed":j,className:Gt,"data-tint":j?"success":void 0,children:t.jsx(Le,{className:M})})})]})})}const Yt={text:Ft.textSecondary,activeText:"#16A34A",activeBg:"rgba(220, 252, 231, 1)"},Qt="DeepAnalysis";function Xt(){return"abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(36*Math.random())]}function eo({isActive:o,hasAnalyzed:n,isLoading:r,onClick:s,basemapMode:a="dark"}){const i="light"===a,l=i?Yt.text:void 0,c=i?Yt.activeText:"#4ADE80",[u,d]=e.useState(!1),[m,h]=e.useState(Qt),g=e.useRef(!1),p=e.useRef(null),[f]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)}),x=u&&!o&&!r&&f;e.useEffect(()=>{if(u&&!o&&!r&&!g.current){g.current=!0;const e=performance.now(),t=o=>{const n=o-e,r=Math.min(n/700,1),s=Math.floor(12*r);let a="";for(let e=0;e<12;e++)a+=e{p.current&&cancelAnimationFrame(p.current)}},[u,o,r]);const y=r?"Analyzing...":m,b=r?"Analyzing packet history":n?o?"Hide topology edges":"Show topology edges":"Load full packet history and build topology";return t.jsxs("button",{onClick:s,onMouseEnter:()=>f&&d(!0),onMouseLeave:()=>f&&d(!1),onPointerEnter:()=>f&&d(!0),onPointerLeave:()=>f&&d(!1),disabled:r,className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base "+(r?"cursor-wait":""),style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:i?Yt.activeBg:"rgba(10, 26, 10, 1)"}},title:b,"aria-label":b,"aria-pressed":o,children:[r?t.jsx(Ee,{className:"w-3.5 h-3.5 shrink-0 animate-spin",style:{color:c}}):t.jsx(Be,{className:"w-3.5 h-3.5 shrink-0 transition-colors "+(o?"":"text-fg-secondary"),style:{...o&&{color:c},...x&&{color:c},...!o&&!x&&l&&{color:l}}}),t.jsx("span",{className:o?"":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:"ui-monospace, SFMono-Regular, monospace",fontSize:"0.6875rem",fontWeight:o||x?700:500,letterSpacing:"-0.01em",lineHeight:1,...o&&{color:c},...x&&{color:c},...!o&&!x&&l&&{color:l}},children:y})]})}const to=y.teal,oo={text:Ft.textSecondary,activeTeal:"#0D7377",activeBg:"rgba(204, 251, 241, 1)"};function no({isActive:o,onClick:n,basemapMode:r="dark"}){const s="light"===r,a=s?oo.text:void 0,i=s?oo.activeTeal:to,[l,c]=e.useState(!1),[u,d]=e.useState(0),m=e.useRef(!1),h=e.useRef(null),[g,p]=e.useState(0),f=e.useRef(!1),[x]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)}),y=l&&!o&&x;e.useEffect(()=>{y&&!f.current&&(f.current=!0,p(1),setTimeout(()=>p(2),100),setTimeout(()=>p(3),200)),l||(f.current=!1,p(0))},[y,l]),e.useEffect(()=>{if(l&&!o&&!m.current){m.current=!0;const e=performance.now(),t=o=>{const n=o-e,r=Math.min(n/400,1);d(r),r<1&&(h.current=requestAnimationFrame(t))};h.current=requestAnimationFrame(t)}return l||(h.current&&(cancelAnimationFrame(h.current),h.current=null),m.current=!1,d(0)),()=>{h.current&&cancelAnimationFrame(h.current)}},[l,o]);const b=e=>{if(o)return i;if(!y)return a;const t=11*u;return e>=t-2&&ex&&c(!0),onMouseLeave:()=>x&&c(!1),onPointerEnter:()=>x&&c(!0),onPointerLeave:()=>x&&c(!1),className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base",style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:s?oo.activeBg:"rgba(10, 36, 32, 1)"}},title:o?"Disable live packet tracing (reduces CPU usage)":"Enable live packet tracing","aria-label":v,"aria-pressed":o,children:[t.jsx(De,{className:"w-3.5 h-3.5 shrink-0 "+(o?"":"text-fg-secondary"),fill:1===g?"#FFFFFF":3===g?i:"none",stroke:1===g||2===g?"#FFFFFF":o||y?i:a||"currentColor",style:{transition:"fill 0.05s, stroke 0.05s"}}),t.jsx("span",{className:o?"":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:"ui-monospace, SFMono-Regular, monospace",fontSize:"0.6875rem",fontWeight:o||y?700:500,letterSpacing:"-0.01em",lineHeight:1},children:"LiveTrace".split("").map((e,o)=>t.jsx("span",{style:{color:b(o)||void 0},children:e},o))})]})}const ro={text:Ft.textSecondary,activeBg:"rgba(254, 243, 199, 1)",disabledText:Ft.disabledText},so="#fe8019";function ao({isActive:o,onClick:n,brightness:r=.7,onBrightnessChange:s,basemapMode:a="dark"}){const i="light"===a,l=i?ro.text:void 0,[c,u]=e.useState(!1),[d,m]=e.useState(!1),[h]=e.useState(()=>{var e;return"undefined"!=typeof window&&((null==(e=window.matchMedia)?void 0:e.call(window,"(hover: hover)").matches)??!1)});e.useEffect(()=>{if(!c||o)return;const e=requestAnimationFrame(()=>m(!0)),t=setTimeout(()=>m(!1),80);return()=>{cancelAnimationFrame(e),clearTimeout(t)}},[c,o]);const g=Math.max(.01,Math.min(1,r)),p=g<.999,f=g>.011,x=c&&!o&&h,y=o?"Configure wardriving coverage":"Show wardriving coverage";return t.jsxs("button",{onClick:n,onMouseEnter:()=>h&&u(!0),onMouseLeave:()=>h&&u(!1),onPointerEnter:()=>h&&u(!0),onPointerLeave:()=>h&&u(!1),className:"map-tool-btn flex items-center gap-2 w-full text-left radius-inner transition-base",style:{padding:"0.5rem 0.625rem",...o&&{backgroundColor:i?ro.activeBg:"rgba(26, 20, 8, 1)"}},title:y,"aria-label":y,"aria-pressed":o,children:[t.jsx(He,{className:"w-3.5 h-3.5 shrink-0 transition-colors "+(o?"text-sys-amber":"text-fg-secondary"),style:x?{color:so}:!o&&l?{color:l}:void 0}),t.jsx("span",{className:o?"text-sys-amber":"text-fg-secondary","aria-hidden":"true",style:{fontFamily:o||x?"'Wardrive', serif":"ui-monospace, SFMono-Regular, monospace",fontSize:o||x?"0.75rem":"0.6875rem",fontWeight:500,letterSpacing:"-0.01em",lineHeight:1,transition:"none",transform:o?"scale(1.45)":x?`scale(${d?1.595:1.45})`:void 0,transformOrigin:"left center",...x?{color:so}:!o&&l?{color:l}:{}},children:"Wardrive"}),o&&s&&t.jsxs("div",{className:"ml-auto flex items-center gap-0.5",children:[t.jsx("button",{onClick:e=>{e.stopPropagation();const t=Math.max(.01,g-.2);null==s||s(t)},disabled:!f,className:"p-1 sm:p-0.5 min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center rounded transition-colors "+(f?"text-sys-amber hover:bg-[var(--map-ui-hover,var(--elevated))] active:bg-[var(--map-ui-active,var(--subtle))]":"cursor-not-allowed"),style:f?void 0:{color:i?ro.disabledText:"rgba(251, 191, 36, 0.3)"},title:`Decrease opacity (${Math.round(100*g)}%)`,"aria-label":`Decrease opacity, currently ${Math.round(100*g)}%`,children:t.jsx(Ne,{className:"w-3.5 h-3.5"})}),t.jsx("button",{onClick:e=>{e.stopPropagation();const t=Math.min(1,g+.2);null==s||s(t)},disabled:!p,className:"p-1 sm:p-0.5 min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center rounded transition-colors "+(p?"text-sys-amber hover:bg-[var(--map-ui-hover,var(--elevated))] active:bg-[var(--map-ui-active,var(--subtle))]":"cursor-not-allowed"),style:p?void 0:{color:i?ro.disabledText:"rgba(251, 191, 36, 0.3)"},title:`Increase opacity (${Math.round(100*g)}%)`,"aria-label":`Increase opacity, currently ${Math.round(100*g)}%`,children:t.jsx(Ce,{className:"w-3.5 h-3.5"})})]})]})}function io(e){let t=!0,o=-90,n=90,r=-180,s=180;for(const a of e.toLowerCase()){const e="0123456789bcdefghjkmnpqrstuvwxyz".indexOf(a);if(-1!==e)for(let a=4;a>=0;a--){const i=e>>a&1;if(t){const e=(r+s)/2;i?r=e:s=e}else{const e=(o+n)/2;i?o=e:n=e}t=!t}}return{lat:(o+n)/2,lon:(r+s)/2}}function lo(e){return Math.exp(-e*Math.LN2/7)}const co="pymc-wardriving-url",uo="pymc-wardriving-enabled",mo="pymc-wardriving-brightness";function ho(e){"undefined"!=typeof localStorage&&(e?localStorage.setItem(co,e):localStorage.removeItem(co))}function go(e){"undefined"!=typeof localStorage&&localStorage.setItem(uo,String(e))}function po(){if("undefined"==typeof localStorage)return.7;const e=localStorage.getItem(mo);if(e){const t=parseFloat(e);if(!isNaN(t)&&t>=.01&&t<=1)return t}return.7}function fo(e,t=null){if(null!==e){const o=(Math.max(-12,Math.min(12,e))+12)/24;return null!==t?.8*o+(Math.max(-120,Math.min(-50,t))+120)/70*.2:o}return null!==t?(Math.max(-120,Math.min(-50,t))+120)/70:.5}const xo=de((e,t)=>({status:"idle",isVisible:"undefined"!=typeof localStorage&&"true"===localStorage.getItem(uo),coveragePoints:[],repeaters:[],error:null,stats:{coverageCount:0,repeaterCount:0,lastUpdated:null},url:"undefined"==typeof localStorage?"":localStorage.getItem(co)||"",brightness:po(),isModalOpen:!1,openModal:()=>e({isModalOpen:!0}),closeModal:()=>e({isModalOpen:!1}),setUrl:t=>e({url:t}),setBrightness:t=>{const o=Math.max(.01,Math.min(1,t));!function(e){if("undefined"==typeof localStorage)return;const t=Math.max(.01,Math.min(1,e));localStorage.setItem(mo,String(t))}(o),e({brightness:o})},toggleVisibility:()=>{const o=!t().isVisible;go(o),e({isVisible:o})},setVisible:t=>{go(t),e({isVisible:t})},loadCoverage:async t=>{if(!t.trim())return e({error:"Please enter a URL",status:"error"}),!1;try{new URL(t.trim())}catch{return e({error:"Invalid URL format",status:"error"}),!1}e({error:null,status:"connecting"});try{e({status:"loading"});const o=await async function(e){const t=`${e.replace(/\/+$/,"").replace(/\/get-nodes$/,"").replace(/\/get-samples$/,"")}/get-samples`,o=await async function(e,t={},o=8e3){const n=new AbortController,r=setTimeout(()=>n.abort(),o);try{return await fetch(e,{...t,signal:n.signal})}catch(s){if(s instanceof Error&&"AbortError"===s.name)throw new Error(`Connection timed out after ${o/1e3}s`);throw s}finally{clearTimeout(r)}}(t,{headers:{Accept:"application/json"}});if(!o.ok)throw new Error(`Failed to fetch precise samples: ${o.status}`);return o.json()}(t.trim());if(!o||"object"!=typeof o)throw new Error("Invalid response from server");if(!Array.isArray(o.keys))throw new Error("No sample data found in response");e({status:"processing"});const n=function(e){var t;const o=[];for(const n of e.keys){if(!n.observed)continue;const{lat:e,lon:r}=io(n.hash),s=parseInt(n.time,10),a=isNaN(s)?30:(Date.now()-s)/864e5,i=lo(a),l=fo(n.snr,n.rssi)*(.3+.7*i);o.push({lat:e,lon:r,successRate:n.observed?1:0,weight:l,totalSamples:1,ageDays:a,geohash:n.hash,repeaters:(null==(t=n.path)?void 0:t.map(e=>e.toLowerCase()))||[]})}return o}(o);if(0===n.length)throw new Error("No valid coverage points found");return e({coveragePoints:n,repeaters:[],stats:{coverageCount:n.length,repeaterCount:0,lastUpdated:new Date},status:"success",isVisible:!0,url:t.trim()}),ho(t.trim()),go(!0),!0}catch(o){const t=o instanceof Error?o.message:"Failed to load coverage data";let n=t;return t.includes("timed out")?n="Connection timed out. Server may be unreachable or slow.":t.includes("Failed to fetch")||t.includes("NetworkError")?n="Could not connect to server. Check the URL and try again.":t.includes("CORS")?n="Server does not allow cross-origin requests.":t.includes("404")?n="Coverage endpoint not found. Check the URL.":(t.includes("ERR_NAME_NOT_RESOLVED")||t.includes("DNS"))&&(n="Server not found. Check the URL for typos."),e({error:n,status:"error"}),!1}},clearCoverage:()=>{e({coveragePoints:[],repeaters:[],stats:{coverageCount:0,repeaterCount:0,lastUpdated:null},status:"idle",error:null,isVisible:!1,url:""}),ho(""),go(!1)}})),yo={bg:"#F8F8F8",bgSubtle:"#F0F0F0",bgElevated:"#FFFFFF",bgInput:"#FFFFFF",border:"rgba(0, 0, 0, 0.12)",borderStrong:"rgba(0, 0, 0, 0.20)",borderFocus:"#3B82F6",text:"#1A1A1A",textSecondary:"#4A4A4A",textMuted:"#737373",success:"#059669",successBg:"#ECFDF5",successBorder:"#A7F3D0",error:"#DC2626",errorBg:"#FEF2F2",errorBorder:"#FECACA",info:"#2563EB",infoBg:"#EFF6FF",infoBorder:"#BFDBFE",warning:"#D97706",warningBg:"#FFFBEB",warningBorder:"#FDE68A",primary:"#F59E0B",hoverBg:"rgba(0, 0, 0, 0.04)",sliderTrack:"#E5E7EB",sliderThumb:"#F59E0B"},bo={bg:"var(--surface)",bgSubtle:"var(--subtle)",bgElevated:"var(--elevated)",bgInput:"var(--subtle)",border:"var(--edge-subtle)",borderStrong:"var(--edge-strong)",borderFocus:"var(--sys-blue)",text:"var(--fg-primary)",textSecondary:"var(--fg-secondary)",textMuted:"var(--fg-muted)",success:"var(--sys-green)",successBg:"rgba(74, 222, 128, 0.1)",successBorder:"rgba(74, 222, 128, 0.3)",error:"var(--sys-red)",errorBg:"rgba(239, 68, 68, 0.1)",errorBorder:"rgba(239, 68, 68, 0.3)",info:"var(--sys-indigo)",infoBg:"rgba(249, 210, 111, 0.1)",infoBorder:"rgba(249, 210, 111, 0.3)",warning:"var(--sys-indigo)",warningBg:"rgba(249, 210, 111, 0.1)",warningBorder:"rgba(249, 210, 111, 0.3)",primary:"var(--sys-indigo)",hoverBg:"var(--hover-tint)",sliderTrack:"var(--elevated)",sliderThumb:"var(--sys-indigo)"},vo=e.createContext({theme:bo,isLight:!1});function jo(){return e.useContext(vo)}function wo({status:o,hasData:n}){const{theme:r,isLight:s}=jo(),a=e.useMemo(()=>"connecting"===o||"loading"===o||"processing"===o?{icon:t.jsx(Ee,{className:"w-3.5 h-3.5 animate-spin"}),label:"connecting"===o?"Connecting...":"loading"===o?"Loading...":"Processing...",color:r.warning,bg:r.warningBg}:"error"===o?{icon:t.jsx(qe,{className:"w-3.5 h-3.5"}),label:"Disconnected",color:r.error,bg:r.errorBg}:n?{icon:t.jsx(Oe,{className:"w-3.5 h-3.5"}),label:"Connected",color:r.success,bg:r.successBg}:{icon:t.jsx($e,{className:"w-3.5 h-3.5"}),label:"Ready",color:r.textMuted,bg:s?"rgba(0,0,0,0.04)":"rgba(255,255,255,0.04)"},[o,n,r,s]);return t.jsxs(nt.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},className:"flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium",style:{backgroundColor:a.bg,color:a.color},children:[a.icon,t.jsx("span",{children:a.label})]},a.label)}function No({status:o}){const{theme:n}=jo(),r=e.useMemo(()=>{switch(o){case"connecting":return 25;case"loading":return 60;case"processing":return 90;default:return 0}},[o]);return 0===r?null:t.jsx(nt.div,{initial:{opacity:0,scaleY:0},animate:{opacity:1,scaleY:1},exit:{opacity:0,scaleY:0},className:"h-1 rounded-full overflow-hidden origin-top",style:{backgroundColor:n.sliderTrack},children:t.jsx(nt.div,{className:"h-full rounded-full",style:{backgroundColor:n.primary},initial:{width:0},animate:{width:`${r}%`},transition:{duration:.4,ease:"easeOut"}})})}function Co({variant:o,title:n,description:r,onDismiss:s}){const{theme:a}=jo(),i=e.useMemo(()=>{switch(o){case"success":return{icon:t.jsx(Ue,{className:"w-4 h-4"}),color:a.success,bg:a.successBg,border:a.successBorder};case"error":return{icon:t.jsx(_e,{className:"w-4 h-4"}),color:a.error,bg:a.errorBg,border:a.errorBorder};case"info":return{icon:t.jsx(We,{className:"w-4 h-4"}),color:a.info,bg:a.infoBg,border:a.infoBorder}}},[o,a]);return t.jsxs(nt.div,{initial:{opacity:0,y:-8},animate:{opacity:1,y:0},exit:{opacity:0,y:-8},transition:M.snappy,className:"flex items-start gap-3 p-3 rounded-lg border",style:{backgroundColor:i.bg,borderColor:i.border,color:i.color},children:[t.jsx("div",{className:"shrink-0 mt-0.5",children:i.icon}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("p",{className:"text-sm font-medium",children:n}),r&&t.jsx("p",{className:"text-xs mt-0.5 opacity-80",children:r})]}),s&&t.jsx("button",{onClick:s,className:"shrink-0 p-1 rounded hover:bg-black/10 transition-colors","aria-label":"Dismiss",children:t.jsx(Ae,{className:"w-3.5 h-3.5"})})]})}function ko({value:o,onChange:n,onSubmit:r,disabled:s}){const{theme:a,isLight:i}=jo(),[l,c]=e.useState(!1);return t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("label",{className:"block text-sm font-medium",style:{color:a.textSecondary},children:"Coverage Server URL"}),t.jsxs("div",{className:"relative",children:[t.jsx("input",{type:"url",value:o,onChange:e=>n(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||s||(e.preventDefault(),r())},onFocus:()=>c(!0),onBlur:()=>c(!1),placeholder:"https://coverage.wcmesh.com",disabled:s,className:ue("w-full pl-3 pr-10 py-2.5 rounded-lg border text-sm transition-all duration-150","focus:outline-none",s&&"opacity-50 cursor-not-allowed"),style:{backgroundColor:a.bgInput,borderColor:l?a.borderFocus:a.border,color:a.text,boxShadow:l?"0 0 0 3px "+(i?"rgba(59, 130, 246, 0.15)":"rgba(139, 92, 246, 0.15)"):"none"}}),o&&!s&&t.jsx("button",{onClick:()=>n(""),className:"absolute right-2.5 top-1/2 -translate-y-1/2 p-1 rounded transition-colors",style:{color:a.textMuted},onMouseEnter:e=>e.currentTarget.style.color=a.text,onMouseLeave:e=>e.currentTarget.style.color=a.textMuted,"aria-label":"Clear URL",children:t.jsx(Ae,{className:"w-4 h-4"})})]}),t.jsx("p",{className:"text-xs",style:{color:a.textMuted},children:"Press Enter to connect, or use the Connect button below"})]})}function Mo({value:e,onChange:o}){const{theme:n,isLight:r}=jo(),s=Math.round(100*e);return t.jsx(nt.div,{initial:{opacity:0,height:0},animate:{opacity:1,height:"auto"},exit:{opacity:0,height:0},transition:M.gentle,className:"overflow-hidden",children:t.jsx("div",{className:"p-3 rounded-lg border",style:{backgroundColor:n.bgSubtle,borderColor:n.border},children:t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsxs("div",{className:"relative w-4 h-4",children:[t.jsx(Ne,{className:"w-4 h-4 absolute inset-0 transition-opacity",style:{color:n.textMuted,opacity:e<.5?1:0}}),t.jsx(Ce,{className:"w-4 h-4 absolute inset-0 transition-opacity",style:{color:n.primary,opacity:e>=.5?1:0}})]}),t.jsxs("div",{className:"flex-1",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[t.jsx("span",{className:"text-xs font-medium",style:{color:n.textSecondary},children:"Layer Opacity"}),t.jsxs("span",{className:"text-xs font-mono tabular-nums px-1.5 py-0.5 rounded",style:{color:n.text,backgroundColor:r?"rgba(0,0,0,0.06)":"rgba(255,255,255,0.06)"},children:[s,"%"]})]}),t.jsx("input",{type:"range",min:5,max:100,value:s,onChange:e=>o(Number(e.target.value)/100),className:ue("w-full h-2 rounded-full appearance-none cursor-pointer","[&::-webkit-slider-thumb]:appearance-none","[&::-webkit-slider-thumb]:w-4","[&::-webkit-slider-thumb]:h-4","[&::-webkit-slider-thumb]:rounded-full","[&::-webkit-slider-thumb]:cursor-pointer","[&::-webkit-slider-thumb]:transition-transform","[&::-webkit-slider-thumb]:hover:scale-110","[&::-webkit-slider-thumb]:shadow-lg","[&::-moz-range-thumb]:appearance-none","[&::-moz-range-thumb]:w-4","[&::-moz-range-thumb]:h-4","[&::-moz-range-thumb]:rounded-full","[&::-moz-range-thumb]:border-0","[&::-moz-range-thumb]:cursor-pointer"),style:{background:`linear-gradient(to right, ${n.primary} ${s}%, ${n.sliderTrack} ${s}%)`,"--thumb-color":n.sliderThumb}}),t.jsx("style",{children:`\n input[type="range"]::-webkit-slider-thumb {\n background-color: ${n.sliderThumb};\n }\n input[type="range"]::-moz-range-thumb {\n background-color: ${n.sliderThumb};\n }\n `})]})]})})})}function So({coverageCount:e,repeaterCount:o,lastUpdated:n}){const{theme:r}=jo();return t.jsxs("div",{className:"grid grid-cols-3 gap-2 p-3 rounded-lg border",style:{backgroundColor:r.bgSubtle,borderColor:r.border},children:[t.jsxs("div",{className:"text-center",children:[t.jsx(it,{value:e,format:{useGrouping:!0,maximumFractionDigits:0},className:"text-lg font-semibold tabular-nums block",style:{color:r.text}}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Points"})]}),t.jsxs("div",{className:"text-center border-x",style:{borderColor:r.border},children:[t.jsx(it,{value:o,format:{useGrouping:!0,maximumFractionDigits:0},className:"text-lg font-semibold tabular-nums block",style:{color:r.text}}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Repeaters"})]}),t.jsxs("div",{className:"text-center",children:[t.jsxs("div",{className:"flex items-center justify-center gap-1",children:[t.jsx(Ke,{className:"w-3.5 h-3.5",style:{color:r.textMuted}}),t.jsx("span",{className:"text-lg font-semibold tabular-nums",style:{color:r.text},children:n?n.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}):"—"})]}),t.jsx("div",{className:"text-xs mt-0.5",style:{color:r.textMuted},children:"Updated"})]})]})}function Fo({icon:o,label:n,onClick:r,disabled:s,variant:a="default",active:i}){const{theme:l,isLight:c}=jo(),u=e.useMemo(()=>"danger"===a?{text:l.error,hoverBg:c?"rgba(220, 38, 38, 0.08)":"rgba(239, 68, 68, 0.15)"}:{text:i?l.primary:l.textSecondary,hoverBg:l.hoverBg},[a,i,l,c]);return t.jsxs("button",{onClick:r,disabled:s,className:ue("flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-sm font-medium transition-colors",s&&"opacity-50 cursor-not-allowed"),style:{color:u.text},onMouseEnter:e=>!s&&(e.currentTarget.style.backgroundColor=u.hoverBg),onMouseLeave:e=>e.currentTarget.style.backgroundColor="transparent",children:[o,t.jsx("span",{children:n})]})}function Ro(){const o=ct(),n="light"===o,r=n?yo:bo,{isModalOpen:s,closeModal:a,status:i,isVisible:l,stats:c,error:u,url:d,brightness:m,loadCoverage:h,clearCoverage:g,toggleVisibility:p,setUrl:f,setBrightness:x}=xo(),y="connecting"===i||"loading"===i||"processing"===i,b=c.coverageCount>0,[v,j]=e.useState(!0),[w,N]=e.useState(d);e.useEffect(()=>{N(d)},[d]),e.useEffect(()=>{"error"===i&&j(!0)},[i]);const C=e.useCallback(async()=>{await h(w)},[w,h]),k=e.useCallback(()=>{N(""),g()},[g]),F=e.useCallback(e=>{N(e),f(e)},[f]),L=e.useCallback(()=>{y||a()},[y,a]),E=w.trim().length>0&&!y;return t.jsx(vo.Provider,{value:{theme:r,isLight:n},children:t.jsxs(R,{open:s,onClose:L,size:"md",bottomSheet:!0,basemapMode:o,children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b",style:{borderColor:r.border},children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:"p-2 rounded-lg",style:{backgroundColor:r.bgSubtle,color:r.primary},children:t.jsx($e,{className:"w-5 h-5"})}),t.jsxs("div",{children:[t.jsx("h2",{className:"type-micro",style:{color:r.text},children:"Wardriving Coverage"}),t.jsx("p",{className:"text-xs",style:{color:r.textMuted},children:"RF coverage heatmap overlay"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(wo,{status:i,hasData:b}),!y&&t.jsxs(t.Fragment,{children:[t.jsx("button",{onClick:L,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium transition-base radius-inner active:bg-subtle-fill",style:{color:r.primary},children:"Done"}),t.jsx("button",{onClick:L,className:"hidden sm:flex items-center justify-center p-2 rounded-lg transition-colors",style:{color:r.textMuted},onMouseEnter:e=>{e.currentTarget.style.color=r.text,e.currentTarget.style.backgroundColor=r.hoverBg},onMouseLeave:e=>{e.currentTarget.style.color=r.textMuted,e.currentTarget.style.backgroundColor="transparent"},"aria-label":"Close",children:t.jsx(Ae,{className:"w-5 h-5"})})]})]})]}),t.jsx(rt,{children:y&&t.jsx(No,{status:i})}),t.jsxs(T,{className:"space-y-4",children:[t.jsx(ko,{value:w,onChange:F,onSubmit:C,disabled:y}),t.jsx(rt,{children:"error"===i&&u&&v&&t.jsx(Co,{variant:"error",title:"Connection Failed",description:u,onDismiss:()=>j(!1)})}),t.jsx(rt,{children:"success"===i&&b&&t.jsx(Co,{variant:"success",title:"Coverage Data Loaded",description:"Adjust opacity below, then close to view on map"})}),t.jsx(rt,{children:b&&!y&&t.jsx(nt.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},exit:{opacity:0,y:8},transition:M.snappy,children:t.jsx(So,{coverageCount:c.coverageCount,repeaterCount:c.repeaterCount,lastUpdated:c.lastUpdated})})}),t.jsx(rt,{children:b&&!y&&t.jsx(Mo,{value:m,onChange:x})})]}),t.jsxs("div",{className:"flex items-center justify-between p-4 border-t",style:{borderColor:r.border},children:[t.jsx("div",{className:"flex items-center gap-1",children:t.jsx(rt,{children:b&&t.jsxs(nt.div,{initial:{opacity:0,x:-10},animate:{opacity:1,x:0},exit:{opacity:0,x:-10},transition:M.snappy,className:"flex items-center gap-1",children:[t.jsx(Fo,{icon:l?t.jsx(Pe,{className:"w-4 h-4"}):t.jsx(ye,{className:"w-4 h-4"}),label:l?"Hide":"Show",onClick:p,disabled:y,active:l}),t.jsx(Fo,{icon:t.jsx(ze,{className:"w-4 h-4"}),label:"Clear",onClick:k,disabled:y,variant:"danger"})]})})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(S,{plain:!0,color:"muted",onClick:L,disabled:y,children:b?"Done":"Cancel"}),t.jsx(S,{color:"warning",onClick:C,disabled:!E,children:y?t.jsxs(t.Fragment,{children:[t.jsx(Ee,{"data-slot":"icon",className:"animate-spin"}),"connecting"===i?"Connecting...":"loading"===i?"Loading...":"Processing..."]}):b?t.jsxs(t.Fragment,{children:[t.jsx(xe,{"data-slot":"icon"}),"Refresh"]}):t.jsxs(t.Fragment,{children:[t.jsx(Ie,{"data-slot":"icon"}),"Connect"]})})]})]})]})})}const To={bandwidth:.07,threshold:.1,opacity:1,strokeWidth:4.5},Lo={...Ft,trackBg:Ft.border};function Eo({label:e,value:o,min:n,max:r,step:s,unit:a,formatValue:i,onChange:l,isLightMode:c}){const u=i?i(o):o.toFixed(2);return t.jsxs("div",{className:"flex items-center gap-2 sm:gap-2",children:[t.jsx("span",{className:"text-xs font-medium w-14 sm:w-16 shrink-0",style:c?{color:Lo.textSecondary}:{color:"var(--fg-secondary)"},children:e}),t.jsx("input",{type:"range",min:n,max:r,step:s,value:o,onChange:e=>l(parseFloat(e.target.value)),className:"flex-1 h-1.5 rounded-full appearance-none cursor-pointer\n [&::-webkit-slider-thumb]:appearance-none\n [&::-webkit-slider-thumb]:w-3.5\n [&::-webkit-slider-thumb]:h-3.5\n [&::-webkit-slider-thumb]:rounded-full\n [&::-webkit-slider-thumb]:bg-sys-indigo\n [&::-webkit-slider-thumb]:cursor-pointer\n [&::-webkit-slider-thumb]:transition-transform\n [&::-webkit-slider-thumb]:hover:scale-110\n [&::-webkit-slider-thumb]:shadow-md",style:c?{backgroundColor:Lo.trackBg}:{backgroundColor:"var(--elevated)"}}),t.jsxs("span",{className:"text-xs font-mono tabular-nums w-12 sm:w-14 text-right shrink-0",style:c?{color:Lo.textPrimary}:{color:"var(--fg-muted)"},children:[u,a&&t.jsx("span",{className:"ml-0.5 opacity-70",style:c?{color:Lo.textMuted}:void 0,children:a})]})]})}function Bo({icon:e,label:o,value:n,subtext:r,isLightMode:s}){return t.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 py-0.5 sm:py-1",children:[t.jsx("div",{style:s?{color:Lo.textMuted}:{color:"var(--fg-muted)"},children:e}),t.jsx("div",{className:"flex-1 min-w-0",children:t.jsx("div",{className:"text-[10px] sm:text-xs truncate",style:s?{color:Lo.textSecondary}:{color:"var(--fg-secondary)"},children:o})}),t.jsxs("div",{className:"text-right",children:[t.jsx("div",{className:"text-xs font-mono tabular-nums",style:s?{color:Lo.textPrimary}:{color:"var(--fg-primary)"},children:n}),r&&t.jsx("div",{className:"text-[9px] leading-tight opacity-70",style:s?{color:Lo.textMuted}:{color:"var(--fg-muted)"},children:r})]})]})}function Do({visible:o,onClose:n,settings:r,onSettingsChange:s,partition:a,totalNodes:i,basemapMode:l="dark"}){const c=st(),u=e.useRef(null),d="light"===l,m=e.useMemo(()=>{if(!a)return{numCommunities:0,avgCommunitySize:0,minCommunitySize:0,maxCommunitySize:0,fiedlerValue:0,modularity:0,coveragePercent:0};const e=Array.from(a.communities.values()).map(e=>e.length),t=e.reduce((e,t)=>e+t,0);return{numCommunities:a.numCommunities,avgCommunitySize:e.length>0?Math.round(t/e.length):0,minCommunitySize:e.length>0?Math.min(...e):0,maxCommunitySize:e.length>0?Math.max(...e):0,fiedlerValue:a.fiedlerValue,modularity:0,coveragePercent:i>0?Math.round(t/i*100):0}},[a,i]),h=(e,t)=>{s({...r,[e]:t})},g=(111*r.bandwidth).toFixed(1);return t.jsx("div",{ref:u,className:"absolute inset-0 z-[600] pointer-events-none",children:t.jsx(rt,{children:o&&t.jsx(nt.div,{drag:!0,dragControls:c,dragConstraints:u,dragElastic:.1,dragMomentum:!1,initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},transition:M.smooth,className:"\n absolute pointer-events-auto\n /* Mobile: bottom sheet style, full width with margins */\n bottom-2 left-2 right-2\n /* sm+: floating panel in bottom-right */\n sm:bottom-16 sm:left-auto sm:right-3 sm:w-64\n /* md+: slightly wider */\n md:w-72\n ",style:{touchAction:"none"},children:t.jsxs("div",{className:"\n map-control-surface rounded-lg overflow-hidden shadow-lg\n /* Mobile: limit height, allow scroll */\n max-h-[45vh] sm:max-h-[calc(100vh-180px)] overflow-y-auto\n /* iOS momentum scrolling */\n overscroll-contain\n ",children:[t.jsxs("div",{className:"\n flex items-center justify-between \n px-3 py-2 sm:px-2.5 sm:py-1.5 \n border-b \n cursor-grab active:cursor-grabbing\n /* Larger touch target on mobile */\n min-h-[44px] sm:min-h-0\n ",style:d?{borderColor:Lo.border}:void 0,onPointerDown:e=>c.start(e),children:[t.jsxs("div",{className:"flex items-center gap-2 sm:gap-1.5",children:[t.jsx(Ve,{className:"w-4 h-4 sm:w-3 sm:h-3",style:d?{color:Lo.textMuted}:void 0}),t.jsx(we,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5 text-sys-blue"}),t.jsx("span",{className:"text-sm sm:text-xs font-medium",style:d?{color:Lo.textPrimary}:void 0,children:"Partition"})]}),t.jsx(S,{plain:!0,color:"muted",onClick:n,className:"!p-1.5 sm:!p-0.5 !rounded min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center","aria-label":"Close toolbox",children:t.jsx(Ae,{className:"w-4 h-4 sm:w-3 sm:h-3"})})]}),t.jsx("div",{className:"px-3 py-2 sm:px-2.5 sm:py-1.5 border-b",style:d?{borderColor:Lo.border}:void 0,children:t.jsxs("div",{className:"grid grid-cols-2 gap-x-4 sm:gap-x-3 gap-y-1 sm:gap-y-0.5",children:[t.jsx(Bo,{icon:t.jsx(we,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Communities",value:m.numCommunities,isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ze,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Avg Size",value:m.avgCommunitySize,subtext:`${m.minCommunitySize}–${m.maxCommunitySize}`,isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ge,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Fiedler λ₂",value:m.fiedlerValue.toFixed(3),isLightMode:d}),t.jsx(Bo,{icon:t.jsx(Ze,{className:"w-3.5 h-3.5 sm:w-3 sm:h-3"}),label:"Coverage",value:`${m.coveragePercent}%`,subtext:`of ${i}`,isLightMode:d})]})}),t.jsx("div",{className:"px-3 py-2 sm:px-2.5 sm:py-1.5",children:t.jsxs("div",{className:"space-y-3 sm:space-y-1.5",children:[t.jsx(Eo,{label:"Bandwidth",value:r.bandwidth,min:.01,max:.15,step:.005,formatValue:()=>g,unit:"km",onChange:e=>h("bandwidth",e),isLightMode:d}),t.jsx(Eo,{label:"Threshold",value:r.threshold,min:.05,max:.5,step:.01,formatValue:e=>`${Math.round(100*(1-e))}%`,unit:"cov",onChange:e=>h("threshold",e),isLightMode:d}),t.jsx(Eo,{label:"Opacity",value:r.opacity,min:.1,max:1,step:.05,formatValue:e=>`${Math.round(100*e)}%`,onChange:e=>h("opacity",e),isLightMode:d}),t.jsx(Eo,{label:"Stroke",value:r.strokeWidth,min:0,max:5,step:.5,unit:"px",formatValue:e=>e.toFixed(1),onChange:e=>h("strokeWidth",e),isLightMode:d})]})})]})})})})}const Ho={excellent:"text-signal-excellent",good:"text-signal-good",fair:"text-signal-fair",poor:"text-signal-poor",critical:"text-signal-critical"};function $o(e,t){return Ho[I(e,t)]}const Ao={backgroundColor:"var(--map-ui-hover, var(--elevated))",color:"var(--map-ui-text, var(--fg-primary))",boxShadow:"inset 0 0 0 1px var(--map-ui-border-strong, var(--edge-strong))"},Po={backgroundColor:"var(--map-ui-bg, var(--body))",color:"var(--map-ui-text, var(--fg-primary))",boxShadow:"0 1px 4px rgba(0,0,0,0.15), inset 0 0 0 1px var(--map-ui-border, var(--edge-subtle))"};function zo({prefix:n,name:r}){const s=e.useRef(null),[a,i]=e.useState(!1),[l,c]=e.useState({top:0,left:0});return t.jsxs(t.Fragment,{children:[t.jsx("span",{ref:s,className:"inline-flex items-center px-1.5 py-0.5 rounded font-mono text-[10px] font-semibold transition-opacity hover:opacity-80 cursor-default",style:Ao,onMouseEnter:()=>{if(!r||!s.current)return;const e=s.current.getBoundingClientRect();c({top:e.top-4,left:e.left+e.width/2}),i(!0)},onMouseLeave:()=>i(!1),children:n}),r&&a&&o.createPortal(t.jsx("span",{className:"fixed z-[9999] pointer-events-none -translate-x-1/2 -translate-y-full whitespace-nowrap rounded px-1.5 py-0.5 text-[10px] font-medium",style:{...Po,top:l.top,left:l.left},children:r}),document.body)]})}function Io(e){if(e._tracePathHashes)return e._tracePathHashes;if(e.payload&&e.payload.length>=20){const t=e.payload.slice(18),o=[];for(let e=0;e0?o:null}return null}function qo(e,t){return e.src_hash?[e.src_hash.replace(/^0x/i,"").slice(0,2).toUpperCase(),...t.map(e=>e.toUpperCase())]:t.map(e=>e.toUpperCase())}function Oo(e){switch(e){case"improving":return t.jsx(Xe,{className:"w-3 h-3 text-sys-green"});case"degrading":return t.jsx(Qe,{className:"w-3 h-3 text-sys-red"});case"stable":return t.jsx(Re,{className:"w-3 h-3 text-fg-muted"});default:return null}}const Wo={backgroundColor:"var(--map-ui-stripe)"};function _o({label:e,value:o,unit:n,color:r,tooltip:s}){return t.jsxs("div",{className:"flex items-center justify-between gap-2 py-[3px] "+(s?"cursor-help":""),title:s,children:[t.jsx("span",{className:"type-data-xs text-fg-muted",children:e}),t.jsxs("span",{className:`data-box data-box-compact ${r||""}`,children:[o,n&&t.jsx("span",{className:"text-fg-muted ml-0.5",children:n})]})]})}function Uo({stats:e,direction:o,sf:n,noiseFloor:r}){if(!e)return t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"flex items-center justify-between mb-1.5",children:t.jsx("p",{className:"type-data-xs text-fg-secondary font-medium",children:o})}),t.jsx("p",{className:"type-data-xs text-fg-muted italic px-1.5",children:"No data"})]});const s=e.max-e.min,a=e.median-e.mean,i=q(n),l=e.mean-i,c=I(e.mean,n),u=[`Mean SNR: ${e.mean.toFixed(1)} dB (${c}) from ${e.count} measurement${1!==e.count?"s":""}`,`Variability: ±${e.stdDev.toFixed(1)} dB`,"",`Link budget (SF${n}, 3.5 dBi omni):`,` Demod threshold: ${i.toFixed(1)} dB`,` SNR margin: ${l>=0?"+":""}${l.toFixed(1)} dB`];return null!=r&&u.push(` Noise floor: ${r} dBm`),t.jsxs("div",{className:"min-w-0",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[t.jsx("p",{className:"type-data-xs text-fg-secondary font-medium",children:o}),t.jsxs("span",{className:"type-data-xs text-fg-muted tabular-nums",title:`${e.count} measurement${1!==e.count?"s":""}`,children:["n=",e.count]})]}),t.jsx(_o,{label:"Mean",value:e.mean.toFixed(1),unit:"dB",color:$o(e.mean,n),tooltip:u.join("\n")}),t.jsx(_o,{label:"Median",value:e.median.toFixed(1),unit:"dB",tooltip:"Middle value — less affected by unusual readings than the average."+(Math.abs(a)>=.15?`\nDiffers from mean by ${a>0?"+":""}${a.toFixed(1)} dB`:"")}),t.jsx(_o,{label:"Range",value:`${e.min.toFixed(1)}–${e.max.toFixed(1)}`,unit:"dB",tooltip:`Best to worst signal observed. Total spread: ${s.toFixed(1)} dB.`})]})}function Ko({pair:o,onClose:n,prefixToName:r}){var s,a,i,l,c,u,d,m,h,g,p,f;const x=L(),y=E(),b=B(),v=D(),[j,w]=e.useState(null),N=(null==(a=null==(s=null==b?void 0:b.config)?void 0:s.radio)?void 0:a.spreading_factor)??H,C=e.useMemo(()=>{const e=`${o.nodeA.hash}>${o.nodeB.hash}`,t=`${o.nodeB.hash}>${o.nodeA.hash}`;return{forward:x.get(e)??null,reverse:x.get(t)??null}},[x,o.nodeA.hash,o.nodeB.hash]),k=e.useMemo(()=>y&&0!==y.length?function(e,t,o,n=15){const r=[],s=t.toUpperCase(),a=o.toUpperCase();for(const i of e){if((i.type??i.payload_type)!==z.TRACE)continue;const e=Io(i);if(!e||e.length<1)continue;const t=qo(i,e);if(!(t.length<2)){for(let e=0;e=n)break}}return r}(y,o.nodeA.prefix,o.nodeB.prefix):[],[y,o.nodeA.prefix,o.nodeB.prefix]),M=o.nodeA.name||(null==r?void 0:r.get(o.nodeA.prefix.toUpperCase()))||null,F=o.nodeB.name||(null==r?void 0:r.get(o.nodeB.prefix.toUpperCase()))||null,R=(null==(i=C.forward)?void 0:i.trend)??(null==(l=C.reverse)?void 0:l.trend)??"insufficient",T=Math.max((null==(c=C.forward)?void 0:c.lastSeen)??0,(null==(u=C.reverse)?void 0:u.lastSeen)??0),I=((null==(d=C.forward)?void 0:d.uniqueTraceCount)??0)+((null==(m=C.reverse)?void 0:m.uniqueTraceCount)??0),q="insufficient"===R?"Not enough data to determine trend (need at least 4 measurements).":"Whether signal quality is getting better or worse over time.\nCompares older measurements to newer ones.",O=(null==(h=C.forward)?void 0:h.uniqueTraceCount)??0,W=(null==(g=C.reverse)?void 0:g.uniqueTraceCount)??0,_=["Number of trace packets that traveled through this link.",`${o.nodeA.prefix}→${o.nodeB.prefix}: ${O}`,`${o.nodeB.prefix}→${o.nodeA.prefix}: ${W}`].join("\n");return t.jsx("div",{className:"\n absolute z-[700] overflow-hidden\n /* Mobile: full-width bottom sheet with breathing room */\n bottom-2 left-2 right-2\n /* sm+: right-aligned floating panel */\n sm:bottom-16 sm:left-auto sm:right-4 sm:w-[280px]\n ",children:t.jsxs("div",{className:"\n map-control-surface flex flex-col\n /* Mobile: cap at 45vh so map stays visible */\n max-h-[45vh]\n /* sm+: taller allowance */\n sm:max-h-[420px]\n ",children:[t.jsxs("div",{className:"flex items-center justify-between gap-2 px-3 py-2 sm:py-2 min-h-[44px] sm:min-h-0 border-b border-edge-subtle",children:[t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx(Le,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5 text-sys-green shrink-0"}),t.jsx(zo,{prefix:o.nodeA.prefix,name:M}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"↔"}),t.jsx(zo,{prefix:o.nodeB.prefix,name:F})]}),t.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[T>0&&t.jsx("span",{className:"type-data-xs text-fg-muted",title:A(T),children:$(T)}),t.jsx(S,{plain:!0,color:"muted",onClick:n,className:"!p-1.5 sm:!p-0.5 !rounded-md min-w-[44px] min-h-[44px] sm:min-w-0 sm:min-h-0 flex items-center justify-center",children:t.jsx(Ae,{className:"w-4 h-4 sm:w-3.5 sm:h-3.5"})})]})]}),t.jsxs("div",{className:"px-3 py-2.5 border-b border-edge-subtle",children:[t.jsxs("div",{className:"space-y-1.5 mb-2",children:[t.jsxs("div",{className:"flex items-center justify-between cursor-help",title:`${o.nodeA.prefix}→${o.nodeB.prefix}: mean of ${(null==(p=o.aToB)?void 0:p.count)??0} measurements`,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx(zo,{prefix:o.nodeA.prefix,name:M}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"→"}),t.jsx(zo,{prefix:o.nodeB.prefix,name:F})]}),o.aToB?t.jsxs("span",{className:`type-data-sm tabular-nums font-semibold ${$o(o.aToB.mean,N)}`,children:[o.aToB.mean.toFixed(1),t.jsx("span",{className:"text-fg-muted font-normal ml-0.5",children:"dB"})]}):t.jsx("span",{className:"type-data-sm text-fg-muted",children:"—"})]}),t.jsxs("div",{className:"flex items-center justify-between cursor-help",title:`${o.nodeB.prefix}→${o.nodeA.prefix}: mean of ${(null==(f=o.bToA)?void 0:f.count)??0} measurements`,children:[t.jsxs("span",{className:"flex items-center gap-1",children:[t.jsx(zo,{prefix:o.nodeB.prefix,name:F}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:"→"}),t.jsx(zo,{prefix:o.nodeA.prefix,name:M})]}),o.bToA?t.jsxs("span",{className:`type-data-sm tabular-nums font-semibold ${$o(o.bToA.mean,N)}`,children:[o.bToA.mean.toFixed(1),t.jsx("span",{className:"text-fg-muted font-normal ml-0.5",children:"dB"})]}):t.jsx("span",{className:"type-data-sm text-fg-muted",children:"—"})]})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-0 -mx-3 border-t border-edge-subtle",children:[t.jsx("div",{className:"px-3 pt-2 pb-1 border-r border-edge-subtle",children:t.jsx(Uo,{stats:o.aToB,direction:`${o.nodeA.prefix}→${o.nodeB.prefix}`,sf:N,noiseFloor:v})}),t.jsx("div",{className:"px-3 pt-2 pb-1",children:t.jsx(Uo,{stats:o.bToA,direction:`${o.nodeB.prefix}→${o.nodeA.prefix}`,sf:N,noiseFloor:v})})]})]}),t.jsxs("div",{className:"px-3 py-1.5 border-b border-edge-subtle",children:["insufficient"!==R&&t.jsxs("div",{className:"flex items-center justify-between gap-2 py-[3px] cursor-help",title:q,children:[t.jsx("span",{className:"type-data-xs text-fg-muted",children:"Trend"}),t.jsx("span",{className:"data-box data-box-compact",children:t.jsxs("span",{className:"flex items-center gap-1",children:[Oo(R),t.jsx("span",{className:"text-fg-secondary capitalize",children:R})]})})]}),I>0&&t.jsx(_o,{label:"Unique traces",value:I.toString(),tooltip:_})]}),k.length>0&&t.jsxs("div",{className:"px-3 py-2 flex-1 min-h-0 flex flex-col",children:[t.jsxs("p",{className:"type-micro text-fg-secondary mb-1 shrink-0",children:["Source packets (",k.length,")"]}),t.jsx("div",{className:"overflow-y-auto flex-1 min-h-0 overscroll-contain",style:{scrollbarGutter:"stable"},children:k.map((e,o)=>{const n=Io(e),s=n?qo(e,n):null,a=s?Math.max(0,s.length-1):0,i=s?s.map(e=>(null==r?void 0:r.get(e))??e).join(" → "):null,l=j===o,c=e.id??`${e.packet_hash}-${e.timestamp}`;return t.jsxs("div",{className:"rounded-sm",style:o%2==1?Wo:void 0,children:[t.jsxs("button",{onClick:()=>w(l?null:o),className:"flex items-center gap-1.5 py-[3px] px-1 w-full text-left text-[10px] font-mono text-fg-secondary hover:text-fg-primary transition-colors group",children:[l?t.jsx(be,{className:"w-2.5 h-2.5 text-fg-muted shrink-0"}):t.jsx(Je,{className:"w-2.5 h-2.5 text-fg-muted shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"}),t.jsx("span",{className:"text-fg-muted w-[52px] shrink-0",children:A(e.timestamp)}),i?t.jsx("span",{className:"text-fg-secondary truncate min-w-0",title:s.join(" → "),children:i}):t.jsx("span",{className:"text-fg-muted truncate min-w-0 italic",children:"path n/a"}),t.jsxs("span",{className:"text-fg-muted shrink-0",children:[a,"h"]}),null!=e.snr&&t.jsx("span",{className:`shrink-0 tabular-nums ${$o(e.snr,N)}`,children:e.snr.toFixed(1)})]}),l&&t.jsxs("div",{className:"mb-1 mt-0.5 mx-1 pl-2 border-l border-edge-subtle space-y-0.5 text-[10px]",children:[null!=e.rssi&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"RSSI"}),t.jsxs("span",{className:"font-mono tabular-nums text-fg-secondary",children:[e.rssi," dBm"]})]}),null!=e.snr&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"SNR"}),t.jsxs("span",{className:`font-mono tabular-nums ${$o(e.snr,N)}`,children:[e.snr.toFixed(1)," dB"]})]}),t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Route"}),t.jsx("span",{className:"font-mono text-fg-secondary",children:P(e.route??e.route_type)})]}),e.packet_hash&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Hash"}),t.jsxs("button",{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.packet_hash)},className:"flex items-center gap-1 font-mono text-fg-secondary hover:text-fg-primary transition-colors",title:"Copy packet hash",children:[t.jsx("span",{className:"truncate max-w-[120px]",children:e.packet_hash}),t.jsx(Ye,{className:"w-2.5 h-2.5 text-fg-muted shrink-0"})]})]}),e.src_hash&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Source"}),t.jsx("span",{className:"font-mono text-fg-secondary truncate max-w-[140px]",title:e.src_hash,children:e.src_hash})]}),s&&s.length>0&&t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Path"}),t.jsx("span",{className:"font-mono text-fg-secondary truncate max-w-[140px]",title:s.join(" → "),children:s.join(" → ")})]})]})]},c)})})]})]})})}const Vo={getItem:e=>{try{return localStorage.getItem(e)}catch{return null}},setItem:(e,t)=>{try{localStorage.setItem(e,t)}catch{}},removeItem:e=>{try{localStorage.removeItem(e)}catch{}}},Zo=de()(me(e=>({isEnabled:!1,toggle:()=>e(e=>({isEnabled:!e.isEnabled})),setEnabled:t=>e({isEnabled:t})}),{name:"pymc-live-trace",storage:he(()=>Vo)})),Go="wardriving-hexagons",Jo="wardriving-hexagons-fill",Yo=[[15,5,30,255],[35,10,55,255],[55,15,75,255],[75,20,90,255],[95,25,100,255],[115,30,105,255],[135,35,100,255],[155,45,90,255],[175,55,75,255],[195,70,60,255],[210,90,50,255],[225,110,45,255],[235,135,45,255],[245,160,50,255],[250,185,60,255],[252,205,80,255],[254,225,105,255],[255,240,135,255],[255,248,170,255],[255,252,200,255],[255,254,225,255],[255,255,240,255],[255,255,250,255],[255,255,255,255]],Qo=[[60,20,120,255],[80,30,140,255],[100,40,160,255],[120,50,170,255],[140,60,175,255],[160,70,175,255],[180,60,150,255],[200,55,120,255],[215,55,90,255],[230,65,60,255],[240,80,40,255],[250,100,30,255],[255,130,30,255],[255,155,35,255],[255,175,40,255],[255,195,50,255],[255,210,60,255],[255,225,70,255],[255,200,40,255],[255,185,30,255],[255,170,20,255],[245,155,15,255],[235,140,10,255],[225,125,5,255]];function Xo(e){return`rgb(${e[0]}, ${e[1]}, ${e[2]})`}function en(e,t,o,n){const r=o-t;if(r<.001)return Xo(n[12]);const s=(a=Math.max(0,Math.min(1,(e-t)/r)))<.15?a/.15*.1:a>.85?.9+(a-.85)/.15*.1:.1+(a-.15)/.7*.8;var a;return Xo(n[Math.min(23,Math.floor(24*s))])}function tn({coveragePoints:o,visible:r,terrainEnabled:s=!1,brightness:a=.7,basemapMode:i="dark"}){const{current:l}=n(),[c,u]=e.useState(null);e.useEffect(()=>{const e=()=>{var e;const t=null==(e=null==l?void 0:l.getMap)?void 0:e.call(l);t&&!c&&u(t)};e();const t=setInterval(e,50),o=setTimeout(()=>clearInterval(t),5e3);return()=>{clearInterval(t),clearTimeout(o)}},[l,c]);const[d,m]=e.useState(null),[h,g]=e.useState(!1),p=e.useRef({aborted:!1}),f=e.useRef(0),x=e.useRef(i),y=function(t){const[o,n]=e.useState(t);return e.useEffect(()=>{const e=setTimeout(()=>n(t),300);return()=>clearTimeout(e)},[t,300]),o}(o),b=e.useMemo(()=>function(e="dark"){var t;if("light"===e)return Qo;const o=O();return 24===o.length&&0!==(null==(t=o[0])?void 0:t[0])?o:Yo}(i),[i]);e.useEffect(()=>{if(!y||!Array.isArray(y)||0===y.length)return void queueMicrotask(()=>{m(null),f.current=0});const e=x.current!==i;if(y.length===f.current&&d&&!e)return;f.current=y.length,x.current=i,p.current.aborted=!0,p.current={aborted:!1};const t=p.current;g(!0);const{cells:o,minQuality:n,maxQuality:r}=function(e){const t=new Map;for(const s of e){if("number"!=typeof s.lat||"number"!=typeof s.lon||isNaN(s.lat)||isNaN(s.lon))continue;const e=mt(s.lat,s.lon,8),o=t.get(e),n=s.weight;o?(o.count++,o.qualitySum+=n):t.set(e,{count:1,qualitySum:n})}const o=[];let n=1/0,r=-1/0;for(const[s,a]of t.entries()){const e=a.qualitySum/a.count;o.push({hexId:s,count:a.count,avgQuality:e}),n=Math.min(n,e),r=Math.max(r,e)}return{cells:o,minQuality:o.length>0?n:0,maxQuality:o.length>0?r:0}}(y);if(0===o.length)return m(null),void g(!1);if(o.length<500){const e=function(e,t,o,n){const r=[];for(const s of e){const e=ht(s.hexId).map(([e,t])=>[t,e]);e.push(e[0]);const a=en(s.avgQuality,t,o,n);r.push({type:"Feature",properties:{color:a,quality:s.avgQuality,count:s.count},geometry:{type:"Polygon",coordinates:[e]}})}return{type:"FeatureCollection",features:r}}(o,n,r,b);return void(t.aborted||(m(e),g(!1)))}return async function(e,t,o,n,r){const s=[];let a=0;for(;a[t,e]);i.push(i[0]);const l=en(r.avgQuality,t,o,n);s.push({type:"Feature",properties:{color:l,quality:r.avgQuality,count:r.count},geometry:{type:"Polygon",coordinates:[i]}})}arequestAnimationFrame(e))}return{type:"FeatureCollection",features:s}}(o,n,r,b,t).then(e=>{!t.aborted&&e&&m(e)}).finally(()=>{t.aborted||g(!1)}),()=>{t.aborted=!0}},[y,b]),e.useEffect(()=>{if(!c)return;const e=()=>{var e,t;try{const o=c.getLayer(Jo),n=c.getSource(Go);if(r&&d&&d.features.length>0){if(n?c.getSource(Go).setData(d):c.addSource(Go,{type:"geojson",data:d}),!o){const o=c.getLayer("topology-weak-edges-native"),n=null==(t=null==(e=c.getStyle())?void 0:e.layers)?void 0:t.find(e=>"symbol"===e.type),r=o?"topology-weak-edges-native":null==n?void 0:n.id;c.addLayer({id:Jo,type:"fill",source:Go,paint:{"fill-color":["get","color"],"fill-opacity":a}},r)}}else o&&c.removeLayer(Jo),n&&c.removeSource(Go)}catch(o){console.warn("[WardrivingHexLayerMapLibre] Layer update error:",o)}};c.isStyleLoaded()?e():c.once("style.load",e)},[c,r,d,s]),e.useEffect(()=>{if(c&&r)try{c.getLayer(Jo)&&c.setPaintProperty(Jo,"fill-opacity",a)}catch{}},[c,a,r]),e.useEffect(()=>()=>{if(c)try{c.getLayer(Jo)&&c.removeLayer(Jo),c.getSource(Go)&&c.removeSource(Go)}catch{}},[c]);const v=(null==d?void 0:d.features.length)??0;return v>0&&r?t.jsx("div",{"data-testid":"wardriving-hexlayer-maplibre-active","data-point-count":(null==o?void 0:o.length)||0,"data-cell-count":v,"data-terrain-enabled":s,"data-is-processing":h,style:{display:"none"}}):null}const on="https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",nn="terrarium",rn="terrain-dem",sn="hillshade-dem",an="terrain-hillshade";function ln({enabled:t,exaggeration:o=4}){const{current:r}=n(),[s,a]=e.useState(null),i=e.useRef(null);return e.useEffect(()=>{const e=()=>{var e;const t=null==(e=null==r?void 0:r.getMap)?void 0:e.call(r);t&&!s&&a(t)};e();const t=setInterval(e,50),o=setTimeout(()=>clearInterval(t),5e3);return()=>{clearInterval(t),clearTimeout(o)}},[r,s]),e.useEffect(()=>{if(!s)return;let e=!0;const t=()=>{var t,o;if(e)try{if(s.getSource(sn)||s.addSource(sn,{type:"raster-dem",tiles:[on],encoding:nn,tileSize:256,maxzoom:14}),!s.getLayer(an)){const e=null==(o=null==(t=s.getStyle())?void 0:t.layers)?void 0:o.find(e=>"symbol"===e.type);s.addLayer({id:an,type:"hillshade",source:sn,paint:{"hillshade-shadow-color":"rgba(10, 10, 10, 0.6)","hillshade-highlight-color":"rgba(245, 240, 230, 0.4)","hillshade-accent-color":"rgba(90, 75, 65, 0.3)","hillshade-illumination-direction":315,"hillshade-exaggeration":.35}},null==e?void 0:e.id)}s.getSource(rn)||s.addSource(rn,{type:"raster-dem",tiles:[on],encoding:nn,tileSize:256,maxzoom:14})}catch(n){console.error("[TerrainLayer] Source/layer setup error:",n)}};return s.isStyleLoaded()?t():(s.once("style.load",t),s.once("load",()=>{e&&!s.getSource(sn)&&t()})),()=>{e=!1}},[s]),e.useEffect(()=>{if(!s)return;let e=!0,n=!1;const r=()=>{if(e&&s.getSource(rn))try{t?(s.setCenterClampedToGround(!1),s.setTerrain({source:rn,exaggeration:o}),s.setMaxPitch(70),!n&&s.getPitch()<30&&!s.isMoving()&&(n=!0,null!==i.current&&clearTimeout(i.current),i.current=window.setTimeout(()=>{i.current=null,e&&!s.isMoving()&&s.getPitch()<30&&s.easeTo({pitch:45,duration:1e3})},200))):(s.setTerrain(null),s.setCenterClampedToGround(!0),s.getPitch()>0&&!s.isMoving()&&s.easeTo({pitch:0,duration:800}),s.setMaxPitch(60))}catch(r){console.error("[TerrainLayer] Terrain state error:",r)}};if(s.isStyleLoaded()&&s.getSource(rn))r();else{const e=()=>{s.getSource(rn)&&r()};s.once("idle",e)}return()=>{e=!1,null!==i.current&&(clearTimeout(i.current),i.current=null)}},[s,t,o]),e.useEffect(()=>()=>{var e;try{(null==(e=null==s?void 0:s.getStyle)?void 0:e.call(s))&&s.isStyleLoaded()&&(s.setTerrain(null),s.getLayer(an)&&s.removeLayer(an),s.getSource(sn)&&s.removeSource(sn),s.getSource(rn)&&s.removeSource(rn))}catch{}},[s]),null}const cn=.03,un=.1,dn=2;function mn(e,t=3){if(e.length<3||t<=0)return e;let o=e;for(let n=0;n0&&e.push([e[0][0],e[0][1]]),o=e}return o}function hn(e,t={}){const o=function(e,t={}){if(e.length<3)return{coordinates:[],valid:!1};const{bandwidth:o=cn,threshold:n=un,cellSize:r=dn}=t,s=function(e,t){let o=1/0,n=-1/0,r=1/0,s=-1/0;for(const[a,i]of e)an&&(n=a),is&&(s=i);return o-=t,n+=t,r-=t,s+=t,{minX:o,minY:r,maxX:n,maxY:s,width:n-o,height:s-r}}(e,.02),a=Math.ceil(s.width/(o/2)),i=Math.ceil(s.height/(o/2)),l=Math.min(1,200/Math.max(a,i)),c=Math.max(10,Math.ceil(a*l)),u=Math.max(10,Math.ceil(i*l)),d=e=>e/c*s.width+s.minX,m=e=>e/u*s.height+s.minY,h=o/s.width*c;try{const t=gt().x(e=>(e[0]-s.minX)/s.width*c).y(e=>(e[1]-s.minY)/s.height*u).size([c,u]).bandwidth(Math.max(5,h)).cellSize(r)(e);if(0===t.length)return{coordinates:[],valid:!1};const o=Math.max(...t.map(e=>e.value))*n;let a=t[0],i=1/0;for(const e of t){const t=Math.abs(e.value-o);t0){const t=e[0],o=e[e.length-1];t[0]===o[0]&&t[1]===o[1]||e.push([t[0],t[1]])}if(e.length>=4){const o=mn(e);t.push(o)}}t.length>0&&l.push(t)}const g=[];for(const e of l)for(const t of e)g.push(t);return{coordinates:l,valid:l.length>0}}catch(g){return console.warn("[KDE Contour] Failed to generate contour:",g),{coordinates:[],valid:!1}}}(e,t);return o.valid&&0!==o.coordinates.length?1===o.coordinates.length?{type:"Polygon",coordinates:o.coordinates[0]}:{type:"MultiPolygon",coordinates:o.coordinates}:null}function gn(e,t,o){return(t[0]-e[0])*(o[1]-e[1])-(t[1]-e[1])*(o[0]-e[0])}function pn(e,t,o,n,r){const s=r*r,a=s*r;return[.5*(2*t[0]+(-e[0]+o[0])*r+(2*e[0]-5*t[0]+4*o[0]-n[0])*s+(-e[0]+3*t[0]-3*o[0]+n[0])*a),.5*(2*t[1]+(-e[1]+o[1])*r+(2*e[1]-5*t[1]+4*o[1]-n[1])*s+(-e[1]+3*t[1]-3*o[1]+n[1])*a)]}function fn(e){let t=function(e){if(e.length<3)return e;const t=[...e].sort((e,t)=>e[0]-t[0]||e[1]-t[1]),o=[];for(const r of t){for(;o.length>=2&&gn(o[o.length-2],o[o.length-1],r)<=0;)o.pop();o.push(r)}const n=[];for(let r=t.length-1;r>=0;r--){const e=t[r];for(;n.length>=2&&gn(n[n.length-2],n[n.length-1],e)<=0;)n.pop();n.push(e)}return o.pop(),n.pop(),o.concat(n)}(e);if(t.length<3)return null;t=function(e){if(e.length<3)return e;let t=0,o=0;for(const[n,r]of e)t+=n,o+=r;return t/=e.length,o/=e.length,e.map(([e,n])=>{const r=e-t,s=n-o,a=Math.sqrt(r*r+s*s);if(a<1e-4)return[e,n];const i=(a+.008)/a;return[t+r*i,o+s*i]})}(t);const o=function(e){if(e.length<3)return e;const t=[],o=e.length;for(let n=0;no?function(e,t,o,n){const r=[];for(const[s,a]of e.communities){const e=[];for(const o of a){const n=t.get(o);n&&e.push([n[1],n[0]])}if(e.length<3)continue;let i=hn(e,{bandwidth:o,threshold:n});i||(i=fn(e)),i&&r.push({type:"Feature",properties:{community:s,color:ie(s),borderColor:ae(s),nodeCount:a.length},geometry:i})}return{type:"FeatureCollection",features:r}}(o,n,l,c):{type:"FeatureCollection",features:[]},[o,n,l,c]),m=a?i:0,h={"fill-color":["get","color"],"fill-opacity":m},g={"line-color":["get","borderColor"],"line-width":u,"line-opacity":m};return t.jsxs(r,{id:"mincut-partition",type:"geojson",data:d,children:[t.jsx(s,{id:"mincut-partition-fill",type:"fill",paint:h}),t.jsx(s,{id:"mincut-partition-stroke",type:"line",paint:g})]})}function yn(e,t=!1,o=!1,n=!1,r=.7,s){const a=j(s);return n?r>=.75?a.restBright:a.rest:r>=.85?a.rest:a.restDim}function bn(e){return[e[1],e[0]]}function vn(e,t,o,n=12){const[r,s]=e,[a,i]=t,l=[];for(let c=0;c<=n;c++){const e=c/n,t=s+(i-s)*e,u=r+(a-r)*e,d=4*o*e*(1-e);l.push([t,u,d])}return l}function jn(e,t,o,n,r,s,a,i,l,c,u,d="dark"){const m=Tt(),h=[];let g=1/0,p=-1/0;const f=[];for(const y of e){const e=.7*(y.edge.avgConfidence??(t?.7:.5))+y.edge.certainCount/Math.max(a,1)*.3+(t?.5:0);f.push({polyline:y,brightnessScore:e}),g=Math.min(g,e),p=Math.max(p,e)}if(0===f.length)return{type:"FeatureCollection",features:[]};const x=p-g||1;f.sort((e,t)=>e.brightnessScore-t.brightnessScore);for(const{polyline:y,brightnessScore:b}of f){const{from:e,to:a,edge:p}=y,f=o.get(p.key)??0;if(f<=0)continue;const v=i.has(p.key),j=l.has(p.key),w=p.avgConfidence??(t?.7:.5),N=c===p.key,C=u[p.fromHash],k=u[p.toHash],M=(null==C?void 0:C.node_name)||(null==C?void 0:C.name)||p.fromHash.slice(0,8),S=(null==k?void 0:k.node_name)||(null==k?void 0:k.name)||p.toHash.slice(0,8),F=[e[0]+(a[0]-e[0])*f,e[1]+(a[1]-e[1])*f];let R,T,L,E;if(t){const e=s.get(p.key)??Mt(p.certainCount),t=r.get(p.key)??e;R=t+(e-t)*n,N?R=Math.max(1.6*R,4.5):j&&(R*=1.3)}else R=1.5;if(T=N?m.edges.highlight:yn(0,p.isDirectPathEdge??!1,v,j,w,d),L=N?m.edges.highlight:p.isDirectPathEdge?m.edges.hoverDirect:v?m.edges.hoverLoop:m.edges.hoverStandard,t){const e=Math.min(1.5*f,1)*m.edgeOpacity;E=j?1.15*e:e}else E=(.3+.3*w)*f;N&&(E=.95);const B=(b-g)/x;h.push({type:"Feature",properties:{key:p.key,baseColor:T,hoverColor:L,baseWidth:R,baseOpacity:E,brightnessScore:B,isLoopEdge:v,isBackbone:j,isDirectPath:p.isDirectPathEdge??!1,isHubConnection:p.isHubConnection??!1,isZeroHop:p.isZeroHop??!1,isValidated:t,certainCount:p.certainCount,confidence:w,symmetryRatio:p.symmetryRatio??1,dominantDirection:p.dominantDirection??"balanced",fromName:M,toName:S,fromHash:p.fromHash,toHash:p.toHash},geometry:{type:"LineString",coordinates:[bn(e),bn(F)]}})}return{type:"FeatureCollection",features:h}}function wn(e,t){const o=Tt(),n=[];let r=0;for(const s of e){const e=t.get(s.hash);e&&e.blendedScore>r&&(r=e.blendedScore)}for(const s of e){const{from:e,to:a,hash:i,neighbor:l,lastHopData:c}=s,u=`neighbor-${i}`,d=(null==c?void 0:c.avgRssi)??l.rssi??null,m=(null==c?void 0:c.avgSnr)??l.snr??null,h=(null==c?void 0:c.count)??0,g=(null==c?void 0:c.confidence)??1,p=t.get(i),f=(null==p?void 0:p.listenerScore)??0,x=(null==p?void 0:p.loudScore)??0,y=(null==p?void 0:p.blendedScore)??0,b=r>0?y/r:0,v=s.rxAdvertCount??0,j=s.txProxyCount??0,w=v+j,N=w>0?(j-v)/w:0,C=vn(e,a,150,8);n.push({type:"Feature",properties:{key:u,hash:i,name:l.node_name||l.name||i.slice(0,8),prefix:i.slice(2,4).toUpperCase(),color:o.neighborColor,width:2.5,opacity:.85,rssi:d,snr:m,packetCount:h,confidence:g,hasAvgRssi:void 0!==(null==c?void 0:c.avgRssi),hasAvgSnr:void 0!==(null==c?void 0:c.avgSnr),isNeighborEdge:!0,listenerScore:f,loudScore:x,blendedScore:y,trafficWeight:b,linkAsymmetry:N,rxAdvertCount:v,txProxyCount:j},geometry:{type:"LineString",coordinates:C}})}return{type:"FeatureCollection",features:n}}function Nn(e,t){if(e<240)return.5;if(e<480)return 1;const o=(e-480)/(t-480);return Math.max(0,.33*(1-o))}function Cn(e,t,o){const n=o?_(o):null,r=[];for(const s of e){if(n&&s.toUpperCase()===n){o&&r.push(o);continue}const e=t.get(s.toUpperCase());e&&r.push(e)}return r}const kn="edge-blink-source",Mn="edge-blink-layer",Sn=1e3,Fn=1e3,Rn=y.teal,Tn="node-markers-layer";function Ln(e){return e<0||e>=Sn?0:1-e/Sn}function En(e){if(e<0)return 0;if(e>=Fn)return 0;const t=e/Fn;return Math.pow(1-t,3)}function Bn(e){return[e[1],e[0]]}const Dn=[{target:"Sparklines",fn:"sparklines",minStage:2}];u(Dn);const Hn=e.memo(function({nodeHash:e,width:o=60,height:n=20,color:r,showArea:s=!0,showTooltip:a=!1,className:i=""}){c(Dn);const l=K(e),u=V(),d=!Z().backgroundLoadComplete||u,m="number"==typeof o?o:60;return t.jsx(Nt,{data:l,width:m,height:n,color:r,isLoading:d,className:i})});function $n(e){const t=new Date(1e3*e);return`${(t.getMonth()+1).toString().padStart(2,"0")}/${t.getDate().toString().padStart(2,"0")}`}function An({txDelayRec:o,onRemove:n}){const[r,s]=e.useState(!1),a=o.floodFactor??o.txDelayFactor,i=o.directFactor??o.directTxDelayFactor;return t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsxs("button",{onClick:async()=>{const e=`set txdelay ${a.toFixed(1)}\nset direct.txdelay ${i.toFixed(1)}`;try{await navigator.clipboard.writeText(e),s(!0),setTimeout(()=>s(!1),1500)}catch(t){const o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select();try{document.execCommand("copy"),s(!0),setTimeout(()=>s(!1),1500)}catch{console.error("Failed to copy")}document.body.removeChild(o)}},className:"flex items-center gap-2 flex-1 py-1 px-1.5 bg-sys-amber/5 hover:bg-sys-amber/10 rounded transition-colors group",title:"Click to copy CLI commands",children:[t.jsx(ot,{className:"w-3 h-3 text-sys-amber shrink-0"}),t.jsx("span",{className:"text-fg-muted",children:"TxDelay"}),t.jsxs("div",{className:"flex gap-2",children:[t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"text-fg-muted",children:"F"}),t.jsxs("span",{className:"data-box data-box-compact text-sys-amber",children:["×",a.toFixed(1)]})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("span",{className:"text-fg-muted",children:"D"}),t.jsxs("span",{className:"data-box data-box-compact text-sys-amber",children:["×",i.toFixed(1)]})]})]}),r?t.jsx(Ue,{className:"w-3 h-3 text-sys-green ml-auto"}):t.jsx(Ye,{className:"w-3 h-3 text-fg-muted opacity-0 group-hover:opacity-100 transition-opacity ml-auto"})]}),n&&t.jsx("button",{onClick:n,className:"p-1 text-fg-secondary hover:text-sys-red hover:bg-sys-red/10 rounded transition-colors",title:"Remove from contacts",children:t.jsx(ze,{className:"w-3.5 h-3.5"})})]})}function Pn({hash:o,hashPrefix:n,name:r,isHub:s,isGateway:a,isBackbone:i,isZeroHop:l,isMobile:c,isRoomServer:u,isStale:d,lastSeenTimestamp:m,centrality:h,affinity:g,meanSnr:p,meanRssi:f,neighbor:x,onRemove:y,txDelayRec:b}){const[v,j]=e.useState(!1),w=l?"Direct":(null==g?void 0:g.typicalHopPosition)?`${g.typicalHopPosition}-hop`:null,N=b&&!b.insufficientData;return t.jsxs("div",{className:"w-[240px] pr-2",children:[t.jsx("div",{className:"text-[14px] font-semibold text-fg-primary leading-tight truncate mb-1",children:r}),t.jsxs("div",{className:"flex items-center gap-1 flex-wrap mb-1.5",children:[t.jsx("code",{className:"type-data-xs text-fg-secondary bg-data-box-bg border border-data-box-border px-1 py-0.5 rounded",children:n}),t.jsx("button",{onClick:async()=>{try{await navigator.clipboard.writeText(o),j(!0),setTimeout(()=>j(!1),1500)}catch(e){console.error("Failed to copy hash:",e);const t=document.createElement("textarea");t.value=o,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();try{document.execCommand("copy"),j(!0),setTimeout(()=>j(!1),1500)}catch{console.error("Fallback copy also failed")}document.body.removeChild(t)}},className:"p-0.5 hover:bg-subtle-fill-hover rounded transition-colors",title:"Copy full hash",children:v?t.jsx(Ue,{className:"w-3 h-3 text-sys-green"}):t.jsx(Ye,{className:"w-3 h-3 text-fg-secondary"})}),t.jsx(Ct,{hash:o,size:"sm"}),w&&t.jsx(G,{color:l?bt.direct:bt.multihop,compact:!0,children:w}),x.is_repeater&&t.jsx(G,{color:vt.repeater,compact:!0,children:"Rptr"}),s&&t.jsx(G,{color:vt.hub,compact:!0,title:"Hub: ≥10% of last-hop traffic",children:"Hub"}),a&&!s&&t.jsx(G,{color:vt.gateway,compact:!0,title:"Gateway: 7-10% of last-hop traffic",children:"Gate"}),i&&t.jsx(G,{color:vt.backbone,compact:!0,title:"Backbone",children:"Bone"}),c&&t.jsx(G,{color:vt.mobile,compact:!0,children:"Mobile"}),u&&t.jsx(G,{color:vt.room,compact:!0,children:"Room"}),d&&m&&t.jsxs(G,{compact:!0,title:"Neighbor not heard in 7+ days",children:["Idle ",$n(m)]})]}),t.jsxs("div",{className:"flex items-center gap-2 text-xs text-fg-secondary mb-1.5",children:[t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(Ke,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsx("span",{className:"font-mono",children:$(x.last_seen)})]}),(null==g?void 0:g.distanceMeters)&&t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(et,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsx("span",{className:"font-mono font-semibold text-fg-primary",children:(C=g.distanceMeters,null===C?"—":C<1e3?`${Math.round(C)}m`:`${(C/1e3).toFixed(1)}km`)})]}),x.latitude&&x.longitude&&0!==x.latitude&&0!==x.longitude&&t.jsxs("span",{className:"flex items-center gap-0.5",children:[t.jsx(tt,{className:"w-3 h-3 text-fg-muted shrink-0"}),t.jsxs("span",{className:"font-mono text-fg-muted",children:[x.latitude.toFixed(2),", ",x.longitude.toFixed(2)]})]})]}),t.jsx("div",{className:"mb-1.5",style:{width:224},children:t.jsx(Hn,{nodeHash:o,width:224,height:26,showArea:!0,showTooltip:!0})}),t.jsxs("div",{className:"flex gap-3 text-xs mb-1.5",children:[t.jsxs("div",{className:"flex-1 space-y-1",children:[t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Packets"}),t.jsx("span",{className:"data-box data-box-compact",children:(null==g?void 0:g.frequency)||0})]}),l&&void 0!==p&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"SNR"}),t.jsxs("span",{className:"data-box data-box-compact",children:[p.toFixed(1)," dB"]})]}),N&&b.networkRole&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Role"}),t.jsx(G,{color:jt[b.networkRole],compact:!0,title:{hub:"Hub: High-connectivity node that bridges many paths",backbone:"Backbone: Critical relay with high traffic",relay:"Relay: Standard forwarding node",edge:"Edge: Peripheral node"}[b.networkRole],children:b.networkRole})]})]}),t.jsxs("div",{className:"flex-1 space-y-1",children:[t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Adverts"}),t.jsx("span",{className:"data-box data-box-compact",children:x.advert_count||0})]}),l&&void 0!==f&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"RSSI"}),t.jsxs("span",{className:"data-box data-box-compact",children:[Math.round(f)," dBm"]})]}),N&&b.dataConfidence&&t.jsxs("div",{className:"flex justify-between items-center gap-2",children:[t.jsx("span",{className:"text-fg-muted",children:"Data"}),t.jsx(G,{color:wt[b.dataConfidence],compact:!0,title:{high:"1000+ packets",medium:"500-999 packets",low:"100-499 packets",insufficient:"Insufficient data"}[b.dataConfidence],children:b.dataConfidence})]})]}),!N&&y&&t.jsx("button",{onClick:y,className:"p-1 self-start text-fg-secondary hover:text-sys-red hover:bg-sys-red/10 rounded transition-colors",title:"Remove from contacts",children:t.jsx(ze,{className:"w-3.5 h-3.5"})})]}),N&&t.jsx(An,{txDelayRec:b,onRemove:y})]});var C}const zn="node-markers-native",In="node-markers-layer",qn="node-markers-layer-local",On="marker-standard",Wn="marker-standard-neighbor",_n="marker-hub",Un="marker-hub-neighbor",Kn="marker-gateway",Vn="marker-gateway-neighbor",Zn="marker-mobile",Gn="marker-mobile-neighbor",Jn="marker-room-server",Yn="marker-room-server-neighbor",Qn="marker-local",Xn="marker-stale-5day",er="marker-stale-10day",tr="marker-blink-black",or="marker-blink-black-local",nr="marker-blink",rr="marker-blink-local",sr={tier1:b[500],tier2:b[700]};function ar(e){if(!e)return 0;const t=(Date.now()-1e3*e)/864e5;return t>=10?2:t>=5?1:0}function ir(e){var t;const o=null==(t=e.contact_type)?void 0:t.toLowerCase();return"room server"===o||"room_server"===o||"room"===o||"server"===o}function lr(e){return e.startsWith("0x")?e.slice(2,4).toUpperCase():e.slice(0,2).toUpperCase()}function cr({neighborsWithLocation:o,localNode:i,localHash:l,zeroHopNeighbors:c,lastHopNeighborMap:u,meshTopology:d,hoveredMarker:m,onMarkerHover:h,getNodeOpacity:g,shouldShowNode:p,onRequestRemove:f,openPopupId:x,onOpenPopup:y,onClosePopup:b,onNodeClick:j,blinkingNodes:w}){const{current:N}=n(),C=e.useRef(!1),[k,M]=e.useState(!1);e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t)return;const o=()=>{try{!function(e){const t=v(),o=(e,t,o=0,n=!1)=>{const r=document.createElement("canvas");r.width=32,r.height=32;const s=r.getContext("2d",n?{colorSpace:"display-p3"}:void 0),a=14-o/2;return s.beginPath(),s.arc(16,16,a,0,2*Math.PI),s.fillStyle=e,s.fill(),t&&o>0&&(s.strokeStyle=t,s.lineWidth=2*o,s.stroke()),s.shadowColor="rgba(0,0,0,0.3)",s.shadowBlur=4,s.shadowOffsetY=2,{data:s.getImageData(0,0,32,32),pixelRatio:2}},n=(e,t=!1)=>{const o=document.createElement("canvas");o.width=48,o.height=48;const n=o.getContext("2d",t?{colorSpace:"display-p3"}:void 0),r=24*.35*2;return n.strokeStyle=e,n.lineWidth=5,n.lineCap="round",n.lineJoin="round",n.beginPath(),n.moveTo(24-r,24),n.lineTo(24,24-r),n.lineTo(40.8,24),n.stroke(),n.beginPath(),n.moveTo(24-.7*r,24),n.lineTo(24-.7*r,35.76),n.lineTo(35.76,35.76),n.lineTo(35.76,24),n.stroke(),n.beginPath(),n.moveTo(20.64,35.76),n.lineTo(20.64,27.36),n.lineTo(27.36,27.36),n.lineTo(27.36,35.76),n.stroke(),{data:n.getImageData(0,0,48,48),pixelRatio:2}},r=(e,t)=>{const o=document.createElement("canvas");o.width=48,o.height=48;const n=o.getContext("2d"),r=24*.35*2;return n.strokeStyle=e,n.lineWidth=5,n.lineCap="round",n.lineJoin="round",t&&(n.fillStyle=t),n.beginPath(),n.roundRect(24-r,24-.6*r,1.6*r,1.2*r,6),t&&n.fill(),n.stroke(),n.beginPath(),n.moveTo(18.96,34.08),n.lineTo(24-.6*r,40.8),n.lineTo(24,34.08),n.stroke(),{data:n.getImageData(0,0,48,48),pixelRatio:2}},s="#00FF00",a={[On]:o(t.nodeFill),[Wn]:o(t.neighborColor),[_n]:o(t.hubColor),[Un]:o(t.neighborColor),[Kn]:o(t.gatewayColor),[Vn]:o(t.neighborColor),[Zn]:o("transparent",t.mobileColor,2.5),[Gn]:o(t.neighborColor),[Jn]:r(t.roomColor),[Yn]:r(t.neighborColor,"#1a1a1c"),[Qn]:n(t.localColor),[Xn]:o(sr.tier1),[er]:o(sr.tier2),[tr]:o("#000000"),[or]:n("#000000"),[nr]:o(s,void 0,0,!0),[rr]:n(s,!0)};for(const[i,l]of Object.entries(a))try{e.hasImage(i)&&e.removeImage(i),e.addImage(i,l.data,{pixelRatio:l.pixelRatio})}catch{}}(t),C.current=!0,k||M(!0)}catch(e){console.warn("Failed to load node marker icons:",e)}};t.isStyleLoaded()?o():t.once("style.load",o);const n=()=>{t.hasImage(On)||o()};t.on("styledata",n);const r=()=>{C.current=!1,o()},s=new MutationObserver(e=>{for(const t of e)if("data-theme"===t.attributeName){setTimeout(r,100);break}});s.observe(document.documentElement,{attributes:!0});const a=document.querySelector("[data-basemap]");let i=null;return a&&(i=new MutationObserver(e=>{for(const t of e)if("data-basemap"===t.attributeName){setTimeout(r,100);break}}),i.observe(a,{attributes:!0})),()=>{t.off("styledata",n),s.disconnect(),null==i||i.disconnect()}},[N,k]);const S=e.useMemo(()=>{var e;const t=[],n=[...o].sort(([e,t],[o,n])=>{const r=(e,t)=>{var o;return ir(t)?5e3:c.has(e)?3e3:d.hubNodes.includes(e)?2e3:(null==(o=d.gatewayNodes)?void 0:o.includes(e))?1e3:0};return r(e,t)-r(o,n)});for(const[o,r]of n){if(!r.latitude||!r.longitude)continue;if(l&&((l.startsWith("0x")?l.slice(2,4).toLowerCase():l.slice(0,2).toLowerCase())===(o.startsWith("0x")?o.slice(2,4).toLowerCase():o.slice(0,2).toLowerCase())||o===l))continue;const n=p(o),s=g(o,n);if(s<=.01)continue;const a=c.has(o),i=d.hubNodes.includes(o),m=(null==(e=d.gatewayNodes)?void 0:e.includes(o))??!1,h=d.mobileNodes.includes(o),f=ir(r),x=d.centrality.get(o)||0,y=u.get(o),b=r.last_seen||(null==y?void 0:y.lastSeen),v=ar(b),j=v>0;let w=s;2===v?w=Math.min(s,.25):1===v&&(w=Math.min(s,.5));let N="standard";f?N="roomServer":i?N="hub":m?N="gateway":h&&(N="mobile");const C=d.fullAffinity.get(o),k=d.txDelayRecommendations.get(o);t.push({type:"Feature",geometry:{type:"Point",coordinates:[r.longitude,r.latitude]},properties:{hash:o,name:r.node_name||r.name||"Unknown",hashPrefix:lr(o),iconType:N,isNeighbor:a,isHub:i,isGateway:m,isMobile:h,isRoomServer:f,isStale:j,staleTier:v,isZeroHop:a,opacity:w,blinkIntensity:0,lastSeenTimestamp:b,centrality:x,neighborJson:JSON.stringify(r),affinityJson:C?JSON.stringify(C):void 0,txDelayRecJson:k?JSON.stringify(k):void 0,meanSnr:(null==y?void 0:y.avgSnr)??void 0,meanRssi:(null==y?void 0:y.avgRssi)??void 0}})}return{type:"FeatureCollection",features:t}},[o,l,c,u,d,g,p]),F=e.useMemo(()=>(null==i?void 0:i.latitude)&&(null==i?void 0:i.longitude)?{type:"FeatureCollection",features:[{type:"Feature",geometry:{type:"Point",coordinates:[i.longitude,i.latitude]},properties:{hash:"local",name:i.name,hashPrefix:l?lr(l):"",iconType:"local",isNeighbor:!1,isHub:!1,isGateway:!1,isMobile:!1,isRoomServer:!1,isStale:!1,staleTier:0,isZeroHop:!1,opacity:1,blinkIntensity:0,centrality:0}}]}:{type:"FeatureCollection",features:[]},[i,l]),R=e.useCallback(e=>{var t;if(!e.features||0===e.features.length)return;const o=null==(t=e.features[0].properties)?void 0:t.hash;o&&(y&&y(o),j&&"local"!==o&&j(o))},[y,j]),T=e.useCallback(e=>{var t,o;if(!e.features||0===e.features.length)return;const n=null==(t=null==N?void 0:N.getMap)?void 0:t.call(N);n&&(n.getCanvas().style.cursor="pointer");const r=null==(o=e.features[0].properties)?void 0:o.hash;r&&h(r)},[N,h]),L=e.useCallback(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);t&&(t.getCanvas().style.cursor=""),h(null)},[N,h]);e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t||!k)return;const o=[In,qn];for(const n of o)t.on("click",n,R),t.on("mouseenter",n,T),t.on("mouseleave",n,L);return()=>{for(const e of o)t.off("click",e,R),t.off("mouseenter",e,T),t.off("mouseleave",e,L)}},[N,k,R,T,L]);const E=e.useRef(S),B=e.useRef(F);e.useEffect(()=>{E.current=S,B.current=F},[S,F]),e.useEffect(()=>{var e;const t=null==(e=null==N?void 0:N.getMap)?void 0:e.call(N);if(!t||!k||!w||0===w.size)return;const o=t.getSource(zn),n=t.getSource(`${zn}-local`);if(o||n){if(o){const e=E.current;let t=!1;const n=e.features.map(e=>{const o=w.get(e.properties.hash)??0;return o!==e.properties.blinkIntensity?(t=!0,{...e,properties:{...e.properties,blinkIntensity:o}}):e});t&&o.setData({type:"FeatureCollection",features:n})}if(n&&l){const e=w.get(l)??0,t=B.current;t.features.length>0&&t.features[0].properties.blinkIntensity!==e&&n.setData({type:"FeatureCollection",features:[{...t.features[0],properties:{...t.features[0].properties,blinkIntensity:e}}]})}}},[N,k,w,l]);const D=e.useMemo(()=>{if(!x)return null;if("local"===x&&i)return{longitude:i.longitude,latitude:i.latitude,isLocal:!0,name:i.name,hash:l};const e=S.features.find(e=>e.properties.hash===x);if(!e)return null;const t=e.properties,o=t.txDelayRecJson?JSON.parse(t.txDelayRecJson):void 0;return{longitude:e.geometry.coordinates[0],latitude:e.geometry.coordinates[1],isLocal:!1,hash:t.hash,hashPrefix:t.hashPrefix,name:t.name,isHub:t.isHub,isGateway:t.isGateway,isBackbone:"backbone"===(null==o?void 0:o.networkRole),isZeroHop:t.isZeroHop,isMobile:t.isMobile,isRoomServer:t.isRoomServer,isStale:t.isStale,lastSeenTimestamp:t.lastSeenTimestamp,centrality:t.centrality,neighbor:t.neighborJson?JSON.parse(t.neighborJson):void 0,affinity:t.affinityJson?JSON.parse(t.affinityJson):void 0,txDelayRec:o,meanSnr:t.meanSnr,meanRssi:t.meanRssi}},[x,i,l,S]);if(!k)return null;const H=v(),$=["case",[">",["get","blinkIntensity"],.66],nr,[">",["get","blinkIntensity"],.33],tr,["==",["get","staleTier"],2],er,["==",["get","staleTier"],1],Xn,["==",["get","iconType"],"roomServer"],["case",["get","isNeighbor"],Yn,Jn],["==",["get","iconType"],"hub"],["case",["get","isNeighbor"],Un,_n],["==",["get","iconType"],"gateway"],["case",["get","isNeighbor"],Vn,Kn],["==",["get","iconType"],"mobile"],["case",["get","isNeighbor"],Gn,Zn],["case",["get","isNeighbor"],Wn,On]],A=["interpolate",["linear"],["zoom"],6,.25,10,1];return t.jsxs(t.Fragment,{children:[t.jsx(r,{id:zn,type:"geojson",data:S,children:t.jsx(s,{id:In,type:"symbol",layout:{"icon-image":$,"icon-size":A,"icon-allow-overlap":!0,"icon-ignore-placement":!0,"symbol-sort-key":["get","opacity"]},paint:{"icon-opacity":["get","opacity"]}})}),t.jsx(r,{id:`${zn}-local`,type:"geojson",data:F,children:t.jsx(s,{id:qn,type:"symbol",layout:{"icon-image":["case",[">",["get","blinkIntensity"],.66],rr,[">",["get","blinkIntensity"],.33],or,Qn],"icon-size":A,"icon-allow-overlap":!0,"icon-ignore-placement":!0},paint:{"icon-opacity":1}})}),D&&b&&t.jsx(a,{longitude:D.longitude,latitude:D.latitude,offset:{center:[0,0],top:[0,12],"top-left":[6,12],"top-right":[-6,12],bottom:[0,-12],"bottom-left":[6,-12],"bottom-right":[-6,-12],left:[12,0],right:[-12,0]},maxWidth:"280px",closeOnClick:!0,onClose:b,className:"maplibre-popup",children:D.isLocal?t.jsxs("div",{className:"text-sm",children:[t.jsx("strong",{className:"text-base",children:D.name}),D.hash&&t.jsx("span",{className:"ml-2 font-mono text-xs text-fg-muted surface-badge px-1.5 py-0.5 rounded",children:lr(D.hash)}),t.jsx("br",{}),t.jsx("span",{style:{color:H.localColor},className:"font-medium",children:"This Node (Local)"}),t.jsx("br",{}),i&&t.jsxs("span",{className:"text-xs text-fg-muted",children:[i.latitude.toFixed(5),", ",i.longitude.toFixed(5)]})]}):D.neighbor&&D.hash?t.jsx(Pn,{hash:D.hash,hashPrefix:D.hashPrefix,name:D.name,isHub:D.isHub,isGateway:D.isGateway,isBackbone:D.isBackbone,isZeroHop:D.isZeroHop,isMobile:D.isMobile,isRoomServer:D.isRoomServer,isStale:D.isStale,lastSeenTimestamp:D.lastSeenTimestamp,centrality:D.centrality,affinity:D.affinity,meanSnr:D.meanSnr,meanRssi:D.meanRssi,neighbor:D.neighbor,txDelayRec:D.txDelayRec,onRemove:f?()=>f(D.hash,D.name):void 0}):null})]})}const ur=[In,qn],dr="topology-validated-edges-native",mr="topology-weak-edges-native",hr="neighbor-edges-native",gr="topology-weak-edges-native",pr="topology-validated-edges-native",fr="neighbor-edges-native",xr={type:"FeatureCollection",features:[]},yr={"line-cap":"round","line-join":"round"},br={"line-color":"transparent","line-width":16,"line-opacity":0};function vr({showTopology:o,isExiting:a,hoveredEdgeKey:i,highlightedLoopEdges:l,highlightedFocusEdges:c,onEdgeHover:u,onLoopHover:d,loops:m=[],neighborNames:h={},opacityBias:p=.5,widthMultiplier:f=1,trafficFilter:x=0,showNeighborLines:y=!0,disableHover:b=!1}){const{current:v}=n(),j=o||a,w=!0,N=y?"visible":"none",C=b||a,k=e.useRef(null),M=e.useRef(C),S=e.useRef(new Map),F=e.useRef(h),R=e.useRef(d);e.useLayoutEffect(()=>{M.current=C,F.current=h,R.current=d});const T=e.useMemo(()=>function(e){const t=new Map;for(const o of e)for(const e of o.edgeKeys){const n=t.get(e)??[];n.push(o),t.set(e,n)}return t}(m),[m]);e.useLayoutEffect(()=>{S.current=T},[T]);const L=e.useCallback(e=>{var t,o;if(M.current)return;if(!e.features||0===e.features.length)return;const n=e.features[0].properties;if(!(null==n?void 0:n.key))return;const r=n.key;if(r!==k.current){k.current=r;const s=!0===n.isNeighborEdge||"true"===n.isNeighborEdge,a=!0===n.isLoopEdge||"true"===n.isLoopEdge;if(s){const o={key:r,fromName:"Local",toName:n.name,certainCount:Number(n.packetCount)||0,confidence:1,isBackbone:!1,isLoopEdge:!1,isDirectPath:!0,isZeroHop:!0,symmetryRatio:1,dominantDirection:"balanced",isHubConnection:!1};u(r,[e.lngLat.lng,e.lngLat.lat],o),null==(t=R.current)||t.call(R,null)}else if(a&&R.current){const t=S.current.get(r)??[];if(t.length>0){const o=new Set;for(const e of t)for(const t of e.edgeKeys)o.add(t);const n={loops:t,highlightedEdgeKeys:o,hoveredEdgeKey:r,nodeNames:t[0].nodes.map(e=>F.current[e]||e.substring(0,4))};R.current(n,[e.lngLat.lng,e.lngLat.lat]),u(r)}else{const t={key:r,fromName:n.fromName,toName:n.toName,certainCount:Number(n.certainCount),confidence:Number(n.confidence),isBackbone:!0===n.isBackbone||"true"===n.isBackbone,isLoopEdge:!0,isDirectPath:!0===n.isDirectPath||"true"===n.isDirectPath,isZeroHop:!0===n.isZeroHop||"true"===n.isZeroHop,symmetryRatio:Number(n.symmetryRatio),dominantDirection:n.dominantDirection,isHubConnection:!0===n.isHubConnection||"true"===n.isHubConnection};u(r,[e.lngLat.lng,e.lngLat.lat],t)}}else{const t={key:r,fromName:n.fromName,toName:n.toName,certainCount:Number(n.certainCount),confidence:Number(n.confidence),isBackbone:!0===n.isBackbone||"true"===n.isBackbone,isLoopEdge:a,isDirectPath:!0===n.isDirectPath||"true"===n.isDirectPath,isZeroHop:!0===n.isZeroHop||"true"===n.isZeroHop,symmetryRatio:Number(n.symmetryRatio),dominantDirection:n.dominantDirection,isHubConnection:!0===n.isHubConnection||"true"===n.isHubConnection};u(r,[e.lngLat.lng,e.lngLat.lat],t),null==(o=R.current)||o.call(R,null)}}},[u]),E=e.useCallback(()=>{var e;null!==k.current&&(k.current=null,u(null),null==(e=R.current)||e.call(R,null))},[u]);e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t||!j)return;const o="topology-validated-edges-hitarea-native",n=()=>{try{return t.getStyle()&&t.getLayer(o)}catch{return!1}},r=()=>!!n()&&(t.on("mousemove",o,L),t.on("mouseleave",o,E),!0);if(!r()){const e=()=>{r()&&t.off("styledata",e)};return t.on("styledata",e),()=>{try{t.off("styledata",e),n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}}return()=>{try{n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}},[v,j,L,E]),e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t||!y)return;const o="neighbor-edges-hitarea-native",n=()=>{try{return t.getStyle()&&t.getLayer(o)}catch{return!1}},r=()=>!!n()&&(t.on("mousemove",o,L),t.on("mouseleave",o,E),!0);if(!r()){const e=()=>{r()&&t.off("styledata",e)};return t.on("styledata",e),()=>{try{t.off("styledata",e),n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}}return()=>{try{n()&&(t.off("mousemove",o,L),t.off("mouseleave",o,E))}catch{}}},[v,w,y,L,E]),e.useEffect(()=>{var e;const t=null==(e=null==v?void 0:v.getMap)?void 0:e.call(v);if(!t)return;let o=null;const n=(e,o)=>{try{if(t.getLayer(e)&&t.getLayer(o))return t.moveLayer(e,o),!0}catch{}return!1},r=()=>{try{if(!t.getLayer("node-markers-layer"))return;n(fr,"node-markers-layer"),n("neighbor-edges-hitarea-native",fr),(n(pr,"neighbor-edges-hitarea-native")||n(pr,"node-markers-layer"))&&n("topology-validated-edges-hitarea-native",pr),n(gr,"topology-validated-edges-hitarea-native")}catch{}},s=()=>{o&&clearTimeout(o),o=setTimeout(r,50)},a=setTimeout(r,100);t.on("styledata",s);const i=e=>{(e.sourceId===dr||e.sourceId===mr||e.sourceId===hr)&&s()};return t.on("sourcedata",i),()=>{clearTimeout(a),o&&clearTimeout(o);try{t.off("styledata",s),t.off("sourcedata",i)}catch{}}},[v,j,w,y]);const B=C?null:i,D=function(e,t,o,n,r,s){const a=Tt(),i=null!==e,l=r&&r.size>0,c=s&&s.size>0,u=l?Array.from(r):[],d=c?Array.from(s):[],m=t<=0?["get","baseColor"]:["case",[">=",["get","brightnessScore"],1-.5*t],"#FFFFFF",["get","baseColor"]],h=t<=0?1:["max",.1,["+",1,["*",t,3,["-",["get","brightnessScore"],.5]]]],g=l?["in",["get","key"],["literal",u]]:c?["in",["get","key"],["literal",d]]:!!i&&["==",["get","key"],e],p=i||l||c,f=a.edges.hoverLoop,x=a.edges.highlight;return{"line-color":p?["case",g,l?f:c?x:["get","hoverColor"],m]:m,"line-width":p?["case",g,["max",["*",["get","baseWidth"],o,1.3],3.5],["*",["get","baseWidth"],o]]:["*",["get","baseWidth"],o],"line-opacity":["case",["<",["get","brightnessScore"],n],0,p?["case",g,["min",["*",["get","baseOpacity"],1.25],1],["*",["get","baseOpacity"],h,.35]]:["*",["get","baseOpacity"],h]]}}(B,p,f,x,C?null:l,c??null),H=function(e){const t=null!==e,{YELLOW:o,GREEN:n,RED:r,GRAY:s}=g,a=["to-number",["get","listenerScore"],0],i=["to-number",["get","loudScore"],0],l=["/",a,["max",["+",a,i],1]],c=["*",["+",.2,["*",["to-number",["get","trafficWeight"],0],.8]],8];return{"line-color":["case",["all",["==",a,0],["==",i,0]],s,[">=",l,.97],n,["<=",l,.03],r,["interpolate",["linear"],l,.03,r,.5,o,.97,n]],"line-width":["interpolate",["linear"],["zoom"],6,t?["case",["==",["get","key"],e],["max",["*",c,.25],1.25],["*",c,.25]]:["*",c,.25],10,t?["case",["==",["get","key"],e],["max",c,5],c]:c],"line-opacity":t?["case",["==",["get","key"],e],1,.35]:.9}}(B);return t.jsxs(t.Fragment,{children:[j&&t.jsx(r,{id:mr,type:"geojson",data:xr,children:t.jsx(s,{id:gr,type:"line",paint:D,layout:{...yr,visibility:N}})}),j&&t.jsxs(r,{id:dr,type:"geojson",data:xr,children:[t.jsx(s,{id:"topology-validated-edges-hitarea-native",type:"line",paint:br,layout:{...yr,visibility:N}}),t.jsx(s,{id:pr,type:"line",paint:D,layout:{...yr,visibility:N}})]}),t.jsxs(r,{id:hr,type:"geojson",data:xr,children:[t.jsx(s,{id:"neighbor-edges-hitarea-native",type:"line",paint:br,layout:{...yr,visibility:N}}),t.jsx(s,{id:fr,type:"line",paint:H,layout:{...yr,visibility:N}})]})]})}const jr=["topology-validated-edges-hitarea-native","topology-validated-edges-native","topology-weak-edges-native","neighbor-edges-hitarea-native","neighbor-edges-native"];function wr({targetHash:t,nodeCoordinates:o,onComplete:r}){const{current:s}=n(),a=e.useRef(null);return e.useEffect(()=>{if(!s||!t||t===a.current)return;const e=o.get(t);if(!e)return;const n=s.getMap();n.isMoving()&&n.stop(),a.current=t;const[i,l]=e;s.flyTo({center:[l,i],zoom:10,duration:2500,essential:!0}),setTimeout(()=>{null==r||r()},2600)},[t,o,s,r]),null}function Nr({highlightedEdgeKey:t,validatedPolylines:o,weakPolylines:r,onEnsureTopology:s}){const{current:a}=n(),i=e.useRef(null);return e.useEffect(()=>{if(!a||!t)return;if(t===i.current)return;i.current=t,s();const e=o.find(e=>e.edge.key===t)||r.find(e=>e.edge.key===t);if(!e)return;if(a.getMap().isMoving())return;const n=(e.from[0]+e.to[0])/2,l=(e.from[1]+e.to[1])/2,c=a.getZoom(),u=Math.max(c,11);a.easeTo({center:[l,n],zoom:u,duration:500})},[t,o,r,a,s]),null}const Cr="link-quality-edges",kr="link-quality-edges-hitarea",Mr={type:"FeatureCollection",features:[]};function Sr(e,t){return eQ(),[]),g=e.useMemo(()=>o&&0!==u.length&&0!==d.size?function(e,t,o,n,r){const s=[];for(const a of e){if(o&&a.nodeA.hash!==o&&a.nodeB.hash!==o)continue;const e=t.get(a.nodeA.hash),i=t.get(a.nodeB.hash);if(!e||!i)continue;const l=n[X(a.composite.mean,r)]||"#888888",c=2+2*a.confidence,u=Sr(a.nodeA.hash,a.nodeB.hash);s.push({type:"Feature",geometry:{type:"LineString",coordinates:[[e[1],e[0]],[i[1],i[0]]]},properties:{key:u,color:l,width:c,quality:a.quality,compositeMeanSnr:a.composite.mean,confidence:a.confidence,fromHash:a.nodeA.hash,toHash:a.nodeB.hash,fromPrefix:a.nodeA.prefix,toPrefix:a.nodeB.prefix,fromName:a.nodeA.name||a.nodeA.prefix,toName:a.nodeB.name||a.nodeB.prefix,asymmetryDb:a.asymmetryDb}})}return{type:"FeatureCollection",features:s}}(u,a,i,h,m):Mr,[o,u,d.size,a,i,h,m]);e.useEffect(()=>{if(!c)return;const e=c.getMap();if(e)try{const t=e.getSource(Cr);t&&"setData"in t&&(t.setData(g),e.triggerRepaint())}catch{}},[g,c]);const p=o?"visible":"none";return t.jsxs(r,{id:Cr,type:"geojson",data:Mr,children:[t.jsx(s,{id:"link-quality-edges-layer",type:"line",layout:{...Fr,visibility:p},paint:Rr}),t.jsx(s,{id:kr,type:"line",layout:{...Fr,visibility:p},paint:Tr})]})}function Er(e,t,o,n=64){const r=[],s=o/6371e3*(180/Math.PI),a=s/Math.cos(t*Math.PI/180);for(let i=0;i<=n;i++){const o=i/n*2*Math.PI,l=e+a*Math.cos(o),c=t+s*Math.sin(o);r.push([l,c])}return{type:"Feature",properties:{},geometry:{type:"Polygon",coordinates:[r]}}}function Br({ghost:o,neighborCoordinates:a,onHighlightedNeighborsChange:i}){const{current:l}=n(),c=e.useRef(null),u=e.useRef(null),d=e.useMemo(()=>o?new Set(o.commonNeighbors):new Set,[o]);e.useEffect(()=>{null==i||i(d)},[d,i]);const m=e.useMemo(()=>{if(!(null==o?void 0:o.commonNeighbors)||o.commonNeighbors.length<2)return 8e3;let e=0;const t=[];for(const n of o.commonNeighbors){const e=a.get(n);e&&t.push(e)}o.estimatedLocation&&t.push([o.estimatedLocation.lat,o.estimatedLocation.lon]);for(let o=0;oe&&(e=r)}return Math.max(e,2e3)},[o,a]),h=e.useMemo(()=>{if(!(null==o?void 0:o.estimatedLocation))return{type:"FeatureCollection",features:[]};const{lat:e,lon:t,uncertaintyM:n}=o.estimatedLocation,r=.5*m,s=n>0?n:2e3;return{type:"FeatureCollection",features:[Er(t,e,Math.max(500,Math.min(s,r)))]}},[o,m]);if(e.useEffect(()=>{if(!l)return;const e=l.getMap();if(o&&o.prefix!==u.current){if(u.current=o.prefix,!c.current&&e.getZoom()>3){const t=e.getCenter();c.current={center:[t.lng,t.lat],zoom:e.getZoom(),pitch:e.getPitch(),bearing:e.getBearing()}}const t=[];for(const e of o.commonNeighbors){const o=a.get(e);o&&t.push([o[1],o[0]])}if(o.estimatedLocation&&t.push([o.estimatedLocation.lon,o.estimatedLocation.lat]),t.length>0){const n=()=>{var r;if(e.isMoving())setTimeout(n,100);else if(1===t.length)l.flyTo({center:t[0],zoom:13,duration:1500});else{let e=1/0,n=-1/0,s=1/0,a=-1/0;for(const[o,r]of t)e=Math.min(e,o),n=Math.max(n,o),s=Math.min(s,r),a=Math.max(a,r);if(null==(r=o.estimatedLocation)?void 0:r.uncertaintyM){const t=o.estimatedLocation.uncertaintyM/111e3;e-=t,n+=t,s-=t,a+=t}l.fitBounds([[e,s],[n,a]],{padding:{top:60,bottom:60,left:60,right:60},maxZoom:14,duration:1500})}};setTimeout(n,50)}}if(!o&&null!==u.current&&(u.current=null,c.current)){const t=c.current,o=()=>{e.isMoving()?setTimeout(o,100):(l.flyTo({center:t.center,zoom:t.zoom,pitch:t.pitch,bearing:t.bearing,duration:1e3}),c.current=null)};setTimeout(o,50)}},[o,l,a]),!(null==o?void 0:o.estimatedLocation))return null;return t.jsx(r,{id:"ghost-uncertainty-circle",type:"geojson",data:h,children:t.jsx(s,{id:"ghost-uncertainty-fill",type:"fill",paint:{"fill-color":"rgba(167, 139, 250, 0.15)","fill-opacity":.8}})})}const Dr=[{target:"Map",fn:"gps",minStage:1,when:d},{target:"Map",fn:"_advertNodeType",minStage:1,when:d},{target:"Topology",fn:"traceHops",minStage:1,when:m},{target:"Topology",fn:"path.entries",minStage:1,when:h},{target:"Topology",fn:"traceSrc",minStage:1,when:m}];u(Dr);const Hr={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"},$r={longitude:0,latitude:0,zoom:2};function Ar({data:e}){const o=e.subtitle&&"loop"===e.type,n=e.subtitle&&"loop"!==e.type;return t.jsxs("div",{className:"w-[540px]",children:[t.jsxs("div",{className:"flex items-center justify-between h-5",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.title.icon&&t.jsx("span",{className:`${e.title.color} text-base leading-none flex-shrink-0`,children:e.title.icon}),t.jsx("span",{className:`${e.title.color} font-semibold text-[13px] truncate`,children:e.title.text}),n&&t.jsx("span",{className:`${e.subtitle.color} text-[11px] flex-shrink-0`,children:e.subtitle.text})]}),e.badges.length>0&&t.jsx("div",{className:"flex items-center gap-2 flex-shrink-0 ml-3",children:e.badges.map((e,o)=>t.jsx("span",{className:`${e.color} text-[11px] font-medium`,children:e.text},o))})]}),o&&t.jsx("div",{className:"h-4 mt-0.5 overflow-hidden",children:t.jsx("span",{className:"type-data-xs text-fg-muted truncate block",children:e.subtitle.text})}),t.jsx("div",{className:`flex items-center gap-4 h-4 ${o?"mt-1":"mt-1.5"} text-[11px]`,children:e.stats.map((e,o)=>t.jsxs("span",{className:"whitespace-nowrap",children:[t.jsx("span",{className:`font-mono tabular-nums font-semibold ${e.color??"text-fg-primary"}`,children:e.value}),t.jsx("span",{className:"text-fg-muted ml-1",children:e.label}),e.unit&&t.jsx("span",{className:"text-fg-muted/50 ml-0.5",children:e.unit})]},o))})]})}function Pr({neighbors:o,localNode:n,localHash:r,onRemoveNode:s,selectedNodeHash:a,onNodeSelected:u,highlightedEdgeKey:d,highlightedGhost:m}){c(Dr);const h=e.useRef(null),g=ee(),f=te(),x=Z(),y=oe(),b=ne(),v=J(),[j,w]=e.useState(!1),N=lt(e=>e.viewState),C=lt(e=>e.toggles),k=lt(e=>e.hasAnalyzed),M=lt(e=>e.setViewState),S=lt(e=>e.setToggle),F=lt(e=>e.setHasAnalyzed),R=lt(e=>e.modalMapOpen),T=re(e=>e.preloadFromNodes),L=re(e=>e.isLoading),E=re(e=>e.terrainGrid),B=r??y,D=e.useMemo(()=>{const e=[];for(const[,t]of Object.entries(o))t.latitude&&t.longitude&&e.push([t.latitude,t.longitude]);return e},[o]),H=e.useMemo(()=>function(e,t){let o=[...e];if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&o.push([t.latitude,t.longitude]),0===o.length)return null;if(1===o.length){const[e,t]=o[0];return{longitude:t,latitude:e,zoom:14}}o=function(e,t){if(e.length<=2)return e;let o,n;if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude))o=t.latitude,n=t.longitude;else{let t=0,r=0;for(const[o,n]of e)t+=o,r+=n;o=t/e.length,n=r/e.length}const r=e.map(([e,t])=>{return{pos:[e,t],dist:(r=o,s=n,a=e,i=t,kt(r,s,a,i)/1e3)};var r,s,a,i});r.sort((e,t)=>e.dist-t.dist);const s=r[Math.floor(r.length/2)].dist,a=Math.max(3*s,50),i=r.filter(e=>e.dist<=a).map(e=>e.pos);return i.length<.5*e.length?e:i}(o,t);let n=1/0,r=-1/0,s=1/0,a=-1/0;for(const[h,g]of o)n=Math.min(n,g),r=Math.max(r,g),s=Math.min(s,h),a=Math.max(a,h);const i=(n+r)/2,l=(s+a)/2,c=a-s,u=r-n,d=Math.max(c,u);let m=16;return d>0&&(m=Math.floor(Math.log2(360/d*1.2)),m=Math.max(1,Math.min(14,m))),m=Math.min(m+1,12),{longitude:i,latitude:l,zoom:m}}(D,n),[D,n]),[$,A]=e.useState(()=>N??H??$r),P=e.useCallback(e=>{A(e),queueMicrotask(()=>M(e))},[M]),z=e.useRef(!!N);e.useEffect(()=>{z.current||!H||N?N&&setTimeout(()=>w(!0),50):(A(H),queueMicrotask(()=>M(H)),z.current=!0,setTimeout(()=>w(!0),50))},[H,N,M]);const[I,q]=e.useState(!1),[O,K]=e.useState(()=>!(C.showTopology&&!x.topologyLoadComplete)&&C.showTopology),[V,G]=e.useState(C.showNeighborLines),[Y,Q]=e.useState(!1),[X,ae]=e.useState(C.showMinCut),[ie,ue]=e.useState(To),[de,me]=e.useState(C.show3DTerrain),[he,ge]=e.useState(C.showLinkQuality),[pe,fe]=e.useState(()=>C.nodeFilters.length>0?C.nodeFilters:[...at]),xe=e.useCallback(e=>{K(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showTopology",o)),o})},[S]),ye=e.useCallback(e=>{G(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showNeighborLines",o)),o})},[S]),be=e.useCallback(e=>{ae(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showMinCut",o)),o})},[S]),ve=e.useCallback(e=>{me(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("show3DTerrain",o)),o})},[S]),je=e.useCallback(e=>{ge(t=>{const o="function"==typeof e?e(t):e;return queueMicrotask(()=>S("showLinkQuality",o)),o})},[S]),we=e.useCallback(e=>{fe(e),queueMicrotask(()=>S("nodeFilters",e))},[S]),[Ne,Ce]=e.useState(null),[ke,Me]=e.useState(null),[Se,Fe]=e.useState(null),[Re,Te]=e.useState(null),[Le]=e.useState(0),[Ee]=e.useState(.5),[Be]=e.useState(0),[De,He]=e.useState(null),[$e,Ae]=e.useState(""),[Pe,ze]=e.useState(!1),[Ie,qe]=e.useState(!1),[Oe,We]=e.useState(()=>!(k&&!x.topologyLoadComplete)&&k);e.useEffect(()=>{if(x.topologyLoadComplete)return;const e=k&&!Oe,t=C.showTopology&&!O;(e||t)&&queueMicrotask(()=>{e&&F(!1),t&&S("showTopology",!1)})},[k,C.showTopology,x.topologyLoadComplete,Oe,O,F,S]);const _e=e.useCallback(e=>{We(e),queueMicrotask(()=>F(e))},[F]),[Ue,Ke]=e.useState(null),Ve=e.useCallback(e=>Ke(e),[]),Ze=e.useCallback(()=>Ke(null),[]),[,Ge]=e.useState(new Set),Je=xo(e=>e.coveragePoints),Ye=xo(e=>e.isVisible),Qe=xo(e=>e.brightness),Xe=xo(e=>e.openModal),et=Zo(e=>e.isEnabled),tt=Zo(e=>e.toggle),ot=ct(),nt=ut(),rt=e.useRef(!1);e.useEffect(()=>{Je.length>0&&Ye&&!rt.current&&(ye(!1),rt.current=!0)},[Je.length,Ye]);const st=e.useRef(null);e.useEffect(()=>{if(a&&a!==st.current){st.current=a;const e=setTimeout(()=>{Ke(a)},1250);return()=>clearTimeout(e)}},[a]);const[it,mt]=e.useState(null),[ht,gt]=e.useState(null),bt=e.useCallback((e,t,o)=>{Me(e),e&&t&&o?mt({longitude:t[0],latitude:t[1],type:"topology",properties:{key:o.key,fromName:o.fromName,toName:o.toName,certainCount:o.certainCount,confidence:o.confidence,isBackbone:o.isBackbone,isLoopEdge:o.isLoopEdge,isDirectPath:o.isDirectPath,isHubConnection:o.isHubConnection,symmetryRatio:o.symmetryRatio,dominantDirection:o.dominantDirection}}):e||mt(null)},[]),vt=e.useCallback((e,t)=>{gt(e),e&&mt(null)},[]),jt=e.useMemo(()=>{var e;if(!O)return null;if(!Ne)return null;if(ke)return null;const t=g.loops;if(0===t.length)return null;const n=function(e,t,o){const n=function(e,t){return t.filter(t=>t.nodes.includes(e)).sort((e,t)=>t.avgCertainCount-e.avgCertainCount)}(e,t),r=new Set,s=[];for(const a of n)for(const e of a.edgeKeys)if(!r.has(e)){r.add(e);const t=o.get(e);s.push({key:e,certainCount:(null==t?void 0:t.certainCount)??0})}return s.sort((e,t)=>t.certainCount-e.certainCount),{loops:n,highlightedEdgeKeys:r,sortedEdges:s}}(Ne,t,g.edgeMap);if(0===n.loops.length)return null;const r=n.loops[0].nodes.map(e=>{var t,n;return e===B?"You":(null==(t=o[e])?void 0:t.node_name)||(null==(n=o[e])?void 0:n.name)||e.substring(0,4)});return{loops:n.loops,highlightedEdgeKeys:n.highlightedEdgeKeys,hoveredEdgeKey:(null==(e=n.sortedEdges[0])?void 0:e.key)||"",nodeNames:r}},[O,Ne,ke,g.loops,g.edgeMap,o,B]);e.useEffect(()=>{ke||gt(jt)},[jt,ke]);const wt=e.useMemo(()=>{const e={};for(const[t,n]of Object.entries(o))e[t]=n.node_name||n.name||t.substring(0,4);return B&&(e[B]="You"),e},[o,B]),Nt=e.useMemo(()=>{const e=new Map;for(const[t,n]of Object.entries(o)){const o=t.slice(0,2).toUpperCase(),r=n.node_name||n.name||o;e.set(o,r)}return B&&e.set(B.slice(0,2).toUpperCase(),"You"),e},[o,B]),Ct=e.useMemo(()=>Object.entries(o).filter(([,e])=>e.latitude&&e.longitude),[o]),Ft=e.useMemo(()=>{const e=new Map;B&&(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude)&&e.set(B,[n.latitude,n.longitude]);for(const[t,o]of Ct)o.latitude&&o.longitude&&e.set(t,[o.latitude,o.longitude]);return e},[B,n,Ct]),Rt=e.useMemo(()=>{const e=new Map;for(const t of f)"expired"!==t.status&&e.set(t.hash,{hash:t.hash,prefix:t.prefix,count:t.count,avgRssi:t.avgRssi,avgSnr:t.avgSnr,lastSeen:t.lastSeen,confidence:1,status:t.status});return e},[f]),Tt=e.useMemo(()=>{var e,t;const n=new Set;for(const r of Rt.keys())(null==(e=o[r])?void 0:e.latitude)&&(null==(t=o[r])?void 0:t.longitude)&&n.add(r);return n},[Rt,o]),Et=St(),Bt=e.useMemo(()=>{if(0===Tt.size||!B)return new Map;if(0===Et.length)return new Map;const e=_(B);return p(Et,Tt,e).scores},[Tt,B,Et]),Dt=e.useCallback(e=>!!(B&&(e.fromHash===B&&Tt.has(e.toHash)||e.toHash===B&&Tt.has(e.fromHash))),[B,Tt]),Ht=e.useMemo(()=>{var e,t;if(0===f.length||!B)return[];if(x.backgroundLoadComplete)return[];const n=[];for(const r of f){if("expired"===r.status)continue;if(!(null==(e=o[r.hash])?void 0:e.latitude)||!(null==(t=o[r.hash])?void 0:t.longitude))continue;const s=[B,r.hash].sort(),a=`${s[0]}~${s[1]}`;n.push({fromHash:B,toHash:r.hash,key:a,packetCount:r.count,avgConfidence:1,strength:.8,avgRecency:1,hopDistanceFromLocal:0,isHubConnection:!1,isCertain:!0,certainCount:r.count,isLoopEdge:!1,forwardCount:r.count,reverseCount:0,symmetryRatio:0,dominantDirection:"forward",floodCount:r.count,directCount:0,isDirectPathEdge:!1,isZeroHop:!0,avgRssi:r.avgRssi,avgSnr:r.avgSnr})}return n},[f,B,x.backgroundLoadComplete,o]),$t=e.useMemo(()=>{const e=[];if(Ht.length>0&&!x.backgroundLoadComplete){for(const t of Ht){const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e}for(const t of g.validatedEdges){if(Dt(t))continue;const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e},[g.validatedEdges,Ft,Dt,Ht,x.backgroundLoadComplete]),At=e.useMemo(()=>{const e=[];for(const t of g.weakEdges){if(Dt(t))continue;const o=Ft.get(t.fromHash),n=Ft.get(t.toHash);o&&n&&e.push({from:o,to:n,edge:t})}return e},[g.weakEdges,Ft,Dt]),Pt=e.useMemo(()=>{if(!(null==n?void 0:n.latitude)||!(null==n?void 0:n.longitude))return[];const e=[],t=[n.latitude,n.longitude],r=new Map;for(const o of g.lastHopNeighbors)r.set(o.hash,o.count);const s=new Map;for(const o of f)s.set(o.hash,o.count);for(const n of Tt){const a=o[n];if(!(null==a?void 0:a.latitude)||!(null==a?void 0:a.longitude))continue;const i=s.get(n),l=r.get(n);e.push({from:t,to:[a.latitude,a.longitude],hash:n,neighbor:a,lastHopData:Rt.get(n)??null,rxAdvertCount:i,txProxyCount:l})}return e},[n,Tt,o,Rt,g.lastHopNeighbors,f]),zt=e.useMemo(()=>new Set(g.loopEdgeKeys),[g.loopEdgeKeys]),It=e.useMemo(()=>new Set(g.backboneEdges),[g.backboneEdges]),qt=e.useMemo(()=>{if(!Se)return null;const e=g.validatedEdges.filter(e=>e.fromHash===Se||e.toHash===Se);if(0===e.length)return null;const t=[...e].sort((e,t)=>t.certainCount-e.certainCount),o=Math.max(1,Math.ceil(.2*t.length)),n=t.slice(0,o);return new Set(n.map(e=>e.key))},[Se,g.validatedEdges]),Wt=e.useMemo(()=>{let e=0;if(Ht.length>0&&!x.backgroundLoadComplete){for(const t of Ht)t.certainCount>e&&(e=t.certainCount);return e||1}for(const t of g.validatedEdges)t.certainCount>e&&(e=t.certainCount);return e||1},[g.validatedEdges,Ht,x.backgroundLoadComplete]),_t=e.useMemo(()=>{if(0===g.validatedEdges.length)return null;const e=new Set;for(const n of g.validatedEdges)e.add(n.fromHash),e.add(n.toHash);const t=Array.from(e).filter(e=>Ft.has(e)).sort();if(t.length<3)return null;const o=new Map;for(const n of t){const e=Ft.get(n);e&&o.set(n,e)}return le(g.validatedEdges,t,o,g.edgeBetweenness)},[g.validatedEdges,Ft,g.edgeBetweenness]),Ut=e.useCallback(()=>{be(e=>{const t=!e;if(t&&_t&&h.current){const e=h.current.getMap();if(!e)return t;let o=1/0,n=-1/0,r=1/0,s=-1/0,a=!1;for(const[,t]of _t.communities)for(const e of t){const t=Ft.get(e);if(t){const[e,i]=t;r=Math.min(r,e),s=Math.max(s,e),o=Math.min(o,i),n=Math.max(n,i),a=!0}}a&&e.fitBounds([[o,r],[n,s]],{padding:{top:60,bottom:100,left:60,right:320},duration:800,maxZoom:14})}return t})},[_t,Ft]),Kt=e.useRef(null);e.useLayoutEffect(()=>{var e,t;Kt.current=(null==(t=null==(e=h.current)?void 0:e.getMap)?void 0:t.call(e))??null});const Vt=St();!function({map:t,nodeCoordinates:o,packets:n,localHash:r,neighbors:s,meshTopology:a,enabled:i=!0}){const l=e.useRef(null),c=t&&"current"in t?t.current:t;e.useEffect(()=>{l.current=c},[c]);const u=e.useRef(!1),d=e.useRef(null),m=e.useRef([]),h=e.useRef(0),g=e.useRef(!1),[p,f]=e.useState(!1),x=e.useRef(null),y=e.useRef([]),b=e.useRef(new Map),v=e.useRef(o);e.useEffect(()=>{v.current=o},[o]),e.useEffect(()=>{b.current=function(e,t){const o=new Map;for(const n of Object.keys(e)){const e=_(n);o.has(e)||o.set(e,n)}if(t){const e=_(t);o.set(e,t)}return o}(s,r)},[s,r]),e.useEffect(()=>{if(!i){x.current&&(clearTimeout(x.current),x.current=null),y.current=[],null!==d.current&&(cancelAnimationFrame(d.current),d.current=null),m.current=[];const e=l.current;if(e&&u.current){const t=e.getSource(kn);t&&t.setData({type:"FeatureCollection",features:[]})}g.current=!1,h.current=0}},[i]),e.useEffect(()=>{const e=c;if(!e)return;let t=null,o=!1;const n=()=>{if(!o&&!u.current)try{e.getLayer(Mn)&&e.removeLayer(Mn),e.getSource(kn)&&e.removeSource(kn),e.addSource(kn,{type:"geojson",data:{type:"FeatureCollection",features:[]}});const o=e.getLayer(Tn)?Tn:void 0;e.addLayer({id:Mn,type:"line",source:kn,layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":["case",["any",["==",["get","isSpeculative"],!0],["==",["get","isSpeculative"],"true"]],"#8B7BAD",Rn],"line-width":["case",["any",["==",["get","isSpeculative"],!0],["==",["get","isSpeculative"],"true"]],1.875,2.5],"line-opacity":["*",["get","opacityMult"],["interpolate",["linear"],["get","intensity"],0,0,.1,.8,.5,1,1,1]]}},o),u.current=!0,f(!0),t&&(clearInterval(t),t=null)}catch{}};return e.isStyleLoaded()&&n(),e.once("style.load",()=>{n()}),u.current||(t=setInterval(()=>{u.current?t&&clearInterval(t):n()},100),setTimeout(()=>{t&&(clearInterval(t),t=null)},5e3)),()=>{o=!0,t&&clearInterval(t),null!==d.current&&(cancelAnimationFrame(d.current),d.current=null);const e=l.current;if(e&&u.current){try{e.getLayer(Mn)&&e.removeLayer(Mn),e.getSource(kn)&&e.removeSource(kn)}catch{}u.current=!1,f(!1)}}},[c]);const j=e.useRef(()=>{});e.useEffect(()=>{j.current=()=>{const e=l.current;if(!e)return;const t=e.getSource(kn);if(!t)return;const o=performance.now(),n=m.current,r=[],s=[];for(const a of n){const e=o-a.startTime-a.delay;if(e<(a.isSpeculative?Fn:Sn)){s.push(a);const t=a.isSpeculative?En(e):Ln(e);t>0&&r.push({type:"Feature",properties:{intensity:t,opacityMult:a.isSpeculative?.5:1,isSpeculative:a.isSpeculative??!1},geometry:{type:"LineString",coordinates:[a.fromCoord,a.toCoord]}})}}t.setData({type:"FeatureCollection",features:r}),m.current=s,s.length>0?d.current=requestAnimationFrame(()=>j.current()):d.current=null}},[]);const w=e.useCallback(()=>{const e=l.current;e&&function(e){if(!e.getLayer(Mn))return;const t=e.getLayer(Tn)?Tn:void 0;try{e.moveLayer(Mn,t)}catch{}}(e),null===d.current&&(d.current=requestAnimationFrame(()=>j.current()))},[]),N=e.useCallback(()=>{if(!l.current||!u.current)return;const e=y.current;if(y.current=[],x.current=null,0===e.length)return;const t=b.current,o=v.current;if(0===t.size)return;const n=performance.now();let s=0,i=!1;const c=new Set;for(const l of e){const e=W(l,r);if(!e||e.original.length<2)continue;const u=e.original;let d=0,h=null;for(let r=0;r0){e.sort((e,t)=>t.confidence-e.confidence);const t=Math.max(1,Math.ceil(.25*e.length)),r=e.slice(0,t),a=s+150*d;for(const{edgeKey:e,otherHash:s}of r){const t=o.get(h),r=o.get(s);m.current.push({edgeKey:e,fromCoord:Bn(t),toCoord:Bn(r),startTime:n,delay:a,isSpeculative:!0}),c.add(e),i=!0}}}d>0&&(s+=150*d*.5)}i&&w()},[r,a,w]);e.useEffect(()=>{const e=l.current;if(!i)return;if(!e)return;if(!p)return;if(0===n.length)return;const t=Date.now(),o=h.current;if(!g.current){g.current=!0;const e=(t-3e4)/1e3,o=n.filter(t=>(t.timestamp??0)>=e);let r=0;for(const t of n){const e=t.timestamp??0;e>r&&(r=e)}if(h.current=r,o.length>0){o.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0));const e=o.slice(-20);y.current.push(...e),N()}return}const r=n.filter(e=>(e.timestamp??0)>o);if(0===r.length)return;let s=0;for(const n of r){const e=n.timestamp??0;e>s&&(s=e)}h.current=s,y.current.push(...r),x.current&&clearTimeout(x.current),x.current=setTimeout(N,175)},[i,n,N,p]),e.useEffect(()=>()=>{x.current&&clearTimeout(x.current)},[])}({map:Kt,nodeCoordinates:Ft,packets:Vt,localHash:B,neighbors:o,meshTopology:g,enabled:et});const{isExiting:Zt,isAnimating:Gt,resetAnimationState:Yt}=function({map:t,showTopology:o,validatedPolylines:n,weakPolylines:r,maxCertainCount:s,loopEdgeKeys:a,backboneEdgeKeys:i,highlightedEdgeKey:l,neighbors:c,validatedSourceId:u,weakSourceId:d,neighborPolylines:m=[],showNeighborLines:h=!0,neighborSourceId:g,neighborLinkScores:p=new Map,basemapMode:f}){const x=e.useRef(null);e.useEffect(()=>{const e=t&&"current"in t?t.current:t;x.current=e});const y=e.useRef(new Map),b=e.useRef(1),v=e.useRef(new Map),j=e.useRef(new Map),w=e.useRef(!1),N=e.useRef(null),C=e.useRef(o),k=e.useRef(new Set),M=e.useRef(""),S=e.useRef(new Map),F=e.useRef(""),R=e.useRef(""),T=e.useRef(""),L=e.useRef(n),E=e.useRef(r),B=e.useRef(s),D=e.useRef(a),H=e.useRef(i),$=e.useRef(l),A=e.useRef(c),P=e.useRef(m),z=e.useRef(h),I=e.useRef(p),q=e.useRef(f);e.useEffect(()=>{L.current=n,E.current=r,B.current=s,D.current=a,H.current=i,$.current=l,A.current=c,P.current=m,z.current=h,I.current=p,q.current=f},[n,r,s,a,i,l,c,m,h,p,f]);const O=e.useCallback((e=!1)=>{var t,o,n,r,s,a,i,l,c,m;const h=x.current;if(!h)return;const p=h.getSource(u),f=h.getSource(d),w=h.getSource(g);if(p){const s=jn(L.current,!0,y.current,b.current,v.current,j.current,B.current,D.current,H.current,$.current,A.current,q.current),a=`${s.features.length}:${(null==(o=null==(t=s.features[0])?void 0:t.properties)?void 0:o.key)??""}:${(null==(r=null==(n=s.features[s.features.length-1])?void 0:n.properties)?void 0:r.key)??""}:${Array.from(y.current.values()).reduce((e,t)=>e+t,0).toFixed(2)}`;(e||a!==F.current)&&(p.setData(s),F.current=a)}if(f){const t=jn(E.current,!1,y.current,b.current,v.current,j.current,B.current,D.current,H.current,$.current,A.current,q.current),o=`${t.features.length}:${(null==(a=null==(s=t.features[0])?void 0:s.properties)?void 0:a.key)??""}:${(null==(l=null==(i=t.features[t.features.length-1])?void 0:i.properties)?void 0:l.key)??""}`;(e||o!==R.current)&&(f.setData(t),R.current=o)}if(w&&P.current.length>0){const t=wn(P.current,I.current),o=`${t.features.length}:${(null==(m=null==(c=t.features[0])?void 0:c.properties)?void 0:m.hash)??""}`;(e||o!==T.current)&&(w.setData(t),T.current=o)}},[u,d,g]),W=e.useCallback(()=>{N.current&&(cancelAnimationFrame(N.current),N.current=null),y.current=new Map,b.current=1,v.current=new Map,j.current=new Map,w.current=!1,k.current=new Set,M.current="",S.current=new Map},[]);e.useEffect(()=>{const e=C.current,t=o;if(C.current=o,x.current){if(N.current&&(cancelAnimationFrame(N.current),N.current=null),e&&!t&&!w.current){w.current=!0;const e=new Map(y.current);let t=null;const o=n=>{t||(t=n);const r=n-t,s=Math.min(r/500,1),a=ft(s);for(const[t,o]of e)y.current.set(t,o*(1-a));O(!0),s<1?N.current=requestAnimationFrame(o):(w.current=!1,y.current=new Map,k.current=new Set,M.current="",v.current=new Map,j.current=new Map,N.current=null,O(!0))};N.current=requestAnimationFrame(o)}!e&&t&&(y.current=new Map,k.current=new Set,M.current="")}},[o,O]),e.useEffect(()=>{const e=x.current;if(!o||w.current||!e)return;const t=[...n,...r],s=t.map(e=>`${e.edge.key}:${e.edge.certainCount}`).sort().join(","),a=0===k.current.size,i=""!==M.current&&M.current!==s;if(!a&&!i)return void O();const l=[],c=[];for(const{edge:o}of t)k.current.has(o.key)?c.push(o.key):l.push(o.key);i&&c.length>0&&(v.current=new Map(S.current),b.current=0),j.current=new Map;for(const{edge:o}of n){const e=Mt(o.certainCount);j.current.set(o.key,e)}for(const o of l)y.current.set(o,0);for(const o of c)y.current.has(o)||y.current.set(o,1);if(l.length>0||i&&c.length>0){N.current&&(cancelAnimationFrame(N.current),N.current=null);let e=null;const t=Math.min(100,Lt/Math.max(l.length,1)/2),o=n=>{e||(e=n);const r=n-e;for(let e=0;e0){const e=Math.min(r/Lt,1);b.current=xt(e)}O(!0);const s=Lt+(l.length-1)*t;N.current=r{const e=x.current;if(!e||!g)return;const t=()=>{const t=e.getSource(g);if(!t)return!1;if(m.length>0){const e=wn(m,p);t.setData(e)}else t.setData({type:"FeatureCollection",features:[]});return!0};if(t())return;const o=n=>{n.sourceId===g&&t()&&e.off("sourcedata",o)};e.on("sourcedata",o);const n=()=>{t()&&(e.off("styledata",n),e.off("sourcedata",o))};return e.on("styledata",n),()=>{e.off("sourcedata",o),e.off("styledata",n)}},[g,m,p]);const _=e.useRef(f);return e.useEffect(()=>{f!==_.current&&(_.current=f,F.current="",R.current="",T.current="",O(!0))},[f,O]),e.useEffect(()=>()=>{N.current&&(cancelAnimationFrame(N.current),N.current=null)},[]),{isExiting:w.current,isAnimating:null!==N.current,resetAnimationState:W,weightAnimProgress:b.current,animStartWeights:v.current,animTargetWeights:j.current}}({map:Kt,showTopology:O,validatedPolylines:$t,weakPolylines:At,maxCertainCount:Wt,loopEdgeKeys:zt,backboneEdgeKeys:It,highlightedEdgeKey:d,neighbors:o,validatedSourceId:dr,weakSourceId:mr,neighborPolylines:Pt,showNeighborLines:V,neighborSourceId:hr,neighborLinkScores:Bt,basemapMode:ot}),Qt=e.useMemo(()=>{const e=new Set;for(const t of g.hubNodes){e.add(t);for(const o of g.validatedEdges)o.fromHash===t&&e.add(o.toHash),o.toHash===t&&e.add(o.fromHash)}return e},[g.hubNodes,g.validatedEdges]),Xt=e.useMemo(()=>{const e=new Set;if(!r)return e;for(const t of g.validatedEdges)t.fromHash===r&&e.add(t.toHash),t.toHash===r&&e.add(t.fromHash);return e},[r,g.validatedEdges]),to=e.useMemo(()=>{const e=new Map;for(const[t,o]of Ct)e.set(t,pt(o).type);return e},[Ct]),oo=e.useMemo(()=>{let e=0,t=0,o=0;for(const[,n]of to)"repeater"===n?e++:"companion"===n||"unknown"===n?t++:"room_server"===n&&o++;return{repeater:e,companion:t,room_server:o,hubs:g.hubNodes.length,direct:Tt.size}},[to,g.hubNodes.length,Tt.size]),ro=e.useMemo(()=>new Set(pe),[pe]),{getNodeOpacity:so}=function({activeFilters:t,neighborHashes:o,hubConnectedNodes:n,directNodeSet:r,localConnectedNodes:s,nodeTypeMap:a,showTopology:i}){const[l,c]=e.useState(new Map),u=e.useMemo(()=>[...t].sort().join(","),[t]),d=e.useRef(u),m=e.useRef(!1),h=e.useRef(new Map),g=e.useRef(null),p=e.useRef(n),f=e.useRef(r),x=e.useRef(s),y=e.useRef(a),b=e.useRef(i);return e.useEffect(()=>{p.current=n,f.current=r,x.current=s,y.current=a,b.current=i},[n,r,s,a,i]),e.useEffect(()=>{const e=d.current,n=u;if(d.current=u,e===n)return;g.current&&(cancelAnimationFrame(g.current),g.current=null);const r=new Set(e?e.split(",").filter(Boolean):[]),s=t,a=p.current,i=f.current,l=y.current;for(const t of o)h.current.has(t)||h.current.set(t,Math.random());const x=(e,t)=>{if(0===t.size)return!1;const o=l.get(e)??"unknown";return!!(t.has("repeater")&&"repeater"===o||t.has("companion")&&("companion"===o||"unknown"===o)||t.has("room_server")&&"room_server"===o||t.has("direct")&&i.has(e)||t.has("hubs")&&a.has(e))},b=[];for(const t of o){const e=x(t,r),o=x(t,s);e!==o&&b.push({hash:t,startOpacity:e?1:0,targetOpacity:o?1:0})}if(0===b.length)return;m.current=!0,c(e=>{const t=new Map(e);for(const{hash:o,startOpacity:n}of b)t.set(o,n);return t});const v=b;let j=null;const w=e=>{j||(j=e);const t=e-j;let o=!0;c(()=>{const e=new Map;for(const{hash:n,startOpacity:r,targetOpacity:s}of v){const a=250*(h.current.get(n)??0),i=Math.max(0,t-a),l=Math.min(i/500,1),c=r+(s-r)*xt(l);e.set(n,c),l<1&&(o=!1)}return e}),t<750&&!o?g.current=requestAnimationFrame(w):(g.current=null,m.current=!1,c(new Map))};return g.current=requestAnimationFrame(w),()=>{g.current&&(cancelAnimationFrame(g.current),g.current=null),m.current=!1}},[u,t,o]),{nodeOpacities:l,getNodeOpacity:(e,t)=>m.current&&l.has(e)?l.get(e):t?1:0}}({activeFilters:ro,neighborHashes:Ct.map(([e])=>e),hubConnectedNodes:Qt,directNodeSet:Tt,localConnectedNodes:Xt,nodeTypeMap:to,showTopology:O}),{blinkingNodes:io,blinkColor:lo}=function({neighbors:t,localHash:o,enabled:n=!0}){const[r,s]=e.useState(new Map),a=St(),i=e.useRef(a);e.useEffect(()=>{i.current=a},[a]);const l=e.useRef(0),c=e.useRef(null),u=e.useRef(new Map),d=e.useRef(new Map);e.useEffect(()=>{d.current=function(e){const t=new Map;for(const o of Object.keys(e)){const e=_(o);t.has(e)||t.set(e,o)}return t}(t)},[t]);const m=e.useRef(null);return e.useEffect(()=>{m.current=()=>{const e=performance.now(),t=u.current;if(0===t.size)return c.current=null,void s(new Map);const o=new Map,n=[];for(const[r,{startTime:s,staggerDelay:a}]of t){const t=e-s-a;if(t<0);else if(t>=750)n.push(r);else{const e=Nn(t,750);e>0&&o.set(r,e)}}for(const r of n)t.delete(r);s(o),t.size>0&&m.current?c.current=requestAnimationFrame(m.current):c.current=null}},[]),e.useEffect(()=>{if(!n)return;const e=i.current;if(0===e.length)return;const t=l.current,r=e.filter(e=>(e.timestamp??0)>t);if(0===t){const t=e.reduce((e,t)=>Math.max(e,t.timestamp??0),0);return void(l.current=t)}if(0===r.length)return;const s=r.reduce((e,t)=>Math.max(e,t.timestamp??0),0);l.current=s;const a=performance.now();let h=0;for(const n of r){const e=W(n,o);if(!e||0===e.original.length)continue;const t=Cn(e.original,d.current,o);if(0===t.length)continue;const r=375;for(let o=0;o()=>{null!==c.current&&(cancelAnimationFrame(c.current),c.current=null)},[]),{blinkingNodes:r,blinkColor:"#00FF00"}}({neighbors:o,localHash:r,enabled:et}),co=e.useCallback(e=>{if(0===ro.size)return!1;const t=to.get(e)??"unknown";return!!(ro.has("repeater")&&"repeater"===t||ro.has("companion")&&("companion"===t||"unknown"===t)||ro.has("room_server")&&"room_server"===t||ro.has("direct")&&Tt.has(e)||ro.has("hubs")&&Qt.has(e))},[ro,to,Tt,Qt]),uo=e.useCallback(()=>{qe(!0),ze(!0)},[]),mo=e.useCallback(()=>{Oe?xe(e=>!e):uo()},[Oe,uo]),ho=e.useCallback(e=>{P(e.viewState),(e.viewState.pitch??0)>10&&!de&&ve(!0)},[de]),go=e.useCallback(()=>{q(e=>{var t,o,n,r,s,a,i;const l=!e,c=null==(n=null==(o=null==(t=h.current)?void 0:t.getContainer())?void 0:o.closest(".map-container-fullscreen, .map-container-16-9"))?void 0:n.parentElement;return l?c&&document.fullscreenEnabled?null==(r=c.requestFullscreen)||r.call(c).catch(()=>{}):c&&document.webkitFullscreenEnabled&&(null==(s=c.webkitRequestFullscreen)||s.call(c)):document.fullscreenElement?null==(a=document.exitFullscreen)||a.call(document).catch(()=>{}):document.webkitFullscreenElement&&(null==(i=document.webkitExitFullscreen)||i.call(document)),l})},[]),po=e.useCallback(()=>{const e=pe.length>=at.length;we(e?[]:[...at])},[pe,we]),fo=e.useCallback(e=>{pe.length>=at.length?we([e]):pe.includes(e)?we(pe.filter(t=>t!==e)):we([...pe,e])},[pe,we]),yo=e.useCallback(()=>{ye(e=>!e)},[]),bo=e.useCallback(()=>{Q(e=>!e)},[]),vo=e.useCallback(()=>{je(e=>{const t=!e;return t||Te(null),t})},[]),jo=e.useCallback(()=>{ve(e=>{const t=!e;if(h.current){const e=h.current.getMap();e&&e.stop()}if(t&&h.current){const e=h.current.getMap();e&&e.easeTo({pitch:45,duration:1500,easing:ft})}if(!t&&h.current){const e=h.current.getMap();e&&e.easeTo({pitch:0,bearing:0,duration:800,easing:yt})}return t})},[]),wo=e.useCallback(()=>{O||xe(!0)},[O]),No=e.useCallback((e,t)=>{He(e),Ae(t)},[]),Co=e.useCallback(()=>{De&&s&&s(De),He(null),Ae("")},[De,s]),ko=e.useMemo(()=>[...jr,...ur,...he?[kr]:[]],[he]),Mo=e.useRef(!1);e.useEffect(()=>{Mo.current="ontouchstart"in window||navigator.maxTouchPoints>0},[]);const So=e.useCallback(e=>{if(he&&e.features&&e.features.length>0){const t=e.features.find(e=>{var t;return(null==(t=e.layer)?void 0:t.id)===kr});if(null==t?void 0:t.properties){const{fromHash:e,toHash:o}=t.properties;if(e&&o){const t=v.find(t=>t.nodeA.hash===e&&t.nodeB.hash===o||t.nodeA.hash===o&&t.nodeB.hash===e);if(t)return void Te(t)}}}e.features&&0!==e.features.length||(Mo.current&&it&&(mt(null),Me(null)),Se&&Fe(null),Re&&Te(null))},[it,Se,he,v,Re]),Fo=e.useCallback(e=>{Fe(t=>t===e?null:e),Te(null)},[]),Lo=e.useCallback(e=>{var t,o,n;if(!e.features||0===e.features.length)return;if(e.features.some(e=>{var t,o;return null==(o=null==(t=e.layer)?void 0:t.id)?void 0:o.startsWith("node-markers-")}))return void(ke&&(Me(null),mt(null)));if(he&&e.features.some(e=>{var t;return(null==(t=e.layer)?void 0:t.id)===kr})){try{(null==(t=h.current)?void 0:t.getCanvas())&&(h.current.getCanvas().style.cursor="pointer")}catch{}return}const r=e.features.find(e=>{var t;const o=null==(t=e.layer)?void 0:t.id;return(null==o?void 0:o.startsWith("topology-"))||(null==o?void 0:o.startsWith("neighbor-"))});if(!r)return;const s=null==(o=r.layer)?void 0:o.id,a=r.properties;if(!(null==a?void 0:a.key))return;const i=null==s?void 0:s.startsWith("topology-"),l=null==s?void 0:s.startsWith("neighbor-");if(i||l){const t=a.key.replace(/-loop[12]$/,"");Me(t),e.lngLat&&mt({longitude:e.lngLat.lng,latitude:e.lngLat.lat,type:i?"topology":"neighbor",properties:a})}try{(null==(n=h.current)?void 0:n.getCanvas())&&(h.current.getCanvas().style.cursor="pointer")}catch{}},[ke,he]),Eo=e.useCallback(()=>{var e;Me(null),mt(null);try{(null==(e=h.current)?void 0:e.getCanvas())&&(h.current.getCanvas().style.cursor="")}catch{}},[]),Bo=I?"map-container-fullscreen":"map-container-16-9",Ho=D.length>0||(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude),$o=!j||!Ho,Ao=Ho;return t.jsxs("div",{className:`relative ${Bo} ${I?"":"rounded-2xl overflow-hidden"}`,role:"application","aria-label":"Mesh network contacts map","aria-describedby":"map-instructions","data-basemap":ot,children:[t.jsx("span",{id:"map-instructions",className:"sr-only",children:"Interactive map showing mesh network contacts. Use mouse or touch to pan and zoom. Press Tab to navigate map controls. Press Escape to exit fullscreen mode."}),$o&&t.jsx("div",{className:"absolute inset-0 z-50 surface-base rounded-2xl flex items-center justify-center","aria-hidden":"true",children:t.jsxs("div",{className:"flex flex-col items-center gap-3",children:[t.jsx("div",{className:"w-6 h-6 border-2 border-sys-blue border-t-transparent rounded-full animate-spin"}),t.jsx("span",{className:"text-sm text-fg-muted",children:"Loading map..."})]})}),Ao&&t.jsx("div",{className:`relative w-full h-full ${I?"":"rounded-[1.125rem] overflow-hidden"} ${$o?"opacity-0":"opacity-100 transition-opacity duration-300"}`,style:R?{visibility:"hidden"}:void 0,children:t.jsxs(i,{ref:h,...$,onMove:ho,mapStyle:Hr,style:{width:"100%",height:"100%"},attributionControl:!1,interactiveLayerIds:ko,onMouseMove:Lo,onMouseLeave:Eo,onClick:So,onError:e=>{console.error("MapLibre error:",e.error)},onIdle:()=>{if(!E&&!L&&h.current){const e=h.current.getMap();if(e){const t=Object.values(o).filter(e=>e.latitude&&e.longitude).map(e=>({latitude:e.latitude,longitude:e.longitude}));(null==n?void 0:n.latitude)&&(null==n?void 0:n.longitude)&&t.push({latitude:n.latitude,longitude:n.longitude}),t.length>0&&T(t,e)}}},children:[t.jsx(l,{position:"bottom-right"}),t.jsx(dt,{mode:ot}),t.jsx(ln,{enabled:de,exaggeration:4}),t.jsx(tn,{coveragePoints:Je,visible:Je.length>0&&Ye,terrainEnabled:de,brightness:Qe,basemapMode:ot}),t.jsx(xn,{partition:_t,nodeCoordinates:Ft,visible:X&&Oe,opacity:ie.opacity,bandwidth:ie.bandwidth,threshold:ie.threshold,strokeWidth:ie.strokeWidth}),t.jsx(vr,{showTopology:O,isExiting:Zt,hoveredEdgeKey:ke,highlightedLoopEdges:null==ht?void 0:ht.highlightedEdgeKeys,highlightedFocusEdges:qt,onEdgeHover:bt,onLoopHover:vt,loops:g.loops,neighborNames:wt,opacityBias:Le,widthMultiplier:Ee,trafficFilter:Be,showNeighborLines:V,disableHover:Gt||Ie}),t.jsx(Lr,{visible:he,nodeCoordinates:Ft,focusedNodeHash:Se,basemapMode:ot}),a&&t.jsx(wr,{targetHash:a,nodeCoordinates:Ft,onComplete:u}),d&&t.jsx(Nr,{highlightedEdgeKey:d,validatedPolylines:$t,weakPolylines:At,onEnsureTopology:wo}),t.jsx(Br,{ghost:m??null,neighborCoordinates:Ft,onHighlightedNeighborsChange:Ge}),t.jsx(cr,{neighborsWithLocation:Ct,localNode:n,localHash:r,zeroHopNeighbors:Tt,lastHopNeighborMap:Rt,meshTopology:g,hoveredMarker:Ne,onMarkerHover:Ce,getNodeOpacity:so,shouldShowNode:co,onRequestRemove:s?No:void 0,openPopupId:Ue,onOpenPopup:Ve,onClosePopup:Ze,onNodeClick:Fo,blinkingNodes:io,blinkColor:lo})]})}),(()=>{const e=function(e,t,o,n){var r;if(t){const e=t.loops[0],o=t.loops.length,n=[{label:"hops",value:e.size},{label:"seen",value:e.minCertainCount}],r=[];return e.includesLocal&&r.push({text:"★ Includes your node",color:"text-sys-amber"}),o>1&&r.push({text:`+${o-1} overlapping`,color:"text-sys-indigo/70"}),{type:"loop",title:{icon:"⟳",text:"Redundant Path"+(o>1?"s":""),color:"text-sys-indigo"},subtitle:{text:`${t.nodeNames.join(" → ")} → ${t.nodeNames[0]}`,color:"text-fg-secondary",mono:!0},stats:n,badges:r}}if("neighbor"===(null==e?void 0:e.type)){const t=e.properties,o=[];void 0!==t.rssi&&null!==t.rssi&&o.push({label:"RSSI",value:`${Math.round(t.rssi)} dBm`,unit:t.hasAvgRssi?"avg":void 0}),void 0!==t.snr&&null!==t.snr&&o.push({label:"SNR",value:`${Number(t.snr).toFixed(1)} dB`,unit:t.hasAvgSnr?"avg":void 0});const n=t.listenerScore??0,r=t.loudScore??0,s=n>0||r>0;return s&&(o.push({label:"listener",value:n,color:"text-sys-green"}),o.push({label:"loud",value:r,color:"text-sys-red"})),void 0===t.packetCount||s||o.push({label:"packets",value:Number(t.packetCount).toLocaleString()}),{type:"neighbor",title:{icon:"●",text:t.prefix?`${t.name} (${t.prefix})`:t.name,color:"text-sys-amber"},subtitle:{text:"Direct RF Neighbor",color:"text-sys-amber/70"},stats:o,badges:[]}}if("topology"===(null==e?void 0:e.type)){const t=e.properties,s=o>0?Number(t.certainCount)/o:0,a=[{label:"validations",value:t.certainCount},{label:"of max traffic",value:`${Math.round(100*s)}%`},{label:"confidence",value:`${Math.round(100*Number(t.confidence))}%`}];if(void 0!==t.symmetryRatio&&t.symmetryRatio<1){const e="forward"===t.dominantDirection?"→":"reverse"===t.dominantDirection?"←":"↔";a.push({label:"symmetric",value:`${e} ${Math.round(100*t.symmetryRatio)}%`,color:"text-fg-muted"})}const i=null==(r=null==n?void 0:n.get(t.key))?void 0:r.traceQuality;if(null==i?void 0:i.composite){const e=i.composite;a.push({label:"trace SNR",value:`${e.mean.toFixed(1)} dB`,unit:`n=${e.count}`,color:e.mean>=10?"text-sys-green":e.mean>=0?"text-sys-amber":"text-sys-red"}),null!=i.asymmetryDb&&i.asymmetryDb>1&&a.push({label:"asymmetry",value:`${i.asymmetryDb.toFixed(1)} dB`,color:i.asymmetryDb>5?"text-sys-red":"text-sys-amber"})}const l=[];if(t.isBackbone&&l.push({text:"Backbone",color:"text-zinc-300"}),t.isLoopEdge&&l.push({text:"Redundant",color:"text-sys-indigo"}),t.isDirectPath&&l.push({text:"Direct Path",color:"text-sys-teal"}),i){const e="excellent"===i.quality||"good"===i.quality?"text-sys-green":"fair"===i.quality?"text-sys-amber":"poor"===i.quality||"critical"===i.quality?"text-sys-red":"text-fg-muted";"unknown"!==i.quality&&l.push({text:`TRACE ${i.quality}`,color:e})}return{type:"topology",title:{icon:"",text:`${t.fromName} ↔ ${t.toName}`,color:"text-fg-primary"},stats:a,badges:l}}return null}(it?{type:it.type,properties:it.properties}:null,ht,Wt,g.edgeMap);return e&&t.jsx("div",{className:"map-edge-tooltip",children:t.jsx("div",{className:"map-control-surface map-edge-tooltip-inner",children:t.jsx(Ar,{data:e})})})})(),t.jsx(Jt,{mapRef:h,showNeighborLines:V,onToggleNeighborLines:yo,hasNeighborPolylines:Pt.length>0,nodeFilters:pe,onToggleFilter:fo,onToggleAll:po,filterCounts:oo,showCoverage:Y,onToggleCoverage:bo,showMinCut:X,onToggleMinCut:Ut,hasMinCutData:Oe&&null!==_t&&_t.numCommunities>1,show3DTerrain:de,onToggle3DTerrain:jo,basemapMode:ot,onToggleBasemap:nt,isFullscreen:I,onToggleFullscreen:go,showLinkQuality:he,onToggleLinkQuality:vo,hasTraceLinks:b}),he&&Re&&t.jsx(Ko,{pair:Re,onClose:()=>Te(null),prefixToName:Nt}),t.jsxs("div",{className:"map-legend-stack",children:[t.jsxs("div",{className:"map-tool-row",children:[t.jsx(eo,{isActive:O,hasAnalyzed:Oe,isLoading:Ie,onClick:mo,basemapMode:ot}),t.jsx(no,{isActive:et,onClick:tt,basemapMode:ot}),t.jsx(ao,{isActive:Je.length>0&&Ye,onClick:Xe,basemapMode:ot})]}),t.jsx(Ot,{showTopology:O,validatedPolylineCount:$t.length,filteredNeighborCount:Ct.length,hasLocalNode:!(!(null==n?void 0:n.latitude)||!(null==n?void 0:n.longitude)),meshTopology:g,zeroHopNeighbors:Tt,neighborsWithLocation:Ct,basemapMode:ot})]}),t.jsx(se,{isOpen:null!==De,onCancel:()=>He(null),onConfirm:Co,title:"Remove Node?",message:`Remove "${$e}" from the contacts list? This will hide the node until it sends a new packet.`,confirmLabel:"Remove",cancelLabel:"Cancel",variant:"danger"}),t.jsx(ce,{isOpen:Pe,onClose:()=>{ze(!1),qe(!1),Yt(),_e(!0),setTimeout(()=>xe(!0),150)}}),t.jsx(Ro,{}),t.jsx(Do,{visible:X&&Oe,onClose:()=>be(!1),settings:ie,onSettingsChange:ue,partition:_t,totalNodes:Object.keys(o).length,basemapMode:ot})]})}export{Pr as default}; diff --git a/frontend/dist/assets/Dashboard-CyVZY-Lj.js b/frontend/dist/assets/Dashboard-Bbh9RnDT.js similarity index 98% rename from frontend/dist/assets/Dashboard-CyVZY-Lj.js rename to frontend/dist/assets/Dashboard-Bbh9RnDT.js index b4040d64..5be323e7 100644 --- a/frontend/dist/assets/Dashboard-CyVZY-Lj.js +++ b/frontend/dist/assets/Dashboard-Bbh9RnDT.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{u as t,U as a,S as n,c as l,d as i,e as o,f as r,h as c,j as d,k as m,m as u,n as x,o as h,p as f,q as p,T as g,L as b,B as j,r as v,t as y,v as N,D as w,w as k,x as M,y as C,z as S,A as L,E as T,F as B,G as F,H as _,J as R,K as D,M as $,N as H,O as P,P as A,Q as I,R as z,V as E,W,X as q,Y as O,_ as G,$ as V,a0 as U,a1 as J,a2 as K}from"./index-D7i6lQrq.js";import{C as X,P as Q,a as Y,B as Z}from"./PageLayout-QhCLxU34.js";import{u as ee,r as se,h as te,a as ae,b as ne,i as le}from"./consumer-registry-KuOoZhsq.js";import{A as ie,m as oe}from"./vendor-motion-DNp0Qg4F.js";import{c as re,d as ce,q as de,a as me,o as ue,L as xe,r as he,s as fe,A as pe,R as ge,t as be,u as je,v as ve,w as ye,x as Ne,y as we,z as ke,Z as Me,g as Ce,B as Se,D as Le,C as Te,H as Be,J as Fe,K as _e,N as Re,O as De,Q as $e}from"./vendor-icons-TO0PZKGR.js";import{u as He}from"./vendor-charts-C916_-gs.js";import{A as Pe}from"./AnimatedNumber-Dx2y1t97.js";import{c as Ae}from"./node-types-CiI69Tya.js";import{b as Ie,c as ze,a as Ee,d as We,F as qe}from"./meshcore-tx-constants-BDLT5LMb.js";import{u as Oe,P as Ge,C as Ve}from"./PacketList-BfWkNwPj.js";import{u as Ue,a as Je}from"./usePipelineStore-D3dOwDkO.js";import{T as Ke}from"./TimeRangeStepper-B5GfHny9.js";import{L as Xe}from"./LightSparkline-BAD3v4m9.js";import{c as Qe}from"./link-scoring-oriFkjrN.js";import{b as Ye,c as Ze}from"./vendor-core-FtpmsTnh.js";import{N as es}from"./NodeInformationCard-68hFKJ-B.js";import{g as ss,e as ts,a as as,f as ns}from"./chat-utils-DbM_TyxC.js";import{C as ls}from"./ChatBubble-BkCCRzh5.js";import{R as is,C as os}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-fonts-CRZaZSFf.js";import"./primitives-YN2ynYwE.js";import"./payload-decoders-DjZO58V7.js";import"./badge-colors-BxLppqaF.js";import"./SignalIndicator-fAt1Aewy.js";import"./DataBox-DpDXI-WX.js";import"./useMapViewStore-1yyjXCM8.js";import"./geo-utils-DJn8DnxF.js";const rs=[{target:"ReceivedChart",fn:"type",minStage:1},{target:"ReceivedChart",fn:"airtime",minStage:1,when:te}];function cs({packets:l,rangeMinutes:i,bucketCount:o}){ee(rs);const r=t(),[c,d]=e.useState(null),[m,u]=e.useState(null),[x,h]=e.useState(null),{buckets:f,activeTypes:p,totalByType:g}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let c=0;ca)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=c.type??c.payload_type??0,d=c.length??c.payload_length??0,m=o[s];m.bytesByType[n]=(m.bytesByType[n]??0)+d,m.totalBytes+=d,r[n]=(r[n]??0)+d}return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),totalByType:r}}(l,i,o),[l,i,o]),b=e.useCallback((e,s,t)=>{d(s),u(t)},[]),j=f.length>0&&p.length>0,v=c?function(e){const s=new Date(1e3*e).getHours();return s>=6&&s<18}(c.start):null,y=c?(N=c.start,new Date(1e3*N).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})):"";var N;const w=null!==x&&null!==v&&x!==v;return v!==x&&h(v),s.jsxs("div",{className:"flex flex-col h-full relative",children:[s.jsx("div",{className:"h-5 relative mb-1 shrink-0",children:c&&null!==m&&s.jsxs("div",{className:"absolute flex items-center gap-1.5 type-data-sm -translate-x-1/2",style:{left:`calc(48px + ${100*m}% * (1 - 48px / 100%))`},children:[s.jsx(ie,{mode:"wait",children:s.jsx(oe.span,{initial:!!w&&{opacity:0,scale:.5,rotate:-90},animate:{opacity:1,scale:1,rotate:0},exit:{opacity:0,scale:.5,rotate:90},transition:{duration:.25,ease:"easeOut"},children:v?s.jsx(re,{className:"w-4 h-4 text-sys-amber"}):s.jsx(ce,{className:"w-4 h-4 text-sys-blue"})},v?"sun":"moon")}),s.jsx("span",{className:"text-fg-secondary",children:y})]})}),s.jsx("div",{className:"flex-1 min-h-0",children:j&&s.jsx(a,{buckets:f,activeTypes:p,gridColor:r.grid,axisTickColor:r.axisTick,onHover:b})}),s.jsx("div",{className:"pt-2 px-1 pb-2 shrink-0",children:j&&s.jsx(n,{activeTypes:p,totalByType:g})})]})}se(rs);const ds=e.memo(function({buckets:t,activeTypes:a}){const n=e.useRef(null),o=e.useRef(t),r=e.useRef(a);o.current=t,r.current=a;const c=e.useMemo(()=>[t.map(e=>e.start),t.map(()=>1)],[t]);return e.useEffect(()=>{if(!n.current||0===t.length)return;const e=n.current,s=e.getBoundingClientRect(),a=Math.floor(s.width)||200,d=Math.floor(s.height)||60,m=new He({width:a,height:d,padding:[0,0,0,0],cursor:{show:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[e=>{const s=e.ctx,{left:t,top:a,width:n,height:c}=e.bbox;!function(e,s,t,a,n,o,r){if(0===s.length)return;const c=function(e,s,t){var a,n;if(e.length<=t)return e;const l=e.length/t,i=[];for(let o=0;o0&&(d.bytesByType[t]=(d.bytesByType[t]??0)+s)}}i.push(d)}return i}(s,t,i.statsCard),d=c.length,m=o/d,u=c.map(e=>e.totalBytes),x=Math.max(...u);if(0!==x){for(let s=0;s{const s=e.getBoundingClientRect();s.width>0&&s.height>0&&m.setSize({width:Math.floor(s.width),height:Math.floor(s.height)})});return u.observe(e),()=>{u.disconnect(),m.destroy()}},[c,t.length]),0===t.length?s.jsx("div",{className:"h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})}):s.jsx("div",{ref:n,className:"w-full h-full"})}),ms=[{target:"ForwardedCard",fn:"type",minStage:1}];function us({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(ms);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;ma)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"FORWARDED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Ratio"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(ms);const xs=[{target:"DroppedCard",fn:"type",minStage:1}];function hs({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(xs);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;ma)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"DROPPED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Drop %"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(xs);const fs={",":"punc",".":"punc-period",":":"punc-colon","/":"punc-slash"},ps=/([,\.:\/])/g,gs=e.memo(function({children:t,className:a="",as:n="span"}){const l=e.useMemo(()=>{let e;return e="number"==typeof t?t.toLocaleString():Array.isArray(t)?t.join(""):String(t??""),ps.test(e)?(ps.lastIndex=0,e.split(ps).map((e,t)=>{const a=fs[e];return a?s.jsx("span",{className:a,children:e},t):e})):e},[t]);return s.jsx(n,{className:`data-tight ${a}`.trim(),children:l})});function bs(e,s,t){return Ee(Math.max(s,Math.min(t,e)))}function js({stats:t,receivedBuckets:a,droppedBuckets:n,forwardedBuckets:l,bucketDurationSeconds:i,timeRangeLabel:u,isLoaded:x=!0}){var h,f,p,g;const[b,j]=e.useState(!1),[v,y]=e.useState("idle"),N=d(),w=e.useCallback(async(e,s)=>{if("applying"!==v){y("applying");try{const t=await m({tx_delay_factor:e,direct_tx_delay_factor:s});(null==t?void 0:t.success)?(y("success"),setTimeout(()=>y("idle"),2e3)):(y("error"),setTimeout(()=>y("idle"),2500))}catch{y("error"),setTimeout(()=>y("idle"),2500)}}},[v]);if(!x)return s.jsx(o,{children:s.jsx(r,{})});const k=Math.floor(Date.now()/1e3)-604800,M=Object.values((null==t?void 0:t.neighbors)??{}).filter(e=>e.zero_hop&&e.last_seen>=k&&Ae(e).isRepeater).length,C=N.filter(e=>"active"===e.status||e.lastSeen>=k).length,S=Math.max(M,C),L=function(e,s,t){const a=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,n=a(s),l=a(t),i=n||(null==e?void 0:e.rx_count)||1,o=l||(null==e?void 0:e.dropped_count)||0;return i>0?o/(i+o)*100:0}(t,a,n),T=function(e,s,t){if((null==s?void 0:s.length)&&t){const e=100;return((null==(a=s)?void 0:a.reduce((e,s)=>e+s.count,0))??0)*e/(s.length*t*1e3)*100}var a;if(e){const s=1e3*(e.uptime_seconds||1);return(e.total_airtime_ms||e.airtime_used_ms||0)/s*100}return 0}(t,l,i),B=(null==(f=null==(h=null==t?void 0:t.config)?void 0:h.delays)?void 0:f.tx_delay_factor)??null,F=(null==(g=null==(p=null==t?void 0:t.config)?void 0:p.delays)?void 0:g.direct_tx_delay_factor)??null,_=function(e,s,t,a){let n=Ie(e);s>20?n+=2*qe:s>12&&(n+=qe),t>8&&(n+=qe);const l=bs(n,0,2);let i=We(e);t>8&&(i+=qe);const o=bs(i,0,1),r=ze(l),c=ze(o),d=null!==a?ze(a):null;let m="stable";return null!==d&&(r>d?m="increase":r20?$.push(`High duplicate rate (${L.toFixed(1)}%) suggests frequent collisions — window widened.`):L>12&&$.push(`Elevated duplicate rate (${L.toFixed(1)}%) — window widened one step.`),T>8&&$.push(`Channel is busy (${T.toFixed(1)}% TX util) — extra spacing added.`));const H=[`Direct uses one forwarder — ×${_.directFactor.toFixed(1)} backoff for channel contention.`];T>8&&H.push("Busy channel — small extra backoff.");const P=[`Flood ×${_.floodFactor.toFixed(1)} (${_.floodSlots} slot${1!==_.floodSlots?"s":""})`,...$,"",`Direct ×${_.directFactor.toFixed(1)}`,...H,"","Click to copy CLI commands"].join("\n"),A=null!==B?ze(B):null,I=null!==F?ze(F):null,z=null!==A&&_.floodSlots!==A,E=null!==I&&_.directSlots!==I,W=z||E;return s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3 flex-wrap",children:[s.jsx(de,{className:"w-4 h-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"DELAY DOCTOR"}),u&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:u})]}),s.jsxs("button",{onClick:async()=>{const e=`set txdelay ${_.floodFactor.toFixed(1)}\nset direct.txdelay ${_.directFactor.toFixed(1)}`;try{await navigator.clipboard.writeText(e),j(!0),setTimeout(()=>j(!1),1500)}catch{const s=document.createElement("textarea");s.value=e,s.style.position="fixed",s.style.opacity="0",document.body.appendChild(s),s.select();try{document.execCommand("copy"),j(!0),setTimeout(()=>j(!1),1500)}catch{console.error("Failed to copy commands")}document.body.removeChild(s)}},className:"flex gap-3 mb-2 sm:mb-3 w-full text-left hover:bg-subtle-fill radius-inner transition-base p-1 -m-1 group",title:P,children:[s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-fg-primary",children:s.jsxs(gs,{children:["×",_.floodFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Flood"})]}),s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-sys-blue",children:s.jsxs(gs,{children:["×",_.directFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Direct"})]}),s.jsx("div",{className:"flex items-center self-center opacity-0 group-hover:opacity-100 transition-opacity",children:b?s.jsx(me,{className:"w-4 h-4 text-sys-green"}):s.jsx(ue,{className:"w-4 h-4 text-fg-muted"})})]}),s.jsx("div",{className:"flex-1 py-2",children:s.jsxs("div",{className:"flex gap-3",children:[s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"Dupe"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left "+(_.duplicateRate>8?"text-status-warning":""),children:[_.duplicateRate.toFixed(1),"%"]})]}),s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"TX Util"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[_.txUtilization.toFixed(2),"%"]})]})]})}),s.jsx("div",{className:"pt-2 mt-auto",children:s.jsxs("div",{className:"flex items-end justify-between gap-2",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Current"}),s.jsx("div",{className:"flex gap-2",children:null!==B?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"data-box",children:["×",B.toFixed(2)]}),s.jsxs("div",{className:"data-box",style:{color:"var(--sys-blue)"},children:["×",(null==F?void 0:F.toFixed(2))??"—"]})]}):s.jsx("span",{className:"text-sm text-fg-muted",children:"No config"})})]}),W&&s.jsxs("button",{onClick:()=>w(_.floodFactor,_.directFactor),disabled:"applying"===v||"success"===v,className:"flex items-center gap-1.5 px-2.5 py-1.5 radius-inner type-micro font-medium transition-base\n "+("success"===v?"bg-sys-green/15 text-sys-green":"error"===v?"bg-sys-red/15 text-sys-red":"applying"===v?"bg-subtle-fill text-fg-muted":"bg-sys-blue/10 text-sys-blue hover:bg-sys-blue/20"),title:`Apply ×${_.floodFactor.toFixed(1)} flood, ×${_.directFactor.toFixed(1)} direct`,children:["success"===v?"Rx'd":"error"===v?"Failed":"Apply","applying"===v?s.jsx(xe,{className:"w-3.5 h-3.5 animate-spin"}):"success"===v?s.jsx(me,{className:"w-3.5 h-3.5"}):s.jsxs("span",{className:"relative inline-flex items-end w-6 h-3.5",children:[s.jsx(he,{className:"w-3.5 h-3.5 absolute left-0 bottom-0"}),s.jsx(fe,{className:"w-3 h-3 absolute right-0 bottom-0"})]})]})]})})]})}const vs=[{target:"RecentPackets",fn:"rssi",minStage:1},{target:"RecentPackets",fn:"snr",minStage:1}];function ys(){ee(vs);const t=u(),a=x(),n=h(),l=f(),i=Ue(),r=Oe(e=>e.requestChannel),[c,d]=e.useState(!0),m=e.useCallback(e=>d(e),[]),v=e.useMemo(()=>[...t.length<=100?t:t.slice(-100)].sort((e,s)=>(s.timestamp??0)-(e.timestamp??0)),[t]),y=null==l?void 0:l.local_hash,N=null==l?void 0:l.neighbors,w=Je();return s.jsxs(o,{noPadding:!0,className:"!overflow-visible",children:[s.jsx(p,{listHeader:!0,icon:s.jsx(ge,{}),title:"Recent Packets",actions:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(g,{enabled:c,onChange:m,label:"Hide Dupes",size:"sm"}),n&&s.jsx(b,{showLabel:!0}),s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})]})}),s.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto px-1",children:s.jsx(Ge,{packets:v,allPackets:t,localHash:y,neighbors:N,resolveSource:w,getDecodedContent:i,onChannelClick:r,loading:a,maxPackets:25,showPagination:!1,flashNewest:!0,hideDupes:c,emptyMessage:"No packets received",footerAction:s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})})})]})}se(vs);const Ns={stable:"M5 12h14",up:"M5 15l7-7 7 7",down:"M19 9l-7 7-7-7"};function ws({trend:e}){return s.jsx("span",{className:`mini-widget-trend ${e}`,children:s.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:Ns[e]})})})}function ks(){return s.jsx("div",{className:"mini-widget-loading",children:s.jsx("div",{className:"mini-widget-loading-spinner"})})}function Ms({message:e}){return s.jsx("div",{className:"mini-widget-error",children:s.jsx("span",{title:e,children:"No data"})})}function Cs({title:e,icon:t,value:a,unit:n,valueSize:l="md",status:i,subtitle:r,trend:c,children:d,isLoading:m=!1,error:u,className:x="",onClick:h}){const f=["mini-widget-value","lg"===l&&"mini-widget-value-lg","sm"===l&&"mini-widget-value-sm"].filter(Boolean).join(" "),p=["mini-widget",x].filter(Boolean).join(" ");return s.jsxs(o,{noPadding:!0,className:p,onClick:h,children:[s.jsxs("div",{className:"mini-widget-header",children:[t,s.jsx("span",{className:"mini-widget-title",children:e}),i&&"unknown"!==i&&s.jsx("div",{className:`mini-widget-status-dot ${i}`}),c&&s.jsx(ws,{trend:c})]}),m?s.jsx(ks,{}):u?s.jsx(Ms,{message:u}):s.jsxs(s.Fragment,{children:[void 0!==a&&s.jsxs("div",{className:f,children:["number"==typeof a?s.jsx(Pe,{value:a,className:"font-mono tabular-nums",priority:"medium",format:Number.isInteger(a)?void 0:{minimumFractionDigits:1,maximumFractionDigits:1}}):s.jsx(gs,{children:a}),n&&s.jsx("span",{className:"mini-widget-unit",children:n})]}),r&&s.jsx("div",{className:"mini-widget-subtitle",children:r}),d]})]})}const Ss={DELTA_CRITICAL:10,SLOPE_CRITICAL:4,JITTER_CRITICAL:6,DELTA_WARNING:5,SLOPE_WARNING:2,JITTER_WARNING:4},Ls={baselineMedian:null,baselineP10:null,baselineP90:null,currentMedian:null,currentSampleCount:0,delta:0,slope:0,jitter:0,penalty:0,penaltyReason:null,computedAt:0,isReliable:!1};function Ts(e,s){if(0===e.length)return null;const t=[...e].sort((e,s)=>e-s),a=s/100*(t.length-1),n=Math.floor(a),l=Math.ceil(a);return n===l?t[n]:t[n]+(t[l]-t[n])*(a-n)}function Bs(e){return Ts(e,50)}const Fs={lbtStats:null,noiseFloor:null,sparklineNoiseFloor:[],noiseFloorWindowHistory:[],linkQuality:null,channelHealth:null,nfTrend:Ls,radioConfig:null,trends:null,stats:null,recentPackets:[],quickNeighbors:[],isLoading:!0,error:null,refresh:async()=>{}},_s=e.createContext(Fs);function Rs({children:t}){var a;const n=f(),l=u(),i=v(),o=y(),r=N(),c=w[r],d=Math.max(1,c.minutes/60),m=null===n,x=e.useMemo(()=>k(l,d),[l,d]),h=(null==n?void 0:n.noise_floor_dbm)??null,p=e.useMemo(()=>M(h)?h:null,[h]),g=e.useMemo(()=>{var e;const s=null==(e=null==n?void 0:n.config)?void 0:e.radio;return s?{sf:s.spreading_factor??7,bwHz:s.bandwidth??125e3}:null},[null==(a=null==n?void 0:n.config)?void 0:a.radio]),b=C(d),j=S(d),F=null==n?void 0:n.neighbors,_=e.useMemo(()=>{const e=F??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!o.has(e)))},[F,o]),R=e.useMemo(()=>i.filter(e=>!o.has(e.hash)),[i,o]),D=e.useMemo(()=>function(e){if(0===e.length)return{...Ls,computedAt:Math.floor(Date.now()/1e3)};const s=Math.floor(Date.now()/1e3),t=e.filter(e=>Number.isFinite(e)),a=e.length>0?[e[e.length-1]]:[],n=e.slice(-4).filter(e=>Number.isFinite(e)),l=Bs(t),i=Ts(t,10),o=Ts(t,90),r=Bs(a),c=null!==r&&null!==i?r-i:0,d=function(e){if(e.length<2)return 0;const s=e.length;let t=0,a=0,n=0,l=0;const i=e[0].timestamp;for(const r of e){const e=(r.timestamp-i)/3600,s=r.value;t+=e,a+=s,n+=e*s,l+=e*e}const o=s*l-t*t;return Math.abs(o)<1e-4?0:(s*n-t*a)/o}(n.map((e,t)=>({timestamp:s-3600*(n.length-1-t),value:e}))),m=function(e){if(e.length<2)return 0;const s=e.reduce((e,s)=>e+s,0)/e.length,t=e.map(e=>Math.pow(e-s,2)).reduce((e,s)=>e+s,0)/e.length;return Math.sqrt(t)}(n),u=t.length>=12,[x,h]=u?function(e,s,t){const a=Ss;return e>=a.DELTA_CRITICAL?[2,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_CRITICAL?[2,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_CRITICAL?[2,`Noise floor unstable (±${t.toFixed(1)} dB)`]:e>=a.DELTA_WARNING?[1,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_WARNING?[1,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_WARNING?[1,`Noise floor variable (±${t.toFixed(1)} dB)`]:[0,null]}(c,d,m):[0,null];return{baselineMedian:l,baselineP10:i,baselineP90:o,currentMedian:r,currentSampleCount:a.length,delta:c,slope:d,jitter:m,penalty:x,penaltyReason:h,computedAt:s,isReliable:u}}(b),[b]),$=e.useMemo(()=>L(R,_,g),[R,_,g]),H=e.useMemo(()=>T(x,p,$),[x,p,$]),[P,A]=e.useState({noiseFloor:null,networkScore:null,channelHealth:null}),I=e.useRef(0);e.useEffect(()=>{const e=()=>{const e=Date.now();e-I.current>3e4&&(I.current=e,A({noiseFloor:p,networkScore:(null==$?void 0:$.networkScore)??null,channelHealth:(null==H?void 0:H.score)??null}))};e();const s=setInterval(e,5e3);return()=>clearInterval(s)},[p,null==$?void 0:$.networkScore,null==H?void 0:H.score]);const z=e.useMemo(()=>({noiseFloor:{current:p,previous:P.noiseFloor,trend:null!==p?B(p,P.noiseFloor,2,!0):"stable"},networkScore:{current:(null==$?void 0:$.networkScore)??0,previous:P.networkScore,trend:B((null==$?void 0:$.networkScore)??0,P.networkScore,3,!1)},channelHealth:{current:(null==H?void 0:H.score)??0,previous:P.channelHealth,trend:B((null==H?void 0:H.score)??0,P.channelHealth,3,!1)}}),[p,null==$?void 0:$.networkScore,null==H?void 0:H.score,P]),E={lbtStats:x,noiseFloor:p,sparklineNoiseFloor:b,noiseFloorWindowHistory:j,linkQuality:$,channelHealth:H,nfTrend:D,radioConfig:g,trends:z,stats:n,recentPackets:l,quickNeighbors:i,isLoading:m,error:null,refresh:async()=>{}};return s.jsx(_s.Provider,{value:E,children:t})}function Ds(){const s=e.useContext(_s);if(void 0===s)throw new Error("useLBTData must be used within an LBTDataProvider");return s}function $s(e,s){return 0===e?"No backoffs":`${s.toFixed(0)}% retry rate`}function Hs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=Ye(),i=(null==t?void 0:t.avgBackoffMs)??0,o=(null==t?void 0:t.retryRate)??0,r=t?(c=i)<100?"excellent":c<250?"good":c<500?"fair":c<1e3?"congested":"critical":"unknown";var c;const d=null==t?void 0:t.sparklineBackoff,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]);return s.jsx(Cs,{title:"LBT Backoff",icon:s.jsx(be,{className:"mini-widget-icon"}),value:Math.round(i),unit:"ms",status:r,subtitle:t?$s(i,o):void 0,isLoading:a,error:n,onClick:()=>l("/packets"),children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Ps(e){return 0===e?"—":e<1?"<1":Math.round(e).toString()}function As(){const{lbtStats:e,isLoading:t,error:a}=Ds(),n=Ye(),l=(null==e?void 0:e.channelBusyCount)??0,i=(null==e?void 0:e.totalPacketsWithLBT)??0,o=(null==e?void 0:e.channelBusyRate)??0,r=(null==e?void 0:e.retryRate)??0,c=(null==e?void 0:e.avgBackoffMs)??0,d=(null==e?void 0:e.minBackoffMs)??0,m=(null==e?void 0:e.maxBackoffMs)??0,u=r>0?Math.max(0,(r-o)/r*100):100;return s.jsx(Cs,{title:"Ch. Busy",icon:s.jsx(je,{className:"mini-widget-icon"}),isLoading:t,error:a,onClick:()=>n("/packets"),children:s.jsx("div",{className:"flex-1 flex items-end",children:s.jsxs("div",{className:"grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto_minmax(0,1fr)] gap-x-2 gap-y-1 sm:gap-y-2 w-full items-baseline",children:[s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:"Failed:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:[s.jsx(gs,{children:l}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:i})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:"Sent:"}),s.jsx("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:s.jsxs(gs,{children:[u.toFixed(0),"%"]})}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:"Mean:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:[s.jsx(gs,{children:Ps(c)}),s.jsx("span",{className:"text-fg-muted text-xs",children:"ms"})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:"Range:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:[s.jsx(gs,{children:Ps(d)}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:Ps(m)})]})]})})})}function Is(e){return null===e?"No reading":e<-115?"Very quiet":e<-105?"Quiet":e<-95?"Moderate":e<-85?"Elevated":"High interference"}function zs(){const{noiseFloor:t,noiseFloorWindowHistory:a,trends:n,isLoading:l,error:i}=Ds(),o=null===(r=t)||r<-110?"excellent":r<-100?"good":r<-90?"fair":r<-80?"congested":"critical";var r;const c=null==n?void 0:n.noiseFloor.trend,d=e.useMemo(()=>{if(!a||a.length<2)return[];return function(e,s,t,a){const n=e.length;if(0===n)return[];if(1===n)return new Array(a).fill(s[0]);if(2===n){const e=new Array(a);for(let t=0;te-s),m=Math.max(a[l-1],1e-10);let u=0,x=0,h=0,f=0,p=0;for(let l=0;l=1)continue;const n=a*a*a,i=(1-n)*(1-n)*(1-n),o=e[l]-t;u+=i,x+=i*o,h+=i*s[l],f+=i*o*o,p+=i*o*s[l]}if(0===u){r[d]=s[Math.round(d/47*(n-1))];continue}const g=u*f-x*x;r[d]=Math.abs(g)<1e-10?h/u:(f*h-x*p)/g}return r}(a.map(e=>e.timestamp),a.map(e=>-e.noise_floor_dbm),0,48).map((e,s)=>({timestamp:Date.now()-36e5*(47-s),count:e}))},[a]),m=null!==t?Math.round(t):"—";return s.jsx(Cs,{title:"Noise Floor",icon:s.jsx(ve,{className:"mini-widget-icon"}),value:m,unit:null!==t?"dBm":void 0,status:o,trend:c,subtitle:Is(t),isLoading:l,error:i,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:d,width:9999,height:22,color:"var(--sys-blue)",isLoading:l,className:"w-full"})})})}const Es=[{target:"LinkLeaders",fn:"path",minStage:1,when:ae},{target:"LinkLeaders",fn:"src_hash",minStage:1,when:ne}];function Ws(){ee(Es);const t=Ye(),a=v(),n=u(),l=f(),i=N(),o=60*w[i].minutes,r=F(),c=e.useMemo(()=>{if(0===r)return n;const e=r-o;return n.filter(s=>s.timestamp>=e)},[n,o,r]),d=null===l,m=(null==l?void 0:l.local_hash)?_(l.local_hash):"",x=(null==l?void 0:l.neighbors)??{},{neighborHashes:h,neighborNames:p}=e.useMemo(()=>{const e=new Set,s=new Map;for(const t of a){e.add(t.hash);const a=x[t.hash],n=(null==a?void 0:a.name)||(null==a?void 0:a.node_name)||t.prefix;s.set(t.hash,n)}return{neighborHashes:e,neighborNames:s}},[a,x]),g=e.useMemo(()=>{if(0===h.size||0===c.length||!m)return{champion:null,listener:null,loudest:null};const{scores:e}=Qe(c,h,m),s=[];for(const[l,i]of e)0!==i.blendedScore&&s.push({...i,name:p.get(l)??_(l)});let t=null,a=null,n=null;for(const l of s)(!t||l.blendedScore>t.blendedScore)&&(t=l),(!a||l.listenerScore>a.listenerScore)&&(a=l),(!n||l.loudScore>n.loudScore)&&(n=l);return{champion:t,listener:a,loudest:n}},[c,h,m,p]),{champion:b,listener:j,loudest:y}=g,k=b||j||y?s.jsxs("div",{className:"flex flex-col gap-0 sm:gap-0.5 mt-auto",children:[b&&s.jsx(R,{content:(M=b,s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["🏆 Champion: ",M.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Blended Score: ",M.blendedScore,s.jsx("span",{className:"text-fg-muted/60 ml-1",children:"(Listener + Loud)"})]}),s.jsxs("div",{className:"border-t border-edge-subtle pt-1 mt-1 space-y-0.5",children:[s.jsxs("div",{children:["Listener: ",M.listenerScore,"/100 (",M.listenerCount," shared paths)"]}),s.jsxs("div",{children:["Loud: ",M.loudScore,"/100 (",M.loudCount," packets relayed)"]})]})]})),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(ye,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-map-neighbor-color flex-shrink-0"}),s.jsx("span",{className:"font-semibold text-map-neighbor-color font-mono truncate flex-1 min-w-0",children:b.name}),s.jsx("span",{className:"text-map-neighbor-color pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:b.blendedScore})]})}),j&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["👂 Best Listener: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.listenerScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.listenerCount," packets where they heard your transmissions"]})})]}))(j),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(Ne,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:j.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:j.listenerScore})]})}),y&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["📢 Loudest: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.loudScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.loudCount," packets they relayed directly to you"]})})]}))(y),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(we,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:y.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:y.loudScore})]})})]}):0===a.length?s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No direct neighbors"}):s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No routing data yet"});var M;return s.jsx(Cs,{title:"Link Leaders",icon:s.jsx(ke,{className:"mini-widget-icon"}),isLoading:d,onClick:()=>t("/contacts"),children:k})}function qs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=t?function(e){const{retryRate:s,channelBusyCount:t,totalPacketsWithLBT:a,avgBackoffMs:n,maxBackoffMs:l}=e;if(0===a)return 0;const i=Math.min(a/10,1),o=Math.log(1+.15*s)/Math.log(16)*40,r=t/a*100,c=Math.min(.5*r,25);let d=0;n>100&&(d=Math.min(8*Math.log10(n/100),15));let m=0;l>500&&n>0&&l>2*n&&(m=Math.min((l-500)/200,5));const u=(o+c+d+m)*i;return Math.min(u,85)}(t):0,i=t?(o=l)<15?"excellent":o<30?"good":o<45?"fair":o<60?"congested":"critical":"unknown";var o;const r=(null==t?void 0:t.maxBackoffMs)??0,c=t?r>200?`Max backoff: ${Math.round(r)}ms`:function(e){return e<15?"Clear channel":e<30?"Light traffic":e<45?"Moderate traffic":e<60?"Heavy traffic":e<75?"Congested":"Severe congestion"}(l):void 0,d=null==t?void 0:t.sparklineCollisionRisk,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]),u=Math.round(10*l)/10;return s.jsx(Cs,{title:"Collision Risk",icon:s.jsx(Me,{className:"mini-widget-icon"}),value:u,unit:"%",status:i,subtitle:c,isLoading:a,error:n,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Os(){const[t,a]=e.useState(!1),[n]=e.useState(0),{stats:l,lbtStats:i,isLoading:o}=Ds(),r=e.useMemo(()=>{if(!l)return null;const e=l.airtime_used_ms??0,s=l.max_airtime_ms??1;return{usedMs:e,maxMs:s,remainingMs:l.airtime_remaining_ms??0,utilizationPercent:l.utilization_percent??(s>0?e/s*100:0)}},[l]),c=e.useMemo(()=>i&&0!==i.totalPacketsWithLBT?(i.totalPacketsWithLBT-i.packetsWithRetries)/i.totalPacketsWithLBT*100:100,[i]),d=(null==r?void 0:r.utilizationPercent)??0,m=(u=d)<30?"excellent":u<50?"good":u<70?"fair":u<90?"congested":"critical";var u;const x=(null==r?void 0:r.remainingMs)??0,h=c<95?`${c.toFixed(0)}% clean TX`:((f=x)<1e3?`${Math.round(f)}ms`:f<6e4?`${(f/1e3).toFixed(1)}s`:`${(f/6e4).toFixed(1)}m`)+" remaining";var f;const p=r?s.jsx("div",{className:"mini-widget-progress mt-auto",children:s.jsx("div",{className:`mini-widget-progress-bar ${m}`,style:{width:`${Math.min(d,100)}%`}})}):null;return s.jsx(Cs,{title:"Duty Cycle",icon:s.jsx(ge,{className:"mini-widget-icon"}),value:d.toFixed(1),unit:"%",status:m,subtitle:h,isLoading:o,children:p})}function Gs(){return s.jsxs("div",{className:"mini-widget",children:[s.jsxs("div",{className:"mini-widget-header",children:[s.jsx(D,{className:"w-4 h-4"}),s.jsx(D,{className:"h-3 w-16"})]}),s.jsx(D,{className:"h-7 w-12 mt-2"}),s.jsx(D,{className:"h-3 w-20 mt-2"})]})}function Vs(){return s.jsx("div",{className:"widget-row",children:Array.from({length:6}).map((e,t)=>s.jsx(Gs,{},t))})}se(Es);const Us=[{target:"MeshHealth",fn:"type",minStage:1}];function Js({className:e="",isLoaded:t=!0}){return ee(Us),s.jsxs("div",{className:`mesh-health-container relative ${e}`,children:[s.jsxs("div",{className:"mesh-health-header",children:[s.jsx(Ce,{className:"w-4 h-4 text-sys-blue"}),s.jsx("span",{className:"type-label text-fg-muted",children:"MESH HEALTH"})]}),t?s.jsx(Rs,{children:s.jsxs("div",{className:"widget-row",children:[s.jsx(Hs,{}),s.jsx(qs,{}),s.jsx(zs,{}),s.jsx(Os,{}),s.jsx(As,{}),s.jsx(Ws,{})]})}):s.jsx(Vs,{})]})}se(Us);const Ks=[{target:"PublicChannel",fn:"decrypt",minStage:2,when:le}];se(Ks);let Xs="",Qs="",Ys="";function Zs(e){!function(){const e=new Date,s=e.toDateString();if(s!==Ys){Ys=s,Xs=s;const t=new Date(e);t.setDate(t.getDate()-1),Qs=t.toDateString()}}();const s=new Date(1e3*e).toDateString();return s===Xs?"Today":s===Qs?"Yesterday":new Date(1e3*e).toLocaleDateString([],{weekday:"short",month:"short",day:"numeric"})}function et(e,s,t){return`${e||""}|${s}|${t}`}const st=e.memo(function({message:e,onChannelClick:t,isChannelSelected:a}){const n=e.channelName||e.channelHash.slice(0,6);return s.jsx("div",{style:{transform:"translateZ(0)",willChange:"transform"},children:s.jsx(ls,{senderName:e.senderName||"Unknown",text:e.text,timestamp:e.timestamp,nameAccessory:s.jsx(Ve,{channelName:n,active:a,onClick:()=>null==t?void 0:t(e.channelHash)})})})},function(e,s){const t=e.message,a=s.message;return t.timestamp===a.timestamp&&t.text===a.text&&t.senderName===a.senderName&&t.channelHash===a.channelHash&&t.channelName===a.channelName&&e.isChannelSelected===s.isChannelSelected&&e.onChannelClick===s.onChannelClick});function tt({open:t,onClose:a,messages:n,onLoadMore:l,hasMoreToLoad:i,isDecoding:o,initialChannel:r}){const c=e.useRef(null),d=e.useRef(!0),m=N(),u=W(),x=e.useRef(!1);e.useEffect(()=>{t?(x.current=!0,q.resume()):x.current&&q.pause()},[t]);const h=e.useMemo(()=>{const e=Date.now()/1e3-60*w[m].minutes;return[...n].filter(s=>s.timestamp>=e).sort((e,s)=>e.timestamp-s.timestamp)},[n,m]),f=e.useCallback(()=>{const e=c.current;e&&(d.current=e.scrollTop>=-50)},[]),p=e.useMemo(()=>{const e=new Map;for(const s of h){const t=s.channelHash,a=e.get(t);a?a.count++:e.set(t,{name:s.channelName||s.channelHash.slice(0,6),hash:s.channelHash,count:1})}return Array.from(e.values()).sort((e,s)=>s.count-e.count)},[h]),g=p.length,[b,j]=e.useState(null),[v,y]=e.useState(!1);e.useEffect(()=>{t&&r&&j(r)},[t,r]);const k=e.useCallback(()=>{l(b,p)},[l,b,p]),M=e.useMemo(()=>b?h.filter(e=>e.channelHash===b):h,[h,b]),C=e.useMemo(()=>{const e=[];let s="";for(const t of M){const a=Zs(t.timestamp);a!==s&&(e.push({type:"date",date:a}),s=a),e.push({type:"message",message:t})}return e},[M]);e.useLayoutEffect(()=>{const e=c.current;e&&d.current&&(e.scrollTop=0)},[M.length]);const S=p.slice(0,19),L=p.slice(19),T=L.length>0;return s.jsx(O,{open:t,onClose:a,size:"lg",motionPlus:!0,solid:!0,children:s.jsxs(G,{className:"p-0 flex flex-col h-[80vh] max-h-[700px] rounded-2xl",children:[s.jsx("div",{className:"flex-shrink-0 px-4 sm:px-5 py-3 sm:py-4",children:s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Se,{className:"size-5 text-icon-card-title flex-shrink-0"}),s.jsx("h2",{className:"type-micro",children:"Public Channels"})]}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:u,size:"sm"}),s.jsx("button",{onClick:a,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),s.jsx("button",{onClick:a,className:"hidden sm:flex items-center justify-center p-2 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-subtle","aria-label":"Close",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}),s.jsx("div",{className:"flex-shrink-0 px-3 pb-2 relative z-10 isolate",style:{minHeight:g>0?void 0:0},children:g>0&&s.jsxs("div",{className:"flex flex-wrap gap-1",children:[s.jsxs("button",{onClick:()=>j(null),className:Ze("px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",null===b?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["All ",g]}),S.map(e=>s.jsx("button",{onClick:()=>j(e.hash),className:Ze("flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",b===e.hash?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:s.jsx("span",{className:"truncate max-w-[80px]",children:e.name})},e.hash)),T&&s.jsxs("div",{className:"relative",children:[s.jsxs("button",{onClick:()=>y(!v),className:Ze("flex items-center gap-0.5 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",v||L.some(e=>e.hash===b)?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["+",L.length,s.jsx(Te,{className:Ze("size-3 transition-transform",v&&"rotate-180")})]}),v&&s.jsx("div",{className:Ze("absolute top-full left-0 mt-1 z-50","min-w-[140px] max-h-[200px] overflow-y-auto","p-1 rounded-lg","bg-elevated backdrop-blur-xl","ring-1 ring-edge-subtle shadow-xl"),children:L.map(e=>s.jsxs("button",{onClick:()=>{j(e.hash),y(!1)},className:Ze("w-full flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-all text-left",b===e.hash?"bg-sys-blue/20 text-sys-blue":"text-fg-secondary hover:bg-subtle-fill-strong"),children:[s.jsx(Be,{className:"size-2.5 opacity-60 flex-shrink-0"}),s.jsx("span",{className:"truncate",children:e.name}),s.jsxs("span",{className:"opacity-60 ml-auto",children:["(",e.count,")"]})]},e.hash))})]})]})}),s.jsx("div",{ref:c,onScroll:f,className:Ze("flex-1 overflow-y-auto overflow-x-hidden","mx-3 mb-3 rounded-md","bg-body","ring-1 ring-inset ring-edge-subtle","flex flex-col-reverse"),children:o&&0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(xe,{className:"size-12 mb-4 text-sys-indigo animate-spin"}),s.jsx("p",{className:"text-lg font-medium",children:"Loading messages..."})]}):0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(Fe,{className:"size-16 mb-4 opacity-20"}),s.jsx("p",{className:"text-lg font-medium",children:"No messages yet"}),s.jsx("p",{className:"text-sm mt-1 opacity-70",children:b?"No messages in this channel":"Public channel messages will appear here"})]}):s.jsxs("div",{className:"px-4 py-4",children:[i&&s.jsx("div",{className:"flex justify-center mb-4",children:s.jsx("button",{onClick:k,disabled:o,className:Ze("px-4 py-1.5 rounded-full","text-[11px] font-medium","ring-1 ring-inset",o?"bg-subtle-fill text-fg-muted ring-edge-subtle cursor-wait":"bg-sys-blue/10 text-sys-blue ring-sys-blue/20 hover:bg-sys-blue/20 hover:ring-sys-blue/30"),children:o?s.jsxs("span",{className:"flex items-center gap-1.5",children:[s.jsx(xe,{className:"size-3 animate-spin"}),"Loading..."]}):"Load older messages"})}),C.map((e,t)=>{if("date"===e.type)return s.jsx("div",{className:"flex justify-center my-4",children:s.jsx("span",{className:Ze("px-3.5 py-1.5 rounded-full","bg-subtle-fill backdrop-blur-sm","text-[11px] text-fg-muted/80 font-medium","ring-1 ring-edge-subtle"),children:e.date})},`date-${e.date}-${t}`);const a=`msg-${e.message.timestamp}-${e.message.senderName||"anon"}-${e.message.channelHash}`;return s.jsx("div",{className:"mb-3",children:s.jsx(st,{message:e.message,onChannelClick:j,isChannelSelected:b===e.message.channelHash})},a)})]})}),s.jsx("div",{className:"flex-shrink-0 px-5 py-2 text-center",children:s.jsxs("p",{className:"text-[11px] text-fg-muted",children:[M.length," messages · ",g," ",1===g?"channel":"channels",o&&s.jsxs("span",{className:"ml-2 text-sys-indigo",children:[s.jsx(xe,{className:"inline size-3 animate-spin mr-1"}),"Decrypting..."]})]})})]})})}function at({isLoaded:t=!0}){ee(Ks);const a=u(),[n,l]=e.useState(!1),[i,o]=e.useState(null),r=N(),c=e.useCallback(()=>{o(null),l(!0),$.getState().queueDecryption(a)},[a]),d=Oe(e=>e.requestedHash),m=Oe(e=>e.clearRequest);e.useEffect(()=>{d&&(o(d),l(!0),$.getState().queueDecryption(a),m())},[d,m,a]);const x=H(),h=P(),f=A(),p=e.useMemo(()=>function(e){const s=[],t=new Set;for(const a of e.values()){const e=a.decoded;if(!e||!e.decrypted||e.macCorrupted||!e.text)continue;const n=et(e.senderName,e.channelHash,e.text);t.has(n)||(t.add(n),s.push({timestamp:a.timestamp,channelName:e.channelName,channelHash:e.channelHash,senderName:e.senderName,text:e.text,rssi:a.rssi,snr:a.snr}))}return s}(x),[x]),g=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes;return p.filter(s=>s.timestamp>=e)},[p,r]),b=e.useMemo(()=>0===g.length?null:g.reduce((e,s)=>s.timestamp>e.timestamp?s:e),[g]),j=h.isDecoding,v=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes,s=new Set;let t=0;for(const n of a)(n.type??n.payload_type)===I.GRP_TXT&&((n.timestamp??0){const e=Date.now()/1e3-60*w[r].minutes;for(const s of a)if((s.type??s.payload_type)===I.GRP_TXT&&!((s.timestamp??0){if(!j){if(e){const t=s.find(s=>s.hash===e);if(t)return t.name,void $.getState().queueChannelDecryption(a,t.name)}$.getState().queueDecryption(a)}},[a,j]);return t?s.jsxs(s.Fragment,{children:[s.jsx("div",{onClick:c,className:Ze("group cursor-pointer rounded-2xl transition-all duration-150","bg-surface/80 backdrop-blur-lg depth-raised","hover:bg-subtle-fill","px-3 py-2.5 sm:px-4 sm:py-3"),children:s.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 flex-shrink-0",children:[s.jsx(Se,{className:"size-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"CHAT ACTIVITY"}),v>0&&s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary",children:v}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors ml-auto sm:hidden"})]}),s.jsxs("div",{className:"flex items-center gap-2 sm:gap-1.5 min-w-0 overflow-hidden",children:[s.jsx(ie,{mode:"wait",initial:!1,children:b?s.jsxs(oe.div,{initial:{opacity:0,y:16},animate:{opacity:1,y:0},exit:{opacity:0,y:-16},transition:{duration:.2,ease:[.4,0,.2,1]},className:"flex items-center gap-2 sm:gap-1.5 min-w-0",children:[b.channelName&&s.jsx("span",{className:"hidden sm:inline-flex",children:s.jsx(Ve,{channelName:b.channelName})}),s.jsx("div",{className:"hidden sm:flex w-[30px] h-[30px] rounded-full items-center justify-center flex-shrink-0 ring-1 ring-edge-subtle",style:{backgroundColor:ss(ts(b.senderName||"").cleanName)},children:ts(b.senderName||"").emoji?s.jsx("span",{className:"text-base",children:ts(b.senderName||"").emoji}):s.jsx("span",{className:"text-white text-xs font-bold tracking-tighter",children:as(b.senderName||"")})}),s.jsx("div",{className:"inline-flex items-center px-3 py-1.5 rounded-2xl rounded-tr-md bg-[#007AFF] shadow-sm min-w-0 flex-1 sm:flex-initial sm:max-w-xs sm:-ml-px",children:s.jsx("span",{className:"text-sm text-white truncate tracking-wide",children:ns(b.text)})}),s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary flex-shrink-0",children:E(b.timestamp)})]},`msg-${b.timestamp}-${b.senderName}-${b.channelHash}`):f?s.jsx(oe.span,{initial:{opacity:0},animate:{opacity:1},className:"text-sm text-fg-muted italic",children:"No messages yet"},"empty"):s.jsxs(oe.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0,y:-16},transition:{duration:.15},className:"flex items-center gap-2 sm:gap-1.5",children:[s.jsx("div",{className:"hidden sm:block w-8 h-4 rounded bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"hidden sm:block w-[30px] h-[30px] rounded-full bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"h-8 w-32 sm:w-48 rounded-2xl bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"w-12 h-6 rounded-md bg-subtle-fill-strong animate-pulse"})]},"skeleton")}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors flex-shrink-0 hidden sm:block ml-1"})]})]})}),s.jsx(tt,{open:n,onClose:()=>l(!1),messages:p,onLoadMore:M,hasMoreToLoad:k,isDecoding:j,initialChannel:i})]}):s.jsx("div",{className:"h-14 rounded-xl bg-elevated/50 animate-pulse"})}function nt(){var t,a;const n=f(),l=V(),i=u(),o=U(),r=e.useRef(!1);o&&!r.current&&(r.current=!0);const d=r.current,m=N(),x=W(),h=J(),g=w[m]??w[4],b=h.isBackgroundLoading&&m>=5,j=null==(t=null==n?void 0:n.config)?void 0:t.radio,v=e.useMemo(()=>j?{sf:j.spreading_factor??10,bw:j.bandwidth??25e4,cr:j.coding_rate??5,preamble:j.preamble_length??8}:null,[j]),y=i.length,k=e.useMemo(()=>y?K(g.minutes,g.buckets,i,n):null,[y,g.minutes,g.buckets,v]),M=e.useMemo(()=>{const e=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,s=e(null==k?void 0:k.received),t=e(null==k?void 0:k.unique_received),a=e(null==k?void 0:k.forwarded),n=e(null==k?void 0:k.dropped),l=e(null==k?void 0:k.transmitted),i=((null==k?void 0:k.time_range_minutes)??g.minutes)/60;return{received:s,uniqueReceived:t,forwarded:a,dropped:n,transmitted:l,rxPerHour:i>0?Math.round(s/i):0,fwdPerHour:i>0?Math.round(a/i):0}},[k,g.minutes]),C=e.useMemo(()=>{if(!i.length)return{totalBytes:0,kbPerHour:0};const e=Date.now()/1e3,s=e-60*g.minutes;let t=0;for(const n of i)n.transmitted||n.timestampe||(t+=n.length??n.payload_length??0);const a=g.minutes/60;return{totalBytes:t,kbPerHour:a>0?Math.round(t/1024/a):0}},[i,g.minutes]),S=(null==n?void 0:n.node_name)??(null==(a=null==n?void 0:n.config)?void 0:a.node_name)??"Unknown Node";return e.useEffect(()=>{S&&"Unknown Node"!==S&&(document.title=`pyMC: ${S}`)},[S]),l?s.jsxs(X,{neomorphic:!0,className:"p-8 text-center",children:[s.jsx("p",{className:"type-subheading text-sys-red mb-2",children:"Failed to connect to backend"}),s.jsx("p",{className:"type-body text-fg-muted",children:l}),s.jsx("p",{className:"type-data-sm text-fg-muted mt-4",children:"Make sure the backend is running on port 8000"})]}):s.jsxs(Q,{children:[s.jsx(Y,{title:S,icon:s.jsx(_e,{}),controls:s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:x,isPending:b})}),s.jsxs(Z,{children:[s.jsx(at,{isLoaded:d}),s.jsx(is,{template:"hero-auto",children:s.jsxs(X,{neomorphic:!0,children:[s.jsx(p,{icon:s.jsx(Re,{}),title:"PACKETS RECEIVED",badge:g.label,badgeColor:"zinc",actions:d?s.jsxs("div",{className:"data-box",children:[C.kbPerHour," KB/hr"]}):s.jsx("div",{className:"data-box opacity-0",children:"0 KB/hr"})}),s.jsxs("div",{className:"flex flex-wrap gap-4 sm:gap-8",children:[s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.received,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Total Rx"})]}),s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.uniqueReceived,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Unique"})]})]}),s.jsxs("div",{className:"mt-2 flex-1 min-h-0 relative",children:[s.jsx("div",{className:"absolute inset-0 flex items-end gap-1 transition-opacity duration-300 "+(d?"opacity-0 pointer-events-none":"opacity-100"),"aria-hidden":d,children:[45,72,33,58,80,42,65,28,55,75,38,62].map((e,t)=>s.jsx("div",{className:"flex-1 bg-subtle-fill rounded-sm animate-pulse",style:{height:`${e}%`}},t))}),s.jsx("div",{className:"h-full transition-opacity duration-300 "+(d?"opacity-100":"opacity-0"),children:s.jsx(cs,{packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets})})]})]})}),s.jsxs(is,{template:"compact",children:[s.jsx(os,{span:6,lg:4,children:s.jsx(us,{value:M.forwarded,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx(De,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:6,lg:4,children:s.jsx(hs,{value:M.dropped,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx($e,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:12,lg:4,children:s.jsx(js,{stats:n,localHash:null==n?void 0:n.local_hash,receivedBuckets:null==k?void 0:k.received,droppedBuckets:null==k?void 0:k.dropped,forwardedBuckets:null==k?void 0:k.forwarded,bucketDurationSeconds:null==k?void 0:k.bucket_duration_seconds,timeRangeLabel:g.label,isLoaded:d})})]}),s.jsx(Js,{isLoaded:d}),s.jsx(ys,{}),n&&s.jsx(is,{template:"auto",children:s.jsx(es,{nodeName:S,repeaterVersion:n.version,coreVersion:n.core_version,localHash:n.local_hash,publicKey:n.public_key})})]})]})}export{nt as default}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{u as t,U as a,S as n,c as l,d as i,e as o,f as r,h as c,j as d,k as m,m as u,n as x,o as h,p as f,q as p,T as g,L as b,B as j,r as v,t as y,v as N,D as w,w as k,x as M,y as C,z as S,A as L,E as T,F as B,G as F,H as _,J as R,K as D,M as $,N as H,O as P,P as A,Q as I,R as z,V as E,W,X as q,Y as O,_ as G,$ as V,a0 as U,a1 as J,a2 as K}from"./index-CkRTgHHA.js";import{C as X,P as Q,a as Y,B as Z}from"./PageLayout-BWMUVZgC.js";import{u as ee,r as se,h as te,a as ae,b as ne,i as le}from"./consumer-registry-BUFl6buY.js";import{A as ie,m as oe}from"./vendor-motion-DNp0Qg4F.js";import{c as re,d as ce,q as de,a as me,o as ue,L as xe,r as he,s as fe,A as pe,R as ge,t as be,u as je,v as ve,w as ye,x as Ne,y as we,z as ke,Z as Me,g as Ce,B as Se,D as Le,C as Te,H as Be,J as Fe,K as _e,N as Re,O as De,Q as $e}from"./vendor-icons-TO0PZKGR.js";import{u as He}from"./vendor-charts-C916_-gs.js";import{A as Pe}from"./AnimatedNumber-DACuG-ay.js";import{c as Ae}from"./node-types-DRVunROD.js";import{b as Ie,c as ze,a as Ee,d as We,F as qe}from"./meshcore-tx-constants-BDLT5LMb.js";import{u as Oe,P as Ge,C as Ve}from"./PacketList-BJFBF77t.js";import{u as Ue,a as Je}from"./usePipelineStore-CLEA3Bev.js";import{T as Ke}from"./TimeRangeStepper-CsLZzi5t.js";import{L as Xe}from"./LightSparkline-BAD3v4m9.js";import{c as Qe}from"./link-scoring-C0BjaK96.js";import{b as Ye,c as Ze}from"./vendor-core-FtpmsTnh.js";import{N as es}from"./NodeInformationCard-tOZNdmfP.js";import{g as ss,e as ts,a as as,f as ns}from"./chat-utils-mqGCinix.js";import{C as ls}from"./ChatBubble-OmHlf-X1.js";import{R as is,C as os}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-fonts-CRZaZSFf.js";import"./primitives-Bgn6Ik6L.js";import"./payload-decoders-_TRhCJrs.js";import"./badge-colors-BxLppqaF.js";import"./SignalIndicator-Bdj3-1hL.js";import"./DataBox-DpDXI-WX.js";import"./useMapViewStore-sFZdb1_p.js";import"./geo-utils-DJn8DnxF.js";const rs=[{target:"ReceivedChart",fn:"type",minStage:1},{target:"ReceivedChart",fn:"airtime",minStage:1,when:te}];function cs({packets:l,rangeMinutes:i,bucketCount:o}){ee(rs);const r=t(),[c,d]=e.useState(null),[m,u]=e.useState(null),[x,h]=e.useState(null),{buckets:f,activeTypes:p,totalByType:g}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let c=0;ca)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=c.type??c.payload_type??0,d=c.length??c.payload_length??0,m=o[s];m.bytesByType[n]=(m.bytesByType[n]??0)+d,m.totalBytes+=d,r[n]=(r[n]??0)+d}return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),totalByType:r}}(l,i,o),[l,i,o]),b=e.useCallback((e,s,t)=>{d(s),u(t)},[]),j=f.length>0&&p.length>0,v=c?function(e){const s=new Date(1e3*e).getHours();return s>=6&&s<18}(c.start):null,y=c?(N=c.start,new Date(1e3*N).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})):"";var N;const w=null!==x&&null!==v&&x!==v;return v!==x&&h(v),s.jsxs("div",{className:"flex flex-col h-full relative",children:[s.jsx("div",{className:"h-5 relative mb-1 shrink-0",children:c&&null!==m&&s.jsxs("div",{className:"absolute flex items-center gap-1.5 type-data-sm -translate-x-1/2",style:{left:`calc(48px + ${100*m}% * (1 - 48px / 100%))`},children:[s.jsx(ie,{mode:"wait",children:s.jsx(oe.span,{initial:!!w&&{opacity:0,scale:.5,rotate:-90},animate:{opacity:1,scale:1,rotate:0},exit:{opacity:0,scale:.5,rotate:90},transition:{duration:.25,ease:"easeOut"},children:v?s.jsx(re,{className:"w-4 h-4 text-sys-amber"}):s.jsx(ce,{className:"w-4 h-4 text-sys-blue"})},v?"sun":"moon")}),s.jsx("span",{className:"text-fg-secondary",children:y})]})}),s.jsx("div",{className:"flex-1 min-h-0",children:j&&s.jsx(a,{buckets:f,activeTypes:p,gridColor:r.grid,axisTickColor:r.axisTick,onHover:b})}),s.jsx("div",{className:"pt-2 px-1 pb-2 shrink-0",children:j&&s.jsx(n,{activeTypes:p,totalByType:g})})]})}se(rs);const ds=e.memo(function({buckets:t,activeTypes:a}){const n=e.useRef(null),o=e.useRef(t),r=e.useRef(a);o.current=t,r.current=a;const c=e.useMemo(()=>[t.map(e=>e.start),t.map(()=>1)],[t]);return e.useEffect(()=>{if(!n.current||0===t.length)return;const e=n.current,s=e.getBoundingClientRect(),a=Math.floor(s.width)||200,d=Math.floor(s.height)||60,m=new He({width:a,height:d,padding:[0,0,0,0],cursor:{show:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[e=>{const s=e.ctx,{left:t,top:a,width:n,height:c}=e.bbox;!function(e,s,t,a,n,o,r){if(0===s.length)return;const c=function(e,s,t){var a,n;if(e.length<=t)return e;const l=e.length/t,i=[];for(let o=0;o0&&(d.bytesByType[t]=(d.bytesByType[t]??0)+s)}}i.push(d)}return i}(s,t,i.statsCard),d=c.length,m=o/d,u=c.map(e=>e.totalBytes),x=Math.max(...u);if(0!==x){for(let s=0;s{const s=e.getBoundingClientRect();s.width>0&&s.height>0&&m.setSize({width:Math.floor(s.width),height:Math.floor(s.height)})});return u.observe(e),()=>{u.disconnect(),m.destroy()}},[c,t.length]),0===t.length?s.jsx("div",{className:"h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})}):s.jsx("div",{ref:n,className:"w-full h-full"})}),ms=[{target:"ForwardedCard",fn:"type",minStage:1}];function us({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(ms);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;ma)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"FORWARDED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Ratio"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(ms);const xs=[{target:"DroppedCard",fn:"type",minStage:1}];function hs({value:t,receivedCount:a,packets:n,rangeMinutes:l,bucketCount:i,timeRangeLabel:d,icon:m,isLoaded:u=!0}){ee(xs);const{buckets:x,activeTypes:h,ratePerHour:f}=e.useMemo(()=>function(e,s,t){const a=Date.now()/1e3,n=60*s,l=a-n,i=n/t,o=[];for(let m=0;ma)continue;const s=Math.min(t-1,Math.floor((e-l)/i)),n=m.type??m.payload_type??0,d=m.length??m.payload_length??0,u=o[s];u.bytesByType[n]=(u.bytesByType[n]??0)+d,u.totalBytes+=d,r[n]=(r[n]??0)+d,c++}const d=s/60;return{buckets:o,activeTypes:Object.keys(r).map(e=>parseInt(e,10)).filter(e=>r[e]>0).sort((e,s)=>r[s]-r[e]),ratePerHour:d>0?Math.round(c/d):0}}(n,l,i),[n,l,i]),p=a>0?(t/a*100).toFixed(1):null;return u?s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[m&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:m}),s.jsx("span",{className:"type-micro",children:"DROPPED"}),d&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:d})]}),s.jsx("div",{className:"type-data-xl text-fg-primary",children:s.jsx(Pe,{value:t,className:"font-mono tabular-nums",priority:"high"})}),s.jsx("div",{className:"flex-1 mt-1 overflow-hidden min-h-[40px] sm:min-h-[60px]",children:h.length>0?s.jsx(ds,{buckets:x,activeTypes:h}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("div",{className:"w-full h-0.5 rounded-full bg-fg-muted/15"})})}),s.jsx("div",{className:"pt-1.5 sm:pt-2 mt-1",children:s.jsxs("div",{className:"flex gap-2 sm:gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Rate"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[f,"/hr"]})]}),null!==p&&s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Drop %"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[p,"%"]})]})]})})]}):s.jsx(o,{children:s.jsx(r,{})})}se(xs);const fs={",":"punc",".":"punc-period",":":"punc-colon","/":"punc-slash"},ps=/([,\.:\/])/g,gs=e.memo(function({children:t,className:a="",as:n="span"}){const l=e.useMemo(()=>{let e;return e="number"==typeof t?t.toLocaleString():Array.isArray(t)?t.join(""):String(t??""),ps.test(e)?(ps.lastIndex=0,e.split(ps).map((e,t)=>{const a=fs[e];return a?s.jsx("span",{className:a,children:e},t):e})):e},[t]);return s.jsx(n,{className:`data-tight ${a}`.trim(),children:l})});function bs(e,s,t){return Ee(Math.max(s,Math.min(t,e)))}function js({stats:t,receivedBuckets:a,droppedBuckets:n,forwardedBuckets:l,bucketDurationSeconds:i,timeRangeLabel:u,isLoaded:x=!0}){var h,f,p,g;const[b,j]=e.useState(!1),[v,y]=e.useState("idle"),N=d(),w=e.useCallback(async(e,s)=>{if("applying"!==v){y("applying");try{const t=await m({tx_delay_factor:e,direct_tx_delay_factor:s});(null==t?void 0:t.success)?(y("success"),setTimeout(()=>y("idle"),2e3)):(y("error"),setTimeout(()=>y("idle"),2500))}catch{y("error"),setTimeout(()=>y("idle"),2500)}}},[v]);if(!x)return s.jsx(o,{children:s.jsx(r,{})});const k=Math.floor(Date.now()/1e3)-604800,M=Object.values((null==t?void 0:t.neighbors)??{}).filter(e=>e.zero_hop&&e.last_seen>=k&&Ae(e).isRepeater).length,C=N.filter(e=>"active"===e.status||e.lastSeen>=k).length,S=Math.max(M,C),L=function(e,s,t){const a=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,n=a(s),l=a(t),i=n||(null==e?void 0:e.rx_count)||1,o=l||(null==e?void 0:e.dropped_count)||0;return i>0?o/(i+o)*100:0}(t,a,n),T=function(e,s,t){if((null==s?void 0:s.length)&&t){const e=100;return((null==(a=s)?void 0:a.reduce((e,s)=>e+s.count,0))??0)*e/(s.length*t*1e3)*100}var a;if(e){const s=1e3*(e.uptime_seconds||1);return(e.total_airtime_ms||e.airtime_used_ms||0)/s*100}return 0}(t,l,i),B=(null==(f=null==(h=null==t?void 0:t.config)?void 0:h.delays)?void 0:f.tx_delay_factor)??null,F=(null==(g=null==(p=null==t?void 0:t.config)?void 0:p.delays)?void 0:g.direct_tx_delay_factor)??null,_=function(e,s,t,a){let n=Ie(e);s>20?n+=2*qe:s>12&&(n+=qe),t>8&&(n+=qe);const l=bs(n,0,2);let i=We(e);t>8&&(i+=qe);const o=bs(i,0,1),r=ze(l),c=ze(o),d=null!==a?ze(a):null;let m="stable";return null!==d&&(r>d?m="increase":r20?$.push(`High duplicate rate (${L.toFixed(1)}%) suggests frequent collisions — window widened.`):L>12&&$.push(`Elevated duplicate rate (${L.toFixed(1)}%) — window widened one step.`),T>8&&$.push(`Channel is busy (${T.toFixed(1)}% TX util) — extra spacing added.`));const H=[`Direct uses one forwarder — ×${_.directFactor.toFixed(1)} backoff for channel contention.`];T>8&&H.push("Busy channel — small extra backoff.");const P=[`Flood ×${_.floodFactor.toFixed(1)} (${_.floodSlots} slot${1!==_.floodSlots?"s":""})`,...$,"",`Direct ×${_.directFactor.toFixed(1)}`,...H,"","Click to copy CLI commands"].join("\n"),A=null!==B?ze(B):null,I=null!==F?ze(F):null,z=null!==A&&_.floodSlots!==A,E=null!==I&&_.directSlots!==I,W=z||E;return s.jsxs(o,{children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3 flex-wrap",children:[s.jsx(de,{className:"w-4 h-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"DELAY DOCTOR"}),u&&s.jsx(c,{color:"zinc",className:"hidden sm:inline-flex",children:u})]}),s.jsxs("button",{onClick:async()=>{const e=`set txdelay ${_.floodFactor.toFixed(1)}\nset direct.txdelay ${_.directFactor.toFixed(1)}`;try{await navigator.clipboard.writeText(e),j(!0),setTimeout(()=>j(!1),1500)}catch{const s=document.createElement("textarea");s.value=e,s.style.position="fixed",s.style.opacity="0",document.body.appendChild(s),s.select();try{document.execCommand("copy"),j(!0),setTimeout(()=>j(!1),1500)}catch{console.error("Failed to copy commands")}document.body.removeChild(s)}},className:"flex gap-3 mb-2 sm:mb-3 w-full text-left hover:bg-subtle-fill radius-inner transition-base p-1 -m-1 group",title:P,children:[s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-fg-primary",children:s.jsxs(gs,{children:["×",_.floodFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Flood"})]}),s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsx("span",{className:"type-data-xl text-sys-blue",children:s.jsxs(gs,{children:["×",_.directFactor.toFixed(1)]})}),s.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Direct"})]}),s.jsx("div",{className:"flex items-center self-center opacity-0 group-hover:opacity-100 transition-opacity",children:b?s.jsx(me,{className:"w-4 h-4 text-sys-green"}):s.jsx(ue,{className:"w-4 h-4 text-fg-muted"})})]}),s.jsx("div",{className:"flex-1 py-2",children:s.jsxs("div",{className:"flex gap-3",children:[s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"Dupe"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left "+(_.duplicateRate>8?"text-status-warning":""),children:[_.duplicateRate.toFixed(1),"%"]})]}),s.jsxs("div",{className:"flex-1",children:[s.jsx("div",{className:"data-box-label",children:"TX Util"}),s.jsxs("div",{className:"data-box data-box-fill data-box-left",children:[_.txUtilization.toFixed(2),"%"]})]})]})}),s.jsx("div",{className:"pt-2 mt-auto",children:s.jsxs("div",{className:"flex items-end justify-between gap-2",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Current"}),s.jsx("div",{className:"flex gap-2",children:null!==B?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"data-box",children:["×",B.toFixed(2)]}),s.jsxs("div",{className:"data-box",style:{color:"var(--sys-blue)"},children:["×",(null==F?void 0:F.toFixed(2))??"—"]})]}):s.jsx("span",{className:"text-sm text-fg-muted",children:"No config"})})]}),W&&s.jsxs("button",{onClick:()=>w(_.floodFactor,_.directFactor),disabled:"applying"===v||"success"===v,className:"flex items-center gap-1.5 px-2.5 py-1.5 radius-inner type-micro font-medium transition-base\n "+("success"===v?"bg-sys-green/15 text-sys-green":"error"===v?"bg-sys-red/15 text-sys-red":"applying"===v?"bg-subtle-fill text-fg-muted":"bg-sys-blue/10 text-sys-blue hover:bg-sys-blue/20"),title:`Apply ×${_.floodFactor.toFixed(1)} flood, ×${_.directFactor.toFixed(1)} direct`,children:["success"===v?"Rx'd":"error"===v?"Failed":"Apply","applying"===v?s.jsx(xe,{className:"w-3.5 h-3.5 animate-spin"}):"success"===v?s.jsx(me,{className:"w-3.5 h-3.5"}):s.jsxs("span",{className:"relative inline-flex items-end w-6 h-3.5",children:[s.jsx(he,{className:"w-3.5 h-3.5 absolute left-0 bottom-0"}),s.jsx(fe,{className:"w-3 h-3 absolute right-0 bottom-0"})]})]})]})})]})}const vs=[{target:"RecentPackets",fn:"rssi",minStage:1},{target:"RecentPackets",fn:"snr",minStage:1}];function ys(){ee(vs);const t=u(),a=x(),n=h(),l=f(),i=Ue(),r=Oe(e=>e.requestChannel),[c,d]=e.useState(!0),m=e.useCallback(e=>d(e),[]),v=e.useMemo(()=>[...t.length<=100?t:t.slice(-100)].sort((e,s)=>(s.timestamp??0)-(e.timestamp??0)),[t]),y=null==l?void 0:l.local_hash,N=null==l?void 0:l.neighbors,w=Je();return s.jsxs(o,{noPadding:!0,className:"!overflow-visible",children:[s.jsx(p,{listHeader:!0,icon:s.jsx(ge,{}),title:"Recent Packets",actions:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(g,{enabled:c,onChange:m,label:"Hide Dupes",size:"sm"}),n&&s.jsx(b,{showLabel:!0}),s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})]})}),s.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto px-1",children:s.jsx(Ge,{packets:v,allPackets:t,localHash:y,neighbors:N,resolveSource:w,getDecodedContent:i,onChannelClick:r,loading:a,maxPackets:25,showPagination:!1,flashNewest:!0,hideDupes:c,emptyMessage:"No packets received",footerAction:s.jsxs(j,{color:"primary",outline:!0,href:"/packets",children:["View all",s.jsx(pe,{"data-slot":"icon"})]})})})]})}se(vs);const Ns={stable:"M5 12h14",up:"M5 15l7-7 7 7",down:"M19 9l-7 7-7-7"};function ws({trend:e}){return s.jsx("span",{className:`mini-widget-trend ${e}`,children:s.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:Ns[e]})})})}function ks(){return s.jsx("div",{className:"mini-widget-loading",children:s.jsx("div",{className:"mini-widget-loading-spinner"})})}function Ms({message:e}){return s.jsx("div",{className:"mini-widget-error",children:s.jsx("span",{title:e,children:"No data"})})}function Cs({title:e,icon:t,value:a,unit:n,valueSize:l="md",status:i,subtitle:r,trend:c,children:d,isLoading:m=!1,error:u,className:x="",onClick:h}){const f=["mini-widget-value","lg"===l&&"mini-widget-value-lg","sm"===l&&"mini-widget-value-sm"].filter(Boolean).join(" "),p=["mini-widget",x].filter(Boolean).join(" ");return s.jsxs(o,{noPadding:!0,className:p,onClick:h,children:[s.jsxs("div",{className:"mini-widget-header",children:[t,s.jsx("span",{className:"mini-widget-title",children:e}),i&&"unknown"!==i&&s.jsx("div",{className:`mini-widget-status-dot ${i}`}),c&&s.jsx(ws,{trend:c})]}),m?s.jsx(ks,{}):u?s.jsx(Ms,{message:u}):s.jsxs(s.Fragment,{children:[void 0!==a&&s.jsxs("div",{className:f,children:["number"==typeof a?s.jsx(Pe,{value:a,className:"font-mono tabular-nums",priority:"medium",format:Number.isInteger(a)?void 0:{minimumFractionDigits:1,maximumFractionDigits:1}}):s.jsx(gs,{children:a}),n&&s.jsx("span",{className:"mini-widget-unit",children:n})]}),r&&s.jsx("div",{className:"mini-widget-subtitle",children:r}),d]})]})}const Ss={DELTA_CRITICAL:10,SLOPE_CRITICAL:4,JITTER_CRITICAL:6,DELTA_WARNING:5,SLOPE_WARNING:2,JITTER_WARNING:4},Ls={baselineMedian:null,baselineP10:null,baselineP90:null,currentMedian:null,currentSampleCount:0,delta:0,slope:0,jitter:0,penalty:0,penaltyReason:null,computedAt:0,isReliable:!1};function Ts(e,s){if(0===e.length)return null;const t=[...e].sort((e,s)=>e-s),a=s/100*(t.length-1),n=Math.floor(a),l=Math.ceil(a);return n===l?t[n]:t[n]+(t[l]-t[n])*(a-n)}function Bs(e){return Ts(e,50)}const Fs={lbtStats:null,noiseFloor:null,sparklineNoiseFloor:[],noiseFloorWindowHistory:[],linkQuality:null,channelHealth:null,nfTrend:Ls,radioConfig:null,trends:null,stats:null,recentPackets:[],quickNeighbors:[],isLoading:!0,error:null,refresh:async()=>{}},_s=e.createContext(Fs);function Rs({children:t}){var a;const n=f(),l=u(),i=v(),o=y(),r=N(),c=w[r],d=Math.max(1,c.minutes/60),m=null===n,x=e.useMemo(()=>k(l,d),[l,d]),h=(null==n?void 0:n.noise_floor_dbm)??null,p=e.useMemo(()=>M(h)?h:null,[h]),g=e.useMemo(()=>{var e;const s=null==(e=null==n?void 0:n.config)?void 0:e.radio;return s?{sf:s.spreading_factor??7,bwHz:s.bandwidth??125e3}:null},[null==(a=null==n?void 0:n.config)?void 0:a.radio]),b=C(d),j=S(d),F=null==n?void 0:n.neighbors,_=e.useMemo(()=>{const e=F??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!o.has(e)))},[F,o]),R=e.useMemo(()=>i.filter(e=>!o.has(e.hash)),[i,o]),D=e.useMemo(()=>function(e){if(0===e.length)return{...Ls,computedAt:Math.floor(Date.now()/1e3)};const s=Math.floor(Date.now()/1e3),t=e.filter(e=>Number.isFinite(e)),a=e.length>0?[e[e.length-1]]:[],n=e.slice(-4).filter(e=>Number.isFinite(e)),l=Bs(t),i=Ts(t,10),o=Ts(t,90),r=Bs(a),c=null!==r&&null!==i?r-i:0,d=function(e){if(e.length<2)return 0;const s=e.length;let t=0,a=0,n=0,l=0;const i=e[0].timestamp;for(const r of e){const e=(r.timestamp-i)/3600,s=r.value;t+=e,a+=s,n+=e*s,l+=e*e}const o=s*l-t*t;return Math.abs(o)<1e-4?0:(s*n-t*a)/o}(n.map((e,t)=>({timestamp:s-3600*(n.length-1-t),value:e}))),m=function(e){if(e.length<2)return 0;const s=e.reduce((e,s)=>e+s,0)/e.length,t=e.map(e=>Math.pow(e-s,2)).reduce((e,s)=>e+s,0)/e.length;return Math.sqrt(t)}(n),u=t.length>=12,[x,h]=u?function(e,s,t){const a=Ss;return e>=a.DELTA_CRITICAL?[2,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_CRITICAL?[2,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_CRITICAL?[2,`Noise floor unstable (±${t.toFixed(1)} dB)`]:e>=a.DELTA_WARNING?[1,`Noise floor ${e.toFixed(1)} dB above baseline`]:s>=a.SLOPE_WARNING?[1,`Noise floor rising ${s.toFixed(1)} dB/hour`]:t>=a.JITTER_WARNING?[1,`Noise floor variable (±${t.toFixed(1)} dB)`]:[0,null]}(c,d,m):[0,null];return{baselineMedian:l,baselineP10:i,baselineP90:o,currentMedian:r,currentSampleCount:a.length,delta:c,slope:d,jitter:m,penalty:x,penaltyReason:h,computedAt:s,isReliable:u}}(b),[b]),$=e.useMemo(()=>L(R,_,g),[R,_,g]),H=e.useMemo(()=>T(x,p,$),[x,p,$]),[P,A]=e.useState({noiseFloor:null,networkScore:null,channelHealth:null}),I=e.useRef(0);e.useEffect(()=>{const e=()=>{const e=Date.now();e-I.current>3e4&&(I.current=e,A({noiseFloor:p,networkScore:(null==$?void 0:$.networkScore)??null,channelHealth:(null==H?void 0:H.score)??null}))};e();const s=setInterval(e,5e3);return()=>clearInterval(s)},[p,null==$?void 0:$.networkScore,null==H?void 0:H.score]);const z=e.useMemo(()=>({noiseFloor:{current:p,previous:P.noiseFloor,trend:null!==p?B(p,P.noiseFloor,2,!0):"stable"},networkScore:{current:(null==$?void 0:$.networkScore)??0,previous:P.networkScore,trend:B((null==$?void 0:$.networkScore)??0,P.networkScore,3,!1)},channelHealth:{current:(null==H?void 0:H.score)??0,previous:P.channelHealth,trend:B((null==H?void 0:H.score)??0,P.channelHealth,3,!1)}}),[p,null==$?void 0:$.networkScore,null==H?void 0:H.score,P]),E={lbtStats:x,noiseFloor:p,sparklineNoiseFloor:b,noiseFloorWindowHistory:j,linkQuality:$,channelHealth:H,nfTrend:D,radioConfig:g,trends:z,stats:n,recentPackets:l,quickNeighbors:i,isLoading:m,error:null,refresh:async()=>{}};return s.jsx(_s.Provider,{value:E,children:t})}function Ds(){const s=e.useContext(_s);if(void 0===s)throw new Error("useLBTData must be used within an LBTDataProvider");return s}function $s(e,s){return 0===e?"No backoffs":`${s.toFixed(0)}% retry rate`}function Hs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=Ye(),i=(null==t?void 0:t.avgBackoffMs)??0,o=(null==t?void 0:t.retryRate)??0,r=t?(c=i)<100?"excellent":c<250?"good":c<500?"fair":c<1e3?"congested":"critical":"unknown";var c;const d=null==t?void 0:t.sparklineBackoff,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]);return s.jsx(Cs,{title:"LBT Backoff",icon:s.jsx(be,{className:"mini-widget-icon"}),value:Math.round(i),unit:"ms",status:r,subtitle:t?$s(i,o):void 0,isLoading:a,error:n,onClick:()=>l("/packets"),children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Ps(e){return 0===e?"—":e<1?"<1":Math.round(e).toString()}function As(){const{lbtStats:e,isLoading:t,error:a}=Ds(),n=Ye(),l=(null==e?void 0:e.channelBusyCount)??0,i=(null==e?void 0:e.totalPacketsWithLBT)??0,o=(null==e?void 0:e.channelBusyRate)??0,r=(null==e?void 0:e.retryRate)??0,c=(null==e?void 0:e.avgBackoffMs)??0,d=(null==e?void 0:e.minBackoffMs)??0,m=(null==e?void 0:e.maxBackoffMs)??0,u=r>0?Math.max(0,(r-o)/r*100):100;return s.jsx(Cs,{title:"Ch. Busy",icon:s.jsx(je,{className:"mini-widget-icon"}),isLoading:t,error:a,onClick:()=>n("/packets"),children:s.jsx("div",{className:"flex-1 flex items-end",children:s.jsxs("div",{className:"grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto_minmax(0,1fr)] gap-x-2 gap-y-1 sm:gap-y-2 w-full items-baseline",children:[s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:"Failed:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${l} packets exceeded max CAD attempts (5) out of ${i} total transmissions.`,children:[s.jsx(gs,{children:l}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:i})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:"Sent:"}),s.jsx("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`${u.toFixed(1)}% of packets that needed LBT retries were sent successfully.`,children:s.jsxs(gs,{children:[u.toFixed(0),"%"]})}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:"Mean:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Average LBT backoff delay: ${c.toFixed(0)}ms.`,children:[s.jsx(gs,{children:Ps(c)}),s.jsx("span",{className:"text-fg-muted text-xs",children:"ms"})]}),s.jsx("span",{className:"data-box-label mb-0 text-[10px] sm:text-sm",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:"Range:"}),s.jsxs("div",{className:"data-box data-box-compact sm:data-box justify-self-start",title:`Backoff range: ${d.toFixed(0)}ms min, ${m.toFixed(0)}ms max.`,children:[s.jsx(gs,{children:Ps(d)}),s.jsx("span",{className:"text-fg-muted punc-slash",children:"/"}),s.jsx(gs,{children:Ps(m)})]})]})})})}function Is(e){return null===e?"No reading":e<-115?"Very quiet":e<-105?"Quiet":e<-95?"Moderate":e<-85?"Elevated":"High interference"}function zs(){const{noiseFloor:t,noiseFloorWindowHistory:a,trends:n,isLoading:l,error:i}=Ds(),o=null===(r=t)||r<-110?"excellent":r<-100?"good":r<-90?"fair":r<-80?"congested":"critical";var r;const c=null==n?void 0:n.noiseFloor.trend,d=e.useMemo(()=>{if(!a||a.length<2)return[];return function(e,s,t,a){const n=e.length;if(0===n)return[];if(1===n)return new Array(a).fill(s[0]);if(2===n){const e=new Array(a);for(let t=0;te-s),m=Math.max(a[l-1],1e-10);let u=0,x=0,h=0,f=0,p=0;for(let l=0;l=1)continue;const n=a*a*a,i=(1-n)*(1-n)*(1-n),o=e[l]-t;u+=i,x+=i*o,h+=i*s[l],f+=i*o*o,p+=i*o*s[l]}if(0===u){r[d]=s[Math.round(d/47*(n-1))];continue}const g=u*f-x*x;r[d]=Math.abs(g)<1e-10?h/u:(f*h-x*p)/g}return r}(a.map(e=>e.timestamp),a.map(e=>-e.noise_floor_dbm),0,48).map((e,s)=>({timestamp:Date.now()-36e5*(47-s),count:e}))},[a]),m=null!==t?Math.round(t):"—";return s.jsx(Cs,{title:"Noise Floor",icon:s.jsx(ve,{className:"mini-widget-icon"}),value:m,unit:null!==t?"dBm":void 0,status:o,trend:c,subtitle:Is(t),isLoading:l,error:i,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:d,width:9999,height:22,color:"var(--sys-blue)",isLoading:l,className:"w-full"})})})}const Es=[{target:"LinkLeaders",fn:"path",minStage:1,when:ae},{target:"LinkLeaders",fn:"src_hash",minStage:1,when:ne}];function Ws(){ee(Es);const t=Ye(),a=v(),n=u(),l=f(),i=N(),o=60*w[i].minutes,r=F(),c=e.useMemo(()=>{if(0===r)return n;const e=r-o;return n.filter(s=>s.timestamp>=e)},[n,o,r]),d=null===l,m=(null==l?void 0:l.local_hash)?_(l.local_hash):"",x=(null==l?void 0:l.neighbors)??{},{neighborHashes:h,neighborNames:p}=e.useMemo(()=>{const e=new Set,s=new Map;for(const t of a){e.add(t.hash);const a=x[t.hash],n=(null==a?void 0:a.name)||(null==a?void 0:a.node_name)||t.prefix;s.set(t.hash,n)}return{neighborHashes:e,neighborNames:s}},[a,x]),g=e.useMemo(()=>{if(0===h.size||0===c.length||!m)return{champion:null,listener:null,loudest:null};const{scores:e}=Qe(c,h,m),s=[];for(const[l,i]of e)0!==i.blendedScore&&s.push({...i,name:p.get(l)??_(l)});let t=null,a=null,n=null;for(const l of s)(!t||l.blendedScore>t.blendedScore)&&(t=l),(!a||l.listenerScore>a.listenerScore)&&(a=l),(!n||l.loudScore>n.loudScore)&&(n=l);return{champion:t,listener:a,loudest:n}},[c,h,m,p]),{champion:b,listener:j,loudest:y}=g,k=b||j||y?s.jsxs("div",{className:"flex flex-col gap-0 sm:gap-0.5 mt-auto",children:[b&&s.jsx(R,{content:(M=b,s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["🏆 Champion: ",M.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Blended Score: ",M.blendedScore,s.jsx("span",{className:"text-fg-muted/60 ml-1",children:"(Listener + Loud)"})]}),s.jsxs("div",{className:"border-t border-edge-subtle pt-1 mt-1 space-y-0.5",children:[s.jsxs("div",{children:["Listener: ",M.listenerScore,"/100 (",M.listenerCount," shared paths)"]}),s.jsxs("div",{children:["Loud: ",M.loudScore,"/100 (",M.loudCount," packets relayed)"]})]})]})),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(ye,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-map-neighbor-color flex-shrink-0"}),s.jsx("span",{className:"font-semibold text-map-neighbor-color font-mono truncate flex-1 min-w-0",children:b.name}),s.jsx("span",{className:"text-map-neighbor-color pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:b.blendedScore})]})}),j&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["👂 Best Listener: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.listenerScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.listenerCount," packets where they heard your transmissions"]})})]}))(j),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(Ne,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:j.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:j.listenerScore})]})}),y&&s.jsx(R,{content:(e=>s.jsxs("div",{className:"max-w-[220px]",children:[s.jsxs("div",{className:"font-semibold mb-1",children:["📢 Loudest: ",e.name]}),s.jsxs("div",{className:"text-fg-muted mb-1",children:["Score: ",e.loudScore,"/100"]}),s.jsx("div",{className:"border-t border-edge-subtle pt-1 mt-1",children:s.jsxs("div",{children:[e.loudCount," packets they relayed directly to you"]})})]}))(y),children:s.jsxs("div",{className:"flex items-center gap-1 text-xs sm:text-sm radius-badge px-1 -mx-1 hover-bg transition-base cursor-default",children:[s.jsx(we,{className:"w-2.5 h-2.5 sm:w-3 sm:h-3 text-fg-muted flex-shrink-0"}),s.jsx("span",{className:"text-fg-muted font-mono truncate flex-1 min-w-0",children:y.name}),s.jsx("span",{className:"text-fg-muted pl-1 sm:pl-2 tabular-nums flex-shrink-0 w-7 sm:w-9 text-right",children:y.loudScore})]})})]}):0===a.length?s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No direct neighbors"}):s.jsx("div",{className:"flex items-center justify-center text-xs sm:text-sm text-fg-muted mt-auto",children:"No routing data yet"});var M;return s.jsx(Cs,{title:"Link Leaders",icon:s.jsx(ke,{className:"mini-widget-icon"}),isLoading:d,onClick:()=>t("/contacts"),children:k})}function qs(){const{lbtStats:t,isLoading:a,error:n}=Ds(),l=t?function(e){const{retryRate:s,channelBusyCount:t,totalPacketsWithLBT:a,avgBackoffMs:n,maxBackoffMs:l}=e;if(0===a)return 0;const i=Math.min(a/10,1),o=Math.log(1+.15*s)/Math.log(16)*40,r=t/a*100,c=Math.min(.5*r,25);let d=0;n>100&&(d=Math.min(8*Math.log10(n/100),15));let m=0;l>500&&n>0&&l>2*n&&(m=Math.min((l-500)/200,5));const u=(o+c+d+m)*i;return Math.min(u,85)}(t):0,i=t?(o=l)<15?"excellent":o<30?"good":o<45?"fair":o<60?"congested":"critical":"unknown";var o;const r=(null==t?void 0:t.maxBackoffMs)??0,c=t?r>200?`Max backoff: ${Math.round(r)}ms`:function(e){return e<15?"Clear channel":e<30?"Light traffic":e<45?"Moderate traffic":e<60?"Heavy traffic":e<75?"Congested":"Severe congestion"}(l):void 0,d=null==t?void 0:t.sparklineCollisionRisk,m=e.useMemo(()=>!d||d.length<2?[]:d.map((e,s)=>({timestamp:Date.now()-36e5*(d.length-1-s),count:e})),[d]),u=Math.round(10*l)/10;return s.jsx(Cs,{title:"Collision Risk",icon:s.jsx(Me,{className:"mini-widget-icon"}),value:u,unit:"%",status:i,subtitle:c,isLoading:a,error:n,children:s.jsx("div",{className:"mini-widget-sparkline w-full",children:s.jsx(Xe,{data:m,width:9999,height:24,color:"var(--sys-blue)",isLoading:a,className:"w-full"})})})}function Os(){const[t,a]=e.useState(!1),[n]=e.useState(0),{stats:l,lbtStats:i,isLoading:o}=Ds(),r=e.useMemo(()=>{if(!l)return null;const e=l.airtime_used_ms??0,s=l.max_airtime_ms??1;return{usedMs:e,maxMs:s,remainingMs:l.airtime_remaining_ms??0,utilizationPercent:l.utilization_percent??(s>0?e/s*100:0)}},[l]),c=e.useMemo(()=>i&&0!==i.totalPacketsWithLBT?(i.totalPacketsWithLBT-i.packetsWithRetries)/i.totalPacketsWithLBT*100:100,[i]),d=(null==r?void 0:r.utilizationPercent)??0,m=(u=d)<30?"excellent":u<50?"good":u<70?"fair":u<90?"congested":"critical";var u;const x=(null==r?void 0:r.remainingMs)??0,h=c<95?`${c.toFixed(0)}% clean TX`:((f=x)<1e3?`${Math.round(f)}ms`:f<6e4?`${(f/1e3).toFixed(1)}s`:`${(f/6e4).toFixed(1)}m`)+" remaining";var f;const p=r?s.jsx("div",{className:"mini-widget-progress mt-auto",children:s.jsx("div",{className:`mini-widget-progress-bar ${m}`,style:{width:`${Math.min(d,100)}%`}})}):null;return s.jsx(Cs,{title:"Duty Cycle",icon:s.jsx(ge,{className:"mini-widget-icon"}),value:d.toFixed(1),unit:"%",status:m,subtitle:h,isLoading:o,children:p})}function Gs(){return s.jsxs("div",{className:"mini-widget",children:[s.jsxs("div",{className:"mini-widget-header",children:[s.jsx(D,{className:"w-4 h-4"}),s.jsx(D,{className:"h-3 w-16"})]}),s.jsx(D,{className:"h-7 w-12 mt-2"}),s.jsx(D,{className:"h-3 w-20 mt-2"})]})}function Vs(){return s.jsx("div",{className:"widget-row",children:Array.from({length:6}).map((e,t)=>s.jsx(Gs,{},t))})}se(Es);const Us=[{target:"MeshHealth",fn:"type",minStage:1}];function Js({className:e="",isLoaded:t=!0}){return ee(Us),s.jsxs("div",{className:`mesh-health-container relative ${e}`,children:[s.jsxs("div",{className:"mesh-health-header",children:[s.jsx(Ce,{className:"w-4 h-4 text-sys-blue"}),s.jsx("span",{className:"type-label text-fg-muted",children:"MESH HEALTH"})]}),t?s.jsx(Rs,{children:s.jsxs("div",{className:"widget-row",children:[s.jsx(Hs,{}),s.jsx(qs,{}),s.jsx(zs,{}),s.jsx(Os,{}),s.jsx(As,{}),s.jsx(Ws,{})]})}):s.jsx(Vs,{})]})}se(Us);const Ks=[{target:"PublicChannel",fn:"decrypt",minStage:2,when:le}];se(Ks);let Xs="",Qs="",Ys="";function Zs(e){!function(){const e=new Date,s=e.toDateString();if(s!==Ys){Ys=s,Xs=s;const t=new Date(e);t.setDate(t.getDate()-1),Qs=t.toDateString()}}();const s=new Date(1e3*e).toDateString();return s===Xs?"Today":s===Qs?"Yesterday":new Date(1e3*e).toLocaleDateString([],{weekday:"short",month:"short",day:"numeric"})}function et(e,s,t){return`${e||""}|${s}|${t}`}const st=e.memo(function({message:e,onChannelClick:t,isChannelSelected:a}){const n=e.channelName||e.channelHash.slice(0,6);return s.jsx("div",{style:{transform:"translateZ(0)",willChange:"transform"},children:s.jsx(ls,{senderName:e.senderName||"Unknown",text:e.text,timestamp:e.timestamp,nameAccessory:s.jsx(Ve,{channelName:n,active:a,onClick:()=>null==t?void 0:t(e.channelHash)})})})},function(e,s){const t=e.message,a=s.message;return t.timestamp===a.timestamp&&t.text===a.text&&t.senderName===a.senderName&&t.channelHash===a.channelHash&&t.channelName===a.channelName&&e.isChannelSelected===s.isChannelSelected&&e.onChannelClick===s.onChannelClick});function tt({open:t,onClose:a,messages:n,onLoadMore:l,hasMoreToLoad:i,isDecoding:o,initialChannel:r}){const c=e.useRef(null),d=e.useRef(!0),m=N(),u=W(),x=e.useRef(!1);e.useEffect(()=>{t?(x.current=!0,q.resume()):x.current&&q.pause()},[t]);const h=e.useMemo(()=>{const e=Date.now()/1e3-60*w[m].minutes;return[...n].filter(s=>s.timestamp>=e).sort((e,s)=>e.timestamp-s.timestamp)},[n,m]),f=e.useCallback(()=>{const e=c.current;e&&(d.current=e.scrollTop>=-50)},[]),p=e.useMemo(()=>{const e=new Map;for(const s of h){const t=s.channelHash,a=e.get(t);a?a.count++:e.set(t,{name:s.channelName||s.channelHash.slice(0,6),hash:s.channelHash,count:1})}return Array.from(e.values()).sort((e,s)=>s.count-e.count)},[h]),g=p.length,[b,j]=e.useState(null),[v,y]=e.useState(!1);e.useEffect(()=>{t&&r&&j(r)},[t,r]);const k=e.useCallback(()=>{l(b,p)},[l,b,p]),M=e.useMemo(()=>b?h.filter(e=>e.channelHash===b):h,[h,b]),C=e.useMemo(()=>{const e=[];let s="";for(const t of M){const a=Zs(t.timestamp);a!==s&&(e.push({type:"date",date:a}),s=a),e.push({type:"message",message:t})}return e},[M]);e.useLayoutEffect(()=>{const e=c.current;e&&d.current&&(e.scrollTop=0)},[M.length]);const S=p.slice(0,19),L=p.slice(19),T=L.length>0;return s.jsx(O,{open:t,onClose:a,size:"lg",motionPlus:!0,solid:!0,children:s.jsxs(G,{className:"p-0 flex flex-col h-[80vh] max-h-[700px] rounded-2xl",children:[s.jsx("div",{className:"flex-shrink-0 px-4 sm:px-5 py-3 sm:py-4",children:s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Se,{className:"size-5 text-icon-card-title flex-shrink-0"}),s.jsx("h2",{className:"type-micro",children:"Public Channels"})]}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:u,size:"sm"}),s.jsx("button",{onClick:a,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),s.jsx("button",{onClick:a,className:"hidden sm:flex items-center justify-center p-2 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-subtle","aria-label":"Close",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}),s.jsx("div",{className:"flex-shrink-0 px-3 pb-2 relative z-10 isolate",style:{minHeight:g>0?void 0:0},children:g>0&&s.jsxs("div",{className:"flex flex-wrap gap-1",children:[s.jsxs("button",{onClick:()=>j(null),className:Ze("px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",null===b?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["All ",g]}),S.map(e=>s.jsx("button",{onClick:()=>j(e.hash),className:Ze("flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",b===e.hash?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:s.jsx("span",{className:"truncate max-w-[80px]",children:e.name})},e.hash)),T&&s.jsxs("div",{className:"relative",children:[s.jsxs("button",{onClick:()=>y(!v),className:Ze("flex items-center gap-0.5 px-2 py-0.5 rounded text-xs font-medium transition-all","ring-1 ring-inset",v||L.some(e=>e.hash===b)?"bg-sys-blue/20 text-sys-blue ring-sys-blue/30":"bg-subtle-fill text-fg-secondary ring-edge-subtle hover:bg-subtle-fill-strong"),children:["+",L.length,s.jsx(Te,{className:Ze("size-3 transition-transform",v&&"rotate-180")})]}),v&&s.jsx("div",{className:Ze("absolute top-full left-0 mt-1 z-50","min-w-[140px] max-h-[200px] overflow-y-auto","p-1 rounded-lg","bg-elevated backdrop-blur-xl","ring-1 ring-edge-subtle shadow-xl"),children:L.map(e=>s.jsxs("button",{onClick:()=>{j(e.hash),y(!1)},className:Ze("w-full flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-all text-left",b===e.hash?"bg-sys-blue/20 text-sys-blue":"text-fg-secondary hover:bg-subtle-fill-strong"),children:[s.jsx(Be,{className:"size-2.5 opacity-60 flex-shrink-0"}),s.jsx("span",{className:"truncate",children:e.name}),s.jsxs("span",{className:"opacity-60 ml-auto",children:["(",e.count,")"]})]},e.hash))})]})]})}),s.jsx("div",{ref:c,onScroll:f,className:Ze("flex-1 overflow-y-auto overflow-x-hidden","mx-3 mb-3 rounded-md","bg-body","ring-1 ring-inset ring-edge-subtle","flex flex-col-reverse"),children:o&&0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(xe,{className:"size-12 mb-4 text-sys-indigo animate-spin"}),s.jsx("p",{className:"text-lg font-medium",children:"Loading messages..."})]}):0===M.length?s.jsxs("div",{className:"flex flex-col items-center justify-center h-full min-h-[300px] text-fg-muted px-4 py-4",children:[s.jsx(Fe,{className:"size-16 mb-4 opacity-20"}),s.jsx("p",{className:"text-lg font-medium",children:"No messages yet"}),s.jsx("p",{className:"text-sm mt-1 opacity-70",children:b?"No messages in this channel":"Public channel messages will appear here"})]}):s.jsxs("div",{className:"px-4 py-4",children:[i&&s.jsx("div",{className:"flex justify-center mb-4",children:s.jsx("button",{onClick:k,disabled:o,className:Ze("px-4 py-1.5 rounded-full","text-[11px] font-medium","ring-1 ring-inset",o?"bg-subtle-fill text-fg-muted ring-edge-subtle cursor-wait":"bg-sys-blue/10 text-sys-blue ring-sys-blue/20 hover:bg-sys-blue/20 hover:ring-sys-blue/30"),children:o?s.jsxs("span",{className:"flex items-center gap-1.5",children:[s.jsx(xe,{className:"size-3 animate-spin"}),"Loading..."]}):"Load older messages"})}),C.map((e,t)=>{if("date"===e.type)return s.jsx("div",{className:"flex justify-center my-4",children:s.jsx("span",{className:Ze("px-3.5 py-1.5 rounded-full","bg-subtle-fill backdrop-blur-sm","text-[11px] text-fg-muted/80 font-medium","ring-1 ring-edge-subtle"),children:e.date})},`date-${e.date}-${t}`);const a=`msg-${e.message.timestamp}-${e.message.senderName||"anon"}-${e.message.channelHash}`;return s.jsx("div",{className:"mb-3",children:s.jsx(st,{message:e.message,onChannelClick:j,isChannelSelected:b===e.message.channelHash})},a)})]})}),s.jsx("div",{className:"flex-shrink-0 px-5 py-2 text-center",children:s.jsxs("p",{className:"text-[11px] text-fg-muted",children:[M.length," messages · ",g," ",1===g?"channel":"channels",o&&s.jsxs("span",{className:"ml-2 text-sys-indigo",children:[s.jsx(xe,{className:"inline size-3 animate-spin mr-1"}),"Decrypting..."]})]})})]})})}function at({isLoaded:t=!0}){ee(Ks);const a=u(),[n,l]=e.useState(!1),[i,o]=e.useState(null),r=N(),c=e.useCallback(()=>{o(null),l(!0),$.getState().queueDecryption(a)},[a]),d=Oe(e=>e.requestedHash),m=Oe(e=>e.clearRequest);e.useEffect(()=>{d&&(o(d),l(!0),$.getState().queueDecryption(a),m())},[d,m,a]);const x=H(),h=P(),f=A(),p=e.useMemo(()=>function(e){const s=[],t=new Set;for(const a of e.values()){const e=a.decoded;if(!e||!e.decrypted||e.macCorrupted||!e.text)continue;const n=et(e.senderName,e.channelHash,e.text);t.has(n)||(t.add(n),s.push({timestamp:a.timestamp,channelName:e.channelName,channelHash:e.channelHash,senderName:e.senderName,text:e.text,rssi:a.rssi,snr:a.snr}))}return s}(x),[x]),g=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes;return p.filter(s=>s.timestamp>=e)},[p,r]),b=e.useMemo(()=>0===g.length?null:g.reduce((e,s)=>s.timestamp>e.timestamp?s:e),[g]),j=h.isDecoding,v=e.useMemo(()=>{const e=Date.now()/1e3-60*w[r].minutes,s=new Set;let t=0;for(const n of a)(n.type??n.payload_type)===I.GRP_TXT&&((n.timestamp??0){const e=Date.now()/1e3-60*w[r].minutes;for(const s of a)if((s.type??s.payload_type)===I.GRP_TXT&&!((s.timestamp??0){if(!j){if(e){const t=s.find(s=>s.hash===e);if(t)return t.name,void $.getState().queueChannelDecryption(a,t.name)}$.getState().queueDecryption(a)}},[a,j]);return t?s.jsxs(s.Fragment,{children:[s.jsx("div",{onClick:c,className:Ze("group cursor-pointer rounded-2xl transition-all duration-150","bg-surface/80 backdrop-blur-lg depth-raised","hover:bg-subtle-fill","px-3 py-2.5 sm:px-4 sm:py-3"),children:s.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex items-center gap-2 sm:gap-3 flex-shrink-0",children:[s.jsx(Se,{className:"size-4 text-icon-card-title flex-shrink-0"}),s.jsx("span",{className:"type-micro",children:"CHAT ACTIVITY"}),v>0&&s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary",children:v}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors ml-auto sm:hidden"})]}),s.jsxs("div",{className:"flex items-center gap-2 sm:gap-1.5 min-w-0 overflow-hidden",children:[s.jsx(ie,{mode:"wait",initial:!1,children:b?s.jsxs(oe.div,{initial:{opacity:0,y:16},animate:{opacity:1,y:0},exit:{opacity:0,y:-16},transition:{duration:.2,ease:[.4,0,.2,1]},className:"flex items-center gap-2 sm:gap-1.5 min-w-0",children:[b.channelName&&s.jsx("span",{className:"hidden sm:inline-flex",children:s.jsx(Ve,{channelName:b.channelName})}),s.jsx("div",{className:"hidden sm:flex w-[30px] h-[30px] rounded-full items-center justify-center flex-shrink-0 ring-1 ring-edge-subtle",style:{backgroundColor:ss(ts(b.senderName||"").cleanName)},children:ts(b.senderName||"").emoji?s.jsx("span",{className:"text-base",children:ts(b.senderName||"").emoji}):s.jsx("span",{className:"text-white text-xs font-bold tracking-tighter",children:as(b.senderName||"")})}),s.jsx("div",{className:"inline-flex items-center px-3 py-1.5 rounded-2xl rounded-tr-md bg-[#007AFF] shadow-sm min-w-0 flex-1 sm:flex-initial sm:max-w-xs sm:-ml-px",children:s.jsx("span",{className:"text-sm text-white truncate tracking-wide",children:ns(b.text)})}),s.jsx("span",{className:"inline-flex items-center px-2 py-1 rounded-md bg-subtle-fill ring-1 ring-inset ring-edge-subtle text-sm tabular-nums text-fg-secondary flex-shrink-0",children:E(b.timestamp)})]},`msg-${b.timestamp}-${b.senderName}-${b.channelHash}`):f?s.jsx(oe.span,{initial:{opacity:0},animate:{opacity:1},className:"text-sm text-fg-muted italic",children:"No messages yet"},"empty"):s.jsxs(oe.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0,y:-16},transition:{duration:.15},className:"flex items-center gap-2 sm:gap-1.5",children:[s.jsx("div",{className:"hidden sm:block w-8 h-4 rounded bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"hidden sm:block w-[30px] h-[30px] rounded-full bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"h-8 w-32 sm:w-48 rounded-2xl bg-subtle-fill-strong animate-pulse"}),s.jsx("div",{className:"w-12 h-6 rounded-md bg-subtle-fill-strong animate-pulse"})]},"skeleton")}),s.jsx(Le,{className:"size-4 text-fg-muted group-hover:text-sys-indigo transition-colors flex-shrink-0 hidden sm:block ml-1"})]})]})}),s.jsx(tt,{open:n,onClose:()=>l(!1),messages:p,onLoadMore:M,hasMoreToLoad:k,isDecoding:j,initialChannel:i})]}):s.jsx("div",{className:"h-14 rounded-xl bg-elevated/50 animate-pulse"})}function nt(){var t,a;const n=f(),l=V(),i=u(),o=U(),r=e.useRef(!1);o&&!r.current&&(r.current=!0);const d=r.current,m=N(),x=W(),h=J(),g=w[m]??w[4],b=h.isBackgroundLoading&&m>=5,j=null==(t=null==n?void 0:n.config)?void 0:t.radio,v=e.useMemo(()=>j?{sf:j.spreading_factor??10,bw:j.bandwidth??25e4,cr:j.coding_rate??5,preamble:j.preamble_length??8}:null,[j]),y=i.length,k=e.useMemo(()=>y?K(g.minutes,g.buckets,i,n):null,[y,g.minutes,g.buckets,v]),M=e.useMemo(()=>{const e=e=>(null==e?void 0:e.reduce((e,s)=>e+s.count,0))??0,s=e(null==k?void 0:k.received),t=e(null==k?void 0:k.unique_received),a=e(null==k?void 0:k.forwarded),n=e(null==k?void 0:k.dropped),l=e(null==k?void 0:k.transmitted),i=((null==k?void 0:k.time_range_minutes)??g.minutes)/60;return{received:s,uniqueReceived:t,forwarded:a,dropped:n,transmitted:l,rxPerHour:i>0?Math.round(s/i):0,fwdPerHour:i>0?Math.round(a/i):0}},[k,g.minutes]),C=e.useMemo(()=>{if(!i.length)return{totalBytes:0,kbPerHour:0};const e=Date.now()/1e3,s=e-60*g.minutes;let t=0;for(const n of i)n.transmitted||n.timestampe||(t+=n.length??n.payload_length??0);const a=g.minutes/60;return{totalBytes:t,kbPerHour:a>0?Math.round(t/1024/a):0}},[i,g.minutes]),S=(null==n?void 0:n.node_name)??(null==(a=null==n?void 0:n.config)?void 0:a.node_name)??"Unknown Node";return e.useEffect(()=>{S&&"Unknown Node"!==S&&(document.title=`pyMC: ${S}`)},[S]),l?s.jsxs(X,{neomorphic:!0,className:"p-8 text-center",children:[s.jsx("p",{className:"type-subheading text-sys-red mb-2",children:"Failed to connect to backend"}),s.jsx("p",{className:"type-body text-fg-muted",children:l}),s.jsx("p",{className:"type-data-sm text-fg-muted mt-4",children:"Make sure the backend is running on port 8000"})]}):s.jsxs(Q,{children:[s.jsx(Y,{title:S,icon:s.jsx(_e,{}),controls:s.jsx(Ke,{ranges:w,selectedIndex:m,onSelect:x,isPending:b})}),s.jsxs(Z,{children:[s.jsx(at,{isLoaded:d}),s.jsx(is,{template:"hero-auto",children:s.jsxs(X,{neomorphic:!0,children:[s.jsx(p,{icon:s.jsx(Re,{}),title:"PACKETS RECEIVED",badge:g.label,badgeColor:"zinc",actions:d?s.jsxs("div",{className:"data-box",children:[C.kbPerHour," KB/hr"]}):s.jsx("div",{className:"data-box opacity-0",children:"0 KB/hr"})}),s.jsxs("div",{className:"flex flex-wrap gap-4 sm:gap-8",children:[s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.received,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Total Rx"})]}),s.jsxs("div",{className:"flex items-end gap-2",children:[s.jsx("div",{className:"type-data-xl text-fg-primary",children:d?s.jsx(Pe,{value:M.uniqueReceived,className:"font-mono tabular-nums",priority:"high"}):s.jsx("span",{className:"opacity-30",children:"—"})}),s.jsx(c,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"Unique"})]})]}),s.jsxs("div",{className:"mt-2 flex-1 min-h-0 relative",children:[s.jsx("div",{className:"absolute inset-0 flex items-end gap-1 transition-opacity duration-300 "+(d?"opacity-0 pointer-events-none":"opacity-100"),"aria-hidden":d,children:[45,72,33,58,80,42,65,28,55,75,38,62].map((e,t)=>s.jsx("div",{className:"flex-1 bg-subtle-fill rounded-sm animate-pulse",style:{height:`${e}%`}},t))}),s.jsx("div",{className:"h-full transition-opacity duration-300 "+(d?"opacity-100":"opacity-0"),children:s.jsx(cs,{packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets})})]})]})}),s.jsxs(is,{template:"compact",children:[s.jsx(os,{span:6,lg:4,children:s.jsx(us,{value:M.forwarded,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx(De,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:6,lg:4,children:s.jsx(hs,{value:M.dropped,receivedCount:M.received,packets:i,rangeMinutes:g.minutes,bucketCount:g.buckets,timeRangeLabel:g.label,icon:s.jsx($e,{className:"w-4 h-4"}),isLoaded:d})}),s.jsx(os,{span:12,lg:4,children:s.jsx(js,{stats:n,localHash:null==n?void 0:n.local_hash,receivedBuckets:null==k?void 0:k.received,droppedBuckets:null==k?void 0:k.dropped,forwardedBuckets:null==k?void 0:k.forwarded,bucketDurationSeconds:null==k?void 0:k.bucket_duration_seconds,timeRangeLabel:g.label,isLoaded:d})})]}),s.jsx(Js,{isLoaded:d}),s.jsx(ys,{}),n&&s.jsx(is,{template:"auto",children:s.jsx(es,{nodeName:S,repeaterVersion:n.version,coreVersion:n.core_version,localHash:n.local_hash,publicKey:n.public_key})})]})]})}export{nt as default}; diff --git a/frontend/dist/assets/DeepAnalysisModal-Ca6cBH6E.js b/frontend/dist/assets/DeepAnalysisModal-L9EkN490.js similarity index 99% rename from frontend/dist/assets/DeepAnalysisModal-Ca6cBH6E.js rename to frontend/dist/assets/DeepAnalysisModal-L9EkN490.js index b0b6d5d5..91e2d2f4 100644 --- a/frontend/dist/assets/DeepAnalysisModal-Ca6cBH6E.js +++ b/frontend/dist/assets/DeepAnalysisModal-L9EkN490.js @@ -1 +1 @@ -import{c as e}from"./geo-utils-DJn8DnxF.js";import{r as t,j as s}from"./vendor-react-alRNW2nb.js";import{c as n}from"./vendor-core-FtpmsTnh.js";import{bH as i,bI as a,av as o,dr as l,ds as r,Y as c,dt as u,_ as f}from"./index-D7i6lQrq.js";import{m as g}from"./vendor-motion-DNp0Qg4F.js";import{a as m,bs as d,aR as h,aa as p,bo as x,L as b}from"./vendor-icons-TO0PZKGR.js";const y={hidden:{opacity:0,scale:.9},visible:{opacity:1,scale:1,transition:{type:"spring",stiffness:400,damping:15}},exit:{opacity:0,scale:.9,transition:{duration:a.fast}}},j={hidden:{opacity:0,y:"100%"},visible:{opacity:1,y:0,transition:{type:"spring",stiffness:400,damping:30}},exit:{opacity:0,y:"100%",transition:{duration:a.medium,ease:i.easeIn}}};function v(e,t){let s=0;for(let n=0;n0)for(let s=0;sArray(t).fill(0));for(let n=0;nArray(t).fill(0));for(let l=0;l43758.5453*Math.sin(12.9898*t)%1-.5);w(a,s),N(a);let o=0;for(let l=0;l<100;l++){const e=M(i,a);w(e,s);const t=v(e,e)/v(a,e);if(N(e),a=e,Math.abs(t-o)<1e-8)return{vector:a,eigenvalue:n-t};o=t}return{vector:a,eigenvalue:n-o}}function k(t,s){if(t.length<2)return 0;const n=[];for(const e of t){const t=s.get(e);t&&n.push(t)}if(n.length<2)return 0;const i=Math.min(n.length,20),a=n.length<=i?n:function(e,t){if(t>=e.length)return e;const s=[],n=e.length/t;for(let i=0;io.has(e.fromHash)&&o.has(e.toHash));if(0===l.length)return null;const r=function(t,s,n,i){const a=s.length,o=new Map(s.map((e,t)=>[e,t])),l=Array(a).fill(null).map(()=>Array(a).fill(0));for(const r of t){const t=o.get(r.fromHash),s=o.get(r.toHash);if(void 0!==t&&void 0!==s&&t!==s){const a=r.strength*r.certainCount;let o=1;if(n){const t=n.get(r.fromHash),s=n.get(r.toHash);t&&s&&(o=A(e(t[0],t[1],s[0],s[1])/1e3))}let c=1;if(i){const e=[r.fromHash,r.toHash].sort().join("-");c=1-.7*(i.get(e)??0)}const u=.3+.7*(r.symmetryRatio??0),f=Math.pow(a,.7)*Math.pow(o,.3)*c*u;l[t][s]=f,l[s][t]=f}}return l}(l,s,n,i),c=C(r),{vector:u,eigenvalue:f}=H(c);if(f<.001)return null;const g=[],m=[];for(let e=0;e({hash:e,community:0,fiedlerValue:0})),numCommunities:1,fiedlerValue:0,isConnected:i<=1};const a=[];let o=1/0;const l=[[t,0]];for(;l.length>0;){const[t,i]=l.shift();if((s?k(t,s):0)>20&&i<4&&t.length>=10){const a=T(e,t,s,n);if(a){o=Math.min(o,a.fiedlerValue),l.push([a.group0,i+1]),l.push([a.group1,i+1]);continue}}a.push(t)}const r=new Map,c=[],u=new Map;for(let f=0;f[e,t])),i=Array(s).fill(null).map(()=>Array(s).fill(0));for(const l of e){const e=n.get(l.fromHash),t=n.get(l.toHash);void 0!==e&&void 0!==t&&e!==t&&(i[e][t]=1,i[t][e]=1)}const a=C(i),{eigenvalue:o}=H(a);return Math.max(0,o)}function z(e){const t=["rgba(139, 92, 246, 0.6)","rgba(16, 185, 129, 0.6)","rgba(245, 158, 11, 0.6)","rgba(239, 68, 68, 0.6)","rgba(59, 130, 246, 0.6)","rgba(236, 72, 153, 0.6)","rgba(20, 184, 166, 0.6)","rgba(249, 115, 22, 0.6)"];return t[e%t.length]}function P({label:e,icon:t,status:i,detail:a}){return s.jsxs("div",{className:n("flex items-center gap-3 py-3 px-4 radius-inset transition-base","active"===i&&"bg-sys-blue/10","complete"===i&&"bg-sys-blue/10 ring-2 ring-inset ring-sys-blue","pending"===i&&"opacity-40"),children:[s.jsx("div",{className:n("w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-300","active"===i&&"bg-sys-blue/20","complete"===i&&"bg-sys-blue/20","pending"===i&&"bg-subtle-fill"),children:"complete"===i?s.jsx(m,{className:"w-4 h-4 text-sys-blue"}):"active"===i?s.jsx(b,{className:"w-4 h-4 animate-spin text-sys-blue"}):s.jsx("span",{className:"text-fg-muted",children:t})}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:n("text-sm font-medium transition-colors","active"===i&&"text-sys-blue","complete"===i&&"text-sys-blue","pending"===i&&"text-fg-muted"),children:e}),a&&"pending"!==i&&s.jsx("div",{className:"text-xs text-fg-muted mt-0.5 truncate",children:a})]})]})}const S=t.memo(function({isOpen:e,onClose:n}){const{packetCacheState:i,triggerDeepAnalysis:a}=o(),b=l(),j=r(),v=i.packetCount,[N,w]=t.useState("fetching");t.useEffect(()=>{e&&a()},[e,a]),t.useEffect(()=>{if(e)if(i.isTopologyLoading)w("fetching");else if(b)w("analyzing"),setTimeout(()=>w("building"),500),setTimeout(()=>w("discovering"),1e3);else if(j>0&&!i.isTopologyLoading){w("complete");const e=setTimeout(()=>{n()},1500);return()=>clearTimeout(e)}},[e,i.isTopologyLoading,b,j,n]);const M="complete"===N,A=i.loadProgress,C=t.useMemo(()=>A&&A.target>0?`Loading... ${(A.loaded/1e3).toFixed(1)}k / ${(A.target/1e3).toFixed(1)}k packets (${A.percent}%)`:v>0?`${v.toLocaleString()} packets loaded`:"Connecting to database...",[A,v]),H=e=>{const t=["fetching","analyzing","building","discovering","complete"],s=t.indexOf(N),n=t.indexOf(e);return n{};return s.jsx(c,{open:e,onClose:k,size:"sm",bottomSheet:!1,children:s.jsx(u,{isLoading:!M,borderRadius:16,children:s.jsx(f,{className:"p-6 radius-card overflow-hidden",children:M?s.jsxs("div",{className:"flex flex-col items-center py-6",children:[s.jsx(g.div,{variants:y,initial:"hidden",animate:"visible",className:"w-16 h-16 rounded-full flex items-center justify-center mb-4 bg-sys-blue/20",children:s.jsx(m,{className:"w-8 h-8 text-sys-blue"})}),s.jsx("h3",{className:"type-micro text-sys-blue",children:"Ready!"}),s.jsx("button",{onClick:n,className:"mt-3 sm:hidden min-h-[44px] min-w-[44px] px-4 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"})]}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"flex items-center gap-3 mb-5",children:[s.jsx("div",{className:"w-10 h-10 radius-inset flex items-center justify-center bg-sys-blue/15",children:s.jsx(d,{className:"w-5 h-5 text-sys-blue"})}),s.jsxs("div",{children:[s.jsx("h3",{className:"type-micro",children:"Deep Analysis"}),s.jsx("p",{className:"text-xs text-fg-muted",children:"Building mesh topology"})]})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(P,{label:"Fetching Packets",icon:s.jsx(h,{className:"w-4 h-4"}),status:H("fetching"),detail:C}),s.jsx(P,{label:"Analyzing Database",icon:s.jsx(p,{className:"w-4 h-4"}),status:H("analyzing"),detail:"Processing packet paths"}),s.jsx(P,{label:"Building Topology",icon:s.jsx(d,{className:"w-4 h-4"}),status:H("building"),detail:"Computing mesh edges"}),s.jsx(P,{label:"Discovering Nodes",icon:s.jsx(x,{className:"w-4 h-4"}),status:H("discovering"),detail:"Viterbi HMM ghost detection"})]}),s.jsx("p",{className:"text-xs text-fg-muted text-center mt-5",children:"This may take a few seconds..."})]})})})})});export{S as D,V as a,L as b,D as c,z as g,j as s}; +import{c as e}from"./geo-utils-DJn8DnxF.js";import{r as t,j as s}from"./vendor-react-alRNW2nb.js";import{c as n}from"./vendor-core-FtpmsTnh.js";import{bH as i,bI as a,av as o,dr as l,ds as r,Y as c,dt as u,_ as f}from"./index-CkRTgHHA.js";import{m as g}from"./vendor-motion-DNp0Qg4F.js";import{a as m,bs as d,aR as h,aa as p,bo as x,L as b}from"./vendor-icons-TO0PZKGR.js";const y={hidden:{opacity:0,scale:.9},visible:{opacity:1,scale:1,transition:{type:"spring",stiffness:400,damping:15}},exit:{opacity:0,scale:.9,transition:{duration:a.fast}}},j={hidden:{opacity:0,y:"100%"},visible:{opacity:1,y:0,transition:{type:"spring",stiffness:400,damping:30}},exit:{opacity:0,y:"100%",transition:{duration:a.medium,ease:i.easeIn}}};function v(e,t){let s=0;for(let n=0;n0)for(let s=0;sArray(t).fill(0));for(let n=0;nArray(t).fill(0));for(let l=0;l43758.5453*Math.sin(12.9898*t)%1-.5);w(a,s),N(a);let o=0;for(let l=0;l<100;l++){const e=M(i,a);w(e,s);const t=v(e,e)/v(a,e);if(N(e),a=e,Math.abs(t-o)<1e-8)return{vector:a,eigenvalue:n-t};o=t}return{vector:a,eigenvalue:n-o}}function k(t,s){if(t.length<2)return 0;const n=[];for(const e of t){const t=s.get(e);t&&n.push(t)}if(n.length<2)return 0;const i=Math.min(n.length,20),a=n.length<=i?n:function(e,t){if(t>=e.length)return e;const s=[],n=e.length/t;for(let i=0;io.has(e.fromHash)&&o.has(e.toHash));if(0===l.length)return null;const r=function(t,s,n,i){const a=s.length,o=new Map(s.map((e,t)=>[e,t])),l=Array(a).fill(null).map(()=>Array(a).fill(0));for(const r of t){const t=o.get(r.fromHash),s=o.get(r.toHash);if(void 0!==t&&void 0!==s&&t!==s){const a=r.strength*r.certainCount;let o=1;if(n){const t=n.get(r.fromHash),s=n.get(r.toHash);t&&s&&(o=A(e(t[0],t[1],s[0],s[1])/1e3))}let c=1;if(i){const e=[r.fromHash,r.toHash].sort().join("-");c=1-.7*(i.get(e)??0)}const u=.3+.7*(r.symmetryRatio??0),f=Math.pow(a,.7)*Math.pow(o,.3)*c*u;l[t][s]=f,l[s][t]=f}}return l}(l,s,n,i),c=C(r),{vector:u,eigenvalue:f}=H(c);if(f<.001)return null;const g=[],m=[];for(let e=0;e({hash:e,community:0,fiedlerValue:0})),numCommunities:1,fiedlerValue:0,isConnected:i<=1};const a=[];let o=1/0;const l=[[t,0]];for(;l.length>0;){const[t,i]=l.shift();if((s?k(t,s):0)>20&&i<4&&t.length>=10){const a=T(e,t,s,n);if(a){o=Math.min(o,a.fiedlerValue),l.push([a.group0,i+1]),l.push([a.group1,i+1]);continue}}a.push(t)}const r=new Map,c=[],u=new Map;for(let f=0;f[e,t])),i=Array(s).fill(null).map(()=>Array(s).fill(0));for(const l of e){const e=n.get(l.fromHash),t=n.get(l.toHash);void 0!==e&&void 0!==t&&e!==t&&(i[e][t]=1,i[t][e]=1)}const a=C(i),{eigenvalue:o}=H(a);return Math.max(0,o)}function z(e){const t=["rgba(139, 92, 246, 0.6)","rgba(16, 185, 129, 0.6)","rgba(245, 158, 11, 0.6)","rgba(239, 68, 68, 0.6)","rgba(59, 130, 246, 0.6)","rgba(236, 72, 153, 0.6)","rgba(20, 184, 166, 0.6)","rgba(249, 115, 22, 0.6)"];return t[e%t.length]}function P({label:e,icon:t,status:i,detail:a}){return s.jsxs("div",{className:n("flex items-center gap-3 py-3 px-4 radius-inset transition-base","active"===i&&"bg-sys-blue/10","complete"===i&&"bg-sys-blue/10 ring-2 ring-inset ring-sys-blue","pending"===i&&"opacity-40"),children:[s.jsx("div",{className:n("w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-300","active"===i&&"bg-sys-blue/20","complete"===i&&"bg-sys-blue/20","pending"===i&&"bg-subtle-fill"),children:"complete"===i?s.jsx(m,{className:"w-4 h-4 text-sys-blue"}):"active"===i?s.jsx(b,{className:"w-4 h-4 animate-spin text-sys-blue"}):s.jsx("span",{className:"text-fg-muted",children:t})}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:n("text-sm font-medium transition-colors","active"===i&&"text-sys-blue","complete"===i&&"text-sys-blue","pending"===i&&"text-fg-muted"),children:e}),a&&"pending"!==i&&s.jsx("div",{className:"text-xs text-fg-muted mt-0.5 truncate",children:a})]})]})}const S=t.memo(function({isOpen:e,onClose:n}){const{packetCacheState:i,triggerDeepAnalysis:a}=o(),b=l(),j=r(),v=i.packetCount,[N,w]=t.useState("fetching");t.useEffect(()=>{e&&a()},[e,a]),t.useEffect(()=>{if(e)if(i.isTopologyLoading)w("fetching");else if(b)w("analyzing"),setTimeout(()=>w("building"),500),setTimeout(()=>w("discovering"),1e3);else if(j>0&&!i.isTopologyLoading){w("complete");const e=setTimeout(()=>{n()},1500);return()=>clearTimeout(e)}},[e,i.isTopologyLoading,b,j,n]);const M="complete"===N,A=i.loadProgress,C=t.useMemo(()=>A&&A.target>0?`Loading... ${(A.loaded/1e3).toFixed(1)}k / ${(A.target/1e3).toFixed(1)}k packets (${A.percent}%)`:v>0?`${v.toLocaleString()} packets loaded`:"Connecting to database...",[A,v]),H=e=>{const t=["fetching","analyzing","building","discovering","complete"],s=t.indexOf(N),n=t.indexOf(e);return n{};return s.jsx(c,{open:e,onClose:k,size:"sm",bottomSheet:!1,children:s.jsx(u,{isLoading:!M,borderRadius:16,children:s.jsx(f,{className:"p-6 radius-card overflow-hidden",children:M?s.jsxs("div",{className:"flex flex-col items-center py-6",children:[s.jsx(g.div,{variants:y,initial:"hidden",animate:"visible",className:"w-16 h-16 rounded-full flex items-center justify-center mb-4 bg-sys-blue/20",children:s.jsx(m,{className:"w-8 h-8 text-sys-blue"})}),s.jsx("h3",{className:"type-micro text-sys-blue",children:"Ready!"}),s.jsx("button",{onClick:n,className:"mt-3 sm:hidden min-h-[44px] min-w-[44px] px-4 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"})]}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"flex items-center gap-3 mb-5",children:[s.jsx("div",{className:"w-10 h-10 radius-inset flex items-center justify-center bg-sys-blue/15",children:s.jsx(d,{className:"w-5 h-5 text-sys-blue"})}),s.jsxs("div",{children:[s.jsx("h3",{className:"type-micro",children:"Deep Analysis"}),s.jsx("p",{className:"text-xs text-fg-muted",children:"Building mesh topology"})]})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(P,{label:"Fetching Packets",icon:s.jsx(h,{className:"w-4 h-4"}),status:H("fetching"),detail:C}),s.jsx(P,{label:"Analyzing Database",icon:s.jsx(p,{className:"w-4 h-4"}),status:H("analyzing"),detail:"Processing packet paths"}),s.jsx(P,{label:"Building Topology",icon:s.jsx(d,{className:"w-4 h-4"}),status:H("building"),detail:"Computing mesh edges"}),s.jsx(P,{label:"Discovering Nodes",icon:s.jsx(x,{className:"w-4 h-4"}),status:H("discovering"),detail:"Viterbi HMM ghost detection"})]}),s.jsx("p",{className:"text-xs text-fg-muted text-center mt-5",children:"This may take a few seconds..."})]})})})})});export{S as D,V as a,L as b,D as c,z as g,j as s}; diff --git a/frontend/dist/assets/KeycapButton-B1_-eSeA.js b/frontend/dist/assets/KeycapButton-DdWNfiky.js similarity index 98% rename from frontend/dist/assets/KeycapButton-B1_-eSeA.js rename to frontend/dist/assets/KeycapButton-DdWNfiky.js index cfe62786..b3957d70 100644 --- a/frontend/dist/assets/KeycapButton-B1_-eSeA.js +++ b/frontend/dist/assets/KeycapButton-DdWNfiky.js @@ -1 +1 @@ -import{r as e,j as a}from"./vendor-react-alRNW2nb.js";import{b as c,c as s}from"./keycap-sfx-Bpx9zhkt.js";import{Z as n}from"./index-D7i6lQrq.js";const d={a:"24,3 76,3 83,7 76,11 24,11 17,7",b:"88,22 93,27 93,71 88,76 83,71 83,27",c:"88,106 93,111 93,155 88,160 83,155 83,111",d:"24,171 76,171 83,175 76,179 24,179 17,175",e:"12,106 17,111 17,155 12,160 7,155 7,111",f:"12,22 17,27 17,71 12,76 7,71 7,27",g:"24,86 76,86 83,91 76,96 24,96 17,91"},t=Object.keys(d),r={0:"abcdef",1:"bc",2:"abdeg",3:"abcdg",4:"bcfg",5:"acdfg",6:"acdefg",7:"abc",8:"abcdefg",9:"abcdfg",A:"abcefg",B:"cdefg",C:"adef",D:"bcdeg",E:"adefg",F:"aefg",G:"acdef",H:"bcefg",I:"ef",J:"bcde",L:"def",M:"abcefg",N:"ceg",O:"abcdef",P:"abefg",Q:"abcfg",R:"eg",S:"acdfg",T:"defg",U:"bcdef",V:"cde",Y:"bcdfg",Z:"abdeg",a:"abcefg",b:"cdefg",c:"deg",d:"bcdeg",e:"adefg",f:"aefg",g:"abcdfg",h:"cefg",i:"c",j:"bcde",l:"def",m:"abcef",n:"ceg",o:"cdeg",p:"abefg",r:"eg",s:"acdfg",t:"defg",u:"cde",v:"cde",y:"bcdfg"," ":"",_:"d","-":"g","=":"dg","°":"abfg",'"':"bf","'":"f","(":"adef",")":"abcd","[":"adef","]":"abcd","!":"bc",".":"d"};function l(e,a){const c=Array.from(e).map(e=>r[e.toUpperCase()]??r[e]??""),s=Math.max(0,(a??0)-e.length);for(let n=0;n{if(i)return;const e=l(c,r),a=6+2*(e.length-1);let s,n=0,d=!1;const o=()=>{d||(n++,n>=a?u(null):(u(e.map((e,a)=>n>=6+2*a?e:t.filter(()=>Math.random()>.45).join(""))),s=setTimeout(o,56)))};return o(),()=>{d=!0,clearTimeout(s)}},[c,r,i]);const m=l(c,r),p=b??m;return a.jsxs("span",{className:"seven-seg"+(o?` ${o}`:""),children:[p.map((e,c)=>((e,c)=>a.jsx("svg",{viewBox:"0 0 100 182",width:g,height:n,className:"seven-seg__char","aria-hidden":"true",children:t.map(c=>a.jsx("polygon",{points:d[c],fill:s,stroke:s,strokeWidth:4,strokeLinejoin:"round",opacity:e.includes(c)?1:f},c))},c))(e,`${c}-${e}`)),a.jsx("span",{className:"sr-only",children:c})]})}const o={grey:"/assets/keycap.svg",red:"/assets/keycap-red.svg"},g=n[900];function f({icon:n,variant:d="grey",onClick:t,onPress:r,sentDuration:l=2e3,title:i,disabled:f=!1,className:b,iconColor:u=g,iconActiveColor:m="#FFDEB0",indicators:p}){const h=!!r,[y,k]=e.useState("idle"),[j,v]=e.useState(!1),x=e.useRef(),N=h?"held"===y:j,C=h&&("sending"===y||"sent"===y),_=h?"held"===y||"sending"===y:j;e.useEffect(()=>()=>clearTimeout(x.current),[]);const $=e.useCallback(()=>{f||C||(c(),h?k("held"):v(!0))},[f,C,h]),T=e.useCallback(async()=>{if(h){if("held"!==y)return;s(),k("sending");const e=await r();k(e?"sent":"idle"),e&&(x.current=setTimeout(()=>k("idle"),l))}else{if(!j)return;v(!1),s(),null==t||t()}},[h,y,r,l,j,t]),M=e.useCallback(()=>{h?"held"===y&&(s(),k("idle")):(j&&s(),v(!1))},[h,y,j]),E=a.jsx("button",{onMouseDown:$,onMouseUp:T,onMouseLeave:M,onTouchStart:$,onTouchEnd:T,onTouchCancel:M,disabled:f||C,className:`keycap-btn${"red"===d?" keycap-btn--red-cap":""}${_?" keycap-btn--pressed":""}${b&&!p?` ${b}`:""}`,title:i,children:a.jsxs("div",{className:"keycap-wrap",children:[a.jsx("img",{src:o[d],alt:"",className:"keycap-btn__img",draggable:!1}),a.jsx("span",{className:"keycap-icon-overlay",style:{color:N||"sending"===y?m:u},children:n})]})});return(null==p?void 0:p.length)?a.jsxs("div",{className:"keycap-group"+(b?` ${b}`:""),children:[E,a.jsx("div",{className:"indicator-key-pair",children:p.map(e=>{const c=e.trackPress?y:e.active?"active":"idle";return a.jsxs("div",{className:"indicator-key"+("idle"!==c?` indicator-key--${c}`:""),children:[a.jsx("span",{className:"indicator-key__label",children:e.label}),a.jsx("span",{className:"indicator-key__led"})]},e.label)})})]}):E}export{f as K,i as S}; +import{r as e,j as a}from"./vendor-react-alRNW2nb.js";import{b as c,c as s}from"./keycap-sfx-Bpx9zhkt.js";import{Z as n}from"./index-CkRTgHHA.js";const d={a:"24,3 76,3 83,7 76,11 24,11 17,7",b:"88,22 93,27 93,71 88,76 83,71 83,27",c:"88,106 93,111 93,155 88,160 83,155 83,111",d:"24,171 76,171 83,175 76,179 24,179 17,175",e:"12,106 17,111 17,155 12,160 7,155 7,111",f:"12,22 17,27 17,71 12,76 7,71 7,27",g:"24,86 76,86 83,91 76,96 24,96 17,91"},t=Object.keys(d),r={0:"abcdef",1:"bc",2:"abdeg",3:"abcdg",4:"bcfg",5:"acdfg",6:"acdefg",7:"abc",8:"abcdefg",9:"abcdfg",A:"abcefg",B:"cdefg",C:"adef",D:"bcdeg",E:"adefg",F:"aefg",G:"acdef",H:"bcefg",I:"ef",J:"bcde",L:"def",M:"abcefg",N:"ceg",O:"abcdef",P:"abefg",Q:"abcfg",R:"eg",S:"acdfg",T:"defg",U:"bcdef",V:"cde",Y:"bcdfg",Z:"abdeg",a:"abcefg",b:"cdefg",c:"deg",d:"bcdeg",e:"adefg",f:"aefg",g:"abcdfg",h:"cefg",i:"c",j:"bcde",l:"def",m:"abcef",n:"ceg",o:"cdeg",p:"abefg",r:"eg",s:"acdfg",t:"defg",u:"cde",v:"cde",y:"bcdfg"," ":"",_:"d","-":"g","=":"dg","°":"abfg",'"':"bf","'":"f","(":"adef",")":"abcd","[":"adef","]":"abcd","!":"bc",".":"d"};function l(e,a){const c=Array.from(e).map(e=>r[e.toUpperCase()]??r[e]??""),s=Math.max(0,(a??0)-e.length);for(let n=0;n{if(i)return;const e=l(c,r),a=6+2*(e.length-1);let s,n=0,d=!1;const o=()=>{d||(n++,n>=a?u(null):(u(e.map((e,a)=>n>=6+2*a?e:t.filter(()=>Math.random()>.45).join(""))),s=setTimeout(o,56)))};return o(),()=>{d=!0,clearTimeout(s)}},[c,r,i]);const m=l(c,r),p=b??m;return a.jsxs("span",{className:"seven-seg"+(o?` ${o}`:""),children:[p.map((e,c)=>((e,c)=>a.jsx("svg",{viewBox:"0 0 100 182",width:g,height:n,className:"seven-seg__char","aria-hidden":"true",children:t.map(c=>a.jsx("polygon",{points:d[c],fill:s,stroke:s,strokeWidth:4,strokeLinejoin:"round",opacity:e.includes(c)?1:f},c))},c))(e,`${c}-${e}`)),a.jsx("span",{className:"sr-only",children:c})]})}const o={grey:"/assets/keycap.svg",red:"/assets/keycap-red.svg"},g=n[900];function f({icon:n,variant:d="grey",onClick:t,onPress:r,sentDuration:l=2e3,title:i,disabled:f=!1,className:b,iconColor:u=g,iconActiveColor:m="#FFDEB0",indicators:p}){const h=!!r,[y,k]=e.useState("idle"),[j,v]=e.useState(!1),x=e.useRef(),N=h?"held"===y:j,C=h&&("sending"===y||"sent"===y),_=h?"held"===y||"sending"===y:j;e.useEffect(()=>()=>clearTimeout(x.current),[]);const $=e.useCallback(()=>{f||C||(c(),h?k("held"):v(!0))},[f,C,h]),T=e.useCallback(async()=>{if(h){if("held"!==y)return;s(),k("sending");const e=await r();k(e?"sent":"idle"),e&&(x.current=setTimeout(()=>k("idle"),l))}else{if(!j)return;v(!1),s(),null==t||t()}},[h,y,r,l,j,t]),M=e.useCallback(()=>{h?"held"===y&&(s(),k("idle")):(j&&s(),v(!1))},[h,y,j]),E=a.jsx("button",{onMouseDown:$,onMouseUp:T,onMouseLeave:M,onTouchStart:$,onTouchEnd:T,onTouchCancel:M,disabled:f||C,className:`keycap-btn${"red"===d?" keycap-btn--red-cap":""}${_?" keycap-btn--pressed":""}${b&&!p?` ${b}`:""}`,title:i,children:a.jsxs("div",{className:"keycap-wrap",children:[a.jsx("img",{src:o[d],alt:"",className:"keycap-btn__img",draggable:!1}),a.jsx("span",{className:"keycap-icon-overlay",style:{color:N||"sending"===y?m:u},children:n})]})});return(null==p?void 0:p.length)?a.jsxs("div",{className:"keycap-group"+(b?` ${b}`:""),children:[E,a.jsx("div",{className:"indicator-key-pair",children:p.map(e=>{const c=e.trackPress?y:e.active?"active":"idle";return a.jsxs("div",{className:"indicator-key"+("idle"!==c?` indicator-key--${c}`:""),children:[a.jsx("span",{className:"indicator-key__label",children:e.label}),a.jsx("span",{className:"indicator-key__led"})]},e.label)})})]}):E}export{f as K,i as S}; diff --git a/frontend/dist/assets/Login-AaBhF2Vi.js b/frontend/dist/assets/Login-DV-gJNAt.js similarity index 99% rename from frontend/dist/assets/Login-AaBhF2Vi.js rename to frontend/dist/assets/Login-DV-gJNAt.js index baa63d9a..7261b798 100644 --- a/frontend/dist/assets/Login-AaBhF2Vi.js +++ b/frontend/dist/assets/Login-DV-gJNAt.js @@ -1 +1 @@ -import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{b as s,c as n}from"./vendor-core-FtpmsTnh.js";import{g as r,i as a,s as i,l,a as o,b as c,I as h,C as m,B as u,Z as d}from"./index-D7i6lQrq.js";import{g as x,B as C,r as p,T as f}from"./ascii-burst-CXC_pYgi.js";import{m as g,A as L}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";const j=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "],y=f-1,b=j.length,v=Math.max(...j.map(e=>e.length)),M={" ":0,".":.08,":":.15,"!":.5,"@":.85,"#":.6,$:.7,"%":.65,"&":.6,"*":.3,"+":.25,"-":.1,"=":.2,_:.05,"~":.2,"^":.15,"|":.4,"/":.3,"\\":.3,"(":.35,")":.35,"[":.4,"]":.4,"{":.45,"}":.45,"<":.3,">":.3,"?":.4,";":.2,"'":.1,'"':.15,",":.08,"`":.05};function w(e){let t="",s=0,n=!1,r="",a=!1,i=!1,l=!1;for(;s",n=!1),r="",a=!1,i=!1,l=!1;else if("1"===c)a=!0,l=!0;else if("2"===c)i=!0,l=!0;else if(c.startsWith("38;2;")){const e=c.split(";");r=`rgb(${e[2]},${e[3]},${e[4]})`,l=!0}}else{if(l){n&&(t+="");const e=[];r&&e.push(`color:${r}`),a&&e.push("font-weight:700"),i&&e.push("opacity:0.6"),e.length>0?(t+=``,n=!0):n=!1,l=!1}const o=e[s];t+="<"===o?"<":">"===o?">":"&"===o?"&":o,s++}return n&&(t+=""),t}function N(e){let t="";for(let s=0;s0&&(t+="\n"),t+=w(e[s]);return t}const k=[[91,91,214],[72,70,200],[110,110,230],[150,150,245],[190,210,255],[0,240,255],[255,50,180],[80,255,180]];function S(e,t,s){return`rgb(${Math.round(e[0]+(t[0]-e[0])*s)},${Math.round(e[1]+(t[1]-e[1])*s)},${Math.round(e[2]+(t[2]-e[2])*s)})`}function T(e){const t=Math.max(0,Math.min(.999,e));return" . ˙·∙⁺˚°:;~*+✧✩×✴░✦✶✳oO▒#%&xX▓@MW8B█████"[Math.floor(42*t)]}function $(e){return M[e]??.5}function _(e,t){const s=Math.abs(e);if(s<.3)return S(k[0],k[2],s/.3);if(s<.6){const e=(s-.3)/.3;return S(k[3],k[4],e)}{const e=.5*Math.sin(17.3*t)+.5;return e<.4?S(k[4],k[5],(s-.6)/.4):e<.6?`rgb(${k[6].join(",")})`:e<.7?`rgb(${k[7].join(",")})`:"rgb(255,252,255)"}}function P(e){let t="";for(let s=0;s0&&(t+="\n");const n=j[s]||"";for(let r=0;r0?Math.exp(-c*c/2):Math.exp(-c*c/12),m=.25*a-.4*t.radius,u=Math.sin(m*Math.PI),d=h*t.strength;i+=h*u*t.strength,d>o&&(o=d,l=m+.1*s+.05*r)}if(i=Math.max(-1,Math.min(1,i)),Math.abs(i)<.008)t+=`${a}`;else{const e=$(a)+.5*i,s=T(Math.max(.02,Math.min(.98,e)));t+=`${s}`}}}return t}const R=e.memo(function(){const s=e.useRef(null),n=e.useRef([]),r=e.useRef(0),[a,i]=e.useState(!1);e.useEffect(()=>{const e=s.current;if(!e)return;let t=0;e.innerHTML=N(x(j,0));const n=setInterval(()=>{if(t++,t>y)return clearInterval(n),void i(!0);e.innerHTML=N(x(j,t))},C);return()=>{clearInterval(n),p()}},[]),e.useEffect(()=>{if(!a)return;const e=s.current;if(!e)return;let t=!0;const i=()=>{if(!t)return;const s=n.current;for(const e of s)e.radius+=.08,e.strength*=.994;n.current=s.filter(e=>e.strength>.008),n.current.length>0?e.innerHTML=P(n.current):e.innerHTML=P([]),r.current=requestAnimationFrame(i)};return r.current=requestAnimationFrame(i),()=>{t=!1,cancelAnimationFrame(r.current)}},[a]);const l=e.useRef(null),o=e.useCallback((e,t,r=1)=>{const i=s.current;if(!i||!a)return;const o=i.getBoundingClientRect(),c=(e-o.left)/9.6,h=(t-o.top)/20;n.current.length>=8&&n.current.shift(),n.current.push({cx:c,cy:h,radius:0,strength:r}),l.current={x:e,y:t}},[a]),c=e.useCallback(e=>{const t=l.current;if(t){const s=e.clientX-t.x,n=e.clientY-t.y;if(Math.sqrt(s*s+n*n)<20)return;o(e.clientX,e.clientY,.7)}else o(e.clientX,e.clientY,.6)},[o]),h=e.useCallback(e=>{o(e.clientX,e.clientY,1)},[o]),m=e.useCallback(e=>{l.current=null,o(e.clientX,e.clientY,.6)},[o]),u=e.useCallback(e=>{if(e.touches.length>0){const t=e.touches[0],s=l.current;if(s){const e=t.clientX-s.x,n=t.clientY-s.y;if(Math.sqrt(e*e+n*n)<20)return}o(t.clientX,t.clientY,.9)}},[o]);return t.jsx("pre",{ref:s,"aria-label":"PYMC",role:"img",onPointerMove:c,onPointerDown:h,onPointerEnter:m,onTouchMove:u,style:{fontFamily:"'JetBrains Mono', monospace",fontSize:"16px",lineHeight:1.25,letterSpacing:"0.01em",textAlign:"center",whiteSpace:"pre",margin:0,overflow:"hidden",cursor:"crosshair",touchAction:"none"}})}),Z=e.memo(function({width:e,height:s,className:n="",fill:r="currentColor"}){return t.jsxs("svg",{viewBox:"0 0 134 15",width:e,height:s,className:n,role:"img","aria-label":"MeshCore",style:{fillRule:"evenodd",clipRule:"evenodd"},children:[t.jsx("path",{fill:r,d:"M3.277,0.053C2.829,0.053 2.401,0.41 2.321,0.851L0.013,13.623C-0.067,14.064 0.232,14.421 0.681,14.421L3.13,14.421C3.578,14.421 4.006,14.064 4.086,13.623L5.004,8.54L6.684,13.957C6.766,14.239 7.02,14.421 7.337,14.421L10.58,14.421C10.897,14.421 11.217,14.239 11.401,13.957L15.043,8.513L14.119,13.623C14.038,14.064 14.338,14.421 14.787,14.421L17.236,14.421C17.684,14.421 18.112,14.064 18.192,13.623L20.5,0.851C20.582,0.41 20.283,0.053 19.834,0.053L16.69,0.053C16.373,0.053 16.053,0.235 15.87,0.517L9.897,9.473C9.803,9.616 9.578,9.578 9.528,9.41L7.074,0.517C6.992,0.235 6.738,0.053 6.421,0.053L3.277,0.053Z"}),t.jsx("path",{fill:r,d:"M21.146,14.421C21.146,14.421 33.257,14.421 33.257,14.421C33.526,14.421 33.784,14.205 33.831,13.942L34.337,11.128C34.385,10.863 34.206,10.649 33.936,10.649L25.519,10.649C25.429,10.649 25.37,10.576 25.385,10.488L25.635,9.105C25.65,9.017 25.736,8.944 25.826,8.944L32.596,8.944C32.865,8.944 33.123,8.728 33.171,8.465L33.621,5.974C33.669,5.709 33.49,5.495 33.221,5.495L26.45,5.495C26.361,5.495 26.301,5.423 26.317,5.335L26.584,3.852C26.599,3.764 26.685,3.691 26.775,3.691L35.192,3.691C35.462,3.691 35.719,3.476 35.767,3.21L36.258,0.498C36.306,0.235 36.126,0.019 35.857,0.019L23.746,0.019C23.297,0.019 22.867,0.378 22.788,0.819L20.474,13.621C20.396,14.062 20.695,14.421 21.146,14.421Z"}),t.jsx("path",{fill:r,d:"M45.926,14.419L45.926,14.421L46.346,14.421C48.453,14.421 50.465,12.742 50.839,10.67L51.081,9.327C51.456,7.256 50.05,5.576 47.943,5.576L41.455,5.576C41.186,5.576 41.007,5.363 41.054,5.097L41.218,4.192C41.266,3.927 41.524,3.713 41.793,3.713L50.569,3.713C51.018,3.713 51.446,3.356 51.526,2.915L51.9,0.85C51.98,0.407 51.68,0.05 51.232,0.05L41.638,0.05C39.531,0.05 37.519,1.73 37.145,3.801L36.88,5.267C36.505,7.339 37.91,9.018 40.018,9.018L46.506,9.018C46.775,9.018 46.954,9.231 46.907,9.497L46.785,10.176C46.737,10.441 46.479,10.655 46.21,10.655L37.189,10.655C36.741,10.655 36.313,11.012 36.233,11.453L35.841,13.621C35.761,14.062 36.061,14.419 36.51,14.419L45.926,14.419Z"}),t.jsx("path",{fill:r,d:"M68.008,0.046C68.008,0.046 65.296,0.046 65.296,0.046C64.847,0.046 64.42,0.403 64.34,0.844L63.532,5.31C63.517,5.398 63.431,5.469 63.341,5.469L58.085,5.469C57.995,5.469 57.936,5.398 57.951,5.31L58.758,0.844C58.837,0.403 58.539,0.046 58.09,0.046L55.378,0.046C54.93,0.046 54.502,0.403 54.422,0.844L52.112,13.623C52.032,14.064 52.331,14.421 52.78,14.421L55.492,14.421C55.941,14.421 56.369,14.064 56.449,13.623L57.272,9.074C57.287,8.986 57.373,8.914 57.462,8.914L62.719,8.914C62.809,8.914 62.868,8.985 62.853,9.074L62.032,13.623C61.952,14.064 62.252,14.421 62.7,14.421L65.413,14.421C65.861,14.421 66.289,14.064 66.369,13.623L68.678,0.844C68.755,0.403 68.457,0.046 68.008,0.046Z"}),t.jsx("path",{fill:r,d:"M72.099,14.421C72.099,14.421 80.066,14.421 80.066,14.421C80.515,14.421 80.943,14.064 81.022,13.623L81.414,11.453C81.494,11.012 81.194,10.655 80.746,10.655L73.828,10.655C73.559,10.655 73.38,10.441 73.427,10.176L74.51,4.215C74.558,3.951 74.815,3.736 75.082,3.736L82,3.736C82.448,3.736 82.876,3.379 82.956,2.938L83.34,0.817C83.42,0.376 83.12,0.019 82.672,0.019L74.724,0.019C72.622,0.019 70.614,1.691 70.236,3.757L68.965,10.665C68.587,12.738 69.99,14.421 72.099,14.421Z"}),t.jsx("path",{fill:r,d:"M97.176,-0C97.176,0 88.882,0 88.882,0C86.775,0 84.763,1.68 84.389,3.751L83.139,10.67C82.765,12.741 84.169,14.421 86.277,14.421L94.571,14.421C96.678,14.421 98.69,12.741 99.064,10.67L100.314,3.751C100.689,1.68 99.284,-0 97.176,-0ZM94.798,10.178C94.75,10.443 94.492,10.657 94.223,10.657L87.978,10.657C87.709,10.657 87.529,10.443 87.577,10.178L88.659,4.192C88.707,3.927 88.964,3.713 89.234,3.713L95.477,3.713C95.747,3.713 95.926,3.927 95.878,4.192L94.798,10.178Z"}),t.jsx("path",{fill:r,d:"M101.284,14.421L103.995,14.421C104.443,14.421 104.871,14.065 104.951,13.624L105.43,10.97C105.446,10.882 105.531,10.81 105.621,10.81L108.902,10.806C109.064,10.806 109.2,10.886 109.267,11.018L110.813,14.035C110.992,14.392 111.319,14.434 112.303,14.419C112.88,14.426 113.756,14.382 115.169,14.382C115.623,14.382 115.902,13.907 115.678,13.51L113.989,10.569C113.945,10.491 113.993,10.386 114.086,10.34C115.39,9.707 116.423,8.477 116.681,7.055L117.27,3.785C117.646,1.713 116.242,0.033 114.134,0.033L103.884,0.033C103.436,0.033 103.008,0.39 102.928,0.831L100.616,13.623C100.536,14.064 100.836,14.421 101.284,14.421L101.284,14.421ZM106.73,3.791C106.745,3.703 106.831,3.631 106.921,3.631L112.225,3.631C112.626,3.631 112.891,3.949 112.821,4.343L112.431,6.494C112.359,6.885 111.979,7.204 111.58,7.204L106.276,7.204C106.186,7.204 106.127,7.133 106.142,7.043L106.73,3.791Z"}),t.jsx("path",{fill:r,d:"M118.277,14.421C118.277,14.421 130.388,14.421 130.388,14.421C130.657,14.421 130.915,14.205 130.963,13.942L131.468,11.128C131.516,10.863 131.337,10.649 131.068,10.649L122.65,10.649C122.56,10.649 122.501,10.576 122.516,10.488L122.766,9.105C122.781,9.017 122.867,8.944 122.957,8.944L129.728,8.944C129.997,8.944 130.254,8.728 130.302,8.465L130.753,5.974C130.801,5.709 130.621,5.495 130.352,5.495L123.581,5.495C123.492,5.495 123.432,5.423 123.448,5.335L123.715,3.852C123.73,3.764 123.816,3.691 123.906,3.691L132.324,3.691C132.593,3.691 132.851,3.476 132.898,3.21L133.389,0.498C133.437,0.235 133.257,0.019 132.988,0.019L120.877,0.019C120.428,0.019 119.999,0.378 119.919,0.819L117.605,13.621C117.527,14.062 117.827,14.421 118.277,14.421Z"})]})}),A={container:{hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:o.normal,delayChildren:.1}}},item:{hidden:{opacity:0,y:12},visible:{opacity:1,y:0,transition:c.smooth}},footer:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{...c.gentle,delay:.4}}},error:{hidden:{opacity:0,height:0,marginTop:0},visible:{opacity:1,height:"auto",marginTop:24,transition:c.snappy},exit:{opacity:0,height:0,marginTop:0,transition:{duration:.15}}}},X=n("block type-badge text-fg-secondary"),Y=e.memo(function({className:e}){return t.jsxs("svg",{className:n("animate-spin",e),viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]})}),q=e.memo(function({href:e,children:s}){return t.jsx(g.a,{href:e,target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.05},whileTap:{scale:.98},className:"inline-flex items-center gap-1.5 opacity-60 hover:opacity-100 transition-opacity",children:s})}),H=()=>t.jsx("span",{className:"text-white/20 text-xs","aria-hidden":"true",children:"•"}),I=e.memo(function(){return t.jsx("div",{className:"fixed inset-0 -z-10",style:{backgroundColor:d[950]},"aria-hidden":"true"})}),z=e.memo(function(){return t.jsxs(g.footer,{variants:A.footer,initial:"hidden",animate:"visible",className:"fixed bottom-0 inset-x-0 px-4 py-6",children:[t.jsx("p",{className:"text-center type-badge text-white/40 mb-3",children:"Powered By"}),t.jsx("div",{className:"mx-auto max-w-xs",children:t.jsxs("div",{className:"flex items-center justify-center gap-4",children:[t.jsx(q,{href:"https://github.com/rightup/pyMC_Repeater",children:t.jsx("img",{src:"/assets/pyMC-logo-CaIkLXHc.svg",alt:"pyMC",className:"h-14"})}),t.jsx(H,{}),t.jsx(q,{href:"https://meshcore.co.uk",children:t.jsx(Z,{height:12,className:"text-white"})}),t.jsx(H,{}),t.jsxs(q,{href:"https://wcmesh.com",children:[t.jsx("div",{className:"size-14 overflow-hidden radius-badge border border-white/10 -translate-y-1",children:t.jsx("img",{src:"/assets/WCM_Waves-RN-_ocPH.gif",alt:"",className:"size-full object-cover"})}),t.jsx("span",{className:"font-mono text-sm font-semibold tracking-tight text-white",children:"WCM"})]})]})})]})}),B={session_expired:"Your session has expired. Please sign in again.",no_token:"Authentication required. Please sign in.",token_expired_away:"Your session expired while you were away."};function F(){const n=s(),[o,c]=e.useState("admin"),[d,x]=e.useState(""),[C,p]=e.useState(r),[f,j]=e.useState(!1),[y,b]=e.useState(null),[v]=e.useState(()=>{try{const e=sessionStorage.getItem("auth_redirect_reason");return sessionStorage.removeItem("auth_redirect_reason"),e?B[e]??null:null}catch{return null}}),M=o.length>0&&d.length>0&&!f;e.useEffect(()=>{a()&&n("/",{replace:!0})},[n]);const w=e.useCallback(()=>b(null),[]),N=e.useCallback(e=>{c(e.target.value),y&&w()},[y,w]),k=e.useCallback(e=>{x(e.target.value),y&&w()},[y,w]),S=e.useCallback(e=>{p(e),i(e)},[]),T=e.useCallback(async e=>{if(e.preventDefault(),!M)return;j(!0),b(null);const t=await l(o,d,C);j(!1),t.success?window.location.href="/":b(t.error??"Login failed")},[M,o,d,C]),$=e.useCallback(e=>{"Enter"===e.key&&M&&"INPUT"===e.target.tagName&&(e.preventDefault(),e.currentTarget.requestSubmit())},[M]);return t.jsxs(t.Fragment,{children:[t.jsx(I,{}),t.jsx("main",{className:"flex min-h-svh items-center justify-center px-4 py-6 sm:px-6 lg:px-8 -mt-6",children:t.jsxs(g.div,{variants:A.container,initial:"hidden",animate:"visible",className:"w-full max-w-sm space-y-10",children:[t.jsx(g.div,{variants:A.item,className:"flex justify-center",children:t.jsx(R,{})}),v&&!y&&t.jsx(g.div,{variants:A.item,className:"rounded-md bg-sys-amber/10 px-3 py-2.5 text-center",children:t.jsx("p",{className:"text-sm text-sys-amber",children:v})}),t.jsxs(g.form,{variants:A.item,onSubmit:T,onKeyDown:$,className:"space-y-6",children:[t.jsxs("div",{children:[t.jsx("label",{htmlFor:"username",className:X,children:"Username"}),t.jsx("div",{className:"mt-2",children:t.jsx(h,{id:"username",name:"username",type:"text",value:o,onChange:N,required:!0,autoComplete:"username",className:"font-mono text-sm font-semibold"})})]}),t.jsxs("div",{children:[t.jsx("label",{htmlFor:"password",className:X,children:"Password"}),t.jsx("div",{className:"mt-2",children:t.jsx(h,{id:"password",name:"password",type:"password",value:d,onChange:k,required:!0,autoComplete:"current-password",autoFocus:!0,className:"font-mono text-sm font-semibold"})})]}),t.jsx("div",{className:"-mt-2",children:t.jsx(m,{checked:C,onChange:S,label:t.jsx("span",{className:"type-badge text-fg-secondary",children:"Remember me"}),size:"sm"})}),t.jsx(L,{mode:"wait",children:y&&t.jsx(g.div,{variants:A.error,initial:"hidden",animate:"visible",exit:"exit",role:"alert",className:"rounded-md bg-sys-red/10 p-3 overflow-hidden",children:t.jsx("p",{className:"text-sm text-sys-red text-center",children:y})},"error")}),t.jsx(g.div,{whileTap:M?{scale:.98}:void 0,children:t.jsx(u,{type:"submit",disabled:!M,className:"w-full py-3 radius-pill font-mono text-sm font-semibold uppercase tracking-wide text-white bg-sys-indigo hover:bg-sys-blue shadow-sm transition-colors",children:f?t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(Y,{className:"size-4"}),"Signing in…"]}):"Sign in"})})]}),t.jsxs(g.p,{variants:A.item,className:"text-center text-sm/6 text-fg-muted",children:["A ",t.jsx("span",{className:"text-sys-blue",children:"@RightUp"})," X"," ",t.jsx("span",{className:"text-sys-blue",children:"@Treehouse⚡"})," Collab"]})]})}),t.jsx(z,{})]})}export{F as default}; +import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{b as s,c as n}from"./vendor-core-FtpmsTnh.js";import{g as r,i as a,s as i,l,a as o,b as c,I as h,C as m,B as u,Z as d}from"./index-CkRTgHHA.js";import{g as x,B as C,r as p,T as f}from"./ascii-burst-CXC_pYgi.js";import{m as g,A as L}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";const j=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "],y=f-1,b=j.length,v=Math.max(...j.map(e=>e.length)),M={" ":0,".":.08,":":.15,"!":.5,"@":.85,"#":.6,$:.7,"%":.65,"&":.6,"*":.3,"+":.25,"-":.1,"=":.2,_:.05,"~":.2,"^":.15,"|":.4,"/":.3,"\\":.3,"(":.35,")":.35,"[":.4,"]":.4,"{":.45,"}":.45,"<":.3,">":.3,"?":.4,";":.2,"'":.1,'"':.15,",":.08,"`":.05};function w(e){let t="",s=0,n=!1,r="",a=!1,i=!1,l=!1;for(;s",n=!1),r="",a=!1,i=!1,l=!1;else if("1"===c)a=!0,l=!0;else if("2"===c)i=!0,l=!0;else if(c.startsWith("38;2;")){const e=c.split(";");r=`rgb(${e[2]},${e[3]},${e[4]})`,l=!0}}else{if(l){n&&(t+="");const e=[];r&&e.push(`color:${r}`),a&&e.push("font-weight:700"),i&&e.push("opacity:0.6"),e.length>0?(t+=``,n=!0):n=!1,l=!1}const o=e[s];t+="<"===o?"<":">"===o?">":"&"===o?"&":o,s++}return n&&(t+=""),t}function N(e){let t="";for(let s=0;s0&&(t+="\n"),t+=w(e[s]);return t}const k=[[91,91,214],[72,70,200],[110,110,230],[150,150,245],[190,210,255],[0,240,255],[255,50,180],[80,255,180]];function S(e,t,s){return`rgb(${Math.round(e[0]+(t[0]-e[0])*s)},${Math.round(e[1]+(t[1]-e[1])*s)},${Math.round(e[2]+(t[2]-e[2])*s)})`}function T(e){const t=Math.max(0,Math.min(.999,e));return" . ˙·∙⁺˚°:;~*+✧✩×✴░✦✶✳oO▒#%&xX▓@MW8B█████"[Math.floor(42*t)]}function $(e){return M[e]??.5}function _(e,t){const s=Math.abs(e);if(s<.3)return S(k[0],k[2],s/.3);if(s<.6){const e=(s-.3)/.3;return S(k[3],k[4],e)}{const e=.5*Math.sin(17.3*t)+.5;return e<.4?S(k[4],k[5],(s-.6)/.4):e<.6?`rgb(${k[6].join(",")})`:e<.7?`rgb(${k[7].join(",")})`:"rgb(255,252,255)"}}function P(e){let t="";for(let s=0;s0&&(t+="\n");const n=j[s]||"";for(let r=0;r0?Math.exp(-c*c/2):Math.exp(-c*c/12),m=.25*a-.4*t.radius,u=Math.sin(m*Math.PI),d=h*t.strength;i+=h*u*t.strength,d>o&&(o=d,l=m+.1*s+.05*r)}if(i=Math.max(-1,Math.min(1,i)),Math.abs(i)<.008)t+=`${a}`;else{const e=$(a)+.5*i,s=T(Math.max(.02,Math.min(.98,e)));t+=`${s}`}}}return t}const R=e.memo(function(){const s=e.useRef(null),n=e.useRef([]),r=e.useRef(0),[a,i]=e.useState(!1);e.useEffect(()=>{const e=s.current;if(!e)return;let t=0;e.innerHTML=N(x(j,0));const n=setInterval(()=>{if(t++,t>y)return clearInterval(n),void i(!0);e.innerHTML=N(x(j,t))},C);return()=>{clearInterval(n),p()}},[]),e.useEffect(()=>{if(!a)return;const e=s.current;if(!e)return;let t=!0;const i=()=>{if(!t)return;const s=n.current;for(const e of s)e.radius+=.08,e.strength*=.994;n.current=s.filter(e=>e.strength>.008),n.current.length>0?e.innerHTML=P(n.current):e.innerHTML=P([]),r.current=requestAnimationFrame(i)};return r.current=requestAnimationFrame(i),()=>{t=!1,cancelAnimationFrame(r.current)}},[a]);const l=e.useRef(null),o=e.useCallback((e,t,r=1)=>{const i=s.current;if(!i||!a)return;const o=i.getBoundingClientRect(),c=(e-o.left)/9.6,h=(t-o.top)/20;n.current.length>=8&&n.current.shift(),n.current.push({cx:c,cy:h,radius:0,strength:r}),l.current={x:e,y:t}},[a]),c=e.useCallback(e=>{const t=l.current;if(t){const s=e.clientX-t.x,n=e.clientY-t.y;if(Math.sqrt(s*s+n*n)<20)return;o(e.clientX,e.clientY,.7)}else o(e.clientX,e.clientY,.6)},[o]),h=e.useCallback(e=>{o(e.clientX,e.clientY,1)},[o]),m=e.useCallback(e=>{l.current=null,o(e.clientX,e.clientY,.6)},[o]),u=e.useCallback(e=>{if(e.touches.length>0){const t=e.touches[0],s=l.current;if(s){const e=t.clientX-s.x,n=t.clientY-s.y;if(Math.sqrt(e*e+n*n)<20)return}o(t.clientX,t.clientY,.9)}},[o]);return t.jsx("pre",{ref:s,"aria-label":"PYMC",role:"img",onPointerMove:c,onPointerDown:h,onPointerEnter:m,onTouchMove:u,style:{fontFamily:"'JetBrains Mono', monospace",fontSize:"16px",lineHeight:1.25,letterSpacing:"0.01em",textAlign:"center",whiteSpace:"pre",margin:0,overflow:"hidden",cursor:"crosshair",touchAction:"none"}})}),Z=e.memo(function({width:e,height:s,className:n="",fill:r="currentColor"}){return t.jsxs("svg",{viewBox:"0 0 134 15",width:e,height:s,className:n,role:"img","aria-label":"MeshCore",style:{fillRule:"evenodd",clipRule:"evenodd"},children:[t.jsx("path",{fill:r,d:"M3.277,0.053C2.829,0.053 2.401,0.41 2.321,0.851L0.013,13.623C-0.067,14.064 0.232,14.421 0.681,14.421L3.13,14.421C3.578,14.421 4.006,14.064 4.086,13.623L5.004,8.54L6.684,13.957C6.766,14.239 7.02,14.421 7.337,14.421L10.58,14.421C10.897,14.421 11.217,14.239 11.401,13.957L15.043,8.513L14.119,13.623C14.038,14.064 14.338,14.421 14.787,14.421L17.236,14.421C17.684,14.421 18.112,14.064 18.192,13.623L20.5,0.851C20.582,0.41 20.283,0.053 19.834,0.053L16.69,0.053C16.373,0.053 16.053,0.235 15.87,0.517L9.897,9.473C9.803,9.616 9.578,9.578 9.528,9.41L7.074,0.517C6.992,0.235 6.738,0.053 6.421,0.053L3.277,0.053Z"}),t.jsx("path",{fill:r,d:"M21.146,14.421C21.146,14.421 33.257,14.421 33.257,14.421C33.526,14.421 33.784,14.205 33.831,13.942L34.337,11.128C34.385,10.863 34.206,10.649 33.936,10.649L25.519,10.649C25.429,10.649 25.37,10.576 25.385,10.488L25.635,9.105C25.65,9.017 25.736,8.944 25.826,8.944L32.596,8.944C32.865,8.944 33.123,8.728 33.171,8.465L33.621,5.974C33.669,5.709 33.49,5.495 33.221,5.495L26.45,5.495C26.361,5.495 26.301,5.423 26.317,5.335L26.584,3.852C26.599,3.764 26.685,3.691 26.775,3.691L35.192,3.691C35.462,3.691 35.719,3.476 35.767,3.21L36.258,0.498C36.306,0.235 36.126,0.019 35.857,0.019L23.746,0.019C23.297,0.019 22.867,0.378 22.788,0.819L20.474,13.621C20.396,14.062 20.695,14.421 21.146,14.421Z"}),t.jsx("path",{fill:r,d:"M45.926,14.419L45.926,14.421L46.346,14.421C48.453,14.421 50.465,12.742 50.839,10.67L51.081,9.327C51.456,7.256 50.05,5.576 47.943,5.576L41.455,5.576C41.186,5.576 41.007,5.363 41.054,5.097L41.218,4.192C41.266,3.927 41.524,3.713 41.793,3.713L50.569,3.713C51.018,3.713 51.446,3.356 51.526,2.915L51.9,0.85C51.98,0.407 51.68,0.05 51.232,0.05L41.638,0.05C39.531,0.05 37.519,1.73 37.145,3.801L36.88,5.267C36.505,7.339 37.91,9.018 40.018,9.018L46.506,9.018C46.775,9.018 46.954,9.231 46.907,9.497L46.785,10.176C46.737,10.441 46.479,10.655 46.21,10.655L37.189,10.655C36.741,10.655 36.313,11.012 36.233,11.453L35.841,13.621C35.761,14.062 36.061,14.419 36.51,14.419L45.926,14.419Z"}),t.jsx("path",{fill:r,d:"M68.008,0.046C68.008,0.046 65.296,0.046 65.296,0.046C64.847,0.046 64.42,0.403 64.34,0.844L63.532,5.31C63.517,5.398 63.431,5.469 63.341,5.469L58.085,5.469C57.995,5.469 57.936,5.398 57.951,5.31L58.758,0.844C58.837,0.403 58.539,0.046 58.09,0.046L55.378,0.046C54.93,0.046 54.502,0.403 54.422,0.844L52.112,13.623C52.032,14.064 52.331,14.421 52.78,14.421L55.492,14.421C55.941,14.421 56.369,14.064 56.449,13.623L57.272,9.074C57.287,8.986 57.373,8.914 57.462,8.914L62.719,8.914C62.809,8.914 62.868,8.985 62.853,9.074L62.032,13.623C61.952,14.064 62.252,14.421 62.7,14.421L65.413,14.421C65.861,14.421 66.289,14.064 66.369,13.623L68.678,0.844C68.755,0.403 68.457,0.046 68.008,0.046Z"}),t.jsx("path",{fill:r,d:"M72.099,14.421C72.099,14.421 80.066,14.421 80.066,14.421C80.515,14.421 80.943,14.064 81.022,13.623L81.414,11.453C81.494,11.012 81.194,10.655 80.746,10.655L73.828,10.655C73.559,10.655 73.38,10.441 73.427,10.176L74.51,4.215C74.558,3.951 74.815,3.736 75.082,3.736L82,3.736C82.448,3.736 82.876,3.379 82.956,2.938L83.34,0.817C83.42,0.376 83.12,0.019 82.672,0.019L74.724,0.019C72.622,0.019 70.614,1.691 70.236,3.757L68.965,10.665C68.587,12.738 69.99,14.421 72.099,14.421Z"}),t.jsx("path",{fill:r,d:"M97.176,-0C97.176,0 88.882,0 88.882,0C86.775,0 84.763,1.68 84.389,3.751L83.139,10.67C82.765,12.741 84.169,14.421 86.277,14.421L94.571,14.421C96.678,14.421 98.69,12.741 99.064,10.67L100.314,3.751C100.689,1.68 99.284,-0 97.176,-0ZM94.798,10.178C94.75,10.443 94.492,10.657 94.223,10.657L87.978,10.657C87.709,10.657 87.529,10.443 87.577,10.178L88.659,4.192C88.707,3.927 88.964,3.713 89.234,3.713L95.477,3.713C95.747,3.713 95.926,3.927 95.878,4.192L94.798,10.178Z"}),t.jsx("path",{fill:r,d:"M101.284,14.421L103.995,14.421C104.443,14.421 104.871,14.065 104.951,13.624L105.43,10.97C105.446,10.882 105.531,10.81 105.621,10.81L108.902,10.806C109.064,10.806 109.2,10.886 109.267,11.018L110.813,14.035C110.992,14.392 111.319,14.434 112.303,14.419C112.88,14.426 113.756,14.382 115.169,14.382C115.623,14.382 115.902,13.907 115.678,13.51L113.989,10.569C113.945,10.491 113.993,10.386 114.086,10.34C115.39,9.707 116.423,8.477 116.681,7.055L117.27,3.785C117.646,1.713 116.242,0.033 114.134,0.033L103.884,0.033C103.436,0.033 103.008,0.39 102.928,0.831L100.616,13.623C100.536,14.064 100.836,14.421 101.284,14.421L101.284,14.421ZM106.73,3.791C106.745,3.703 106.831,3.631 106.921,3.631L112.225,3.631C112.626,3.631 112.891,3.949 112.821,4.343L112.431,6.494C112.359,6.885 111.979,7.204 111.58,7.204L106.276,7.204C106.186,7.204 106.127,7.133 106.142,7.043L106.73,3.791Z"}),t.jsx("path",{fill:r,d:"M118.277,14.421C118.277,14.421 130.388,14.421 130.388,14.421C130.657,14.421 130.915,14.205 130.963,13.942L131.468,11.128C131.516,10.863 131.337,10.649 131.068,10.649L122.65,10.649C122.56,10.649 122.501,10.576 122.516,10.488L122.766,9.105C122.781,9.017 122.867,8.944 122.957,8.944L129.728,8.944C129.997,8.944 130.254,8.728 130.302,8.465L130.753,5.974C130.801,5.709 130.621,5.495 130.352,5.495L123.581,5.495C123.492,5.495 123.432,5.423 123.448,5.335L123.715,3.852C123.73,3.764 123.816,3.691 123.906,3.691L132.324,3.691C132.593,3.691 132.851,3.476 132.898,3.21L133.389,0.498C133.437,0.235 133.257,0.019 132.988,0.019L120.877,0.019C120.428,0.019 119.999,0.378 119.919,0.819L117.605,13.621C117.527,14.062 117.827,14.421 118.277,14.421Z"})]})}),A={container:{hidden:{opacity:0},visible:{opacity:1,transition:{staggerChildren:o.normal,delayChildren:.1}}},item:{hidden:{opacity:0,y:12},visible:{opacity:1,y:0,transition:c.smooth}},footer:{hidden:{opacity:0,y:20},visible:{opacity:1,y:0,transition:{...c.gentle,delay:.4}}},error:{hidden:{opacity:0,height:0,marginTop:0},visible:{opacity:1,height:"auto",marginTop:24,transition:c.snappy},exit:{opacity:0,height:0,marginTop:0,transition:{duration:.15}}}},X=n("block type-badge text-fg-secondary"),Y=e.memo(function({className:e}){return t.jsxs("svg",{className:n("animate-spin",e),viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]})}),q=e.memo(function({href:e,children:s}){return t.jsx(g.a,{href:e,target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.05},whileTap:{scale:.98},className:"inline-flex items-center gap-1.5 opacity-60 hover:opacity-100 transition-opacity",children:s})}),H=()=>t.jsx("span",{className:"text-white/20 text-xs","aria-hidden":"true",children:"•"}),I=e.memo(function(){return t.jsx("div",{className:"fixed inset-0 -z-10",style:{backgroundColor:d[950]},"aria-hidden":"true"})}),z=e.memo(function(){return t.jsxs(g.footer,{variants:A.footer,initial:"hidden",animate:"visible",className:"fixed bottom-0 inset-x-0 px-4 py-6",children:[t.jsx("p",{className:"text-center type-badge text-white/40 mb-3",children:"Powered By"}),t.jsx("div",{className:"mx-auto max-w-xs",children:t.jsxs("div",{className:"flex items-center justify-center gap-4",children:[t.jsx(q,{href:"https://github.com/rightup/pyMC_Repeater",children:t.jsx("img",{src:"/assets/pyMC-logo-CaIkLXHc.svg",alt:"pyMC",className:"h-14"})}),t.jsx(H,{}),t.jsx(q,{href:"https://meshcore.co.uk",children:t.jsx(Z,{height:12,className:"text-white"})}),t.jsx(H,{}),t.jsxs(q,{href:"https://wcmesh.com",children:[t.jsx("div",{className:"size-14 overflow-hidden radius-badge border border-white/10 -translate-y-1",children:t.jsx("img",{src:"/assets/WCM_Waves-RN-_ocPH.gif",alt:"",className:"size-full object-cover"})}),t.jsx("span",{className:"font-mono text-sm font-semibold tracking-tight text-white",children:"WCM"})]})]})})]})}),B={session_expired:"Your session has expired. Please sign in again.",no_token:"Authentication required. Please sign in.",token_expired_away:"Your session expired while you were away."};function F(){const n=s(),[o,c]=e.useState("admin"),[d,x]=e.useState(""),[C,p]=e.useState(r),[f,j]=e.useState(!1),[y,b]=e.useState(null),[v]=e.useState(()=>{try{const e=sessionStorage.getItem("auth_redirect_reason");return sessionStorage.removeItem("auth_redirect_reason"),e?B[e]??null:null}catch{return null}}),M=o.length>0&&d.length>0&&!f;e.useEffect(()=>{a()&&n("/",{replace:!0})},[n]);const w=e.useCallback(()=>b(null),[]),N=e.useCallback(e=>{c(e.target.value),y&&w()},[y,w]),k=e.useCallback(e=>{x(e.target.value),y&&w()},[y,w]),S=e.useCallback(e=>{p(e),i(e)},[]),T=e.useCallback(async e=>{if(e.preventDefault(),!M)return;j(!0),b(null);const t=await l(o,d,C);j(!1),t.success?window.location.href="/":b(t.error??"Login failed")},[M,o,d,C]),$=e.useCallback(e=>{"Enter"===e.key&&M&&"INPUT"===e.target.tagName&&(e.preventDefault(),e.currentTarget.requestSubmit())},[M]);return t.jsxs(t.Fragment,{children:[t.jsx(I,{}),t.jsx("main",{className:"flex min-h-svh items-center justify-center px-4 py-6 sm:px-6 lg:px-8 -mt-6",children:t.jsxs(g.div,{variants:A.container,initial:"hidden",animate:"visible",className:"w-full max-w-sm space-y-10",children:[t.jsx(g.div,{variants:A.item,className:"flex justify-center",children:t.jsx(R,{})}),v&&!y&&t.jsx(g.div,{variants:A.item,className:"rounded-md bg-sys-amber/10 px-3 py-2.5 text-center",children:t.jsx("p",{className:"text-sm text-sys-amber",children:v})}),t.jsxs(g.form,{variants:A.item,onSubmit:T,onKeyDown:$,className:"space-y-6",children:[t.jsxs("div",{children:[t.jsx("label",{htmlFor:"username",className:X,children:"Username"}),t.jsx("div",{className:"mt-2",children:t.jsx(h,{id:"username",name:"username",type:"text",value:o,onChange:N,required:!0,autoComplete:"username",className:"font-mono text-sm font-semibold"})})]}),t.jsxs("div",{children:[t.jsx("label",{htmlFor:"password",className:X,children:"Password"}),t.jsx("div",{className:"mt-2",children:t.jsx(h,{id:"password",name:"password",type:"password",value:d,onChange:k,required:!0,autoComplete:"current-password",autoFocus:!0,className:"font-mono text-sm font-semibold"})})]}),t.jsx("div",{className:"-mt-2",children:t.jsx(m,{checked:C,onChange:S,label:t.jsx("span",{className:"type-badge text-fg-secondary",children:"Remember me"}),size:"sm"})}),t.jsx(L,{mode:"wait",children:y&&t.jsx(g.div,{variants:A.error,initial:"hidden",animate:"visible",exit:"exit",role:"alert",className:"rounded-md bg-sys-red/10 p-3 overflow-hidden",children:t.jsx("p",{className:"text-sm text-sys-red text-center",children:y})},"error")}),t.jsx(g.div,{whileTap:M?{scale:.98}:void 0,children:t.jsx(u,{type:"submit",disabled:!M,className:"w-full py-3 radius-pill font-mono text-sm font-semibold uppercase tracking-wide text-white bg-sys-indigo hover:bg-sys-blue shadow-sm transition-colors",children:f?t.jsxs("span",{className:"flex items-center gap-2",children:[t.jsx(Y,{className:"size-4"}),"Signing in…"]}):"Sign in"})})]}),t.jsxs(g.p,{variants:A.item,className:"text-center text-sm/6 text-fg-muted",children:["A ",t.jsx("span",{className:"text-sys-blue",children:"@RightUp"})," X"," ",t.jsx("span",{className:"text-sys-blue",children:"@Treehouse⚡"})," Collab"]})]})}),t.jsx(z,{})]})}export{F as default}; diff --git a/frontend/dist/assets/Logs-0I5VPDkH.js b/frontend/dist/assets/Logs-CVA2ZaR8.js similarity index 95% rename from frontend/dist/assets/Logs-0I5VPDkH.js rename to frontend/dist/assets/Logs-CVA2ZaR8.js index aed333a2..2fdc193b 100644 --- a/frontend/dist/assets/Logs-0I5VPDkH.js +++ b/frontend/dist/assets/Logs-CVA2ZaR8.js @@ -1 +1 @@ -import{r as s,j as e}from"./vendor-react-alRNW2nb.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{bn as t,bo as r,o as n,bp as o,bq as i,br as l,q as c,B as m,bs as d,bd as p,bt as x}from"./index-D7i6lQrq.js";import{P as h,a as j,B as g,C as u}from"./PageLayout-QhCLxU34.js";import{F as f,aZ as v,a_ as b}from"./vendor-icons-TO0PZKGR.js";import{m as y}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";const N=s.memo(function({log:s}){return e.jsx(y.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},transition:{duration:.15,ease:"easeOut"},className:"p-3 bg-subtle-fill/80 radius-inner depth-stroke-raised hover:bg-subtle-fill-strong transition-base",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:a("type-data-sm w-14 shrink-0",x(s.level)),children:s.level}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"type-data-sm text-fg-primary break-words whitespace-pre-wrap",children:s.message}),e.jsx("p",{className:"type-data-xs text-fg-muted mt-1",children:new Date(s.timestamp).toLocaleString()})]})]})})});function w({showDebug:s,onToggle:t}){return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:a("type-data-sm",s?"text-sys-orange":"text-sys-cyan"),children:s?"DEBUG":"INFO"}),e.jsx(p,{enabled:s,onChange:t,size:"sm"})]})}function k(){const p=t(),x=r(),y=n(),k=o(),D=i(),[B,C]=s.useState(!1),E=s.useCallback(()=>{C(s=>!s)},[]),L=B?p:p.filter(s=>"DEBUG"!==s.level),P=s.useRef(k);return P.current=k,s.useEffect(()=>{if(!y)return;P.current();const s=setInterval(()=>P.current(),l.logs);return()=>clearInterval(s)},[y]),e.jsxs(h,{children:[e.jsx(j,{title:"System Logs",icon:e.jsx(f,{}),controls:e.jsx(w,{showDebug:B,onToggle:E})}),e.jsx(g,{children:e.jsxs(u,{neomorphic:!0,noPadding:!0,children:[e.jsx(c,{listHeader:!0,icon:e.jsx(f,{className:"icon-sm"}),title:"Log Entries",actions:e.jsx(m,{plain:!0,color:y?"danger":"primary",onClick:()=>D(!y),title:y?"Pause":"Resume",className:a(!y&&"animate-pulse-slow"),children:y?e.jsx(v,{"data-slot":"icon",className:"!w-5 !h-5"}):e.jsx(b,{"data-slot":"icon",className:"!w-5 !h-5"})})}),e.jsx("div",{className:"space-y-2 max-h-[calc(100dvh-226px)] sm:max-h-[calc(100dvh-234px)] lg:max-h-[calc(100vh-194px)] overflow-y-auto p-4",children:x&&0===p.length?e.jsx(d,{count:10}):0===L.length?e.jsx("div",{className:"text-center py-12 text-fg-muted",children:0===p.length?"No logs available":"No logs match selected filters"}):L.map((s,a)=>e.jsx(N,{log:s},`${s.timestamp}-${a}`))})]})})]})}export{k as default}; +import{r as s,j as e}from"./vendor-react-alRNW2nb.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{bn as t,bo as r,o as n,bp as o,bq as i,br as l,q as c,B as m,bs as d,bd as p,bt as x}from"./index-CkRTgHHA.js";import{P as h,a as j,B as g,C as u}from"./PageLayout-BWMUVZgC.js";import{F as f,aZ as v,a_ as b}from"./vendor-icons-TO0PZKGR.js";import{m as y}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";const N=s.memo(function({log:s}){return e.jsx(y.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},transition:{duration:.15,ease:"easeOut"},className:"p-3 bg-subtle-fill/80 radius-inner depth-stroke-raised hover:bg-subtle-fill-strong transition-base",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:a("type-data-sm w-14 shrink-0",x(s.level)),children:s.level}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"type-data-sm text-fg-primary break-words whitespace-pre-wrap",children:s.message}),e.jsx("p",{className:"type-data-xs text-fg-muted mt-1",children:new Date(s.timestamp).toLocaleString()})]})]})})});function w({showDebug:s,onToggle:t}){return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:a("type-data-sm",s?"text-sys-orange":"text-sys-cyan"),children:s?"DEBUG":"INFO"}),e.jsx(p,{enabled:s,onChange:t,size:"sm"})]})}function k(){const p=t(),x=r(),y=n(),k=o(),D=i(),[B,C]=s.useState(!1),E=s.useCallback(()=>{C(s=>!s)},[]),L=B?p:p.filter(s=>"DEBUG"!==s.level),P=s.useRef(k);return P.current=k,s.useEffect(()=>{if(!y)return;P.current();const s=setInterval(()=>P.current(),l.logs);return()=>clearInterval(s)},[y]),e.jsxs(h,{children:[e.jsx(j,{title:"System Logs",icon:e.jsx(f,{}),controls:e.jsx(w,{showDebug:B,onToggle:E})}),e.jsx(g,{children:e.jsxs(u,{neomorphic:!0,noPadding:!0,children:[e.jsx(c,{listHeader:!0,icon:e.jsx(f,{className:"icon-sm"}),title:"Log Entries",actions:e.jsx(m,{plain:!0,color:y?"danger":"primary",onClick:()=>D(!y),title:y?"Pause":"Resume",className:a(!y&&"animate-pulse-slow"),children:y?e.jsx(v,{"data-slot":"icon",className:"!w-5 !h-5"}):e.jsx(b,{"data-slot":"icon",className:"!w-5 !h-5"})})}),e.jsx("div",{className:"space-y-2 max-h-[calc(100dvh-226px)] sm:max-h-[calc(100dvh-234px)] lg:max-h-[calc(100vh-194px)] overflow-y-auto p-4",children:x&&0===p.length?e.jsx(d,{count:10}):0===L.length?e.jsx("div",{className:"text-center py-12 text-fg-muted",children:0===p.length?"No logs available":"No logs match selected filters"}):L.map((s,a)=>e.jsx(N,{log:s},`${s.timestamp}-${a}`))})]})})]})}export{k as default}; diff --git a/frontend/dist/assets/MeshGraph-DIhPFkau.js b/frontend/dist/assets/MeshGraph-BfYUTS82.js similarity index 99% rename from frontend/dist/assets/MeshGraph-DIhPFkau.js rename to frontend/dist/assets/MeshGraph-BfYUTS82.js index 16ec24c3..24eac529 100644 --- a/frontend/dist/assets/MeshGraph-DIhPFkau.js +++ b/frontend/dist/assets/MeshGraph-BfYUTS82.js @@ -1 +1 @@ -var e=Object.defineProperty,t=(t,s,n)=>((t,s,n)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n)(t,"symbol"!=typeof s?s+"":s,n);import{r as s,j as n,m as a,W as i,Z as o}from"./vendor-react-alRNW2nb.js";import{r}from"./cosmograph-DqYT4sUA.js";import{b1 as l,b2 as c,aF as d,aB as u,b3 as m,b4 as h,b5 as x,b6 as p,b7 as g,b8 as f,b9 as v,p as b,aR as y,ba as j,bb as N,Z as w,h as C,J as k,bc as S,bd as D,be as L,B as F,av as R}from"./index-D7i6lQrq.js";import{u as M,r as H,f as B,g as P,e as E}from"./consumer-registry-KuOoZhsq.js";import{c as A,D as z,s as $}from"./DeepAnalysisModal-Ca6cBH6E.js";import{D as T}from"./DataBox-DpDXI-WX.js";import{h as I,c as G}from"./geo-utils-DJn8DnxF.js";import{b as O,A as Z,m as W}from"./vendor-motion-DNp0Qg4F.js";import{aK as K,aL as V,b as _,X as U,W as X,ah as Q,aM as q,aN as J,aO as Y,a4 as ee,au as te,m as se,P as ne,aP as ae,R as ie,aQ as oe,aR as re,aB as le,aS as ce,aT as de,C as ue,D as me,ar as he,L as xe,ak as pe,a as ge,o as fe,E as ve,aU as be}from"./vendor-icons-TO0PZKGR.js";import{N as ye,a as je}from"./badge-colors-BxLppqaF.js";import{e as Ne,f as we,g as Ce}from"./meshcore-tx-constants-BDLT5LMb.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-core-FtpmsTnh.js";import"./vendor-fonts-CRZaZSFf.js";function ke(e){if(null==e)return"";const t=String(e);return t.includes(",")||t.includes('"')||t.includes("\n")?`"${t.replace(/"/g,'""')}"`:t}function Se(e,t){const s=[e.join(",")];for(const n of t)s.push(n.map(ke).join(","));return s.join("\n")}function De(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function Le(e){return!e||e<=0?"":new Date(1e3*e).toISOString()}function Fe(e,t){return`${e}-${(new Date).toISOString().replace(/[:.]/g,"-").slice(0,19)}.${t}`}const Re=["hash","prefix","name","nodeClass","communityId","degree","inDegree","outDegree","betweenness","pathDiversity","packetCount","lastSeen","activityLevel","recencyScore","avgRssi","avgSnr","isZeroHop","prefixConfidence","hasCollision","collisionCandidates","isLocal","isHub","isGateway","isBackbone","isMobile","isGhost","isInLoop","latitude","longitude","contactType"];function Me(e){var t,s;return[e.hash,e.prefix,e.name??"",e.nodeClass,e.communityId,e.degree,e.inDegree,e.outDegree,e.betweenness.toFixed(6),e.pathDiversity,e.packetCount,Le(e.lastSeen),e.activityLevel,e.recencyScore.toFixed(4),(null==(t=e.avgRssi)?void 0:t.toFixed(1))??"",(null==(s=e.avgSnr)?void 0:s.toFixed(1))??"",e.isZeroHop,e.prefixConfidence.toFixed(4),e.hasCollision,e.collisionCandidates,e.isLocal,e.isHub,e.isGateway,e.isBackbone,e.isMobile,e.isGhost,e.isInLoop,e.latitude??"",e.longitude??"",e.contactType??""]}function He(e,t){const s=[];for(const n of e.nodeMetrics.values())!t&&n.isGhost||s.push({hash:n.hash,prefix:n.prefix,name:n.name,nodeClass:n.nodeClass,communityId:n.communityId,degree:n.degree,inDegree:n.inDegree,outDegree:n.outDegree,betweenness:n.betweenness,pathDiversity:n.pathDiversity,packetCount:n.packetCount,lastSeen:n.lastSeen,activityLevel:n.activityLevel,recencyScore:n.recencyScore,avgRssi:n.avgRssi,avgSnr:n.avgSnr,isZeroHop:n.isZeroHop,prefixConfidence:n.prefixConfidence,hasCollision:n.hasCollision,isLocal:n.isLocal,isHub:n.isHub,isGateway:n.isGateway,isBackbone:n.isBackbone,isMobile:n.isMobile,isGhost:n.isGhost,isInLoop:n.isInLoop,latitude:n.latitude,longitude:n.longitude,contactType:n.contactType});return s}const Be=["fromHash","toHash","key","packetCount","certainCount","avgConfidence","strength","forwardCount","reverseCount","symmetryRatio","dominantDirection","floodCount","directCount","isDirectPathEdge","isZeroHop","isLoopEdge","isCertain","avgRssi","avgSnr","avgRecency","hopDistanceFromLocal","edgeBetweenness","isBackbone"];function Pe(e,t){const s=t?e.edges:e.validatedEdges,n=new Set(e.backboneEdges);return s.map(t=>({fromHash:t.fromHash,toHash:t.toHash,key:t.key,packetCount:t.packetCount,certainCount:t.certainCount,avgConfidence:t.avgConfidence,strength:t.strength,forwardCount:t.forwardCount,reverseCount:t.reverseCount,symmetryRatio:t.symmetryRatio,dominantDirection:t.dominantDirection,floodCount:t.floodCount,directCount:t.directCount,isDirectPathEdge:t.isDirectPathEdge,isZeroHop:t.isZeroHop??!1,isLoopEdge:t.isLoopEdge??!1,isCertain:t.isCertain,avgRssi:t.avgRssi??null,avgSnr:t.avgSnr??null,avgRecency:t.avgRecency,hopDistanceFromLocal:t.hopDistanceFromLocal,edgeBetweenness:e.edgeBetweenness.get(t.key)??0,isBackbone:n.has(t.key)}))}const Ee=["pathKey","hops","hopCount","healthScore","weakestLinkKey","weakestLinkConfidence","avgEdgeCertainty","observationTrend","alternatePathsCount","estimatedLatencyMs","observationCount","routeType","lastSeen","involvesHub"];function Ae(e){return[e.pathKey,e.hops.join(">"),e.hops.length,e.healthScore.toFixed(4),e.weakestLinkKey??"",e.weakestLinkConfidence.toFixed(4),e.avgEdgeCertainty.toFixed(4),e.observationTrend.toFixed(4),e.alternatePathsCount,e.estimatedLatencyMs.toFixed(0),e.observationCount,e.routeType,Le(e.lastSeen),e.involvesHub]}const ze=["nodeHash","nodePrefix","nodeName","networkRole","floodFactor","directFactor","floodSlots","directSlots","trafficIntensity","directNeighborCount","collisionRisk","confidence","adjustment","dataConfidence","observationSymmetry","rationale"];function $e(e,t,s){const n=s.get(e);return[e,(null==n?void 0:n.prefix)??"",(null==n?void 0:n.name)??"",t.networkRole,t.floodFactor.toFixed(2),t.directFactor.toFixed(2),t.floodSlots,t.directSlots,t.trafficIntensity.toFixed(4),t.directNeighborCount,t.collisionRisk.toFixed(4),t.confidence.toFixed(4),t.adjustment,t.dataConfidence,t.observationSymmetry.toFixed(4),t.rationale]}function Te(e,t){var s,n;const a=new Set(e.backboneEdges),i=['','',` `,` pymc_console v${l}`," MeshCore LoRa Mesh Network Topology"," ",' ',""," \x3c!-- Node Attributes --\x3e",' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '," ",""," \x3c!-- Edge Attributes --\x3e",' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '," ",""," "];for(const o of e.nodeMetrics.values()){if(!t&&o.isGhost)continue;const e=De(o.name??o.prefix);i.push(` `),i.push(" "),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),null!=o.avgRssi&&i.push(` `),null!=o.avgSnr&&i.push(` `),i.push(" "),null==o.latitude||null==o.longitude||0===o.latitude&&0===o.longitude||i.push(` `),i.push(" ")}i.push(" "),i.push(""),i.push(" ");for(const o of e.validatedEdges){const r=e.nodeMetrics;if(!t&&((null==(s=r.get(o.fromHash))?void 0:s.isGhost)||(null==(n=r.get(o.toHash))?void 0:n.isGhost)))continue;const l=e.edgeBetweenness.get(o.key)??0;i.push(` `),i.push(" "),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(" "),i.push(" ")}return i.push(" "),i.push(" "),i.push(""),i.join("\n")}function Ie(e,t,s){const n={meta:{exportedAt:(new Date).toISOString(),pymcConsoleVersion:l,nodeCount:e.nodeMetrics.size,edgeCount:e.validatedEdges.length,communityCount:e.communityCount,loopCount:e.loops.length,backboneEdgeCount:e.backboneEdges.length,hubNodes:e.hubNodes.length,gatewayNodes:e.gatewayNodes.length,mobileNodes:e.mobileNodes.length,ghostNodes:e.discoveredNodes.filter(e=>e.isLikelyReal).length},nodes:He(e,t),edges:Pe(e,s),pathHealth:e.pathHealth.map(e=>({pathKey:e.pathKey,hops:e.hops,healthScore:e.healthScore,weakestLinkKey:e.weakestLinkKey,weakestLinkConfidence:e.weakestLinkConfidence,avgEdgeCertainty:e.avgEdgeCertainty,observationTrend:e.observationTrend,alternatePathsCount:e.alternatePathsCount,estimatedLatencyMs:e.estimatedLatencyMs,observationCount:e.observationCount,routeType:e.routeType,lastSeen:e.lastSeen,involvesHub:e.involvesHub})),txDelayRecommendations:Array.from(e.txDelayRecommendations.entries()).map(([t,s])=>{var n,a;return{nodeHash:t,nodePrefix:(null==(n=e.nodeMetrics.get(t))?void 0:n.prefix)??"",nodeName:(null==(a=e.nodeMetrics.get(t))?void 0:a.name)??null,networkRole:s.networkRole,floodFactor:s.floodFactor,directFactor:s.directFactor,floodSlots:s.floodSlots,directSlots:s.directSlots,trafficIntensity:s.trafficIntensity,collisionRisk:s.collisionRisk,confidence:s.confidence,adjustment:s.adjustment,dataConfidence:s.dataConfidence,rationale:s.rationale}}),loops:e.loops.map(e=>({id:e.id,nodes:e.nodes,edgeKeys:e.edgeKeys,size:e.size,avgCertainCount:e.avgCertainCount,minCertainCount:e.minCertainCount,includesLocal:e.includesLocal,strength:e.strength})),disambiguationStats:{totalPrefixes:e.disambiguationStats.totalPrefixes,unambiguousPrefixes:e.disambiguationStats.unambiguousPrefixes,collisionPrefixes:e.disambiguationStats.collisionPrefixes,collisionRate:e.disambiguationStats.collisionRate,avgConfidence:e.disambiguationStats.avgConfidence},viterbiStats:{totalPaths:e.viterbiStats.totalPaths,pathsWithGhosts:e.viterbiStats.pathsWithGhosts,avgPathConfidence:e.viterbiStats.avgPathConfidence,tracePacketsProcessed:e.viterbiStats.tracePacketsProcessed,pathPacketsProcessed:e.viterbiStats.pathPacketsProcessed,distantEdgesDiscovered:e.viterbiStats.distantEdgesDiscovered,duplicateGroupsFound:e.viterbiStats.duplicateGroupsFound,echolocationEdgesInferred:e.viterbiStats.echolocationEdgesInferred}};return JSON.stringify(n,null,2)}function Ge(e,t){const s=t.includeGhosts??!0,n=t.includeWeakEdges??!1;switch(t.format){case"csv":{let a,i;switch(t.dataset){case"nodes":case"full":default:a=function(e,t){const s=[];for(const n of e.nodeMetrics.values())!t&&n.isGhost||s.push(Me(n));return Se(Re,s)}(e,s),i="mesh-nodes";break;case"edges":a=function(e,t){const s=t?e.edges:e.validatedEdges,n=new Set(e.backboneEdges),a=s.map(t=>function(e,t,s){var n,a;return[e.fromHash,e.toHash,e.key,e.packetCount,e.certainCount,e.avgConfidence.toFixed(4),e.strength.toFixed(4),e.forwardCount,e.reverseCount,e.symmetryRatio.toFixed(4),e.dominantDirection,e.floodCount,e.directCount,e.isDirectPathEdge,e.isZeroHop??!1,e.isLoopEdge??!1,e.isCertain,(null==(n=e.avgRssi)?void 0:n.toFixed(1))??"",(null==(a=e.avgSnr)?void 0:a.toFixed(1))??"",e.avgRecency.toFixed(4),e.hopDistanceFromLocal,(t.get(e.key)??0).toFixed(6),s.has(e.key)]}(t,e.edgeBetweenness,n));return Se(Be,a)}(e,n),i="mesh-edges";break;case"pathHealth":a=function(e){const t=e.pathHealth.map(Ae);return Se(Ee,t)}(e),i="mesh-path-health";break;case"txDelay":a=function(e){const t=[];for(const[s,n]of e.txDelayRecommendations)t.push($e(s,n,e.nodeMetrics));return Se(ze,t)}(e),i="mesh-tx-delay"}return{content:a,filename:Fe(i,"csv"),mimeType:"text/csv"}}case"gexf":return{content:Te(e,s),filename:Fe("mesh-topology","gexf"),mimeType:"application/xml"};default:return{content:Ie(e,s,n),filename:Fe("mesh-topology","json"),mimeType:"application/json"}}}function Oe(e,t,s=1){const{n:n,adjList:a,totalWeight:i,degree:o}=e;if(0===i)return!1;const r=2*i,l=new Float64Array(n);for(let u=0;up+1e-7&&(p=a,x=e)}x!==n&&(l[n]-=u,l[x]+=u,t[e]=x,d=!0,c=!0)}}return c}function Ze(e,t){const{n:s,adjList:n}=e,a=new Set;for(let h=0;he-t),o=new Map;for(let h=0;h[]);for(const[h,x]of c){const[e,t]=h.split("-").map(Number),s=x/2;m[e].push({j:t,w:s}),m[t].push({j:e,w:s}),d[e]+=s,d[t]+=s,u+=s}return{newGraph:{n:r,adjList:m,totalWeight:u,degree:Array.from(d)},mapping:l}}function We(e,t,s){const n=(null==s?void 0:s.resolution)??1,a=(null==s?void 0:s.kWeight)??1,i=t.length;if(0===i)return{communities:new Map,numCommunities:0,modularity:0,passes:0};if(1===i)return{communities:new Map([[t[0],0]]),numCommunities:1,modularity:0,passes:0};const{graph:o}=function(e,t,s=1){const n=t.length,a=new Map;for(let l=0;l[]),o=new Array(n).fill(0);let r=0;for(const l of e){const e=a.get(l.fromHash),t=a.get(l.toHash);if(void 0===e||void 0===t)continue;if(e===t)continue;const n=Math.max(.01,(l.certainCount+1)*l.avgConfidence*l.strength),c=1===s?n:Math.pow(n,s);i[e].push({j:t,w:c}),i[t].push({j:e,w:c}),o[e]+=c,o[t]+=c,r+=c}return{graph:{n:n,adjList:i,totalWeight:r,degree:o},hashToIdx:a}}(e,t,a);let r=o,l=new Int32Array(i);for(let v=0;v=r.n)break;r=e,l=new Int32Array(e.n);for(let s=0;se-t),x=new Map;for(let v=0;v=20?"excellent":e>=10?"good":e>=3?"fair":e>=0?"marginal":"critical"}function Je(e){return e>=15?"anomalous-good":e>=5?"better":e>=-5?"expected":e>=-20?"worse":"anomalous-bad"}function Ye(e,t,s,n,a){const i=n.tx_power??22,o=n.spreading_factor??12,r=n.coding_rate??5,l=n.frequency??0,c=l>1e5?l/1e6:l||915,d=n.bandwidth??0,u=d>1e3?d/1e3:d||125,m=(null==a?void 0:a.sensitivityOverrideDbm)??Xe(o,u,r);let h=null,x=null;t&&s&&I(t.latitude??void 0,t.longitude??void 0)&&I(s.latitude??void 0,s.longitude??void 0)&&(h=G(t.latitude,t.longitude,s.latitude,s.longitude),x=h/1e3);let p=null,g=null;null!=h&&h>0&&(p=Ue(h,c),g=i+2.15+2.15-p);const f=e.avgRssi??null,v=e.avgSnr??null;let b=null,y=null;null!=f&&null!=g&&(b=f-g,y=Je(b));let j=null,N=null;null!=f&&(j=f-m,N=qe(j));const w=null!=f,C="anomalous-good"===y||"anomalous-bad"===y;return{edgeKey:e.key,fromHash:e.fromHash,toHash:e.toHash,distanceM:h,distanceKm:x,fsplDb:p,theoreticalRxPowerDbm:g,observedRssiDbm:f,observedSnrDb:v,deviationDb:b,deviationClass:y,marginDb:j,marginClass:N,sensitivityDbm:m,txPowerDbm:i,frequencyMhz:c,spreadingFactor:o,bandwidthKhz:u,noiseFloorDbm:null,isZeroHop:e.isZeroHop??!1,isTraceEstimated:!1,hasData:w,isAnomalous:C}}function et(e,t,s,n,a=22,i){var o,r;const l=e.traceQuality;if(!l)return null;let c=null;if(c=null!=l.forward&&null!=l.reverse?Math.min(l.forward.mean,l.reverse.mean):(null==(o=l.forward)?void 0:o.mean)??(null==(r=l.reverse)?void 0:r.mean)??null,null==c)return null;const d=n.spreading_factor??12,u=n.coding_rate??5,m=n.bandwidth??0,h=m>1e3?m/1e3:m||125,x=1e3*h,p=n.frequency??0,g=p>1e5?p/1e6:p||915,f=(null==i?void 0:i.sensitivityOverrideDbm)??Xe(d,h,u),v=(null==i?void 0:i.observedNoiseFloorDbm)??Qe(x),b=v+c;let y=null,j=null;t&&s&&I(t.latitude??void 0,t.longitude??void 0)&&I(s.latitude??void 0,s.longitude??void 0)&&(y=G(t.latitude,t.longitude,s.latitude,s.longitude),j=y/1e3);let N=null,w=null;null!=y&&y>0&&(N=Ue(y,g),w=a+2.15+2.15-N);let C=null,k=null;null!=w&&(C=b-w,k=Je(C));const S=b-f,D=qe(S);return{edgeKey:e.key,fromHash:e.fromHash,toHash:e.toHash,distanceM:y,distanceKm:j,fsplDb:N,theoreticalRxPowerDbm:w,observedRssiDbm:b,observedSnrDb:c,deviationDb:C,deviationClass:k,marginDb:S,marginClass:D,sensitivityDbm:f,noiseFloorDbm:v,txPowerDbm:a,frequencyMhz:g,spreadingFactor:d,bandwidthKhz:h,isZeroHop:!1,isTraceEstimated:!0,hasData:!0,isAnomalous:"anomalous-good"===k||"anomalous-bad"===k}}const tt={"anomalous-good":"#2DD4BF",better:"#34D399",expected:"#9CA3AF",worse:"#FB923C","anomalous-bad":"#EF4444"},st={excellent:"#34D399",good:"#A3E635",fair:"#FBBF24",marginal:"#FB923C",critical:"#EF4444"};function nt(e,t="margin"){return e.hasData?"deviation"===t?e.deviationClass?tt[e.deviationClass]:"#505058":e.marginClass?st[e.marginClass]:"#505058":"#505058"}function at(e,t=.5,s=4){return null==e.marginDb?t:t+Math.max(0,Math.min(1,e.marginDb/40))*(s-t)}let it=0;function ot(){return`ta-${++it}-${Date.now()}`}function rt(e){return{standard:0,ghost:1,mobile:2,neighbor:3,backbone:4,gateway:5,hub:6,local:7}[e]??0}class lt{constructor(e=200){t(this,"prevSnapshot",null),t(this,"log",[]),t(this,"maxLog"),this.maxLog=e}update(e,t){const s=function(e){var t,s;const n=new Set;for(const u of e.edges)n.add(u.key);const a=new Map,i=new Map,o=new Map,r=new Set;for(const[u,m]of e.nodeMetrics)a.set(u,m.betweenness),i.set(u,m.communityId),o.set(u,m.nodeClass),r.add(u);const l=new Set;for(const u of e.discoveredNodes)u.isLikelyReal&&l.add(u.prefix);const c=new Map,d=new Map;for(const u of e.edges)(null==(t=u.traceQuality)?void 0:t.composite)&&c.set(u.key,u.traceQuality.composite.mean),null!=(null==(s=u.traceQuality)?void 0:s.asymmetryDb)&&d.set(u.key,u.traceQuality.asymmetryDb);return{timestamp:Date.now(),edgeKeys:n,betweenness:a,communities:i,nodeClasses:o,ghostPrefixes:l,nodeHashes:r,traceSnr:c,traceAsymmetry:d}}(e);if(!this.prevSnapshot)return this.prevSnapshot=s,{anomalies:[],categoryCounts:{"edge-appeared":0,"edge-disappeared":0,"ghost-appeared":0,"ghost-disappeared":0,"betweenness-shift":0,"community-change":0,"class-change":0,"node-appeared":0,"node-disappeared":0,"snr-degradation":0,"asymmetry-shift":0},severityCounts:{info:0,warning:0,critical:0},totalCount:0,timestamp:Date.now()};const n=function(e,t,s){const n=Date.now(),a=[],i=e=>(null==s?void 0:s.get(e))??null;for(const d of t.edgeKeys)if(!e.edgeKeys.has(d)){const[e,t]=d.split("-"),s=i(e)??(null==e?void 0:e.slice(0,6)),o=i(t)??(null==t?void 0:t.slice(0,6));a.push({id:ot(),detectedAt:n,category:"edge-appeared",severity:"info",description:`New edge: ${s} ↔ ${o}`,edgeKey:d})}for(const d of e.edgeKeys)if(!t.edgeKeys.has(d)){const[e,t]=d.split("-"),s=i(e)??(null==e?void 0:e.slice(0,6)),o=i(t)??(null==t?void 0:t.slice(0,6));a.push({id:ot(),detectedAt:n,category:"edge-disappeared",severity:"warning",description:`Edge lost: ${s} ↔ ${o}`,edgeKey:d})}for(const d of t.nodeHashes)if(!e.nodeHashes.has(d)){const e=i(d);a.push({id:ot(),detectedAt:n,category:"node-appeared",severity:"info",description:`Node appeared: ${e??d.slice(0,8)}`,nodeHash:d,nodeName:e??void 0})}for(const d of e.nodeHashes)if(!t.nodeHashes.has(d)){const e=i(d);a.push({id:ot(),detectedAt:n,category:"node-disappeared",severity:"warning",description:`Node dropped: ${e??d.slice(0,8)}`,nodeHash:d,nodeName:e??void 0})}for(const d of t.ghostPrefixes)e.ghostPrefixes.has(d)||a.push({id:ot(),detectedAt:n,category:"ghost-appeared",severity:"info",description:`Ghost node discovered: ${d.toUpperCase()}`});for(const d of e.ghostPrefixes)t.ghostPrefixes.has(d)||a.push({id:ot(),detectedAt:n,category:"ghost-disappeared",severity:"info",description:`Ghost node resolved: ${d.toUpperCase()}`});for(const[d,u]of t.traceSnr){const t=e.traceSnr.get(d);if(void 0===t)continue;const s=t-u;s>=3&&a.push({id:ot(),detectedAt:n,category:"snr-degradation",severity:s>=6?"critical":"warning",description:`SNR dropped ${s.toFixed(1)} dB on edge ${d.slice(0,13)}`,edgeKey:d,previousValue:t,currentValue:u})}for(const[d,u]of t.traceAsymmetry){const t=e.traceAsymmetry.get(d);if(void 0===t)continue;const s=u-t;s>=4&&a.push({id:ot(),detectedAt:n,category:"asymmetry-shift",severity:s>=8?"critical":"warning",description:`Asymmetry grew ${s.toFixed(1)} dB on edge ${d.slice(0,13)}`,edgeKey:d,previousValue:t,currentValue:u})}for(const[d,u]of t.betweenness){const t=e.betweenness.get(d);if(void 0===t)continue;const s=Math.abs(u-t);if(s>=.15){const e=i(d),o=u>t?"increased":"decreased";a.push({id:ot(),detectedAt:n,category:"betweenness-shift",severity:s>=.3?"critical":"warning",description:`${e??d.slice(0,8)} betweenness ${o}: ${t.toFixed(3)} → ${u.toFixed(3)}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}for(const[d,u]of t.communities){const t=e.communities.get(d);if(void 0!==t&&u!==t){const e=i(d);a.push({id:ot(),detectedAt:n,category:"community-change",severity:"info",description:`${e??d.slice(0,8)} moved: community #${t} → #${u}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}for(const[d,u]of t.nodeClasses){const t=e.nodeClasses.get(d);if(void 0!==t&&u!==t){const e=i(d),s=rt(u)>rt(t);a.push({id:ot(),detectedAt:n,category:"class-change",severity:s?"warning":"info",description:`${e??d.slice(0,8)} ${s?"promoted":"changed"}: ${t} → ${u}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}const o={},r={},l=["edge-appeared","edge-disappeared","ghost-appeared","ghost-disappeared","betweenness-shift","community-change","class-change","node-appeared","node-disappeared","snr-degradation","asymmetry-shift"],c=["info","warning","critical"];for(const d of l)o[d]=0;for(const d of c)r[d]=0;for(const d of a)o[d.category]++,r[d.severity]++;return a.sort((e,t)=>t.detectedAt-e.detectedAt),{anomalies:a,categoryCounts:o,severityCounts:r,totalCount:a.length,timestamp:n}}(this.prevSnapshot,s,t);this.prevSnapshot=s;try{!function(e,t){var s,n,a;const i=t.edgeMap,o=t.nodeMetrics,r=new Set(t.backboneEdges??[]);for(const l of e){if(l.edgeKey&&("edge-appeared"===l.category||"edge-disappeared"===l.category)){const e=null==i?void 0:i.get(l.edgeKey),t=l.edgeKey.split("-"),c=t[0],d=t[1],u=c?null==o?void 0:o.get(c):void 0,m=d?null==o?void 0:o.get(d):void 0;l.edgeDetail=e?{fromName:(null==u?void 0:u.name)??null,toName:(null==m?void 0:m.name)??null,fromClass:(null==u?void 0:u.nodeClass)??null,toClass:(null==m?void 0:m.nodeClass)??null,packetCount:e.packetCount,confidence:e.avgConfidence,symmetryRatio:e.symmetryRatio,isBackbone:r.has(l.edgeKey),isLoop:e.isLoopEdge??!1,isZeroHop:e.isZeroHop??!1,isDirectPath:e.isDirectPathEdge,avgRssi:e.avgRssi??null,avgSnr:e.avgSnr??null,fromBetweenness:(null==u?void 0:u.betweenness)??null,toBetweenness:(null==m?void 0:m.betweenness)??null,traceCompositeSnr:(null==(n=null==(s=e.traceQuality)?void 0:s.composite)?void 0:n.mean)??null,traceAsymmetryDb:(null==(a=e.traceQuality)?void 0:a.asymmetryDb)??null}:{fromName:(null==u?void 0:u.name)??null,toName:(null==m?void 0:m.name)??null,fromClass:(null==u?void 0:u.nodeClass)??null,toClass:(null==m?void 0:m.nodeClass)??null,packetCount:0,confidence:0,symmetryRatio:0,isBackbone:!1,isLoop:!1,isZeroHop:!1,isDirectPath:!1,avgRssi:null,avgSnr:null,fromBetweenness:(null==u?void 0:u.betweenness)??null,toBetweenness:(null==m?void 0:m.betweenness)??null,traceCompositeSnr:null,traceAsymmetryDb:null}}if(l.nodeHash){const e=null==o?void 0:o.get(l.nodeHash);e&&(l.nodeDetail=ct(e))}}}(n.anomalies,e)}catch(a){console.warn("[TopologyAnomalyTracker] Enrichment failed, anomalies logged without detail:",a)}return this.log.unshift(...n.anomalies),this.log.length>this.maxLog&&(this.log.length=this.maxLog),n}getLog(){return this.log}getFiltered(e){const t=Date.now();return this.log.filter(s=>!(e.category&&s.category!==e.category||e.severity&&s.severity!==e.severity||e.nodeHash&&s.nodeHash!==e.nodeHash||e.maxAge&&t-s.detectedAt>e.maxAge))}clear(){this.log=[],this.prevSnapshot=null}}function ct(e){return{nodeClass:e.nodeClass,degree:e.degree,betweenness:e.betweenness,activityLevel:e.activityLevel,isZeroHop:e.isZeroHop,avgRssi:e.avgRssi,avgSnr:e.avgSnr,communityId:e.communityId,packetCount:e.packetCount,connectionCount:e.degree}}function dt(e){if(e.length<2)return 0;const t=e.length;let s=0,n=0,a=0,i=0;for(let r=0;r.3&&n.push({name:"Weak link certainty",description:e.weakestLinkKey?`Weakest: ${e.weakestLinkConfidence<.3?"very low":"low"} confidence`:`Average certainty: ${(100*e.avgEdgeCertainty).toFixed(0)}%`,score:i,weight:.25});let o=0;0===e.alternatePathsCount?(o=1,n.push({name:"No alternate paths",description:"Single route to destination — no failover available",score:o,weight:ut})):1===e.alternatePathsCount&&(o=.5,n.push({name:"Limited redundancy",description:"Only 1 alternate path available",score:o,weight:ut}));let r=0;if(e.weakestLinkKey){const a=t.get(e.weakestLinkKey),i=(null==a?void 0:a.avgRssi)??null,o=e.weakestLinkTraceSnr;if(null!=i){const e=i-s;e<3?(r=1,n.push({name:"Signal near sensitivity",description:`Weakest link: ${e.toFixed(1)} dB margin (< 3 dB)`,score:r,weight:mt})):e<10&&(r=1-(e-3)/7,n.push({name:"Low signal margin",description:`Weakest link: ${e.toFixed(1)} dB margin`,score:r,weight:mt}))}else null!=o&&o<5&&(r=o<-5?1:o<0?.7:.4,n.push({name:"Low trace SNR",description:`Weakest link trace SNR: ${o.toFixed(1)} dB`,score:r,weight:mt}))}let l=0;if(e.weakestLinkKey){const s=t.get(e.weakestLinkKey),a=null==s?void 0:s.traceQuality;(null==a?void 0:a.composite)&&(a.composite.mean<0?(l=.8,n.push({name:"Trace SNR negative",description:`Composite trace SNR: ${a.composite.mean.toFixed(1)} dB (negative)`,score:l,weight:ht})):a.composite.stdDev>4?(l=.6,n.push({name:"Unstable trace SNR",description:`High variance: σ=${a.composite.stdDev.toFixed(1)} dB`,score:l,weight:ht})):null!=a.asymmetryDb&&a.asymmetryDb>8&&(l=.5,n.push({name:"High SNR asymmetry",description:`Bidirectional asymmetry: ${a.asymmetryDb.toFixed(1)} dB`,score:l,weight:ht})))}const c=.3*a+.25*i+o*ut+r*mt+l*ht;if(c<.35)return null;let d,u;return c>=.75?(d="critical",u="imminent"):c>=.55?(d="high",u="near-term"):(d="moderate",u="watch"),{pathKey:e.pathKey,hops:e.hops,riskScore:Math.round(100*c)/100,riskLevel:d,factors:n,weakestEdgeKey:e.weakestLinkKey,healthScore:e.healthScore,observationTrend:e.observationTrend,alternatePathsCount:e.alternatePathsCount,urgency:u}}let pt=100;function gt(){return++pt}const ft="meshgraph-panel-";function vt(e){try{const t=localStorage.getItem(ft+e);return t?JSON.parse(t):null}catch{return null}}function bt({id:e,title:t,icon:a,open:i,onClose:o,defaultPosition:r,defaultSize:l,minSize:c={width:180,height:120},maxSize:d,autoHeight:u=!1,headerActions:m,children:h}){const x=O(),p=s.useRef(null),g=s.useRef(null),f=s.useMemo(()=>{const t=vt(e);return t?{x:t.x,y:t.y,w:t.w,h:u?l.height:t.h,minimized:t.minimized}:{x:r.x,y:r.y,w:l.width,h:l.height,minimized:!1}},[e]),[v,b]=s.useState({w:f.w,h:f.h}),[y,j]=s.useState(f.minimized),[N,w]=s.useState(()=>gt()),[C,k]=s.useState({x:f.x,y:f.y});s.useLayoutEffect(()=>{const t=p.current;if(!i||!t)return;const s=t.getBoundingClientRect();if(s.width<1||s.height<1)return;const n=vt(e),a=(o=(null==n?void 0:n.x)??f.x,r=(null==n?void 0:n.y)??f.y,l=(null==n?void 0:n.w)??v.w,c=s.width,d=s.height,{x:Math.max(8,Math.min(o,Math.max(8,c-l-8))),y:Math.max(8,Math.min(r,Math.max(8,d-36)))});var o,r,l,c,d;k(a)},[i,e]);const[S,D]=s.useState(!1),L=s.useRef({startX:0,startY:0,startW:0,startH:0,edge:""}),F=s.useRef(),R=s.useCallback(()=>{F.current&&clearTimeout(F.current),F.current=setTimeout(()=>{const t=g.current;if(!t)return;const s=window.getComputedStyle(t),n=new DOMMatrix(s.transform);!function(e,t){try{localStorage.setItem(ft+e,JSON.stringify(t))}catch{}}(e,{x:n.m41,y:n.m42,w:v.w,h:v.h,minimized:y})},300)},[e,v.w,v.h,y]);s.useEffect(()=>{R()},[v,y,R]);const M=s.useCallback(()=>{w(gt())},[]),H=s.useCallback(()=>{j(e=>!e)},[]),B=s.useCallback((e,t)=>{e.preventDefault(),e.stopPropagation(),D(!0),L.current={startX:e.clientX,startY:e.clientY,startW:v.w,startH:v.h,edge:t},M();const s=e=>{const{startX:t,startY:s,startW:n,startH:a,edge:i}=L.current,o=e.clientX-t,r=e.clientY-s;let l=n,u=a;"e"!==i&&"se"!==i||(l=Math.max(c.width,n+o),d&&(l=Math.min(d.width,l))),"s"!==i&&"se"!==i||(u=Math.max(c.height,a+r),d&&(u=Math.min(d.height,u))),b({w:l,h:u})},n=()=>{D(!1),window.removeEventListener("pointermove",s),window.removeEventListener("pointerup",n)};window.addEventListener("pointermove",s),window.addEventListener("pointerup",n)},[v,c,d,M]);return n.jsx("div",{ref:p,className:"absolute inset-0 pointer-events-none",style:{zIndex:N},children:n.jsx(Z,{children:i&&n.jsxs(W.div,{ref:g,drag:!S,dragControls:x,dragConstraints:p,dragElastic:.05,dragMomentum:!1,dragListener:!1,initial:{opacity:0,scale:.96,x:C.x,y:C.y},animate:{opacity:1,scale:1,x:C.x,y:C.y},exit:{opacity:0,scale:.96},transition:{duration:.15},onPointerDown:M,className:"absolute top-0 left-0 pointer-events-auto",style:{width:v.w,touchAction:"none"},children:[n.jsxs("div",{className:"surface-elevated radius-inset shadow-xl overflow-hidden flex flex-col",style:{maxHeight:y?void 0:u?"80vh":v.h},children:[n.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 border-b border-edge-subtle cursor-grab active:cursor-grabbing select-none shrink-0",onPointerDown:e=>{M(),x.start(e)},children:[n.jsx(K,{className:"w-3 h-3 text-fg-muted/50 shrink-0"}),a&&n.jsx("span",{className:"text-fg-muted shrink-0 [&>svg]:w-3 [&>svg]:h-3",children:a}),n.jsx("span",{className:"text-[11px] font-medium text-fg-primary flex-1 truncate",children:t}),m,n.jsx("button",{onClick:H,className:"p-0.5 radius-badge hover-bg transition-base",title:y?"Expand":"Minimize",children:y?n.jsx(V,{className:"w-2.5 h-2.5 text-fg-muted"}):n.jsx(_,{className:"w-2.5 h-2.5 text-fg-muted"})}),n.jsx("button",{onClick:o,className:"p-0.5 radius-badge hover-bg transition-base",title:"Close",children:n.jsx(U,{className:"w-2.5 h-2.5 text-fg-muted"})})]}),n.jsx(Z,{initial:!1,children:!y&&n.jsx(W.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.15},className:"overflow-hidden",children:n.jsx("div",{className:"overflow-y-auto",style:{maxHeight:u?"70vh":void 0},children:h})})})]}),!y&&!u&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"absolute top-0 -right-1 w-2 h-full cursor-ew-resize",onPointerDown:e=>B(e,"e")}),n.jsx("div",{className:"absolute -bottom-1 left-0 w-full h-2 cursor-ns-resize",onPointerDown:e=>B(e,"s")}),n.jsx("div",{className:"absolute -bottom-1 -right-1 w-3 h-3 cursor-nwse-resize",onPointerDown:e=>B(e,"se"),children:n.jsxs("svg",{className:"w-full h-full text-fg-muted/30",viewBox:"0 0 12 12",children:[n.jsx("path",{d:"M10 2 L10 10 L2 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),n.jsx("path",{d:"M7 5 L7 7 L5 7",fill:"none",stroke:"currentColor",strokeWidth:"1"})]})})]})]})})})}const yt=[{target:"Graph",fn:"topology.edges",minStage:2,when:B},{target:"Graph",fn:"topology.edges",minStage:2,when:P},{target:"Graph",fn:"nodeMetrics",minStage:2},{target:"Graph",fn:"ghostNodes",minStage:2,when:B},{target:"Graph",fn:"_advertNodeType",minStage:1,when:E},{target:"Graph",fn:"pathHealth",minStage:2}];H(yt);const jt=800,Nt={critical:[N.red,N.red],poor:[N.orange,N.orange],fair:[N.amber,N.amber],good:[N.green,N.green],excellent:[N.blue,N.blue]},wt={active:1,recent:.85,stale:.45,inactive:.25},Ct=[N.purple,N.green,N.amber,N.red,N.blue,N.pink,N.teal,N.orange],kt=[N.purple,N.green,N.amber,N.red,N.blue,N.pink,N.teal,N.orange];function St(e,t,s){const n=(e,t)=>parseInt(e.slice(1+2*t,3+2*t),16);return`#${[0,1,2].map(a=>{return(i=a,Math.round(n(e,i)*s+n(t,i)*(1-s))).toString(16).padStart(2,"0");var i}).join("")}`}const Dt={zeroHop:St(N.amber,w[500],.55),directPath:St(N.teal,w[500],.55),loop:St(N.purple,w[500],.55),backbone:w[300],standard:w[500],standardDim:w[600],ghost:w[600]},Lt={zeroHop:St(N.amber,w[700],.5),directPath:St(N.teal,w[700],.5),loop:St(N.purple,w[700],.5),backbone:w[700],standard:w[400],standardDim:w[300],ghost:w[400]},Ft=!1,Rt=!0,Mt=!0,Ht=!0,Bt=!0,Pt=!0,Et={local:N.amber,hub:N.purple,gateway:N.blue,backbone:N.green,neighbor:N.pink,mobile:N.orange,ghost:w[400],standard:w[300]},At={local:N.amber,hub:N.purple,gateway:N.blue,backbone:N.green,neighbor:N.pink,mobile:N.orange,ghost:w[500],standard:w[600]},zt={local:"Your repeater — the home node running this dashboard",hub:"≥10% of last-hop traffic — dominant forwarder for your local node",gateway:"7-10% of last-hop traffic — significant relay node",backbone:"High betweenness centrality — critical path node connecting clusters",neighbor:"Zero-hop direct RF contact — no intermediate forwarders",mobile:"High path volatility — node appears and disappears frequently",ghost:"Unresolved prefix inferred by Viterbi HMM from path patterns",standard:"<7% of traffic — normal mesh participant"};function $t(e){const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}function Tt(e,t,s){const[n,a,i]=$t(e),[o,r,l]=$t(t),c=Math.max(0,Math.min(1,s)),d=Math.round(n*c+o*(1-c)),u=Math.round(a*c+r*(1-c)),m=Math.round(i*c+l*(1-c));return`#${d.toString(16).padStart(2,"0")}${u.toString(16).padStart(2,"0")}${m.toString(16).padStart(2,"0")}`}function It(e,t){return e.isZeroHop?"zero-hop":e.isDirectPathEdge?"direct-path":e.isLoopEdge?"loop":t.has(e.key)?"backbone":"standard"}function Gt(e,t,s){const n=s?Dt:Lt;switch(e){case"zero-hop":return n.zeroHop;case"direct-path":return n.directPath;case"loop":return n.loop;case"backbone":return n.backbone;case"ghost":return n.ghost;default:return t>=.7?n.standard:n.standardDim}}const Ot={"zero-hop":"Zero-Hop (Direct RF)","direct-path":"Direct Path (Unicast)",loop:"Redundant Loop",backbone:"Backbone",standard:"Standard",ghost:"Ghost (Inferred)"},Zt={"zero-hop":"Direct radio contact — no intermediate forwarders in path","direct-path":"Unicast-routed edge — verified via DIRECT route type packets",loop:"Redundant path — alternate route between the same endpoints exists",backbone:"High betweenness centrality — critical traffic flow edge",standard:"Normal mesh edge with moderate-to-high confidence",ghost:"Inferred connection from Viterbi HMM ghost node analysis"},Wt=s.memo(function({timeline:e}){const t=e.buckets;if(t.length<2)return null;const[s,a]=e.rssiRange,i=Math.max(1,a-s),[o,r]=e.snrRange,l=Math.max(1,r-o),c=198/(t.length-1),d=t.map((e,t)=>{const n=1+t*c,a=1+34*(1-(e.avgRssi-s)/i);return`${n.toFixed(1)},${a.toFixed(1)}`}).join(" "),u=t.map((e,t)=>{const s=1+t*c,n=1+34*(1-(e.avgSnr-o)/l);return`${s.toFixed(1)},${n.toFixed(1)}`}).join(" "),m=e.rssiTrend>.1?"↑":e.rssiTrend<-.1?"↓":"→",h=e.snrTrend>.1?"↑":e.snrTrend<-.1?"↓":"→",x=e.rssiTrend>.1?"#34D399":e.rssiTrend<-.1?"#EF4444":"#9CA3AF",p=e.snrTrend>.1?"#34D399":e.snrTrend<-.1?"#EF4444":"#9CA3AF",g=(e.timeSpanMs/36e5).toFixed(1),f=function(e){const t=e.rssiTrend<-.1,s=e.snrTrend<-.1,n=e.rssiTrend>.1,a=e.snrTrend>.1,i=e.rssiRange[1]-e.rssiRange[0],o=e.snrRange[1]-e.snrRange[0];return t&&s?{text:"Both RSSI and SNR declining — possible antenna degradation or increasing distance",color:"#EF4444"}:s&&!t?{text:"SNR declining while RSSI stable — likely RF interference or noise floor increase",color:"#F97316"}:t&&!s?{text:"RSSI declining while SNR stable — possible path obstruction or power change",color:"#F97316"}:n&&a?{text:"Signal improving — conditions favorable or antenna adjustment working",color:"#34D399"}:i>15||o>10?{text:"High signal variance — intermittent obstruction or multipath fading",color:"#FBBF24"}:{text:"Signal stable — no significant degradation detected",color:"#9CA3AF"}}(e);return n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center justify-between mb-1",children:[n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Signal Quality Over Time"}),n.jsx("div",{className:"text-fg-secondary text-[11px]",children:"Tracks RSSI (signal power) and SNR (signal-to-noise ratio) for zero-hop packets received directly from this neighbor. Reveals weather effects, interference, and antenna degradation."}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 font-mono text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Samples"}),n.jsx("span",{className:"text-fg-primary tabular-nums",children:e.totalSamples})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Time span"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[g,"h"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg RSSI"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg SNR"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"RSSI trend"}),n.jsxs("span",{className:"tabular-nums",style:{color:x},children:[e.rssiTrend>0?"+":"",e.rssiTrend.toFixed(3)," dBm/bucket"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"SNR trend"}),n.jsxs("span",{className:"tabular-nums",style:{color:p},children:[e.snrTrend>0?"+":"",e.snrTrend.toFixed(3)," dB/bucket"]})]})]}),n.jsxs("div",{className:"text-[10px] text-fg-muted italic",children:["Trend is linear regression slope across ",t.length," time buckets. ↑ = improving, ↓ = degrading, → = stable."]})]}),children:n.jsx("span",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Signal Timeline"})}),n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums",children:[e.totalSamples," samples · ",g,"h"]})]}),n.jsxs("svg",{viewBox:"0 0 200 36",className:"w-full h-9",preserveAspectRatio:"none",children:[n.jsx("polyline",{points:d,fill:"none",stroke:"#60A5FA",strokeWidth:"1.5",strokeLinejoin:"round",strokeLinecap:"round",opacity:"0.8"}),n.jsx("polyline",{points:u,fill:"none",stroke:"#34D399",strokeWidth:"1",strokeLinejoin:"round",strokeLinecap:"round",opacity:"0.5",strokeDasharray:"3 2"})]}),n.jsxs("div",{className:"flex items-center justify-between text-[9px] mt-0.5",children:[n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsxs("span",{className:"flex items-center gap-0.5",children:[n.jsx("span",{className:"w-2.5 h-[1.5px] bg-[#60A5FA] rounded-full inline-block"}),n.jsx("span",{className:"text-fg-muted",children:"RSSI"}),n.jsx("span",{className:"tabular-nums",style:{color:x},children:m})]}),n.jsxs("span",{className:"flex items-center gap-0.5",children:[n.jsx("span",{className:"w-2.5 h-[1px] bg-[#34D399] rounded-full inline-block opacity-50",style:{borderTop:"1px dashed #34D399"}}),n.jsx("span",{className:"text-fg-muted",children:"SNR"}),n.jsx("span",{className:"tabular-nums",style:{color:p},children:h})]})]}),n.jsxs("div",{className:"flex items-center gap-2 text-fg-muted tabular-nums",children:[n.jsxs("span",{children:[s.toFixed(0),"…",a.toFixed(0)," dBm"]}),n.jsxs("span",{children:[o.toFixed(0),"…",r.toFixed(0)," dB"]})]})]}),n.jsx("div",{className:"mt-1 text-[9px] leading-tight",style:{color:f.color},children:f.text})]})}),Kt=s.memo(function({edge:e,onClose:t}){const[a,i]=s.useState(null);return s.useEffect(()=>{if(!e.isZeroHop&&"zero-hop"!==e.edgeType)return void i(null);const t=R.getState().packets,s=R.getState().cachedLocalHash??void 0,n=function(e,t,s,n,a=24){const i=function(e,t,s,n){var a;const i=[],o=t.replace(/^0x/i,"").slice(0,2).toLowerCase();for(const r of e){if(r.transmitted)continue;if(null==r.rssi||null==r.snr)continue;if(0===r.rssi&&0===r.snr)continue;const e=(null==(a=r.src_hash)?void 0:a.replace(/^0x/i,""))??"";if(e.slice(0,2).toLowerCase()!==o&&e!==t.replace(/^0x/i,""))continue;const s=r.original_path??r.forwarded_path??[],l=c(s,n),u=(null==l?void 0:l.effectiveLength)??0,m=r.route??r.route_type;let h=!1;h=null!=m&&d(m)?u<=1:0===u,h&&i.push({timestamp:1e3*r.timestamp,rssi:r.rssi,snr:r.snr})}if(i.sort((e,t)=>e.timestamp-t.timestamp),i.length>0&&i[0].timestamp<4102444800)for(const r of i)r.timestamp*=1e3;return i}(e,t,0,n);if(i.length<3)return null;const o=function(e,t=24){if(0===e.length)return[];const s=e[0].timestamp,n=e[e.length-1].timestamp-s;if(n<=0)return[{timestamp:s,avgRssi:e.reduce((e,t)=>e+t.rssi,0)/e.length,avgSnr:e.reduce((e,t)=>e+t.snr,0)/e.length,minRssi:Math.min(...e.map(e=>e.rssi)),maxRssi:Math.max(...e.map(e=>e.rssi)),minSnr:Math.min(...e.map(e=>e.snr)),maxSnr:Math.max(...e.map(e=>e.snr)),count:e.length}];const a=n/t,i=[];for(let r=0;r0&&(r.avgRssi/=r.count,r.avgSnr/=r.count,o.push(r));return o}(i,a);if(o.length<2)return null;let r=0,l=0,u=1/0,m=-1/0,h=1/0,x=-1/0;for(const c of i)r+=c.rssi,l+=c.snr,u=Math.min(u,c.rssi),m=Math.max(m,c.rssi),h=Math.min(h,c.snr),x=Math.max(x,c.snr);const p=dt(o.map(e=>e.avgRssi)),g=dt(o.map(e=>e.avgSnr)),f=i[0].timestamp,v=i[i.length-1].timestamp;return{buckets:o,totalSamples:i.length,rssiRange:[u,m],snrRange:[h,x],avgRssi:r/i.length,avgSnr:l/i.length,rssiTrend:p,snrTrend:g,timeSpanMs:v-f}}(t,e.source,e.target,s);i(n)},[e.source,e.target,e.isZeroHop,e.edgeType]),n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx(be,{className:"size-3.5 text-fg-muted shrink-0"}),n.jsxs("span",{className:"text-sm font-semibold text-fg-primary truncate",children:[e.fromName??e.source.slice(0,6)," → ",e.toName??e.target.slice(0,6)]}),n.jsxs("div",{className:"flex gap-1 shrink-0",children:[n.jsx(C,{color:"zinc",compact:!0,children:Ot[e.edgeType]}),e.isBackbone&&n.jsx(C,{color:"emerald",compact:!0,children:"BONE"}),e.isLoopEdge&&n.jsx(C,{color:"indigo",compact:!0,children:"LOOP"}),e.isGhost&&n.jsx(C,{color:"zinc",compact:!0,children:"GHOST"})]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Average disambiguation confidence across all observations of this edge",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.confidence).toFixed(0),"%"]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Observations where both endpoints had high-confidence disambiguation",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Certain"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.certainCount.toLocaleString()})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Total packets observed traversing this edge",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Packets"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.packetCount.toLocaleString()})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Combined certainCount × confidence metric for edge ranking",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Strength"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.strength.toFixed(2)})]})]}),n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Bidirectional balance (min/max) — 0 = one-way traffic, 1 = perfectly balanced",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Symmetry"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.symmetryRatio.toFixed(2)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Dominant traffic flow direction between these nodes",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Direction"})}),n.jsx("div",{className:"text-fg-primary capitalize",children:e.dominantDirection})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Forward (A→B) vs reverse (B→A) observation counts",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Fwd / Rev"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.forwardCount," / ",e.reverseCount]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Routing method — broadcast flood vs unicast direct routing",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Flood / Direct"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.floodCount," / ",e.directCount]})]})]}),(null!=e.avgRssi||null!=e.avgSnr)&&n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),null!=e.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]})]}),e.linkBudget&&n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.linkBudget.distanceKm&&n.jsxs("div",{children:[n.jsx(k,{content:"Haversine distance between endpoint locations",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Distance"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.distanceKm.toFixed(2)," km"]})]}),null!=e.linkBudget.fsplDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Free Space Path Loss — theoretical signal attenuation over this distance at configured frequency",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"FSPL"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.fsplDb.toFixed(1)," dB"]})]}),null!=e.linkBudget.marginDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Link margin — observed RSSI minus receiver sensitivity. Positive = signal headroom above minimum.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Margin"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",style:{color:e.linkBudget.marginClass?st[e.linkBudget.marginClass]:void 0},children:[e.linkBudget.marginDb>0?"+":"",e.linkBudget.marginDb.toFixed(1)," dB"]})]}),null!=e.linkBudget.deviationDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Deviation from theoretical FSPL — positive means better signal than free-space prediction",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"vs Theory"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.deviationDb>0?"+":"",e.linkBudget.deviationDb.toFixed(1)," dB"]})]})]}),a&&n.jsx(Wt,{timeline:a})]})]})}),Vt=s.memo(function({node:e,onClose:t,egoMetrics:a,onExpandEgo:i,neighbors:o,onSelectNeighbor:r,txDelayRec:l}){const[c,d]=s.useState(!1),[u,m]=s.useState(!1);return n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl max-h-[60vh] flex flex-col",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx("span",{className:"size-2 shrink-0 rounded-full",style:{backgroundColor:(L()?Et:At)[e.nodeClass]}}),n.jsx("code",{className:"text-sm font-semibold text-fg-primary shrink-0",children:e.prefix}),e.name&&n.jsx("span",{className:"text-sm text-fg-secondary truncate",children:e.name}),n.jsxs("div",{className:"flex gap-1 shrink-0",children:[e.isLocal&&n.jsx(C,{color:"yellow",compact:!0,children:"LOCAL"}),e.isHub&&n.jsx(C,{color:"violet",compact:!0,children:"HUB"}),e.isGateway&&n.jsx(C,{color:"sky",compact:!0,children:"GW"}),e.isBackbone&&n.jsx(C,{color:"emerald",compact:!0,children:"BONE"}),e.isMobile&&n.jsx(C,{color:"orange",compact:!0,children:"MOB"}),e.isZeroHop&&n.jsx(C,{color:"amber",compact:!0,children:"RF"}),e.isGhost&&n.jsx(C,{color:"zinc",compact:!0,children:"GHOST"}),e.isInLoop&&n.jsx(C,{color:"indigo",compact:!0,children:"LOOP"})]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsx(T,{copy:!0,size:"compact",truncate:[10,6],className:"w-full mb-3",children:e.hash}),n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Total connections (edges) to this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Degree"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.degree})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Inbound vs outbound edge count — indicates traffic directionality",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"In / Out"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.inDegree," / ",e.outDegree]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Betweenness centrality (0–1) — how often this node lies on shortest paths. High value = critical relay.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Between."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.betweenness.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Total packets observed involving this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Packets"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.packetCount.toLocaleString()})]})]}),n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Number of topology edges connected to this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Edges"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.edgeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Community cluster assignment from graph partitioning algorithm",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Community"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:["#",e.communityId]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Prefix disambiguation confidence — how certain the 2-char prefix→node mapping is (multi-factor scoring)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.prefixConfidence).toFixed(0),"%"]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Recency level — active (<1h), recent (<6h), stale (<24h), inactive (>24h)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Activity"})}),n.jsx("div",{className:"text-fg-primary capitalize",children:e.activityLevel})]})]}),(null!=e.avgRssi||null!=e.avgSnr)&&n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),null!=e.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]})]}),a&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"grid grid-cols-3 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Number of direct 1-hop neighbors in the topology",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Ego Size"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.neighborCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Local clustering coefficient — how interconnected this node's neighbors are (0 = none, 1 = fully connected)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Clustering"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.clusteringCoeff.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Average betweenness centrality of this node's direct neighbors",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Nbr Btw."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.avgNeighborBetweenness.toFixed(3)})]})]}),n.jsxs("div",{className:"grid grid-cols-3 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Average disambiguation confidence across all connected edges",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Edge Conf."})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*a.avgEdgeConfidence).toFixed(0),"%"]})]}),null!=a.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Avg RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[a.avgRssi.toFixed(1)," dBm"]})]}),null!=a.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Avg SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[a.avgSnr.toFixed(1)," dB"]})]})]})]}),l&&!l.insufficientData&&n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[n.jsx(k,{content:"RF-grounded TX delay recommendation from centralized topology engine. Anchored to MeshCore firmware defaults with observer bias correction.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase tracking-wide cursor-help",children:"TX Delay Recommendation"})}),n.jsxs("div",{className:"flex items-center gap-1",children:[l.networkRole&&n.jsx(C,{color:ye[l.networkRole],compact:!0,children:l.networkRole}),l.dataConfidence&&n.jsx(C,{color:je[l.dataConfidence],compact:!0,children:l.dataConfidence})]})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:`Flood TX delay factor (firmware default: ×${Ne})`,children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Flood"})}),n.jsx("div",{className:"text-fg-primary tabular-nums text-sys-amber",children:we(l.floodFactor)})]}),n.jsxs("div",{children:[n.jsx(k,{content:`Direct TX delay factor (firmware default: ×${Ce})`,children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Direct"})}),n.jsx("div",{className:"text-fg-primary tabular-nums text-sys-amber",children:we(l.directFactor)})]})]}),l.rationale&&n.jsx("div",{className:"mt-1 text-[9px] text-fg-muted leading-snug",children:l.rationale}),null!=l.observationSymmetry&&l.observationSymmetry<.6&&n.jsxs("div",{className:"mt-1 text-[9px] text-sys-amber/70 leading-snug",children:["⚠ Low observation symmetry (",(100*l.observationSymmetry).toFixed(0),"%) — recommendation damped toward firmware defaults"]}),n.jsxs("button",{onClick:async()=>{const e=`set txdelay ${l.floodFactor.toFixed(1)}\nset direct.txdelay ${l.directFactor.toFixed(1)}`;try{await navigator.clipboard.writeText(e)}catch{}m(!0),setTimeout(()=>m(!1),1500)},className:"mt-1.5 flex items-center gap-1 text-[9px] text-sys-blue hover:text-sys-blue/80 transition-base",children:[u?n.jsx(ge,{className:"w-3 h-3 text-sys-green"}):n.jsx(fe,{className:"w-3 h-3"}),u?"Copied!":"Copy CLI commands"]})]}),i&&n.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:n.jsxs("button",{onClick:i,className:"flex items-center gap-1.5 text-[10px] text-sys-blue hover:text-sys-blue/80 transition-base",children:[n.jsx(ve,{className:"w-3 h-3"}),"Expand 2-hop neighborhood"]})}),o&&o.length>0&&n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("button",{onClick:()=>d(e=>!e),className:"flex items-center justify-between w-full text-[9px] text-fg-muted uppercase tracking-wide cursor-pointer hover:text-fg-secondary transition-base",children:[n.jsxs("span",{children:["Neighbors (",o.length,")"]}),n.jsx(ue,{className:"w-3 h-3 transition-transform "+(c?"rotate-180":"")})]}),c&&n.jsx("div",{className:"mt-1.5 max-h-32 overflow-y-auto space-y-0.5",children:o.map(e=>n.jsxs("button",{onClick:()=>null==r?void 0:r(e.hash),className:"w-full flex items-center gap-2 px-1.5 py-1 radius-badge hover-bg transition-base text-left group",children:[n.jsx("code",{className:"text-[10px] text-sys-blue shrink-0 tabular-nums",children:e.prefix}),n.jsx("span",{className:"text-[10px] text-fg-secondary truncate flex-1",children:e.name||"—"}),null!=e.avgSnr&&n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums shrink-0",children:[e.avgSnr.toFixed(0)," dB"]}),null!=e.avgRssi&&n.jsx("span",{className:"text-[9px] text-fg-muted tabular-nums shrink-0",children:e.avgRssi.toFixed(0)}),n.jsxs("span",{className:"text-[9px] text-fg-muted/60 tabular-nums shrink-0",children:[(100*e.edgeConfidence).toFixed(0),"%"]})]},e.hash))})]})]})]})}),_t=s.memo(function({metrics:e,onClose:t}){const s=Object.entries(e.communities).sort(([,e],[,t])=>t-e),a=Object.entries(e.nodeClasses).sort(([,e],[,t])=>t-e);return n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx(Y,{className:"size-3.5 text-fg-muted shrink-0"}),n.jsx("span",{className:"text-sm font-semibold text-fg-primary",children:"Subgraph Analysis"}),n.jsxs(C,{color:"violet",compact:!0,children:[e.nodeCount," nodes"]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Nodes"}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.nodeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Edges where both endpoints are within the lasso selection",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Internal Edges"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.edgeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Mean betweenness centrality of selected nodes",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Between."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.avgBetweenness.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Mean edge disambiguation confidence for internal edges",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.avgConfidence).toFixed(0),"%"]})]})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase mb-1",children:"Communities"}),n.jsx("div",{className:"flex flex-wrap gap-1",children:s.map(([e,t])=>n.jsxs("span",{className:"text-fg-secondary",children:["#",e,"×",t]},e))})]}),n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase mb-1",children:"Node Types"}),n.jsx("div",{className:"flex flex-wrap gap-1",children:a.map(([e,t])=>n.jsxs("span",{className:"text-fg-secondary capitalize",children:[e,"×",t]},e))})]})]}),e.nodeCount>1&&n.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:n.jsxs("div",{className:"text-[9px] text-fg-muted flex items-center gap-1 flex-wrap",children:[n.jsx(k,{content:"Fraction of possible edges that exist — 2E / N(N-1)",children:n.jsxs("span",{className:"cursor-help",children:["Density: ",(2*e.edgeCount/(e.nodeCount*(e.nodeCount-1))*100).toFixed(1),"%"]})}),n.jsx("span",{children:"·"}),n.jsx(k,{content:"Mean connections per node — 2E / N",children:n.jsxs("span",{className:"cursor-help",children:["Avg Degree: ",(2*e.edgeCount/e.nodeCount).toFixed(1)]})}),null!=e.avgPathHealth&&n.jsxs(n.Fragment,{children:[n.jsx("span",{children:"·"}),n.jsx(k,{content:"Average health score of paths within the selection",children:n.jsxs("span",{className:"cursor-help",children:["Path Health: ",(100*e.avgPathHealth).toFixed(0),"%"]})})]})]})})]})]})});function Ut(){return n.jsxs("div",{className:"flex flex-col items-center justify-center gap-6 text-center px-8",children:[n.jsx("div",{className:"p-4 radius-pill bg-subtle-fill",children:n.jsx(pe,{className:"w-8 h-8 text-fg-muted"})}),n.jsxs("div",{className:"space-y-2",children:[n.jsx("h2",{className:"type-subheading text-fg-primary",children:"No Topology Data"}),n.jsx("p",{className:"type-body text-fg-muted max-w-sm",children:"The mesh topology will appear here once packets are received and processed."})]}),n.jsxs("div",{className:"flex items-center gap-2 type-data-xs text-fg-muted",children:[n.jsx(ie,{className:"w-4 h-4 animate-pulse"}),n.jsx("span",{children:"Waiting for mesh traffic..."})]})]})}const Xt=s.memo(function({label:e,value:t,onChange:a,min:i,max:o,step:r}){const[l,c]=s.useState(!1),[d,u]=s.useState(""),m=s.useRef(null),h=s.useCallback(()=>{const e=parseFloat(d);isNaN(e)||a(Math.min(o,Math.max(i,Math.round(e/r)*r))),c(!1)},[d,a,i,o,r]),x=s.useCallback(()=>{u(t.toFixed(2)),c(!0),setTimeout(()=>{var e;return null==(e=m.current)?void 0:e.select()},0)},[t]);return n.jsxs("div",{className:"space-y-1",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsx("span",{className:"text-[10px] text-fg-muted",children:e}),l?n.jsx("input",{ref:m,type:"number",value:d,onChange:e=>u(e.target.value),onBlur:h,onKeyDown:e=>{"Enter"===e.key&&h(),"Escape"===e.key&&c(!1)},min:i,max:o,step:r,className:"w-14 text-right text-[10px] text-fg-secondary tabular-nums bg-subtle-fill radius-badge px-1 py-0.5 border border-edge-subtle focus:outline-none focus:border-sys-blue"}):n.jsx("button",{onClick:x,className:"text-[10px] text-fg-secondary tabular-nums hover:text-sys-blue cursor-text transition-colors",title:"Click to type a value",children:t.toFixed(2)})]}),n.jsx("input",{type:"range",min:i,max:o,step:r,value:t,onChange:e=>a(parseFloat(e.target.value)),className:"w-full h-1 bg-subtle-fill rounded appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:bg-sys-blue [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:cursor-pointer"})]})}),Qt=s.memo(function({label:e,checked:t,onChange:s}){return n.jsxs(i,{className:"flex items-center justify-between",children:[n.jsx(o,{className:"text-[10px] text-fg-muted cursor-pointer select-none",children:e}),n.jsx(D,{enabled:t,onChange:s,size:"sm"})]})});function qt(){var e,t,i,o,l,c,d,N,D,L,F,R,H,B,P;M(yt);const E=u(),[$,T]=s.useState(!1),[I,G]=s.useState(!1),O=s.useRef(!1);s.useEffect(()=>{E&&!O.current&&(O.current=!0,G(!0))},[E]);const K=s.useCallback(()=>{G(!1),T(!0)},[]),_=m(),pe=function(e,t=1e3){const[n,a]=s.useState(e),i=s.useRef(Date.now()),o=s.useRef(null);return s.useEffect(()=>{const s=Date.now(),n=t-(s-i.current);return n<=0?(a(e),i.current=s):(o.current&&clearTimeout(o.current),o.current=setTimeout(()=>{a(e),i.current=Date.now()},n)),()=>{o.current&&clearTimeout(o.current)}},[e,t]),n}(h(),2e3),ge=x(),fe=p(),ve=g(),be=f(),ye=v(),je=b(),Ne=y(),we=Ne?Et:At,Ce=Ne?Ct:kt,ke=s.useMemo(()=>function(e){if("undefined"==typeof document)return e?w[950]:"#EFF0F1";const t=getComputedStyle(document.documentElement).getPropertyValue("--bg-body").trim();return t.startsWith("#")?t:e?w[950]:"#EFF0F1"}(Ne),[Ne]),Se=s.useMemo(()=>function(e){if("undefined"==typeof document)return e?w[400]:w[500];const t=getComputedStyle(document.documentElement).getPropertyValue("--text-secondary").trim();return t.startsWith("#")?t:e?w[400]:w[500]}(Ne),[Ne]),[De,Le]=s.useState(!0),[Fe,Re]=s.useState(null),[Me,He]=s.useState(null),[Be,Pe]=s.useState(!1),[Ee,Ae]=s.useState(""),[ze,$e]=s.useState(!1),[Te,Ie]=s.useState(!1),[Oe,Ze]=s.useState("simulation"),[Ke,Ve]=s.useState(!0),[_e,Ue]=s.useState(!1),[qe,Je]=s.useState(!0),[tt,it]=s.useState(!1),[ot,rt]=s.useState(!1),[ct,dt]=s.useState(new Set),[ut,mt]=s.useState(!1),[ht,pt]=s.useState("spectral"),[gt,ft]=s.useState(1),[vt,St]=s.useState(1),[$t,Ot]=s.useState(!1),[Wt,qt]=s.useState(null),[Jt,Yt]=s.useState(!1),[es,ts]=s.useState(!1),[ss,ns]=s.useState(null),[as,is]=s.useState(null),[os,rs]=s.useState(null),[ls,cs]=s.useState(null),[ds,us]=s.useState(null),ms=j(),[hs,xs]=s.useState(!1),[ps,gs]=s.useState([]),[fs,vs]=s.useState(0),[bs,ys]=s.useState(null),js=s.useRef(new lt),Ns=s.useRef(null),ws=s.useRef(null),[Cs,ks]=s.useState(null),[Ss,Ds]=s.useState(null),[Ls,Fs]=s.useState({}),[Rs,Ms]=s.useState({simulationDecay:2e4,simulationGravity:.05,simulationCenter:.05,simulationRepulsion:5,simulationRepulsionTheta:.4,simulationLinkSpring:.05,simulationLinkDistance:78,simulationFriction:.72,simulationRepulsionFromMouse:0,pointSizeScale:.4,pointOpacity:1,pointGreyoutOpacity:.1,linkWidthScale:.06,linkOpacity:.95,linkGreyoutOpacity:.1,curvedLinks:Ft,curvedLinkWeight:.8,linkDefaultArrows:Rt,linkArrowsSizeScale:1.7,scalePointsOnZoom:Mt,scaleLinksOnZoom:Ht,renderLinks:Bt,renderHoveredPointRing:Pt,spaceSize:4096}),Hs=s.useCallback((e,t)=>{Ms(s=>({...s,[e]:t}))},[]),Bs=s.useCallback(()=>{Ms({simulationDecay:2e4,simulationGravity:.05,simulationCenter:.05,simulationRepulsion:5,simulationRepulsionTheta:.4,simulationLinkSpring:.05,simulationLinkDistance:78,simulationFriction:.72,simulationRepulsionFromMouse:0,pointSizeScale:.4,pointOpacity:1,pointGreyoutOpacity:.1,linkWidthScale:.06,linkOpacity:.95,linkGreyoutOpacity:.1,curvedLinks:Ft,curvedLinkWeight:.8,linkDefaultArrows:Rt,linkArrowsSizeScale:1.7,scalePointsOnZoom:Mt,scaleLinksOnZoom:Ht,renderLinks:Bt,renderHoveredPointRing:Pt,spaceSize:4096})},[]);s.useEffect(()=>()=>{var e;try{null==(e=ws.current)||e.destroy()}catch{}ws.current=null},[]),s.useEffect(()=>{const e=e=>{var t,s;if(!(e.target instanceof HTMLInputElement||e.target instanceof HTMLSelectElement))switch(e.key.toLowerCase()){case"f":e.metaKey||e.ctrlKey||(e.preventDefault(),null==(t=ws.current)||t.fitView(jt));break;case"escape":ze?($e(!1),Ae("")):Fe&&(Re(null),null==(s=ws.current)||s.unselectAllPoints());break;case"/":ze||(e.preventDefault(),$e(!0),setTimeout(()=>{var e;return null==(e=Ns.current)?void 0:e.focus()},50));break;case" ":e.preventDefault(),ws.current&&(De?ws.current.pause():ws.current.start(),Le(e=>!e));break;case"l":Ve(e=>!e)}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[ze,Fe,De]);const Ps=s.useMemo(()=>new Set((null==_?void 0:_.backboneEdges)??[]),[null==_?void 0:_.backboneEdges]),Es=s.useMemo(()=>({resolution:gt,kWeight:vt}),[gt,vt]),As=s.useMemo(()=>{if("louvain"!==ht)return null;const e=null==_?void 0:_.edges;return!e||0===e.length||!pe||pe.size<3?null:We(e,Array.from(pe.keys()),Es).communities},[ht,null==_?void 0:_.edges,pe,Es]),zs=s.useMemo(()=>{var e;if(!pe||0===pe.size||!$)return[];const t=[],s=(null==je?void 0:je.node_name)??(null==(e=null==je?void 0:je.config)?void 0:e.node_name)??null,n=Ne?"#171717":"#EFF0F1";let a=1;for(const i of pe.values())i.degree>a&&(a=i.degree);for(const i of pe.values()){const e=i,o=e.degree>0?Math.log10(e.degree+1)/Math.log10(a+1):0,r=5+23*Math.min(1,o),l=6*e.betweenness,c=e.isLocal?28:Math.min(34,r+l),d=(null==As?void 0:As.get(e.hash))??e.communityId,u=ut&&d>=0?Ce[d%Ce.length]:we[e.nodeClass],m=wt[e.activityLevel]??1,h=e.isLocal?we.local:m<1?Tt(u,n,m):u,x=e.isLocal?s??e.name:e.name;t.push({id:e.hash,label:x?`${e.prefix} ${x}`:e.prefix,color:h,size:c,nodeClass:e.nodeClass,name:x,prefix:e.prefix,packetCount:e.packetCount,isLocal:e.isLocal,isHub:e.isHub,isGateway:e.isGateway,isBackbone:e.isBackbone,isMobile:e.isMobile,isZeroHop:e.isZeroHop,isGhost:e.isGhost,degree:e.degree,betweenness:e.betweenness,communityId:(null==As?void 0:As.get(e.hash))??e.communityId,activityLevel:e.activityLevel,prefixConfidence:e.prefixConfidence,hasCollision:e.hasCollision,inDegree:e.inDegree,outDegree:e.outDegree,isInLoop:e.isInLoop,avgRssi:e.avgRssi,avgSnr:e.avgSnr})}for(const i of ge){const e=`ghost-${i.prefix}`;if(t.some(t=>t.id===e))continue;const s=Tt(we.ghost,n,.6);t.push({id:e,label:`? ${i.prefix.toUpperCase()}`,color:s,size:6,nodeClass:"ghost",name:null,prefix:i.prefix,packetCount:i.observationCount,isLocal:!1,isHub:!1,isGateway:!1,isBackbone:!1,isMobile:!1,isZeroHop:!1,isGhost:!0,degree:i.commonNeighbors.size,betweenness:0,communityId:-1,activityLevel:"active",prefixConfidence:i.confidence,hasCollision:!1,inDegree:0,outDegree:0,isInLoop:!1,avgRssi:null,avgSnr:null})}return t},[pe,$,null==je?void 0:je.node_name,null==(e=null==je?void 0:je.config)?void 0:e.node_name,we,Ne,ge,Ce,ut,ht,As]),$s=s.useMemo(()=>new Set(zs.map(e=>e.id)),[zs]),Ts=s.useMemo(()=>{const e=new Map;if(!pe)return e;for(const t of pe.values())e.set(t.hash,t.name);return e},[pe]),Is=s.useMemo(()=>{const e=(null==_?void 0:_.edges)??[];if(!e.length||!$)return[];const t=[],s=(null==_?void 0:_.edgeBetweenness)??new Map;for(const a of e){if(!$s.has(a.fromHash)||!$s.has(a.toHash))continue;const e=It(a,Ps),n=Gt(e,a.avgConfidence,Ne),i=s.get(a.key)??0,o=i>0?.5+4*i:.5+2*Math.min(1,a.certainCount/50);t.push({source:a.fromHash,target:a.toHash,color:n,width:o,key:a.key,packetCount:a.packetCount,certainCount:a.certainCount,confidence:a.avgConfidence,symmetryRatio:a.symmetryRatio,dominantDirection:a.dominantDirection,isBackbone:Ps.has(a.key),isLoopEdge:a.isLoopEdge??!1,isDirectPath:a.isDirectPathEdge,isZeroHop:a.isZeroHop??!1,isGhost:!1,forwardCount:a.forwardCount,reverseCount:a.reverseCount,floodCount:a.floodCount,directCount:a.directCount,avgRssi:a.avgRssi??null,avgSnr:a.avgSnr??null,strength:a.strength,fromName:Ts.get(a.fromHash)??null,toName:Ts.get(a.toHash)??null,edgeType:e})}const n=Ne?Dt:Lt;for(const a of ge){const e=`ghost-${a.prefix}`;if($s.has(e))for(const s of a.commonNeighbors)$s.has(s)&&t.push({source:e,target:s,color:n.ghost,width:.4,key:`ghost-${a.prefix}-${s}`,packetCount:a.observationCount,certainCount:0,confidence:a.confidence,symmetryRatio:0,dominantDirection:"balanced",isBackbone:!1,isLoopEdge:!1,isDirectPath:!1,isZeroHop:!1,isGhost:!0,forwardCount:0,reverseCount:0,floodCount:0,directCount:0,avgRssi:null,avgSnr:null,strength:a.confidence,fromName:null,toName:Ts.get(s)??null,edgeType:"ghost"})}return t},[null==_?void 0:_.edges,null==_?void 0:_.edgeBetweenness,$,$s,Ne,Ps,Ts,ge]),Gs=null==(i=null==(t=null==je?void 0:je.config)?void 0:t.radio)?void 0:i.frequency,Os=null==(l=null==(o=null==je?void 0:je.config)?void 0:o.radio)?void 0:l.bandwidth,Zs=null==(d=null==(c=null==je?void 0:je.config)?void 0:c.radio)?void 0:d.spreading_factor,Ws=null==(D=null==(N=null==je?void 0:je.config)?void 0:N.radio)?void 0:D.tx_power,Ks=null==(F=null==(L=null==je?void 0:je.config)?void 0:L.radio)?void 0:F.coding_rate,Vs=s.useMemo(()=>{if(!_||!es)return null;const e={frequency:Gs,bandwidth:null!=os?1e3*os:Os,spreading_factor:as??Zs,tx_power:ss??Ws,coding_rate:ls??Ks},t={};return null!=ds&&(t.sensitivityOverrideDbm=ds),null!=ms&&(t.observedNoiseFloorDbm=ms),function(e,t,s){const n=[],a=e.nodeMetrics,i=new Set,o=t.tx_power??22;for(const r of e.edges){if(!r.isZeroHop)continue;const e=a.get(r.fromHash),o=a.get(r.toHash);n.push(Ye(r,e,o,t,s)),i.add(r.key)}for(const r of e.edges){if(i.has(r.key))continue;if(!r.traceQuality)continue;const e=et(r,a.get(r.fromHash),a.get(r.toHash),t,o,s);e&&(n.push(e),i.add(r.key))}return n}(_,e,t)},[_,es,Gs,Os,Zs,Ws,Ks,ss,as,os,ls,ds,ms]),_s=s.useMemo(()=>{if(!Vs)return null;const e=new Map;for(const t of Vs)e.set(t.edgeKey,t);return e},[Vs]),Us=s.useMemo(()=>Vs&&0!==Vs.length?function(e){const t={"anomalous-good":0,better:0,expected:0,worse:0,"anomalous-bad":0},s={excellent:0,good:0,fair:0,marginal:0,critical:0};let n=0,a=0,i=null,o=null,r=0,l=0;for(const c of e)c.hasData&&(null!=c.marginDb&&(n+=c.marginDb,a++,(!i||c.marginDb<(i.marginDb??1/0))&&(i=c),(!o||c.marginDb>(o.marginDb??-1/0))&&(o=c)),c.marginClass&&s[c.marginClass]++,null!=c.deviationDb&&c.deviationClass?(t[c.deviationClass]++,l++):r++);return{totalEdges:e.length,analyzedEdges:l,rssiOnlyEdges:r,avgMarginDb:a>0?n/a:null,worstMargin:i,bestMargin:o,deviationCounts:t,marginCounts:s,anomalousCount:t["anomalous-good"]+t["anomalous-bad"]}}(Vs):null,[Vs]),Xs=s.useMemo(()=>{if(!es||!_s)return Is;const e=Ne?"#303038":"#D0D0D8";return Is.map(t=>{const s=_s.get(t.key);return s&&s.hasData?{...t,color:nt(s,"margin"),width:at(s),linkBudget:s}:{...t,color:e,width:.3}})},[Is,es,_s,Ne]),Qs=s.useMemo(()=>0===ct.size?zs:zs.filter(e=>!ct.has(e.nodeClass)),[zs,ct]),qs=s.useMemo(()=>{if(0===ct.size)return Xs;const e=new Set(Qs.map(e=>e.id));return Xs.filter(t=>e.has(t.source)&&e.has(t.target))},[Xs,Qs,ct]),Js=s.useRef([]);s.useEffect(()=>{Js.current=qs},[qs]);const Ys=s.useMemo(()=>{const e=new Map;for(const t of Is)e.set(t.source,(e.get(t.source)??0)+1),e.set(t.target,(e.get(t.target)??0)+1);return e},[Is]),en=s.useMemo(()=>{const e=new Map;for(const t of zs)e.set(t.id,t);return e},[zs]);s.useEffect(()=>{if(0===Qs.length)return ks(null),Ds(null),void Fs({});let e=!1;const t=setTimeout(async()=>{try{const t=Qs.map(e=>({id:e.id,label:e.label,color:e.color,size:e.size,communityId:String(e.communityId)})),s=qs.map(e=>({source:e.source,target:e.target,color:e.color,width:e.width})),n={points:{pointIdBy:"id",pointColorBy:"color",pointColorStrategy:"direct",pointDefaultColor:Ne?"#9CA3AF":"#374151",pointLabelBy:"label",pointSizeBy:"size",pointSizeStrategy:"direct",pointDefaultSize:8,pointSizeScale:1,pointGreyoutOpacity:.3,pointIncludeColumns:["communityId"]},links:{linkSourceBy:"source",linkTargetsBy:["target"],linkColorBy:"color",linkColorStrategy:"direct",linkDefaultColor:Ne?"#6B7280":"#9CA3AF",linkWidthBy:"width",linkWidthStrategy:"direct",linkDefaultWidth:1,linkWidthScale:1,linkGreyoutOpacity:.1}},a=await r(n,t,s);if(e||!a)return;a.points,a.links,a.cosmographConfig,ks(a.points??null),Ds(a.links??null),Fs(a.cosmographConfig??{})}catch(t){console.error("[MeshGraph] Data preparation failed:",t)}},100);return()=>{e=!0,clearTimeout(t)}},[Qs,qs,Ne]);const tn=s.useCallback(e=>{e&&(ws.current=e,e.start(),setTimeout(()=>{e.fitView(jt)},1500))},[]),sn=s.useCallback(()=>{var e;null==(e=ws.current)||e.fitView(jt)},[]),nn=s.useCallback(()=>{const e=ws.current;e&&(De?e.pause():e.start(),Le(!De))},[De]),an=s.useCallback(async e=>{const t=ws.current,s=en.get(e);if(s){if(t)try{const s=await t.getPointIndicesByIds([e]);s&&s.length>0&&void 0!==s[0]&&(t.zoomToPoint(s[0],400,2.5),t.selectPoint(s[0],!1,!0))}catch{}He(null),Re({hash:e,name:s.name,prefix:s.prefix,nodeClass:s.nodeClass,packetCount:s.packetCount,edgeCount:Ys.get(e)??0,degree:s.degree,betweenness:s.betweenness,communityId:s.communityId,isLocal:s.isLocal,isHub:s.isHub,isGateway:s.isGateway,isBackbone:s.isBackbone,isMobile:s.isMobile,isZeroHop:s.isZeroHop,isGhost:s.isGhost,isInLoop:s.isInLoop,activityLevel:s.activityLevel,prefixConfidence:s.prefixConfidence,hasCollision:s.hasCollision,inDegree:s.inDegree,outDegree:s.outDegree,avgRssi:s.avgRssi,avgSnr:s.avgSnr})}},[en,Ys]),on=s.useRef(null);s.useEffect(()=>{on.current=_s},[_s]);const rn=s.useCallback(e=>{var t;if(void 0===e)return void He(null);const s=Js.current[e];if(!s)return;const n=null==(t=on.current)?void 0:t.get(s.key);He(n&&!s.linkBudget?{...s,linkBudget:n}:s),Re(null)},[]),ln=s.useCallback(async(e,t,s)=>{var n;if(void 0===e)return Re(null),qt(null),void(null==(n=ws.current)||n.unselectAllPoints());He(null);const a=ws.current;if(a)try{const t=await a.getPointIdsByIndices([e]);if(!t||0===t.length)return;const s=t[0],n=en.get(s);if(!n)return;a.selectPoint(e,!1,!0),Re({hash:s,name:n.name,prefix:n.prefix,nodeClass:n.nodeClass,packetCount:n.packetCount,edgeCount:Ys.get(s)??0,degree:n.degree,betweenness:n.betweenness,communityId:n.communityId,isLocal:n.isLocal,isHub:n.isHub,isGateway:n.isGateway,isBackbone:n.isBackbone,isMobile:n.isMobile,isZeroHop:n.isZeroHop,isGhost:n.isGhost,isInLoop:n.isInLoop,activityLevel:n.activityLevel,prefixConfidence:n.prefixConfidence,hasCollision:n.hasCollision,inDegree:n.inDegree,outDegree:n.outDegree,avgRssi:n.avgRssi,avgSnr:n.avgSnr})}catch{}},[en,Ys]),cn=s.useMemo(()=>{if(!ze||!Ee.trim())return[];const e=Ee.toLowerCase();return zs.filter(t=>{var s;return t.prefix.toLowerCase().includes(e)||(null==(s=t.name)?void 0:s.toLowerCase().includes(e))||t.id.toLowerCase().includes(e)}).slice(0,8)},[zs,Ee,ze]),dn=s.useCallback(e=>{$e(!1),Ae(""),an(e.id)},[an]),un=s.useCallback(()=>{Pe(e=>!e)},[]),mn=s.useCallback(e=>{dt(t=>{const s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})},[]),hn=s.useCallback(()=>{mt(e=>{const t=!e,s=ws.current;return s&&s.start(.5),t})},[]),xn=s.useCallback(()=>{Ot(e=>{const t=!e,s=ws.current;return s?(t?s.activatePolygonalSelection():(s.deactivatePolygonalSelection(),qt(null),s.unselectAllPoints()),t):t})},[]),pn=s.useCallback(async()=>{const e=ws.current;if(!e)return;await new Promise(e=>setTimeout(e,80));const t=e.getSelectedPointIndices();if(!t||0===t.length)return void qt(null);const s=await e.getPointIdsByIndices(t);if(!s||0===s.length)return void qt(null);const n=new Set(s);let a=0,i=0;for(const m of Js.current)n.has(m.source)&&n.has(m.target)&&(a++,i+=m.confidence);let o=0;const r={},l={};for(const m of s){const e=en.get(m);e&&(o+=e.betweenness,r[e.communityId]=(r[e.communityId]??0)+1,l[e.nodeClass]=(l[e.nodeClass]??0)+1)}const c=new Set;for(const m of s){const e=en.get(m);e&&c.add(e.prefix.toLowerCase())}let d=0,u=0;for(const m of be)if(m.hops.length>=2){const e=m.hops[0].toLowerCase(),t=m.hops[m.hops.length-1].toLowerCase();c.has(e)&&c.has(t)&&(d+=m.healthScore,u++)}qt({nodeCount:s.length,edgeCount:a,avgBetweenness:s.length>0?o/s.length:0,avgConfidence:a>0?i/a:0,avgPathHealth:u>0?d/u:null,communities:r,nodeClasses:l}),Re(null),He(null)},[en,be]),gn=s.useCallback(()=>{var e;qt(null),null==(e=ws.current)||e.unselectAllPoints()},[]),fn=s.useMemo(()=>{var e;if(!Fe)return null;const t=Fe.hash,s=new Set;for(const h of qs)h.source===t?s.add(h.target):h.target===t&&s.add(h.source);if(0===s.size)return{clusteringCoeff:0,avgNeighborBetweenness:0,neighborCount:0,avgEdgeConfidence:0,avgRssi:null,avgSnr:null};let n=0;for(const h of qs)s.has(h.source)&&s.has(h.target)&&n++;const a=s.size,i=a>1?2*n/(a*(a-1)):0;let o=0;for(const h of s)o+=(null==(e=en.get(h))?void 0:e.betweenness)??0;let r=0,l=0,c=0,d=0,u=0,m=0;for(const h of qs)h.source!==t&&h.target!==t||(r+=h.confidence,l++,null!=h.avgRssi&&(c+=h.avgRssi,d++),null!=h.avgSnr&&(u+=h.avgSnr,m++));return{clusteringCoeff:Math.min(1,i),avgNeighborBetweenness:o/a,neighborCount:a,avgEdgeConfidence:l>0?r/l:0,avgRssi:d>0?c/d:null,avgSnr:m>0?u/m:null}},[Fe,qs,en]),vn=s.useMemo(()=>Fe&&ye?ye.get(Fe.hash)??null:null,[Fe,ye]),bn=s.useMemo(()=>{if(!Fe)return[];const e=Fe.hash,t=[],s=new Set;for(const n of qs){let a=null;if(n.source===e?a=n.target:n.target===e&&(a=n.source),!a||s.has(a))continue;s.add(a);const i=en.get(a);t.push({hash:a,prefix:(null==i?void 0:i.prefix)??a.slice(2,4).toUpperCase(),name:(null==i?void 0:i.name)??null,edgeConfidence:n.confidence,edgeType:n.edgeType,avgRssi:n.avgRssi,avgSnr:n.avgSnr})}return t.sort((e,t)=>t.edgeConfidence-e.edgeConfidence),t},[Fe,qs,en]),yn=s.useCallback(async()=>{const e=ws.current;if(!e||!Fe)return;const t=await e.getPointIndicesByIds([Fe.hash]);if(!t||void 0===t[0])return;const s=t[0],n=e.getConnectedPointIndices(s)??[],a=new Set([s,...n]);for(const o of n){const t=e.getConnectedPointIndices(o)??[];for(const e of t)a.add(e)}const i=Array.from(a);e.selectPoints(i),e.fitViewByIndices(i,jt,.15)},[Fe]);s.useEffect(()=>{if(!$t)return;const e=e=>{var t,s;"Escape"===e.key&&(Ot(!1),null==(t=ws.current)||t.deactivatePolygonalSelection(),qt(null),null==(s=ws.current)||s.unselectAllPoints())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[$t]);const jn=s.useCallback((e,t)=>{_&&(function(e,t){!function(e){const t=new Blob([e.content],{type:e.mimeType}),s=URL.createObjectURL(t),n=document.createElement("a");n.href=s,n.download=e.filename,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(s)}(Ge(e,t))}(_,{format:e,dataset:t}),Yt(!1))},[_]),Nn=s.useMemo(()=>{if(!_||!be.length)return null;const e=_.edges??[];return 0===e.length?null:function(e,t,s=-137){const n=new Map;for(const o of t)n.set(o.key,o);const a=t.filter(e=>null!=e.avgRssi).length,i=[];for(const o of e){const e=xt(o,n,s);e&&i.push(e)}return i.sort((e,t)=>t.riskScore-e.riskScore),{atRiskPaths:i,criticalCount:i.filter(e=>"critical"===e.riskLevel).length,highCount:i.filter(e=>"high"===e.riskLevel).length,moderateCount:i.filter(e=>"moderate"===e.riskLevel).length,edgesAnalyzed:t.length,edgesWithSignal:a}}(be,e)},[_,be]),wn=s.useMemo(()=>{const e=null==_?void 0:_.edges;if(!e||0===e.length||!pe||pe.size<3)return null;const t=Array.from(pe.keys());return A(e,t)},[null==_?void 0:_.edges,pe]),Cn=s.useMemo(()=>{if("louvain"!==ht)return null;const e=null==_?void 0:_.edges;return!e||0===e.length||!pe||pe.size<3?null:We(e,Array.from(pe.keys()),Es)},[ht,null==_?void 0:_.edges,pe,Es]);s.useEffect(()=>{if(!_)return;const e=new Map;for(const[s,n]of _.nodeMetrics)e.set(s,n.name);const t=js.current.update(_,e);t.totalCount>0&&(gs(js.current.getLog()),vs(e=>e+t.totalCount))},[_]);const kn=s.useCallback(()=>{vs(0),xs(e=>!e)},[]),Sn=s.useMemo(()=>function(e,t){if(null==e)return null;const s=Math.max(0,e),n=s>0?(Math.log10(s)+4)/4.5:0,a=Math.round(Math.max(0,Math.min(100,100*n)));let i,o;a<10?(i="critical",o="Partition risk"):a<30?(i="poor",o="Weak connectivity"):a<55?(i="fair",o="Moderate resilience"):a<80?(i="good",o="Well connected"):(i="excellent",o="Highly resilient");const[r,l]=Nt[i];return{score:a,grade:i,label:o,color:t?r:l}}(wn,Ne),[wn,Ne]),Dn=n.jsxs("div",{className:"absolute top-0 left-0 right-0 z-20 px-4 py-3 pointer-events-none flex items-start justify-between",children:[n.jsxs("h1",{className:"type-title text-fg-primary flex items-center gap-2 sm:gap-3 pointer-events-auto",children:[n.jsx(X,{className:"w-5 h-5 sm:w-6 sm:h-6 text-icon-page-title"}),n.jsx("span",{children:"MeshGraph"}),n.jsx(C,{color:"violet",compact:!0,children:"Analytics"})]}),Sn&&n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-2",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Mesh Resilience Score"}),n.jsx("div",{className:"text-fg-secondary",children:"Derived from the Fiedler eigenvalue (λ₂) — the second-smallest eigenvalue of the graph Laplacian. Measures how well-connected the mesh is and how resistant it is to partitioning."}),n.jsxs("div",{className:"space-y-0.5 font-mono text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Raw λ₂"}),n.jsx("span",{className:"text-fg-primary tabular-nums",children:(null==wn?void 0:wn.toFixed(6))??"—"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Score"}),n.jsxs("span",{className:"tabular-nums",style:{color:Sn.color},children:[Sn.score,"/100"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Grade"}),n.jsx("span",{className:"capitalize",style:{color:Sn.color},children:Sn.grade})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Grade thresholds"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.excellent[0]},children:"Excellent"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"80-100 (λ₂ > 0.3)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.good[0]},children:"Good"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"55-79 (λ₂ 0.03-0.3)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.fair[0]},children:"Fair"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"30-54 (λ₂ 0.003-0.03)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.poor[0]},children:"Poor"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"10-29 (λ₂ 0.0001-0.003)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.critical[0]},children:"Critical"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"<10 (λ₂ ≈ 0)"})]})]}),n.jsx("div",{className:"text-[10px] text-fg-muted italic",children:"Near-zero λ₂ = one bridge away from network partition. Log-scale mapping: small λ₂ changes at low values have outsized impact."})]}),children:n.jsxs("div",{className:"pointer-events-auto surface-control radius-inner px-3 py-1.5 flex items-center gap-2 cursor-help",children:[n.jsxs("div",{className:"flex items-baseline gap-1.5",children:[n.jsx("span",{className:"text-[10px] text-fg-muted uppercase tracking-wider",children:"Resilience"}),n.jsx("span",{className:"text-lg font-semibold tabular-nums leading-none",style:{color:Sn.color},children:Sn.score})]}),n.jsx("div",{className:"w-12 h-1.5 rounded-full bg-subtle-fill overflow-hidden",children:n.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${Sn.score}%`,backgroundColor:Sn.color}})})]})})]}),Ln=(e,t=!1)=>{const s="flex flex-col items-center gap-0.5 px-1.5 py-1 radius-inner transition-all duration-100 active:scale-95";return e&&t?`${s} bg-status-warning/15 text-status-warning shadow-inner`:e?`${s} bg-sys-blue/20 text-sys-blue shadow-inner`:`${s} hover:bg-white/5 hover:scale-105 text-fg-secondary`},Fn=n.jsx("div",{className:"w-px h-6 bg-border-subtle/40 mx-0.5 shrink-0"}),Rn=n.jsxs("div",{className:"absolute top-12 right-3 z-10 flex items-center gap-0.5 surface-control radius-inner px-1.5 py-1",children:[n.jsx(k,{content:"Visible nodes / edges in the graph",children:n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums mr-1.5 leading-none cursor-help",children:[Qs.length,n.jsx("br",{}),qs.length]})}),Fn,n.jsx(k,{content:Ke?"Hide labels (L)":"Show labels (L)",children:n.jsxs("button",{onClick:()=>Ve(e=>!e),className:Ln(!Ke,!0),children:[Ke?n.jsx(Q,{className:"w-3.5 h-3.5"}):n.jsx(q,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Lbl"})]})}),n.jsx(k,{content:ut?"Disable clustering":"Community clustering",children:n.jsxs("button",{onClick:hn,className:Ln(ut),children:[n.jsx(J,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Grp"})]})}),n.jsx(k,{content:$t?"Exit lasso (Esc)":"Lasso selection",children:n.jsxs("button",{onClick:xn,className:Ln($t,!0),children:[n.jsx(Y,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Sel"})]})}),Fn,n.jsx(k,{content:"Legend",children:n.jsxs("button",{onClick:()=>Ue(e=>!e),className:Ln(_e),children:[n.jsx(ee,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Map"})]})}),n.jsx(k,{content:"Search (/)",children:n.jsxs("button",{onClick:()=>{$e(!0),setTimeout(()=>{var e;return null==(e=Ns.current)?void 0:e.focus()},50)},className:Ln(ze),children:[n.jsx(te,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Fnd"})]})}),Fn,n.jsx(k,{content:De?"Pause (Space)":"Play (Space)",children:n.jsxs("button",{onClick:nn,className:Ln(!De),children:[De?n.jsx(se,{className:"w-3.5 h-3.5 text-sys-green"}):n.jsx(ne,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:De?"Run":"Stop"})]})}),n.jsx(k,{content:"Fit view (F)",children:n.jsxs("button",{onClick:sn,className:Ln(!1),children:[n.jsx(ae,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Fit"})]})}),Fn,n.jsx(k,{content:es?"Disable link budget":"Link budget overlay",children:n.jsxs("button",{onClick:()=>ts(e=>!e),className:Ln(es),children:[n.jsx(ie,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"RF"})]})}),n.jsx(k,{content:"Anomaly log",children:n.jsxs("button",{onClick:kn,className:`relative ${Ln(hs,!0)}`,children:[n.jsx(oe,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Alert"}),fs>0&&n.jsx("span",{className:"absolute -top-1 -right-0.5 w-3 h-3 rounded-full bg-status-danger text-[7px] font-bold text-white flex items-center justify-center",children:fs>9?"9+":fs})]})}),n.jsx(k,{content:"Export topology",children:n.jsxs("button",{onClick:()=>Yt(e=>!e),className:Ln(Jt),children:[n.jsx(re,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Exp"})]})}),n.jsx(k,{content:"Settings",children:n.jsxs("button",{onClick:()=>Ie(e=>!e),className:Ln(Te),children:[n.jsx(le,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Cfg"})]})}),Fn,n.jsx(k,{content:Be?"Exit fullscreen":"Fullscreen",children:n.jsxs("button",{onClick:un,className:Ln(Be),children:[Be?n.jsx(ce,{className:"w-3.5 h-3.5"}):n.jsx(V,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Max"})]})})]}),Mn=n.jsxs(bt,{id:"settings",title:"Graph Settings",icon:n.jsx(le,{}),open:Te,onClose:()=>Ie(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-308:600,y:60},defaultSize:{width:288,height:420},minSize:{width:260,height:200},maxSize:{width:400,height:600},headerActions:n.jsx(k,{content:"Reset to defaults",children:n.jsx("button",{onClick:Bs,className:"p-0.5 radius-badge hover-bg transition-base",children:n.jsx(de,{className:"w-2.5 h-2.5 text-fg-muted"})})}),children:[n.jsx("div",{className:"flex border-b border-edge-subtle",children:["simulation","points","links","rendering"].map(e=>n.jsx("button",{onClick:()=>Ze(e),className:"flex-1 px-2 py-1.5 text-[10px] font-medium capitalize transition-colors "+(Oe===e?"text-sys-blue border-b-2 border-sys-blue":"text-fg-muted hover:text-fg-secondary"),children:e},e))}),n.jsxs("div",{className:"p-3 space-y-3",children:["simulation"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Gravity",value:Rs.simulationGravity,onChange:e=>Hs("simulationGravity",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Repulsion",value:Rs.simulationRepulsion,onChange:e=>Hs("simulationRepulsion",e),min:0,max:5,step:.1}),n.jsx(Xt,{label:"Link Spring",value:Rs.simulationLinkSpring,onChange:e=>Hs("simulationLinkSpring",e),min:0,max:2,step:.05}),n.jsx(Xt,{label:"Link Distance",value:Rs.simulationLinkDistance,onChange:e=>Hs("simulationLinkDistance",e),min:1,max:100,step:1}),n.jsx(Xt,{label:"Friction",value:Rs.simulationFriction,onChange:e=>Hs("simulationFriction",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Center Force",value:Rs.simulationCenter,onChange:e=>Hs("simulationCenter",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Decay",value:Rs.simulationDecay,onChange:e=>Hs("simulationDecay",e),min:100,max:2e4,step:100}),n.jsx(Xt,{label:"Repulsion Theta",value:Rs.simulationRepulsionTheta,onChange:e=>Hs("simulationRepulsionTheta",e),min:.1,max:3,step:.05}),n.jsx(Xt,{label:"Mouse Repulsion",value:Rs.simulationRepulsionFromMouse,onChange:e=>Hs("simulationRepulsionFromMouse",e),min:0,max:10,step:.5})]}),"points"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Size Scale",value:Rs.pointSizeScale,onChange:e=>Hs("pointSizeScale",e),min:.1,max:5,step:.1}),n.jsx(Xt,{label:"Opacity",value:Rs.pointOpacity,onChange:e=>Hs("pointOpacity",e),min:0,max:1,step:.05}),n.jsx(Xt,{label:"Greyout Opacity",value:Rs.pointGreyoutOpacity,onChange:e=>Hs("pointGreyoutOpacity",e),min:0,max:1,step:.05}),n.jsx(Qt,{label:"Scale on Zoom",checked:Rs.scalePointsOnZoom,onChange:e=>Hs("scalePointsOnZoom",e)}),n.jsx(Qt,{label:"Hover Ring",checked:Rs.renderHoveredPointRing,onChange:e=>Hs("renderHoveredPointRing",e)})]}),"links"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Qt,{label:"Show Links",checked:Rs.renderLinks,onChange:e=>Hs("renderLinks",e)}),n.jsx(Qt,{label:"Curved Links",checked:Rs.curvedLinks,onChange:e=>Hs("curvedLinks",e)}),n.jsx(Qt,{label:"Show Arrows",checked:Rs.linkDefaultArrows,onChange:e=>Hs("linkDefaultArrows",e)}),n.jsx(Xt,{label:"Width Scale",value:Rs.linkWidthScale,onChange:e=>Hs("linkWidthScale",e),min:.1,max:5,step:.1}),n.jsx(Xt,{label:"Opacity",value:Rs.linkOpacity,onChange:e=>Hs("linkOpacity",e),min:0,max:1,step:.05}),n.jsx(Xt,{label:"Greyout Opacity",value:Rs.linkGreyoutOpacity,onChange:e=>Hs("linkGreyoutOpacity",e),min:0,max:1,step:.05}),Rs.curvedLinks&&n.jsx(Xt,{label:"Curve Weight",value:Rs.curvedLinkWeight,onChange:e=>Hs("curvedLinkWeight",e),min:0,max:1,step:.05}),Rs.linkDefaultArrows&&n.jsx(Xt,{label:"Arrow Size",value:Rs.linkArrowsSizeScale,onChange:e=>Hs("linkArrowsSizeScale",e),min:.1,max:3,step:.1}),n.jsx(Qt,{label:"Scale on Zoom",checked:Rs.scaleLinksOnZoom,onChange:e=>Hs("scaleLinksOnZoom",e)})]}),"rendering"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Space Size",value:Rs.spaceSize,onChange:e=>Hs("spaceSize",e),min:1024,max:16384,step:512}),n.jsx("div",{className:"pt-2 border-t border-edge-subtle/50",children:n.jsx("p",{className:"text-[9px] text-fg-muted",children:"Space size defines the simulation boundary. Larger values allow more spread."})})]})]})]}),Hn=n.jsxs(bt,{id:"export",title:"Export Topology",icon:n.jsx(re,{}),open:Jt,onClose:()=>Yt(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-280:600,y:100},defaultSize:{width:256,height:320},minSize:{width:220,height:150},autoHeight:!0,children:[n.jsx("div",{className:"py-1",children:[{label:"Full Topology (JSON)",format:"json",dataset:"full",desc:"All data: nodes, edges, paths, TX delay"},{label:"Gephi Graph (GEXF)",format:"gexf",dataset:"full",desc:"Import into Gephi for advanced analysis"},{label:"Nodes (CSV)",format:"csv",dataset:"nodes",desc:"Node metrics: centrality, class, signal"},{label:"Edges (CSV)",format:"csv",dataset:"edges",desc:"Edge metrics: confidence, symmetry, type"},{label:"Path Health (CSV)",format:"csv",dataset:"pathHealth",desc:"Route health scores and trends"},{label:"TX Delay (CSV)",format:"csv",dataset:"txDelay",desc:"TX delay recommendations per node"}].map(({label:e,format:t,dataset:s,desc:a})=>n.jsxs("button",{onClick:()=>jn(t,s),className:"w-full flex flex-col px-3 py-2 text-left hover-bg transition-base",children:[n.jsx("span",{className:"text-[11px] font-medium text-fg-primary",children:e}),n.jsx("span",{className:"text-[9px] text-fg-muted",children:a})]},`${t}-${s}`))}),n.jsx("div",{className:"px-3 py-1.5 border-t border-edge-subtle",children:n.jsxs("span",{className:"text-[9px] text-fg-muted",children:[(null==(R=null==_?void 0:_.nodeMetrics)?void 0:R.size)??0," nodes · ",(null==(H=null==_?void 0:_.validatedEdges)?void 0:H.length)??0," edges"]})})]}),Bn={info:{dot:"bg-sys-blue",text:"text-fg-secondary"},warning:{dot:"bg-status-warning",text:"text-status-warning"},critical:{dot:"bg-status-danger",text:"text-status-danger"}},Pn={"edge-appeared":"Link Discovered","edge-disappeared":"Link Lost","ghost-appeared":"Ghost Discovered","ghost-disappeared":"Ghost Resolved","betweenness-shift":"Traffic Rerouting","community-change":"Community Change","class-change":"Role Change","node-appeared":"Node Appeared","node-disappeared":"Node Dropped","snr-degradation":"SNR Degradation","asymmetry-shift":"Asymmetry Shift"},En=(e,t,s)=>null==t||""===t?null:n.jsxs("div",{className:"flex justify-between gap-2",children:[n.jsx("span",{className:"text-fg-muted",children:e}),n.jsx("span",{className:`tabular-nums text-right ${s??"text-fg-secondary"}`,children:t})]}),An=e=>{const t=[];return e.isZeroHop&&t.push({label:"Zero-Hop",color:"text-status-warning"}),e.isDirectPath&&t.push({label:"Direct",color:"text-sys-blue"}),e.isBackbone&&t.push({label:"Backbone",color:"text-fg-primary"}),e.isLoop&&t.push({label:"Loop",color:"text-sys-indigo"}),0===t.length?null:n.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:t.map(e=>n.jsx("span",{className:`text-[8px] font-medium uppercase tracking-wider px-1 py-px radius-badge bg-subtle-fill ${e.color}`,children:e.label},e.label))})},zn=e=>n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("span",{className:"capitalize font-medium text-fg-secondary",children:e.nodeClass}),e.isZeroHop&&n.jsx("span",{className:"text-[8px] font-medium uppercase tracking-wider px-1 py-px radius-badge bg-subtle-fill text-status-warning",children:"Neighbor"})]}),En("Degree",e.degree),e.betweenness>.01&&En("Betweenness",e.betweenness.toFixed(3)),En("Packets",e.packetCount),En("Community",`#${e.communityId}`),En("Activity",e.activityLevel),null!=e.avgRssi&&En("RSSI",`${e.avgRssi.toFixed(0)} dBm`),null!=e.avgSnr&&En("SNR",`${e.avgSnr.toFixed(1)} dB`)]}),$n=e=>n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[null!=e.previousValue&&null!=e.currentValue&&n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"text-fg-muted font-mono",children:"number"==typeof e.previousValue?e.previousValue.toFixed(3):e.previousValue}),n.jsx("span",{className:"text-fg-muted/40",children:"→"}),n.jsx("span",{className:"text-fg-secondary font-mono",children:"number"==typeof e.currentValue?e.currentValue.toFixed(3):e.currentValue}),"number"==typeof e.previousValue&&"number"==typeof e.currentValue&&n.jsxs("span",{className:e.currentValue>e.previousValue?"text-sys-green":"text-signal-poor",children:["(",e.currentValue>e.previousValue?"+":"",(e.currentValue-e.previousValue).toFixed(3),")"]})]}),e.nodeDetail&&n.jsxs(n.Fragment,{children:[En("Class",e.nodeDetail.nodeClass),En("Degree",e.nodeDetail.degree),e.nodeDetail.betweenness>.01&&En("Betweenness",e.nodeDetail.betweenness.toFixed(3))]})]}),Tn=s.useCallback(e=>{ys(t=>t===e?null:e)},[]),In=n.jsxs(bt,{id:"anomaly",title:"Anomaly Log",icon:n.jsx(oe,{}),open:hs,onClose:()=>xs(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-328:600,y:100},defaultSize:{width:308,height:400},minSize:{width:260,height:180},maxSize:{width:440,height:700},headerActions:ps.length>0?n.jsx("button",{onClick:()=>{js.current.clear(),gs([]),ys(null)},className:"p-0.5 radius-badge hover-bg transition-base",title:"Clear all",children:n.jsx(de,{className:"w-2.5 h-2.5 text-fg-muted"})}):void 0,children:[0===ps.length?n.jsxs("div",{className:"px-3 py-6 text-center",children:[n.jsx(oe,{className:"w-5 h-5 text-fg-muted mx-auto mb-1.5"}),n.jsx("p",{className:"text-[11px] text-fg-muted",children:"No anomalies detected yet"}),n.jsx("p",{className:"text-[9px] text-fg-muted/60 mt-0.5",children:"Changes appear after topology recomputes"})]}):n.jsx("div",{className:"overflow-y-auto",children:ps.slice(0,50).map(e=>{const t=Bn[e.severity],s=S(e.detectedAt/1e3),a=bs===e.id,i=!(!e.edgeDetail&&!e.nodeDetail&&null==e.previousValue);return n.jsxs("div",{className:`border-b border-edge-subtle/50 last:border-0 transition-colors ${i?"cursor-pointer hover-bg":""} ${a?"bg-subtle-fill/50":""}`,onClick:i?()=>Tn(e.id):void 0,children:[n.jsxs("div",{className:"flex items-start gap-2 px-3 py-1.5",children:[n.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 mt-1.5 ${t.dot}`}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("p",{className:`text-[10px] leading-tight ${t.text}`,children:e.description}),n.jsxs("p",{className:"text-[9px] text-fg-muted/60 mt-0.5",children:[Pn[e.category]??e.category," · ",s]})]}),i&&n.jsx(ue,{className:"w-3 h-3 text-fg-muted/40 shrink-0 mt-0.5 transition-transform duration-150 "+(a?"rotate-180":"")})]}),a&&n.jsx("div",{className:"px-3 pb-2 pl-6",children:n.jsxs("div",{className:"border-l-2 border-edge-subtle/60 pl-2 py-0.5",children:[e.edgeDetail&&(o=e.edgeDetail,r=e.category,n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[(o.fromClass||o.toClass)&&n.jsxs("div",{className:"flex items-center gap-1 text-fg-muted",children:[n.jsx("span",{className:"capitalize",children:o.fromClass??"?"}),n.jsx("span",{className:"text-fg-muted/40",children:"↔"}),n.jsx("span",{className:"capitalize",children:o.toClass??"?"})]}),"edge-appeared"===r&&o.packetCount>0&&n.jsxs(n.Fragment,{children:[En("Packets",o.packetCount),En("Confidence",`${(100*o.confidence).toFixed(0)}%`,o.confidence>=.8?"text-sys-green":o.confidence>=.5?"text-sys-indigo":"text-signal-poor"),En("Symmetry",`${(100*o.symmetryRatio).toFixed(0)}%`)]}),o.isZeroHop&&null!=o.avgRssi&&En("RSSI",`${o.avgRssi.toFixed(0)} dBm`),o.isZeroHop&&null!=o.avgSnr&&En("SNR",`${o.avgSnr.toFixed(1)} dB`),null!=o.fromBetweenness&&o.fromBetweenness>.01&&En(`${o.fromName??"A"} centrality`,o.fromBetweenness.toFixed(3)),null!=o.toBetweenness&&o.toBetweenness>.01&&En(`${o.toName??"B"} centrality`,o.toBetweenness.toFixed(3)),An(o)]})),e.nodeDetail&&!e.edgeDetail&&("node-appeared"===e.category||"node-disappeared"===e.category)&&zn(e.nodeDetail),("betweenness-shift"===e.category||"community-change"===e.category||"class-change"===e.category)&&$n(e)]})})]},e.id);var o,r})}),ps.length>0&&n.jsx("div",{className:"px-3 py-1.5 border-t border-edge-subtle",children:n.jsxs("span",{className:"text-[9px] text-fg-muted",children:[ps.length," total · showing ",Math.min(ps.length,50)]})})]}),Gn=s.useMemo(()=>{const e={};for(const t of Is)e[t.edgeType]=(e[t.edgeType]??0)+1;return e},[Is]),On=n.jsxs(bt,{id:"legend",title:"Legend",icon:n.jsx(ee,{}),open:_e,onClose:()=>Ue(!1),defaultPosition:{x:12,y:60},defaultSize:{width:224,height:400},minSize:{width:200,height:150},maxSize:{width:360,height:700},autoHeight:!0,children:[n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("button",{onClick:()=>Je(e=>!e),className:"w-full flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-fg-secondary hover-bg transition-base",children:[qe?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"Nodes",n.jsx("span",{className:"text-fg-muted ml-auto tabular-nums",children:Qs.length})]}),qe&&n.jsx("div",{className:"px-2 pb-2 space-y-0.5",children:[["local","Local"],["hub","Hub"],["gateway","Gateway"],["backbone","Backbone"],["neighbor","Neighbor"],["mobile","Mobile"],["ghost","Ghost"],["standard","Standard"]].map(([e,t])=>{const s=fe[e]??0;if(0===s&&"local"!==e)return null;const a=ct.has(e);return n.jsx(k,{content:zt[e],children:n.jsxs("button",{onClick:()=>mn(e),className:"w-full flex items-center gap-2 px-2 py-1 radius-badge transition-base text-left "+(a?"opacity-40":"hover-bg"),children:[n.jsx("span",{className:"w-2.5 h-2.5 rounded-full shrink-0",style:{backgroundColor:we[e]}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1",children:t}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:s})]})},e)})})]}),n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("button",{onClick:()=>it(e=>!e),className:"w-full flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-fg-secondary hover-bg transition-base",children:[tt?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"Edges",n.jsx("span",{className:"text-fg-muted ml-auto tabular-nums",children:qs.length})]}),tt&&n.jsx("div",{className:"px-2 pb-2 space-y-0.5",children:[{type:"zero-hop",label:"Zero-Hop RF"},{type:"direct-path",label:"Direct Path"},{type:"loop",label:"Loop"},{type:"backbone",label:"Backbone"},{type:"standard",label:"Standard"},{type:"ghost",label:"Ghost"}].map(({type:e,label:t})=>{const s=Gn[e]??0;if(0===s)return null;const a=Gt(e,.8,Ne);return n.jsx(k,{content:Zt[e],children:n.jsxs("div",{className:"flex items-center gap-2 px-2 py-1 cursor-help",children:[n.jsx("span",{className:"w-4 h-0.5 shrink-0 rounded-full",style:{backgroundColor:a}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1",children:t}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:s})]})},e)})})]}),es&&Us&&n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("div",{className:"px-3 py-1.5 text-[10px] font-medium text-sys-green flex items-center gap-1.5",children:[n.jsx(ie,{className:"w-3 h-3"}),"Link Budget",n.jsxs("span",{className:"text-fg-muted ml-auto tabular-nums",children:[Us.analyzedEdges+Us.rssiOnlyEdges,"/",Us.totalEdges]})]}),n.jsxs("div",{className:"px-3 pb-2 space-y-0.5",children:[(()=>{const e=Gs&&Gs>1e5?Gs/1e6:Gs||915,t=as??Zs??12,s=os??(Os&&Os>1e3?Os/1e3:Os||125),a=ls??Ks??5,i=ss??Ws??22,o=Xe(t,s,a),r=ds??o,l=Qe(1e3*s),c=ms??l,d=(null==Vs?void 0:Vs.filter(e=>e.isTraceEstimated).length)??0,u=(null==Vs?void 0:Vs.filter(e=>e.isZeroHop).length)??0,m=null!=ss||null!=as||null!=os||null!=ls||null!=ds,h="w-10 px-1 py-0 text-[10px] text-right tabular-nums bg-subtle-fill border border-edge-subtle rounded text-fg-secondary focus:outline-none focus:border-sys-blue";return n.jsxs("div",{className:"pb-1 mb-1 border-b border-edge-subtle space-y-0.5",children:[n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Frequency"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[e.toFixed(3)," MHz"]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"SF"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:t,onChange:e=>{const t=parseInt(e.target.value,10);is(t===(Zs??12)?null:t)},className:h+" w-12 appearance-none",children:[7,8,9,10,11,12].map(e=>n.jsxs("option",{value:e,children:["SF",e]},e))}),null!=as&&n.jsx("button",{onClick:()=>is(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"BW"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:s,onChange:e=>{const t=parseFloat(e.target.value);rs(t===(Os&&Os>1e3?Os/1e3:Os||125)?null:t)},className:h+" w-14 appearance-none",children:[62.5,125,250,500].map(e=>n.jsxs("option",{value:e,children:[e," kHz"]},e))}),null!=os&&n.jsx("button",{onClick:()=>rs(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"CR"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:a,onChange:e=>{const t=parseInt(e.target.value,10);cs(t===(Ks??5)?null:t)},className:h+" w-12 appearance-none",children:[5,6,7,8].map(e=>n.jsxs("option",{value:e,children:["4/",e]},e))}),null!=ls&&n.jsx("button",{onClick:()=>cs(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"TX Power"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("input",{type:"number",min:1,max:36,step:1,value:i,onChange:e=>{const t=parseInt(e.target.value,10);isNaN(t)||ns(t)},onBlur:e=>{const t=parseInt(e.target.value,10);isNaN(t)?ns(null):ns(Math.max(1,Math.min(36,t)))},className:h}),n.jsx("span",{className:"text-fg-muted",children:"dBm"}),null!=ss&&n.jsx("button",{onClick:()=>ns(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"Sensitivity"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("input",{type:"number",min:-150,max:-80,step:.5,value:Math.round(10*r)/10,onChange:e=>{const t=parseFloat(e.target.value);isNaN(t)||us(t)},onBlur:e=>{const t=parseFloat(e.target.value);isNaN(t)?us(null):us(Math.max(-150,Math.min(-80,t)))},className:h+" w-12"}),n.jsx("span",{className:"text-fg-muted",children:"dBm"}),null!=ds&&n.jsx("button",{onClick:()=>us(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),d>0&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Noise Floor"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums "+(null!=ms?"":"italic text-fg-muted"),children:[c.toFixed(1)," dBm",null!=ms?"":" (est.)"]})]}),m&&n.jsx("button",{onClick:()=>{ns(null),is(null),rs(null),cs(null),us(null)},className:"w-full text-[9px] text-sys-blue hover:underline text-center pt-0.5",children:"Reset all to radio config"}),(u>0||d>0)&&n.jsxs("div",{className:"flex items-center justify-between text-[10px] pt-0.5",children:[n.jsx("span",{className:"text-fg-muted",children:"Sources"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[u>0&&n.jsxs("span",{children:[u," direct"]}),u>0&&d>0&&n.jsx("span",{className:"text-fg-muted",children:" · "}),d>0&&n.jsxs("span",{className:"text-sys-indigo",children:[d," trace"]})]})]})]})})(),null!=Us.avgMarginDb&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg Margin"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[Us.avgMarginDb>0?"+":"",Us.avgMarginDb.toFixed(1)," dB"]})]}),["excellent","good","fair","marginal","critical"].map(e=>{const t=Us.marginCounts[e];return 0===t?null:n.jsxs("div",{className:"flex items-center gap-2 px-1 py-0.5",children:[n.jsx("span",{className:"w-3 h-0.5 shrink-0 rounded-full",style:{backgroundColor:st[e]}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1 capitalize",children:e}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:t})]},e)}),Us.anomalousCount>0&&n.jsxs("div",{className:"flex items-center justify-between text-[10px] pt-0.5",children:[n.jsx("span",{className:"text-status-warning",children:"Anomalous"}),n.jsx("span",{className:"text-status-warning tabular-nums",children:Us.anomalousCount})]})]})]}),Nn&&Nn.atRiskPaths.length>0&&n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("div",{className:"flex items-center",children:[n.jsxs("button",{onClick:()=>rt(e=>!e),className:"flex-1 flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-status-warning hover-bg transition-base",children:[ot?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"At-Risk Paths",n.jsxs("span",{className:"text-fg-muted ml-auto tabular-nums",children:[Nn.criticalCount>0&&n.jsxs("span",{className:"text-status-danger",children:[Nn.criticalCount,"c"]}),Nn.criticalCount>0&&Nn.highCount>0&&" ",Nn.highCount>0&&n.jsxs("span",{className:"text-status-warning",children:[Nn.highCount,"h"]}),(Nn.criticalCount>0||Nn.highCount>0)&&Nn.moderateCount>0&&" ",Nn.moderateCount>0&&n.jsxs("span",{className:"text-fg-muted",children:[Nn.moderateCount,"m"]})]})]}),n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Predictive Path Failure"}),n.jsx("div",{className:"text-fg-secondary text-[11px]",children:"Identifies paths at risk of failure by combining four weighted factors. Paths below the moderate threshold (35%) are not shown."}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Factor weights"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Declining usage"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"35%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Weak link certainty"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"30%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"No alternate paths"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"20%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Low signal margin"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"15%"})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Risk thresholds"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-status-danger",children:"Critical"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"≥75% — failure likely imminent"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-status-warning",children:"High"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"55-74% — significant risk"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Moderate"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"35-54% — worth monitoring"})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 text-[10px] text-fg-muted font-mono space-y-0.5",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{children:"Edges analyzed"}),n.jsx("span",{className:"tabular-nums",children:Nn.edgesAnalyzed})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{children:"With signal data"}),n.jsx("span",{className:"tabular-nums",children:Nn.edgesWithSignal})]})]})]}),children:n.jsx("span",{className:"px-2 py-1.5 text-fg-muted cursor-help",children:n.jsx(oe,{className:"w-3 h-3"})})})]}),ot&&n.jsx("div",{className:"px-2 pb-2 space-y-1",children:Nn.atRiskPaths.slice(0,8).map(e=>{const t="critical"===e.riskLevel?"#EF4444":"high"===e.riskLevel?"#F97316":"#FBBF24",s="imminent"===e.urgency?"IMM":"near-term"===e.urgency?"NEAR":"WATCH";return n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary font-mono text-[11px]",children:e.hops.join(" → ")}),n.jsxs("div",{className:"space-y-0.5 text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Risk score"}),n.jsxs("span",{className:"font-semibold tabular-nums",style:{color:t},children:[(100*e.riskScore).toFixed(1),"%"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Health score"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[(100*e.healthScore).toFixed(0),"%"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Obs. trend"}),n.jsxs("span",{className:"tabular-nums "+(e.observationTrend<0?"text-status-danger":"text-fg-secondary"),children:[e.observationTrend>0?"+":"",e.observationTrend.toFixed(3)]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Alt. paths"}),n.jsx("span",{className:"tabular-nums "+(0===e.alternatePathsCount?"text-status-danger":"text-fg-secondary"),children:e.alternatePathsCount})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Urgency"}),n.jsx("span",{className:"capitalize",style:{color:t},children:e.urgency})]})]}),e.factors.length>0&&n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Contributing factors"}),e.factors.map((e,t)=>n.jsxs("div",{className:"space-y-0.5",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:e.name}),n.jsxs("span",{className:"text-fg-muted tabular-nums",children:[(e.score*e.weight*100).toFixed(1),"% (",(100*e.weight).toFixed(0),"w × ",(100*e.score).toFixed(0),"s)"]})]}),n.jsx("div",{className:"text-fg-muted pl-1",children:e.description})]},t))]})]}),children:n.jsxs("div",{className:"px-2 py-1 radius-badge bg-subtle-fill/30 cursor-help",children:[n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"w-1.5 h-1.5 rounded-full shrink-0",style:{backgroundColor:t}}),n.jsx("span",{className:"text-[10px] text-fg-secondary font-mono truncate flex-1",children:e.hops.join(" → ")}),n.jsx("span",{className:"text-[8px] uppercase tracking-wide px-1 py-px radius-badge",style:{backgroundColor:`${t}20`,color:t},children:s}),n.jsxs("span",{className:"text-[10px] tabular-nums font-semibold",style:{color:t},children:[(100*e.riskScore).toFixed(0),"%"]})]}),n.jsx("div",{className:"flex flex-wrap gap-1 mt-0.5 pl-3",children:e.factors.map((t,s)=>n.jsxs("span",{className:"text-[8px] text-fg-muted",children:[t.name," (",(t.score*t.weight*100).toFixed(0),"%)",spt(e=>"spectral"===e?"louvain":"spectral"),className:"text-sys-blue hover:underline cursor-pointer",children:"spectral"===ht?"Spectral":"Louvain"})]}),"louvain"===ht&&Cn&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Louvain modularity score — quality of community partition (higher = better defined communities)",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Modularity Q"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:Cn.modularity.toFixed(4)})]}),"louvain"===ht&&n.jsxs("div",{className:"mt-1.5 pt-1.5 border-t border-edge-subtle space-y-1.5",children:[n.jsx(Xt,{label:"Resolution γ",value:gt,onChange:ft,min:.01,max:5,step:.01}),n.jsx(Xt,{label:"K-weight",value:vt,onChange:St,min:.01,max:5,step:.01}),(1!==gt||1!==vt)&&n.jsx("button",{onClick:()=>{ft(1),St(1)},className:"w-full text-[10px] text-sys-blue hover:underline text-center",children:"Reset defaults"})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Redundant path cycles in the topology — indicates alternate routing options",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Loops"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:(null==(B=null==_?void 0:_.loops)?void 0:B.length)??0})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"High-betweenness edges that carry disproportionate traffic flow",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Backbone"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:(null==(P=null==_?void 0:_.backboneEdges)?void 0:P.length)??0})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Unresolved prefix nodes inferred by Viterbi HMM from repeated path patterns",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Ghosts"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:ge.length})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Community-aware node coloring — groups nodes by cluster assignment",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Clustering"})}),n.jsx("span",{className:"tabular-nums "+(ut?"text-sys-blue":"text-fg-muted"),children:ut?"On":"Off"})]}),null!=wn&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Algebraic connectivity — 2nd-smallest eigenvalue of the graph Laplacian. Near-zero = one bridge from network partition.",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Fiedler λ₂"})}),n.jsx("span",{className:"tabular-nums "+(wn<.01?"text-status-warning":"text-fg-secondary"),children:wn.toFixed(4)})]}),ct.size>0&&n.jsxs("button",{onClick:()=>dt(new Set),className:"w-full mt-1 text-[10px] text-sys-blue hover:underline text-center",children:["Clear filters (",ct.size,")"]})]})]}),Zn=n.jsx(Z,{children:ze&&n.jsx(W.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},transition:{duration:.15},className:"absolute top-4 left-1/2 -translate-x-1/2 z-30 w-80",children:n.jsxs("div",{className:"surface-elevated radius-inset shadow-2xl overflow-hidden",children:[n.jsxs("div",{className:"flex items-center gap-2 px-3 py-2.5 border-b border-edge-subtle",children:[n.jsx(te,{className:"w-4 h-4 text-fg-muted shrink-0"}),n.jsx("input",{ref:Ns,type:"text",value:Ee,onChange:e=>Ae(e.target.value),placeholder:"Search by name or prefix...",className:"flex-1 bg-transparent text-sm text-fg-primary placeholder:text-fg-muted focus:outline-none",onKeyDown:e=>{"Escape"===e.key?($e(!1),Ae("")):"Enter"===e.key&&cn.length>0&&dn(cn[0])}}),Ee&&n.jsx("button",{onClick:()=>Ae(""),className:"p-0.5 radius-badge hover-bg transition-base",children:n.jsx(U,{className:"w-3 h-3 text-fg-muted"})})]}),cn.length>0&&n.jsx("div",{className:"max-h-64 overflow-y-auto",children:cn.map((e,t)=>n.jsxs("button",{onClick:()=>dn(e),className:"w-full flex items-center gap-3 px-3 py-2 text-left hover-bg transition-base "+(0===t?"bg-subtle-fill/50":""),children:[n.jsx("span",{className:"w-2.5 h-2.5 rounded-full shrink-0",style:{backgroundColor:we[e.nodeClass]}}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("div",{className:"text-sm text-fg-primary truncate",children:e.name||e.prefix}),e.name&&n.jsx("div",{className:"text-[10px] text-fg-muted",children:e.prefix})]}),n.jsx(he,{className:"w-3 h-3 text-fg-muted shrink-0"})]},e.id))}),Ee&&0===cn.length&&n.jsx("div",{className:"px-3 py-4 text-center text-sm text-fg-muted",children:"No nodes found"}),!Ee&&n.jsx("div",{className:"px-3 py-2 type-data-xs text-fg-muted",children:"Type to search • Enter to select • Esc to close"})]})})});return $?0===zs.length?n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsx("div",{className:"absolute inset-0 bg-body flex items-center justify-center",children:n.jsx(Ut,{})})]}):Cs?Be?n.jsxs("div",{className:"fixed inset-0 z-50 bg-body flex flex-col overflow-hidden",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 surface-header z-10",children:[n.jsxs("div",{className:"flex items-center gap-3",children:[n.jsx(X,{className:"w-5 h-5 text-icon-page-title"}),n.jsxs("h1",{className:"type-title text-fg-primary flex items-center gap-2",children:["MeshGraph",n.jsx(C,{color:"violet",compact:!0,children:"Analytics"})]}),n.jsxs("span",{className:"text-[10px] text-fg-muted tabular-nums",children:[Qs.length," nodes • ",qs.length," edges"]})]}),n.jsx(k,{content:"Exit fullscreen",children:n.jsx("button",{onClick:un,className:"p-1.5 radius-inner hover-bg transition-base",children:n.jsx(ce,{className:"w-4 h-4 text-fg-muted"})})})]}),n.jsxs("div",{className:"flex-1 relative min-h-0 m-2 surface-base radius-inset overflow-hidden border border-edge-subtle",children:[n.jsx(a,{className:"absolute inset-0",points:Cs,links:Ss,...Ls,...Rs,backgroundColor:ke,fitViewOnInit:!0,fitViewPadding:.15,showLabels:Ke,showDynamicLabels:!1,showTopLabels:Ke,showTopLabelsLimit:200,showHoveredPointLabel:!0,pointLabelColor:Se,pointClusterBy:ut?"communityId":void 0,onPolygonSelected:$t?pn:void 0,polygonalSelectorStrokeColor:Ne?"#FBBF24":"#D97706",onClick:ln,onLinkClick:rn,onMount:tn,hoveredPointRingColor:Ne?"#FBBF24":"#D97706",hoveredPointCursor:"pointer",hoveredLinkCursor:"pointer"}),Zn,On,Rn,Mn,Hn,In,n.jsxs(Z,{children:[Fe&&n.jsx(Vt,{node:Fe,egoMetrics:fn,onExpandEgo:yn,neighbors:bn,onSelectNeighbor:an,txDelayRec:vn,onClose:()=>{var e;Re(null),null==(e=ws.current)||e.unselectAllPoints()}}),Me&&!Fe&&n.jsx(Kt,{edge:Me,onClose:()=>He(null)}),Wt&&!Fe&&!Me&&n.jsx(_t,{metrics:Wt,onClose:gn})]})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0",children:[n.jsx(a,{className:"absolute inset-0",points:Cs,links:Ss,...Ls,...Rs,backgroundColor:ke,fitViewOnInit:!0,fitViewPadding:.15,showLabels:Ke,showDynamicLabels:!1,showTopLabels:Ke,showTopLabelsLimit:200,showHoveredPointLabel:!0,pointLabelColor:Se,pointClusterBy:ut?"communityId":void 0,onPolygonSelected:$t?pn:void 0,polygonalSelectorStrokeColor:Ne?"#FBBF24":"#D97706",onClick:ln,onLinkClick:rn,onMount:tn,hoveredPointRingColor:Ne?"#FBBF24":"#D97706",hoveredPointCursor:"pointer",hoveredLinkCursor:"pointer"}),Zn,On,Rn,Mn,Hn,In,n.jsxs("div",{className:"absolute bottom-4 right-4 z-10 hidden lg:flex items-center gap-3 type-data-xs text-fg-muted/60",children:[n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"/"})," Search"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"F"})," Fit"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"L"})," Labels"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"Space"})," Pause"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"Esc"})," Clear"]})]}),n.jsxs(Z,{children:[Fe&&n.jsx(Vt,{node:Fe,egoMetrics:fn,onExpandEgo:yn,neighbors:bn,onSelectNeighbor:an,txDelayRec:vn,onClose:()=>{var e;Re(null),null==(e=ws.current)||e.unselectAllPoints()}}),Me&&!Fe&&n.jsx(Kt,{edge:Me,onClose:()=>He(null)}),Wt&&!Fe&&!Me&&n.jsx(_t,{metrics:Wt,onClose:gn})]})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0 bg-body flex flex-col items-center justify-center gap-3",children:[n.jsx(xe,{className:"w-8 h-8 text-sys-blue animate-spin"}),n.jsx("span",{className:"type-body text-fg-muted",children:"Preparing graph..."})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0 bg-body flex items-center justify-center",children:[n.jsx(z,{isOpen:I,onClose:K}),!I&&n.jsx(xe,{className:"w-8 h-8 text-sys-blue animate-spin"})]})]})}export{qt as default}; +var e=Object.defineProperty,t=(t,s,n)=>((t,s,n)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n)(t,"symbol"!=typeof s?s+"":s,n);import{r as s,j as n,m as a,W as i,Z as o}from"./vendor-react-alRNW2nb.js";import{r}from"./cosmograph-DqYT4sUA.js";import{b1 as l,b2 as c,aF as d,aB as u,b3 as m,b4 as h,b5 as x,b6 as p,b7 as g,b8 as f,b9 as v,p as b,aR as y,ba as j,bb as N,Z as w,h as C,J as k,bc as S,bd as D,be as L,B as F,av as R}from"./index-CkRTgHHA.js";import{u as M,r as H,f as B,g as P,e as E}from"./consumer-registry-BUFl6buY.js";import{c as A,D as z,s as $}from"./DeepAnalysisModal-L9EkN490.js";import{D as T}from"./DataBox-DpDXI-WX.js";import{h as I,c as G}from"./geo-utils-DJn8DnxF.js";import{b as O,A as Z,m as W}from"./vendor-motion-DNp0Qg4F.js";import{aK as K,aL as V,b as _,X as U,W as X,ah as Q,aM as q,aN as J,aO as Y,a4 as ee,au as te,m as se,P as ne,aP as ae,R as ie,aQ as oe,aR as re,aB as le,aS as ce,aT as de,C as ue,D as me,ar as he,L as xe,ak as pe,a as ge,o as fe,E as ve,aU as be}from"./vendor-icons-TO0PZKGR.js";import{N as ye,a as je}from"./badge-colors-BxLppqaF.js";import{e as Ne,f as we,g as Ce}from"./meshcore-tx-constants-BDLT5LMb.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-core-FtpmsTnh.js";import"./vendor-fonts-CRZaZSFf.js";function ke(e){if(null==e)return"";const t=String(e);return t.includes(",")||t.includes('"')||t.includes("\n")?`"${t.replace(/"/g,'""')}"`:t}function Se(e,t){const s=[e.join(",")];for(const n of t)s.push(n.map(ke).join(","));return s.join("\n")}function De(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function Le(e){return!e||e<=0?"":new Date(1e3*e).toISOString()}function Fe(e,t){return`${e}-${(new Date).toISOString().replace(/[:.]/g,"-").slice(0,19)}.${t}`}const Re=["hash","prefix","name","nodeClass","communityId","degree","inDegree","outDegree","betweenness","pathDiversity","packetCount","lastSeen","activityLevel","recencyScore","avgRssi","avgSnr","isZeroHop","prefixConfidence","hasCollision","collisionCandidates","isLocal","isHub","isGateway","isBackbone","isMobile","isGhost","isInLoop","latitude","longitude","contactType"];function Me(e){var t,s;return[e.hash,e.prefix,e.name??"",e.nodeClass,e.communityId,e.degree,e.inDegree,e.outDegree,e.betweenness.toFixed(6),e.pathDiversity,e.packetCount,Le(e.lastSeen),e.activityLevel,e.recencyScore.toFixed(4),(null==(t=e.avgRssi)?void 0:t.toFixed(1))??"",(null==(s=e.avgSnr)?void 0:s.toFixed(1))??"",e.isZeroHop,e.prefixConfidence.toFixed(4),e.hasCollision,e.collisionCandidates,e.isLocal,e.isHub,e.isGateway,e.isBackbone,e.isMobile,e.isGhost,e.isInLoop,e.latitude??"",e.longitude??"",e.contactType??""]}function He(e,t){const s=[];for(const n of e.nodeMetrics.values())!t&&n.isGhost||s.push({hash:n.hash,prefix:n.prefix,name:n.name,nodeClass:n.nodeClass,communityId:n.communityId,degree:n.degree,inDegree:n.inDegree,outDegree:n.outDegree,betweenness:n.betweenness,pathDiversity:n.pathDiversity,packetCount:n.packetCount,lastSeen:n.lastSeen,activityLevel:n.activityLevel,recencyScore:n.recencyScore,avgRssi:n.avgRssi,avgSnr:n.avgSnr,isZeroHop:n.isZeroHop,prefixConfidence:n.prefixConfidence,hasCollision:n.hasCollision,isLocal:n.isLocal,isHub:n.isHub,isGateway:n.isGateway,isBackbone:n.isBackbone,isMobile:n.isMobile,isGhost:n.isGhost,isInLoop:n.isInLoop,latitude:n.latitude,longitude:n.longitude,contactType:n.contactType});return s}const Be=["fromHash","toHash","key","packetCount","certainCount","avgConfidence","strength","forwardCount","reverseCount","symmetryRatio","dominantDirection","floodCount","directCount","isDirectPathEdge","isZeroHop","isLoopEdge","isCertain","avgRssi","avgSnr","avgRecency","hopDistanceFromLocal","edgeBetweenness","isBackbone"];function Pe(e,t){const s=t?e.edges:e.validatedEdges,n=new Set(e.backboneEdges);return s.map(t=>({fromHash:t.fromHash,toHash:t.toHash,key:t.key,packetCount:t.packetCount,certainCount:t.certainCount,avgConfidence:t.avgConfidence,strength:t.strength,forwardCount:t.forwardCount,reverseCount:t.reverseCount,symmetryRatio:t.symmetryRatio,dominantDirection:t.dominantDirection,floodCount:t.floodCount,directCount:t.directCount,isDirectPathEdge:t.isDirectPathEdge,isZeroHop:t.isZeroHop??!1,isLoopEdge:t.isLoopEdge??!1,isCertain:t.isCertain,avgRssi:t.avgRssi??null,avgSnr:t.avgSnr??null,avgRecency:t.avgRecency,hopDistanceFromLocal:t.hopDistanceFromLocal,edgeBetweenness:e.edgeBetweenness.get(t.key)??0,isBackbone:n.has(t.key)}))}const Ee=["pathKey","hops","hopCount","healthScore","weakestLinkKey","weakestLinkConfidence","avgEdgeCertainty","observationTrend","alternatePathsCount","estimatedLatencyMs","observationCount","routeType","lastSeen","involvesHub"];function Ae(e){return[e.pathKey,e.hops.join(">"),e.hops.length,e.healthScore.toFixed(4),e.weakestLinkKey??"",e.weakestLinkConfidence.toFixed(4),e.avgEdgeCertainty.toFixed(4),e.observationTrend.toFixed(4),e.alternatePathsCount,e.estimatedLatencyMs.toFixed(0),e.observationCount,e.routeType,Le(e.lastSeen),e.involvesHub]}const ze=["nodeHash","nodePrefix","nodeName","networkRole","floodFactor","directFactor","floodSlots","directSlots","trafficIntensity","directNeighborCount","collisionRisk","confidence","adjustment","dataConfidence","observationSymmetry","rationale"];function $e(e,t,s){const n=s.get(e);return[e,(null==n?void 0:n.prefix)??"",(null==n?void 0:n.name)??"",t.networkRole,t.floodFactor.toFixed(2),t.directFactor.toFixed(2),t.floodSlots,t.directSlots,t.trafficIntensity.toFixed(4),t.directNeighborCount,t.collisionRisk.toFixed(4),t.confidence.toFixed(4),t.adjustment,t.dataConfidence,t.observationSymmetry.toFixed(4),t.rationale]}function Te(e,t){var s,n;const a=new Set(e.backboneEdges),i=['','',` `,` pymc_console v${l}`," MeshCore LoRa Mesh Network Topology"," ",' ',""," \x3c!-- Node Attributes --\x3e",' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '," ",""," \x3c!-- Edge Attributes --\x3e",' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '," ",""," "];for(const o of e.nodeMetrics.values()){if(!t&&o.isGhost)continue;const e=De(o.name??o.prefix);i.push(` `),i.push(" "),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),null!=o.avgRssi&&i.push(` `),null!=o.avgSnr&&i.push(` `),i.push(" "),null==o.latitude||null==o.longitude||0===o.latitude&&0===o.longitude||i.push(` `),i.push(" ")}i.push(" "),i.push(""),i.push(" ");for(const o of e.validatedEdges){const r=e.nodeMetrics;if(!t&&((null==(s=r.get(o.fromHash))?void 0:s.isGhost)||(null==(n=r.get(o.toHash))?void 0:n.isGhost)))continue;const l=e.edgeBetweenness.get(o.key)??0;i.push(` `),i.push(" "),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(` `),i.push(" "),i.push(" ")}return i.push(" "),i.push(" "),i.push(""),i.join("\n")}function Ie(e,t,s){const n={meta:{exportedAt:(new Date).toISOString(),pymcConsoleVersion:l,nodeCount:e.nodeMetrics.size,edgeCount:e.validatedEdges.length,communityCount:e.communityCount,loopCount:e.loops.length,backboneEdgeCount:e.backboneEdges.length,hubNodes:e.hubNodes.length,gatewayNodes:e.gatewayNodes.length,mobileNodes:e.mobileNodes.length,ghostNodes:e.discoveredNodes.filter(e=>e.isLikelyReal).length},nodes:He(e,t),edges:Pe(e,s),pathHealth:e.pathHealth.map(e=>({pathKey:e.pathKey,hops:e.hops,healthScore:e.healthScore,weakestLinkKey:e.weakestLinkKey,weakestLinkConfidence:e.weakestLinkConfidence,avgEdgeCertainty:e.avgEdgeCertainty,observationTrend:e.observationTrend,alternatePathsCount:e.alternatePathsCount,estimatedLatencyMs:e.estimatedLatencyMs,observationCount:e.observationCount,routeType:e.routeType,lastSeen:e.lastSeen,involvesHub:e.involvesHub})),txDelayRecommendations:Array.from(e.txDelayRecommendations.entries()).map(([t,s])=>{var n,a;return{nodeHash:t,nodePrefix:(null==(n=e.nodeMetrics.get(t))?void 0:n.prefix)??"",nodeName:(null==(a=e.nodeMetrics.get(t))?void 0:a.name)??null,networkRole:s.networkRole,floodFactor:s.floodFactor,directFactor:s.directFactor,floodSlots:s.floodSlots,directSlots:s.directSlots,trafficIntensity:s.trafficIntensity,collisionRisk:s.collisionRisk,confidence:s.confidence,adjustment:s.adjustment,dataConfidence:s.dataConfidence,rationale:s.rationale}}),loops:e.loops.map(e=>({id:e.id,nodes:e.nodes,edgeKeys:e.edgeKeys,size:e.size,avgCertainCount:e.avgCertainCount,minCertainCount:e.minCertainCount,includesLocal:e.includesLocal,strength:e.strength})),disambiguationStats:{totalPrefixes:e.disambiguationStats.totalPrefixes,unambiguousPrefixes:e.disambiguationStats.unambiguousPrefixes,collisionPrefixes:e.disambiguationStats.collisionPrefixes,collisionRate:e.disambiguationStats.collisionRate,avgConfidence:e.disambiguationStats.avgConfidence},viterbiStats:{totalPaths:e.viterbiStats.totalPaths,pathsWithGhosts:e.viterbiStats.pathsWithGhosts,avgPathConfidence:e.viterbiStats.avgPathConfidence,tracePacketsProcessed:e.viterbiStats.tracePacketsProcessed,pathPacketsProcessed:e.viterbiStats.pathPacketsProcessed,distantEdgesDiscovered:e.viterbiStats.distantEdgesDiscovered,duplicateGroupsFound:e.viterbiStats.duplicateGroupsFound,echolocationEdgesInferred:e.viterbiStats.echolocationEdgesInferred}};return JSON.stringify(n,null,2)}function Ge(e,t){const s=t.includeGhosts??!0,n=t.includeWeakEdges??!1;switch(t.format){case"csv":{let a,i;switch(t.dataset){case"nodes":case"full":default:a=function(e,t){const s=[];for(const n of e.nodeMetrics.values())!t&&n.isGhost||s.push(Me(n));return Se(Re,s)}(e,s),i="mesh-nodes";break;case"edges":a=function(e,t){const s=t?e.edges:e.validatedEdges,n=new Set(e.backboneEdges),a=s.map(t=>function(e,t,s){var n,a;return[e.fromHash,e.toHash,e.key,e.packetCount,e.certainCount,e.avgConfidence.toFixed(4),e.strength.toFixed(4),e.forwardCount,e.reverseCount,e.symmetryRatio.toFixed(4),e.dominantDirection,e.floodCount,e.directCount,e.isDirectPathEdge,e.isZeroHop??!1,e.isLoopEdge??!1,e.isCertain,(null==(n=e.avgRssi)?void 0:n.toFixed(1))??"",(null==(a=e.avgSnr)?void 0:a.toFixed(1))??"",e.avgRecency.toFixed(4),e.hopDistanceFromLocal,(t.get(e.key)??0).toFixed(6),s.has(e.key)]}(t,e.edgeBetweenness,n));return Se(Be,a)}(e,n),i="mesh-edges";break;case"pathHealth":a=function(e){const t=e.pathHealth.map(Ae);return Se(Ee,t)}(e),i="mesh-path-health";break;case"txDelay":a=function(e){const t=[];for(const[s,n]of e.txDelayRecommendations)t.push($e(s,n,e.nodeMetrics));return Se(ze,t)}(e),i="mesh-tx-delay"}return{content:a,filename:Fe(i,"csv"),mimeType:"text/csv"}}case"gexf":return{content:Te(e,s),filename:Fe("mesh-topology","gexf"),mimeType:"application/xml"};default:return{content:Ie(e,s,n),filename:Fe("mesh-topology","json"),mimeType:"application/json"}}}function Oe(e,t,s=1){const{n:n,adjList:a,totalWeight:i,degree:o}=e;if(0===i)return!1;const r=2*i,l=new Float64Array(n);for(let u=0;up+1e-7&&(p=a,x=e)}x!==n&&(l[n]-=u,l[x]+=u,t[e]=x,d=!0,c=!0)}}return c}function Ze(e,t){const{n:s,adjList:n}=e,a=new Set;for(let h=0;he-t),o=new Map;for(let h=0;h[]);for(const[h,x]of c){const[e,t]=h.split("-").map(Number),s=x/2;m[e].push({j:t,w:s}),m[t].push({j:e,w:s}),d[e]+=s,d[t]+=s,u+=s}return{newGraph:{n:r,adjList:m,totalWeight:u,degree:Array.from(d)},mapping:l}}function We(e,t,s){const n=(null==s?void 0:s.resolution)??1,a=(null==s?void 0:s.kWeight)??1,i=t.length;if(0===i)return{communities:new Map,numCommunities:0,modularity:0,passes:0};if(1===i)return{communities:new Map([[t[0],0]]),numCommunities:1,modularity:0,passes:0};const{graph:o}=function(e,t,s=1){const n=t.length,a=new Map;for(let l=0;l[]),o=new Array(n).fill(0);let r=0;for(const l of e){const e=a.get(l.fromHash),t=a.get(l.toHash);if(void 0===e||void 0===t)continue;if(e===t)continue;const n=Math.max(.01,(l.certainCount+1)*l.avgConfidence*l.strength),c=1===s?n:Math.pow(n,s);i[e].push({j:t,w:c}),i[t].push({j:e,w:c}),o[e]+=c,o[t]+=c,r+=c}return{graph:{n:n,adjList:i,totalWeight:r,degree:o},hashToIdx:a}}(e,t,a);let r=o,l=new Int32Array(i);for(let v=0;v=r.n)break;r=e,l=new Int32Array(e.n);for(let s=0;se-t),x=new Map;for(let v=0;v=20?"excellent":e>=10?"good":e>=3?"fair":e>=0?"marginal":"critical"}function Je(e){return e>=15?"anomalous-good":e>=5?"better":e>=-5?"expected":e>=-20?"worse":"anomalous-bad"}function Ye(e,t,s,n,a){const i=n.tx_power??22,o=n.spreading_factor??12,r=n.coding_rate??5,l=n.frequency??0,c=l>1e5?l/1e6:l||915,d=n.bandwidth??0,u=d>1e3?d/1e3:d||125,m=(null==a?void 0:a.sensitivityOverrideDbm)??Xe(o,u,r);let h=null,x=null;t&&s&&I(t.latitude??void 0,t.longitude??void 0)&&I(s.latitude??void 0,s.longitude??void 0)&&(h=G(t.latitude,t.longitude,s.latitude,s.longitude),x=h/1e3);let p=null,g=null;null!=h&&h>0&&(p=Ue(h,c),g=i+2.15+2.15-p);const f=e.avgRssi??null,v=e.avgSnr??null;let b=null,y=null;null!=f&&null!=g&&(b=f-g,y=Je(b));let j=null,N=null;null!=f&&(j=f-m,N=qe(j));const w=null!=f,C="anomalous-good"===y||"anomalous-bad"===y;return{edgeKey:e.key,fromHash:e.fromHash,toHash:e.toHash,distanceM:h,distanceKm:x,fsplDb:p,theoreticalRxPowerDbm:g,observedRssiDbm:f,observedSnrDb:v,deviationDb:b,deviationClass:y,marginDb:j,marginClass:N,sensitivityDbm:m,txPowerDbm:i,frequencyMhz:c,spreadingFactor:o,bandwidthKhz:u,noiseFloorDbm:null,isZeroHop:e.isZeroHop??!1,isTraceEstimated:!1,hasData:w,isAnomalous:C}}function et(e,t,s,n,a=22,i){var o,r;const l=e.traceQuality;if(!l)return null;let c=null;if(c=null!=l.forward&&null!=l.reverse?Math.min(l.forward.mean,l.reverse.mean):(null==(o=l.forward)?void 0:o.mean)??(null==(r=l.reverse)?void 0:r.mean)??null,null==c)return null;const d=n.spreading_factor??12,u=n.coding_rate??5,m=n.bandwidth??0,h=m>1e3?m/1e3:m||125,x=1e3*h,p=n.frequency??0,g=p>1e5?p/1e6:p||915,f=(null==i?void 0:i.sensitivityOverrideDbm)??Xe(d,h,u),v=(null==i?void 0:i.observedNoiseFloorDbm)??Qe(x),b=v+c;let y=null,j=null;t&&s&&I(t.latitude??void 0,t.longitude??void 0)&&I(s.latitude??void 0,s.longitude??void 0)&&(y=G(t.latitude,t.longitude,s.latitude,s.longitude),j=y/1e3);let N=null,w=null;null!=y&&y>0&&(N=Ue(y,g),w=a+2.15+2.15-N);let C=null,k=null;null!=w&&(C=b-w,k=Je(C));const S=b-f,D=qe(S);return{edgeKey:e.key,fromHash:e.fromHash,toHash:e.toHash,distanceM:y,distanceKm:j,fsplDb:N,theoreticalRxPowerDbm:w,observedRssiDbm:b,observedSnrDb:c,deviationDb:C,deviationClass:k,marginDb:S,marginClass:D,sensitivityDbm:f,noiseFloorDbm:v,txPowerDbm:a,frequencyMhz:g,spreadingFactor:d,bandwidthKhz:h,isZeroHop:!1,isTraceEstimated:!0,hasData:!0,isAnomalous:"anomalous-good"===k||"anomalous-bad"===k}}const tt={"anomalous-good":"#2DD4BF",better:"#34D399",expected:"#9CA3AF",worse:"#FB923C","anomalous-bad":"#EF4444"},st={excellent:"#34D399",good:"#A3E635",fair:"#FBBF24",marginal:"#FB923C",critical:"#EF4444"};function nt(e,t="margin"){return e.hasData?"deviation"===t?e.deviationClass?tt[e.deviationClass]:"#505058":e.marginClass?st[e.marginClass]:"#505058":"#505058"}function at(e,t=.5,s=4){return null==e.marginDb?t:t+Math.max(0,Math.min(1,e.marginDb/40))*(s-t)}let it=0;function ot(){return`ta-${++it}-${Date.now()}`}function rt(e){return{standard:0,ghost:1,mobile:2,neighbor:3,backbone:4,gateway:5,hub:6,local:7}[e]??0}class lt{constructor(e=200){t(this,"prevSnapshot",null),t(this,"log",[]),t(this,"maxLog"),this.maxLog=e}update(e,t){const s=function(e){var t,s;const n=new Set;for(const u of e.edges)n.add(u.key);const a=new Map,i=new Map,o=new Map,r=new Set;for(const[u,m]of e.nodeMetrics)a.set(u,m.betweenness),i.set(u,m.communityId),o.set(u,m.nodeClass),r.add(u);const l=new Set;for(const u of e.discoveredNodes)u.isLikelyReal&&l.add(u.prefix);const c=new Map,d=new Map;for(const u of e.edges)(null==(t=u.traceQuality)?void 0:t.composite)&&c.set(u.key,u.traceQuality.composite.mean),null!=(null==(s=u.traceQuality)?void 0:s.asymmetryDb)&&d.set(u.key,u.traceQuality.asymmetryDb);return{timestamp:Date.now(),edgeKeys:n,betweenness:a,communities:i,nodeClasses:o,ghostPrefixes:l,nodeHashes:r,traceSnr:c,traceAsymmetry:d}}(e);if(!this.prevSnapshot)return this.prevSnapshot=s,{anomalies:[],categoryCounts:{"edge-appeared":0,"edge-disappeared":0,"ghost-appeared":0,"ghost-disappeared":0,"betweenness-shift":0,"community-change":0,"class-change":0,"node-appeared":0,"node-disappeared":0,"snr-degradation":0,"asymmetry-shift":0},severityCounts:{info:0,warning:0,critical:0},totalCount:0,timestamp:Date.now()};const n=function(e,t,s){const n=Date.now(),a=[],i=e=>(null==s?void 0:s.get(e))??null;for(const d of t.edgeKeys)if(!e.edgeKeys.has(d)){const[e,t]=d.split("-"),s=i(e)??(null==e?void 0:e.slice(0,6)),o=i(t)??(null==t?void 0:t.slice(0,6));a.push({id:ot(),detectedAt:n,category:"edge-appeared",severity:"info",description:`New edge: ${s} ↔ ${o}`,edgeKey:d})}for(const d of e.edgeKeys)if(!t.edgeKeys.has(d)){const[e,t]=d.split("-"),s=i(e)??(null==e?void 0:e.slice(0,6)),o=i(t)??(null==t?void 0:t.slice(0,6));a.push({id:ot(),detectedAt:n,category:"edge-disappeared",severity:"warning",description:`Edge lost: ${s} ↔ ${o}`,edgeKey:d})}for(const d of t.nodeHashes)if(!e.nodeHashes.has(d)){const e=i(d);a.push({id:ot(),detectedAt:n,category:"node-appeared",severity:"info",description:`Node appeared: ${e??d.slice(0,8)}`,nodeHash:d,nodeName:e??void 0})}for(const d of e.nodeHashes)if(!t.nodeHashes.has(d)){const e=i(d);a.push({id:ot(),detectedAt:n,category:"node-disappeared",severity:"warning",description:`Node dropped: ${e??d.slice(0,8)}`,nodeHash:d,nodeName:e??void 0})}for(const d of t.ghostPrefixes)e.ghostPrefixes.has(d)||a.push({id:ot(),detectedAt:n,category:"ghost-appeared",severity:"info",description:`Ghost node discovered: ${d.toUpperCase()}`});for(const d of e.ghostPrefixes)t.ghostPrefixes.has(d)||a.push({id:ot(),detectedAt:n,category:"ghost-disappeared",severity:"info",description:`Ghost node resolved: ${d.toUpperCase()}`});for(const[d,u]of t.traceSnr){const t=e.traceSnr.get(d);if(void 0===t)continue;const s=t-u;s>=3&&a.push({id:ot(),detectedAt:n,category:"snr-degradation",severity:s>=6?"critical":"warning",description:`SNR dropped ${s.toFixed(1)} dB on edge ${d.slice(0,13)}`,edgeKey:d,previousValue:t,currentValue:u})}for(const[d,u]of t.traceAsymmetry){const t=e.traceAsymmetry.get(d);if(void 0===t)continue;const s=u-t;s>=4&&a.push({id:ot(),detectedAt:n,category:"asymmetry-shift",severity:s>=8?"critical":"warning",description:`Asymmetry grew ${s.toFixed(1)} dB on edge ${d.slice(0,13)}`,edgeKey:d,previousValue:t,currentValue:u})}for(const[d,u]of t.betweenness){const t=e.betweenness.get(d);if(void 0===t)continue;const s=Math.abs(u-t);if(s>=.15){const e=i(d),o=u>t?"increased":"decreased";a.push({id:ot(),detectedAt:n,category:"betweenness-shift",severity:s>=.3?"critical":"warning",description:`${e??d.slice(0,8)} betweenness ${o}: ${t.toFixed(3)} → ${u.toFixed(3)}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}for(const[d,u]of t.communities){const t=e.communities.get(d);if(void 0!==t&&u!==t){const e=i(d);a.push({id:ot(),detectedAt:n,category:"community-change",severity:"info",description:`${e??d.slice(0,8)} moved: community #${t} → #${u}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}for(const[d,u]of t.nodeClasses){const t=e.nodeClasses.get(d);if(void 0!==t&&u!==t){const e=i(d),s=rt(u)>rt(t);a.push({id:ot(),detectedAt:n,category:"class-change",severity:s?"warning":"info",description:`${e??d.slice(0,8)} ${s?"promoted":"changed"}: ${t} → ${u}`,nodeHash:d,nodeName:e??void 0,previousValue:t,currentValue:u})}}const o={},r={},l=["edge-appeared","edge-disappeared","ghost-appeared","ghost-disappeared","betweenness-shift","community-change","class-change","node-appeared","node-disappeared","snr-degradation","asymmetry-shift"],c=["info","warning","critical"];for(const d of l)o[d]=0;for(const d of c)r[d]=0;for(const d of a)o[d.category]++,r[d.severity]++;return a.sort((e,t)=>t.detectedAt-e.detectedAt),{anomalies:a,categoryCounts:o,severityCounts:r,totalCount:a.length,timestamp:n}}(this.prevSnapshot,s,t);this.prevSnapshot=s;try{!function(e,t){var s,n,a;const i=t.edgeMap,o=t.nodeMetrics,r=new Set(t.backboneEdges??[]);for(const l of e){if(l.edgeKey&&("edge-appeared"===l.category||"edge-disappeared"===l.category)){const e=null==i?void 0:i.get(l.edgeKey),t=l.edgeKey.split("-"),c=t[0],d=t[1],u=c?null==o?void 0:o.get(c):void 0,m=d?null==o?void 0:o.get(d):void 0;l.edgeDetail=e?{fromName:(null==u?void 0:u.name)??null,toName:(null==m?void 0:m.name)??null,fromClass:(null==u?void 0:u.nodeClass)??null,toClass:(null==m?void 0:m.nodeClass)??null,packetCount:e.packetCount,confidence:e.avgConfidence,symmetryRatio:e.symmetryRatio,isBackbone:r.has(l.edgeKey),isLoop:e.isLoopEdge??!1,isZeroHop:e.isZeroHop??!1,isDirectPath:e.isDirectPathEdge,avgRssi:e.avgRssi??null,avgSnr:e.avgSnr??null,fromBetweenness:(null==u?void 0:u.betweenness)??null,toBetweenness:(null==m?void 0:m.betweenness)??null,traceCompositeSnr:(null==(n=null==(s=e.traceQuality)?void 0:s.composite)?void 0:n.mean)??null,traceAsymmetryDb:(null==(a=e.traceQuality)?void 0:a.asymmetryDb)??null}:{fromName:(null==u?void 0:u.name)??null,toName:(null==m?void 0:m.name)??null,fromClass:(null==u?void 0:u.nodeClass)??null,toClass:(null==m?void 0:m.nodeClass)??null,packetCount:0,confidence:0,symmetryRatio:0,isBackbone:!1,isLoop:!1,isZeroHop:!1,isDirectPath:!1,avgRssi:null,avgSnr:null,fromBetweenness:(null==u?void 0:u.betweenness)??null,toBetweenness:(null==m?void 0:m.betweenness)??null,traceCompositeSnr:null,traceAsymmetryDb:null}}if(l.nodeHash){const e=null==o?void 0:o.get(l.nodeHash);e&&(l.nodeDetail=ct(e))}}}(n.anomalies,e)}catch(a){console.warn("[TopologyAnomalyTracker] Enrichment failed, anomalies logged without detail:",a)}return this.log.unshift(...n.anomalies),this.log.length>this.maxLog&&(this.log.length=this.maxLog),n}getLog(){return this.log}getFiltered(e){const t=Date.now();return this.log.filter(s=>!(e.category&&s.category!==e.category||e.severity&&s.severity!==e.severity||e.nodeHash&&s.nodeHash!==e.nodeHash||e.maxAge&&t-s.detectedAt>e.maxAge))}clear(){this.log=[],this.prevSnapshot=null}}function ct(e){return{nodeClass:e.nodeClass,degree:e.degree,betweenness:e.betweenness,activityLevel:e.activityLevel,isZeroHop:e.isZeroHop,avgRssi:e.avgRssi,avgSnr:e.avgSnr,communityId:e.communityId,packetCount:e.packetCount,connectionCount:e.degree}}function dt(e){if(e.length<2)return 0;const t=e.length;let s=0,n=0,a=0,i=0;for(let r=0;r.3&&n.push({name:"Weak link certainty",description:e.weakestLinkKey?`Weakest: ${e.weakestLinkConfidence<.3?"very low":"low"} confidence`:`Average certainty: ${(100*e.avgEdgeCertainty).toFixed(0)}%`,score:i,weight:.25});let o=0;0===e.alternatePathsCount?(o=1,n.push({name:"No alternate paths",description:"Single route to destination — no failover available",score:o,weight:ut})):1===e.alternatePathsCount&&(o=.5,n.push({name:"Limited redundancy",description:"Only 1 alternate path available",score:o,weight:ut}));let r=0;if(e.weakestLinkKey){const a=t.get(e.weakestLinkKey),i=(null==a?void 0:a.avgRssi)??null,o=e.weakestLinkTraceSnr;if(null!=i){const e=i-s;e<3?(r=1,n.push({name:"Signal near sensitivity",description:`Weakest link: ${e.toFixed(1)} dB margin (< 3 dB)`,score:r,weight:mt})):e<10&&(r=1-(e-3)/7,n.push({name:"Low signal margin",description:`Weakest link: ${e.toFixed(1)} dB margin`,score:r,weight:mt}))}else null!=o&&o<5&&(r=o<-5?1:o<0?.7:.4,n.push({name:"Low trace SNR",description:`Weakest link trace SNR: ${o.toFixed(1)} dB`,score:r,weight:mt}))}let l=0;if(e.weakestLinkKey){const s=t.get(e.weakestLinkKey),a=null==s?void 0:s.traceQuality;(null==a?void 0:a.composite)&&(a.composite.mean<0?(l=.8,n.push({name:"Trace SNR negative",description:`Composite trace SNR: ${a.composite.mean.toFixed(1)} dB (negative)`,score:l,weight:ht})):a.composite.stdDev>4?(l=.6,n.push({name:"Unstable trace SNR",description:`High variance: σ=${a.composite.stdDev.toFixed(1)} dB`,score:l,weight:ht})):null!=a.asymmetryDb&&a.asymmetryDb>8&&(l=.5,n.push({name:"High SNR asymmetry",description:`Bidirectional asymmetry: ${a.asymmetryDb.toFixed(1)} dB`,score:l,weight:ht})))}const c=.3*a+.25*i+o*ut+r*mt+l*ht;if(c<.35)return null;let d,u;return c>=.75?(d="critical",u="imminent"):c>=.55?(d="high",u="near-term"):(d="moderate",u="watch"),{pathKey:e.pathKey,hops:e.hops,riskScore:Math.round(100*c)/100,riskLevel:d,factors:n,weakestEdgeKey:e.weakestLinkKey,healthScore:e.healthScore,observationTrend:e.observationTrend,alternatePathsCount:e.alternatePathsCount,urgency:u}}let pt=100;function gt(){return++pt}const ft="meshgraph-panel-";function vt(e){try{const t=localStorage.getItem(ft+e);return t?JSON.parse(t):null}catch{return null}}function bt({id:e,title:t,icon:a,open:i,onClose:o,defaultPosition:r,defaultSize:l,minSize:c={width:180,height:120},maxSize:d,autoHeight:u=!1,headerActions:m,children:h}){const x=O(),p=s.useRef(null),g=s.useRef(null),f=s.useMemo(()=>{const t=vt(e);return t?{x:t.x,y:t.y,w:t.w,h:u?l.height:t.h,minimized:t.minimized}:{x:r.x,y:r.y,w:l.width,h:l.height,minimized:!1}},[e]),[v,b]=s.useState({w:f.w,h:f.h}),[y,j]=s.useState(f.minimized),[N,w]=s.useState(()=>gt()),[C,k]=s.useState({x:f.x,y:f.y});s.useLayoutEffect(()=>{const t=p.current;if(!i||!t)return;const s=t.getBoundingClientRect();if(s.width<1||s.height<1)return;const n=vt(e),a=(o=(null==n?void 0:n.x)??f.x,r=(null==n?void 0:n.y)??f.y,l=(null==n?void 0:n.w)??v.w,c=s.width,d=s.height,{x:Math.max(8,Math.min(o,Math.max(8,c-l-8))),y:Math.max(8,Math.min(r,Math.max(8,d-36)))});var o,r,l,c,d;k(a)},[i,e]);const[S,D]=s.useState(!1),L=s.useRef({startX:0,startY:0,startW:0,startH:0,edge:""}),F=s.useRef(),R=s.useCallback(()=>{F.current&&clearTimeout(F.current),F.current=setTimeout(()=>{const t=g.current;if(!t)return;const s=window.getComputedStyle(t),n=new DOMMatrix(s.transform);!function(e,t){try{localStorage.setItem(ft+e,JSON.stringify(t))}catch{}}(e,{x:n.m41,y:n.m42,w:v.w,h:v.h,minimized:y})},300)},[e,v.w,v.h,y]);s.useEffect(()=>{R()},[v,y,R]);const M=s.useCallback(()=>{w(gt())},[]),H=s.useCallback(()=>{j(e=>!e)},[]),B=s.useCallback((e,t)=>{e.preventDefault(),e.stopPropagation(),D(!0),L.current={startX:e.clientX,startY:e.clientY,startW:v.w,startH:v.h,edge:t},M();const s=e=>{const{startX:t,startY:s,startW:n,startH:a,edge:i}=L.current,o=e.clientX-t,r=e.clientY-s;let l=n,u=a;"e"!==i&&"se"!==i||(l=Math.max(c.width,n+o),d&&(l=Math.min(d.width,l))),"s"!==i&&"se"!==i||(u=Math.max(c.height,a+r),d&&(u=Math.min(d.height,u))),b({w:l,h:u})},n=()=>{D(!1),window.removeEventListener("pointermove",s),window.removeEventListener("pointerup",n)};window.addEventListener("pointermove",s),window.addEventListener("pointerup",n)},[v,c,d,M]);return n.jsx("div",{ref:p,className:"absolute inset-0 pointer-events-none",style:{zIndex:N},children:n.jsx(Z,{children:i&&n.jsxs(W.div,{ref:g,drag:!S,dragControls:x,dragConstraints:p,dragElastic:.05,dragMomentum:!1,dragListener:!1,initial:{opacity:0,scale:.96,x:C.x,y:C.y},animate:{opacity:1,scale:1,x:C.x,y:C.y},exit:{opacity:0,scale:.96},transition:{duration:.15},onPointerDown:M,className:"absolute top-0 left-0 pointer-events-auto",style:{width:v.w,touchAction:"none"},children:[n.jsxs("div",{className:"surface-elevated radius-inset shadow-xl overflow-hidden flex flex-col",style:{maxHeight:y?void 0:u?"80vh":v.h},children:[n.jsxs("div",{className:"flex items-center gap-1.5 px-2 py-1.5 border-b border-edge-subtle cursor-grab active:cursor-grabbing select-none shrink-0",onPointerDown:e=>{M(),x.start(e)},children:[n.jsx(K,{className:"w-3 h-3 text-fg-muted/50 shrink-0"}),a&&n.jsx("span",{className:"text-fg-muted shrink-0 [&>svg]:w-3 [&>svg]:h-3",children:a}),n.jsx("span",{className:"text-[11px] font-medium text-fg-primary flex-1 truncate",children:t}),m,n.jsx("button",{onClick:H,className:"p-0.5 radius-badge hover-bg transition-base",title:y?"Expand":"Minimize",children:y?n.jsx(V,{className:"w-2.5 h-2.5 text-fg-muted"}):n.jsx(_,{className:"w-2.5 h-2.5 text-fg-muted"})}),n.jsx("button",{onClick:o,className:"p-0.5 radius-badge hover-bg transition-base",title:"Close",children:n.jsx(U,{className:"w-2.5 h-2.5 text-fg-muted"})})]}),n.jsx(Z,{initial:!1,children:!y&&n.jsx(W.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.15},className:"overflow-hidden",children:n.jsx("div",{className:"overflow-y-auto",style:{maxHeight:u?"70vh":void 0},children:h})})})]}),!y&&!u&&n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"absolute top-0 -right-1 w-2 h-full cursor-ew-resize",onPointerDown:e=>B(e,"e")}),n.jsx("div",{className:"absolute -bottom-1 left-0 w-full h-2 cursor-ns-resize",onPointerDown:e=>B(e,"s")}),n.jsx("div",{className:"absolute -bottom-1 -right-1 w-3 h-3 cursor-nwse-resize",onPointerDown:e=>B(e,"se"),children:n.jsxs("svg",{className:"w-full h-full text-fg-muted/30",viewBox:"0 0 12 12",children:[n.jsx("path",{d:"M10 2 L10 10 L2 10",fill:"none",stroke:"currentColor",strokeWidth:"1.5"}),n.jsx("path",{d:"M7 5 L7 7 L5 7",fill:"none",stroke:"currentColor",strokeWidth:"1"})]})})]})]})})})}const yt=[{target:"Graph",fn:"topology.edges",minStage:2,when:B},{target:"Graph",fn:"topology.edges",minStage:2,when:P},{target:"Graph",fn:"nodeMetrics",minStage:2},{target:"Graph",fn:"ghostNodes",minStage:2,when:B},{target:"Graph",fn:"_advertNodeType",minStage:1,when:E},{target:"Graph",fn:"pathHealth",minStage:2}];H(yt);const jt=800,Nt={critical:[N.red,N.red],poor:[N.orange,N.orange],fair:[N.amber,N.amber],good:[N.green,N.green],excellent:[N.blue,N.blue]},wt={active:1,recent:.85,stale:.45,inactive:.25},Ct=[N.purple,N.green,N.amber,N.red,N.blue,N.pink,N.teal,N.orange],kt=[N.purple,N.green,N.amber,N.red,N.blue,N.pink,N.teal,N.orange];function St(e,t,s){const n=(e,t)=>parseInt(e.slice(1+2*t,3+2*t),16);return`#${[0,1,2].map(a=>{return(i=a,Math.round(n(e,i)*s+n(t,i)*(1-s))).toString(16).padStart(2,"0");var i}).join("")}`}const Dt={zeroHop:St(N.amber,w[500],.55),directPath:St(N.teal,w[500],.55),loop:St(N.purple,w[500],.55),backbone:w[300],standard:w[500],standardDim:w[600],ghost:w[600]},Lt={zeroHop:St(N.amber,w[700],.5),directPath:St(N.teal,w[700],.5),loop:St(N.purple,w[700],.5),backbone:w[700],standard:w[400],standardDim:w[300],ghost:w[400]},Ft=!1,Rt=!0,Mt=!0,Ht=!0,Bt=!0,Pt=!0,Et={local:N.amber,hub:N.purple,gateway:N.blue,backbone:N.green,neighbor:N.pink,mobile:N.orange,ghost:w[400],standard:w[300]},At={local:N.amber,hub:N.purple,gateway:N.blue,backbone:N.green,neighbor:N.pink,mobile:N.orange,ghost:w[500],standard:w[600]},zt={local:"Your repeater — the home node running this dashboard",hub:"≥10% of last-hop traffic — dominant forwarder for your local node",gateway:"7-10% of last-hop traffic — significant relay node",backbone:"High betweenness centrality — critical path node connecting clusters",neighbor:"Zero-hop direct RF contact — no intermediate forwarders",mobile:"High path volatility — node appears and disappears frequently",ghost:"Unresolved prefix inferred by Viterbi HMM from path patterns",standard:"<7% of traffic — normal mesh participant"};function $t(e){const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}function Tt(e,t,s){const[n,a,i]=$t(e),[o,r,l]=$t(t),c=Math.max(0,Math.min(1,s)),d=Math.round(n*c+o*(1-c)),u=Math.round(a*c+r*(1-c)),m=Math.round(i*c+l*(1-c));return`#${d.toString(16).padStart(2,"0")}${u.toString(16).padStart(2,"0")}${m.toString(16).padStart(2,"0")}`}function It(e,t){return e.isZeroHop?"zero-hop":e.isDirectPathEdge?"direct-path":e.isLoopEdge?"loop":t.has(e.key)?"backbone":"standard"}function Gt(e,t,s){const n=s?Dt:Lt;switch(e){case"zero-hop":return n.zeroHop;case"direct-path":return n.directPath;case"loop":return n.loop;case"backbone":return n.backbone;case"ghost":return n.ghost;default:return t>=.7?n.standard:n.standardDim}}const Ot={"zero-hop":"Zero-Hop (Direct RF)","direct-path":"Direct Path (Unicast)",loop:"Redundant Loop",backbone:"Backbone",standard:"Standard",ghost:"Ghost (Inferred)"},Zt={"zero-hop":"Direct radio contact — no intermediate forwarders in path","direct-path":"Unicast-routed edge — verified via DIRECT route type packets",loop:"Redundant path — alternate route between the same endpoints exists",backbone:"High betweenness centrality — critical traffic flow edge",standard:"Normal mesh edge with moderate-to-high confidence",ghost:"Inferred connection from Viterbi HMM ghost node analysis"},Wt=s.memo(function({timeline:e}){const t=e.buckets;if(t.length<2)return null;const[s,a]=e.rssiRange,i=Math.max(1,a-s),[o,r]=e.snrRange,l=Math.max(1,r-o),c=198/(t.length-1),d=t.map((e,t)=>{const n=1+t*c,a=1+34*(1-(e.avgRssi-s)/i);return`${n.toFixed(1)},${a.toFixed(1)}`}).join(" "),u=t.map((e,t)=>{const s=1+t*c,n=1+34*(1-(e.avgSnr-o)/l);return`${s.toFixed(1)},${n.toFixed(1)}`}).join(" "),m=e.rssiTrend>.1?"↑":e.rssiTrend<-.1?"↓":"→",h=e.snrTrend>.1?"↑":e.snrTrend<-.1?"↓":"→",x=e.rssiTrend>.1?"#34D399":e.rssiTrend<-.1?"#EF4444":"#9CA3AF",p=e.snrTrend>.1?"#34D399":e.snrTrend<-.1?"#EF4444":"#9CA3AF",g=(e.timeSpanMs/36e5).toFixed(1),f=function(e){const t=e.rssiTrend<-.1,s=e.snrTrend<-.1,n=e.rssiTrend>.1,a=e.snrTrend>.1,i=e.rssiRange[1]-e.rssiRange[0],o=e.snrRange[1]-e.snrRange[0];return t&&s?{text:"Both RSSI and SNR declining — possible antenna degradation or increasing distance",color:"#EF4444"}:s&&!t?{text:"SNR declining while RSSI stable — likely RF interference or noise floor increase",color:"#F97316"}:t&&!s?{text:"RSSI declining while SNR stable — possible path obstruction or power change",color:"#F97316"}:n&&a?{text:"Signal improving — conditions favorable or antenna adjustment working",color:"#34D399"}:i>15||o>10?{text:"High signal variance — intermittent obstruction or multipath fading",color:"#FBBF24"}:{text:"Signal stable — no significant degradation detected",color:"#9CA3AF"}}(e);return n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center justify-between mb-1",children:[n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Signal Quality Over Time"}),n.jsx("div",{className:"text-fg-secondary text-[11px]",children:"Tracks RSSI (signal power) and SNR (signal-to-noise ratio) for zero-hop packets received directly from this neighbor. Reveals weather effects, interference, and antenna degradation."}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 font-mono text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Samples"}),n.jsx("span",{className:"text-fg-primary tabular-nums",children:e.totalSamples})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Time span"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[g,"h"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg RSSI"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg SNR"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"RSSI trend"}),n.jsxs("span",{className:"tabular-nums",style:{color:x},children:[e.rssiTrend>0?"+":"",e.rssiTrend.toFixed(3)," dBm/bucket"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"SNR trend"}),n.jsxs("span",{className:"tabular-nums",style:{color:p},children:[e.snrTrend>0?"+":"",e.snrTrend.toFixed(3)," dB/bucket"]})]})]}),n.jsxs("div",{className:"text-[10px] text-fg-muted italic",children:["Trend is linear regression slope across ",t.length," time buckets. ↑ = improving, ↓ = degrading, → = stable."]})]}),children:n.jsx("span",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Signal Timeline"})}),n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums",children:[e.totalSamples," samples · ",g,"h"]})]}),n.jsxs("svg",{viewBox:"0 0 200 36",className:"w-full h-9",preserveAspectRatio:"none",children:[n.jsx("polyline",{points:d,fill:"none",stroke:"#60A5FA",strokeWidth:"1.5",strokeLinejoin:"round",strokeLinecap:"round",opacity:"0.8"}),n.jsx("polyline",{points:u,fill:"none",stroke:"#34D399",strokeWidth:"1",strokeLinejoin:"round",strokeLinecap:"round",opacity:"0.5",strokeDasharray:"3 2"})]}),n.jsxs("div",{className:"flex items-center justify-between text-[9px] mt-0.5",children:[n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsxs("span",{className:"flex items-center gap-0.5",children:[n.jsx("span",{className:"w-2.5 h-[1.5px] bg-[#60A5FA] rounded-full inline-block"}),n.jsx("span",{className:"text-fg-muted",children:"RSSI"}),n.jsx("span",{className:"tabular-nums",style:{color:x},children:m})]}),n.jsxs("span",{className:"flex items-center gap-0.5",children:[n.jsx("span",{className:"w-2.5 h-[1px] bg-[#34D399] rounded-full inline-block opacity-50",style:{borderTop:"1px dashed #34D399"}}),n.jsx("span",{className:"text-fg-muted",children:"SNR"}),n.jsx("span",{className:"tabular-nums",style:{color:p},children:h})]})]}),n.jsxs("div",{className:"flex items-center gap-2 text-fg-muted tabular-nums",children:[n.jsxs("span",{children:[s.toFixed(0),"…",a.toFixed(0)," dBm"]}),n.jsxs("span",{children:[o.toFixed(0),"…",r.toFixed(0)," dB"]})]})]}),n.jsx("div",{className:"mt-1 text-[9px] leading-tight",style:{color:f.color},children:f.text})]})}),Kt=s.memo(function({edge:e,onClose:t}){const[a,i]=s.useState(null);return s.useEffect(()=>{if(!e.isZeroHop&&"zero-hop"!==e.edgeType)return void i(null);const t=R.getState().packets,s=R.getState().cachedLocalHash??void 0,n=function(e,t,s,n,a=24){const i=function(e,t,s,n){var a;const i=[],o=t.replace(/^0x/i,"").slice(0,2).toLowerCase();for(const r of e){if(r.transmitted)continue;if(null==r.rssi||null==r.snr)continue;if(0===r.rssi&&0===r.snr)continue;const e=(null==(a=r.src_hash)?void 0:a.replace(/^0x/i,""))??"";if(e.slice(0,2).toLowerCase()!==o&&e!==t.replace(/^0x/i,""))continue;const s=r.original_path??r.forwarded_path??[],l=c(s,n),u=(null==l?void 0:l.effectiveLength)??0,m=r.route??r.route_type;let h=!1;h=null!=m&&d(m)?u<=1:0===u,h&&i.push({timestamp:1e3*r.timestamp,rssi:r.rssi,snr:r.snr})}if(i.sort((e,t)=>e.timestamp-t.timestamp),i.length>0&&i[0].timestamp<4102444800)for(const r of i)r.timestamp*=1e3;return i}(e,t,0,n);if(i.length<3)return null;const o=function(e,t=24){if(0===e.length)return[];const s=e[0].timestamp,n=e[e.length-1].timestamp-s;if(n<=0)return[{timestamp:s,avgRssi:e.reduce((e,t)=>e+t.rssi,0)/e.length,avgSnr:e.reduce((e,t)=>e+t.snr,0)/e.length,minRssi:Math.min(...e.map(e=>e.rssi)),maxRssi:Math.max(...e.map(e=>e.rssi)),minSnr:Math.min(...e.map(e=>e.snr)),maxSnr:Math.max(...e.map(e=>e.snr)),count:e.length}];const a=n/t,i=[];for(let r=0;r0&&(r.avgRssi/=r.count,r.avgSnr/=r.count,o.push(r));return o}(i,a);if(o.length<2)return null;let r=0,l=0,u=1/0,m=-1/0,h=1/0,x=-1/0;for(const c of i)r+=c.rssi,l+=c.snr,u=Math.min(u,c.rssi),m=Math.max(m,c.rssi),h=Math.min(h,c.snr),x=Math.max(x,c.snr);const p=dt(o.map(e=>e.avgRssi)),g=dt(o.map(e=>e.avgSnr)),f=i[0].timestamp,v=i[i.length-1].timestamp;return{buckets:o,totalSamples:i.length,rssiRange:[u,m],snrRange:[h,x],avgRssi:r/i.length,avgSnr:l/i.length,rssiTrend:p,snrTrend:g,timeSpanMs:v-f}}(t,e.source,e.target,s);i(n)},[e.source,e.target,e.isZeroHop,e.edgeType]),n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx(be,{className:"size-3.5 text-fg-muted shrink-0"}),n.jsxs("span",{className:"text-sm font-semibold text-fg-primary truncate",children:[e.fromName??e.source.slice(0,6)," → ",e.toName??e.target.slice(0,6)]}),n.jsxs("div",{className:"flex gap-1 shrink-0",children:[n.jsx(C,{color:"zinc",compact:!0,children:Ot[e.edgeType]}),e.isBackbone&&n.jsx(C,{color:"emerald",compact:!0,children:"BONE"}),e.isLoopEdge&&n.jsx(C,{color:"indigo",compact:!0,children:"LOOP"}),e.isGhost&&n.jsx(C,{color:"zinc",compact:!0,children:"GHOST"})]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Average disambiguation confidence across all observations of this edge",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.confidence).toFixed(0),"%"]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Observations where both endpoints had high-confidence disambiguation",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Certain"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.certainCount.toLocaleString()})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Total packets observed traversing this edge",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Packets"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.packetCount.toLocaleString()})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Combined certainCount × confidence metric for edge ranking",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Strength"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.strength.toFixed(2)})]})]}),n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Bidirectional balance (min/max) — 0 = one-way traffic, 1 = perfectly balanced",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Symmetry"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.symmetryRatio.toFixed(2)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Dominant traffic flow direction between these nodes",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Direction"})}),n.jsx("div",{className:"text-fg-primary capitalize",children:e.dominantDirection})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Forward (A→B) vs reverse (B→A) observation counts",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Fwd / Rev"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.forwardCount," / ",e.reverseCount]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Routing method — broadcast flood vs unicast direct routing",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Flood / Direct"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.floodCount," / ",e.directCount]})]})]}),(null!=e.avgRssi||null!=e.avgSnr)&&n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),null!=e.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]})]}),e.linkBudget&&n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.linkBudget.distanceKm&&n.jsxs("div",{children:[n.jsx(k,{content:"Haversine distance between endpoint locations",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Distance"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.distanceKm.toFixed(2)," km"]})]}),null!=e.linkBudget.fsplDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Free Space Path Loss — theoretical signal attenuation over this distance at configured frequency",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"FSPL"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.fsplDb.toFixed(1)," dB"]})]}),null!=e.linkBudget.marginDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Link margin — observed RSSI minus receiver sensitivity. Positive = signal headroom above minimum.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Margin"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",style:{color:e.linkBudget.marginClass?st[e.linkBudget.marginClass]:void 0},children:[e.linkBudget.marginDb>0?"+":"",e.linkBudget.marginDb.toFixed(1)," dB"]})]}),null!=e.linkBudget.deviationDb&&n.jsxs("div",{children:[n.jsx(k,{content:"Deviation from theoretical FSPL — positive means better signal than free-space prediction",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"vs Theory"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.linkBudget.deviationDb>0?"+":"",e.linkBudget.deviationDb.toFixed(1)," dB"]})]})]}),a&&n.jsx(Wt,{timeline:a})]})]})}),Vt=s.memo(function({node:e,onClose:t,egoMetrics:a,onExpandEgo:i,neighbors:o,onSelectNeighbor:r,txDelayRec:l}){const[c,d]=s.useState(!1),[u,m]=s.useState(!1);return n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl max-h-[60vh] flex flex-col",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx("span",{className:"size-2 shrink-0 rounded-full",style:{backgroundColor:(L()?Et:At)[e.nodeClass]}}),n.jsx("code",{className:"text-sm font-semibold text-fg-primary shrink-0",children:e.prefix}),e.name&&n.jsx("span",{className:"text-sm text-fg-secondary truncate",children:e.name}),n.jsxs("div",{className:"flex gap-1 shrink-0",children:[e.isLocal&&n.jsx(C,{color:"yellow",compact:!0,children:"LOCAL"}),e.isHub&&n.jsx(C,{color:"violet",compact:!0,children:"HUB"}),e.isGateway&&n.jsx(C,{color:"sky",compact:!0,children:"GW"}),e.isBackbone&&n.jsx(C,{color:"emerald",compact:!0,children:"BONE"}),e.isMobile&&n.jsx(C,{color:"orange",compact:!0,children:"MOB"}),e.isZeroHop&&n.jsx(C,{color:"amber",compact:!0,children:"RF"}),e.isGhost&&n.jsx(C,{color:"zinc",compact:!0,children:"GHOST"}),e.isInLoop&&n.jsx(C,{color:"indigo",compact:!0,children:"LOOP"})]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsx(T,{copy:!0,size:"compact",truncate:[10,6],className:"w-full mb-3",children:e.hash}),n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Total connections (edges) to this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Degree"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.degree})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Inbound vs outbound edge count — indicates traffic directionality",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"In / Out"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.inDegree," / ",e.outDegree]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Betweenness centrality (0–1) — how often this node lies on shortest paths. High value = critical relay.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Between."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.betweenness.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Total packets observed involving this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Packets"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.packetCount.toLocaleString()})]})]}),n.jsxs("div",{className:"grid grid-cols-4 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Number of topology edges connected to this node",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Edges"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.edgeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Community cluster assignment from graph partitioning algorithm",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Community"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:["#",e.communityId]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Prefix disambiguation confidence — how certain the 2-char prefix→node mapping is (multi-factor scoring)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.prefixConfidence).toFixed(0),"%"]})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Recency level — active (<1h), recent (<6h), stale (<24h), inactive (>24h)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Activity"})}),n.jsx("div",{className:"text-fg-primary capitalize",children:e.activityLevel})]})]}),(null!=e.avgRssi||null!=e.avgSnr)&&n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[null!=e.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgRssi.toFixed(1)," dBm"]})]}),null!=e.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[e.avgSnr.toFixed(1)," dB"]})]})]}),a&&n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"grid grid-cols-3 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Number of direct 1-hop neighbors in the topology",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Ego Size"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.neighborCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Local clustering coefficient — how interconnected this node's neighbors are (0 = none, 1 = fully connected)",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Clustering"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.clusteringCoeff.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Average betweenness centrality of this node's direct neighbors",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Nbr Btw."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:a.avgNeighborBetweenness.toFixed(3)})]})]}),n.jsxs("div",{className:"grid grid-cols-3 gap-3 mt-2",children:[n.jsxs("div",{children:[n.jsx(k,{content:"Average disambiguation confidence across all connected edges",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Edge Conf."})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*a.avgEdgeConfidence).toFixed(0),"%"]})]}),null!=a.avgRssi&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Avg RSSI"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[a.avgRssi.toFixed(1)," dBm"]})]}),null!=a.avgSnr&&n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Avg SNR"}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[a.avgSnr.toFixed(1)," dB"]})]})]})]}),l&&!l.insufficientData&&n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[n.jsx(k,{content:"RF-grounded TX delay recommendation from centralized topology engine. Anchored to MeshCore firmware defaults with observer bias correction.",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase tracking-wide cursor-help",children:"TX Delay Recommendation"})}),n.jsxs("div",{className:"flex items-center gap-1",children:[l.networkRole&&n.jsx(C,{color:ye[l.networkRole],compact:!0,children:l.networkRole}),l.dataConfidence&&n.jsx(C,{color:je[l.dataConfidence],compact:!0,children:l.dataConfidence})]})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[n.jsxs("div",{children:[n.jsx(k,{content:`Flood TX delay factor (firmware default: ×${Ne})`,children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Flood"})}),n.jsx("div",{className:"text-fg-primary tabular-nums text-sys-amber",children:we(l.floodFactor)})]}),n.jsxs("div",{children:[n.jsx(k,{content:`Direct TX delay factor (firmware default: ×${Ce})`,children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Direct"})}),n.jsx("div",{className:"text-fg-primary tabular-nums text-sys-amber",children:we(l.directFactor)})]})]}),l.rationale&&n.jsx("div",{className:"mt-1 text-[9px] text-fg-muted leading-snug",children:l.rationale}),null!=l.observationSymmetry&&l.observationSymmetry<.6&&n.jsxs("div",{className:"mt-1 text-[9px] text-sys-amber/70 leading-snug",children:["⚠ Low observation symmetry (",(100*l.observationSymmetry).toFixed(0),"%) — recommendation damped toward firmware defaults"]}),n.jsxs("button",{onClick:async()=>{const e=`set txdelay ${l.floodFactor.toFixed(1)}\nset direct.txdelay ${l.directFactor.toFixed(1)}`;try{await navigator.clipboard.writeText(e)}catch{}m(!0),setTimeout(()=>m(!1),1500)},className:"mt-1.5 flex items-center gap-1 text-[9px] text-sys-blue hover:text-sys-blue/80 transition-base",children:[u?n.jsx(ge,{className:"w-3 h-3 text-sys-green"}):n.jsx(fe,{className:"w-3 h-3"}),u?"Copied!":"Copy CLI commands"]})]}),i&&n.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:n.jsxs("button",{onClick:i,className:"flex items-center gap-1.5 text-[10px] text-sys-blue hover:text-sys-blue/80 transition-base",children:[n.jsx(ve,{className:"w-3 h-3"}),"Expand 2-hop neighborhood"]})}),o&&o.length>0&&n.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("button",{onClick:()=>d(e=>!e),className:"flex items-center justify-between w-full text-[9px] text-fg-muted uppercase tracking-wide cursor-pointer hover:text-fg-secondary transition-base",children:[n.jsxs("span",{children:["Neighbors (",o.length,")"]}),n.jsx(ue,{className:"w-3 h-3 transition-transform "+(c?"rotate-180":"")})]}),c&&n.jsx("div",{className:"mt-1.5 max-h-32 overflow-y-auto space-y-0.5",children:o.map(e=>n.jsxs("button",{onClick:()=>null==r?void 0:r(e.hash),className:"w-full flex items-center gap-2 px-1.5 py-1 radius-badge hover-bg transition-base text-left group",children:[n.jsx("code",{className:"text-[10px] text-sys-blue shrink-0 tabular-nums",children:e.prefix}),n.jsx("span",{className:"text-[10px] text-fg-secondary truncate flex-1",children:e.name||"—"}),null!=e.avgSnr&&n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums shrink-0",children:[e.avgSnr.toFixed(0)," dB"]}),null!=e.avgRssi&&n.jsx("span",{className:"text-[9px] text-fg-muted tabular-nums shrink-0",children:e.avgRssi.toFixed(0)}),n.jsxs("span",{className:"text-[9px] text-fg-muted/60 tabular-nums shrink-0",children:[(100*e.edgeConfidence).toFixed(0),"%"]})]},e.hash))})]})]})]})}),_t=s.memo(function({metrics:e,onClose:t}){const s=Object.entries(e.communities).sort(([,e],[,t])=>t-e),a=Object.entries(e.nodeClasses).sort(([,e],[,t])=>t-e);return n.jsxs(W.div,{variants:$,initial:"hidden",animate:"visible",exit:"exit",className:"absolute inset-x-3 bottom-3 z-20 surface-elevated radius-inset shadow-xl",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 border-b border-edge-subtle/50",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx(Y,{className:"size-3.5 text-fg-muted shrink-0"}),n.jsx("span",{className:"text-sm font-semibold text-fg-primary",children:"Subgraph Analysis"}),n.jsxs(C,{color:"violet",compact:!0,children:[e.nodeCount," nodes"]})]}),n.jsx(F,{plain:!0,onClick:t,title:"Close",className:"shrink-0",children:n.jsx(U,{className:"size-4"})})]}),n.jsxs("div",{className:"p-3 font-mono text-[11px]",children:[n.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase",children:"Nodes"}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.nodeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Edges where both endpoints are within the lasso selection",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Internal Edges"})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.edgeCount})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Mean betweenness centrality of selected nodes",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Between."})}),n.jsx("div",{className:"text-fg-primary tabular-nums",children:e.avgBetweenness.toFixed(3)})]}),n.jsxs("div",{children:[n.jsx(k,{content:"Mean edge disambiguation confidence for internal edges",children:n.jsx("div",{className:"text-[9px] text-fg-muted uppercase cursor-help",children:"Avg Confidence"})}),n.jsxs("div",{className:"text-fg-primary tabular-nums",children:[(100*e.avgConfidence).toFixed(0),"%"]})]})]}),n.jsxs("div",{className:"grid grid-cols-2 gap-3 mt-2 pt-2 border-t border-edge-subtle/50",children:[n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase mb-1",children:"Communities"}),n.jsx("div",{className:"flex flex-wrap gap-1",children:s.map(([e,t])=>n.jsxs("span",{className:"text-fg-secondary",children:["#",e,"×",t]},e))})]}),n.jsxs("div",{children:[n.jsx("div",{className:"text-[9px] text-fg-muted uppercase mb-1",children:"Node Types"}),n.jsx("div",{className:"flex flex-wrap gap-1",children:a.map(([e,t])=>n.jsxs("span",{className:"text-fg-secondary capitalize",children:[e,"×",t]},e))})]})]}),e.nodeCount>1&&n.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle/50",children:n.jsxs("div",{className:"text-[9px] text-fg-muted flex items-center gap-1 flex-wrap",children:[n.jsx(k,{content:"Fraction of possible edges that exist — 2E / N(N-1)",children:n.jsxs("span",{className:"cursor-help",children:["Density: ",(2*e.edgeCount/(e.nodeCount*(e.nodeCount-1))*100).toFixed(1),"%"]})}),n.jsx("span",{children:"·"}),n.jsx(k,{content:"Mean connections per node — 2E / N",children:n.jsxs("span",{className:"cursor-help",children:["Avg Degree: ",(2*e.edgeCount/e.nodeCount).toFixed(1)]})}),null!=e.avgPathHealth&&n.jsxs(n.Fragment,{children:[n.jsx("span",{children:"·"}),n.jsx(k,{content:"Average health score of paths within the selection",children:n.jsxs("span",{className:"cursor-help",children:["Path Health: ",(100*e.avgPathHealth).toFixed(0),"%"]})})]})]})})]})]})});function Ut(){return n.jsxs("div",{className:"flex flex-col items-center justify-center gap-6 text-center px-8",children:[n.jsx("div",{className:"p-4 radius-pill bg-subtle-fill",children:n.jsx(pe,{className:"w-8 h-8 text-fg-muted"})}),n.jsxs("div",{className:"space-y-2",children:[n.jsx("h2",{className:"type-subheading text-fg-primary",children:"No Topology Data"}),n.jsx("p",{className:"type-body text-fg-muted max-w-sm",children:"The mesh topology will appear here once packets are received and processed."})]}),n.jsxs("div",{className:"flex items-center gap-2 type-data-xs text-fg-muted",children:[n.jsx(ie,{className:"w-4 h-4 animate-pulse"}),n.jsx("span",{children:"Waiting for mesh traffic..."})]})]})}const Xt=s.memo(function({label:e,value:t,onChange:a,min:i,max:o,step:r}){const[l,c]=s.useState(!1),[d,u]=s.useState(""),m=s.useRef(null),h=s.useCallback(()=>{const e=parseFloat(d);isNaN(e)||a(Math.min(o,Math.max(i,Math.round(e/r)*r))),c(!1)},[d,a,i,o,r]),x=s.useCallback(()=>{u(t.toFixed(2)),c(!0),setTimeout(()=>{var e;return null==(e=m.current)?void 0:e.select()},0)},[t]);return n.jsxs("div",{className:"space-y-1",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsx("span",{className:"text-[10px] text-fg-muted",children:e}),l?n.jsx("input",{ref:m,type:"number",value:d,onChange:e=>u(e.target.value),onBlur:h,onKeyDown:e=>{"Enter"===e.key&&h(),"Escape"===e.key&&c(!1)},min:i,max:o,step:r,className:"w-14 text-right text-[10px] text-fg-secondary tabular-nums bg-subtle-fill radius-badge px-1 py-0.5 border border-edge-subtle focus:outline-none focus:border-sys-blue"}):n.jsx("button",{onClick:x,className:"text-[10px] text-fg-secondary tabular-nums hover:text-sys-blue cursor-text transition-colors",title:"Click to type a value",children:t.toFixed(2)})]}),n.jsx("input",{type:"range",min:i,max:o,step:r,value:t,onChange:e=>a(parseFloat(e.target.value)),className:"w-full h-1 bg-subtle-fill rounded appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:bg-sys-blue [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:cursor-pointer"})]})}),Qt=s.memo(function({label:e,checked:t,onChange:s}){return n.jsxs(i,{className:"flex items-center justify-between",children:[n.jsx(o,{className:"text-[10px] text-fg-muted cursor-pointer select-none",children:e}),n.jsx(D,{enabled:t,onChange:s,size:"sm"})]})});function qt(){var e,t,i,o,l,c,d,N,D,L,F,R,H,B,P;M(yt);const E=u(),[$,T]=s.useState(!1),[I,G]=s.useState(!1),O=s.useRef(!1);s.useEffect(()=>{E&&!O.current&&(O.current=!0,G(!0))},[E]);const K=s.useCallback(()=>{G(!1),T(!0)},[]),_=m(),pe=function(e,t=1e3){const[n,a]=s.useState(e),i=s.useRef(Date.now()),o=s.useRef(null);return s.useEffect(()=>{const s=Date.now(),n=t-(s-i.current);return n<=0?(a(e),i.current=s):(o.current&&clearTimeout(o.current),o.current=setTimeout(()=>{a(e),i.current=Date.now()},n)),()=>{o.current&&clearTimeout(o.current)}},[e,t]),n}(h(),2e3),ge=x(),fe=p(),ve=g(),be=f(),ye=v(),je=b(),Ne=y(),we=Ne?Et:At,Ce=Ne?Ct:kt,ke=s.useMemo(()=>function(e){if("undefined"==typeof document)return e?w[950]:"#EFF0F1";const t=getComputedStyle(document.documentElement).getPropertyValue("--bg-body").trim();return t.startsWith("#")?t:e?w[950]:"#EFF0F1"}(Ne),[Ne]),Se=s.useMemo(()=>function(e){if("undefined"==typeof document)return e?w[400]:w[500];const t=getComputedStyle(document.documentElement).getPropertyValue("--text-secondary").trim();return t.startsWith("#")?t:e?w[400]:w[500]}(Ne),[Ne]),[De,Le]=s.useState(!0),[Fe,Re]=s.useState(null),[Me,He]=s.useState(null),[Be,Pe]=s.useState(!1),[Ee,Ae]=s.useState(""),[ze,$e]=s.useState(!1),[Te,Ie]=s.useState(!1),[Oe,Ze]=s.useState("simulation"),[Ke,Ve]=s.useState(!0),[_e,Ue]=s.useState(!1),[qe,Je]=s.useState(!0),[tt,it]=s.useState(!1),[ot,rt]=s.useState(!1),[ct,dt]=s.useState(new Set),[ut,mt]=s.useState(!1),[ht,pt]=s.useState("spectral"),[gt,ft]=s.useState(1),[vt,St]=s.useState(1),[$t,Ot]=s.useState(!1),[Wt,qt]=s.useState(null),[Jt,Yt]=s.useState(!1),[es,ts]=s.useState(!1),[ss,ns]=s.useState(null),[as,is]=s.useState(null),[os,rs]=s.useState(null),[ls,cs]=s.useState(null),[ds,us]=s.useState(null),ms=j(),[hs,xs]=s.useState(!1),[ps,gs]=s.useState([]),[fs,vs]=s.useState(0),[bs,ys]=s.useState(null),js=s.useRef(new lt),Ns=s.useRef(null),ws=s.useRef(null),[Cs,ks]=s.useState(null),[Ss,Ds]=s.useState(null),[Ls,Fs]=s.useState({}),[Rs,Ms]=s.useState({simulationDecay:2e4,simulationGravity:.05,simulationCenter:.05,simulationRepulsion:5,simulationRepulsionTheta:.4,simulationLinkSpring:.05,simulationLinkDistance:78,simulationFriction:.72,simulationRepulsionFromMouse:0,pointSizeScale:.4,pointOpacity:1,pointGreyoutOpacity:.1,linkWidthScale:.06,linkOpacity:.95,linkGreyoutOpacity:.1,curvedLinks:Ft,curvedLinkWeight:.8,linkDefaultArrows:Rt,linkArrowsSizeScale:1.7,scalePointsOnZoom:Mt,scaleLinksOnZoom:Ht,renderLinks:Bt,renderHoveredPointRing:Pt,spaceSize:4096}),Hs=s.useCallback((e,t)=>{Ms(s=>({...s,[e]:t}))},[]),Bs=s.useCallback(()=>{Ms({simulationDecay:2e4,simulationGravity:.05,simulationCenter:.05,simulationRepulsion:5,simulationRepulsionTheta:.4,simulationLinkSpring:.05,simulationLinkDistance:78,simulationFriction:.72,simulationRepulsionFromMouse:0,pointSizeScale:.4,pointOpacity:1,pointGreyoutOpacity:.1,linkWidthScale:.06,linkOpacity:.95,linkGreyoutOpacity:.1,curvedLinks:Ft,curvedLinkWeight:.8,linkDefaultArrows:Rt,linkArrowsSizeScale:1.7,scalePointsOnZoom:Mt,scaleLinksOnZoom:Ht,renderLinks:Bt,renderHoveredPointRing:Pt,spaceSize:4096})},[]);s.useEffect(()=>()=>{var e;try{null==(e=ws.current)||e.destroy()}catch{}ws.current=null},[]),s.useEffect(()=>{const e=e=>{var t,s;if(!(e.target instanceof HTMLInputElement||e.target instanceof HTMLSelectElement))switch(e.key.toLowerCase()){case"f":e.metaKey||e.ctrlKey||(e.preventDefault(),null==(t=ws.current)||t.fitView(jt));break;case"escape":ze?($e(!1),Ae("")):Fe&&(Re(null),null==(s=ws.current)||s.unselectAllPoints());break;case"/":ze||(e.preventDefault(),$e(!0),setTimeout(()=>{var e;return null==(e=Ns.current)?void 0:e.focus()},50));break;case" ":e.preventDefault(),ws.current&&(De?ws.current.pause():ws.current.start(),Le(e=>!e));break;case"l":Ve(e=>!e)}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[ze,Fe,De]);const Ps=s.useMemo(()=>new Set((null==_?void 0:_.backboneEdges)??[]),[null==_?void 0:_.backboneEdges]),Es=s.useMemo(()=>({resolution:gt,kWeight:vt}),[gt,vt]),As=s.useMemo(()=>{if("louvain"!==ht)return null;const e=null==_?void 0:_.edges;return!e||0===e.length||!pe||pe.size<3?null:We(e,Array.from(pe.keys()),Es).communities},[ht,null==_?void 0:_.edges,pe,Es]),zs=s.useMemo(()=>{var e;if(!pe||0===pe.size||!$)return[];const t=[],s=(null==je?void 0:je.node_name)??(null==(e=null==je?void 0:je.config)?void 0:e.node_name)??null,n=Ne?"#171717":"#EFF0F1";let a=1;for(const i of pe.values())i.degree>a&&(a=i.degree);for(const i of pe.values()){const e=i,o=e.degree>0?Math.log10(e.degree+1)/Math.log10(a+1):0,r=5+23*Math.min(1,o),l=6*e.betweenness,c=e.isLocal?28:Math.min(34,r+l),d=(null==As?void 0:As.get(e.hash))??e.communityId,u=ut&&d>=0?Ce[d%Ce.length]:we[e.nodeClass],m=wt[e.activityLevel]??1,h=e.isLocal?we.local:m<1?Tt(u,n,m):u,x=e.isLocal?s??e.name:e.name;t.push({id:e.hash,label:x?`${e.prefix} ${x}`:e.prefix,color:h,size:c,nodeClass:e.nodeClass,name:x,prefix:e.prefix,packetCount:e.packetCount,isLocal:e.isLocal,isHub:e.isHub,isGateway:e.isGateway,isBackbone:e.isBackbone,isMobile:e.isMobile,isZeroHop:e.isZeroHop,isGhost:e.isGhost,degree:e.degree,betweenness:e.betweenness,communityId:(null==As?void 0:As.get(e.hash))??e.communityId,activityLevel:e.activityLevel,prefixConfidence:e.prefixConfidence,hasCollision:e.hasCollision,inDegree:e.inDegree,outDegree:e.outDegree,isInLoop:e.isInLoop,avgRssi:e.avgRssi,avgSnr:e.avgSnr})}for(const i of ge){const e=`ghost-${i.prefix}`;if(t.some(t=>t.id===e))continue;const s=Tt(we.ghost,n,.6);t.push({id:e,label:`? ${i.prefix.toUpperCase()}`,color:s,size:6,nodeClass:"ghost",name:null,prefix:i.prefix,packetCount:i.observationCount,isLocal:!1,isHub:!1,isGateway:!1,isBackbone:!1,isMobile:!1,isZeroHop:!1,isGhost:!0,degree:i.commonNeighbors.size,betweenness:0,communityId:-1,activityLevel:"active",prefixConfidence:i.confidence,hasCollision:!1,inDegree:0,outDegree:0,isInLoop:!1,avgRssi:null,avgSnr:null})}return t},[pe,$,null==je?void 0:je.node_name,null==(e=null==je?void 0:je.config)?void 0:e.node_name,we,Ne,ge,Ce,ut,ht,As]),$s=s.useMemo(()=>new Set(zs.map(e=>e.id)),[zs]),Ts=s.useMemo(()=>{const e=new Map;if(!pe)return e;for(const t of pe.values())e.set(t.hash,t.name);return e},[pe]),Is=s.useMemo(()=>{const e=(null==_?void 0:_.edges)??[];if(!e.length||!$)return[];const t=[],s=(null==_?void 0:_.edgeBetweenness)??new Map;for(const a of e){if(!$s.has(a.fromHash)||!$s.has(a.toHash))continue;const e=It(a,Ps),n=Gt(e,a.avgConfidence,Ne),i=s.get(a.key)??0,o=i>0?.5+4*i:.5+2*Math.min(1,a.certainCount/50);t.push({source:a.fromHash,target:a.toHash,color:n,width:o,key:a.key,packetCount:a.packetCount,certainCount:a.certainCount,confidence:a.avgConfidence,symmetryRatio:a.symmetryRatio,dominantDirection:a.dominantDirection,isBackbone:Ps.has(a.key),isLoopEdge:a.isLoopEdge??!1,isDirectPath:a.isDirectPathEdge,isZeroHop:a.isZeroHop??!1,isGhost:!1,forwardCount:a.forwardCount,reverseCount:a.reverseCount,floodCount:a.floodCount,directCount:a.directCount,avgRssi:a.avgRssi??null,avgSnr:a.avgSnr??null,strength:a.strength,fromName:Ts.get(a.fromHash)??null,toName:Ts.get(a.toHash)??null,edgeType:e})}const n=Ne?Dt:Lt;for(const a of ge){const e=`ghost-${a.prefix}`;if($s.has(e))for(const s of a.commonNeighbors)$s.has(s)&&t.push({source:e,target:s,color:n.ghost,width:.4,key:`ghost-${a.prefix}-${s}`,packetCount:a.observationCount,certainCount:0,confidence:a.confidence,symmetryRatio:0,dominantDirection:"balanced",isBackbone:!1,isLoopEdge:!1,isDirectPath:!1,isZeroHop:!1,isGhost:!0,forwardCount:0,reverseCount:0,floodCount:0,directCount:0,avgRssi:null,avgSnr:null,strength:a.confidence,fromName:null,toName:Ts.get(s)??null,edgeType:"ghost"})}return t},[null==_?void 0:_.edges,null==_?void 0:_.edgeBetweenness,$,$s,Ne,Ps,Ts,ge]),Gs=null==(i=null==(t=null==je?void 0:je.config)?void 0:t.radio)?void 0:i.frequency,Os=null==(l=null==(o=null==je?void 0:je.config)?void 0:o.radio)?void 0:l.bandwidth,Zs=null==(d=null==(c=null==je?void 0:je.config)?void 0:c.radio)?void 0:d.spreading_factor,Ws=null==(D=null==(N=null==je?void 0:je.config)?void 0:N.radio)?void 0:D.tx_power,Ks=null==(F=null==(L=null==je?void 0:je.config)?void 0:L.radio)?void 0:F.coding_rate,Vs=s.useMemo(()=>{if(!_||!es)return null;const e={frequency:Gs,bandwidth:null!=os?1e3*os:Os,spreading_factor:as??Zs,tx_power:ss??Ws,coding_rate:ls??Ks},t={};return null!=ds&&(t.sensitivityOverrideDbm=ds),null!=ms&&(t.observedNoiseFloorDbm=ms),function(e,t,s){const n=[],a=e.nodeMetrics,i=new Set,o=t.tx_power??22;for(const r of e.edges){if(!r.isZeroHop)continue;const e=a.get(r.fromHash),o=a.get(r.toHash);n.push(Ye(r,e,o,t,s)),i.add(r.key)}for(const r of e.edges){if(i.has(r.key))continue;if(!r.traceQuality)continue;const e=et(r,a.get(r.fromHash),a.get(r.toHash),t,o,s);e&&(n.push(e),i.add(r.key))}return n}(_,e,t)},[_,es,Gs,Os,Zs,Ws,Ks,ss,as,os,ls,ds,ms]),_s=s.useMemo(()=>{if(!Vs)return null;const e=new Map;for(const t of Vs)e.set(t.edgeKey,t);return e},[Vs]),Us=s.useMemo(()=>Vs&&0!==Vs.length?function(e){const t={"anomalous-good":0,better:0,expected:0,worse:0,"anomalous-bad":0},s={excellent:0,good:0,fair:0,marginal:0,critical:0};let n=0,a=0,i=null,o=null,r=0,l=0;for(const c of e)c.hasData&&(null!=c.marginDb&&(n+=c.marginDb,a++,(!i||c.marginDb<(i.marginDb??1/0))&&(i=c),(!o||c.marginDb>(o.marginDb??-1/0))&&(o=c)),c.marginClass&&s[c.marginClass]++,null!=c.deviationDb&&c.deviationClass?(t[c.deviationClass]++,l++):r++);return{totalEdges:e.length,analyzedEdges:l,rssiOnlyEdges:r,avgMarginDb:a>0?n/a:null,worstMargin:i,bestMargin:o,deviationCounts:t,marginCounts:s,anomalousCount:t["anomalous-good"]+t["anomalous-bad"]}}(Vs):null,[Vs]),Xs=s.useMemo(()=>{if(!es||!_s)return Is;const e=Ne?"#303038":"#D0D0D8";return Is.map(t=>{const s=_s.get(t.key);return s&&s.hasData?{...t,color:nt(s,"margin"),width:at(s),linkBudget:s}:{...t,color:e,width:.3}})},[Is,es,_s,Ne]),Qs=s.useMemo(()=>0===ct.size?zs:zs.filter(e=>!ct.has(e.nodeClass)),[zs,ct]),qs=s.useMemo(()=>{if(0===ct.size)return Xs;const e=new Set(Qs.map(e=>e.id));return Xs.filter(t=>e.has(t.source)&&e.has(t.target))},[Xs,Qs,ct]),Js=s.useRef([]);s.useEffect(()=>{Js.current=qs},[qs]);const Ys=s.useMemo(()=>{const e=new Map;for(const t of Is)e.set(t.source,(e.get(t.source)??0)+1),e.set(t.target,(e.get(t.target)??0)+1);return e},[Is]),en=s.useMemo(()=>{const e=new Map;for(const t of zs)e.set(t.id,t);return e},[zs]);s.useEffect(()=>{if(0===Qs.length)return ks(null),Ds(null),void Fs({});let e=!1;const t=setTimeout(async()=>{try{const t=Qs.map(e=>({id:e.id,label:e.label,color:e.color,size:e.size,communityId:String(e.communityId)})),s=qs.map(e=>({source:e.source,target:e.target,color:e.color,width:e.width})),n={points:{pointIdBy:"id",pointColorBy:"color",pointColorStrategy:"direct",pointDefaultColor:Ne?"#9CA3AF":"#374151",pointLabelBy:"label",pointSizeBy:"size",pointSizeStrategy:"direct",pointDefaultSize:8,pointSizeScale:1,pointGreyoutOpacity:.3,pointIncludeColumns:["communityId"]},links:{linkSourceBy:"source",linkTargetsBy:["target"],linkColorBy:"color",linkColorStrategy:"direct",linkDefaultColor:Ne?"#6B7280":"#9CA3AF",linkWidthBy:"width",linkWidthStrategy:"direct",linkDefaultWidth:1,linkWidthScale:1,linkGreyoutOpacity:.1}},a=await r(n,t,s);if(e||!a)return;a.points,a.links,a.cosmographConfig,ks(a.points??null),Ds(a.links??null),Fs(a.cosmographConfig??{})}catch(t){console.error("[MeshGraph] Data preparation failed:",t)}},100);return()=>{e=!0,clearTimeout(t)}},[Qs,qs,Ne]);const tn=s.useCallback(e=>{e&&(ws.current=e,e.start(),setTimeout(()=>{e.fitView(jt)},1500))},[]),sn=s.useCallback(()=>{var e;null==(e=ws.current)||e.fitView(jt)},[]),nn=s.useCallback(()=>{const e=ws.current;e&&(De?e.pause():e.start(),Le(!De))},[De]),an=s.useCallback(async e=>{const t=ws.current,s=en.get(e);if(s){if(t)try{const s=await t.getPointIndicesByIds([e]);s&&s.length>0&&void 0!==s[0]&&(t.zoomToPoint(s[0],400,2.5),t.selectPoint(s[0],!1,!0))}catch{}He(null),Re({hash:e,name:s.name,prefix:s.prefix,nodeClass:s.nodeClass,packetCount:s.packetCount,edgeCount:Ys.get(e)??0,degree:s.degree,betweenness:s.betweenness,communityId:s.communityId,isLocal:s.isLocal,isHub:s.isHub,isGateway:s.isGateway,isBackbone:s.isBackbone,isMobile:s.isMobile,isZeroHop:s.isZeroHop,isGhost:s.isGhost,isInLoop:s.isInLoop,activityLevel:s.activityLevel,prefixConfidence:s.prefixConfidence,hasCollision:s.hasCollision,inDegree:s.inDegree,outDegree:s.outDegree,avgRssi:s.avgRssi,avgSnr:s.avgSnr})}},[en,Ys]),on=s.useRef(null);s.useEffect(()=>{on.current=_s},[_s]);const rn=s.useCallback(e=>{var t;if(void 0===e)return void He(null);const s=Js.current[e];if(!s)return;const n=null==(t=on.current)?void 0:t.get(s.key);He(n&&!s.linkBudget?{...s,linkBudget:n}:s),Re(null)},[]),ln=s.useCallback(async(e,t,s)=>{var n;if(void 0===e)return Re(null),qt(null),void(null==(n=ws.current)||n.unselectAllPoints());He(null);const a=ws.current;if(a)try{const t=await a.getPointIdsByIndices([e]);if(!t||0===t.length)return;const s=t[0],n=en.get(s);if(!n)return;a.selectPoint(e,!1,!0),Re({hash:s,name:n.name,prefix:n.prefix,nodeClass:n.nodeClass,packetCount:n.packetCount,edgeCount:Ys.get(s)??0,degree:n.degree,betweenness:n.betweenness,communityId:n.communityId,isLocal:n.isLocal,isHub:n.isHub,isGateway:n.isGateway,isBackbone:n.isBackbone,isMobile:n.isMobile,isZeroHop:n.isZeroHop,isGhost:n.isGhost,isInLoop:n.isInLoop,activityLevel:n.activityLevel,prefixConfidence:n.prefixConfidence,hasCollision:n.hasCollision,inDegree:n.inDegree,outDegree:n.outDegree,avgRssi:n.avgRssi,avgSnr:n.avgSnr})}catch{}},[en,Ys]),cn=s.useMemo(()=>{if(!ze||!Ee.trim())return[];const e=Ee.toLowerCase();return zs.filter(t=>{var s;return t.prefix.toLowerCase().includes(e)||(null==(s=t.name)?void 0:s.toLowerCase().includes(e))||t.id.toLowerCase().includes(e)}).slice(0,8)},[zs,Ee,ze]),dn=s.useCallback(e=>{$e(!1),Ae(""),an(e.id)},[an]),un=s.useCallback(()=>{Pe(e=>!e)},[]),mn=s.useCallback(e=>{dt(t=>{const s=new Set(t);return s.has(e)?s.delete(e):s.add(e),s})},[]),hn=s.useCallback(()=>{mt(e=>{const t=!e,s=ws.current;return s&&s.start(.5),t})},[]),xn=s.useCallback(()=>{Ot(e=>{const t=!e,s=ws.current;return s?(t?s.activatePolygonalSelection():(s.deactivatePolygonalSelection(),qt(null),s.unselectAllPoints()),t):t})},[]),pn=s.useCallback(async()=>{const e=ws.current;if(!e)return;await new Promise(e=>setTimeout(e,80));const t=e.getSelectedPointIndices();if(!t||0===t.length)return void qt(null);const s=await e.getPointIdsByIndices(t);if(!s||0===s.length)return void qt(null);const n=new Set(s);let a=0,i=0;for(const m of Js.current)n.has(m.source)&&n.has(m.target)&&(a++,i+=m.confidence);let o=0;const r={},l={};for(const m of s){const e=en.get(m);e&&(o+=e.betweenness,r[e.communityId]=(r[e.communityId]??0)+1,l[e.nodeClass]=(l[e.nodeClass]??0)+1)}const c=new Set;for(const m of s){const e=en.get(m);e&&c.add(e.prefix.toLowerCase())}let d=0,u=0;for(const m of be)if(m.hops.length>=2){const e=m.hops[0].toLowerCase(),t=m.hops[m.hops.length-1].toLowerCase();c.has(e)&&c.has(t)&&(d+=m.healthScore,u++)}qt({nodeCount:s.length,edgeCount:a,avgBetweenness:s.length>0?o/s.length:0,avgConfidence:a>0?i/a:0,avgPathHealth:u>0?d/u:null,communities:r,nodeClasses:l}),Re(null),He(null)},[en,be]),gn=s.useCallback(()=>{var e;qt(null),null==(e=ws.current)||e.unselectAllPoints()},[]),fn=s.useMemo(()=>{var e;if(!Fe)return null;const t=Fe.hash,s=new Set;for(const h of qs)h.source===t?s.add(h.target):h.target===t&&s.add(h.source);if(0===s.size)return{clusteringCoeff:0,avgNeighborBetweenness:0,neighborCount:0,avgEdgeConfidence:0,avgRssi:null,avgSnr:null};let n=0;for(const h of qs)s.has(h.source)&&s.has(h.target)&&n++;const a=s.size,i=a>1?2*n/(a*(a-1)):0;let o=0;for(const h of s)o+=(null==(e=en.get(h))?void 0:e.betweenness)??0;let r=0,l=0,c=0,d=0,u=0,m=0;for(const h of qs)h.source!==t&&h.target!==t||(r+=h.confidence,l++,null!=h.avgRssi&&(c+=h.avgRssi,d++),null!=h.avgSnr&&(u+=h.avgSnr,m++));return{clusteringCoeff:Math.min(1,i),avgNeighborBetweenness:o/a,neighborCount:a,avgEdgeConfidence:l>0?r/l:0,avgRssi:d>0?c/d:null,avgSnr:m>0?u/m:null}},[Fe,qs,en]),vn=s.useMemo(()=>Fe&&ye?ye.get(Fe.hash)??null:null,[Fe,ye]),bn=s.useMemo(()=>{if(!Fe)return[];const e=Fe.hash,t=[],s=new Set;for(const n of qs){let a=null;if(n.source===e?a=n.target:n.target===e&&(a=n.source),!a||s.has(a))continue;s.add(a);const i=en.get(a);t.push({hash:a,prefix:(null==i?void 0:i.prefix)??a.slice(2,4).toUpperCase(),name:(null==i?void 0:i.name)??null,edgeConfidence:n.confidence,edgeType:n.edgeType,avgRssi:n.avgRssi,avgSnr:n.avgSnr})}return t.sort((e,t)=>t.edgeConfidence-e.edgeConfidence),t},[Fe,qs,en]),yn=s.useCallback(async()=>{const e=ws.current;if(!e||!Fe)return;const t=await e.getPointIndicesByIds([Fe.hash]);if(!t||void 0===t[0])return;const s=t[0],n=e.getConnectedPointIndices(s)??[],a=new Set([s,...n]);for(const o of n){const t=e.getConnectedPointIndices(o)??[];for(const e of t)a.add(e)}const i=Array.from(a);e.selectPoints(i),e.fitViewByIndices(i,jt,.15)},[Fe]);s.useEffect(()=>{if(!$t)return;const e=e=>{var t,s;"Escape"===e.key&&(Ot(!1),null==(t=ws.current)||t.deactivatePolygonalSelection(),qt(null),null==(s=ws.current)||s.unselectAllPoints())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[$t]);const jn=s.useCallback((e,t)=>{_&&(function(e,t){!function(e){const t=new Blob([e.content],{type:e.mimeType}),s=URL.createObjectURL(t),n=document.createElement("a");n.href=s,n.download=e.filename,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(s)}(Ge(e,t))}(_,{format:e,dataset:t}),Yt(!1))},[_]),Nn=s.useMemo(()=>{if(!_||!be.length)return null;const e=_.edges??[];return 0===e.length?null:function(e,t,s=-137){const n=new Map;for(const o of t)n.set(o.key,o);const a=t.filter(e=>null!=e.avgRssi).length,i=[];for(const o of e){const e=xt(o,n,s);e&&i.push(e)}return i.sort((e,t)=>t.riskScore-e.riskScore),{atRiskPaths:i,criticalCount:i.filter(e=>"critical"===e.riskLevel).length,highCount:i.filter(e=>"high"===e.riskLevel).length,moderateCount:i.filter(e=>"moderate"===e.riskLevel).length,edgesAnalyzed:t.length,edgesWithSignal:a}}(be,e)},[_,be]),wn=s.useMemo(()=>{const e=null==_?void 0:_.edges;if(!e||0===e.length||!pe||pe.size<3)return null;const t=Array.from(pe.keys());return A(e,t)},[null==_?void 0:_.edges,pe]),Cn=s.useMemo(()=>{if("louvain"!==ht)return null;const e=null==_?void 0:_.edges;return!e||0===e.length||!pe||pe.size<3?null:We(e,Array.from(pe.keys()),Es)},[ht,null==_?void 0:_.edges,pe,Es]);s.useEffect(()=>{if(!_)return;const e=new Map;for(const[s,n]of _.nodeMetrics)e.set(s,n.name);const t=js.current.update(_,e);t.totalCount>0&&(gs(js.current.getLog()),vs(e=>e+t.totalCount))},[_]);const kn=s.useCallback(()=>{vs(0),xs(e=>!e)},[]),Sn=s.useMemo(()=>function(e,t){if(null==e)return null;const s=Math.max(0,e),n=s>0?(Math.log10(s)+4)/4.5:0,a=Math.round(Math.max(0,Math.min(100,100*n)));let i,o;a<10?(i="critical",o="Partition risk"):a<30?(i="poor",o="Weak connectivity"):a<55?(i="fair",o="Moderate resilience"):a<80?(i="good",o="Well connected"):(i="excellent",o="Highly resilient");const[r,l]=Nt[i];return{score:a,grade:i,label:o,color:t?r:l}}(wn,Ne),[wn,Ne]),Dn=n.jsxs("div",{className:"absolute top-0 left-0 right-0 z-20 px-4 py-3 pointer-events-none flex items-start justify-between",children:[n.jsxs("h1",{className:"type-title text-fg-primary flex items-center gap-2 sm:gap-3 pointer-events-auto",children:[n.jsx(X,{className:"w-5 h-5 sm:w-6 sm:h-6 text-icon-page-title"}),n.jsx("span",{children:"MeshGraph"}),n.jsx(C,{color:"violet",compact:!0,children:"Analytics"})]}),Sn&&n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-2",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Mesh Resilience Score"}),n.jsx("div",{className:"text-fg-secondary",children:"Derived from the Fiedler eigenvalue (λ₂) — the second-smallest eigenvalue of the graph Laplacian. Measures how well-connected the mesh is and how resistant it is to partitioning."}),n.jsxs("div",{className:"space-y-0.5 font-mono text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Raw λ₂"}),n.jsx("span",{className:"text-fg-primary tabular-nums",children:(null==wn?void 0:wn.toFixed(6))??"—"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Score"}),n.jsxs("span",{className:"tabular-nums",style:{color:Sn.color},children:[Sn.score,"/100"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Grade"}),n.jsx("span",{className:"capitalize",style:{color:Sn.color},children:Sn.grade})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Grade thresholds"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.excellent[0]},children:"Excellent"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"80-100 (λ₂ > 0.3)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.good[0]},children:"Good"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"55-79 (λ₂ 0.03-0.3)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.fair[0]},children:"Fair"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"30-54 (λ₂ 0.003-0.03)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.poor[0]},children:"Poor"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"10-29 (λ₂ 0.0001-0.003)"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{style:{color:Nt.critical[0]},children:"Critical"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"<10 (λ₂ ≈ 0)"})]})]}),n.jsx("div",{className:"text-[10px] text-fg-muted italic",children:"Near-zero λ₂ = one bridge away from network partition. Log-scale mapping: small λ₂ changes at low values have outsized impact."})]}),children:n.jsxs("div",{className:"pointer-events-auto surface-control radius-inner px-3 py-1.5 flex items-center gap-2 cursor-help",children:[n.jsxs("div",{className:"flex items-baseline gap-1.5",children:[n.jsx("span",{className:"text-[10px] text-fg-muted uppercase tracking-wider",children:"Resilience"}),n.jsx("span",{className:"text-lg font-semibold tabular-nums leading-none",style:{color:Sn.color},children:Sn.score})]}),n.jsx("div",{className:"w-12 h-1.5 rounded-full bg-subtle-fill overflow-hidden",children:n.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${Sn.score}%`,backgroundColor:Sn.color}})})]})})]}),Ln=(e,t=!1)=>{const s="flex flex-col items-center gap-0.5 px-1.5 py-1 radius-inner transition-all duration-100 active:scale-95";return e&&t?`${s} bg-status-warning/15 text-status-warning shadow-inner`:e?`${s} bg-sys-blue/20 text-sys-blue shadow-inner`:`${s} hover:bg-white/5 hover:scale-105 text-fg-secondary`},Fn=n.jsx("div",{className:"w-px h-6 bg-border-subtle/40 mx-0.5 shrink-0"}),Rn=n.jsxs("div",{className:"absolute top-12 right-3 z-10 flex items-center gap-0.5 surface-control radius-inner px-1.5 py-1",children:[n.jsx(k,{content:"Visible nodes / edges in the graph",children:n.jsxs("span",{className:"text-[9px] text-fg-muted tabular-nums mr-1.5 leading-none cursor-help",children:[Qs.length,n.jsx("br",{}),qs.length]})}),Fn,n.jsx(k,{content:Ke?"Hide labels (L)":"Show labels (L)",children:n.jsxs("button",{onClick:()=>Ve(e=>!e),className:Ln(!Ke,!0),children:[Ke?n.jsx(Q,{className:"w-3.5 h-3.5"}):n.jsx(q,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Lbl"})]})}),n.jsx(k,{content:ut?"Disable clustering":"Community clustering",children:n.jsxs("button",{onClick:hn,className:Ln(ut),children:[n.jsx(J,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Grp"})]})}),n.jsx(k,{content:$t?"Exit lasso (Esc)":"Lasso selection",children:n.jsxs("button",{onClick:xn,className:Ln($t,!0),children:[n.jsx(Y,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Sel"})]})}),Fn,n.jsx(k,{content:"Legend",children:n.jsxs("button",{onClick:()=>Ue(e=>!e),className:Ln(_e),children:[n.jsx(ee,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Map"})]})}),n.jsx(k,{content:"Search (/)",children:n.jsxs("button",{onClick:()=>{$e(!0),setTimeout(()=>{var e;return null==(e=Ns.current)?void 0:e.focus()},50)},className:Ln(ze),children:[n.jsx(te,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Fnd"})]})}),Fn,n.jsx(k,{content:De?"Pause (Space)":"Play (Space)",children:n.jsxs("button",{onClick:nn,className:Ln(!De),children:[De?n.jsx(se,{className:"w-3.5 h-3.5 text-sys-green"}):n.jsx(ne,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:De?"Run":"Stop"})]})}),n.jsx(k,{content:"Fit view (F)",children:n.jsxs("button",{onClick:sn,className:Ln(!1),children:[n.jsx(ae,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Fit"})]})}),Fn,n.jsx(k,{content:es?"Disable link budget":"Link budget overlay",children:n.jsxs("button",{onClick:()=>ts(e=>!e),className:Ln(es),children:[n.jsx(ie,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"RF"})]})}),n.jsx(k,{content:"Anomaly log",children:n.jsxs("button",{onClick:kn,className:`relative ${Ln(hs,!0)}`,children:[n.jsx(oe,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Alert"}),fs>0&&n.jsx("span",{className:"absolute -top-1 -right-0.5 w-3 h-3 rounded-full bg-status-danger text-[7px] font-bold text-white flex items-center justify-center",children:fs>9?"9+":fs})]})}),n.jsx(k,{content:"Export topology",children:n.jsxs("button",{onClick:()=>Yt(e=>!e),className:Ln(Jt),children:[n.jsx(re,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Exp"})]})}),n.jsx(k,{content:"Settings",children:n.jsxs("button",{onClick:()=>Ie(e=>!e),className:Ln(Te),children:[n.jsx(le,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Cfg"})]})}),Fn,n.jsx(k,{content:Be?"Exit fullscreen":"Fullscreen",children:n.jsxs("button",{onClick:un,className:Ln(Be),children:[Be?n.jsx(ce,{className:"w-3.5 h-3.5"}):n.jsx(V,{className:"w-3.5 h-3.5"}),n.jsx("span",{className:"text-[7px] uppercase tracking-wider leading-none",children:"Max"})]})})]}),Mn=n.jsxs(bt,{id:"settings",title:"Graph Settings",icon:n.jsx(le,{}),open:Te,onClose:()=>Ie(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-308:600,y:60},defaultSize:{width:288,height:420},minSize:{width:260,height:200},maxSize:{width:400,height:600},headerActions:n.jsx(k,{content:"Reset to defaults",children:n.jsx("button",{onClick:Bs,className:"p-0.5 radius-badge hover-bg transition-base",children:n.jsx(de,{className:"w-2.5 h-2.5 text-fg-muted"})})}),children:[n.jsx("div",{className:"flex border-b border-edge-subtle",children:["simulation","points","links","rendering"].map(e=>n.jsx("button",{onClick:()=>Ze(e),className:"flex-1 px-2 py-1.5 text-[10px] font-medium capitalize transition-colors "+(Oe===e?"text-sys-blue border-b-2 border-sys-blue":"text-fg-muted hover:text-fg-secondary"),children:e},e))}),n.jsxs("div",{className:"p-3 space-y-3",children:["simulation"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Gravity",value:Rs.simulationGravity,onChange:e=>Hs("simulationGravity",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Repulsion",value:Rs.simulationRepulsion,onChange:e=>Hs("simulationRepulsion",e),min:0,max:5,step:.1}),n.jsx(Xt,{label:"Link Spring",value:Rs.simulationLinkSpring,onChange:e=>Hs("simulationLinkSpring",e),min:0,max:2,step:.05}),n.jsx(Xt,{label:"Link Distance",value:Rs.simulationLinkDistance,onChange:e=>Hs("simulationLinkDistance",e),min:1,max:100,step:1}),n.jsx(Xt,{label:"Friction",value:Rs.simulationFriction,onChange:e=>Hs("simulationFriction",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Center Force",value:Rs.simulationCenter,onChange:e=>Hs("simulationCenter",e),min:0,max:1,step:.01}),n.jsx(Xt,{label:"Decay",value:Rs.simulationDecay,onChange:e=>Hs("simulationDecay",e),min:100,max:2e4,step:100}),n.jsx(Xt,{label:"Repulsion Theta",value:Rs.simulationRepulsionTheta,onChange:e=>Hs("simulationRepulsionTheta",e),min:.1,max:3,step:.05}),n.jsx(Xt,{label:"Mouse Repulsion",value:Rs.simulationRepulsionFromMouse,onChange:e=>Hs("simulationRepulsionFromMouse",e),min:0,max:10,step:.5})]}),"points"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Size Scale",value:Rs.pointSizeScale,onChange:e=>Hs("pointSizeScale",e),min:.1,max:5,step:.1}),n.jsx(Xt,{label:"Opacity",value:Rs.pointOpacity,onChange:e=>Hs("pointOpacity",e),min:0,max:1,step:.05}),n.jsx(Xt,{label:"Greyout Opacity",value:Rs.pointGreyoutOpacity,onChange:e=>Hs("pointGreyoutOpacity",e),min:0,max:1,step:.05}),n.jsx(Qt,{label:"Scale on Zoom",checked:Rs.scalePointsOnZoom,onChange:e=>Hs("scalePointsOnZoom",e)}),n.jsx(Qt,{label:"Hover Ring",checked:Rs.renderHoveredPointRing,onChange:e=>Hs("renderHoveredPointRing",e)})]}),"links"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Qt,{label:"Show Links",checked:Rs.renderLinks,onChange:e=>Hs("renderLinks",e)}),n.jsx(Qt,{label:"Curved Links",checked:Rs.curvedLinks,onChange:e=>Hs("curvedLinks",e)}),n.jsx(Qt,{label:"Show Arrows",checked:Rs.linkDefaultArrows,onChange:e=>Hs("linkDefaultArrows",e)}),n.jsx(Xt,{label:"Width Scale",value:Rs.linkWidthScale,onChange:e=>Hs("linkWidthScale",e),min:.1,max:5,step:.1}),n.jsx(Xt,{label:"Opacity",value:Rs.linkOpacity,onChange:e=>Hs("linkOpacity",e),min:0,max:1,step:.05}),n.jsx(Xt,{label:"Greyout Opacity",value:Rs.linkGreyoutOpacity,onChange:e=>Hs("linkGreyoutOpacity",e),min:0,max:1,step:.05}),Rs.curvedLinks&&n.jsx(Xt,{label:"Curve Weight",value:Rs.curvedLinkWeight,onChange:e=>Hs("curvedLinkWeight",e),min:0,max:1,step:.05}),Rs.linkDefaultArrows&&n.jsx(Xt,{label:"Arrow Size",value:Rs.linkArrowsSizeScale,onChange:e=>Hs("linkArrowsSizeScale",e),min:.1,max:3,step:.1}),n.jsx(Qt,{label:"Scale on Zoom",checked:Rs.scaleLinksOnZoom,onChange:e=>Hs("scaleLinksOnZoom",e)})]}),"rendering"===Oe&&n.jsxs(n.Fragment,{children:[n.jsx(Xt,{label:"Space Size",value:Rs.spaceSize,onChange:e=>Hs("spaceSize",e),min:1024,max:16384,step:512}),n.jsx("div",{className:"pt-2 border-t border-edge-subtle/50",children:n.jsx("p",{className:"text-[9px] text-fg-muted",children:"Space size defines the simulation boundary. Larger values allow more spread."})})]})]})]}),Hn=n.jsxs(bt,{id:"export",title:"Export Topology",icon:n.jsx(re,{}),open:Jt,onClose:()=>Yt(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-280:600,y:100},defaultSize:{width:256,height:320},minSize:{width:220,height:150},autoHeight:!0,children:[n.jsx("div",{className:"py-1",children:[{label:"Full Topology (JSON)",format:"json",dataset:"full",desc:"All data: nodes, edges, paths, TX delay"},{label:"Gephi Graph (GEXF)",format:"gexf",dataset:"full",desc:"Import into Gephi for advanced analysis"},{label:"Nodes (CSV)",format:"csv",dataset:"nodes",desc:"Node metrics: centrality, class, signal"},{label:"Edges (CSV)",format:"csv",dataset:"edges",desc:"Edge metrics: confidence, symmetry, type"},{label:"Path Health (CSV)",format:"csv",dataset:"pathHealth",desc:"Route health scores and trends"},{label:"TX Delay (CSV)",format:"csv",dataset:"txDelay",desc:"TX delay recommendations per node"}].map(({label:e,format:t,dataset:s,desc:a})=>n.jsxs("button",{onClick:()=>jn(t,s),className:"w-full flex flex-col px-3 py-2 text-left hover-bg transition-base",children:[n.jsx("span",{className:"text-[11px] font-medium text-fg-primary",children:e}),n.jsx("span",{className:"text-[9px] text-fg-muted",children:a})]},`${t}-${s}`))}),n.jsx("div",{className:"px-3 py-1.5 border-t border-edge-subtle",children:n.jsxs("span",{className:"text-[9px] text-fg-muted",children:[(null==(R=null==_?void 0:_.nodeMetrics)?void 0:R.size)??0," nodes · ",(null==(H=null==_?void 0:_.validatedEdges)?void 0:H.length)??0," edges"]})})]}),Bn={info:{dot:"bg-sys-blue",text:"text-fg-secondary"},warning:{dot:"bg-status-warning",text:"text-status-warning"},critical:{dot:"bg-status-danger",text:"text-status-danger"}},Pn={"edge-appeared":"Link Discovered","edge-disappeared":"Link Lost","ghost-appeared":"Ghost Discovered","ghost-disappeared":"Ghost Resolved","betweenness-shift":"Traffic Rerouting","community-change":"Community Change","class-change":"Role Change","node-appeared":"Node Appeared","node-disappeared":"Node Dropped","snr-degradation":"SNR Degradation","asymmetry-shift":"Asymmetry Shift"},En=(e,t,s)=>null==t||""===t?null:n.jsxs("div",{className:"flex justify-between gap-2",children:[n.jsx("span",{className:"text-fg-muted",children:e}),n.jsx("span",{className:`tabular-nums text-right ${s??"text-fg-secondary"}`,children:t})]}),An=e=>{const t=[];return e.isZeroHop&&t.push({label:"Zero-Hop",color:"text-status-warning"}),e.isDirectPath&&t.push({label:"Direct",color:"text-sys-blue"}),e.isBackbone&&t.push({label:"Backbone",color:"text-fg-primary"}),e.isLoop&&t.push({label:"Loop",color:"text-sys-indigo"}),0===t.length?null:n.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:t.map(e=>n.jsx("span",{className:`text-[8px] font-medium uppercase tracking-wider px-1 py-px radius-badge bg-subtle-fill ${e.color}`,children:e.label},e.label))})},zn=e=>n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("span",{className:"capitalize font-medium text-fg-secondary",children:e.nodeClass}),e.isZeroHop&&n.jsx("span",{className:"text-[8px] font-medium uppercase tracking-wider px-1 py-px radius-badge bg-subtle-fill text-status-warning",children:"Neighbor"})]}),En("Degree",e.degree),e.betweenness>.01&&En("Betweenness",e.betweenness.toFixed(3)),En("Packets",e.packetCount),En("Community",`#${e.communityId}`),En("Activity",e.activityLevel),null!=e.avgRssi&&En("RSSI",`${e.avgRssi.toFixed(0)} dBm`),null!=e.avgSnr&&En("SNR",`${e.avgSnr.toFixed(1)} dB`)]}),$n=e=>n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[null!=e.previousValue&&null!=e.currentValue&&n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"text-fg-muted font-mono",children:"number"==typeof e.previousValue?e.previousValue.toFixed(3):e.previousValue}),n.jsx("span",{className:"text-fg-muted/40",children:"→"}),n.jsx("span",{className:"text-fg-secondary font-mono",children:"number"==typeof e.currentValue?e.currentValue.toFixed(3):e.currentValue}),"number"==typeof e.previousValue&&"number"==typeof e.currentValue&&n.jsxs("span",{className:e.currentValue>e.previousValue?"text-sys-green":"text-signal-poor",children:["(",e.currentValue>e.previousValue?"+":"",(e.currentValue-e.previousValue).toFixed(3),")"]})]}),e.nodeDetail&&n.jsxs(n.Fragment,{children:[En("Class",e.nodeDetail.nodeClass),En("Degree",e.nodeDetail.degree),e.nodeDetail.betweenness>.01&&En("Betweenness",e.nodeDetail.betweenness.toFixed(3))]})]}),Tn=s.useCallback(e=>{ys(t=>t===e?null:e)},[]),In=n.jsxs(bt,{id:"anomaly",title:"Anomaly Log",icon:n.jsx(oe,{}),open:hs,onClose:()=>xs(!1),defaultPosition:{x:"undefined"!=typeof window?window.innerWidth-328:600,y:100},defaultSize:{width:308,height:400},minSize:{width:260,height:180},maxSize:{width:440,height:700},headerActions:ps.length>0?n.jsx("button",{onClick:()=>{js.current.clear(),gs([]),ys(null)},className:"p-0.5 radius-badge hover-bg transition-base",title:"Clear all",children:n.jsx(de,{className:"w-2.5 h-2.5 text-fg-muted"})}):void 0,children:[0===ps.length?n.jsxs("div",{className:"px-3 py-6 text-center",children:[n.jsx(oe,{className:"w-5 h-5 text-fg-muted mx-auto mb-1.5"}),n.jsx("p",{className:"text-[11px] text-fg-muted",children:"No anomalies detected yet"}),n.jsx("p",{className:"text-[9px] text-fg-muted/60 mt-0.5",children:"Changes appear after topology recomputes"})]}):n.jsx("div",{className:"overflow-y-auto",children:ps.slice(0,50).map(e=>{const t=Bn[e.severity],s=S(e.detectedAt/1e3),a=bs===e.id,i=!(!e.edgeDetail&&!e.nodeDetail&&null==e.previousValue);return n.jsxs("div",{className:`border-b border-edge-subtle/50 last:border-0 transition-colors ${i?"cursor-pointer hover-bg":""} ${a?"bg-subtle-fill/50":""}`,onClick:i?()=>Tn(e.id):void 0,children:[n.jsxs("div",{className:"flex items-start gap-2 px-3 py-1.5",children:[n.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 mt-1.5 ${t.dot}`}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("p",{className:`text-[10px] leading-tight ${t.text}`,children:e.description}),n.jsxs("p",{className:"text-[9px] text-fg-muted/60 mt-0.5",children:[Pn[e.category]??e.category," · ",s]})]}),i&&n.jsx(ue,{className:"w-3 h-3 text-fg-muted/40 shrink-0 mt-0.5 transition-transform duration-150 "+(a?"rotate-180":"")})]}),a&&n.jsx("div",{className:"px-3 pb-2 pl-6",children:n.jsxs("div",{className:"border-l-2 border-edge-subtle/60 pl-2 py-0.5",children:[e.edgeDetail&&(o=e.edgeDetail,r=e.category,n.jsxs("div",{className:"text-[9px] space-y-0.5",children:[(o.fromClass||o.toClass)&&n.jsxs("div",{className:"flex items-center gap-1 text-fg-muted",children:[n.jsx("span",{className:"capitalize",children:o.fromClass??"?"}),n.jsx("span",{className:"text-fg-muted/40",children:"↔"}),n.jsx("span",{className:"capitalize",children:o.toClass??"?"})]}),"edge-appeared"===r&&o.packetCount>0&&n.jsxs(n.Fragment,{children:[En("Packets",o.packetCount),En("Confidence",`${(100*o.confidence).toFixed(0)}%`,o.confidence>=.8?"text-sys-green":o.confidence>=.5?"text-sys-indigo":"text-signal-poor"),En("Symmetry",`${(100*o.symmetryRatio).toFixed(0)}%`)]}),o.isZeroHop&&null!=o.avgRssi&&En("RSSI",`${o.avgRssi.toFixed(0)} dBm`),o.isZeroHop&&null!=o.avgSnr&&En("SNR",`${o.avgSnr.toFixed(1)} dB`),null!=o.fromBetweenness&&o.fromBetweenness>.01&&En(`${o.fromName??"A"} centrality`,o.fromBetweenness.toFixed(3)),null!=o.toBetweenness&&o.toBetweenness>.01&&En(`${o.toName??"B"} centrality`,o.toBetweenness.toFixed(3)),An(o)]})),e.nodeDetail&&!e.edgeDetail&&("node-appeared"===e.category||"node-disappeared"===e.category)&&zn(e.nodeDetail),("betweenness-shift"===e.category||"community-change"===e.category||"class-change"===e.category)&&$n(e)]})})]},e.id);var o,r})}),ps.length>0&&n.jsx("div",{className:"px-3 py-1.5 border-t border-edge-subtle",children:n.jsxs("span",{className:"text-[9px] text-fg-muted",children:[ps.length," total · showing ",Math.min(ps.length,50)]})})]}),Gn=s.useMemo(()=>{const e={};for(const t of Is)e[t.edgeType]=(e[t.edgeType]??0)+1;return e},[Is]),On=n.jsxs(bt,{id:"legend",title:"Legend",icon:n.jsx(ee,{}),open:_e,onClose:()=>Ue(!1),defaultPosition:{x:12,y:60},defaultSize:{width:224,height:400},minSize:{width:200,height:150},maxSize:{width:360,height:700},autoHeight:!0,children:[n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("button",{onClick:()=>Je(e=>!e),className:"w-full flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-fg-secondary hover-bg transition-base",children:[qe?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"Nodes",n.jsx("span",{className:"text-fg-muted ml-auto tabular-nums",children:Qs.length})]}),qe&&n.jsx("div",{className:"px-2 pb-2 space-y-0.5",children:[["local","Local"],["hub","Hub"],["gateway","Gateway"],["backbone","Backbone"],["neighbor","Neighbor"],["mobile","Mobile"],["ghost","Ghost"],["standard","Standard"]].map(([e,t])=>{const s=fe[e]??0;if(0===s&&"local"!==e)return null;const a=ct.has(e);return n.jsx(k,{content:zt[e],children:n.jsxs("button",{onClick:()=>mn(e),className:"w-full flex items-center gap-2 px-2 py-1 radius-badge transition-base text-left "+(a?"opacity-40":"hover-bg"),children:[n.jsx("span",{className:"w-2.5 h-2.5 rounded-full shrink-0",style:{backgroundColor:we[e]}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1",children:t}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:s})]})},e)})})]}),n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("button",{onClick:()=>it(e=>!e),className:"w-full flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-fg-secondary hover-bg transition-base",children:[tt?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"Edges",n.jsx("span",{className:"text-fg-muted ml-auto tabular-nums",children:qs.length})]}),tt&&n.jsx("div",{className:"px-2 pb-2 space-y-0.5",children:[{type:"zero-hop",label:"Zero-Hop RF"},{type:"direct-path",label:"Direct Path"},{type:"loop",label:"Loop"},{type:"backbone",label:"Backbone"},{type:"standard",label:"Standard"},{type:"ghost",label:"Ghost"}].map(({type:e,label:t})=>{const s=Gn[e]??0;if(0===s)return null;const a=Gt(e,.8,Ne);return n.jsx(k,{content:Zt[e],children:n.jsxs("div",{className:"flex items-center gap-2 px-2 py-1 cursor-help",children:[n.jsx("span",{className:"w-4 h-0.5 shrink-0 rounded-full",style:{backgroundColor:a}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1",children:t}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:s})]})},e)})})]}),es&&Us&&n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("div",{className:"px-3 py-1.5 text-[10px] font-medium text-sys-green flex items-center gap-1.5",children:[n.jsx(ie,{className:"w-3 h-3"}),"Link Budget",n.jsxs("span",{className:"text-fg-muted ml-auto tabular-nums",children:[Us.analyzedEdges+Us.rssiOnlyEdges,"/",Us.totalEdges]})]}),n.jsxs("div",{className:"px-3 pb-2 space-y-0.5",children:[(()=>{const e=Gs&&Gs>1e5?Gs/1e6:Gs||915,t=as??Zs??12,s=os??(Os&&Os>1e3?Os/1e3:Os||125),a=ls??Ks??5,i=ss??Ws??22,o=Xe(t,s,a),r=ds??o,l=Qe(1e3*s),c=ms??l,d=(null==Vs?void 0:Vs.filter(e=>e.isTraceEstimated).length)??0,u=(null==Vs?void 0:Vs.filter(e=>e.isZeroHop).length)??0,m=null!=ss||null!=as||null!=os||null!=ls||null!=ds,h="w-10 px-1 py-0 text-[10px] text-right tabular-nums bg-subtle-fill border border-edge-subtle rounded text-fg-secondary focus:outline-none focus:border-sys-blue";return n.jsxs("div",{className:"pb-1 mb-1 border-b border-edge-subtle space-y-0.5",children:[n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Frequency"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[e.toFixed(3)," MHz"]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"SF"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:t,onChange:e=>{const t=parseInt(e.target.value,10);is(t===(Zs??12)?null:t)},className:h+" w-12 appearance-none",children:[7,8,9,10,11,12].map(e=>n.jsxs("option",{value:e,children:["SF",e]},e))}),null!=as&&n.jsx("button",{onClick:()=>is(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"BW"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:s,onChange:e=>{const t=parseFloat(e.target.value);rs(t===(Os&&Os>1e3?Os/1e3:Os||125)?null:t)},className:h+" w-14 appearance-none",children:[62.5,125,250,500].map(e=>n.jsxs("option",{value:e,children:[e," kHz"]},e))}),null!=os&&n.jsx("button",{onClick:()=>rs(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"CR"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("select",{value:a,onChange:e=>{const t=parseInt(e.target.value,10);cs(t===(Ks??5)?null:t)},className:h+" w-12 appearance-none",children:[5,6,7,8].map(e=>n.jsxs("option",{value:e,children:["4/",e]},e))}),null!=ls&&n.jsx("button",{onClick:()=>cs(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"TX Power"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("input",{type:"number",min:1,max:36,step:1,value:i,onChange:e=>{const t=parseInt(e.target.value,10);isNaN(t)||ns(t)},onBlur:e=>{const t=parseInt(e.target.value,10);isNaN(t)?ns(null):ns(Math.max(1,Math.min(36,t)))},className:h}),n.jsx("span",{className:"text-fg-muted",children:"dBm"}),null!=ss&&n.jsx("button",{onClick:()=>ns(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px] gap-1",children:[n.jsx("span",{className:"text-fg-muted",children:"Sensitivity"}),n.jsxs("div",{className:"flex items-center gap-1",children:[n.jsx("input",{type:"number",min:-150,max:-80,step:.5,value:Math.round(10*r)/10,onChange:e=>{const t=parseFloat(e.target.value);isNaN(t)||us(t)},onBlur:e=>{const t=parseFloat(e.target.value);isNaN(t)?us(null):us(Math.max(-150,Math.min(-80,t)))},className:h+" w-12"}),n.jsx("span",{className:"text-fg-muted",children:"dBm"}),null!=ds&&n.jsx("button",{onClick:()=>us(null),className:"text-[8px] text-sys-blue hover:underline",title:"Reset",children:"↺"})]})]}),d>0&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Noise Floor"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums "+(null!=ms?"":"italic text-fg-muted"),children:[c.toFixed(1)," dBm",null!=ms?"":" (est.)"]})]}),m&&n.jsx("button",{onClick:()=>{ns(null),is(null),rs(null),cs(null),us(null)},className:"w-full text-[9px] text-sys-blue hover:underline text-center pt-0.5",children:"Reset all to radio config"}),(u>0||d>0)&&n.jsxs("div",{className:"flex items-center justify-between text-[10px] pt-0.5",children:[n.jsx("span",{className:"text-fg-muted",children:"Sources"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[u>0&&n.jsxs("span",{children:[u," direct"]}),u>0&&d>0&&n.jsx("span",{className:"text-fg-muted",children:" · "}),d>0&&n.jsxs("span",{className:"text-sys-indigo",children:[d," trace"]})]})]})]})})(),null!=Us.avgMarginDb&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx("span",{className:"text-fg-muted",children:"Avg Margin"}),n.jsxs("span",{className:"text-fg-secondary tabular-nums",children:[Us.avgMarginDb>0?"+":"",Us.avgMarginDb.toFixed(1)," dB"]})]}),["excellent","good","fair","marginal","critical"].map(e=>{const t=Us.marginCounts[e];return 0===t?null:n.jsxs("div",{className:"flex items-center gap-2 px-1 py-0.5",children:[n.jsx("span",{className:"w-3 h-0.5 shrink-0 rounded-full",style:{backgroundColor:st[e]}}),n.jsx("span",{className:"text-[10px] text-fg-secondary flex-1 capitalize",children:e}),n.jsx("span",{className:"text-[10px] text-fg-muted tabular-nums",children:t})]},e)}),Us.anomalousCount>0&&n.jsxs("div",{className:"flex items-center justify-between text-[10px] pt-0.5",children:[n.jsx("span",{className:"text-status-warning",children:"Anomalous"}),n.jsx("span",{className:"text-status-warning tabular-nums",children:Us.anomalousCount})]})]})]}),Nn&&Nn.atRiskPaths.length>0&&n.jsxs("div",{className:"border-b border-edge-subtle",children:[n.jsxs("div",{className:"flex items-center",children:[n.jsxs("button",{onClick:()=>rt(e=>!e),className:"flex-1 flex items-center gap-1.5 px-3 py-1.5 text-[10px] font-medium text-status-warning hover-bg transition-base",children:[ot?n.jsx(ue,{className:"w-3 h-3"}):n.jsx(me,{className:"w-3 h-3"}),"At-Risk Paths",n.jsxs("span",{className:"text-fg-muted ml-auto tabular-nums",children:[Nn.criticalCount>0&&n.jsxs("span",{className:"text-status-danger",children:[Nn.criticalCount,"c"]}),Nn.criticalCount>0&&Nn.highCount>0&&" ",Nn.highCount>0&&n.jsxs("span",{className:"text-status-warning",children:[Nn.highCount,"h"]}),(Nn.criticalCount>0||Nn.highCount>0)&&Nn.moderateCount>0&&" ",Nn.moderateCount>0&&n.jsxs("span",{className:"text-fg-muted",children:[Nn.moderateCount,"m"]})]})]}),n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary",children:"Predictive Path Failure"}),n.jsx("div",{className:"text-fg-secondary text-[11px]",children:"Identifies paths at risk of failure by combining four weighted factors. Paths below the moderate threshold (35%) are not shown."}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Factor weights"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Declining usage"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"35%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Weak link certainty"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"30%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"No alternate paths"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"20%"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:"Low signal margin"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"15%"})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Risk thresholds"}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-status-danger",children:"Critical"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"≥75% — failure likely imminent"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-status-warning",children:"High"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"55-74% — significant risk"})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Moderate"}),n.jsx("span",{className:"text-fg-muted tabular-nums",children:"35-54% — worth monitoring"})]})]}),n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 text-[10px] text-fg-muted font-mono space-y-0.5",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{children:"Edges analyzed"}),n.jsx("span",{className:"tabular-nums",children:Nn.edgesAnalyzed})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{children:"With signal data"}),n.jsx("span",{className:"tabular-nums",children:Nn.edgesWithSignal})]})]})]}),children:n.jsx("span",{className:"px-2 py-1.5 text-fg-muted cursor-help",children:n.jsx(oe,{className:"w-3 h-3"})})})]}),ot&&n.jsx("div",{className:"px-2 pb-2 space-y-1",children:Nn.atRiskPaths.slice(0,8).map(e=>{const t="critical"===e.riskLevel?"#EF4444":"high"===e.riskLevel?"#F97316":"#FBBF24",s="imminent"===e.urgency?"IMM":"near-term"===e.urgency?"NEAR":"WATCH";return n.jsx(k,{content:n.jsxs("div",{className:"max-w-xs space-y-1.5",children:[n.jsx("div",{className:"font-semibold text-fg-primary font-mono text-[11px]",children:e.hops.join(" → ")}),n.jsxs("div",{className:"space-y-0.5 text-[10px]",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Risk score"}),n.jsxs("span",{className:"font-semibold tabular-nums",style:{color:t},children:[(100*e.riskScore).toFixed(1),"%"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Health score"}),n.jsxs("span",{className:"text-fg-primary tabular-nums",children:[(100*e.healthScore).toFixed(0),"%"]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Obs. trend"}),n.jsxs("span",{className:"tabular-nums "+(e.observationTrend<0?"text-status-danger":"text-fg-secondary"),children:[e.observationTrend>0?"+":"",e.observationTrend.toFixed(3)]})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Alt. paths"}),n.jsx("span",{className:"tabular-nums "+(0===e.alternatePathsCount?"text-status-danger":"text-fg-secondary"),children:e.alternatePathsCount})]}),n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-muted",children:"Urgency"}),n.jsx("span",{className:"capitalize",style:{color:t},children:e.urgency})]})]}),e.factors.length>0&&n.jsxs("div",{className:"pt-1 border-t border-edge-subtle/30 space-y-0.5 text-[10px]",children:[n.jsx("div",{className:"text-fg-muted font-medium",children:"Contributing factors"}),e.factors.map((e,t)=>n.jsxs("div",{className:"space-y-0.5",children:[n.jsxs("div",{className:"flex justify-between",children:[n.jsx("span",{className:"text-fg-secondary",children:e.name}),n.jsxs("span",{className:"text-fg-muted tabular-nums",children:[(e.score*e.weight*100).toFixed(1),"% (",(100*e.weight).toFixed(0),"w × ",(100*e.score).toFixed(0),"s)"]})]}),n.jsx("div",{className:"text-fg-muted pl-1",children:e.description})]},t))]})]}),children:n.jsxs("div",{className:"px-2 py-1 radius-badge bg-subtle-fill/30 cursor-help",children:[n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"w-1.5 h-1.5 rounded-full shrink-0",style:{backgroundColor:t}}),n.jsx("span",{className:"text-[10px] text-fg-secondary font-mono truncate flex-1",children:e.hops.join(" → ")}),n.jsx("span",{className:"text-[8px] uppercase tracking-wide px-1 py-px radius-badge",style:{backgroundColor:`${t}20`,color:t},children:s}),n.jsxs("span",{className:"text-[10px] tabular-nums font-semibold",style:{color:t},children:[(100*e.riskScore).toFixed(0),"%"]})]}),n.jsx("div",{className:"flex flex-wrap gap-1 mt-0.5 pl-3",children:e.factors.map((t,s)=>n.jsxs("span",{className:"text-[8px] text-fg-muted",children:[t.name," (",(t.score*t.weight*100).toFixed(0),"%)",spt(e=>"spectral"===e?"louvain":"spectral"),className:"text-sys-blue hover:underline cursor-pointer",children:"spectral"===ht?"Spectral":"Louvain"})]}),"louvain"===ht&&Cn&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Louvain modularity score — quality of community partition (higher = better defined communities)",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Modularity Q"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:Cn.modularity.toFixed(4)})]}),"louvain"===ht&&n.jsxs("div",{className:"mt-1.5 pt-1.5 border-t border-edge-subtle space-y-1.5",children:[n.jsx(Xt,{label:"Resolution γ",value:gt,onChange:ft,min:.01,max:5,step:.01}),n.jsx(Xt,{label:"K-weight",value:vt,onChange:St,min:.01,max:5,step:.01}),(1!==gt||1!==vt)&&n.jsx("button",{onClick:()=>{ft(1),St(1)},className:"w-full text-[10px] text-sys-blue hover:underline text-center",children:"Reset defaults"})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Redundant path cycles in the topology — indicates alternate routing options",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Loops"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:(null==(B=null==_?void 0:_.loops)?void 0:B.length)??0})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"High-betweenness edges that carry disproportionate traffic flow",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Backbone"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:(null==(P=null==_?void 0:_.backboneEdges)?void 0:P.length)??0})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Unresolved prefix nodes inferred by Viterbi HMM from repeated path patterns",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Ghosts"})}),n.jsx("span",{className:"text-fg-secondary tabular-nums",children:ge.length})]}),n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Community-aware node coloring — groups nodes by cluster assignment",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Clustering"})}),n.jsx("span",{className:"tabular-nums "+(ut?"text-sys-blue":"text-fg-muted"),children:ut?"On":"Off"})]}),null!=wn&&n.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[n.jsx(k,{content:"Algebraic connectivity — 2nd-smallest eigenvalue of the graph Laplacian. Near-zero = one bridge from network partition.",children:n.jsx("span",{className:"text-fg-muted cursor-help",children:"Fiedler λ₂"})}),n.jsx("span",{className:"tabular-nums "+(wn<.01?"text-status-warning":"text-fg-secondary"),children:wn.toFixed(4)})]}),ct.size>0&&n.jsxs("button",{onClick:()=>dt(new Set),className:"w-full mt-1 text-[10px] text-sys-blue hover:underline text-center",children:["Clear filters (",ct.size,")"]})]})]}),Zn=n.jsx(Z,{children:ze&&n.jsx(W.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},transition:{duration:.15},className:"absolute top-4 left-1/2 -translate-x-1/2 z-30 w-80",children:n.jsxs("div",{className:"surface-elevated radius-inset shadow-2xl overflow-hidden",children:[n.jsxs("div",{className:"flex items-center gap-2 px-3 py-2.5 border-b border-edge-subtle",children:[n.jsx(te,{className:"w-4 h-4 text-fg-muted shrink-0"}),n.jsx("input",{ref:Ns,type:"text",value:Ee,onChange:e=>Ae(e.target.value),placeholder:"Search by name or prefix...",className:"flex-1 bg-transparent text-sm text-fg-primary placeholder:text-fg-muted focus:outline-none",onKeyDown:e=>{"Escape"===e.key?($e(!1),Ae("")):"Enter"===e.key&&cn.length>0&&dn(cn[0])}}),Ee&&n.jsx("button",{onClick:()=>Ae(""),className:"p-0.5 radius-badge hover-bg transition-base",children:n.jsx(U,{className:"w-3 h-3 text-fg-muted"})})]}),cn.length>0&&n.jsx("div",{className:"max-h-64 overflow-y-auto",children:cn.map((e,t)=>n.jsxs("button",{onClick:()=>dn(e),className:"w-full flex items-center gap-3 px-3 py-2 text-left hover-bg transition-base "+(0===t?"bg-subtle-fill/50":""),children:[n.jsx("span",{className:"w-2.5 h-2.5 rounded-full shrink-0",style:{backgroundColor:we[e.nodeClass]}}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsx("div",{className:"text-sm text-fg-primary truncate",children:e.name||e.prefix}),e.name&&n.jsx("div",{className:"text-[10px] text-fg-muted",children:e.prefix})]}),n.jsx(he,{className:"w-3 h-3 text-fg-muted shrink-0"})]},e.id))}),Ee&&0===cn.length&&n.jsx("div",{className:"px-3 py-4 text-center text-sm text-fg-muted",children:"No nodes found"}),!Ee&&n.jsx("div",{className:"px-3 py-2 type-data-xs text-fg-muted",children:"Type to search • Enter to select • Esc to close"})]})})});return $?0===zs.length?n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsx("div",{className:"absolute inset-0 bg-body flex items-center justify-center",children:n.jsx(Ut,{})})]}):Cs?Be?n.jsxs("div",{className:"fixed inset-0 z-50 bg-body flex flex-col overflow-hidden",children:[n.jsxs("div",{className:"flex items-center justify-between px-4 py-2.5 surface-header z-10",children:[n.jsxs("div",{className:"flex items-center gap-3",children:[n.jsx(X,{className:"w-5 h-5 text-icon-page-title"}),n.jsxs("h1",{className:"type-title text-fg-primary flex items-center gap-2",children:["MeshGraph",n.jsx(C,{color:"violet",compact:!0,children:"Analytics"})]}),n.jsxs("span",{className:"text-[10px] text-fg-muted tabular-nums",children:[Qs.length," nodes • ",qs.length," edges"]})]}),n.jsx(k,{content:"Exit fullscreen",children:n.jsx("button",{onClick:un,className:"p-1.5 radius-inner hover-bg transition-base",children:n.jsx(ce,{className:"w-4 h-4 text-fg-muted"})})})]}),n.jsxs("div",{className:"flex-1 relative min-h-0 m-2 surface-base radius-inset overflow-hidden border border-edge-subtle",children:[n.jsx(a,{className:"absolute inset-0",points:Cs,links:Ss,...Ls,...Rs,backgroundColor:ke,fitViewOnInit:!0,fitViewPadding:.15,showLabels:Ke,showDynamicLabels:!1,showTopLabels:Ke,showTopLabelsLimit:200,showHoveredPointLabel:!0,pointLabelColor:Se,pointClusterBy:ut?"communityId":void 0,onPolygonSelected:$t?pn:void 0,polygonalSelectorStrokeColor:Ne?"#FBBF24":"#D97706",onClick:ln,onLinkClick:rn,onMount:tn,hoveredPointRingColor:Ne?"#FBBF24":"#D97706",hoveredPointCursor:"pointer",hoveredLinkCursor:"pointer"}),Zn,On,Rn,Mn,Hn,In,n.jsxs(Z,{children:[Fe&&n.jsx(Vt,{node:Fe,egoMetrics:fn,onExpandEgo:yn,neighbors:bn,onSelectNeighbor:an,txDelayRec:vn,onClose:()=>{var e;Re(null),null==(e=ws.current)||e.unselectAllPoints()}}),Me&&!Fe&&n.jsx(Kt,{edge:Me,onClose:()=>He(null)}),Wt&&!Fe&&!Me&&n.jsx(_t,{metrics:Wt,onClose:gn})]})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0",children:[n.jsx(a,{className:"absolute inset-0",points:Cs,links:Ss,...Ls,...Rs,backgroundColor:ke,fitViewOnInit:!0,fitViewPadding:.15,showLabels:Ke,showDynamicLabels:!1,showTopLabels:Ke,showTopLabelsLimit:200,showHoveredPointLabel:!0,pointLabelColor:Se,pointClusterBy:ut?"communityId":void 0,onPolygonSelected:$t?pn:void 0,polygonalSelectorStrokeColor:Ne?"#FBBF24":"#D97706",onClick:ln,onLinkClick:rn,onMount:tn,hoveredPointRingColor:Ne?"#FBBF24":"#D97706",hoveredPointCursor:"pointer",hoveredLinkCursor:"pointer"}),Zn,On,Rn,Mn,Hn,In,n.jsxs("div",{className:"absolute bottom-4 right-4 z-10 hidden lg:flex items-center gap-3 type-data-xs text-fg-muted/60",children:[n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"/"})," Search"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"F"})," Fit"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"L"})," Labels"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"Space"})," Pause"]}),n.jsxs("span",{children:[n.jsx("kbd",{className:"px-1 py-0.5 radius-badge bg-subtle-fill/50 font-mono",children:"Esc"})," Clear"]})]}),n.jsxs(Z,{children:[Fe&&n.jsx(Vt,{node:Fe,egoMetrics:fn,onExpandEgo:yn,neighbors:bn,onSelectNeighbor:an,txDelayRec:vn,onClose:()=>{var e;Re(null),null==(e=ws.current)||e.unselectAllPoints()}}),Me&&!Fe&&n.jsx(Kt,{edge:Me,onClose:()=>He(null)}),Wt&&!Fe&&!Me&&n.jsx(_t,{metrics:Wt,onClose:gn})]})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0 bg-body flex flex-col items-center justify-center gap-3",children:[n.jsx(xe,{className:"w-8 h-8 text-sys-blue animate-spin"}),n.jsx("span",{className:"type-body text-fg-muted",children:"Preparing graph..."})]})]}):n.jsxs("div",{className:"relative h-[calc(100dvh-56px)] lg:h-dvh min-h-[500px] -mx-4 sm:-mx-6 lg:-mx-8 -mt-5 -mb-4 sm:-mb-6 lg:-mb-8 overflow-hidden",children:[Dn,n.jsxs("div",{className:"absolute inset-0 bg-body flex items-center justify-center",children:[n.jsx(z,{isOpen:I,onClose:K}),!I&&n.jsx(xe,{className:"w-8 h-8 text-sys-blue animate-spin"})]})]})}export{qt as default}; diff --git a/frontend/dist/assets/NodeInformationCard-68hFKJ-B.js b/frontend/dist/assets/NodeInformationCard-tOZNdmfP.js similarity index 93% rename from frontend/dist/assets/NodeInformationCard-68hFKJ-B.js rename to frontend/dist/assets/NodeInformationCard-tOZNdmfP.js index b5842cc6..30f14b54 100644 --- a/frontend/dist/assets/NodeInformationCard-68hFKJ-B.js +++ b/frontend/dist/assets/NodeInformationCard-tOZNdmfP.js @@ -1 +1 @@ -import{j as s}from"./vendor-react-alRNW2nb.js";import{C as e}from"./PageLayout-QhCLxU34.js";import{D as a}from"./DataBox-DpDXI-WX.js";import{q as t,b1 as r}from"./index-D7i6lQrq.js";import{R as c}from"./vendor-icons-TO0PZKGR.js";function l({nodeName:l,repeaterVersion:m,coreVersion:i,localHash:n,publicKey:d}){return s.jsxs(e,{neomorphic:!0,children:[s.jsx(t,{icon:s.jsx(c,{}),title:"Node Information"}),s.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3 sm:gap-4",children:[s.jsxs("div",{className:"min-w-0 col-span-2 sm:col-span-1",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Node Name"}),s.jsx("p",{className:"type-body text-fg-primary mt-0.5 sm:mt-1 truncate",title:l,children:l})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Repeater"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${m}`,children:["v",m]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Core"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${i}`,children:["v",i]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Console"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${r}`,children:["v",r]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Local Hash"}),s.jsx("div",{className:"mt-0.5 sm:mt-1",children:n?s.jsx(a,{copy:!0,size:"compact",children:n}):s.jsx("span",{className:"type-data-sm text-fg-secondary",children:"N/A"})})]})]}),d&&s.jsxs("div",{className:"mt-3 sm:mt-4 pt-3 sm:pt-4 border-t border-edge-subtle",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Public Key"}),s.jsx("div",{className:"mt-0.5 sm:mt-1",children:s.jsx(a,{copy:!0,size:"responsive",children:d})})]})]})}export{l as N}; +import{j as s}from"./vendor-react-alRNW2nb.js";import{C as e}from"./PageLayout-BWMUVZgC.js";import{D as a}from"./DataBox-DpDXI-WX.js";import{q as t,b1 as r}from"./index-CkRTgHHA.js";import{R as c}from"./vendor-icons-TO0PZKGR.js";function l({nodeName:l,repeaterVersion:m,coreVersion:i,localHash:n,publicKey:d}){return s.jsxs(e,{neomorphic:!0,children:[s.jsx(t,{icon:s.jsx(c,{}),title:"Node Information"}),s.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3 sm:gap-4",children:[s.jsxs("div",{className:"min-w-0 col-span-2 sm:col-span-1",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Node Name"}),s.jsx("p",{className:"type-body text-fg-primary mt-0.5 sm:mt-1 truncate",title:l,children:l})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Repeater"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${m}`,children:["v",m]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Core"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${i}`,children:["v",i]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Console"}),s.jsxs("p",{className:"type-data text-fg-primary mt-0.5 sm:mt-1 truncate",title:`v${r}`,children:["v",r]})]}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Local Hash"}),s.jsx("div",{className:"mt-0.5 sm:mt-1",children:n?s.jsx(a,{copy:!0,size:"compact",children:n}):s.jsx("span",{className:"type-data-sm text-fg-secondary",children:"N/A"})})]})]}),d&&s.jsxs("div",{className:"mt-3 sm:mt-4 pt-3 sm:pt-4 border-t border-edge-subtle",children:[s.jsx("span",{className:"type-label text-fg-secondary",children:"Public Key"}),s.jsx("div",{className:"mt-0.5 sm:mt-1",children:s.jsx(a,{copy:!0,size:"responsive",children:d})})]})]})}export{l as N}; diff --git a/frontend/dist/assets/PacketList-BfWkNwPj.js b/frontend/dist/assets/PacketList-BJFBF77t.js similarity index 99% rename from frontend/dist/assets/PacketList-BfWkNwPj.js rename to frontend/dist/assets/PacketList-BJFBF77t.js index 711528d1..1462b6b5 100644 --- a/frontend/dist/assets/PacketList-BfWkNwPj.js +++ b/frontend/dist/assets/PacketList-BJFBF77t.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PathMapMapLibre-Copwhk_5.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-core-FtpmsTnh.js","assets/BasemapLayer-CSqjQAiA.js","assets/index-D7i6lQrq.js","assets/vendor-charts-C916_-gs.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/maplibre-gl-B1CfjdFi.css","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-B2A_8ldG.css"])))=>i.map(i=>d[i]); -import{c as e,a as s}from"./vendor-core-FtpmsTnh.js";import{j as t,r as a}from"./vendor-react-alRNW2nb.js";import{u as n}from"./vendor-virt-BytWoLhu.js";import{B as l,h as r,a5 as i,a6 as c,a7 as d,a8 as o,a9 as x,aa as m,H as p,ab as h,Q as u,ac as g,ad as f,ae as y,af as j,ag as b,ah as N,ai as v,aj as w,ak as k,M as C,p as _,al as S,am as P,an as H,ao as T,Y as B,_ as M,ap as F,aq as L,ar as D}from"./index-D7i6lQrq.js";import{p as z,d as $,e as R,g as A,b as E}from"./primitives-YN2ynYwE.js";import{u as U,r as I,a as V,b as Q,c as G,d as O,i as W}from"./consumer-registry-KuOoZhsq.js";import{D as q,R as K,P as X,g as Y}from"./badge-colors-BxLppqaF.js";import{g as J,e as Z,a as ee}from"./chat-utils-DbM_TyxC.js";import{P as se,d as te,a as ae,b as ne}from"./payload-decoders-DjZO58V7.js";import{S as le,i as re,g as ie}from"./SignalIndicator-fAt1Aewy.js";import{_ as ce,$ as de,o as oe,A as xe,V as me,D as pe,R as he,a0 as ue,a1 as ge,a2 as fe,a3 as ye,a as je,a4 as be,H as Ne,a5 as ve,a6 as we,a7 as ke,a8 as Ce,a9 as _e,aa as Se,ab as Pe,ac as He,l as Te,K as Be,ad as Me,ae as Fe,af as Le,ag as De,C as ze,q as $e,Z as Re,w as Ae}from"./vendor-icons-TO0PZKGR.js";import{_ as Ee}from"./cosmograph-DqYT4sUA.js";import{f as Ue,r as Ie}from"./usePipelineStore-D3dOwDkO.js";import{D as Ve}from"./DataBox-DpDXI-WX.js";import{L as Qe,m as Ge,u as Oe,A as We}from"./vendor-motion-DNp0Qg4F.js";import{D as qe,u as Ke}from"./useMapViewStore-1yyjXCM8.js";function Xe({"aria-label":s="Page navigation",className:a,...n}){return t.jsx("nav",{"aria-label":s,...n,className:e("flex gap-x-2",a)})}function Ye({onClick:s,disabled:a=!1,className:n,children:r="Previous"}){return t.jsx("span",{className:e("grow basis-0",n),children:t.jsxs(l,{plain:!0,onClick:s,disabled:a,"aria-label":"Previous page",className:e("gap-1",a&&"invisible"),children:[t.jsx("svg",{className:"size-4 stroke-current",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M2.75 8H13.25M2.75 8L5.25 5.5M2.75 8L5.25 10.5",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})}),r]})})}function Je({onClick:s,disabled:a=!1,className:n,children:r="Next"}){return t.jsx("span",{className:e("flex grow basis-0 justify-end",n),children:t.jsxs(l,{plain:!0,onClick:s,disabled:a,"aria-label":"Next page",className:e("gap-1",a&&"invisible"),children:[r,t.jsx("svg",{className:"size-4 stroke-current",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M13.25 8L2.75 8M13.25 8L10.75 10.5M13.25 8L10.75 5.5",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})})]})})}function Ze({className:s,...a}){return t.jsx("span",{...a,className:e("hidden items-baseline gap-x-2 sm:flex",s)})}function es({page:s,current:a=!1,onClick:n,className:r,children:i}){return t.jsx(l,{plain:!a,outline:a,onClick:()=>null==n?void 0:n(s),"aria-label":`Page ${s}`,"aria-current":a?"page":void 0,className:e("min-w-[2.25rem] before:absolute before:-inset-px before:rounded-lg",a&&"before:bg-subtle-fill",r),children:i??s})}function ss({className:s,...a}){return t.jsx("span",{"aria-hidden":"true",...a,className:e("w-[2.25rem] select-none text-center text-sm text-fg-muted",s),children:"…"})}const ts=s(e=>({requestedHash:null,requestChannel:s=>e({requestedHash:s}),clearRequest:()=>e({requestedHash:null})})),as={rx:{icon:me,label:"Rx",badgeColor:q.rx,avatarBg:"bg-sys-green/15",avatarText:"text-sys-green"},forward:{icon:xe,label:"Fwd",badgeColor:q.forward,avatarBg:"bg-sys-cyan/15",avatarText:"text-sys-cyan"},duplicate:{icon:oe,label:"Dupe",badgeColor:q.duplicate,avatarBg:"bg-fg-muted/15",avatarText:"text-fg-secondary"},tx:{icon:de,label:"Tx",badgeColor:q.tx,avatarBg:"bg-sys-indigo/15",avatarText:"text-sys-indigo"},dropped:{icon:ce,label:"Drop",badgeColor:q.dropped,avatarBg:"bg-sys-amber/15",avatarText:"text-sys-amber"}},ns={sm:"w-3.5 h-3.5",md:"w-4 h-4",lg:"w-5 h-5"},ls={sm:"w-8 h-8",md:"w-9 h-9",lg:"w-10 h-10"};function rs(e){return"tx_local"===e.packet_origin?"tx":"tx_forward"===e.packet_origin?"forward":e.is_duplicate?"duplicate":e.transmitted?"forward":e.drop_reason?"dropped":"rx"}const is=a.memo(function({packet:s,showLabel:a=!0,variant:n="avatar",size:l="sm"}){const i=rs(s),c=as[i],d=c.icon;return"avatar"===n?t.jsx("div",{className:e("flex items-center justify-center rounded-full flex-shrink-0",c.avatarBg,ls[l]),children:t.jsx(d,{className:e(ns[l],c.avatarText)})}):t.jsxs(r,{color:c.badgeColor,children:[t.jsx(d,{className:ns[l]}),a&&c.label]})}),cs=a.memo(function({path:s,localHash:a,className:n}){if(!s||0===s.length)return t.jsx("span",{className:e("text-fg-muted text-xs",n),children:"—"});const l=a?(a.startsWith("0x")?a.slice(2,4):a.slice(0,2)).toUpperCase():null;return t.jsx("span",{className:e("flex items-center gap-0.5 type-data-xs overflow-hidden",n),children:s.map((e,a)=>{const n=a===s.length-1,r=l&&e.toUpperCase()===l;return t.jsxs("span",{className:"flex items-center flex-shrink-0",children:[r?t.jsx("span",{className:"px-1 py-0.5 rounded bg-sys-amber/20 text-sys-amber text-[9px] font-medium",children:"You"}):t.jsx("span",{className:"px-1 py-0.5 rounded bg-subtle-fill-hover text-fg-secondary",children:e.toUpperCase()}),!n&&t.jsx(pe,{className:"w-2.5 h-2.5 text-fg-muted mx-0.5 flex-shrink-0"})]},`${e}-${a}`)})})});function ds({channelName:s,onClick:a,active:n,compact:l,className:r}){const i=s.startsWith("#")?s:`#${s}`,c=e("inline-flex items-center flex-shrink-0","font-medium",l?"px-1.5 h-4 leading-4 rounded text-[10px]":"px-2 h-5 leading-5 rounded text-xs",n?"bg-sys-blue/20 text-sys-blue":"bg-sys-blue/10 text-sys-blue",a&&!n&&"hover:bg-sys-blue/20 cursor-pointer",r);return a?t.jsx("button",{type:"button",onClick:a,className:c,children:i}):t.jsx("span",{className:c,children:i})}function os(e){return{"--data-box-accent":x[e]}}function xs(e){const s=e.payload_type_name||d(e.payload_type??e.type),t=e.route_type_name||o(e.route_type??e.route);return{payloadType:s,routeType:t,payloadColor:X[s]??"zinc",routeColor:K[t]??"zinc"}}function ms(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function ps(e,s){if(s){const t=s(e);return{name:t.name,isCompanion:t.isCompanion,isRepeater:t.isRepeater}}return{name:null,isCompanion:!1,isRepeater:!1}}const hs=a.memo(function({packet:s,onClick:n,localHash:l,neighbors:r,resolveSource:d,isFlashing:o=!1,isTraceHighlighted:m,onTraceHover:p,traceTag:h,onViewTraceReport:u,dupeGroupPosition:g,isDupeGroupHovered:f=!1,onDupeGroupHover:y,dupeCount:j,getDecodedContent:b,onChannelClick:N}){const v=!j&&i(s.is_duplicate),w=void 0!==g,{payloadType:k,routeType:C,payloadColor:_,routeColor:S}=xs(s),P="tx_local"===s.packet_origin,H="TRACE"===k,T=ms(s.original_path),B=ms(s.forwarded_path),M=B.length>0?B:T,F=s.src_hash?(s.src_hash.startsWith("0x")?s.src_hash.slice(2,6):s.src_hash.slice(0,4)).toUpperCase():null,{name:L,isRepeater:D}=ps(s,d);let z=null,$=null,R=null,A=null;if("GRP_TXT"===k&&b){const e=b(s);(null==e?void 0:e.decrypted)&&($=e.senderName,R=e.channelName,A=e.channelHash,e.text&&(z=e.text))}else if("TXT_MSG"===k&&s.raw_packet)try{const e=se.fromHex(s.raw_packet);if(e.success&&e.packet){const s=te(e.packet.payload);s&&!s.encrypted&&(z=s.text)}}catch{}const E=$||(D?null:L),U=!!E,I=!U&&D&&!!L,V=!U&&!I&&"GRP_TXT"===k&&!z,Q=s.payload_length??s.length??0;s.lbt_attempts;const G=a.useCallback(()=>{H&&h&&u?u(h):n(s)},[H,h,u,n,s]),O=a.useCallback(()=>{H&&h&&p&&p(h),w&&y&&s.packet_hash&&y(s.packet_hash)},[H,h,p,w,y,s.packet_hash]),W=a.useCallback(()=>{p&&p(null),y&&y(null)},[p,y]),q=x[_]||x.zinc,K=f;return t.jsxs("div",{onClick:G,onMouseEnter:O,onMouseLeave:W,className:e("group relative cursor-pointer","hover:bg-subtle-fill",v&&!f&&"opacity-40",o&&"flash-row",P&&"bg-sys-indigo/5",m&&"bg-sys-teal/10"),children:[t.jsx("div",{className:e("absolute pointer-events-none transition-opacity duration-75",w?K?"opacity-100":"opacity-0":"opacity-0 group-hover:opacity-100"),style:(()=>{const e={pointerEvents:"none"};return"first"===g?{...e,borderTop:`2px solid ${q}`,borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:"none",borderRadius:"8px 8px 0 0",inset:"-2px -2px 0 -2px"}:"middle"===g?{...e,borderTop:"none",borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:"none",borderRadius:0,inset:"0 -2px"}:"last"===g?{...e,borderTop:"none",borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:`2px solid ${q}`,borderRadius:"0 0 8px 8px",inset:"0 -2px -2px -2px"}:{...e,border:`2px solid ${q}`,borderRadius:"8px",inset:"-2px"}})()}),t.jsxs("div",{className:"relative flex items-center gap-2 min-[600px]:gap-3 px-2 py-2 min-[600px]:px-3 min-[600px]:py-2.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 flex-shrink-0",children:[t.jsx("div",{className:"relative flex-shrink-0",children:U?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-1 ring-edge-subtle",style:{backgroundColor:J(Z(E).cleanName)},children:Z(E).emoji?t.jsx("span",{className:"text-base leading-none",children:Z(E).emoji}):t.jsx("span",{className:"text-white text-[10px] font-bold tracking-tighter",children:ee(E)})}):I?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:t.jsx(he,{className:"size-5 text-sys-blue"})}):V?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center bg-zinc-500/20 ring-1 ring-edge-subtle",children:t.jsx(ue,{className:"size-4 text-fg-muted"})}):t.jsx(is,{packet:s,variant:"avatar",size:"sm"})}),t.jsx("div",{className:"min-w-0",children:U?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-semibold text-[13px] text-fg-primary font-sans truncate max-w-[90px]",children:E}),F&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate",children:F})]}):I?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-semibold text-[13px] text-fg-primary font-sans truncate max-w-[90px]",children:L}),F&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate",children:F})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-bold text-[13px] text-fg-primary font-sans truncate",children:F||"—"}),L&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate max-w-[70px]",children:L})]})})]}),t.jsxs("div",{className:"flex-1 flex items-center gap-1 min-[600px]:gap-1.5 min-[900px]:gap-2 min-w-0",children:[t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(_),children:k}),j&&j>1&&t.jsxs("span",{className:"data-box data-box-compact flex-shrink-0",children:["×",j]}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(S),children:C}),t.jsxs("span",{className:"hidden min-[520px]:inline type-data-xs text-fg-muted flex-shrink-0",children:[Q,"B"]}),t.jsx("div",{className:"flex-1 min-w-0 overflow-hidden",children:z||R?t.jsxs("span",{className:"text-[11px] text-fg-secondary truncate block flex items-center gap-1",children:[R&&t.jsx(ds,{channelName:R,compact:!0,onClick:N&&A?e=>{e.stopPropagation(),N(A)}:void 0}),z&&t.jsx("span",{className:"italic truncate",children:z})]}):t.jsx(cs,{path:M,localHash:l})})]}),t.jsxs("div",{className:"flex items-center gap-1.5 flex-shrink-0",children:[t.jsx("span",{className:"data-box data-box-compact",children:c(s.timestamp)}),t.jsx(le,{rssi:s.rssi,snr:s.snr,compact:!0,showValues:!0,validated:re(s)})]})]})]})}),us=a.memo(function({packet:s,onClick:a,localHash:n,neighbors:l,resolveSource:r,isFlashing:d=!1,isTraceHighlighted:o,traceTag:m,onViewTraceReport:p,dupeGroupPosition:h,isDupeGroupHovered:u=!1,onDupeGroupHover:g,dupeCount:f,getDecodedContent:y,onChannelClick:j}){const{payloadType:b,routeType:N,payloadColor:v,routeColor:w}=xs(s),k="tx_local"===s.packet_origin,C="TRACE"===b,_=!f&&i(s.is_duplicate),S=ms(s.original_path),P=ms(s.forwarded_path),H=P.length>0?P:S,T=s._hopCount??H.length,B=s.src_hash?(s.src_hash.startsWith("0x")?s.src_hash.slice(2,6):s.src_hash.slice(0,4)).toUpperCase():null,{name:M,isRepeater:F}=ps(s,r);let L=null,D=null,z=null,$=null;if("GRP_TXT"===b&&y){const e=y(s);(null==e?void 0:e.decrypted)&&(D=e.senderName,z=e.channelName,$=e.channelHash,e.text&&(L=e.text))}else if("TXT_MSG"===b&&s.raw_packet)try{const e=se.fromHex(s.raw_packet);if(e.success&&e.packet){const s=te(e.packet.payload);s&&!s.encrypted&&(L=s.text)}}catch{}const R=D||(F?null:M),A=!!R,E=!A&&F&&!!M,U=!A&&!E&&"GRP_TXT"===b&&!L,I=s.payload_length??s.length??0,V=s.lbt_attempts??0,Q=x[v]||x.zinc;return t.jsxs("div",{onClick:()=>{C&&m&&p?p(m):a(s)},className:e("relative pl-3 pr-2.5 py-2 cursor-pointer","active:bg-subtle-fill-hover",_&&"opacity-40",d&&"flash-row",k&&"bg-sys-indigo/5",o&&"bg-sys-teal/10"),children:[t.jsx("div",{className:"absolute left-0 transition-all",style:(()=>{if(!h)return{opacity:0};const e=u?1:.4,s=u?"3px":"2px";return"first"===h?{backgroundColor:Q,opacity:e,width:s,top:"6px",bottom:0,borderRadius:"0 9999px 0 0"}:"middle"===h?{backgroundColor:Q,opacity:e,width:s,top:0,bottom:0,borderRadius:0}:"last"===h?{backgroundColor:Q,opacity:e,width:s,top:0,bottom:"6px",borderRadius:"0 0 9999px 0"}:{backgroundColor:Q,opacity:e,width:s,top:"6px",bottom:"6px",borderRadius:"9999px"}})()}),t.jsxs("div",{className:"flex items-start gap-2",children:[t.jsx("div",{className:"relative flex-shrink-0 mt-0.5",children:A?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-1 ring-edge-subtle",style:{backgroundColor:J(Z(R).cleanName)},children:Z(R).emoji?t.jsx("span",{className:"text-base leading-none",children:Z(R).emoji}):t.jsx("span",{className:"text-white text-[10px] font-bold tracking-tighter",children:ee(R)})}):E?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:t.jsx(he,{className:"size-5 text-sys-blue"})}):U?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center bg-zinc-500/20 ring-1 ring-edge-subtle",children:t.jsx(ue,{className:"size-4 text-fg-muted"})}):t.jsx(is,{packet:s,variant:"avatar",size:"sm"})}),t.jsxs("div",{className:"flex-1 min-w-0 space-y-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[A?t.jsx("span",{className:"font-medium text-[14px] text-fg-primary tracking-tight truncate min-w-0",children:R}):E?t.jsx("span",{className:"font-medium text-[14px] text-fg-primary tracking-tight truncate min-w-0",children:M}):t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"font-semibold text-[14px] text-fg-primary tracking-tight flex-shrink-0",children:B||"—"}),M&&t.jsx("span",{className:"text-[12px] text-fg-muted truncate min-w-0",children:M})]}),t.jsx("div",{className:"flex-1"}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(v),children:b}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(w),children:N}),f&&f>1&&t.jsxs("span",{className:"data-box data-box-compact flex-shrink-0",children:["×",f]}),t.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[t.jsx("span",{className:"type-data-xs text-fg-muted w-[28px] text-right",children:s.rssi}),t.jsx(le,{rssi:s.rssi,compact:!0,showValues:!1,validated:re(s)})]})]}),t.jsxs("div",{className:"flex items-center gap-1 type-data-xs text-fg-muted",children:[t.jsx("span",{className:"data-box data-box-compact flex-shrink-0",children:c(s.timestamp)}),I>0&&t.jsxs("span",{children:[I,"B"]}),V>0&&t.jsxs("span",{className:V>1?"text-sys-amber/60":void 0,children:["LBT:",V]}),null!=s.snr&&t.jsxs("span",{children:[s.snr.toFixed(0),"dB"]}),L||z?t.jsxs("span",{className:"text-[11px] text-fg-secondary truncate flex items-center gap-1 min-w-0",children:[z&&t.jsx(ds,{channelName:z,compact:!0,onClick:j&&$?e=>{e.stopPropagation(),j($)}:void 0}),L&&t.jsx("span",{className:"italic truncate",children:L})]}):T>0?t.jsx(cs,{path:H,localHash:n}):null]})]})]})]})}),gs=a.lazy(()=>Ee(()=>import("./PathMapMapLibre-Copwhk_5.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])));function fs(e){return`${(100*e).toFixed(0)}%`}function ys(e,s,t){let a;return a=0===s?t.muted:e>=1?t.success:e>=.5?t.secondary:e>=.25?t.poor:e>0?t.danger:t.muted,{color:a}}class js extends a.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?t.jsxs("div",{className:"h-[200px] flex items-center justify-center text-fg-muted",children:[t.jsx(ye,{className:"w-4 h-4 mr-2"}),"Map failed to load"]}):this.props.children}}function bs({path:s,neighbors:n,localNode:l,localHash:r,srcHash:i,dstHash:c,neighborAffinity:d,prefixLookup:o,hubNodes:x,traceSnr:h,advertiserSource:u}){const[g,f]=a.useState(null),y=a.useMemo(()=>{if(!u)return null;const e="wardrive"===u.nodeType;return{prefix:u.prefix||"??",candidates:[{hash:u.publicKey||u.prefix||"source",name:u.name,latitude:u.latitude,longitude:u.longitude,probability:1,isLocal:!1,isWardrive:e}],confidence:1,totalMatches:1,isSource:!0}},[u]),j=a.useMemo(()=>{if(u)return null;if(!i)return null;const e=p(i),s=n[i];if((null==s?void 0:s.latitude)&&(null==s?void 0:s.longitude)&&(0!==s.latitude||0!==s.longitude))return{prefix:e,candidates:[{hash:i,name:s.node_name||s.name||"Source",latitude:s.latitude,longitude:s.longitude,probability:1,isLocal:!1,isDirectNeighbor:!0===s.zero_hop}],confidence:1,totalMatches:1,isSource:!0};const t=(null==s?void 0:s.node_name)||(null==s?void 0:s.name)||i.slice(0,8);return{prefix:e,candidates:[{hash:i,name:t,latitude:0,longitude:0,probability:1,isLocal:!1}],confidence:1,totalMatches:1,isSource:!0}},[u,i,n]),b=a.useMemo(()=>{const e=(null==c?void 0:c.startsWith("0x"))?c.slice(2):c;if((!e||"00"===e||"0000000000000000"===e)&&l&&r){const e=p(r),s=0!==l.latitude||0!==l.longitude;return{prefix:e,candidates:[{hash:r,name:l.name||"Local Node",latitude:s?l.latitude:0,longitude:s?l.longitude:0,probability:1,isLocal:!0}],confidence:1,totalMatches:1,isDestination:!0}}if(!c)return null;const s=p(c);if(r&&c===r&&l){const e=0!==l.latitude||0!==l.longitude;return{prefix:s,candidates:[{hash:c,name:l.name||"Local Node",latitude:e?l.latitude:0,longitude:e?l.longitude:0,probability:1,isLocal:!0}],confidence:1,totalMatches:1,isDestination:!0}}const t=n[c];if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&(0!==t.latitude||0!==t.longitude))return{prefix:s,candidates:[{hash:c,name:t.node_name||t.name||"Destination",latitude:t.latitude,longitude:t.longitude,probability:1,isLocal:!1,isDirectNeighbor:!0===t.zero_hop}],confidence:1,totalMatches:1,isDestination:!0};const a=(null==t?void 0:t.node_name)||(null==t?void 0:t.name)||c.slice(0,8);return{prefix:s,candidates:[{hash:c,name:a,latitude:0,longitude:0,probability:1,isLocal:!1}],confidence:1,totalMatches:1,isDestination:!0}},[c,n,l,r]),N=a.useMemo(()=>function(e,s,t,a,n,l){if(!e||0===e.length)return{hops:[],overallConfidence:0,hasValidPath:!1};const r=e.length-1,i=e.map((i,c)=>{const d=c===r,o=e.length-c,{candidates:x,totalMatches:p}=function(e,s,t,a,n=!1,l,r,i){const c=Ue(s);let d;r&&(d=Ie(r,e,{position:i,isLastHop:n}).confidence);const{matches:o,probability:x}=function(e,s,t,a,n=!1){const l=e.toUpperCase(),r=[],i=t&&m(l,t);i&&r.push(t);for(const h of Object.keys(s))m(l,h)&&r.push(h);if(n&&i&&t&&1===r.length)return{matches:r,probability:1,bestMatch:t};if(n&&i&&r.length>1){const e=r.filter(e=>e!==t);if(1===e.length)return{matches:r,probability:1,bestMatch:e[0]}}const c=r.length>0?1/r.length:0,d=[...r].sort();let o=null,x=-1;if(1===d.length)o=d[0];else if(d.length>1&&a){for(const e of d){const s=a.get(e),t=s?"number"==typeof s?s:s.combinedScore:0;t>x&&(x=t,o=e)}o||(o=d[0])}else d.length>0&&(o=d[0]);let p=c;if(r.length>1&&a&&x>0){let e=0;for(const s of r){const t=a.get(s);e+=t?"number"==typeof t?t:t.combinedScore:0}e>0&&(p=Math.min(.95,x/e))}return{matches:r,probability:p,bestMatch:o}}(e,c,a,l,n),p=o.length,h=[],u=e.toUpperCase(),g=t&&void 0!==t.latitude&&void 0!==t.longitude&&(0!==t.latitude||0!==t.longitude);for(const y of o){if(a&&m(u,a)&&y===a&&g&&t){h.push({hash:y,name:t.name||"Local Node",latitude:t.latitude,longitude:t.longitude,probability:n?1:x,isLocal:!0});continue}const e=c[y];(null==e?void 0:e.latitude)&&(null==e?void 0:e.longitude)&&(0!==e.latitude||0!==e.longitude)&&h.push({hash:y,name:e.node_name||e.name||"Unknown",latitude:e.latitude,longitude:e.longitude,probability:x,isLocal:!1,isDirectNeighbor:!0===e.zero_hop})}const f=h.length;if(1===f)h[0].probability=d??1;else if(f>1)if(void 0!==d&&d>0){h[0].probability=d;const e=1-d,s=f-1;h.slice(1).forEach(t=>{t.probability=e/s})}else{let e=0;const s=h.map(s=>{if(s.isLocal)return{candidate:s,score:1};const a=null==l?void 0:l.get(s.hash);let n=.5;var r;let i;return g&&t&&(n=(r=function(e,s,t,a){const n=(t-e)*Math.PI/180,l=(a-s)*Math.PI/180,r=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(t*Math.PI/180)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))*6371e3}(t.latitude,t.longitude,s.latitude,s.longitude))<100?1:r<500?.9:r<1e3?.7:r<5e3?.5:r<1e4?.3:.1),a?i=.3*n+.3*a.hopConsistencyScore+.4*a.frequencyScore:(i=n,s.isDirectNeighbor&&(i=Math.max(i,.8))),e+=i,{candidate:s,score:i}});if(e>0)s.forEach(({candidate:s,score:t})=>{s.probability=Math.min(.95,t/e)});else{const e=1/f;h.forEach(s=>s.probability=e)}}return{candidates:h,totalMatches:p}}(i,s,t,a,d,n,l,o),h=x.length>0?Math.max(...x.map(e=>e.probability)):0;return{prefix:i,candidates:x,confidence:h,totalMatches:p}}),c=i.reduce((e,s)=>0===s.confidence?0:e*s.confidence,1),d=i.some(e=>e.candidates.length>0);return{hops:i,overallConfidence:c,hasValidPath:d}}(s,n,l,r,d,o),[s,n,l,r,d,o]),v=a.useMemo(()=>{const e=[];y?e.push(y):j&&e.push(j),e.push(...N.hops),b&&e.push(b);const s=e.reduce((e,s)=>0===s.confidence?0:e*s.confidence,1),t=e.some(e=>e.candidates.some(e=>0!==e.latitude||0!==e.longitude));return{hops:e,overallConfidence:s,hasValidPath:t}},[y,j,N,b]),w=a.useMemo(()=>{const e=getComputedStyle(document.documentElement);return{success:e.getPropertyValue("--sys-green").trim()||"#39D98A",secondary:e.getPropertyValue("--sys-indigo").trim()||"#F9D26F",poor:e.getPropertyValue("--signal-poor").trim()||"#FF8A5C",danger:e.getPropertyValue("--sys-red").trim()||"#FF5C7A",muted:e.getPropertyValue("--text-muted").trim()||"#767688"}},[]);return v.hasValidPath?t.jsxs("div",{className:"h-full flex flex-col space-y-2",children:[t.jsxs("div",{className:"flex items-center justify-between text-xs",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"text-fg-muted",children:"Path Confidence:"}),t.jsx("span",{className:(k=v.overallConfidence,k>=1?"text-sys-green":k>=.5?"text-sys-indigo":k>=.25?"text-signal-poor":k>0?"text-sys-red":"text-fg-muted"),children:fs(v.overallConfidence)}),t.jsx("button",{className:"text-fg-muted hover:text-fg-secondary transition-colors",title:"Confidence is calculated based on how many known nodes match each path prefix. Multiple matches reduce confidence due to collision probability.",children:t.jsx(fe,{className:"w-3 h-3"})})]}),t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-sys-green"}),t.jsx("span",{className:"text-fg-muted",children:"Exact"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-sys-indigo"}),t.jsx("span",{className:"text-fg-muted",children:"Multi"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-fg-muted"}),t.jsx("span",{className:"text-fg-muted",children:"Unknown"})]})]})]}),t.jsx("div",{className:"flex-1 min-h-0 overflow-hidden",children:t.jsx(js,{children:t.jsx(a.Suspense,{fallback:t.jsx("div",{className:"h-full bg-elevated flex items-center justify-center text-fg-muted text-sm",children:"Loading map..."}),children:t.jsx(gs,{resolvedPath:v,localNode:l,hubNodes:x,hoveredHopIndex:g,onHoverHop:f,traceSnr:h})})})}),t.jsx("div",{className:"flex flex-wrap items-center gap-1.5",children:v.hops.map((s,a)=>{var n,l,r;const i=!0===s.isSource,c=!0===s.isDestination,d=g===a;let o;return o=i?`Source: ${(null==(n=s.candidates[0])?void 0:n.name)||"Unknown"}`:c?`Destination: ${(null==(l=s.candidates[0])?void 0:l.name)||"Unknown"}`:0===s.totalMatches?"No matching nodes found":1===s.totalMatches?`Exact match: ${(null==(r=s.candidates[0])?void 0:r.name)||"Unknown"}`:`${s.totalMatches} possible matches (${(100*s.confidence).toFixed(0)}% confidence)`,t.jsxs("div",{className:e("flex items-center gap-1 px-1.5 py-0.5 rounded type-data-xs cursor-pointer transition-all",d?"bg-sys-blue/20 ring-1 ring-sys-blue/50":"bg-elevated hover:bg-subtle",i&&"border border-sys-green/30",c&&"border border-sys-blue/30"),title:o,onMouseEnter:()=>f(a),onMouseLeave:()=>f(null),children:[i&&t.jsx("span",{className:"text-sys-green text-[8px] mr-0.5",children:"SRC"}),c&&t.jsx("span",{className:"text-sys-blue text-[8px] mr-0.5",children:"DST"}),t.jsx("span",{style:ys(s.confidence,s.totalMatches,w),children:s.prefix}),!i&&!c&&s.totalMatches>1&&t.jsxs("span",{className:"text-fg-muted",children:["×",s.totalMatches]}),!i&&!c&&0===s.totalMatches&&t.jsx("span",{className:"text-fg-muted",children:"?"})]},a)})})]}):t.jsxs("div",{className:"flex items-center justify-center text-fg-muted text-xs py-4",children:[t.jsx(ge,{className:"w-3.5 h-3.5 mr-1.5 opacity-50"}),"No location data available for path nodes"]});var k}function Ns(e){return e.match(/.{1,2}/g)||[]}function vs(e){return null!==e&&e.startsWith("payload:")}const ws=15,ks="color-mix(in srgb, var(--elevated) 60%, var(--body))",Cs="\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n ",_s=2,Ss={type:"tween",duration:.25,ease:[.25,.1,.25,1]};function Ps(e,s){return e?`inset 0 0 0 ${_s}px ${x[s]}`:Cs}function Hs(e,s){return e?s:`color-mix(in srgb, ${s} ${ws}%, transparent)`}function Ts({segments:e,selectedSegment:s,onSegmentClick:n}){const[l,r]=a.useState(null),[i,c]=a.useState(null),d=e.some(e=>void 0!==e.id)&&n,o=[];for(const t of e){const e=Ns(t.hex);for(const s of e)o.push({byte:s.toUpperCase(),color:t.color,id:t.id})}const m=[];for(let t=0;t{const o=e.length<16;return t.jsx("div",{className:"flex rounded-md overflow-hidden",children:e.map(({byte:a,color:m,id:p},h)=>{const u=h===e.length-1,g=o&&u,f=x[m],y=p?l===p:i===m,j=Boolean(p&&s===p),b=y||j;return t.jsx("span",{className:"w-[1.75rem] text-xs text-center py-0.5 font-mono select-text "+(d?"cursor-pointer":""),style:{backgroundColor:Hs(b,f),color:b?"rgba(255,255,255,0.95)":f,transition:b?"none":"background-color 0.15s ease-out, color 0.15s ease-out",touchAction:"manipulation",...g?{borderRadius:"0 0.375rem 0.375rem 0"}:{}},onMouseEnter:()=>{p?r(p):c(m)},onMouseLeave:()=>{r(null),c(null)},onClick:()=>p&&(null==n?void 0:n(p)),onTouchStart:()=>{p?r(p):c(m)},onTouchEnd:()=>{r(null),c(null)},children:a},h)})},a)})})}function Bs({rawHex:e,hexSegments:s,selectedSegment:n,onSegmentClick:l}){const[r,i]=a.useState(!1),c=a.useCallback(async()=>{try{await navigator.clipboard.writeText(e.toUpperCase()),i(!0),setTimeout(()=>i(!1),2e3)}catch(s){console.error("Failed to copy:",s)}},[e]);return t.jsxs("div",{className:"bg-black rounded-2xl p-6 relative",children:[t.jsx(Ts,{segments:s,selectedSegment:n,onSegmentClick:l}),t.jsx("button",{onClick:c,className:"absolute bottom-3 right-3 flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg bg-subtle-fill-hover hover:bg-subtle-fill-strong text-fg-muted hover:text-fg-secondary transition-all text-xs font-sans",title:"Copy raw packet hex",children:r?t.jsxs(t.Fragment,{children:[t.jsx(je,{className:"w-3.5 h-3.5 text-sys-green"}),t.jsx("span",{className:"text-sys-green",children:"Copied"})]}):t.jsxs(t.Fragment,{children:[t.jsx(oe,{className:"w-3.5 h-3.5"}),t.jsx("span",{children:"Copy"})]})})]})}function Ms({bits:e,field:s,value:a,binary:n}){return t.jsxs("tr",{children:[t.jsx("td",{className:"py-1.5 text-xs text-fg-muted tabular-nums",children:e}),t.jsx("td",{className:"py-1.5 text-sm text-fg-secondary",children:s}),t.jsx("td",{className:"py-1.5",children:(()=>{if("Payload Type"===s){const e=X[a]||"zinc";return t.jsx(r,{color:e,children:a})}if("Route Type"===s){const e=K[a]||"zinc";return t.jsx(r,{color:e,children:a})}return t.jsx("span",{className:"text-sm text-fg-primary",children:a})})()}),t.jsx("td",{className:"py-1.5 type-data-xs text-sys-cyan",children:n})]})}function Fs({id:e,title:s,color:a,hexBytes:n,startByte:l,endByte:i,isSelected:c,children:d}){const o=n?Ns(n):[];return t.jsxs(Ge.div,{layout:"position",layoutId:e,transition:Ss,className:"w-full min-w-0 overflow-hidden rounded-xl p-4 sm:p-5 space-y-4",style:{backgroundColor:ks,boxShadow:Ps(c,a)},children:[t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 min-w-0",children:[t.jsx(r,{color:a,children:s}),o.length>0&&o.length<=16&&o.map((e,s)=>t.jsx(r,{color:a,className:"font-mono",children:e.toUpperCase()},s))]}),t.jsxs("span",{className:"type-data-xs text-fg-muted flex-shrink-0",children:["Bytes ",l,"-",i]})]}),t.jsx("div",{className:"min-w-0 overflow-hidden",children:d})]})}function Ls({advert:e,timestamp:s}){const a=f(s||e.timestamp);return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-indigo/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-indigo) 0%, var(--sys-blue) 100%)"},children:t.jsx(he,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.name||"Unknown Node"}),t.jsx("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:e.nodeType})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[void 0!==e.latitude&&void 0!==e.longitude&&t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ge,{className:"w-4 h-4 text-sys-indigo flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-mono",children:[e.latitude.toFixed(5),"°, ",e.longitude.toFixed(5),"°"]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-indigo flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]})]})]})})}function Ds({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-teal/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-teal) 0%, var(--sys-cyan) 100%)"},children:t.jsx(Se,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.channelName||"Channel Data"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:[e.dataLength," bytes • ",e.decrypted?"Decrypted":"Encrypted"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(Ne,{className:"w-4 h-4 text-sys-teal flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-sans",children:["Channel: ",t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-teal flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]}),e.decrypted&&e.decryptedHex&&t.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:[t.jsx("p",{className:"type-micro text-fg-muted mb-1 font-sans",children:"Decrypted Data"}),t.jsx("div",{className:"max-w-full overflow-x-auto",children:t.jsx(Ve,{size:"compact",copy:!0,className:"inline-block",children:t.jsx("span",{className:"break-all text-xs",children:e.decryptedHex.toUpperCase()})})})]})]})]})})}function zs({decoded:e,timestamp:s,isLoading:n=!1,onDecrypted:l}){const r=s?f(s):"Unknown",[i,c]=a.useState(""),[d,o]=a.useState(!1),[x,m]=a.useState(null),[p,h]=a.useState(!1),u=a.useCallback(async()=>{if(i.trim()&&e.ciphertextHex&&e.macHex){o(!0),m(null);try{const s=parseInt(e.channelHash,16),t=y(e.macHex),a=y(e.ciphertextHex),n=await j(i.trim(),s,t,a);if(n.success){const s=n.result.plaintext,t=new TextDecoder("utf-8",{fatal:!1}).decode(s.slice(5)),a=t.indexOf(": "),r={...e,channelName:n.result.channelName,decrypted:!0,timestamp:s[0]|s[1]<<8|s[2]<<16|s[3]<<24,flags:s[4],senderName:a>0?t.slice(0,a):void 0,text:a>0?t.slice(a+2):t};null==l||l(r),c(""),h(!1)}else m(n.error)}catch(s){m(s instanceof Error?s.message:"Unknown error")}finally{o(!1)}}},[i,e,l]);return n?t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-xl p-4 sm:p-5",style:{backgroundColor:"color-mix(in srgb, var(--elevated) 60%, var(--body))",boxShadow:"\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n "},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-3 h-[15px]",children:[t.jsx("div",{className:"h-2.5 w-12 rounded bg-subtle-fill-hover animate-pulse"}),t.jsx("div",{className:"h-2.5 w-16 rounded bg-subtle-fill-hover animate-pulse"})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tl-md",style:{background:"color-mix(in srgb, var(--sys-blue) 30%, transparent)"},children:t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("div",{className:"h-3.5 w-48 rounded bg-subtle-fill-strong animate-pulse"}),t.jsx("div",{className:"h-3.5 w-32 rounded bg-subtle-fill-strong animate-pulse"})]})})]})}):e.decrypted?t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-xl p-4 sm:p-5",style:{backgroundColor:"color-mix(in srgb, var(--elevated) 60%, var(--body))",boxShadow:"\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n "},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.senderName&&t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["From ",t.jsx("span",{className:"text-fg-secondary font-medium",children:e.senderName})]}),e.channelName&&t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["in ",t.jsx("span",{className:"text-sys-cyan font-medium",children:e.channelName})]})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tl-md",style:{background:"linear-gradient(135deg, var(--sys-blue) 0%, color-mix(in srgb, var(--sys-blue) 85%, var(--sys-cyan)) 100%)"},children:t.jsx("p",{className:"text-sm text-white font-sans leading-relaxed whitespace-pre-wrap break-words",children:e.text})})]})}):t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-zinc-500/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--zinc-500) 0%, color-mix(in srgb, var(--zinc-500) 70%, black) 100%)"},children:t.jsx(we,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.isPublicHashChannel?"Public Hash Channel":"Encrypted Message"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:["Channel hash: ",t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-zinc-400 flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:r})]}),e.ciphertextHex&&e.macHex&&t.jsx("div",{className:"space-y-2",children:p?t.jsxs("div",{className:"space-y-2",children:[t.jsxs("div",{className:"flex gap-2",children:[t.jsx("input",{type:"text",value:i,onChange:e=>c(e.target.value),placeholder:"Channel name (e.g. south-bay)",className:"flex-1 px-3 py-1.5 text-sm rounded-lg bg-subtle-fill-strong border border-edge-subtle text-fg-primary placeholder:text-fg-muted focus:outline-none focus:border-zinc-500",onKeyDown:e=>"Enter"===e.key&&u(),disabled:d}),t.jsx("button",{onClick:u,disabled:d||!i.trim(),className:"px-3 py-1.5 text-sm font-medium rounded-lg bg-zinc-600 hover:bg-zinc-500 text-white disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:d?"Testing...":"Try"}),t.jsx("button",{onClick:()=>{h(!1),m(null),c("")},className:"px-2 py-1.5 text-sm rounded-lg hover:bg-subtle-fill-strong text-fg-muted transition-colors",children:"×"})]}),x&&t.jsx("p",{className:"text-xs text-sys-red",children:x})]}):t.jsx("button",{onClick:()=>h(!0),className:"text-xs text-zinc-400 hover:text-zinc-300 underline underline-offset-2 transition-colors",children:"Know the channel name? Try to decrypt"})}),!p&&t.jsx("p",{className:"text-xs text-fg-muted",children:e.isPublicHashChannel?"Public hash channel message. Key not in common channel list.":"Unknown hash channel. Channel name required for decryption."})]})]})})}function $s({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:"linear-gradient(135deg, var(--sys-green) 0%, var(--sys-teal) 100%)"},children:t.jsx(_e,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:"Acknowledgment"}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:["CRC: ",t.jsxs("span",{className:"font-mono text-sys-green",children:["0x",e.crc]})," · ",a]})]})]})}function Rs({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=e.path.length;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-amber/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-amber) 0%, var(--sys-orange) 100%)"},children:t.jsx(Ce,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:"Path Response"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:[n," ",1===n?"hop":"hops"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-amber flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]}),e.path.length>0&&t.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:t.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.path.map((e,s)=>t.jsxs("div",{className:"flex items-center gap-2",children:[s>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-amber"}),t.jsx(r,{color:"amber",className:"font-mono",children:e})]},s))})})]})]})})}function As({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=e.pathHashes.length,l=e.snrValues.length;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-blue/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-blue) 0%, var(--sys-indigo) 100%)"},children:t.jsx(ke,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:["Trace ",e.isComplete?"Complete":"In Progress"]}),t.jsxs("p",{className:"text-sm text-fg-muted mt-0.5",children:["Tag: 0x",e.traceTag.slice(0,8),e.isComplete&&" • ✓"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary",children:a})]}),t.jsxs("div",{className:"flex items-center gap-4 text-xs text-fg-muted",children:[t.jsxs("span",{children:[n," target ",1===n?"hop":"hops"]}),t.jsx("span",{children:"•"}),t.jsxs("span",{children:[l," SNR ",1===l?"sample":"samples"]}),0!==e.authCode&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"•"}),t.jsxs("span",{children:["Auth: ",e.authCode]})]})]}),e.pathHashes.length>0&&t.jsx("div",{className:"flex flex-wrap items-center gap-2 pt-1",children:e.pathHashes.map((s,a)=>{const n=e.snrValues[a],l=void 0!==n?(e=>e>=7?"green":e>=0?"yellow":e>=-5?"orange":"red")(n):"zinc",i=void 0!==n;return t.jsxs("div",{className:"flex items-center gap-2",children:[a>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx(r,{color:i?"blue":"zinc",className:"font-mono",children:s}),i&&t.jsxs(r,{color:l,className:"font-mono",children:[n>=0?"+":"",Number.isInteger(n)?n:n.toFixed(1),"dB"]})]})]},a)})})]})]})})}function Es({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return e.encrypted?t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:"linear-gradient(135deg, var(--sys-indigo) 0%, var(--sys-blue) 100%)"},children:t.jsx(we,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:"Encrypted Message"}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:[e.srcHash," → ",e.destHash," · ",a]})]})]}):t.jsxs("div",{className:"mb-4",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1.5 px-1",children:[t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:[t.jsx("span",{className:"font-mono text-fg-secondary",children:e.srcHash})," → ",t.jsx("span",{className:"font-mono text-fg-secondary",children:e.destHash})]}),t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["· ",a]})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tr-md ml-auto",style:{background:"linear-gradient(135deg, var(--sys-green) 0%, var(--sys-teal) 100%)"},children:t.jsx("p",{className:"text-sm text-white font-sans leading-relaxed whitespace-pre-wrap break-words",children:e.text})})]})}function Us({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=(e.partNumber+1)/e.totalParts*100;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-yellow/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-yellow) 0%, var(--sys-amber) 100%)"},children:t.jsx(be,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:"Multipart Segment"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:["Part ",e.partNumber+1," of ",e.totalParts]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsx("div",{children:t.jsx("div",{className:"h-2 bg-subtle-fill-strong rounded-full overflow-hidden",children:t.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${n}%`,background:"linear-gradient(90deg, var(--sys-yellow), var(--sys-amber))"}})})}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(Ne,{className:"w-4 h-4 text-sys-yellow flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-sans",children:["Message ID: ",t.jsx("span",{className:"font-mono",children:e.messageId})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-yellow flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]})]})]})})}function Is({decoded:e,timestamp:s,payloadType:a}){const n=s?f(s):"Unknown",l=(()=>{switch(a){case u.REQ:return{icon:Te,gradient:"var(--sys-orange), var(--sys-red)",bg:"rgba(249, 115, 22, 0.15)",label:"Request"};case u.RESPONSE:return{icon:He,gradient:"var(--sys-green), var(--sys-teal)",bg:"rgba(34, 197, 94, 0.15)",label:"Response"};case u.ANON_REQ:return{icon:we,gradient:"var(--sys-indigo), var(--sys-pink)",bg:"rgba(91, 91, 214, 0.15)",label:"Anonymous Request"};default:return{icon:Pe,gradient:"var(--sys-gray), var(--sys-slate)",bg:"rgba(107, 114, 128, 0.15)",label:e.payloadTypeName}}})(),r=l.icon;return t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:`linear-gradient(135deg, ${l.gradient})`},children:t.jsx(r,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:l.label}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:[e.length," bytes · ",n]})]})]})}function Vs({pathHex:e}){if(!e)return null;const s=Ns(e);return t.jsx("div",{className:"flex flex-wrap items-center gap-2 py-2",children:s.map((e,s)=>t.jsxs("div",{className:"flex items-center gap-2",children:[s>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-amber flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(Ve,{size:"compact",copy:!0,children:e.toUpperCase()}),t.jsx("span",{className:"text-xs text-fg-muted font-sans tabular-nums w-4 text-left",children:s+1})]})]},s))})}function Qs({decoded:e,payloadType:s}){const a=g[s]||`TYPE_${s}`;switch(e.type){case"advert":{const s="chat"===e.nodeType?"companion":e.nodeType.replace("_"," "),a=void 0!==e.latitude&&void 0!==e.longitude&&!(0===e.latitude&&0===e.longitude);return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Role:"})," ",s]}),e.name&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Name:"})," ",e.name]}),a&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Location:"})," ",e.latitude.toFixed(4),"°, ",e.longitude.toFixed(4),"°"]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Time:"})," ",f(e.timestamp)]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Flags:"})," ",e.flagsDescription]})]})}case"ack":return t.jsx("div",{className:"text-xs text-fg-primary space-y-0.5",children:t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"CRC:"})," 0x",e.crc]})});case"path":return t.jsx("div",{className:"text-xs text-fg-primary space-y-1",children:t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Path:"})," ",e.pathString||"(empty)"]})});case"trace":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-1",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Tag:"})," 0x",e.traceTag]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Target Path:"})," ",e.pathString||"(empty)"]}),e.snrValues.length>0&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"SNR:"})," ",e.snrValues.map(e=>`${e>=0?"+":""}${Number.isInteger(e)?e:e.toFixed(1)}dB`).join(" → ")]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Status:"})," ",e.isComplete?"✓ Complete":`In progress (${e.snrValues.length}/${e.pathHashes.length})`]})]});case"txt_msg":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Src:"})," ",e.srcHash]}),e.encrypted?t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted content"}):t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Text:"})," ",e.text]})]});case"grp_txt":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Channel:"})," ",e.channelName?t.jsx("span",{className:"text-sys-green",children:e.channelName}):e.isPublicHashChannel?t.jsx("span",{className:"text-sys-indigo",children:"Public Hash Channel"}):t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]}),e.decrypted?t.jsxs(t.Fragment,{children:[e.senderName&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"From:"})," ",e.senderName]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Text:"})," ",e.text]})]}):e.isPublicHashChannel?t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted (public hash channel)"}):t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted (unknown channel)"})]});case"grp_data":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Channel:"})," ",e.channelName?t.jsx("span",{className:"text-sys-teal",children:e.channelName}):t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Data:"})," ",e.dataLength," bytes ",e.decrypted?"(decrypted)":"(encrypted)"]})]});case"multipart":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Part:"})," ",e.partNumber+1,"/",e.totalParts]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Message ID:"})," ",e.messageId]})]});case"control":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Control:"})," ",e.subtypeName]}),e.dataLength>0&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Data:"})," ",e.dataLength," bytes"]})]});case"req":case"response":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Src:"})," ",e.srcHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Ciphertext:"})," ",e.ciphertextLength," bytes"]})]});case"anon_req":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Pub Key:"})," ",t.jsxs("span",{className:"font-mono break-all",children:[e.senderPublicKey.slice(0,16),"…"]})]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Ciphertext:"})," ",e.ciphertextLength," bytes"]})]});default:return t.jsxs("p",{className:"text-xs text-fg-secondary",children:[a," (","length"in e?e.length:0," bytes)"]})}}const Gs=a.memo(function({packet:e,decodedGrpTxt:s}){var n,l;const i=e.raw_packet||"",c=i.length/2,d=h(),[o,x]=a.useState(null),[m,p]=a.useState(null),[g,y]=a.useState(!1),[j,b]=a.useState(null),N=a.useCallback(e=>{b(s=>s===e?null:e)},[]),v=a.useMemo(()=>z(i),[i]),w=null==(n=null==v?void 0:v.packet)?void 0:n.payloadType,k=(null==v?void 0:v.payloadHex)||"",C=null==(l=null==v?void 0:v.packet)?void 0:l.payload,_=w===u.GRP_TXT,S=w===u.GRP_DATA,P=_&&!s&&(!d||g);if(a.useEffect(()=>{if(x(null),y(!1),s)return;if(!_||!C||C.length<4)return;if(!d)return void y(!0);y(!0);let e=!1;return ae(C).then(s=>{e||(x(s),y(!1))}),()=>{e=!0}},[k,_,d,s]),a.useEffect(()=>{if(p(null),!S||!C||C.length<4)return;if(!d)return;let e=!1;return ne(C).then(s=>{e||p(s)}),()=>{e=!0}},[k,S,d]),!v||0===i.length)return t.jsx("div",{className:"p-4 text-center text-fg-muted",children:t.jsx("p",{className:"text-sm",children:"No raw packet data available"})});const{packet:H}=v;let T=v.decoded;s&&"grp_txt"===v.decoded.type?T=s:o&&"grp_txt"===v.decoded.type?T=o:m&&"grp_data"===v.decoded.type&&(T=m);const B=a.useMemo(()=>function(e,s){switch(e.type){case"advert":return function(e,s){const a=[];let n=0;const l=s.slice(0,64);a.push({id:"payload:publicKey",title:"Public Key",color:"pink",hex:l,startByte:n,endByte:n+31,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:e.publicKey.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Ed25519 public key (32 bytes)"})]})}),n+=32;const r=s.slice(64,72);a.push({id:"payload:timestamp",title:"Timestamp",color:"orange",hex:r,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:r.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.timestamp," (",f(e.timestamp),")"]})]})}),n+=4;const i=s.slice(72,200);a.push({id:"payload:signature",title:"Signature",color:"teal",hex:i,startByte:n,endByte:n+63,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:e.signature.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Ed25519 signature (64 bytes)"})]})}),n+=64;const c=s.slice(200,202);if(a.push({id:"payload:flags",title:"Flags",color:"blue",hex:c,startByte:n,endByte:n,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.flags.toString(16).padStart(2,"0").toUpperCase()]}),t.jsx("p",{className:"text-xs text-fg-primary mt-1",children:e.flagsDescription}),t.jsxs("p",{className:"text-xs text-fg-muted",children:["Node Type: ",e.nodeType]})]})}),n+=1,void 0!==e.latitude){const l=s.slice(2*n,2*n+8);a.push({id:"payload:latitude",title:"Latitude",color:"green",hex:l,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.latitude.toFixed(6),"°"]})]})}),n+=4}if(void 0!==e.longitude){const l=s.slice(2*n,2*n+8);a.push({id:"payload:longitude",title:"Longitude",color:"indigo",hex:l,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.longitude.toFixed(6),"°"]})]})}),n+=4}if(e.name){const l=s.slice(2*n),r=l.length/2;a.push({id:"payload:name",title:"Name",color:"amber",hex:l,startByte:n,endByte:n+r-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:['"',e.name,'"']})]})})}return a}(e,s);case"ack":return function(e,s){return[{id:"payload:crc",title:"CRC",color:"green",hex:s.slice(0,8),startByte:0,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.crc]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"CRC32 of acknowledged packet"})]})}]}(e,s);case"grp_txt":return function(e,s){const a=[];a.push({id:"payload:channelHash",title:"Channel Hash",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.channelHash]}),e.channelName&&t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:["Channel: ",e.channelName]})]})}),e.macHex&&a.push({id:"payload:mac",title:"MAC",color:"indigo",hex:s.slice(2,6),startByte:1,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.macHex.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Truncated HMAC-SHA256"})]})});const n=s.slice(6);return n&&a.push({id:"payload:ciphertext",title:e.decrypted?"Message":"Ciphertext",color:e.decrypted?"green":"zinc",hex:n,startByte:3,endByte:3+n.length/2-1,decoded:e.decrypted?t.jsxs(t.Fragment,{children:[t.jsxs("p",{className:"text-sm text-fg-primary",children:['"',e.text,'"']}),e.senderName&&t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:["From: ",e.senderName]})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:n.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"AES-128-ECB encrypted"})]})}),a}(e,s);case"grp_data":return function(e,s){const a=[];a.push({id:"payload:channelHash",title:"Channel Hash",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.channelHash]}),e.channelName&&t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:["Channel: ",e.channelName]})]})}),e.macHex&&a.push({id:"payload:mac",title:"MAC",color:"indigo",hex:s.slice(2,6),startByte:1,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.macHex.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Truncated HMAC-SHA256"})]})});const n=s.slice(6);return n&&a.push({id:"payload:ciphertext",title:e.decrypted?"Decrypted Data":"Encrypted Data",color:e.decrypted?"green":"zinc",hex:n,startByte:3,endByte:3+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:(e.decryptedHex||n).toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.dataLength," bytes",e.decrypted?"":" (AES-128-ECB encrypted)"]})]})}),a}(e,s);case"path":return function(e,s){const a=[];if(a.push({id:"payload:pathLength",title:"Path Length",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",children:e.pathLength}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.pathLength," hop",1!==e.pathLength?"s":""]})]})}),e.path.length>0){const n=s.slice(2,2+2*e.pathLength);a.push({id:"payload:path",title:"Path Hops",color:"amber",hex:n,startByte:1,endByte:e.pathLength,decoded:t.jsx(t.Fragment,{children:t.jsx("div",{className:"flex flex-wrap items-center gap-1",children:e.path.map((e,s)=>t.jsxs("span",{className:"flex items-center gap-1",children:[s>0&&t.jsx(xe,{className:"w-3 h-3 text-fg-muted"}),t.jsx(r,{color:"amber",className:"font-mono",children:e})]},s))})})})}if(null!=e.extraType){const n=1+e.pathLength;a.push({id:"payload:extraType",title:"Extra Type",color:"indigo",hex:s.slice(2*n,2*n+2),startByte:n,endByte:n,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",children:e.extraTypeName??`0x${e.extraType.toString(16).padStart(2,"0")}`}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Bundled payload type"})]})})}if(e.extraData){const n=1+e.pathLength+1,l=s.slice(2*n);l&&a.push({id:"payload:extraData",title:"Extra Data",color:"indigo",hex:l,startByte:n,endByte:n+l.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[l.length/2," bytes"]})]})})}return a}(e,s);case"trace":return function(e,s){const a=[];a.push({id:"payload:crc",title:"Trace Tag",color:"blue",hex:s.slice(0,8),startByte:0,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.traceTag]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Unique trace request identifier"})]})}),a.push({id:"payload:mac",title:"Auth Code",color:"indigo",hex:s.slice(8,16),startByte:4,endByte:7,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.authCode}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Authentication/verification code"})]})}),a.push({id:"payload:flags",title:"Flags",color:"amber",hex:s.slice(16,18),startByte:8,endByte:8,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.flags.toString(16).toUpperCase().padStart(2,"0")]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:0===e.flags?"No flags set":`Flags: ${e.flags.toString(2).padStart(8,"0")}b`})]})});const n=s.slice(18);return n&&a.push({id:"payload:path",title:"Target Path",color:"indigo",hex:n,startByte:9,endByte:9+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"flex flex-wrap items-center gap-1",children:e.pathHashes.map((s,a)=>{const n=e.snrValues[a],l=void 0!==n?Y(n):"zinc";return t.jsxs("span",{className:"flex items-center gap-1",children:[a>0&&t.jsx(xe,{className:"w-3 h-3 text-fg-muted"}),t.jsx(r,{color:"indigo",className:"font-mono",children:s}),void 0!==n&&t.jsxs(r,{color:l,className:"font-mono",children:[n>=0?"+":"",Number.isInteger(n)?n:n.toFixed(1),"dB"]})]},a)})}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.pathHashes.length," target ",1===e.pathHashes.length?"hop":"hops",e.snrValues.length>0&&` • ${e.snrValues.length} SNR ${1===e.snrValues.length?"value":"values"} collected`,e.isComplete&&" • ✓ Complete"]})]})}),a}(e,s);case"multipart":return function(e,s){const a=[];a.push({id:"payload:msgId",title:"Message ID",color:"blue",hex:s.slice(0,4),startByte:0,endByte:1,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.messageId.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Unique message identifier"})]})}),a.push({id:"payload:partNum",title:"Part Number",color:"amber",hex:s.slice(4,6),startByte:2,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.partNumber}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"0-indexed part number"})]})}),a.push({id:"payload:totalParts",title:"Total Parts",color:"orange",hex:s.slice(6,8),startByte:3,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.totalParts}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:["Part ",e.partNumber+1," of ",e.totalParts]})]})});const n=s.slice(8);return n&&a.push({id:"payload:partData",title:"Part Data",color:"cyan",hex:n,startByte:4,endByte:4+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:n.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[n.length/2," bytes"]})]})}),a}(e,s);default:return[{id:"payload:ciphertext",title:"Raw Data",color:"zinc",hex:s,startByte:0,endByte:s.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:s.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[s.length/2," bytes"]})]})}]}}(T,v.payloadHex),[T,v.payloadHex]),M="payload"===j||vs(j),F=a.useMemo(()=>{const e=[{id:"header",hex:v.headerHex,color:"red"},...v.transportCodesHex?[{id:"transportCodes",hex:v.transportCodesHex,color:"indigo"}]:[],{id:"pathLength",hex:v.pathLengthHex,color:"green"},...v.pathDataHex?[{id:"pathData",hex:v.pathDataHex,color:"amber"}]:[]];return M?[...e,...(s=B,s.map(e=>({id:e.id,hex:e.hex,color:e.color})))]:[...e,{id:"payload",hex:v.payloadHex,color:"cyan"}];var s},[v,M,B]);return t.jsxs("div",{className:"font-mono space-y-2 min-w-0 overflow-hidden",children:[(()=>{switch(T.type){case"advert":return t.jsx(Ls,{advert:T,timestamp:e.timestamp});case"grp_data":return t.jsx(Ds,{decoded:T,timestamp:e.timestamp});case"grp_txt":return t.jsx(zs,{decoded:T,timestamp:e.timestamp,isLoading:P,onDecrypted:x});case"ack":return t.jsx($s,{decoded:T,timestamp:e.timestamp});case"path":return t.jsx(Rs,{decoded:T,timestamp:e.timestamp});case"trace":return t.jsx(As,{decoded:T,timestamp:e.timestamp});case"txt_msg":return t.jsx(Es,{decoded:T,timestamp:e.timestamp});case"multipart":return t.jsx(Us,{decoded:T,timestamp:e.timestamp});case"generic":return H.payloadType===u.REQ||H.payloadType===u.RESPONSE||H.payloadType===u.ANON_REQ?t.jsx(Is,{decoded:T,timestamp:e.timestamp,payloadType:H.payloadType}):null;default:return null}})(),t.jsx(Bs,{rawHex:i,hexSegments:F,selectedSegment:j,onSegmentClick:N}),t.jsx(Qe,{children:t.jsx(Ge.div,{layout:!0,transition:Ss,className:"space-y-2 min-w-0",children:(()=>{var e,s,a,n;const l=[{id:"header",title:"Header",color:"red",startByte:0,endByte:0,hexBytes:`0x${v.headerHex.toUpperCase()}`,condition:!0,content:t.jsxs("table",{className:"w-full text-left",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"type-micro text-fg-muted border-b border-edge-subtle font-sans",children:[t.jsx("th",{className:"py-1 font-medium",children:"Bits"}),t.jsx("th",{className:"py-1 font-medium",children:"Field"}),t.jsx("th",{className:"py-1 font-medium",children:"Value"}),t.jsx("th",{className:"py-1 font-medium",children:"Binary"})]})}),t.jsx("tbody",{children:v.headerFields.map(e=>t.jsx(Ms,{...e},e.bits))})]})},{id:"transportCodes",title:"Transport Codes",color:"indigo",startByte:1,endByte:4,hexBytes:(null==(e=v.transportCodesHex)?void 0:e.toUpperCase())||"",condition:!!v.transportCodesHex,content:t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"text-xs text-fg-muted",children:"Two 16-bit transport codes for encrypted routing"}),t.jsxs("div",{className:"mt-1 text-xs text-fg-secondary",children:["Code 1: 0x",null==(s=v.transportCodesHex)?void 0:s.slice(0,4).toUpperCase()," | Code 2: 0x",null==(a=v.transportCodesHex)?void 0:a.slice(4,8).toUpperCase()]})]})},{id:"pathLength",title:"Path Length",color:"green",startByte:v.transportCodesHex?5:1,endByte:v.transportCodesHex?5:1,hexBytes:`0x${v.pathLengthHex.toUpperCase()}`,condition:!0,content:t.jsxs("p",{className:"text-xs text-fg-muted pt-1",children:[H.pathLen," bytes showing route taken (increases as packet floods)"]})},{id:"pathData",title:"Path Data",color:"amber",startByte:v.transportCodesHex?6:2,endByte:(v.transportCodesHex?5:1)+H.pathLen,hexBytes:(null==(n=v.pathDataHex)?void 0:n.toUpperCase())||"",condition:H.pathLen>0,content:t.jsxs("div",{className:"space-y-3",children:[t.jsx(Vs,{pathHex:v.pathDataHex}),t.jsx("p",{className:"text-xs text-fg-muted",children:"Historical route taken (bytes are added as packet floods through network)"})]})},{id:"payload",title:"Payload",color:"cyan",startByte:v.payloadStartByte,endByte:c-1,hexBytes:v.payloadHex.toUpperCase(),condition:!0,content:t.jsxs(t.Fragment,{children:[!vs(j)&&t.jsxs("div",{className:"p-3 rounded-lg bg-black",children:[t.jsx("p",{className:"type-micro text-fg-muted mb-1.5 font-sans",children:"Decoded"}),t.jsx(Qs,{decoded:T,payloadType:H.payloadType})]}),!vs(j)&&B.length>0&&t.jsx("p",{className:"type-micro text-fg-muted mt-3 font-sans",children:"Click a field below to highlight its bytes"}),vs(j)&&t.jsx("p",{className:"type-micro text-fg-muted font-sans",children:"↑ Selected field above • Other fields below ↓"})]})}].filter(e=>e.condition),i=vs(j)?B.find(e=>e.id===j):null,d=vs(j)?[...l].sort((e,s)=>"payload"===e.id?-1:"payload"===s.id?1:0):[...l].sort((e,s)=>e.id===j?-1:s.id===j?1:0),o=vs(j)?B.filter(e=>e.id!==j):[];return t.jsxs(t.Fragment,{children:[i&&t.jsx(Fs,{id:`subfield-${i.id}`,title:i.title,color:i.color,startByte:v.payloadStartByte+i.startByte,endByte:v.payloadStartByte+i.endByte,hexBytes:i.hex.toUpperCase(),isSelected:!0,children:i.decoded},i.id),d.map(e=>t.jsx(Fs,{id:`section-${e.id}`,title:e.title,color:e.color,startByte:e.startByte,endByte:e.endByte,hexBytes:e.hexBytes,isSelected:e.id===j,children:e.content},e.id)),o.map(e=>t.jsxs(Ge.div,{layout:"position",layoutId:`subfield-${e.id}`,transition:Ss,className:"w-full min-w-0 overflow-hidden rounded-xl p-4 sm:p-5 space-y-4",style:{backgroundColor:ks,boxShadow:Cs},children:[t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 min-w-0",children:[t.jsx(r,{color:e.color,children:e.title}),e.hex.length<=32&&Ns(e.hex).map((s,a)=>t.jsx(r,{color:e.color,className:"font-mono",children:s.toUpperCase()},a))]}),t.jsxs("span",{className:"type-data-xs text-fg-muted flex-shrink-0",children:["Bytes ",v.payloadStartByte+e.startByte,"-",v.payloadStartByte+e.endByte]})]}),t.jsx("div",{className:"min-w-0 overflow-hidden p-3 rounded-lg bg-black",children:e.decoded})]},e.id))]})})()})})]})});function Os(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function Ws(e){return e?(e.startsWith("0x")?e.slice(2):e).slice(0,2).toUpperCase():""}function qs({hop:s,compact:n=!1,index:l=0,highlightIndex:r=-1,isTrace:i=!1}){var c;const d=l===r,o=Oe();return a.useEffect(()=>{d&&i&&o.start({boxShadow:["0 0 0 0px rgba(113, 156, 223, 0)","0 0 0 2px rgba(113, 156, 223, 0.5)","0 0 0 2px rgba(113, 156, 223, 0.5)","0 0 0 0px rgba(113, 156, 223, 0)"],transition:{duration:.5,times:[0,.2,.7,1],ease:"easeInOut"}})},[d,i,o]),t.jsxs(Ge.div,{className:e("flex items-center gap-1.5",n?"flex-row":"flex-col"),animate:{scale:d?1.05:1,opacity:d?1:.85},transition:{duration:.3,ease:"easeInOut"},children:[t.jsxs(Ge.div,{className:e("flex items-center gap-1.5 px-2.5 py-1 rounded-md","font-mono text-xs font-semibold",s.isLocal?"bg-sys-amber/20 text-sys-amber ring-1 ring-sys-amber/30":"bg-elevated/50 text-fg-primary ring-1 ring-edge-strong/50"),animate:o,initial:{boxShadow:"0 0 0 0px rgba(113, 156, 223, 0)"},children:[s.isLocal&&t.jsx(Be,{className:"w-3 h-3"}),t.jsx("span",{children:s.prefix}),void 0!==s.confidence&&s.confidence<.9&&t.jsxs("span",{className:"text-[9px] opacity-70",children:[(100*s.confidence).toFixed(0),"%"]})]}),!n&&(null==(c=s.neighborInfo)?void 0:c.name)&&t.jsx("span",{className:"text-xs text-fg-muted truncate max-w-[80px]",children:s.neighborInfo.name})]})}function Ks({snr:e,sf:s}){const a=v(e,s),n=N()[a]||"#6b7280",l=Number.isInteger(e)?e.toString():e.toFixed(1);return t.jsxs(r,{customColor:n,compact:!0,className:"font-mono",children:[e>=0?"+":"",l,"dB"]})}function Xs({hops:s,compact:n,isTrace:l=!1,sf:r}){const[i,c]=a.useState(-1);return a.useEffect(()=>{if(0===s.length)return;const e=setTimeout(()=>{c(0)},400),t=setInterval(()=>{c(e=>{const a=e+1;return a>=s.length?(clearInterval(t),-1):a})},l?500:600);return()=>{clearTimeout(e),clearInterval(t)}},[s.length,l]),t.jsx("div",{className:"p-6",style:{display:"grid",gridTemplateColumns:"1fr auto 1fr",gap:"4px 8px"},children:s.map((a,c)=>{const d=c%2==0,o=c===s.length-1;return t.jsxs("div",{className:"contents",children:[t.jsx("div",{className:e("flex items-center","justify-end"),children:d&&t.jsx(qs,{hop:a,compact:n,index:c,highlightIndex:i,isTrace:l})}),t.jsx("div",{className:"flex flex-col items-center justify-center min-h-[28px]",children:!o&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px flex-1 bg-border-strong/40 min-h-[8px]"}),void 0!==a.snr&&t.jsx(Ks,{snr:a.snr,sf:r}),t.jsx("svg",{className:"w-3 h-3 text-fg-muted flex-shrink-0",viewBox:"0 0 12 12",fill:"none",children:t.jsx("path",{d:"M6 2v8M3 7l3 3 3-3",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]})}),t.jsx("div",{className:e("flex items-center","justify-start"),children:!d&&t.jsx(qs,{hop:a,compact:n,index:c,highlightIndex:i,isTrace:l})})]},`${a.prefix}-${c}`)})})}const Ys=a.memo(function({packet:s,neighbors:n,localHash:l,neighborAffinity:r,ghostPrefixes:i,direction:c="horizontal",compact:d=!1,traceSnr:o,overridePath:x}){const m=void 0!==o&&o.length>0,p=b(),h=Os(s.original_path),u=Os(s.forwarded_path),g=x??(u.length>0?u:h),f=Ws(l),y=a.useMemo(()=>g.map((e,s)=>{const t=e.toUpperCase(),a=t===f,l=(null==i?void 0:i.has(t))??!1,c=function(e,s,t){const a=e.toUpperCase();if(t){let e=null,n=0;if(t.forEach((s,t)=>{if(Ws(t)===a){const a=s.combinedScore??0;a>n&&(n=a,e=t)}}),e&&s[e])return{hash:e,info:s[e],confidence:n}}for(const[n,l]of Object.entries(s))if(Ws(n)===a)return{hash:n,info:l,confidence:void 0};return null}(t,n,r);return{prefix:t,fullHash:null==c?void 0:c.hash,neighborInfo:null==c?void 0:c.info,isLocal:a,isGhost:l,confidence:null==c?void 0:c.confidence,snr:null==o?void 0:o[s]}}),[g,n,r,f,i,o]);if(0===y.length)return t.jsxs("div",{className:"flex items-center gap-2 text-fg-muted text-xs",children:[t.jsx(he,{className:"w-4 h-4 opacity-50"}),t.jsx("span",{children:"Direct / No path data"})]});if("flowchart"===c)return t.jsx(Xs,{hops:y,compact:d,isTrace:m,sf:p});const j="horizontal"===c?xe:me;return t.jsx("div",{className:e("flex gap-1.5","horizontal"===c?"flex-row flex-wrap items-center":"flex-col items-start"),children:y.map((s,a)=>t.jsxs("div",{className:e("flex items-center gap-1.5","vertical"===c&&"flex-col"),children:[t.jsx(qs,{hop:s,compact:d}),a"blue",et=[{fn:"id",group:"identity",fmt:"int",read:e=>Js(e.id),color:Zs},{fn:"packet_hash",group:"identity",fmt:"hex",read:e=>e.packet_hash||void 0,color:Zs},{fn:"timestamp",group:"identity",fmt:"epoch",read:e=>e.timestamp?String(e.timestamp):void 0,color:Zs,annotate:e=>e.timestamp>0?w(e.timestamp):void 0},{fn:"type",group:"classification",fmt:"enum",read:e=>Js(e.type??e.payload_type),color:Zs},{fn:"route",group:"classification",fmt:"enum",read:e=>Js(e.route??e.route_type),color:Zs},{fn:"rssi",group:"signal",fmt:"int",read:e=>Js(e.rssi,"dBm"),color:Zs},{fn:"snr",group:"signal",fmt:"float",read:e=>Js(e.snr,"dB"),color:Zs},{fn:"path_length",group:"size",fmt:"int",read:e=>{if(null!=e.path_length)return 0===e.path_length?"zero-hop":`${e.path_length} hops`},color:Zs},{fn:"payload_length",group:"size",fmt:"int",read:e=>Js(e.payload_length,"B"),color:Zs},{fn:"airtime",group:"size",fmt:"float",read:e=>Js(e.airtime_ms,"ms"),color:Zs},{fn:"src_hash",group:"addressing",fmt:"hex<2>",read:e=>e.src_hash??void 0,color:Zs},{fn:"dst_hash",group:"addressing",fmt:"hex<2>",read:e=>e.dst_hash??void 0,color:Zs},{fn:"path_hash",group:"addressing",fmt:"hex[]|hex",read:e=>Array.isArray(e.path_hash)?`[${e.path_hash.join(", ")}]`:Js(e.path_hash),color:Zs,renderValue:e=>Array.isArray(e.path_hash)?st(e.path_hash):null},{fn:"score",group:"addressing",fmt:"int",read:e=>Js(e.score),color:Zs},{fn:"original_path",group:"paths",fmt:"hex[]",read:e=>Array.isArray(e.original_path)?`[${e.original_path.join(", ")}]`:void 0,color:Zs,renderValue:e=>Array.isArray(e.original_path)&&e.original_path.length>0?st(e.original_path,e.src_hash||void 0,e.dst_hash||void 0,!0):null},{fn:"forwarded_path",group:"paths",fmt:"hex[]",read:e=>Array.isArray(e.forwarded_path)?`[${e.forwarded_path.join(", ")}]`:void 0,color:Zs,renderValue:e=>Array.isArray(e.forwarded_path)&&e.forwarded_path.length>0?st(e.forwarded_path):null},{fn:"transmitted",group:"status",fmt:"bool",read:e=>Js(e.transmitted),color:Zs},{fn:"is_duplicate",group:"status",fmt:"bool",read:e=>Js(e.is_duplicate),color:Zs},{fn:"drop_reason",group:"status",fmt:"string|null",read:e=>e.drop_reason??void 0,color:Zs},{fn:"tx_delay",group:"status",fmt:"int",read:e=>Js(e.tx_delay_ms,"ms"),color:Zs},{fn:"origin",group:"status",fmt:"enum",read:e=>e.packet_origin??void 0,color:Zs},{fn:"duplicates",group:"status",fmt:"PacketDuplicate[]",read:e=>null!=e.duplicates&&e.duplicates.length>0?`${e.duplicates.length}`:Js(e.duplicates),color:Zs},{fn:"lbt_attempts",group:"lbt",fmt:"int",read:e=>Js(e.lbt_attempts),color:Zs},{fn:"lbt_backoff",group:"lbt",fmt:"json",read:e=>Js(e.lbt_backoff_delays_ms),color:Zs},{fn:"lbt_busy",group:"lbt",fmt:"bool|int",read:e=>Js(e.lbt_channel_busy),color:Zs}];function st(e,s,n,l){const r=e.length>0,i=s||l,c=n||l;return t.jsxs("span",{className:"inline-flex items-center gap-1 flex-wrap",children:[i&&t.jsxs(t.Fragment,{children:[s?t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:s}):t.jsx("span",{className:"inline-block border border-edge-subtle/50 rounded px-1.5 py-0.5 font-mono text-[11px] text-fg-muted/30",children:"XX"}),(r||c)&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"})]}),e.map((e,s)=>t.jsxs(a.Fragment,{children:[s>0&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:e})]},s)),c&&t.jsxs(t.Fragment,{children:[r&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),n?t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:n}):t.jsx("span",{className:"inline-block border border-edge-subtle/50 rounded px-1.5 py-0.5 font-mono text-[11px] text-fg-muted/30",children:"XX"})]})]})}let tt=null;function at(e,s){var t;const a=function(){if(!tt){tt=new Map;for(const e of et)tt.set(e.fn,e)}return tt}().get(s);if(!a)return null;const n=a.read(e);if(void 0===n)return null;const l=a.color(e),r=null==(t=a.annotate)?void 0:t.call(a,e);return r?{text:n,color:l,annotation:r}:{text:n,color:l}}function nt(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function lt({packets:s,selectedIndex:a,onSelect:n,compact:l=!1}){if(s.length<=1)return null;const r=a>0,i=ar&&n(a-1),disabled:!r,className:e("p-0.5 radius-badge transition-base",r?"text-fg-muted hover:text-fg-primary hover-bg":"text-fg-muted cursor-not-allowed"),"aria-label":"Previous observation",children:t.jsx(Le,{className:l?"size-3":"size-4"})}),t.jsx("div",{className:"flex items-center gap-0.5",children:s.map((s,r)=>{const i=r===a,c=new Date(1e3*s.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});return t.jsx(F,{color:i?"cyan":"zinc",filled:i,compact:l,onClick:()=>n(r),title:`Observation ${r+1} at ${c}`,className:e("transition-all duration-150",!i&&"opacity-60 hover:opacity-100"),children:l?t.jsx("span",{className:"tabular-nums",children:r+1}):t.jsxs("span",{className:"tabular-nums text-xs",children:["#",r+1,null!=s.rssi&&t.jsx("span",{className:"ml-1 opacity-70",children:s.rssi})]})},`${s.timestamp}_${r}`)})}),t.jsx("button",{onClick:()=>i&&n(a+1),disabled:!i,className:e("p-0.5 radius-badge transition-base",i?"text-fg-muted hover:text-fg-primary hover-bg":"text-fg-muted cursor-not-allowed"),"aria-label":"Next observation",children:t.jsx(pe,{className:l?"size-3":"size-4"})}),t.jsxs("span",{className:e("text-fg-muted ml-1",l?"text-[9px]":"text-xs"),children:[t.jsx(oe,{className:"inline size-3 mr-0.5 opacity-50"}),s.length]})]})}function rt({icon:s,label:a,disabled:n=!1}){return t.jsx(Ge.div,{className:"flex items-center gap-1 text-xs",title:a,animate:{opacity:n?.25:.6},transition:{duration:.15,ease:[.4,0,.2,1]},children:t.jsx("span",{className:e("flex items-center justify-center size-5 radius-badge border-control transition-base",n?"bg-subtle-fill border-edge-subtle":"bg-subtle-fill"),children:s})})}function it({hasDuplicates:e,hasPrev:s,hasNext:a,canPrevDupe:n,canNextDupe:l}){return t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsxs("div",{className:"flex items-center gap-0.5",children:[t.jsx(rt,{icon:t.jsx(De,{className:"size-3"}),label:"Previous packet (↑)",disabled:!s}),t.jsx(rt,{icon:t.jsx(ze,{className:"size-3"}),label:"Next packet (↓)",disabled:!a})]}),e&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px h-3 bg-subtle-fill-strong"}),t.jsxs("div",{className:"flex items-center gap-0.5",children:[t.jsx(rt,{icon:t.jsx(Le,{className:"size-3"}),label:"Previous observation (←)",disabled:!n}),t.jsx(rt,{icon:t.jsx(pe,{className:"size-3"}),label:"Next observation (→)",disabled:!l})]})]})]})}const ct=a.memo(function({packets:e,initialIndex:s=0,onClose:n,onNavigatePrev:l,onNavigateNext:i,hasPrev:c=!1,hasNext:m=!1,resolveSource:p}){var h;const[g,f]=a.useState(s),y=e[g]??e[0],j=e.length>1,[b,N]=a.useState(null),[v,w]=a.useState(!1);a.useEffect(()=>{if(!y._stripped)return void N(null);let e=!1;w(!0);const s=y.packet_hash;if(s)return k(s).then(s=>{e||(s.success&&s.data&&(N(s.data),(s.data.type??s.data.payload_type)===u.GRP_TXT&&s.data.raw_packet&&C.getState().queueDecryption([s.data])),w(!1))}).catch(()=>{e||w(!1)}),()=>{e=!0};w(!1)},[y]);const F=b??y,L=g>0,D=g{f(Math.max(0,Math.min(s,e.length-1)))},[e.length]);a.useEffect(()=>{const e=e=>{if(!(e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement))switch(e.key){case"ArrowUp":e.preventDefault(),null==l||l();break;case"ArrowDown":e.preventDefault(),null==i||i();break;case"ArrowLeft":e.preventDefault(),L&&f(e=>e-1);break;case"ArrowRight":e.preventDefault(),D&&f(e=>e+1)}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[l,i,L,D]);const R=_(),A=S(),E=P(),U=H(),I=a.useMemo(()=>new Set(U.map(e=>e.prefix.toUpperCase())),[U]),V=F.payload_type_name||d(F.payload_type??F.type),Q=F.route_type_name||o(F.route_type??F.route),G=F.payload_length??F.length??0,O=nt(F.original_path),W=nt(F.forwarded_path),q=O.length>0||W.length>0,Y=W.length>0?W:O,J=a.useMemo(()=>{var e;if(null==(e=null==R?void 0:R.config)?void 0:e.repeater)return{latitude:R.config.repeater.latitude,longitude:R.config.repeater.longitude,name:R.config.node_name||"Local Node"}},[R]),Z=(null==R?void 0:R.neighbors)??{},ee=E.size>0?E:void 0,se=F.raw_packet&&F.raw_packet.length>0,te=y._stripped&&v,ae=a.useMemo(()=>p?p(F):null,[p,F]),ne=T(F.packet_hash),ce=a.useMemo(()=>{if((F.payload_type??F.type)!==u.GRP_TXT)return null;if(!(null==ne?void 0:ne.decoded))return null;const e=ne.decoded;return{type:"grp_txt",channelHash:e.channelHash,channelName:e.channelName,text:e.text??"",decrypted:e.decrypted,senderName:e.senderName,timestamp:e.timestamp,flags:e.flags,macCorrupted:e.macCorrupted}},[F,ne]),de=a.useMemo(()=>$(F,ce),[F,ce]),oe="trace"===de.kind?de.data:null,xe="trace"===de.kind?de.snrValues:void 0,me="advert"===de.kind?de.data:null,pe="advert"===de.kind?de.sourceNode:void 0,ue="grp_txt"===de.kind?de.wardriveSourceNode??void 0:void 0,fe=e=>e&&0!==e?new Date(1e3*e).toLocaleString():"Unknown",ye=(F.payload_type??F.type)===u.ADVERT&&(void 0!==pe||q),je=void 0!==ue,be=pe??ue,Ne=X[V]??"zinc",we=x[Ne]||x.zinc;return t.jsxs(B,{open:!0,onClose:n,size:"5xl",motionPlus:!0,className:"sm:h-[85vh] sm:max-h-[800px] md:h-[80vh] md:max-h-[900px]",children:[t.jsxs("div",{className:"sm:hidden",children:[t.jsx("div",{className:"flex justify-center pt-2 pb-1",children:t.jsx("div",{className:"w-9 h-1 rounded-full bg-fg-muted","aria-hidden":"true"})}),t.jsxs("div",{className:"flex items-center justify-between px-3 pb-2",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:X[V]??"zinc",className:"!text-[9px] !px-1.5 !py-0",children:V}),t.jsx(r,{color:K[Q]??"zinc",className:"!text-[9px] !px-1.5 !py-0",children:Q}),t.jsxs(r,{color:"zinc",className:"!text-[9px] !px-1.5 !py-0",children:[G,"B"]})]}),t.jsx("button",{onClick:n,className:"px-3 py-1.5 text-[15px] font-medium text-sys-blue active:text-sys-blue/80 transition-base flex-shrink-0 radius-inner active:bg-subtle-fill",children:"Done"})]}),j&&t.jsx("div",{className:"px-3 pb-2",children:t.jsx(lt,{packets:e,selectedIndex:g,onSelect:z,compact:!0})})]}),t.jsx("div",{className:"hidden sm:block px-6 pt-5 pb-4",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(r,{color:X[V]??"zinc",children:V}),t.jsx(r,{color:K[Q]??"zinc",children:Q}),t.jsxs(r,{color:"zinc",children:[G,"B"]}),j&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px h-4 bg-subtle-fill-strong"}),t.jsx(lt,{packets:e,selectedIndex:g,onSelect:z})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(it,{hasDuplicates:j,hasPrev:c,hasNext:m,canPrevDupe:L,canNextDupe:D}),t.jsx("button",{onClick:n,className:"p-1.5 -m-1.5 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-elevated flex-shrink-0",children:t.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}),t.jsx("div",{className:"sm:hidden h-[2px]",style:{backgroundColor:we,opacity:.6}}),t.jsxs(M,{className:"p-0 overflow-hidden flex-1 flex flex-col min-h-0",children:[t.jsx("div",{className:"md:hidden flex-1 overflow-y-auto overflow-x-hidden",children:t.jsxs("div",{className:"p-2 space-y-2",children:[(null!=F.rssi||null!=F.snr)&&t.jsxs("div",{className:"relative flex items-center justify-between px-2 py-1.5 radius-inner bg-subtle-fill",children:[t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.div,{className:"flex items-center gap-3",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[t.jsx(le,{rssi:F.rssi,snr:F.snr,compact:!0,showValues:!0,validated:re(F)}),t.jsx("span",{className:"text-[11px] text-fg-muted",children:ie(F.rssi)})]},g)}),Y.length>0&&t.jsxs("span",{className:"type-data-xs text-fg-muted",children:[Y.length," hop",1!==Y.length?"s":""]})]}),(q&&Y.length>0||ye||je)&&t.jsx("div",{className:"overflow-hidden radius-inset",children:t.jsx("div",{className:"aspect-[4/3] w-full",children:t.jsx(bs,{path:Y,neighbors:Z,localNode:J,localHash:null==R?void 0:R.local_hash,srcHash:F.src_hash,dstHash:F.dst_hash,neighborAffinity:ee,hubNodes:[...A],traceSnr:xe,advertiserSource:be})})}),oe&&oe.pathHashes.length>0&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsx("div",{className:"px-3 py-2 space-y-1.5",children:t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsx("div",{className:"flex items-center gap-1.5",children:t.jsx(r,{color:oe.isComplete?"green":"amber",compact:!0,children:oe.isComplete?"Complete":"In Progress"})})]})}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,overridePath:oe.pathHashes,traceSnr:oe.snrValues})]}),q&&!oe&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Path"}),t.jsxs(r,{color:"zinc",compact:!0,children:[Y.length," hop",1!==Y.length?"s":""]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,traceSnr:xe})]}),ae&&(ae.name||ae.hash)&&!me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Source"}),t.jsx(r,{color:ae.isRepeater?"blue":ae.isCompanion?"violet":"room_server"===ae.type?"lime":"zinc",compact:!0,children:"room_server"===ae.type?"room server":ae.type})]}),t.jsxs("div",{className:"p-3 space-y-1.5",children:[ae.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:ae.name}),!ae.confident&&t.jsx("span",{className:"text-[9px] text-fg-muted/60 italic",children:"ambiguous"})]}),ae.hash&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-muted truncate font-mono",children:[ae.hash.startsWith("0x")?ae.hash.slice(2,10):ae.hash.slice(0,8),"…"]})]})]})]}),me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Advertiser Info"}),t.jsx(r,{color:"lime",compact:!0,children:me.nodeType})]}),t.jsxs("div",{className:"p-3 space-y-2",children:[me.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:me.name})]}),me.latitude&&me.longitude&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ge,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-secondary",children:[me.latitude.toFixed(5),", ",me.longitude.toFixed(5)]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-muted truncate",children:[me.publicKey.slice(0,16),"...",me.publicKey.slice(-8)]})]}),me.timestamp>0&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ve,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:fe(me.timestamp)})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(he,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:me.flagsDescription||`Flags: 0x${me.flags.toString(16).padStart(2,"0")}`})]})]})]}),te?t.jsx("div",{className:"pt-1 px-3 py-6 text-center",children:t.jsx("span",{className:"text-xs text-fg-muted animate-pulse",children:"Loading packet details…"})}):se?t.jsx("div",{className:"pt-1",children:t.jsx(Gs,{packet:F,decodedGrpTxt:ce})}):null]})}),t.jsxs("div",{className:"hidden md:grid md:grid-cols-2 flex-1 overflow-hidden",children:[t.jsx("div",{className:"overflow-y-auto overflow-x-hidden scrollbar-none p-4 border-r border-edge-subtle",children:te?t.jsx("div",{className:"flex items-center justify-center h-full",children:t.jsx("span",{className:"text-sm text-fg-muted animate-pulse",children:"Loading packet details…"})}):se?t.jsx(Gs,{packet:F,decodedGrpTxt:ce}):null}),t.jsxs("div",{className:"grid overflow-hidden",style:{gridTemplateRows:"minmax(280px, 1fr) auto"},children:[t.jsx("div",{className:"overflow-hidden p-2",children:q&&Y.length>0||ye||je?t.jsx("div",{className:"h-full w-full",children:t.jsx(bs,{path:Y,neighbors:Z,localNode:J,localHash:null==R?void 0:R.local_hash,srcHash:F.src_hash,dstHash:F.dst_hash,neighborAffinity:ee,hubNodes:[...A],traceSnr:xe,advertiserSource:be})}):t.jsxs("div",{className:"h-full w-full flex flex-col items-center justify-center text-center px-4",children:[t.jsx(he,{className:"w-8 h-8 text-fg-muted/50 mb-2"}),t.jsx("span",{className:"text-sm text-fg-muted",children:"Direct Reception"}),t.jsx("span",{className:"text-xs text-fg-muted/70 mt-1",children:"Zero-hop packet — received directly from sender"})]})}),t.jsxs("div",{className:"overflow-y-auto max-h-[200px] p-2 space-y-2",children:[!oe&&Y.length<=1&&(null!=F.rssi||null!=F.snr)&&t.jsx("div",{className:"surface-base radius-inset p-4",children:t.jsxs("dl",{className:"text-xs grid grid-cols-2 gap-2",children:[t.jsxs("div",{children:[t.jsx("dt",{className:"text-fg-muted mb-1",children:"Signal"}),t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.dd,{className:"flex items-center gap-2",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[t.jsx(le,{rssi:F.rssi,snr:F.snr,validated:re(F)}),t.jsx("span",{className:"font-medium text-fg-primary",children:ie(F.rssi)})]},g)})]}),t.jsxs("div",{children:[t.jsx("dt",{className:"text-fg-muted mb-1",children:"RF"}),t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.dd,{className:"type-data text-fg-secondary",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[null==(h=at(F,"rssi"))?void 0:h.text,(()=>{const e=at(F,"snr");return e?` · ${e.text}`:null})()]},g)})]})]})}),ae&&(ae.name||ae.hash)&&!me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Source"}),t.jsx(r,{color:ae.isRepeater?"blue":ae.isCompanion?"violet":"room_server"===ae.type?"lime":"zinc",compact:!0,children:"room_server"===ae.type?"room server":ae.type})]}),t.jsxs("div",{className:"p-4 space-y-2",children:[ae.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:ae.name}),!ae.confident&&t.jsx("span",{className:"text-[10px] text-fg-muted/60 italic",children:"ambiguous"})]}),ae.hash&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-muted truncate",children:[ae.hash.startsWith("0x")?ae.hash.slice(2,10):ae.hash.slice(0,8),"…"]})]})]})]}),me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Advertiser"}),t.jsx(r,{color:"lime",compact:!0,children:me.nodeType})]}),t.jsxs("div",{className:"p-4 space-y-2.5",children:[me.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:me.name})]}),me.latitude&&me.longitude&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ge,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-secondary",children:[me.latitude.toFixed(5),", ",me.longitude.toFixed(5)]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-muted truncate",children:[me.publicKey.slice(0,16),"...",me.publicKey.slice(-8)]})]}),me.timestamp>0&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ve,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:fe(me.timestamp)})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(he,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-[11px] text-fg-muted",children:me.flagsDescription||`Flags: 0x${me.flags.toString(16).padStart(2,"0")}`})]})]})]}),oe&&oe.pathHashes.length>0&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"px-4 py-2 flex items-center justify-between",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:oe.isComplete?"green":"amber",compact:!0,children:oe.isComplete?"Complete":"In Progress"}),t.jsxs(r,{color:"teal",compact:!0,children:[oe.pathHashes.length,"h"]})]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,overridePath:oe.pathHashes,traceSnr:oe.snrValues})]}),q&&!oe&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Path"}),t.jsxs(r,{color:"zinc",compact:!0,children:[Y.length,"h"]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,traceSnr:xe})]})]})]})]})]})]})});function dt({label:e,numericValue:s,unit:a,icon:n,subtext:l,showSign:r=!1}){return t.jsxs("div",{className:"radius-inner p-3 sm:radius-inset sm:p-4 bg-subtle-fill ring-1 ring-inset ring-edge-subtle",children:[t.jsx("div",{className:"mb-1.5 sm:mb-2",children:t.jsx("span",{className:"text-xs sm:type-micro text-fg-muted",children:e})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(qe,{value:s,format:{minimumFractionDigits:1,maximumFractionDigits:1,signDisplay:r?"always":"auto"},className:"type-data-hero tracking-tight text-fg-primary"}),t.jsxs("div",{className:"flex flex-col items-center justify-center",children:[t.jsx(n,{className:"w-[14px] h-[14px] text-fg-muted"}),a&&t.jsx("span",{className:"text-xs font-medium leading-tight text-fg-muted",children:a})]})]}),l&&t.jsx("p",{className:"mt-1.5 sm:mt-2 type-data-xs sm:text-[11px] text-fg-muted/80 truncate",children:l})]})}function ot({snr:s}){const a=s>=5?"bg-sys-teal":s>=0?"bg-sys-green":s>=-5?"bg-sys-amber":s>=-10?"bg-sys-orange":"bg-sys-red";return t.jsx("span",{className:e("w-1.5 h-1.5 rounded-full flex-shrink-0",a),title:`SNR: ${s.toFixed(1)} dB`})}function xt({fromPrefix:s,toPrefix:a,fromName:n,toName:l,snr:i,maxSnr:c,isWeakest:d,isStrongest:o,index:x=0}){const m=Math.max(c+5,15),p=Math.max(0,Math.min(100,(i- -20)/(m- -20)*100)),h="bg-[#0074BE]",u=i>=5?"bg-sys-teal":i>=0?"bg-sys-green":i>=-5?"bg-sys-amber":i>=-10?"bg-sys-orange":"bg-sys-red",g=.3+.15*x;return t.jsxs("div",{className:"relative p-3 pl-5 radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle",children:[t.jsx("span",{className:e("absolute left-0 top-1/2 -translate-y-1/2 h-4 w-0.5 rounded-full",u)}),t.jsx("span",{className:"absolute -top-0.5 -right-0.5",children:t.jsx(ot,{snr:i})}),t.jsxs("div",{className:"sm:hidden",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[t.jsx("span",{className:"text-[13px] font-medium text-fg-secondary truncate",children:n||s}),t.jsx(xe,{className:"w-3 h-3 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-[13px] font-semibold text-fg-primary truncate",children:l||a})]}),t.jsxs("div",{className:"flex items-center gap-1.5 ml-2 flex-shrink-0",children:[d&&t.jsx(r,{color:"red",compact:!0,children:"Low"}),o&&!d&&t.jsxs(r,{color:"amber",compact:!0,children:[t.jsx(Ae,{className:"w-2.5 h-2.5"}),"Best"]}),t.jsxs("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-[12px] font-mono font-bold tabular-nums bg-subtle-fill-hover text-fg-primary ring-1 ring-inset ring-edge-subtle",children:[i>=0?"+":"−",Math.abs(i).toFixed(1)]})]})]}),t.jsx("div",{className:"h-1.5 bg-subtle-fill-strong rounded-full overflow-hidden",children:t.jsx(Ge.div,{className:e("h-full rounded-full",h),initial:{width:0},animate:{width:`${p}%`},transition:{duration:1.5,delay:g,ease:[.25,.1,.25,1]}})})]}),t.jsxs("div",{className:"hidden sm:block",children:[t.jsxs("div",{className:"flex items-center justify-between mb-2",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx("code",{className:"type-data-xs text-fg-muted",children:s}),n&&t.jsx("span",{className:"text-xs text-fg-secondary truncate max-w-[100px]",children:n})]}),t.jsx(xe,{className:"w-3 h-3 text-fg-muted/40 flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx("code",{className:"font-mono text-xs font-semibold text-fg-primary",children:a}),l&&t.jsx("span",{className:"text-xs text-fg-secondary truncate max-w-[100px]",children:l})]})]}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[d&&t.jsx(r,{color:"red",compact:!0,children:"Bottleneck"}),o&&!d&&t.jsxs(r,{color:"amber",compact:!0,children:[t.jsx(Ae,{className:"w-3 h-3"}),"Strongest"]}),t.jsxs("span",{className:"inline-flex items-center px-2 py-0.5 rounded text-sm font-mono font-semibold tabular-nums bg-subtle-fill-hover text-fg-primary ring-1 ring-inset ring-edge-subtle",children:[i>=0?"+":"−",Math.abs(i).toFixed(1)]})]})]}),t.jsx("div",{className:"h-1.5 bg-elevated rounded-full overflow-hidden",children:t.jsx(Ge.div,{className:e("h-full rounded-full",h),initial:{width:0},animate:{width:`${p}%`},transition:{duration:1.5,delay:g,ease:[.25,.1,.25,1]}})})]})]})}function mt(e,s){if("You"===e)return"You";const t=e.toUpperCase();for(const[a,n]of Object.entries(s))if((a.startsWith("0x")?a.slice(2,4):a.slice(0,2)).toUpperCase()===t)return n.name||n.node_name||void 0}const pt=a.memo(function({report:e,onClose:s}){var a,n;const l=_(),i=(null==l?void 0:l.neighbors)??{},c=(null==(a=null==l?void 0:l.config)?void 0:a.repeater)?{latitude:l.config.repeater.latitude,longitude:l.config.repeater.longitude,name:l.config.node_name||"Local Node"}:void 0,d=null==(n=e.bestObservation)?void 0:n.decoded.snrValues,o=e.linkQuality?e.linkQuality.avgSnr>=5?"excellent":e.linkQuality.avgSnr>=0?"good":e.linkQuality.avgSnr>=-5?"fair":"poor":"unknown",x={excellent:"var(--signal-excellent)",good:"var(--signal-good)",fair:"var(--signal-fair)",poor:"var(--signal-poor)",unknown:"var(--fg-muted)"}[o];return t.jsxs(B,{open:!0,onClose:s,size:"5xl",motionPlus:!0,children:[t.jsxs("div",{className:"sm:hidden",children:[t.jsx("div",{className:"flex justify-center pt-2 pb-1",children:t.jsx("div",{className:"w-9 h-1 rounded-full bg-fg-primary/30","aria-hidden":"true"})}),t.jsxs("div",{className:"flex items-center justify-between px-4 pb-2",children:[t.jsx("h2",{className:"font-semibold text-[17px] text-fg-primary",children:"Trace Report"}),t.jsx("button",{onClick:s,className:"text-[17px] font-medium text-sys-blue active:text-sys-blue/80",children:"Done"})]})]}),t.jsx("div",{className:"sm:hidden h-[2px]",style:{backgroundColor:x,opacity:.6}}),t.jsx("div",{className:"hidden sm:block px-6 pt-5 pb-4",children:t.jsxs("div",{className:"flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-2 sm:gap-3",children:[t.jsx("h2",{className:"type-micro",children:"Trace Report"}),t.jsxs(r,{color:"excellent"===o||"good"===o?"green":"fair"===o?"amber":"red",children:[t.jsx($e,{className:"w-3 h-3 mr-1"}),"excellent"===o?"Excellent":"good"===o?"Good":"fair"===o?"Fair":"Poor"]})]}),t.jsx("p",{className:"mt-1 text-xs sm:text-sm font-mono text-fg-muted tabular-nums",children:e.traceTag})]}),t.jsx("button",{onClick:s,className:"p-1.5 -m-1.5 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-elevated flex-shrink-0",children:t.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})}),t.jsxs("div",{className:"hidden sm:flex flex-wrap items-center gap-1.5 sm:gap-2 px-4 sm:px-6 pb-3 sm:pb-4 border-b border-edge-subtle",children:[t.jsxs(r,{color:"teal",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.targetHopCount}),t.jsxs("span",{className:"ml-1",children:["hop",1!==e.targetHopCount?"s":""]})]}),t.jsxs(r,{color:"zinc",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.observationCount}),t.jsx("span",{className:"ml-1",children:"obs"})]}),e.linkQuality&&t.jsxs(r,{color:"indigo",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.avgSnr.toFixed(1)}),t.jsx("span",{className:"ml-1",children:"dB avg"})]}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:L(e.duration)}),e.linkQuality&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"text-fg-muted/40",children:"•"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium bg-sys-red/15 text-sys-red ring-1 ring-inset ring-sys-red/25",children:[t.jsx("span",{className:"opacity-70",children:"Min"}),t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.minSnr.toFixed(1)})]}),t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium bg-sys-teal/15 text-sys-teal ring-1 ring-inset ring-sys-teal/25",children:[t.jsx("span",{className:"opacity-70",children:"Max"}),t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.maxSnr.toFixed(1)})]})]})]})]}),t.jsxs(M,{className:"p-0 overflow-hidden",children:[t.jsx("div",{className:"md:hidden h-[75vh] max-h-[calc(100vh-80px)] overflow-y-auto overflow-x-hidden",children:t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[e.linkQuality&&t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsxs("div",{className:"radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle p-2.5 text-center",children:[t.jsx(qe,{value:Math.abs(e.linkQuality.minSnr),format:{maximumFractionDigits:0,signDisplay:"never"},prefix:e.linkQuality.minSnr<0?"-":"",className:"text-[20px] font-bold font-mono tabular-nums flex items-center justify-center text-fg-primary"}),t.jsxs("div",{className:"flex items-center justify-center gap-1 mt-1",children:[t.jsx(ye,{className:"w-2.5 h-2.5 text-fg-muted"}),t.jsx("span",{className:"text-xs text-fg-muted",children:"Min dB"})]})]}),t.jsxs("div",{className:"radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle p-2.5 text-center",children:[t.jsx(qe,{value:e.linkQuality.maxSnr,format:{maximumFractionDigits:0,signDisplay:"always"},className:"text-[20px] font-bold font-mono text-fg-primary tabular-nums flex items-center justify-center"}),t.jsxs("div",{className:"flex items-center justify-center gap-1 mt-1",children:[t.jsx(Re,{className:"w-2.5 h-2.5 text-fg-muted"}),t.jsx("span",{className:"text-xs text-fg-muted",children:"Max dB"})]})]})]}),t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsxs(r,{color:"excellent"===o||"good"===o?"green":"fair"===o?"amber":"red",compact:!0,children:[t.jsx($e,{className:"w-2.5 h-2.5 mr-0.5"}),"excellent"===o?"Excellent":"good"===o?"Good":"fair"===o?"Fair":"Poor"]}),t.jsxs(r,{color:"teal",compact:!0,children:[e.targetHopCount," hops"]}),t.jsxs(r,{color:"zinc",compact:!0,children:[e.observationCount," obs"]}),t.jsx("span",{className:"type-data-xs text-fg-muted ml-auto",children:e.traceTag.slice(0,8)})]}),e.targetPath.length>0&&t.jsx("div",{className:"overflow-hidden radius-inset",children:t.jsx("div",{className:"aspect-[4/3] w-full",children:t.jsx(bs,{path:e.targetPath,neighbors:i,localNode:c,localHash:null==l?void 0:l.local_hash,srcHash:e.srcHash,dstHash:e.dstHash,traceSnr:d})})}),t.jsxs("div",{className:"radius-inset bg-body overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"text-[11px] font-medium text-fg-secondary",children:"Route Path"}),e.linkQuality&&t.jsxs("span",{className:"type-data-xs text-fg-muted",children:["SNR ",e.linkQuality.minSnr.toFixed(1)," → ",e.linkQuality.maxSnr.toFixed(1)," dB"]})]}),e.bestObservation?t.jsx(Ys,{packet:e.bestObservation.packet,neighbors:i,localHash:null==l?void 0:l.local_hash,direction:"flowchart",compact:!0,overridePath:e.targetPath,traceSnr:e.bestObservation.decoded.snrValues}):t.jsx("div",{className:"p-6 text-center text-fg-muted text-xs",children:"No path data available"})]}),t.jsxs("div",{children:[t.jsxs("h3",{className:"type-micro text-fg-muted mb-2",children:["Link Quality · ",e.hopStats.length," hops"]}),t.jsx("div",{className:"space-y-1.5",children:e.hopStats.length>0?e.hopStats.map((s,a)=>{var n,l,r;const c=a{const s=e.targetPath[e.linkQuality.weakestLinkPosition],a=e.targetPath[e.linkQuality.weakestLinkPosition+1]||"You",n=mt(s,i),l=mt(a,i),r=e.targetPath[e.linkQuality.strongestLinkPosition],c=e.targetPath[e.linkQuality.strongestLinkPosition+1]||"You",d=mt(r,i),o=mt(c,i);return t.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[t.jsx(dt,{label:"Weakest Link",numericValue:e.linkQuality.minSnr,unit:"dB",icon:ye,subtext:`${n||s} → ${l||a}`}),t.jsx(dt,{label:"Best Link",numericValue:e.linkQuality.maxSnr,showSign:!0,unit:"dB",icon:Re,subtext:`${d||r} → ${o||c}`})]})})(),t.jsxs("div",{children:[t.jsx("h3",{className:"type-micro text-fg-muted mb-3",children:"Link Details"}),t.jsx("div",{className:"space-y-2",children:e.hopStats.length>0?e.hopStats.map((s,a)=>{var n,l,r;const c=a0&&t.jsx("div",{className:"overflow-hidden",children:t.jsx("div",{className:"aspect-square w-full",children:t.jsx(bs,{path:e.targetPath,neighbors:i,localNode:c,localHash:null==l?void 0:l.local_hash,srcHash:e.srcHash,dstHash:e.dstHash,traceSnr:d})})}),t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:e.isComplete?"green":"amber",compact:!0,children:e.isComplete?"Complete":`${e.maxHopsObserved}/${e.targetHopCount}`}),t.jsxs(r,{color:"teal",compact:!0,children:[e.targetHopCount," hop",1!==e.targetHopCount?"s":""]})]})]}),e.linkQuality&&e.bestObservation&&t.jsxs("div",{className:"flex items-center gap-4 px-4 pb-2 type-data-xs text-fg-muted",children:[t.jsxs("span",{children:[t.jsx("span",{className:"opacity-60",children:"Tag"})," ",t.jsx("code",{className:"text-sys-teal tabular-nums",children:e.traceTag.slice(0,8)})]}),t.jsxs("span",{children:[t.jsx("span",{className:"opacity-60",children:"SNR"})," ",t.jsxs("code",{className:"text-sys-indigo tabular-nums",children:[e.linkQuality.minSnr.toFixed(1),"–",e.linkQuality.maxSnr.toFixed(1)]}),t.jsx("span",{className:"opacity-60",children:" dB"})]})]}),e.bestObservation?t.jsx(Ys,{packet:e.bestObservation.packet,neighbors:i,localHash:null==l?void 0:l.local_hash,direction:"flowchart",compact:!0,overridePath:e.targetPath,traceSnr:e.bestObservation.decoded.snrValues}):t.jsx("div",{className:"p-8 text-center text-fg-muted text-xs",children:"No path data available"})]})]})]})]})]})}),ht=[{target:"PacketList",fn:"type",minStage:1},{target:"PacketList",fn:"route",minStage:1},{target:"PacketList",fn:"rssi",minStage:1},{target:"PacketList",fn:"snr",minStage:1},{target:"PacketList",fn:"path",minStage:1,when:V},{target:"PacketList",fn:"src_hash",minStage:1,when:Q},{target:"PacketList",fn:"text",minStage:1,when:G},{target:"PacketList",fn:"ack",minStage:1,when:O},{target:"PacketList",fn:"decrypt",minStage:2,when:W},{target:"PacketList",fn:"duplicates",minStage:1}];I(ht);const ut="(min-width: 640px)";let gt=null;function ft(e){return"undefined"==typeof window?()=>{}:(gt||(gt=window.matchMedia(ut)),gt.addEventListener("change",e),()=>null==gt?void 0:gt.removeEventListener("change",e))}function yt(){return"undefined"==typeof window||(gt||(gt=window.matchMedia(ut)),gt.matches)}function jt(e){if(!e||e.length<6)return null;const s=e,t=parseInt(s.slice(0,2),16);if(isNaN(t))return null;const a=3&t;let n=2;if(0!==a&&3!==a||(n=10),n+2>s.length)return null;const l=parseInt(s.slice(n,n+2),16);if(isNaN(l))return null;if(n+=2+2*l,n>=s.length)return null;const r=s.slice(n);return r.length>=38?r.slice(0,38):r}function bt({message:e}){return t.jsxs("div",{className:"flex flex-col items-center justify-center py-14 text-center",children:[t.jsx(he,{className:"size-6 text-fg-muted mb-2"}),t.jsx("p",{className:"text-sm text-fg-primary",children:e}),t.jsx("p",{className:"text-xs text-fg-muted",children:"Packets will appear here"})]})}function Nt(){return t.jsx("div",{className:"py-14 text-center text-sm text-fg-muted",children:"Loading packets…"})}function vt({showPagination:e,currentPage:s,perPage:a,displayCount:n,totalCount:l,action:r}){const i=e?(s-1)*a+1:1,c=e?Math.min(s*a,l):n;return t.jsxs("div",{className:"flex items-center justify-between gap-4 border-t border-edge-subtle px-4 py-3 text-xs text-fg-muted sm:px-6",children:[t.jsxs("span",{children:["Showing"," ",t.jsx("span",{className:"font-medium text-fg-secondary",children:e?`${i}–${c}`:n})," ","of"," ",t.jsx("span",{className:"font-medium text-fg-secondary",children:l})," ","packets"]}),r]})}function wt({packets:s,allPackets:l,localHash:r,neighbors:i,loading:c=!1,maxPackets:d,perPage:o=50,showPagination:x=!1,onPacketSelect:m,flashNewest:p=!1,emptyMessage:h="No packets found",className:u,footerAction:g,hideDupes:f=!1,getDecodedContent:y,onChannelClick:j,resolveSource:b,virtualized:N=!0}){U(ht);const[v,w]=a.useState(null),[k,C]=a.useState(null),[_,S]=a.useState({traceTag:null,dupeGroup:null}),P=a.useRef(null),H=Ke(e=>e.setModalMapOpen);a.useEffect(()=>(H(!!v),()=>H(!1)),[v,H]),a.useLayoutEffect(()=>{S({traceTag:null,dupeGroup:null})},[s]);const T=l??s,B=a.useMemo(()=>d&&d>0&&!f?s.slice(0,d):s,[s,d,f]),M=a.useMemo(()=>{if(!f)return null;const e=function(e){if(0===e.length)return[];const s=[];let t=0;for(;t0?{packet:e[r].packet,dupeCount:e[r].dupeCount+s}:e[r])}return l}(e);return d&&d>0?s.slice(0,d):s},[B,f,d]),F=M?M.length:B.length,{currentPage:L,totalPages:z,goToPage:$,pageRange:I}=function(e,s,t){const[n,l]=a.useState(1),r=t?Math.ceil(e/s):1;a.useEffect(()=>{n>r&&r>0&&queueMicrotask(()=>l(1))},[r,n]);const i=a.useCallback(e=>l(Math.max(1,Math.min(e,r))),[r]),c=a.useMemo(()=>function(e,s,t=1){if(s<=7)return Array.from({length:s},(e,s)=>s+1);const a=Math.max(e-t,1),n=Math.min(e+t,s),l=a>2,r=ns+1),"gap",s]}if(l&&!r){const e=3+2*t;return[1,"gap",...Array.from({length:e},(t,a)=>s-e+a+1)]}return[1,"gap",...Array.from({length:n-a+1},(e,s)=>a+s),"gap",s]}(n,r),[n,r]);return{currentPage:n,totalPages:r,goToPage:i,pageRange:c}}(F,o,x),V=a.useMemo(()=>{if(f)return B;if(!x)return B;const e=(L-1)*o;return B.slice(e,e+o)},[B,x,L,o,f]),Q=a.useMemo(()=>{if(!M)return null;if(!x)return M;const e=(L-1)*o;return M.slice(e,e+o)},[M,x,L,o]),G=a.useMemo(()=>function(e){const s=new Map;for(const t of e)if((t.payload_type??t.type)===D.TRACE&&t.packet_hash){const e=t._traceTag??(t.payload?R(t.payload):null);e&&s.set(t.packet_hash,e)}return s}(V),[V]),O=a.useMemo(()=>function(e){const s=new Map;if(0===e.length)return s;for(let t=0;t{var t,a;if(!s||!e.length)return;const r=(null==(t=e[0])?void 0:t.timestamp)??0,i=r>l.current&&l.current>0;if(l.current=r,!i)return;const c=null==(a=e[0])?void 0:a.packet_hash;if(!c)return;const d=requestAnimationFrame(()=>n(c)),o=setTimeout(()=>n(null),600);return()=>{cancelAnimationFrame(d),clearTimeout(o)}},[e,s]),t}(s,p),q=a.useSyncExternalStore(ft,yt,()=>!0),K=a.useMemo(()=>f&&Q?Q:V,[f,Q,V]),X=N&&K.length>100,Y=q?48:72,J=n({count:X?K.length:0,getScrollElement:()=>P.current,estimateSize:()=>Y,overscan:5}),Z=a.useCallback((e,s)=>{var t,a;const n=e.packet_hash;if(!n)return[e];let l=s;for(;l>0&&(null==(t=V[l-1])?void 0:t.packet_hash)===n;)l--;let r=s;for(;r{var s,t;const a=null==(s=V[e])?void 0:s.packet_hash;if(!a)return e;let n=e;for(;n>0&&(null==(t=V[n-1])?void 0:t.packet_hash)===a;)n--;return n},[V]),se=a.useCallback(e=>{var s,t;const a=null==(s=V[e])?void 0:s.packet_hash;if(!a)return e;let n=e;for(;n{if(m)m(e);else if(void 0!==s){const t=Z(e,s),a=t.indexOf(e);w({packets:t,initialIndex:a>=0?a:0,rowIndex:s})}else w({packets:[e],initialIndex:0,rowIndex:0})},[m,Z]),ae=a.useCallback(()=>{if(!v)return;const e=ee(v.rowIndex)-1;if(e<0)return;const s=V[e];if(!s)return;const t=Z(s,e);w({packets:t,initialIndex:0,rowIndex:e})},[v,V,ee,Z]),ne=a.useCallback(()=>{if(!v)return;const e=se(v.rowIndex)+1;if(e>=V.length)return;const s=V[e];if(!s)return;const t=Z(s,e);w({packets:t,initialIndex:0,rowIndex:e})},[v,V,se,Z]),le=a.useMemo(()=>!!v&&ee(v.rowIndex)>0,[v,ee]),re=a.useMemo(()=>!!v&&se(v.rowIndex)S(s=>({...s,traceTag:e})),[]),ce=a.useCallback(e=>S(s=>({...s,dupeGroup:e})),[]),de=a.useCallback(()=>{S({traceTag:null,dupeGroup:null})},[]),oe=a.useCallback(e=>{const s=T.filter(s=>(s.payload_type??s.type)===D.TRACE&&s.payload&&R(s.payload)===e);if(0===s.length)return;const t=A(s).get(e);(null==t?void 0:t.length)&&C(E(e,t))},[T]),xe=a.useCallback(e=>{const s=T.find(s=>s.packet_hash===e);s&&(C(null),te(s))},[T,te]),me=a.useCallback((e,s,a)=>{const n=q?hs:us;if(a){const{packet:a,dupeCount:l}=e,c=a.packet_hash?G.get(a.packet_hash):void 0,d=null!==_.traceTag&&c===_.traceTag;return t.jsx(n,{packet:a,onClick:e=>te(e,s),localHash:r,neighbors:i,resolveSource:b,isFlashing:p&&W===a.packet_hash,traceTag:c,isTraceHighlighted:d,onTraceHover:ie,onViewTraceReport:oe,dupeCount:l,getDecodedContent:y,onChannelClick:j},`${a.packet_hash}_${a.timestamp}_${s}`)}const l=e,c=l.packet_hash?G.get(l.packet_hash):void 0,d=null!==_.traceTag&&c===_.traceTag,o=O.get(s),x=void 0!==o&&null!==_.dupeGroup&&l.packet_hash===_.dupeGroup;return t.jsx(n,{packet:l,onClick:e=>te(e,s),localHash:r,neighbors:i,resolveSource:b,isFlashing:p&&W===l.packet_hash,traceTag:c,isTraceHighlighted:d,onTraceHover:ie,onViewTraceReport:oe,dupeGroupPosition:o,isDupeGroupHovered:x,onDupeGroupHover:ce,getDecodedContent:y,onChannelClick:j},`${l.packet_hash}_${l.timestamp}_${s}`)},[q,G,_.traceTag,_.dupeGroup,te,r,i,b,p,W,ie,oe,O,ce,y,j]);return t.jsxs("div",{className:e("flex flex-col",u),onMouseLeave:de,children:[X?t.jsx("div",{ref:P,className:"divide-y divide-edge-subtle overflow-auto",style:{maxHeight:600},children:(()=>{if(c&&0===s.length)return t.jsx(Nt,{});if(0===K.length)return t.jsx(bt,{message:h});const e=f&&null!==Q,a=J.getVirtualItems();return t.jsx("div",{style:{height:`${J.getTotalSize()}px`,width:"100%",position:"relative"},children:a.map(s=>{const a=K[s.index];return t.jsx("div",{"data-index":s.index,ref:J.measureElement,style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${s.start}px)`},children:me(a,s.index,e)},s.key)})})})()}):t.jsx("div",{className:"divide-y divide-edge-subtle py-1",children:(()=>{if(c&&0===s.length)return t.jsx(Nt,{});if(0===V.length)return t.jsx(bt,{message:h});const e=f&&null!==Q;return(e?Q:V).map((s,t)=>me(s,t,e))})()}),x&&z>1&&t.jsx("nav",{className:"border-t border-edge-subtle px-4 py-3",children:t.jsxs(Xe,{className:"justify-center",children:[t.jsx(Ye,{onClick:()=>$(L-1),disabled:1===L}),t.jsx(Ze,{children:I.map((e,s)=>"gap"===e?t.jsx(ss,{},`gap-${s}`):t.jsx(es,{page:e,current:e===L,onClick:$},e))}),t.jsx(Je,{onClick:()=>$(L+1),disabled:L===z})]})}),t.jsx(vt,{showPagination:x,currentPage:L,perPage:o,displayCount:Q?Q.length:V.length,totalCount:x?F:s.length,action:g}),!m&&v&&t.jsx(ct,{packets:v.packets,initialIndex:v.initialIndex,onClose:()=>w(null),onNavigatePrev:ae,onNavigateNext:ne,hasPrev:le,hasNext:re,resolveSource:b}),k&&t.jsx(pt,{report:k,onClose:()=>C(null),onViewPacket:xe})]})}export{ds as C,wt as P,rs as g,ts as u}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PathMapMapLibre-_vG9wINu.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-core-FtpmsTnh.js","assets/BasemapLayer-CSqjQAiA.js","assets/index-CkRTgHHA.js","assets/vendor-charts-C916_-gs.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/maplibre-gl-B1CfjdFi.css","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-BawBpZYt.css"])))=>i.map(i=>d[i]); +import{c as e,a as s}from"./vendor-core-FtpmsTnh.js";import{j as t,r as a}from"./vendor-react-alRNW2nb.js";import{u as n}from"./vendor-virt-BytWoLhu.js";import{B as l,h as r,a5 as i,a6 as c,a7 as d,a8 as o,a9 as x,aa as m,H as p,ab as h,Q as u,ac as g,ad as f,ae as y,af as j,ag as b,ah as N,ai as v,aj as w,ak as k,M as C,p as _,al as S,am as P,an as H,ao as T,Y as B,_ as M,ap as F,aq as L,ar as D}from"./index-CkRTgHHA.js";import{p as z,d as $,e as R,g as A,b as E}from"./primitives-Bgn6Ik6L.js";import{u as U,r as I,a as V,b as Q,c as G,d as O,i as W}from"./consumer-registry-BUFl6buY.js";import{D as q,R as K,P as X,g as Y}from"./badge-colors-BxLppqaF.js";import{g as J,e as Z,a as ee}from"./chat-utils-mqGCinix.js";import{P as se,d as te,a as ae,b as ne}from"./payload-decoders-_TRhCJrs.js";import{S as le,i as re,g as ie}from"./SignalIndicator-Bdj3-1hL.js";import{_ as ce,$ as de,o as oe,A as xe,V as me,D as pe,R as he,a0 as ue,a1 as ge,a2 as fe,a3 as ye,a as je,a4 as be,H as Ne,a5 as ve,a6 as we,a7 as ke,a8 as Ce,a9 as _e,aa as Se,ab as Pe,ac as He,l as Te,K as Be,ad as Me,ae as Fe,af as Le,ag as De,C as ze,q as $e,Z as Re,w as Ae}from"./vendor-icons-TO0PZKGR.js";import{_ as Ee}from"./cosmograph-DqYT4sUA.js";import{f as Ue,r as Ie}from"./usePipelineStore-CLEA3Bev.js";import{D as Ve}from"./DataBox-DpDXI-WX.js";import{L as Qe,m as Ge,u as Oe,A as We}from"./vendor-motion-DNp0Qg4F.js";import{D as qe,u as Ke}from"./useMapViewStore-sFZdb1_p.js";function Xe({"aria-label":s="Page navigation",className:a,...n}){return t.jsx("nav",{"aria-label":s,...n,className:e("flex gap-x-2",a)})}function Ye({onClick:s,disabled:a=!1,className:n,children:r="Previous"}){return t.jsx("span",{className:e("grow basis-0",n),children:t.jsxs(l,{plain:!0,onClick:s,disabled:a,"aria-label":"Previous page",className:e("gap-1",a&&"invisible"),children:[t.jsx("svg",{className:"size-4 stroke-current",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M2.75 8H13.25M2.75 8L5.25 5.5M2.75 8L5.25 10.5",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})}),r]})})}function Je({onClick:s,disabled:a=!1,className:n,children:r="Next"}){return t.jsx("span",{className:e("flex grow basis-0 justify-end",n),children:t.jsxs(l,{plain:!0,onClick:s,disabled:a,"aria-label":"Next page",className:e("gap-1",a&&"invisible"),children:[r,t.jsx("svg",{className:"size-4 stroke-current",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M13.25 8L2.75 8M13.25 8L10.75 10.5M13.25 8L10.75 5.5",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})})]})})}function Ze({className:s,...a}){return t.jsx("span",{...a,className:e("hidden items-baseline gap-x-2 sm:flex",s)})}function es({page:s,current:a=!1,onClick:n,className:r,children:i}){return t.jsx(l,{plain:!a,outline:a,onClick:()=>null==n?void 0:n(s),"aria-label":`Page ${s}`,"aria-current":a?"page":void 0,className:e("min-w-[2.25rem] before:absolute before:-inset-px before:rounded-lg",a&&"before:bg-subtle-fill",r),children:i??s})}function ss({className:s,...a}){return t.jsx("span",{"aria-hidden":"true",...a,className:e("w-[2.25rem] select-none text-center text-sm text-fg-muted",s),children:"…"})}const ts=s(e=>({requestedHash:null,requestChannel:s=>e({requestedHash:s}),clearRequest:()=>e({requestedHash:null})})),as={rx:{icon:me,label:"Rx",badgeColor:q.rx,avatarBg:"bg-sys-green/15",avatarText:"text-sys-green"},forward:{icon:xe,label:"Fwd",badgeColor:q.forward,avatarBg:"bg-sys-cyan/15",avatarText:"text-sys-cyan"},duplicate:{icon:oe,label:"Dupe",badgeColor:q.duplicate,avatarBg:"bg-fg-muted/15",avatarText:"text-fg-secondary"},tx:{icon:de,label:"Tx",badgeColor:q.tx,avatarBg:"bg-sys-indigo/15",avatarText:"text-sys-indigo"},dropped:{icon:ce,label:"Drop",badgeColor:q.dropped,avatarBg:"bg-sys-amber/15",avatarText:"text-sys-amber"}},ns={sm:"w-3.5 h-3.5",md:"w-4 h-4",lg:"w-5 h-5"},ls={sm:"w-8 h-8",md:"w-9 h-9",lg:"w-10 h-10"};function rs(e){return"tx_local"===e.packet_origin?"tx":"tx_forward"===e.packet_origin?"forward":e.is_duplicate?"duplicate":e.transmitted?"forward":e.drop_reason?"dropped":"rx"}const is=a.memo(function({packet:s,showLabel:a=!0,variant:n="avatar",size:l="sm"}){const i=rs(s),c=as[i],d=c.icon;return"avatar"===n?t.jsx("div",{className:e("flex items-center justify-center rounded-full flex-shrink-0",c.avatarBg,ls[l]),children:t.jsx(d,{className:e(ns[l],c.avatarText)})}):t.jsxs(r,{color:c.badgeColor,children:[t.jsx(d,{className:ns[l]}),a&&c.label]})}),cs=a.memo(function({path:s,localHash:a,className:n}){if(!s||0===s.length)return t.jsx("span",{className:e("text-fg-muted text-xs",n),children:"—"});const l=a?(a.startsWith("0x")?a.slice(2,4):a.slice(0,2)).toUpperCase():null;return t.jsx("span",{className:e("flex items-center gap-0.5 type-data-xs overflow-hidden",n),children:s.map((e,a)=>{const n=a===s.length-1,r=l&&e.toUpperCase()===l;return t.jsxs("span",{className:"flex items-center flex-shrink-0",children:[r?t.jsx("span",{className:"px-1 py-0.5 rounded bg-sys-amber/20 text-sys-amber text-[9px] font-medium",children:"You"}):t.jsx("span",{className:"px-1 py-0.5 rounded bg-subtle-fill-hover text-fg-secondary",children:e.toUpperCase()}),!n&&t.jsx(pe,{className:"w-2.5 h-2.5 text-fg-muted mx-0.5 flex-shrink-0"})]},`${e}-${a}`)})})});function ds({channelName:s,onClick:a,active:n,compact:l,className:r}){const i=s.startsWith("#")?s:`#${s}`,c=e("inline-flex items-center flex-shrink-0","font-medium",l?"px-1.5 h-4 leading-4 rounded text-[10px]":"px-2 h-5 leading-5 rounded text-xs",n?"bg-sys-blue/20 text-sys-blue":"bg-sys-blue/10 text-sys-blue",a&&!n&&"hover:bg-sys-blue/20 cursor-pointer",r);return a?t.jsx("button",{type:"button",onClick:a,className:c,children:i}):t.jsx("span",{className:c,children:i})}function os(e){return{"--data-box-accent":x[e]}}function xs(e){const s=e.payload_type_name||d(e.payload_type??e.type),t=e.route_type_name||o(e.route_type??e.route);return{payloadType:s,routeType:t,payloadColor:X[s]??"zinc",routeColor:K[t]??"zinc"}}function ms(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function ps(e,s){if(s){const t=s(e);return{name:t.name,isCompanion:t.isCompanion,isRepeater:t.isRepeater}}return{name:null,isCompanion:!1,isRepeater:!1}}const hs=a.memo(function({packet:s,onClick:n,localHash:l,neighbors:r,resolveSource:d,isFlashing:o=!1,isTraceHighlighted:m,onTraceHover:p,traceTag:h,onViewTraceReport:u,dupeGroupPosition:g,isDupeGroupHovered:f=!1,onDupeGroupHover:y,dupeCount:j,getDecodedContent:b,onChannelClick:N}){const v=!j&&i(s.is_duplicate),w=void 0!==g,{payloadType:k,routeType:C,payloadColor:_,routeColor:S}=xs(s),P="tx_local"===s.packet_origin,H="TRACE"===k,T=ms(s.original_path),B=ms(s.forwarded_path),M=B.length>0?B:T,F=s.src_hash?(s.src_hash.startsWith("0x")?s.src_hash.slice(2,6):s.src_hash.slice(0,4)).toUpperCase():null,{name:L,isRepeater:D}=ps(s,d);let z=null,$=null,R=null,A=null;if("GRP_TXT"===k&&b){const e=b(s);(null==e?void 0:e.decrypted)&&($=e.senderName,R=e.channelName,A=e.channelHash,e.text&&(z=e.text))}else if("TXT_MSG"===k&&s.raw_packet)try{const e=se.fromHex(s.raw_packet);if(e.success&&e.packet){const s=te(e.packet.payload);s&&!s.encrypted&&(z=s.text)}}catch{}const E=$||(D?null:L),U=!!E,I=!U&&D&&!!L,V=!U&&!I&&"GRP_TXT"===k&&!z,Q=s.payload_length??s.length??0;s.lbt_attempts;const G=a.useCallback(()=>{H&&h&&u?u(h):n(s)},[H,h,u,n,s]),O=a.useCallback(()=>{H&&h&&p&&p(h),w&&y&&s.packet_hash&&y(s.packet_hash)},[H,h,p,w,y,s.packet_hash]),W=a.useCallback(()=>{p&&p(null),y&&y(null)},[p,y]),q=x[_]||x.zinc,K=f;return t.jsxs("div",{onClick:G,onMouseEnter:O,onMouseLeave:W,className:e("group relative cursor-pointer","hover:bg-subtle-fill",v&&!f&&"opacity-40",o&&"flash-row",P&&"bg-sys-indigo/5",m&&"bg-sys-teal/10"),children:[t.jsx("div",{className:e("absolute pointer-events-none transition-opacity duration-75",w?K?"opacity-100":"opacity-0":"opacity-0 group-hover:opacity-100"),style:(()=>{const e={pointerEvents:"none"};return"first"===g?{...e,borderTop:`2px solid ${q}`,borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:"none",borderRadius:"8px 8px 0 0",inset:"-2px -2px 0 -2px"}:"middle"===g?{...e,borderTop:"none",borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:"none",borderRadius:0,inset:"0 -2px"}:"last"===g?{...e,borderTop:"none",borderLeft:`2px solid ${q}`,borderRight:`2px solid ${q}`,borderBottom:`2px solid ${q}`,borderRadius:"0 0 8px 8px",inset:"0 -2px -2px -2px"}:{...e,border:`2px solid ${q}`,borderRadius:"8px",inset:"-2px"}})()}),t.jsxs("div",{className:"relative flex items-center gap-2 min-[600px]:gap-3 px-2 py-2 min-[600px]:px-3 min-[600px]:py-2.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5 flex-shrink-0",children:[t.jsx("div",{className:"relative flex-shrink-0",children:U?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-1 ring-edge-subtle",style:{backgroundColor:J(Z(E).cleanName)},children:Z(E).emoji?t.jsx("span",{className:"text-base leading-none",children:Z(E).emoji}):t.jsx("span",{className:"text-white text-[10px] font-bold tracking-tighter",children:ee(E)})}):I?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:t.jsx(he,{className:"size-5 text-sys-blue"})}):V?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center bg-zinc-500/20 ring-1 ring-edge-subtle",children:t.jsx(ue,{className:"size-4 text-fg-muted"})}):t.jsx(is,{packet:s,variant:"avatar",size:"sm"})}),t.jsx("div",{className:"min-w-0",children:U?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-semibold text-[13px] text-fg-primary font-sans truncate max-w-[90px]",children:E}),F&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate",children:F})]}):I?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-semibold text-[13px] text-fg-primary font-sans truncate max-w-[90px]",children:L}),F&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate",children:F})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"font-bold text-[13px] text-fg-primary font-sans truncate",children:F||"—"}),L&&t.jsx("div",{className:"hidden min-[900px]:block text-[9px] text-fg-muted truncate max-w-[70px]",children:L})]})})]}),t.jsxs("div",{className:"flex-1 flex items-center gap-1 min-[600px]:gap-1.5 min-[900px]:gap-2 min-w-0",children:[t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(_),children:k}),j&&j>1&&t.jsxs("span",{className:"data-box data-box-compact flex-shrink-0",children:["×",j]}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(S),children:C}),t.jsxs("span",{className:"hidden min-[520px]:inline type-data-xs text-fg-muted flex-shrink-0",children:[Q,"B"]}),t.jsx("div",{className:"flex-1 min-w-0 overflow-hidden",children:z||R?t.jsxs("span",{className:"text-[11px] text-fg-secondary truncate block flex items-center gap-1",children:[R&&t.jsx(ds,{channelName:R,compact:!0,onClick:N&&A?e=>{e.stopPropagation(),N(A)}:void 0}),z&&t.jsx("span",{className:"italic truncate",children:z})]}):t.jsx(cs,{path:M,localHash:l})})]}),t.jsxs("div",{className:"flex items-center gap-1.5 flex-shrink-0",children:[t.jsx("span",{className:"data-box data-box-compact",children:c(s.timestamp)}),t.jsx(le,{rssi:s.rssi,snr:s.snr,compact:!0,showValues:!0,validated:re(s)})]})]})]})}),us=a.memo(function({packet:s,onClick:a,localHash:n,neighbors:l,resolveSource:r,isFlashing:d=!1,isTraceHighlighted:o,traceTag:m,onViewTraceReport:p,dupeGroupPosition:h,isDupeGroupHovered:u=!1,onDupeGroupHover:g,dupeCount:f,getDecodedContent:y,onChannelClick:j}){const{payloadType:b,routeType:N,payloadColor:v,routeColor:w}=xs(s),k="tx_local"===s.packet_origin,C="TRACE"===b,_=!f&&i(s.is_duplicate),S=ms(s.original_path),P=ms(s.forwarded_path),H=P.length>0?P:S,T=s._hopCount??H.length,B=s.src_hash?(s.src_hash.startsWith("0x")?s.src_hash.slice(2,6):s.src_hash.slice(0,4)).toUpperCase():null,{name:M,isRepeater:F}=ps(s,r);let L=null,D=null,z=null,$=null;if("GRP_TXT"===b&&y){const e=y(s);(null==e?void 0:e.decrypted)&&(D=e.senderName,z=e.channelName,$=e.channelHash,e.text&&(L=e.text))}else if("TXT_MSG"===b&&s.raw_packet)try{const e=se.fromHex(s.raw_packet);if(e.success&&e.packet){const s=te(e.packet.payload);s&&!s.encrypted&&(L=s.text)}}catch{}const R=D||(F?null:M),A=!!R,E=!A&&F&&!!M,U=!A&&!E&&"GRP_TXT"===b&&!L,I=s.payload_length??s.length??0,V=s.lbt_attempts??0,Q=x[v]||x.zinc;return t.jsxs("div",{onClick:()=>{C&&m&&p?p(m):a(s)},className:e("relative pl-3 pr-2.5 py-2 cursor-pointer","active:bg-subtle-fill-hover",_&&"opacity-40",d&&"flash-row",k&&"bg-sys-indigo/5",o&&"bg-sys-teal/10"),children:[t.jsx("div",{className:"absolute left-0 transition-all",style:(()=>{if(!h)return{opacity:0};const e=u?1:.4,s=u?"3px":"2px";return"first"===h?{backgroundColor:Q,opacity:e,width:s,top:"6px",bottom:0,borderRadius:"0 9999px 0 0"}:"middle"===h?{backgroundColor:Q,opacity:e,width:s,top:0,bottom:0,borderRadius:0}:"last"===h?{backgroundColor:Q,opacity:e,width:s,top:0,bottom:"6px",borderRadius:"0 0 9999px 0"}:{backgroundColor:Q,opacity:e,width:s,top:"6px",bottom:"6px",borderRadius:"9999px"}})()}),t.jsxs("div",{className:"flex items-start gap-2",children:[t.jsx("div",{className:"relative flex-shrink-0 mt-0.5",children:A?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-1 ring-edge-subtle",style:{backgroundColor:J(Z(R).cleanName)},children:Z(R).emoji?t.jsx("span",{className:"text-base leading-none",children:Z(R).emoji}):t.jsx("span",{className:"text-white text-[10px] font-bold tracking-tighter",children:ee(R)})}):E?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center ring-[1.5px] ring-sys-blue",children:t.jsx(he,{className:"size-5 text-sys-blue"})}):U?t.jsx("div",{className:"w-8 h-8 rounded-full flex items-center justify-center bg-zinc-500/20 ring-1 ring-edge-subtle",children:t.jsx(ue,{className:"size-4 text-fg-muted"})}):t.jsx(is,{packet:s,variant:"avatar",size:"sm"})}),t.jsxs("div",{className:"flex-1 min-w-0 space-y-0.5",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[A?t.jsx("span",{className:"font-medium text-[14px] text-fg-primary tracking-tight truncate min-w-0",children:R}):E?t.jsx("span",{className:"font-medium text-[14px] text-fg-primary tracking-tight truncate min-w-0",children:M}):t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"font-semibold text-[14px] text-fg-primary tracking-tight flex-shrink-0",children:B||"—"}),M&&t.jsx("span",{className:"text-[12px] text-fg-muted truncate min-w-0",children:M})]}),t.jsx("div",{className:"flex-1"}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(v),children:b}),t.jsx("span",{className:"data-box data-box-compact data-box-outlined flex-shrink-0",style:os(w),children:N}),f&&f>1&&t.jsxs("span",{className:"data-box data-box-compact flex-shrink-0",children:["×",f]}),t.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[t.jsx("span",{className:"type-data-xs text-fg-muted w-[28px] text-right",children:s.rssi}),t.jsx(le,{rssi:s.rssi,compact:!0,showValues:!1,validated:re(s)})]})]}),t.jsxs("div",{className:"flex items-center gap-1 type-data-xs text-fg-muted",children:[t.jsx("span",{className:"data-box data-box-compact flex-shrink-0",children:c(s.timestamp)}),I>0&&t.jsxs("span",{children:[I,"B"]}),V>0&&t.jsxs("span",{className:V>1?"text-sys-amber/60":void 0,children:["LBT:",V]}),null!=s.snr&&t.jsxs("span",{children:[s.snr.toFixed(0),"dB"]}),L||z?t.jsxs("span",{className:"text-[11px] text-fg-secondary truncate flex items-center gap-1 min-w-0",children:[z&&t.jsx(ds,{channelName:z,compact:!0,onClick:j&&$?e=>{e.stopPropagation(),j($)}:void 0}),L&&t.jsx("span",{className:"italic truncate",children:L})]}):T>0?t.jsx(cs,{path:H,localHash:n}):null]})]})]})]})}),gs=a.lazy(()=>Ee(()=>import("./PathMapMapLibre-_vG9wINu.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])));function fs(e){return`${(100*e).toFixed(0)}%`}function ys(e,s,t){let a;return a=0===s?t.muted:e>=1?t.success:e>=.5?t.secondary:e>=.25?t.poor:e>0?t.danger:t.muted,{color:a}}class js extends a.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?t.jsxs("div",{className:"h-[200px] flex items-center justify-center text-fg-muted",children:[t.jsx(ye,{className:"w-4 h-4 mr-2"}),"Map failed to load"]}):this.props.children}}function bs({path:s,neighbors:n,localNode:l,localHash:r,srcHash:i,dstHash:c,neighborAffinity:d,prefixLookup:o,hubNodes:x,traceSnr:h,advertiserSource:u}){const[g,f]=a.useState(null),y=a.useMemo(()=>{if(!u)return null;const e="wardrive"===u.nodeType;return{prefix:u.prefix||"??",candidates:[{hash:u.publicKey||u.prefix||"source",name:u.name,latitude:u.latitude,longitude:u.longitude,probability:1,isLocal:!1,isWardrive:e}],confidence:1,totalMatches:1,isSource:!0}},[u]),j=a.useMemo(()=>{if(u)return null;if(!i)return null;const e=p(i),s=n[i];if((null==s?void 0:s.latitude)&&(null==s?void 0:s.longitude)&&(0!==s.latitude||0!==s.longitude))return{prefix:e,candidates:[{hash:i,name:s.node_name||s.name||"Source",latitude:s.latitude,longitude:s.longitude,probability:1,isLocal:!1,isDirectNeighbor:!0===s.zero_hop}],confidence:1,totalMatches:1,isSource:!0};const t=(null==s?void 0:s.node_name)||(null==s?void 0:s.name)||i.slice(0,8);return{prefix:e,candidates:[{hash:i,name:t,latitude:0,longitude:0,probability:1,isLocal:!1}],confidence:1,totalMatches:1,isSource:!0}},[u,i,n]),b=a.useMemo(()=>{const e=(null==c?void 0:c.startsWith("0x"))?c.slice(2):c;if((!e||"00"===e||"0000000000000000"===e)&&l&&r){const e=p(r),s=0!==l.latitude||0!==l.longitude;return{prefix:e,candidates:[{hash:r,name:l.name||"Local Node",latitude:s?l.latitude:0,longitude:s?l.longitude:0,probability:1,isLocal:!0}],confidence:1,totalMatches:1,isDestination:!0}}if(!c)return null;const s=p(c);if(r&&c===r&&l){const e=0!==l.latitude||0!==l.longitude;return{prefix:s,candidates:[{hash:c,name:l.name||"Local Node",latitude:e?l.latitude:0,longitude:e?l.longitude:0,probability:1,isLocal:!0}],confidence:1,totalMatches:1,isDestination:!0}}const t=n[c];if((null==t?void 0:t.latitude)&&(null==t?void 0:t.longitude)&&(0!==t.latitude||0!==t.longitude))return{prefix:s,candidates:[{hash:c,name:t.node_name||t.name||"Destination",latitude:t.latitude,longitude:t.longitude,probability:1,isLocal:!1,isDirectNeighbor:!0===t.zero_hop}],confidence:1,totalMatches:1,isDestination:!0};const a=(null==t?void 0:t.node_name)||(null==t?void 0:t.name)||c.slice(0,8);return{prefix:s,candidates:[{hash:c,name:a,latitude:0,longitude:0,probability:1,isLocal:!1}],confidence:1,totalMatches:1,isDestination:!0}},[c,n,l,r]),N=a.useMemo(()=>function(e,s,t,a,n,l){if(!e||0===e.length)return{hops:[],overallConfidence:0,hasValidPath:!1};const r=e.length-1,i=e.map((i,c)=>{const d=c===r,o=e.length-c,{candidates:x,totalMatches:p}=function(e,s,t,a,n=!1,l,r,i){const c=Ue(s);let d;r&&(d=Ie(r,e,{position:i,isLastHop:n}).confidence);const{matches:o,probability:x}=function(e,s,t,a,n=!1){const l=e.toUpperCase(),r=[],i=t&&m(l,t);i&&r.push(t);for(const h of Object.keys(s))m(l,h)&&r.push(h);if(n&&i&&t&&1===r.length)return{matches:r,probability:1,bestMatch:t};if(n&&i&&r.length>1){const e=r.filter(e=>e!==t);if(1===e.length)return{matches:r,probability:1,bestMatch:e[0]}}const c=r.length>0?1/r.length:0,d=[...r].sort();let o=null,x=-1;if(1===d.length)o=d[0];else if(d.length>1&&a){for(const e of d){const s=a.get(e),t=s?"number"==typeof s?s:s.combinedScore:0;t>x&&(x=t,o=e)}o||(o=d[0])}else d.length>0&&(o=d[0]);let p=c;if(r.length>1&&a&&x>0){let e=0;for(const s of r){const t=a.get(s);e+=t?"number"==typeof t?t:t.combinedScore:0}e>0&&(p=Math.min(.95,x/e))}return{matches:r,probability:p,bestMatch:o}}(e,c,a,l,n),p=o.length,h=[],u=e.toUpperCase(),g=t&&void 0!==t.latitude&&void 0!==t.longitude&&(0!==t.latitude||0!==t.longitude);for(const y of o){if(a&&m(u,a)&&y===a&&g&&t){h.push({hash:y,name:t.name||"Local Node",latitude:t.latitude,longitude:t.longitude,probability:n?1:x,isLocal:!0});continue}const e=c[y];(null==e?void 0:e.latitude)&&(null==e?void 0:e.longitude)&&(0!==e.latitude||0!==e.longitude)&&h.push({hash:y,name:e.node_name||e.name||"Unknown",latitude:e.latitude,longitude:e.longitude,probability:x,isLocal:!1,isDirectNeighbor:!0===e.zero_hop})}const f=h.length;if(1===f)h[0].probability=d??1;else if(f>1)if(void 0!==d&&d>0){h[0].probability=d;const e=1-d,s=f-1;h.slice(1).forEach(t=>{t.probability=e/s})}else{let e=0;const s=h.map(s=>{if(s.isLocal)return{candidate:s,score:1};const a=null==l?void 0:l.get(s.hash);let n=.5;var r;let i;return g&&t&&(n=(r=function(e,s,t,a){const n=(t-e)*Math.PI/180,l=(a-s)*Math.PI/180,r=Math.sin(n/2)*Math.sin(n/2)+Math.cos(e*Math.PI/180)*Math.cos(t*Math.PI/180)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))*6371e3}(t.latitude,t.longitude,s.latitude,s.longitude))<100?1:r<500?.9:r<1e3?.7:r<5e3?.5:r<1e4?.3:.1),a?i=.3*n+.3*a.hopConsistencyScore+.4*a.frequencyScore:(i=n,s.isDirectNeighbor&&(i=Math.max(i,.8))),e+=i,{candidate:s,score:i}});if(e>0)s.forEach(({candidate:s,score:t})=>{s.probability=Math.min(.95,t/e)});else{const e=1/f;h.forEach(s=>s.probability=e)}}return{candidates:h,totalMatches:p}}(i,s,t,a,d,n,l,o),h=x.length>0?Math.max(...x.map(e=>e.probability)):0;return{prefix:i,candidates:x,confidence:h,totalMatches:p}}),c=i.reduce((e,s)=>0===s.confidence?0:e*s.confidence,1),d=i.some(e=>e.candidates.length>0);return{hops:i,overallConfidence:c,hasValidPath:d}}(s,n,l,r,d,o),[s,n,l,r,d,o]),v=a.useMemo(()=>{const e=[];y?e.push(y):j&&e.push(j),e.push(...N.hops),b&&e.push(b);const s=e.reduce((e,s)=>0===s.confidence?0:e*s.confidence,1),t=e.some(e=>e.candidates.some(e=>0!==e.latitude||0!==e.longitude));return{hops:e,overallConfidence:s,hasValidPath:t}},[y,j,N,b]),w=a.useMemo(()=>{const e=getComputedStyle(document.documentElement);return{success:e.getPropertyValue("--sys-green").trim()||"#39D98A",secondary:e.getPropertyValue("--sys-indigo").trim()||"#F9D26F",poor:e.getPropertyValue("--signal-poor").trim()||"#FF8A5C",danger:e.getPropertyValue("--sys-red").trim()||"#FF5C7A",muted:e.getPropertyValue("--text-muted").trim()||"#767688"}},[]);return v.hasValidPath?t.jsxs("div",{className:"h-full flex flex-col space-y-2",children:[t.jsxs("div",{className:"flex items-center justify-between text-xs",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"text-fg-muted",children:"Path Confidence:"}),t.jsx("span",{className:(k=v.overallConfidence,k>=1?"text-sys-green":k>=.5?"text-sys-indigo":k>=.25?"text-signal-poor":k>0?"text-sys-red":"text-fg-muted"),children:fs(v.overallConfidence)}),t.jsx("button",{className:"text-fg-muted hover:text-fg-secondary transition-colors",title:"Confidence is calculated based on how many known nodes match each path prefix. Multiple matches reduce confidence due to collision probability.",children:t.jsx(fe,{className:"w-3 h-3"})})]}),t.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-sys-green"}),t.jsx("span",{className:"text-fg-muted",children:"Exact"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-sys-indigo"}),t.jsx("span",{className:"text-fg-muted",children:"Multi"})]}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("div",{className:"w-2 h-2 rounded-full bg-fg-muted"}),t.jsx("span",{className:"text-fg-muted",children:"Unknown"})]})]})]}),t.jsx("div",{className:"flex-1 min-h-0 overflow-hidden",children:t.jsx(js,{children:t.jsx(a.Suspense,{fallback:t.jsx("div",{className:"h-full bg-elevated flex items-center justify-center text-fg-muted text-sm",children:"Loading map..."}),children:t.jsx(gs,{resolvedPath:v,localNode:l,hubNodes:x,hoveredHopIndex:g,onHoverHop:f,traceSnr:h})})})}),t.jsx("div",{className:"flex flex-wrap items-center gap-1.5",children:v.hops.map((s,a)=>{var n,l,r;const i=!0===s.isSource,c=!0===s.isDestination,d=g===a;let o;return o=i?`Source: ${(null==(n=s.candidates[0])?void 0:n.name)||"Unknown"}`:c?`Destination: ${(null==(l=s.candidates[0])?void 0:l.name)||"Unknown"}`:0===s.totalMatches?"No matching nodes found":1===s.totalMatches?`Exact match: ${(null==(r=s.candidates[0])?void 0:r.name)||"Unknown"}`:`${s.totalMatches} possible matches (${(100*s.confidence).toFixed(0)}% confidence)`,t.jsxs("div",{className:e("flex items-center gap-1 px-1.5 py-0.5 rounded type-data-xs cursor-pointer transition-all",d?"bg-sys-blue/20 ring-1 ring-sys-blue/50":"bg-elevated hover:bg-subtle",i&&"border border-sys-green/30",c&&"border border-sys-blue/30"),title:o,onMouseEnter:()=>f(a),onMouseLeave:()=>f(null),children:[i&&t.jsx("span",{className:"text-sys-green text-[8px] mr-0.5",children:"SRC"}),c&&t.jsx("span",{className:"text-sys-blue text-[8px] mr-0.5",children:"DST"}),t.jsx("span",{style:ys(s.confidence,s.totalMatches,w),children:s.prefix}),!i&&!c&&s.totalMatches>1&&t.jsxs("span",{className:"text-fg-muted",children:["×",s.totalMatches]}),!i&&!c&&0===s.totalMatches&&t.jsx("span",{className:"text-fg-muted",children:"?"})]},a)})})]}):t.jsxs("div",{className:"flex items-center justify-center text-fg-muted text-xs py-4",children:[t.jsx(ge,{className:"w-3.5 h-3.5 mr-1.5 opacity-50"}),"No location data available for path nodes"]});var k}function Ns(e){return e.match(/.{1,2}/g)||[]}function vs(e){return null!==e&&e.startsWith("payload:")}const ws=15,ks="color-mix(in srgb, var(--elevated) 60%, var(--body))",Cs="\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n ",_s=2,Ss={type:"tween",duration:.25,ease:[.25,.1,.25,1]};function Ps(e,s){return e?`inset 0 0 0 ${_s}px ${x[s]}`:Cs}function Hs(e,s){return e?s:`color-mix(in srgb, ${s} ${ws}%, transparent)`}function Ts({segments:e,selectedSegment:s,onSegmentClick:n}){const[l,r]=a.useState(null),[i,c]=a.useState(null),d=e.some(e=>void 0!==e.id)&&n,o=[];for(const t of e){const e=Ns(t.hex);for(const s of e)o.push({byte:s.toUpperCase(),color:t.color,id:t.id})}const m=[];for(let t=0;t{const o=e.length<16;return t.jsx("div",{className:"flex rounded-md overflow-hidden",children:e.map(({byte:a,color:m,id:p},h)=>{const u=h===e.length-1,g=o&&u,f=x[m],y=p?l===p:i===m,j=Boolean(p&&s===p),b=y||j;return t.jsx("span",{className:"w-[1.75rem] text-xs text-center py-0.5 font-mono select-text "+(d?"cursor-pointer":""),style:{backgroundColor:Hs(b,f),color:b?"rgba(255,255,255,0.95)":f,transition:b?"none":"background-color 0.15s ease-out, color 0.15s ease-out",touchAction:"manipulation",...g?{borderRadius:"0 0.375rem 0.375rem 0"}:{}},onMouseEnter:()=>{p?r(p):c(m)},onMouseLeave:()=>{r(null),c(null)},onClick:()=>p&&(null==n?void 0:n(p)),onTouchStart:()=>{p?r(p):c(m)},onTouchEnd:()=>{r(null),c(null)},children:a},h)})},a)})})}function Bs({rawHex:e,hexSegments:s,selectedSegment:n,onSegmentClick:l}){const[r,i]=a.useState(!1),c=a.useCallback(async()=>{try{await navigator.clipboard.writeText(e.toUpperCase()),i(!0),setTimeout(()=>i(!1),2e3)}catch(s){console.error("Failed to copy:",s)}},[e]);return t.jsxs("div",{className:"bg-black rounded-2xl p-6 relative",children:[t.jsx(Ts,{segments:s,selectedSegment:n,onSegmentClick:l}),t.jsx("button",{onClick:c,className:"absolute bottom-3 right-3 flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg bg-subtle-fill-hover hover:bg-subtle-fill-strong text-fg-muted hover:text-fg-secondary transition-all text-xs font-sans",title:"Copy raw packet hex",children:r?t.jsxs(t.Fragment,{children:[t.jsx(je,{className:"w-3.5 h-3.5 text-sys-green"}),t.jsx("span",{className:"text-sys-green",children:"Copied"})]}):t.jsxs(t.Fragment,{children:[t.jsx(oe,{className:"w-3.5 h-3.5"}),t.jsx("span",{children:"Copy"})]})})]})}function Ms({bits:e,field:s,value:a,binary:n}){return t.jsxs("tr",{children:[t.jsx("td",{className:"py-1.5 text-xs text-fg-muted tabular-nums",children:e}),t.jsx("td",{className:"py-1.5 text-sm text-fg-secondary",children:s}),t.jsx("td",{className:"py-1.5",children:(()=>{if("Payload Type"===s){const e=X[a]||"zinc";return t.jsx(r,{color:e,children:a})}if("Route Type"===s){const e=K[a]||"zinc";return t.jsx(r,{color:e,children:a})}return t.jsx("span",{className:"text-sm text-fg-primary",children:a})})()}),t.jsx("td",{className:"py-1.5 type-data-xs text-sys-cyan",children:n})]})}function Fs({id:e,title:s,color:a,hexBytes:n,startByte:l,endByte:i,isSelected:c,children:d}){const o=n?Ns(n):[];return t.jsxs(Ge.div,{layout:"position",layoutId:e,transition:Ss,className:"w-full min-w-0 overflow-hidden rounded-xl p-4 sm:p-5 space-y-4",style:{backgroundColor:ks,boxShadow:Ps(c,a)},children:[t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 min-w-0",children:[t.jsx(r,{color:a,children:s}),o.length>0&&o.length<=16&&o.map((e,s)=>t.jsx(r,{color:a,className:"font-mono",children:e.toUpperCase()},s))]}),t.jsxs("span",{className:"type-data-xs text-fg-muted flex-shrink-0",children:["Bytes ",l,"-",i]})]}),t.jsx("div",{className:"min-w-0 overflow-hidden",children:d})]})}function Ls({advert:e,timestamp:s}){const a=f(s||e.timestamp);return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-indigo/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-indigo) 0%, var(--sys-blue) 100%)"},children:t.jsx(he,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.name||"Unknown Node"}),t.jsx("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:e.nodeType})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[void 0!==e.latitude&&void 0!==e.longitude&&t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ge,{className:"w-4 h-4 text-sys-indigo flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-mono",children:[e.latitude.toFixed(5),"°, ",e.longitude.toFixed(5),"°"]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-indigo flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]})]})]})})}function Ds({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-teal/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-teal) 0%, var(--sys-cyan) 100%)"},children:t.jsx(Se,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.channelName||"Channel Data"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:[e.dataLength," bytes • ",e.decrypted?"Decrypted":"Encrypted"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(Ne,{className:"w-4 h-4 text-sys-teal flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-sans",children:["Channel: ",t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-teal flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]}),e.decrypted&&e.decryptedHex&&t.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:[t.jsx("p",{className:"type-micro text-fg-muted mb-1 font-sans",children:"Decrypted Data"}),t.jsx("div",{className:"max-w-full overflow-x-auto",children:t.jsx(Ve,{size:"compact",copy:!0,className:"inline-block",children:t.jsx("span",{className:"break-all text-xs",children:e.decryptedHex.toUpperCase()})})})]})]})]})})}function zs({decoded:e,timestamp:s,isLoading:n=!1,onDecrypted:l}){const r=s?f(s):"Unknown",[i,c]=a.useState(""),[d,o]=a.useState(!1),[x,m]=a.useState(null),[p,h]=a.useState(!1),u=a.useCallback(async()=>{if(i.trim()&&e.ciphertextHex&&e.macHex){o(!0),m(null);try{const s=parseInt(e.channelHash,16),t=y(e.macHex),a=y(e.ciphertextHex),n=await j(i.trim(),s,t,a);if(n.success){const s=n.result.plaintext,t=new TextDecoder("utf-8",{fatal:!1}).decode(s.slice(5)),a=t.indexOf(": "),r={...e,channelName:n.result.channelName,decrypted:!0,timestamp:s[0]|s[1]<<8|s[2]<<16|s[3]<<24,flags:s[4],senderName:a>0?t.slice(0,a):void 0,text:a>0?t.slice(a+2):t};null==l||l(r),c(""),h(!1)}else m(n.error)}catch(s){m(s instanceof Error?s.message:"Unknown error")}finally{o(!1)}}},[i,e,l]);return n?t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-xl p-4 sm:p-5",style:{backgroundColor:"color-mix(in srgb, var(--elevated) 60%, var(--body))",boxShadow:"\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n "},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-3 h-[15px]",children:[t.jsx("div",{className:"h-2.5 w-12 rounded bg-subtle-fill-hover animate-pulse"}),t.jsx("div",{className:"h-2.5 w-16 rounded bg-subtle-fill-hover animate-pulse"})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tl-md",style:{background:"color-mix(in srgb, var(--sys-blue) 30%, transparent)"},children:t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("div",{className:"h-3.5 w-48 rounded bg-subtle-fill-strong animate-pulse"}),t.jsx("div",{className:"h-3.5 w-32 rounded bg-subtle-fill-strong animate-pulse"})]})})]})}):e.decrypted?t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-xl p-4 sm:p-5",style:{backgroundColor:"color-mix(in srgb, var(--elevated) 60%, var(--body))",boxShadow:"\n inset 0 0 0 1px color-mix(in srgb, var(--fg-primary) 6%, transparent),\n inset 0 1px 0 color-mix(in srgb, white 3%, transparent),\n 0 1px 2px color-mix(in srgb, black 5%, transparent)\n "},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.senderName&&t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["From ",t.jsx("span",{className:"text-fg-secondary font-medium",children:e.senderName})]}),e.channelName&&t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["in ",t.jsx("span",{className:"text-sys-cyan font-medium",children:e.channelName})]})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tl-md",style:{background:"linear-gradient(135deg, var(--sys-blue) 0%, color-mix(in srgb, var(--sys-blue) 85%, var(--sys-cyan)) 100%)"},children:t.jsx("p",{className:"text-sm text-white font-sans leading-relaxed whitespace-pre-wrap break-words",children:e.text})})]})}):t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-zinc-500/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--zinc-500) 0%, color-mix(in srgb, var(--zinc-500) 70%, black) 100%)"},children:t.jsx(we,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:e.isPublicHashChannel?"Public Hash Channel":"Encrypted Message"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:["Channel hash: ",t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-zinc-400 flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:r})]}),e.ciphertextHex&&e.macHex&&t.jsx("div",{className:"space-y-2",children:p?t.jsxs("div",{className:"space-y-2",children:[t.jsxs("div",{className:"flex gap-2",children:[t.jsx("input",{type:"text",value:i,onChange:e=>c(e.target.value),placeholder:"Channel name (e.g. south-bay)",className:"flex-1 px-3 py-1.5 text-sm rounded-lg bg-subtle-fill-strong border border-edge-subtle text-fg-primary placeholder:text-fg-muted focus:outline-none focus:border-zinc-500",onKeyDown:e=>"Enter"===e.key&&u(),disabled:d}),t.jsx("button",{onClick:u,disabled:d||!i.trim(),className:"px-3 py-1.5 text-sm font-medium rounded-lg bg-zinc-600 hover:bg-zinc-500 text-white disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:d?"Testing...":"Try"}),t.jsx("button",{onClick:()=>{h(!1),m(null),c("")},className:"px-2 py-1.5 text-sm rounded-lg hover:bg-subtle-fill-strong text-fg-muted transition-colors",children:"×"})]}),x&&t.jsx("p",{className:"text-xs text-sys-red",children:x})]}):t.jsx("button",{onClick:()=>h(!0),className:"text-xs text-zinc-400 hover:text-zinc-300 underline underline-offset-2 transition-colors",children:"Know the channel name? Try to decrypt"})}),!p&&t.jsx("p",{className:"text-xs text-fg-muted",children:e.isPublicHashChannel?"Public hash channel message. Key not in common channel list.":"Unknown hash channel. Channel name required for decryption."})]})]})})}function $s({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:"linear-gradient(135deg, var(--sys-green) 0%, var(--sys-teal) 100%)"},children:t.jsx(_e,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:"Acknowledgment"}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:["CRC: ",t.jsxs("span",{className:"font-mono text-sys-green",children:["0x",e.crc]})," · ",a]})]})]})}function Rs({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=e.path.length;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-amber/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-amber) 0%, var(--sys-orange) 100%)"},children:t.jsx(Ce,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:"Path Response"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:[n," ",1===n?"hop":"hops"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-2",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-amber flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]}),e.path.length>0&&t.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:t.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.path.map((e,s)=>t.jsxs("div",{className:"flex items-center gap-2",children:[s>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-amber"}),t.jsx(r,{color:"amber",className:"font-mono",children:e})]},s))})})]})]})})}function As({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=e.pathHashes.length,l=e.snrValues.length;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-blue/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-blue) 0%, var(--sys-indigo) 100%)"},children:t.jsx(ke,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:["Trace ",e.isComplete?"Complete":"In Progress"]}),t.jsxs("p",{className:"text-sm text-fg-muted mt-0.5",children:["Tag: 0x",e.traceTag.slice(0,8),e.isComplete&&" • ✓"]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary",children:a})]}),t.jsxs("div",{className:"flex items-center gap-4 text-xs text-fg-muted",children:[t.jsxs("span",{children:[n," target ",1===n?"hop":"hops"]}),t.jsx("span",{children:"•"}),t.jsxs("span",{children:[l," SNR ",1===l?"sample":"samples"]}),0!==e.authCode&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"•"}),t.jsxs("span",{children:["Auth: ",e.authCode]})]})]}),e.pathHashes.length>0&&t.jsx("div",{className:"flex flex-wrap items-center gap-2 pt-1",children:e.pathHashes.map((s,a)=>{const n=e.snrValues[a],l=void 0!==n?(e=>e>=7?"green":e>=0?"yellow":e>=-5?"orange":"red")(n):"zinc",i=void 0!==n;return t.jsxs("div",{className:"flex items-center gap-2",children:[a>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-blue flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx(r,{color:i?"blue":"zinc",className:"font-mono",children:s}),i&&t.jsxs(r,{color:l,className:"font-mono",children:[n>=0?"+":"",Number.isInteger(n)?n:n.toFixed(1),"dB"]})]})]},a)})})]})]})})}function Es({decoded:e,timestamp:s}){const a=s?f(s):"Unknown";return e.encrypted?t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:"linear-gradient(135deg, var(--sys-indigo) 0%, var(--sys-blue) 100%)"},children:t.jsx(we,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:"Encrypted Message"}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:[e.srcHash," → ",e.destHash," · ",a]})]})]}):t.jsxs("div",{className:"mb-4",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1.5 px-1",children:[t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:[t.jsx("span",{className:"font-mono text-fg-secondary",children:e.srcHash})," → ",t.jsx("span",{className:"font-mono text-fg-secondary",children:e.destHash})]}),t.jsxs("span",{className:"text-[11px] text-fg-muted font-sans",children:["· ",a]})]}),t.jsx("div",{className:"inline-block max-w-[85%] px-3.5 py-2 rounded-2xl rounded-tr-md ml-auto",style:{background:"linear-gradient(135deg, var(--sys-green) 0%, var(--sys-teal) 100%)"},children:t.jsx("p",{className:"text-sm text-white font-sans leading-relaxed whitespace-pre-wrap break-words",children:e.text})})]})}function Us({decoded:e,timestamp:s}){const a=s?f(s):"Unknown",n=(e.partNumber+1)/e.totalParts*100;return t.jsx("div",{className:"mb-4",children:t.jsxs("div",{className:"rounded-2xl overflow-hidden bg-sys-yellow/10",style:{backdropFilter:"blur(20px)",WebkitBackdropFilter:"blur(20px)"},children:[t.jsxs("div",{className:"px-4 pt-4 pb-3 flex items-center gap-3",children:[t.jsx("div",{className:"w-12 h-12 rounded-xl flex items-center justify-center shadow-lg",style:{background:"linear-gradient(135deg, var(--sys-yellow) 0%, var(--sys-amber) 100%)"},children:t.jsx(be,{className:"w-6 h-6 text-white"})}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsx("h3",{className:"text-lg font-semibold text-fg-primary font-sans truncate leading-tight",children:"Multipart Segment"}),t.jsxs("p",{className:"text-sm text-fg-muted font-sans mt-0.5",children:["Part ",e.partNumber+1," of ",e.totalParts]})]})]}),t.jsx("div",{className:"mx-4 border-t border-edge-subtle"}),t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[t.jsx("div",{children:t.jsx("div",{className:"h-2 bg-subtle-fill-strong rounded-full overflow-hidden",children:t.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${n}%`,background:"linear-gradient(90deg, var(--sys-yellow), var(--sys-amber))"}})})}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(Ne,{className:"w-4 h-4 text-sys-yellow flex-shrink-0"}),t.jsxs("span",{className:"text-sm text-fg-secondary font-sans",children:["Message ID: ",t.jsx("span",{className:"font-mono",children:e.messageId})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(ve,{className:"w-4 h-4 text-sys-yellow flex-shrink-0"}),t.jsx("span",{className:"text-sm text-fg-secondary font-sans",children:a})]})]})]})})}function Is({decoded:e,timestamp:s,payloadType:a}){const n=s?f(s):"Unknown",l=(()=>{switch(a){case u.REQ:return{icon:Te,gradient:"var(--sys-orange), var(--sys-red)",bg:"rgba(249, 115, 22, 0.15)",label:"Request"};case u.RESPONSE:return{icon:He,gradient:"var(--sys-green), var(--sys-teal)",bg:"rgba(34, 197, 94, 0.15)",label:"Response"};case u.ANON_REQ:return{icon:we,gradient:"var(--sys-indigo), var(--sys-pink)",bg:"rgba(91, 91, 214, 0.15)",label:"Anonymous Request"};default:return{icon:Pe,gradient:"var(--sys-gray), var(--sys-slate)",bg:"rgba(107, 114, 128, 0.15)",label:e.payloadTypeName}}})(),r=l.icon;return t.jsxs("div",{className:"mb-4 flex items-center gap-3",children:[t.jsx("div",{className:"w-10 h-10 rounded-xl flex items-center justify-center shadow-md",style:{background:`linear-gradient(135deg, ${l.gradient})`},children:t.jsx(r,{className:"w-5 h-5 text-white"})}),t.jsxs("div",{className:"flex-1",children:[t.jsx("p",{className:"text-sm font-semibold text-fg-primary font-sans",children:l.label}),t.jsxs("p",{className:"text-xs text-fg-muted font-sans mt-0.5",children:[e.length," bytes · ",n]})]})]})}function Vs({pathHex:e}){if(!e)return null;const s=Ns(e);return t.jsx("div",{className:"flex flex-wrap items-center gap-2 py-2",children:s.map((e,s)=>t.jsxs("div",{className:"flex items-center gap-2",children:[s>0&&t.jsx(xe,{className:"w-4 h-4 text-sys-amber flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(Ve,{size:"compact",copy:!0,children:e.toUpperCase()}),t.jsx("span",{className:"text-xs text-fg-muted font-sans tabular-nums w-4 text-left",children:s+1})]})]},s))})}function Qs({decoded:e,payloadType:s}){const a=g[s]||`TYPE_${s}`;switch(e.type){case"advert":{const s="chat"===e.nodeType?"companion":e.nodeType.replace("_"," "),a=void 0!==e.latitude&&void 0!==e.longitude&&!(0===e.latitude&&0===e.longitude);return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Role:"})," ",s]}),e.name&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Name:"})," ",e.name]}),a&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Location:"})," ",e.latitude.toFixed(4),"°, ",e.longitude.toFixed(4),"°"]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Time:"})," ",f(e.timestamp)]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Flags:"})," ",e.flagsDescription]})]})}case"ack":return t.jsx("div",{className:"text-xs text-fg-primary space-y-0.5",children:t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"CRC:"})," 0x",e.crc]})});case"path":return t.jsx("div",{className:"text-xs text-fg-primary space-y-1",children:t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Path:"})," ",e.pathString||"(empty)"]})});case"trace":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-1",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Tag:"})," 0x",e.traceTag]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Target Path:"})," ",e.pathString||"(empty)"]}),e.snrValues.length>0&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"SNR:"})," ",e.snrValues.map(e=>`${e>=0?"+":""}${Number.isInteger(e)?e:e.toFixed(1)}dB`).join(" → ")]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Status:"})," ",e.isComplete?"✓ Complete":`In progress (${e.snrValues.length}/${e.pathHashes.length})`]})]});case"txt_msg":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Src:"})," ",e.srcHash]}),e.encrypted?t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted content"}):t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Text:"})," ",e.text]})]});case"grp_txt":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Channel:"})," ",e.channelName?t.jsx("span",{className:"text-sys-green",children:e.channelName}):e.isPublicHashChannel?t.jsx("span",{className:"text-sys-indigo",children:"Public Hash Channel"}):t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]}),e.decrypted?t.jsxs(t.Fragment,{children:[e.senderName&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"From:"})," ",e.senderName]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Text:"})," ",e.text]})]}):e.isPublicHashChannel?t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted (public hash channel)"}):t.jsx("p",{className:"text-fg-muted italic",children:"Encrypted (unknown channel)"})]});case"grp_data":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Channel:"})," ",e.channelName?t.jsx("span",{className:"text-sys-teal",children:e.channelName}):t.jsxs("span",{className:"font-mono",children:["0x",e.channelHash]})]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Data:"})," ",e.dataLength," bytes ",e.decrypted?"(decrypted)":"(encrypted)"]})]});case"multipart":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Part:"})," ",e.partNumber+1,"/",e.totalParts]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Message ID:"})," ",e.messageId]})]});case"control":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Control:"})," ",e.subtypeName]}),e.dataLength>0&&t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Data:"})," ",e.dataLength," bytes"]})]});case"req":case"response":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Src:"})," ",e.srcHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Ciphertext:"})," ",e.ciphertextLength," bytes"]})]});case"anon_req":return t.jsxs("div",{className:"text-xs text-fg-primary space-y-0.5",children:[t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Dest:"})," ",e.destHash]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Pub Key:"})," ",t.jsxs("span",{className:"font-mono break-all",children:[e.senderPublicKey.slice(0,16),"…"]})]}),t.jsxs("p",{children:[t.jsx("span",{className:"text-fg-muted",children:"Ciphertext:"})," ",e.ciphertextLength," bytes"]})]});default:return t.jsxs("p",{className:"text-xs text-fg-secondary",children:[a," (","length"in e?e.length:0," bytes)"]})}}const Gs=a.memo(function({packet:e,decodedGrpTxt:s}){var n,l;const i=e.raw_packet||"",c=i.length/2,d=h(),[o,x]=a.useState(null),[m,p]=a.useState(null),[g,y]=a.useState(!1),[j,b]=a.useState(null),N=a.useCallback(e=>{b(s=>s===e?null:e)},[]),v=a.useMemo(()=>z(i),[i]),w=null==(n=null==v?void 0:v.packet)?void 0:n.payloadType,k=(null==v?void 0:v.payloadHex)||"",C=null==(l=null==v?void 0:v.packet)?void 0:l.payload,_=w===u.GRP_TXT,S=w===u.GRP_DATA,P=_&&!s&&(!d||g);if(a.useEffect(()=>{if(x(null),y(!1),s)return;if(!_||!C||C.length<4)return;if(!d)return void y(!0);y(!0);let e=!1;return ae(C).then(s=>{e||(x(s),y(!1))}),()=>{e=!0}},[k,_,d,s]),a.useEffect(()=>{if(p(null),!S||!C||C.length<4)return;if(!d)return;let e=!1;return ne(C).then(s=>{e||p(s)}),()=>{e=!0}},[k,S,d]),!v||0===i.length)return t.jsx("div",{className:"p-4 text-center text-fg-muted",children:t.jsx("p",{className:"text-sm",children:"No raw packet data available"})});const{packet:H}=v;let T=v.decoded;s&&"grp_txt"===v.decoded.type?T=s:o&&"grp_txt"===v.decoded.type?T=o:m&&"grp_data"===v.decoded.type&&(T=m);const B=a.useMemo(()=>function(e,s){switch(e.type){case"advert":return function(e,s){const a=[];let n=0;const l=s.slice(0,64);a.push({id:"payload:publicKey",title:"Public Key",color:"pink",hex:l,startByte:n,endByte:n+31,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:e.publicKey.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Ed25519 public key (32 bytes)"})]})}),n+=32;const r=s.slice(64,72);a.push({id:"payload:timestamp",title:"Timestamp",color:"orange",hex:r,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:r.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.timestamp," (",f(e.timestamp),")"]})]})}),n+=4;const i=s.slice(72,200);a.push({id:"payload:signature",title:"Signature",color:"teal",hex:i,startByte:n,endByte:n+63,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:e.signature.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Ed25519 signature (64 bytes)"})]})}),n+=64;const c=s.slice(200,202);if(a.push({id:"payload:flags",title:"Flags",color:"blue",hex:c,startByte:n,endByte:n,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.flags.toString(16).padStart(2,"0").toUpperCase()]}),t.jsx("p",{className:"text-xs text-fg-primary mt-1",children:e.flagsDescription}),t.jsxs("p",{className:"text-xs text-fg-muted",children:["Node Type: ",e.nodeType]})]})}),n+=1,void 0!==e.latitude){const l=s.slice(2*n,2*n+8);a.push({id:"payload:latitude",title:"Latitude",color:"green",hex:l,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.latitude.toFixed(6),"°"]})]})}),n+=4}if(void 0!==e.longitude){const l=s.slice(2*n,2*n+8);a.push({id:"payload:longitude",title:"Longitude",color:"indigo",hex:l,startByte:n,endByte:n+3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:[e.longitude.toFixed(6),"°"]})]})}),n+=4}if(e.name){const l=s.slice(2*n),r=l.length/2;a.push({id:"payload:name",title:"Name",color:"amber",hex:l,startByte:n,endByte:n+r-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:['"',e.name,'"']})]})})}return a}(e,s);case"ack":return function(e,s){return[{id:"payload:crc",title:"CRC",color:"green",hex:s.slice(0,8),startByte:0,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.crc]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"CRC32 of acknowledged packet"})]})}]}(e,s);case"grp_txt":return function(e,s){const a=[];a.push({id:"payload:channelHash",title:"Channel Hash",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.channelHash]}),e.channelName&&t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:["Channel: ",e.channelName]})]})}),e.macHex&&a.push({id:"payload:mac",title:"MAC",color:"indigo",hex:s.slice(2,6),startByte:1,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.macHex.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Truncated HMAC-SHA256"})]})});const n=s.slice(6);return n&&a.push({id:"payload:ciphertext",title:e.decrypted?"Message":"Ciphertext",color:e.decrypted?"green":"zinc",hex:n,startByte:3,endByte:3+n.length/2-1,decoded:e.decrypted?t.jsxs(t.Fragment,{children:[t.jsxs("p",{className:"text-sm text-fg-primary",children:['"',e.text,'"']}),e.senderName&&t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:["From: ",e.senderName]})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:n.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"AES-128-ECB encrypted"})]})}),a}(e,s);case"grp_data":return function(e,s){const a=[];a.push({id:"payload:channelHash",title:"Channel Hash",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.channelHash]}),e.channelName&&t.jsxs("p",{className:"text-xs text-fg-primary mt-1",children:["Channel: ",e.channelName]})]})}),e.macHex&&a.push({id:"payload:mac",title:"MAC",color:"indigo",hex:s.slice(2,6),startByte:1,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.macHex.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Truncated HMAC-SHA256"})]})});const n=s.slice(6);return n&&a.push({id:"payload:ciphertext",title:e.decrypted?"Decrypted Data":"Encrypted Data",color:e.decrypted?"green":"zinc",hex:n,startByte:3,endByte:3+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:(e.decryptedHex||n).toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.dataLength," bytes",e.decrypted?"":" (AES-128-ECB encrypted)"]})]})}),a}(e,s);case"path":return function(e,s){const a=[];if(a.push({id:"payload:pathLength",title:"Path Length",color:"blue",hex:s.slice(0,2),startByte:0,endByte:0,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",children:e.pathLength}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.pathLength," hop",1!==e.pathLength?"s":""]})]})}),e.path.length>0){const n=s.slice(2,2+2*e.pathLength);a.push({id:"payload:path",title:"Path Hops",color:"amber",hex:n,startByte:1,endByte:e.pathLength,decoded:t.jsx(t.Fragment,{children:t.jsx("div",{className:"flex flex-wrap items-center gap-1",children:e.path.map((e,s)=>t.jsxs("span",{className:"flex items-center gap-1",children:[s>0&&t.jsx(xe,{className:"w-3 h-3 text-fg-muted"}),t.jsx(r,{color:"amber",className:"font-mono",children:e})]},s))})})})}if(null!=e.extraType){const n=1+e.pathLength;a.push({id:"payload:extraType",title:"Extra Type",color:"indigo",hex:s.slice(2*n,2*n+2),startByte:n,endByte:n,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",children:e.extraTypeName??`0x${e.extraType.toString(16).padStart(2,"0")}`}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Bundled payload type"})]})})}if(e.extraData){const n=1+e.pathLength+1,l=s.slice(2*n);l&&a.push({id:"payload:extraData",title:"Extra Data",color:"indigo",hex:l,startByte:n,endByte:n+l.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:l.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[l.length/2," bytes"]})]})})}return a}(e,s);case"trace":return function(e,s){const a=[];a.push({id:"payload:crc",title:"Trace Tag",color:"blue",hex:s.slice(0,8),startByte:0,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.traceTag]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Unique trace request identifier"})]})}),a.push({id:"payload:mac",title:"Auth Code",color:"indigo",hex:s.slice(8,16),startByte:4,endByte:7,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.authCode}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Authentication/verification code"})]})}),a.push({id:"payload:flags",title:"Flags",color:"amber",hex:s.slice(16,18),startByte:8,endByte:8,decoded:t.jsxs(t.Fragment,{children:[t.jsxs(Ve,{size:"standard",copy:!0,children:["0x",e.flags.toString(16).toUpperCase().padStart(2,"0")]}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:0===e.flags?"No flags set":`Flags: ${e.flags.toString(2).padStart(8,"0")}b`})]})});const n=s.slice(18);return n&&a.push({id:"payload:path",title:"Target Path",color:"indigo",hex:n,startByte:9,endByte:9+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"flex flex-wrap items-center gap-1",children:e.pathHashes.map((s,a)=>{const n=e.snrValues[a],l=void 0!==n?Y(n):"zinc";return t.jsxs("span",{className:"flex items-center gap-1",children:[a>0&&t.jsx(xe,{className:"w-3 h-3 text-fg-muted"}),t.jsx(r,{color:"indigo",className:"font-mono",children:s}),void 0!==n&&t.jsxs(r,{color:l,className:"font-mono",children:[n>=0?"+":"",Number.isInteger(n)?n:n.toFixed(1),"dB"]})]},a)})}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[e.pathHashes.length," target ",1===e.pathHashes.length?"hop":"hops",e.snrValues.length>0&&` • ${e.snrValues.length} SNR ${1===e.snrValues.length?"value":"values"} collected`,e.isComplete&&" • ✓ Complete"]})]})}),a}(e,s);case"multipart":return function(e,s){const a=[];a.push({id:"payload:msgId",title:"Message ID",color:"blue",hex:s.slice(0,4),startByte:0,endByte:1,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.messageId.toUpperCase()}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"Unique message identifier"})]})}),a.push({id:"payload:partNum",title:"Part Number",color:"amber",hex:s.slice(4,6),startByte:2,endByte:2,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.partNumber}),t.jsx("p",{className:"text-xs text-fg-muted mt-1",children:"0-indexed part number"})]})}),a.push({id:"payload:totalParts",title:"Total Parts",color:"orange",hex:s.slice(6,8),startByte:3,endByte:3,decoded:t.jsxs(t.Fragment,{children:[t.jsx(Ve,{size:"standard",copy:!0,children:e.totalParts}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:["Part ",e.partNumber+1," of ",e.totalParts]})]})});const n=s.slice(8);return n&&a.push({id:"payload:partData",title:"Part Data",color:"cyan",hex:n,startByte:4,endByte:4+n.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:n.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[n.length/2," bytes"]})]})}),a}(e,s);default:return[{id:"payload:ciphertext",title:"Raw Data",color:"zinc",hex:s,startByte:0,endByte:s.length/2-1,decoded:t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"text-[11px] text-fg-secondary break-all p-2 rounded bg-body/50 font-mono",children:s.toUpperCase()}),t.jsxs("p",{className:"text-xs text-fg-muted mt-1",children:[s.length/2," bytes"]})]})}]}}(T,v.payloadHex),[T,v.payloadHex]),M="payload"===j||vs(j),F=a.useMemo(()=>{const e=[{id:"header",hex:v.headerHex,color:"red"},...v.transportCodesHex?[{id:"transportCodes",hex:v.transportCodesHex,color:"indigo"}]:[],{id:"pathLength",hex:v.pathLengthHex,color:"green"},...v.pathDataHex?[{id:"pathData",hex:v.pathDataHex,color:"amber"}]:[]];return M?[...e,...(s=B,s.map(e=>({id:e.id,hex:e.hex,color:e.color})))]:[...e,{id:"payload",hex:v.payloadHex,color:"cyan"}];var s},[v,M,B]);return t.jsxs("div",{className:"font-mono space-y-2 min-w-0 overflow-hidden",children:[(()=>{switch(T.type){case"advert":return t.jsx(Ls,{advert:T,timestamp:e.timestamp});case"grp_data":return t.jsx(Ds,{decoded:T,timestamp:e.timestamp});case"grp_txt":return t.jsx(zs,{decoded:T,timestamp:e.timestamp,isLoading:P,onDecrypted:x});case"ack":return t.jsx($s,{decoded:T,timestamp:e.timestamp});case"path":return t.jsx(Rs,{decoded:T,timestamp:e.timestamp});case"trace":return t.jsx(As,{decoded:T,timestamp:e.timestamp});case"txt_msg":return t.jsx(Es,{decoded:T,timestamp:e.timestamp});case"multipart":return t.jsx(Us,{decoded:T,timestamp:e.timestamp});case"generic":return H.payloadType===u.REQ||H.payloadType===u.RESPONSE||H.payloadType===u.ANON_REQ?t.jsx(Is,{decoded:T,timestamp:e.timestamp,payloadType:H.payloadType}):null;default:return null}})(),t.jsx(Bs,{rawHex:i,hexSegments:F,selectedSegment:j,onSegmentClick:N}),t.jsx(Qe,{children:t.jsx(Ge.div,{layout:!0,transition:Ss,className:"space-y-2 min-w-0",children:(()=>{var e,s,a,n;const l=[{id:"header",title:"Header",color:"red",startByte:0,endByte:0,hexBytes:`0x${v.headerHex.toUpperCase()}`,condition:!0,content:t.jsxs("table",{className:"w-full text-left",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"type-micro text-fg-muted border-b border-edge-subtle font-sans",children:[t.jsx("th",{className:"py-1 font-medium",children:"Bits"}),t.jsx("th",{className:"py-1 font-medium",children:"Field"}),t.jsx("th",{className:"py-1 font-medium",children:"Value"}),t.jsx("th",{className:"py-1 font-medium",children:"Binary"})]})}),t.jsx("tbody",{children:v.headerFields.map(e=>t.jsx(Ms,{...e},e.bits))})]})},{id:"transportCodes",title:"Transport Codes",color:"indigo",startByte:1,endByte:4,hexBytes:(null==(e=v.transportCodesHex)?void 0:e.toUpperCase())||"",condition:!!v.transportCodesHex,content:t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"text-xs text-fg-muted",children:"Two 16-bit transport codes for encrypted routing"}),t.jsxs("div",{className:"mt-1 text-xs text-fg-secondary",children:["Code 1: 0x",null==(s=v.transportCodesHex)?void 0:s.slice(0,4).toUpperCase()," | Code 2: 0x",null==(a=v.transportCodesHex)?void 0:a.slice(4,8).toUpperCase()]})]})},{id:"pathLength",title:"Path Length",color:"green",startByte:v.transportCodesHex?5:1,endByte:v.transportCodesHex?5:1,hexBytes:`0x${v.pathLengthHex.toUpperCase()}`,condition:!0,content:t.jsxs("p",{className:"text-xs text-fg-muted pt-1",children:[H.pathLen," bytes showing route taken (increases as packet floods)"]})},{id:"pathData",title:"Path Data",color:"amber",startByte:v.transportCodesHex?6:2,endByte:(v.transportCodesHex?5:1)+H.pathLen,hexBytes:(null==(n=v.pathDataHex)?void 0:n.toUpperCase())||"",condition:H.pathLen>0,content:t.jsxs("div",{className:"space-y-3",children:[t.jsx(Vs,{pathHex:v.pathDataHex}),t.jsx("p",{className:"text-xs text-fg-muted",children:"Historical route taken (bytes are added as packet floods through network)"})]})},{id:"payload",title:"Payload",color:"cyan",startByte:v.payloadStartByte,endByte:c-1,hexBytes:v.payloadHex.toUpperCase(),condition:!0,content:t.jsxs(t.Fragment,{children:[!vs(j)&&t.jsxs("div",{className:"p-3 rounded-lg bg-black",children:[t.jsx("p",{className:"type-micro text-fg-muted mb-1.5 font-sans",children:"Decoded"}),t.jsx(Qs,{decoded:T,payloadType:H.payloadType})]}),!vs(j)&&B.length>0&&t.jsx("p",{className:"type-micro text-fg-muted mt-3 font-sans",children:"Click a field below to highlight its bytes"}),vs(j)&&t.jsx("p",{className:"type-micro text-fg-muted font-sans",children:"↑ Selected field above • Other fields below ↓"})]})}].filter(e=>e.condition),i=vs(j)?B.find(e=>e.id===j):null,d=vs(j)?[...l].sort((e,s)=>"payload"===e.id?-1:"payload"===s.id?1:0):[...l].sort((e,s)=>e.id===j?-1:s.id===j?1:0),o=vs(j)?B.filter(e=>e.id!==j):[];return t.jsxs(t.Fragment,{children:[i&&t.jsx(Fs,{id:`subfield-${i.id}`,title:i.title,color:i.color,startByte:v.payloadStartByte+i.startByte,endByte:v.payloadStartByte+i.endByte,hexBytes:i.hex.toUpperCase(),isSelected:!0,children:i.decoded},i.id),d.map(e=>t.jsx(Fs,{id:`section-${e.id}`,title:e.title,color:e.color,startByte:e.startByte,endByte:e.endByte,hexBytes:e.hexBytes,isSelected:e.id===j,children:e.content},e.id)),o.map(e=>t.jsxs(Ge.div,{layout:"position",layoutId:`subfield-${e.id}`,transition:Ss,className:"w-full min-w-0 overflow-hidden rounded-xl p-4 sm:p-5 space-y-4",style:{backgroundColor:ks,boxShadow:Cs},children:[t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 min-w-0",children:[t.jsx(r,{color:e.color,children:e.title}),e.hex.length<=32&&Ns(e.hex).map((s,a)=>t.jsx(r,{color:e.color,className:"font-mono",children:s.toUpperCase()},a))]}),t.jsxs("span",{className:"type-data-xs text-fg-muted flex-shrink-0",children:["Bytes ",v.payloadStartByte+e.startByte,"-",v.payloadStartByte+e.endByte]})]}),t.jsx("div",{className:"min-w-0 overflow-hidden p-3 rounded-lg bg-black",children:e.decoded})]},e.id))]})})()})})]})});function Os(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function Ws(e){return e?(e.startsWith("0x")?e.slice(2):e).slice(0,2).toUpperCase():""}function qs({hop:s,compact:n=!1,index:l=0,highlightIndex:r=-1,isTrace:i=!1}){var c;const d=l===r,o=Oe();return a.useEffect(()=>{d&&i&&o.start({boxShadow:["0 0 0 0px rgba(113, 156, 223, 0)","0 0 0 2px rgba(113, 156, 223, 0.5)","0 0 0 2px rgba(113, 156, 223, 0.5)","0 0 0 0px rgba(113, 156, 223, 0)"],transition:{duration:.5,times:[0,.2,.7,1],ease:"easeInOut"}})},[d,i,o]),t.jsxs(Ge.div,{className:e("flex items-center gap-1.5",n?"flex-row":"flex-col"),animate:{scale:d?1.05:1,opacity:d?1:.85},transition:{duration:.3,ease:"easeInOut"},children:[t.jsxs(Ge.div,{className:e("flex items-center gap-1.5 px-2.5 py-1 rounded-md","font-mono text-xs font-semibold",s.isLocal?"bg-sys-amber/20 text-sys-amber ring-1 ring-sys-amber/30":"bg-elevated/50 text-fg-primary ring-1 ring-edge-strong/50"),animate:o,initial:{boxShadow:"0 0 0 0px rgba(113, 156, 223, 0)"},children:[s.isLocal&&t.jsx(Be,{className:"w-3 h-3"}),t.jsx("span",{children:s.prefix}),void 0!==s.confidence&&s.confidence<.9&&t.jsxs("span",{className:"text-[9px] opacity-70",children:[(100*s.confidence).toFixed(0),"%"]})]}),!n&&(null==(c=s.neighborInfo)?void 0:c.name)&&t.jsx("span",{className:"text-xs text-fg-muted truncate max-w-[80px]",children:s.neighborInfo.name})]})}function Ks({snr:e,sf:s}){const a=v(e,s),n=N()[a]||"#6b7280",l=Number.isInteger(e)?e.toString():e.toFixed(1);return t.jsxs(r,{customColor:n,compact:!0,className:"font-mono",children:[e>=0?"+":"",l,"dB"]})}function Xs({hops:s,compact:n,isTrace:l=!1,sf:r}){const[i,c]=a.useState(-1);return a.useEffect(()=>{if(0===s.length)return;const e=setTimeout(()=>{c(0)},400),t=setInterval(()=>{c(e=>{const a=e+1;return a>=s.length?(clearInterval(t),-1):a})},l?500:600);return()=>{clearTimeout(e),clearInterval(t)}},[s.length,l]),t.jsx("div",{className:"p-6",style:{display:"grid",gridTemplateColumns:"1fr auto 1fr",gap:"4px 8px"},children:s.map((a,c)=>{const d=c%2==0,o=c===s.length-1;return t.jsxs("div",{className:"contents",children:[t.jsx("div",{className:e("flex items-center","justify-end"),children:d&&t.jsx(qs,{hop:a,compact:n,index:c,highlightIndex:i,isTrace:l})}),t.jsx("div",{className:"flex flex-col items-center justify-center min-h-[28px]",children:!o&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px flex-1 bg-border-strong/40 min-h-[8px]"}),void 0!==a.snr&&t.jsx(Ks,{snr:a.snr,sf:r}),t.jsx("svg",{className:"w-3 h-3 text-fg-muted flex-shrink-0",viewBox:"0 0 12 12",fill:"none",children:t.jsx("path",{d:"M6 2v8M3 7l3 3 3-3",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]})}),t.jsx("div",{className:e("flex items-center","justify-start"),children:!d&&t.jsx(qs,{hop:a,compact:n,index:c,highlightIndex:i,isTrace:l})})]},`${a.prefix}-${c}`)})})}const Ys=a.memo(function({packet:s,neighbors:n,localHash:l,neighborAffinity:r,ghostPrefixes:i,direction:c="horizontal",compact:d=!1,traceSnr:o,overridePath:x}){const m=void 0!==o&&o.length>0,p=b(),h=Os(s.original_path),u=Os(s.forwarded_path),g=x??(u.length>0?u:h),f=Ws(l),y=a.useMemo(()=>g.map((e,s)=>{const t=e.toUpperCase(),a=t===f,l=(null==i?void 0:i.has(t))??!1,c=function(e,s,t){const a=e.toUpperCase();if(t){let e=null,n=0;if(t.forEach((s,t)=>{if(Ws(t)===a){const a=s.combinedScore??0;a>n&&(n=a,e=t)}}),e&&s[e])return{hash:e,info:s[e],confidence:n}}for(const[n,l]of Object.entries(s))if(Ws(n)===a)return{hash:n,info:l,confidence:void 0};return null}(t,n,r);return{prefix:t,fullHash:null==c?void 0:c.hash,neighborInfo:null==c?void 0:c.info,isLocal:a,isGhost:l,confidence:null==c?void 0:c.confidence,snr:null==o?void 0:o[s]}}),[g,n,r,f,i,o]);if(0===y.length)return t.jsxs("div",{className:"flex items-center gap-2 text-fg-muted text-xs",children:[t.jsx(he,{className:"w-4 h-4 opacity-50"}),t.jsx("span",{children:"Direct / No path data"})]});if("flowchart"===c)return t.jsx(Xs,{hops:y,compact:d,isTrace:m,sf:p});const j="horizontal"===c?xe:me;return t.jsx("div",{className:e("flex gap-1.5","horizontal"===c?"flex-row flex-wrap items-center":"flex-col items-start"),children:y.map((s,a)=>t.jsxs("div",{className:e("flex items-center gap-1.5","vertical"===c&&"flex-col"),children:[t.jsx(qs,{hop:s,compact:d}),a"blue",et=[{fn:"id",group:"identity",fmt:"int",read:e=>Js(e.id),color:Zs},{fn:"packet_hash",group:"identity",fmt:"hex",read:e=>e.packet_hash||void 0,color:Zs},{fn:"timestamp",group:"identity",fmt:"epoch",read:e=>e.timestamp?String(e.timestamp):void 0,color:Zs,annotate:e=>e.timestamp>0?w(e.timestamp):void 0},{fn:"type",group:"classification",fmt:"enum",read:e=>Js(e.type??e.payload_type),color:Zs},{fn:"route",group:"classification",fmt:"enum",read:e=>Js(e.route??e.route_type),color:Zs},{fn:"rssi",group:"signal",fmt:"int",read:e=>Js(e.rssi,"dBm"),color:Zs},{fn:"snr",group:"signal",fmt:"float",read:e=>Js(e.snr,"dB"),color:Zs},{fn:"path_length",group:"size",fmt:"int",read:e=>{if(null!=e.path_length)return 0===e.path_length?"zero-hop":`${e.path_length} hops`},color:Zs},{fn:"payload_length",group:"size",fmt:"int",read:e=>Js(e.payload_length,"B"),color:Zs},{fn:"airtime",group:"size",fmt:"float",read:e=>Js(e.airtime_ms,"ms"),color:Zs},{fn:"src_hash",group:"addressing",fmt:"hex<2>",read:e=>e.src_hash??void 0,color:Zs},{fn:"dst_hash",group:"addressing",fmt:"hex<2>",read:e=>e.dst_hash??void 0,color:Zs},{fn:"path_hash",group:"addressing",fmt:"hex[]|hex",read:e=>Array.isArray(e.path_hash)?`[${e.path_hash.join(", ")}]`:Js(e.path_hash),color:Zs,renderValue:e=>Array.isArray(e.path_hash)?st(e.path_hash):null},{fn:"score",group:"addressing",fmt:"int",read:e=>Js(e.score),color:Zs},{fn:"original_path",group:"paths",fmt:"hex[]",read:e=>Array.isArray(e.original_path)?`[${e.original_path.join(", ")}]`:void 0,color:Zs,renderValue:e=>Array.isArray(e.original_path)&&e.original_path.length>0?st(e.original_path,e.src_hash||void 0,e.dst_hash||void 0,!0):null},{fn:"forwarded_path",group:"paths",fmt:"hex[]",read:e=>Array.isArray(e.forwarded_path)?`[${e.forwarded_path.join(", ")}]`:void 0,color:Zs,renderValue:e=>Array.isArray(e.forwarded_path)&&e.forwarded_path.length>0?st(e.forwarded_path):null},{fn:"transmitted",group:"status",fmt:"bool",read:e=>Js(e.transmitted),color:Zs},{fn:"is_duplicate",group:"status",fmt:"bool",read:e=>Js(e.is_duplicate),color:Zs},{fn:"drop_reason",group:"status",fmt:"string|null",read:e=>e.drop_reason??void 0,color:Zs},{fn:"tx_delay",group:"status",fmt:"int",read:e=>Js(e.tx_delay_ms,"ms"),color:Zs},{fn:"origin",group:"status",fmt:"enum",read:e=>e.packet_origin??void 0,color:Zs},{fn:"duplicates",group:"status",fmt:"PacketDuplicate[]",read:e=>null!=e.duplicates&&e.duplicates.length>0?`${e.duplicates.length}`:Js(e.duplicates),color:Zs},{fn:"lbt_attempts",group:"lbt",fmt:"int",read:e=>Js(e.lbt_attempts),color:Zs},{fn:"lbt_backoff",group:"lbt",fmt:"json",read:e=>Js(e.lbt_backoff_delays_ms),color:Zs},{fn:"lbt_busy",group:"lbt",fmt:"bool|int",read:e=>Js(e.lbt_channel_busy),color:Zs}];function st(e,s,n,l){const r=e.length>0,i=s||l,c=n||l;return t.jsxs("span",{className:"inline-flex items-center gap-1 flex-wrap",children:[i&&t.jsxs(t.Fragment,{children:[s?t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:s}):t.jsx("span",{className:"inline-block border border-edge-subtle/50 rounded px-1.5 py-0.5 font-mono text-[11px] text-fg-muted/30",children:"XX"}),(r||c)&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"})]}),e.map((e,s)=>t.jsxs(a.Fragment,{children:[s>0&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:e})]},s)),c&&t.jsxs(t.Fragment,{children:[r&&t.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),n?t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] text-sys-blue",children:n}):t.jsx("span",{className:"inline-block border border-edge-subtle/50 rounded px-1.5 py-0.5 font-mono text-[11px] text-fg-muted/30",children:"XX"})]})]})}let tt=null;function at(e,s){var t;const a=function(){if(!tt){tt=new Map;for(const e of et)tt.set(e.fn,e)}return tt}().get(s);if(!a)return null;const n=a.read(e);if(void 0===n)return null;const l=a.color(e),r=null==(t=a.annotate)?void 0:t.call(a,e);return r?{text:n,color:l,annotation:r}:{text:n,color:l}}function nt(e){if(!e)return[];if(Array.isArray(e))return e;try{const s=JSON.parse(e);return Array.isArray(s)?s:[]}catch{return[]}}function lt({packets:s,selectedIndex:a,onSelect:n,compact:l=!1}){if(s.length<=1)return null;const r=a>0,i=ar&&n(a-1),disabled:!r,className:e("p-0.5 radius-badge transition-base",r?"text-fg-muted hover:text-fg-primary hover-bg":"text-fg-muted cursor-not-allowed"),"aria-label":"Previous observation",children:t.jsx(Le,{className:l?"size-3":"size-4"})}),t.jsx("div",{className:"flex items-center gap-0.5",children:s.map((s,r)=>{const i=r===a,c=new Date(1e3*s.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});return t.jsx(F,{color:i?"cyan":"zinc",filled:i,compact:l,onClick:()=>n(r),title:`Observation ${r+1} at ${c}`,className:e("transition-all duration-150",!i&&"opacity-60 hover:opacity-100"),children:l?t.jsx("span",{className:"tabular-nums",children:r+1}):t.jsxs("span",{className:"tabular-nums text-xs",children:["#",r+1,null!=s.rssi&&t.jsx("span",{className:"ml-1 opacity-70",children:s.rssi})]})},`${s.timestamp}_${r}`)})}),t.jsx("button",{onClick:()=>i&&n(a+1),disabled:!i,className:e("p-0.5 radius-badge transition-base",i?"text-fg-muted hover:text-fg-primary hover-bg":"text-fg-muted cursor-not-allowed"),"aria-label":"Next observation",children:t.jsx(pe,{className:l?"size-3":"size-4"})}),t.jsxs("span",{className:e("text-fg-muted ml-1",l?"text-[9px]":"text-xs"),children:[t.jsx(oe,{className:"inline size-3 mr-0.5 opacity-50"}),s.length]})]})}function rt({icon:s,label:a,disabled:n=!1}){return t.jsx(Ge.div,{className:"flex items-center gap-1 text-xs",title:a,animate:{opacity:n?.25:.6},transition:{duration:.15,ease:[.4,0,.2,1]},children:t.jsx("span",{className:e("flex items-center justify-center size-5 radius-badge border-control transition-base",n?"bg-subtle-fill border-edge-subtle":"bg-subtle-fill"),children:s})})}function it({hasDuplicates:e,hasPrev:s,hasNext:a,canPrevDupe:n,canNextDupe:l}){return t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsxs("div",{className:"flex items-center gap-0.5",children:[t.jsx(rt,{icon:t.jsx(De,{className:"size-3"}),label:"Previous packet (↑)",disabled:!s}),t.jsx(rt,{icon:t.jsx(ze,{className:"size-3"}),label:"Next packet (↓)",disabled:!a})]}),e&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px h-3 bg-subtle-fill-strong"}),t.jsxs("div",{className:"flex items-center gap-0.5",children:[t.jsx(rt,{icon:t.jsx(Le,{className:"size-3"}),label:"Previous observation (←)",disabled:!n}),t.jsx(rt,{icon:t.jsx(pe,{className:"size-3"}),label:"Next observation (→)",disabled:!l})]})]})]})}const ct=a.memo(function({packets:e,initialIndex:s=0,onClose:n,onNavigatePrev:l,onNavigateNext:i,hasPrev:c=!1,hasNext:m=!1,resolveSource:p}){var h;const[g,f]=a.useState(s),y=e[g]??e[0],j=e.length>1,[b,N]=a.useState(null),[v,w]=a.useState(!1);a.useEffect(()=>{if(!y._stripped)return void N(null);let e=!1;w(!0);const s=y.packet_hash;if(s)return k(s).then(s=>{e||(s.success&&s.data&&(N(s.data),(s.data.type??s.data.payload_type)===u.GRP_TXT&&s.data.raw_packet&&C.getState().queueDecryption([s.data])),w(!1))}).catch(()=>{e||w(!1)}),()=>{e=!0};w(!1)},[y]);const F=b??y,L=g>0,D=g{f(Math.max(0,Math.min(s,e.length-1)))},[e.length]);a.useEffect(()=>{const e=e=>{if(!(e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement))switch(e.key){case"ArrowUp":e.preventDefault(),null==l||l();break;case"ArrowDown":e.preventDefault(),null==i||i();break;case"ArrowLeft":e.preventDefault(),L&&f(e=>e-1);break;case"ArrowRight":e.preventDefault(),D&&f(e=>e+1)}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[l,i,L,D]);const R=_(),A=S(),E=P(),U=H(),I=a.useMemo(()=>new Set(U.map(e=>e.prefix.toUpperCase())),[U]),V=F.payload_type_name||d(F.payload_type??F.type),Q=F.route_type_name||o(F.route_type??F.route),G=F.payload_length??F.length??0,O=nt(F.original_path),W=nt(F.forwarded_path),q=O.length>0||W.length>0,Y=W.length>0?W:O,J=a.useMemo(()=>{var e;if(null==(e=null==R?void 0:R.config)?void 0:e.repeater)return{latitude:R.config.repeater.latitude,longitude:R.config.repeater.longitude,name:R.config.node_name||"Local Node"}},[R]),Z=(null==R?void 0:R.neighbors)??{},ee=E.size>0?E:void 0,se=F.raw_packet&&F.raw_packet.length>0,te=y._stripped&&v,ae=a.useMemo(()=>p?p(F):null,[p,F]),ne=T(F.packet_hash),ce=a.useMemo(()=>{if((F.payload_type??F.type)!==u.GRP_TXT)return null;if(!(null==ne?void 0:ne.decoded))return null;const e=ne.decoded;return{type:"grp_txt",channelHash:e.channelHash,channelName:e.channelName,text:e.text??"",decrypted:e.decrypted,senderName:e.senderName,timestamp:e.timestamp,flags:e.flags,macCorrupted:e.macCorrupted}},[F,ne]),de=a.useMemo(()=>$(F,ce),[F,ce]),oe="trace"===de.kind?de.data:null,xe="trace"===de.kind?de.snrValues:void 0,me="advert"===de.kind?de.data:null,pe="advert"===de.kind?de.sourceNode:void 0,ue="grp_txt"===de.kind?de.wardriveSourceNode??void 0:void 0,fe=e=>e&&0!==e?new Date(1e3*e).toLocaleString():"Unknown",ye=(F.payload_type??F.type)===u.ADVERT&&(void 0!==pe||q),je=void 0!==ue,be=pe??ue,Ne=X[V]??"zinc",we=x[Ne]||x.zinc;return t.jsxs(B,{open:!0,onClose:n,size:"5xl",motionPlus:!0,className:"sm:h-[85vh] sm:max-h-[800px] md:h-[80vh] md:max-h-[900px]",children:[t.jsxs("div",{className:"sm:hidden",children:[t.jsx("div",{className:"flex justify-center pt-2 pb-1",children:t.jsx("div",{className:"w-9 h-1 rounded-full bg-fg-muted","aria-hidden":"true"})}),t.jsxs("div",{className:"flex items-center justify-between px-3 pb-2",children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:X[V]??"zinc",className:"!text-[9px] !px-1.5 !py-0",children:V}),t.jsx(r,{color:K[Q]??"zinc",className:"!text-[9px] !px-1.5 !py-0",children:Q}),t.jsxs(r,{color:"zinc",className:"!text-[9px] !px-1.5 !py-0",children:[G,"B"]})]}),t.jsx("button",{onClick:n,className:"px-3 py-1.5 text-[15px] font-medium text-sys-blue active:text-sys-blue/80 transition-base flex-shrink-0 radius-inner active:bg-subtle-fill",children:"Done"})]}),j&&t.jsx("div",{className:"px-3 pb-2",children:t.jsx(lt,{packets:e,selectedIndex:g,onSelect:z,compact:!0})})]}),t.jsx("div",{className:"hidden sm:block px-6 pt-5 pb-4",children:t.jsxs("div",{className:"flex items-center justify-between gap-3",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(r,{color:X[V]??"zinc",children:V}),t.jsx(r,{color:K[Q]??"zinc",children:Q}),t.jsxs(r,{color:"zinc",children:[G,"B"]}),j&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"w-px h-4 bg-subtle-fill-strong"}),t.jsx(lt,{packets:e,selectedIndex:g,onSelect:z})]})]}),t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(it,{hasDuplicates:j,hasPrev:c,hasNext:m,canPrevDupe:L,canNextDupe:D}),t.jsx("button",{onClick:n,className:"p-1.5 -m-1.5 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-elevated flex-shrink-0",children:t.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}),t.jsx("div",{className:"sm:hidden h-[2px]",style:{backgroundColor:we,opacity:.6}}),t.jsxs(M,{className:"p-0 overflow-hidden flex-1 flex flex-col min-h-0",children:[t.jsx("div",{className:"md:hidden flex-1 overflow-y-auto overflow-x-hidden",children:t.jsxs("div",{className:"p-2 space-y-2",children:[(null!=F.rssi||null!=F.snr)&&t.jsxs("div",{className:"relative flex items-center justify-between px-2 py-1.5 radius-inner bg-subtle-fill",children:[t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.div,{className:"flex items-center gap-3",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[t.jsx(le,{rssi:F.rssi,snr:F.snr,compact:!0,showValues:!0,validated:re(F)}),t.jsx("span",{className:"text-[11px] text-fg-muted",children:ie(F.rssi)})]},g)}),Y.length>0&&t.jsxs("span",{className:"type-data-xs text-fg-muted",children:[Y.length," hop",1!==Y.length?"s":""]})]}),(q&&Y.length>0||ye||je)&&t.jsx("div",{className:"overflow-hidden radius-inset",children:t.jsx("div",{className:"aspect-[4/3] w-full",children:t.jsx(bs,{path:Y,neighbors:Z,localNode:J,localHash:null==R?void 0:R.local_hash,srcHash:F.src_hash,dstHash:F.dst_hash,neighborAffinity:ee,hubNodes:[...A],traceSnr:xe,advertiserSource:be})})}),oe&&oe.pathHashes.length>0&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsx("div",{className:"px-3 py-2 space-y-1.5",children:t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsx("div",{className:"flex items-center gap-1.5",children:t.jsx(r,{color:oe.isComplete?"green":"amber",compact:!0,children:oe.isComplete?"Complete":"In Progress"})})]})}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,overridePath:oe.pathHashes,traceSnr:oe.snrValues})]}),q&&!oe&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Path"}),t.jsxs(r,{color:"zinc",compact:!0,children:[Y.length," hop",1!==Y.length?"s":""]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,traceSnr:xe})]}),ae&&(ae.name||ae.hash)&&!me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Source"}),t.jsx(r,{color:ae.isRepeater?"blue":ae.isCompanion?"violet":"room_server"===ae.type?"lime":"zinc",compact:!0,children:"room_server"===ae.type?"room server":ae.type})]}),t.jsxs("div",{className:"p-3 space-y-1.5",children:[ae.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:ae.name}),!ae.confident&&t.jsx("span",{className:"text-[9px] text-fg-muted/60 italic",children:"ambiguous"})]}),ae.hash&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-muted truncate font-mono",children:[ae.hash.startsWith("0x")?ae.hash.slice(2,10):ae.hash.slice(0,8),"…"]})]})]})]}),me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Advertiser Info"}),t.jsx(r,{color:"lime",compact:!0,children:me.nodeType})]}),t.jsxs("div",{className:"p-3 space-y-2",children:[me.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:me.name})]}),me.latitude&&me.longitude&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ge,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-secondary",children:[me.latitude.toFixed(5),", ",me.longitude.toFixed(5)]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-muted truncate",children:[me.publicKey.slice(0,16),"...",me.publicKey.slice(-8)]})]}),me.timestamp>0&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ve,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:fe(me.timestamp)})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(he,{className:"w-3.5 h-3.5 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:me.flagsDescription||`Flags: 0x${me.flags.toString(16).padStart(2,"0")}`})]})]})]}),te?t.jsx("div",{className:"pt-1 px-3 py-6 text-center",children:t.jsx("span",{className:"text-xs text-fg-muted animate-pulse",children:"Loading packet details…"})}):se?t.jsx("div",{className:"pt-1",children:t.jsx(Gs,{packet:F,decodedGrpTxt:ce})}):null]})}),t.jsxs("div",{className:"hidden md:grid md:grid-cols-2 flex-1 overflow-hidden",children:[t.jsx("div",{className:"overflow-y-auto overflow-x-hidden scrollbar-none p-4 border-r border-edge-subtle",children:te?t.jsx("div",{className:"flex items-center justify-center h-full",children:t.jsx("span",{className:"text-sm text-fg-muted animate-pulse",children:"Loading packet details…"})}):se?t.jsx(Gs,{packet:F,decodedGrpTxt:ce}):null}),t.jsxs("div",{className:"grid overflow-hidden",style:{gridTemplateRows:"minmax(280px, 1fr) auto"},children:[t.jsx("div",{className:"overflow-hidden p-2",children:q&&Y.length>0||ye||je?t.jsx("div",{className:"h-full w-full",children:t.jsx(bs,{path:Y,neighbors:Z,localNode:J,localHash:null==R?void 0:R.local_hash,srcHash:F.src_hash,dstHash:F.dst_hash,neighborAffinity:ee,hubNodes:[...A],traceSnr:xe,advertiserSource:be})}):t.jsxs("div",{className:"h-full w-full flex flex-col items-center justify-center text-center px-4",children:[t.jsx(he,{className:"w-8 h-8 text-fg-muted/50 mb-2"}),t.jsx("span",{className:"text-sm text-fg-muted",children:"Direct Reception"}),t.jsx("span",{className:"text-xs text-fg-muted/70 mt-1",children:"Zero-hop packet — received directly from sender"})]})}),t.jsxs("div",{className:"overflow-y-auto max-h-[200px] p-2 space-y-2",children:[!oe&&Y.length<=1&&(null!=F.rssi||null!=F.snr)&&t.jsx("div",{className:"surface-base radius-inset p-4",children:t.jsxs("dl",{className:"text-xs grid grid-cols-2 gap-2",children:[t.jsxs("div",{children:[t.jsx("dt",{className:"text-fg-muted mb-1",children:"Signal"}),t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.dd,{className:"flex items-center gap-2",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[t.jsx(le,{rssi:F.rssi,snr:F.snr,validated:re(F)}),t.jsx("span",{className:"font-medium text-fg-primary",children:ie(F.rssi)})]},g)})]}),t.jsxs("div",{children:[t.jsx("dt",{className:"text-fg-muted mb-1",children:"RF"}),t.jsx(We,{mode:"popLayout",initial:!1,children:t.jsxs(Ge.dd,{className:"type-data text-fg-secondary",initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:.15,ease:[.4,0,.2,1]},children:[null==(h=at(F,"rssi"))?void 0:h.text,(()=>{const e=at(F,"snr");return e?` · ${e.text}`:null})()]},g)})]})]})}),ae&&(ae.name||ae.hash)&&!me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Source"}),t.jsx(r,{color:ae.isRepeater?"blue":ae.isCompanion?"violet":"room_server"===ae.type?"lime":"zinc",compact:!0,children:"room_server"===ae.type?"room server":ae.type})]}),t.jsxs("div",{className:"p-4 space-y-2",children:[ae.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:ae.name}),!ae.confident&&t.jsx("span",{className:"text-[10px] text-fg-muted/60 italic",children:"ambiguous"})]}),ae.hash&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-muted truncate",children:[ae.hash.startsWith("0x")?ae.hash.slice(2,10):ae.hash.slice(0,8),"…"]})]})]})]}),me&&t.jsxs("div",{className:"radius-inset bg-subtle-fill overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Advertiser"}),t.jsx(r,{color:"lime",compact:!0,children:me.nodeType})]}),t.jsxs("div",{className:"p-4 space-y-2.5",children:[me.name&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Me,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"type-label text-fg-primary truncate",children:me.name})]}),me.latitude&&me.longitude&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ge,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"type-data-xs text-fg-secondary",children:[me.latitude.toFixed(5),", ",me.longitude.toFixed(5)]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(Fe,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-muted truncate",children:[me.publicKey.slice(0,16),"...",me.publicKey.slice(-8)]})]}),me.timestamp>0&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(ve,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-xs text-fg-muted",children:fe(me.timestamp)})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(he,{className:"w-4 h-4 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-[11px] text-fg-muted",children:me.flagsDescription||`Flags: 0x${me.flags.toString(16).padStart(2,"0")}`})]})]})]}),oe&&oe.pathHashes.length>0&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"px-4 py-2 flex items-center justify-between",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:oe.isComplete?"green":"amber",compact:!0,children:oe.isComplete?"Complete":"In Progress"}),t.jsxs(r,{color:"teal",compact:!0,children:[oe.pathHashes.length,"h"]})]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,overridePath:oe.pathHashes,traceSnr:oe.snrValues})]}),q&&!oe&&t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-2",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Path"}),t.jsxs(r,{color:"zinc",compact:!0,children:[Y.length,"h"]})]}),t.jsx(Ys,{packet:F,neighbors:Z,localHash:null==R?void 0:R.local_hash,neighborAffinity:ee,ghostPrefixes:I,direction:"flowchart",compact:!0,traceSnr:xe})]})]})]})]})]})]})});function dt({label:e,numericValue:s,unit:a,icon:n,subtext:l,showSign:r=!1}){return t.jsxs("div",{className:"radius-inner p-3 sm:radius-inset sm:p-4 bg-subtle-fill ring-1 ring-inset ring-edge-subtle",children:[t.jsx("div",{className:"mb-1.5 sm:mb-2",children:t.jsx("span",{className:"text-xs sm:type-micro text-fg-muted",children:e})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(qe,{value:s,format:{minimumFractionDigits:1,maximumFractionDigits:1,signDisplay:r?"always":"auto"},className:"type-data-hero tracking-tight text-fg-primary"}),t.jsxs("div",{className:"flex flex-col items-center justify-center",children:[t.jsx(n,{className:"w-[14px] h-[14px] text-fg-muted"}),a&&t.jsx("span",{className:"text-xs font-medium leading-tight text-fg-muted",children:a})]})]}),l&&t.jsx("p",{className:"mt-1.5 sm:mt-2 type-data-xs sm:text-[11px] text-fg-muted/80 truncate",children:l})]})}function ot({snr:s}){const a=s>=5?"bg-sys-teal":s>=0?"bg-sys-green":s>=-5?"bg-sys-amber":s>=-10?"bg-sys-orange":"bg-sys-red";return t.jsx("span",{className:e("w-1.5 h-1.5 rounded-full flex-shrink-0",a),title:`SNR: ${s.toFixed(1)} dB`})}function xt({fromPrefix:s,toPrefix:a,fromName:n,toName:l,snr:i,maxSnr:c,isWeakest:d,isStrongest:o,index:x=0}){const m=Math.max(c+5,15),p=Math.max(0,Math.min(100,(i- -20)/(m- -20)*100)),h="bg-[#0074BE]",u=i>=5?"bg-sys-teal":i>=0?"bg-sys-green":i>=-5?"bg-sys-amber":i>=-10?"bg-sys-orange":"bg-sys-red",g=.3+.15*x;return t.jsxs("div",{className:"relative p-3 pl-5 radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle",children:[t.jsx("span",{className:e("absolute left-0 top-1/2 -translate-y-1/2 h-4 w-0.5 rounded-full",u)}),t.jsx("span",{className:"absolute -top-0.5 -right-0.5",children:t.jsx(ot,{snr:i})}),t.jsxs("div",{className:"sm:hidden",children:[t.jsxs("div",{className:"flex items-center justify-between mb-1",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[t.jsx("span",{className:"text-[13px] font-medium text-fg-secondary truncate",children:n||s}),t.jsx(xe,{className:"w-3 h-3 text-fg-muted flex-shrink-0"}),t.jsx("span",{className:"text-[13px] font-semibold text-fg-primary truncate",children:l||a})]}),t.jsxs("div",{className:"flex items-center gap-1.5 ml-2 flex-shrink-0",children:[d&&t.jsx(r,{color:"red",compact:!0,children:"Low"}),o&&!d&&t.jsxs(r,{color:"amber",compact:!0,children:[t.jsx(Ae,{className:"w-2.5 h-2.5"}),"Best"]}),t.jsxs("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-[12px] font-mono font-bold tabular-nums bg-subtle-fill-hover text-fg-primary ring-1 ring-inset ring-edge-subtle",children:[i>=0?"+":"−",Math.abs(i).toFixed(1)]})]})]}),t.jsx("div",{className:"h-1.5 bg-subtle-fill-strong rounded-full overflow-hidden",children:t.jsx(Ge.div,{className:e("h-full rounded-full",h),initial:{width:0},animate:{width:`${p}%`},transition:{duration:1.5,delay:g,ease:[.25,.1,.25,1]}})})]}),t.jsxs("div",{className:"hidden sm:block",children:[t.jsxs("div",{className:"flex items-center justify-between mb-2",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx("code",{className:"type-data-xs text-fg-muted",children:s}),n&&t.jsx("span",{className:"text-xs text-fg-secondary truncate max-w-[100px]",children:n})]}),t.jsx(xe,{className:"w-3 h-3 text-fg-muted/40 flex-shrink-0"}),t.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[t.jsx("code",{className:"font-mono text-xs font-semibold text-fg-primary",children:a}),l&&t.jsx("span",{className:"text-xs text-fg-secondary truncate max-w-[100px]",children:l})]})]}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[d&&t.jsx(r,{color:"red",compact:!0,children:"Bottleneck"}),o&&!d&&t.jsxs(r,{color:"amber",compact:!0,children:[t.jsx(Ae,{className:"w-3 h-3"}),"Strongest"]}),t.jsxs("span",{className:"inline-flex items-center px-2 py-0.5 rounded text-sm font-mono font-semibold tabular-nums bg-subtle-fill-hover text-fg-primary ring-1 ring-inset ring-edge-subtle",children:[i>=0?"+":"−",Math.abs(i).toFixed(1)]})]})]}),t.jsx("div",{className:"h-1.5 bg-elevated rounded-full overflow-hidden",children:t.jsx(Ge.div,{className:e("h-full rounded-full",h),initial:{width:0},animate:{width:`${p}%`},transition:{duration:1.5,delay:g,ease:[.25,.1,.25,1]}})})]})]})}function mt(e,s){if("You"===e)return"You";const t=e.toUpperCase();for(const[a,n]of Object.entries(s))if((a.startsWith("0x")?a.slice(2,4):a.slice(0,2)).toUpperCase()===t)return n.name||n.node_name||void 0}const pt=a.memo(function({report:e,onClose:s}){var a,n;const l=_(),i=(null==l?void 0:l.neighbors)??{},c=(null==(a=null==l?void 0:l.config)?void 0:a.repeater)?{latitude:l.config.repeater.latitude,longitude:l.config.repeater.longitude,name:l.config.node_name||"Local Node"}:void 0,d=null==(n=e.bestObservation)?void 0:n.decoded.snrValues,o=e.linkQuality?e.linkQuality.avgSnr>=5?"excellent":e.linkQuality.avgSnr>=0?"good":e.linkQuality.avgSnr>=-5?"fair":"poor":"unknown",x={excellent:"var(--signal-excellent)",good:"var(--signal-good)",fair:"var(--signal-fair)",poor:"var(--signal-poor)",unknown:"var(--fg-muted)"}[o];return t.jsxs(B,{open:!0,onClose:s,size:"5xl",motionPlus:!0,children:[t.jsxs("div",{className:"sm:hidden",children:[t.jsx("div",{className:"flex justify-center pt-2 pb-1",children:t.jsx("div",{className:"w-9 h-1 rounded-full bg-fg-primary/30","aria-hidden":"true"})}),t.jsxs("div",{className:"flex items-center justify-between px-4 pb-2",children:[t.jsx("h2",{className:"font-semibold text-[17px] text-fg-primary",children:"Trace Report"}),t.jsx("button",{onClick:s,className:"text-[17px] font-medium text-sys-blue active:text-sys-blue/80",children:"Done"})]})]}),t.jsx("div",{className:"sm:hidden h-[2px]",style:{backgroundColor:x,opacity:.6}}),t.jsx("div",{className:"hidden sm:block px-6 pt-5 pb-4",children:t.jsxs("div",{className:"flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-2 sm:gap-3",children:[t.jsx("h2",{className:"type-micro",children:"Trace Report"}),t.jsxs(r,{color:"excellent"===o||"good"===o?"green":"fair"===o?"amber":"red",children:[t.jsx($e,{className:"w-3 h-3 mr-1"}),"excellent"===o?"Excellent":"good"===o?"Good":"fair"===o?"Fair":"Poor"]})]}),t.jsx("p",{className:"mt-1 text-xs sm:text-sm font-mono text-fg-muted tabular-nums",children:e.traceTag})]}),t.jsx("button",{onClick:s,className:"p-1.5 -m-1.5 text-fg-muted hover:text-fg-primary transition-base radius-inner hover:bg-elevated flex-shrink-0",children:t.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})}),t.jsxs("div",{className:"hidden sm:flex flex-wrap items-center gap-1.5 sm:gap-2 px-4 sm:px-6 pb-3 sm:pb-4 border-b border-edge-subtle",children:[t.jsxs(r,{color:"teal",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.targetHopCount}),t.jsxs("span",{className:"ml-1",children:["hop",1!==e.targetHopCount?"s":""]})]}),t.jsxs(r,{color:"zinc",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.observationCount}),t.jsx("span",{className:"ml-1",children:"obs"})]}),e.linkQuality&&t.jsxs(r,{color:"indigo",children:[t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.avgSnr.toFixed(1)}),t.jsx("span",{className:"ml-1",children:"dB avg"})]}),t.jsx("span",{className:"type-data-xs text-fg-muted",children:L(e.duration)}),e.linkQuality&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"text-fg-muted/40",children:"•"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium bg-sys-red/15 text-sys-red ring-1 ring-inset ring-sys-red/25",children:[t.jsx("span",{className:"opacity-70",children:"Min"}),t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.minSnr.toFixed(1)})]}),t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium bg-sys-teal/15 text-sys-teal ring-1 ring-inset ring-sys-teal/25",children:[t.jsx("span",{className:"opacity-70",children:"Max"}),t.jsx("span",{className:"font-mono tabular-nums",children:e.linkQuality.maxSnr.toFixed(1)})]})]})]})]}),t.jsxs(M,{className:"p-0 overflow-hidden",children:[t.jsx("div",{className:"md:hidden h-[75vh] max-h-[calc(100vh-80px)] overflow-y-auto overflow-x-hidden",children:t.jsxs("div",{className:"px-4 py-3 space-y-3",children:[e.linkQuality&&t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsxs("div",{className:"radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle p-2.5 text-center",children:[t.jsx(qe,{value:Math.abs(e.linkQuality.minSnr),format:{maximumFractionDigits:0,signDisplay:"never"},prefix:e.linkQuality.minSnr<0?"-":"",className:"text-[20px] font-bold font-mono tabular-nums flex items-center justify-center text-fg-primary"}),t.jsxs("div",{className:"flex items-center justify-center gap-1 mt-1",children:[t.jsx(ye,{className:"w-2.5 h-2.5 text-fg-muted"}),t.jsx("span",{className:"text-xs text-fg-muted",children:"Min dB"})]})]}),t.jsxs("div",{className:"radius-inner bg-subtle-fill ring-1 ring-inset ring-edge-subtle p-2.5 text-center",children:[t.jsx(qe,{value:e.linkQuality.maxSnr,format:{maximumFractionDigits:0,signDisplay:"always"},className:"text-[20px] font-bold font-mono text-fg-primary tabular-nums flex items-center justify-center"}),t.jsxs("div",{className:"flex items-center justify-center gap-1 mt-1",children:[t.jsx(Re,{className:"w-2.5 h-2.5 text-fg-muted"}),t.jsx("span",{className:"text-xs text-fg-muted",children:"Max dB"})]})]})]}),t.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.jsxs(r,{color:"excellent"===o||"good"===o?"green":"fair"===o?"amber":"red",compact:!0,children:[t.jsx($e,{className:"w-2.5 h-2.5 mr-0.5"}),"excellent"===o?"Excellent":"good"===o?"Good":"fair"===o?"Fair":"Poor"]}),t.jsxs(r,{color:"teal",compact:!0,children:[e.targetHopCount," hops"]}),t.jsxs(r,{color:"zinc",compact:!0,children:[e.observationCount," obs"]}),t.jsx("span",{className:"type-data-xs text-fg-muted ml-auto",children:e.traceTag.slice(0,8)})]}),e.targetPath.length>0&&t.jsx("div",{className:"overflow-hidden radius-inset",children:t.jsx("div",{className:"aspect-[4/3] w-full",children:t.jsx(bs,{path:e.targetPath,neighbors:i,localNode:c,localHash:null==l?void 0:l.local_hash,srcHash:e.srcHash,dstHash:e.dstHash,traceSnr:d})})}),t.jsxs("div",{className:"radius-inset bg-body overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b border-edge-subtle",children:[t.jsx("span",{className:"text-[11px] font-medium text-fg-secondary",children:"Route Path"}),e.linkQuality&&t.jsxs("span",{className:"type-data-xs text-fg-muted",children:["SNR ",e.linkQuality.minSnr.toFixed(1)," → ",e.linkQuality.maxSnr.toFixed(1)," dB"]})]}),e.bestObservation?t.jsx(Ys,{packet:e.bestObservation.packet,neighbors:i,localHash:null==l?void 0:l.local_hash,direction:"flowchart",compact:!0,overridePath:e.targetPath,traceSnr:e.bestObservation.decoded.snrValues}):t.jsx("div",{className:"p-6 text-center text-fg-muted text-xs",children:"No path data available"})]}),t.jsxs("div",{children:[t.jsxs("h3",{className:"type-micro text-fg-muted mb-2",children:["Link Quality · ",e.hopStats.length," hops"]}),t.jsx("div",{className:"space-y-1.5",children:e.hopStats.length>0?e.hopStats.map((s,a)=>{var n,l,r;const c=a{const s=e.targetPath[e.linkQuality.weakestLinkPosition],a=e.targetPath[e.linkQuality.weakestLinkPosition+1]||"You",n=mt(s,i),l=mt(a,i),r=e.targetPath[e.linkQuality.strongestLinkPosition],c=e.targetPath[e.linkQuality.strongestLinkPosition+1]||"You",d=mt(r,i),o=mt(c,i);return t.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[t.jsx(dt,{label:"Weakest Link",numericValue:e.linkQuality.minSnr,unit:"dB",icon:ye,subtext:`${n||s} → ${l||a}`}),t.jsx(dt,{label:"Best Link",numericValue:e.linkQuality.maxSnr,showSign:!0,unit:"dB",icon:Re,subtext:`${d||r} → ${o||c}`})]})})(),t.jsxs("div",{children:[t.jsx("h3",{className:"type-micro text-fg-muted mb-3",children:"Link Details"}),t.jsx("div",{className:"space-y-2",children:e.hopStats.length>0?e.hopStats.map((s,a)=>{var n,l,r;const c=a0&&t.jsx("div",{className:"overflow-hidden",children:t.jsx("div",{className:"aspect-square w-full",children:t.jsx(bs,{path:e.targetPath,neighbors:i,localNode:c,localHash:null==l?void 0:l.local_hash,srcHash:e.srcHash,dstHash:e.dstHash,traceSnr:d})})}),t.jsxs("div",{className:"radius-inset bg-black overflow-hidden",children:[t.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[t.jsx("span",{className:"type-micro text-fg-muted",children:"Trace Route"}),t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsx(r,{color:e.isComplete?"green":"amber",compact:!0,children:e.isComplete?"Complete":`${e.maxHopsObserved}/${e.targetHopCount}`}),t.jsxs(r,{color:"teal",compact:!0,children:[e.targetHopCount," hop",1!==e.targetHopCount?"s":""]})]})]}),e.linkQuality&&e.bestObservation&&t.jsxs("div",{className:"flex items-center gap-4 px-4 pb-2 type-data-xs text-fg-muted",children:[t.jsxs("span",{children:[t.jsx("span",{className:"opacity-60",children:"Tag"})," ",t.jsx("code",{className:"text-sys-teal tabular-nums",children:e.traceTag.slice(0,8)})]}),t.jsxs("span",{children:[t.jsx("span",{className:"opacity-60",children:"SNR"})," ",t.jsxs("code",{className:"text-sys-indigo tabular-nums",children:[e.linkQuality.minSnr.toFixed(1),"–",e.linkQuality.maxSnr.toFixed(1)]}),t.jsx("span",{className:"opacity-60",children:" dB"})]})]}),e.bestObservation?t.jsx(Ys,{packet:e.bestObservation.packet,neighbors:i,localHash:null==l?void 0:l.local_hash,direction:"flowchart",compact:!0,overridePath:e.targetPath,traceSnr:e.bestObservation.decoded.snrValues}):t.jsx("div",{className:"p-8 text-center text-fg-muted text-xs",children:"No path data available"})]})]})]})]})]})}),ht=[{target:"PacketList",fn:"type",minStage:1},{target:"PacketList",fn:"route",minStage:1},{target:"PacketList",fn:"rssi",minStage:1},{target:"PacketList",fn:"snr",minStage:1},{target:"PacketList",fn:"path",minStage:1,when:V},{target:"PacketList",fn:"src_hash",minStage:1,when:Q},{target:"PacketList",fn:"text",minStage:1,when:G},{target:"PacketList",fn:"ack",minStage:1,when:O},{target:"PacketList",fn:"decrypt",minStage:2,when:W},{target:"PacketList",fn:"duplicates",minStage:1}];I(ht);const ut="(min-width: 640px)";let gt=null;function ft(e){return"undefined"==typeof window?()=>{}:(gt||(gt=window.matchMedia(ut)),gt.addEventListener("change",e),()=>null==gt?void 0:gt.removeEventListener("change",e))}function yt(){return"undefined"==typeof window||(gt||(gt=window.matchMedia(ut)),gt.matches)}function jt(e){if(!e||e.length<6)return null;const s=e,t=parseInt(s.slice(0,2),16);if(isNaN(t))return null;const a=3&t;let n=2;if(0!==a&&3!==a||(n=10),n+2>s.length)return null;const l=parseInt(s.slice(n,n+2),16);if(isNaN(l))return null;if(n+=2+2*l,n>=s.length)return null;const r=s.slice(n);return r.length>=38?r.slice(0,38):r}function bt({message:e}){return t.jsxs("div",{className:"flex flex-col items-center justify-center py-14 text-center",children:[t.jsx(he,{className:"size-6 text-fg-muted mb-2"}),t.jsx("p",{className:"text-sm text-fg-primary",children:e}),t.jsx("p",{className:"text-xs text-fg-muted",children:"Packets will appear here"})]})}function Nt(){return t.jsx("div",{className:"py-14 text-center text-sm text-fg-muted",children:"Loading packets…"})}function vt({showPagination:e,currentPage:s,perPage:a,displayCount:n,totalCount:l,action:r}){const i=e?(s-1)*a+1:1,c=e?Math.min(s*a,l):n;return t.jsxs("div",{className:"flex items-center justify-between gap-4 border-t border-edge-subtle px-4 py-3 text-xs text-fg-muted sm:px-6",children:[t.jsxs("span",{children:["Showing"," ",t.jsx("span",{className:"font-medium text-fg-secondary",children:e?`${i}–${c}`:n})," ","of"," ",t.jsx("span",{className:"font-medium text-fg-secondary",children:l})," ","packets"]}),r]})}function wt({packets:s,allPackets:l,localHash:r,neighbors:i,loading:c=!1,maxPackets:d,perPage:o=50,showPagination:x=!1,onPacketSelect:m,flashNewest:p=!1,emptyMessage:h="No packets found",className:u,footerAction:g,hideDupes:f=!1,getDecodedContent:y,onChannelClick:j,resolveSource:b,virtualized:N=!0}){U(ht);const[v,w]=a.useState(null),[k,C]=a.useState(null),[_,S]=a.useState({traceTag:null,dupeGroup:null}),P=a.useRef(null),H=Ke(e=>e.setModalMapOpen);a.useEffect(()=>(H(!!v),()=>H(!1)),[v,H]),a.useLayoutEffect(()=>{S({traceTag:null,dupeGroup:null})},[s]);const T=l??s,B=a.useMemo(()=>d&&d>0&&!f?s.slice(0,d):s,[s,d,f]),M=a.useMemo(()=>{if(!f)return null;const e=function(e){if(0===e.length)return[];const s=[];let t=0;for(;t0?{packet:e[r].packet,dupeCount:e[r].dupeCount+s}:e[r])}return l}(e);return d&&d>0?s.slice(0,d):s},[B,f,d]),F=M?M.length:B.length,{currentPage:L,totalPages:z,goToPage:$,pageRange:I}=function(e,s,t){const[n,l]=a.useState(1),r=t?Math.ceil(e/s):1;a.useEffect(()=>{n>r&&r>0&&queueMicrotask(()=>l(1))},[r,n]);const i=a.useCallback(e=>l(Math.max(1,Math.min(e,r))),[r]),c=a.useMemo(()=>function(e,s,t=1){if(s<=7)return Array.from({length:s},(e,s)=>s+1);const a=Math.max(e-t,1),n=Math.min(e+t,s),l=a>2,r=ns+1),"gap",s]}if(l&&!r){const e=3+2*t;return[1,"gap",...Array.from({length:e},(t,a)=>s-e+a+1)]}return[1,"gap",...Array.from({length:n-a+1},(e,s)=>a+s),"gap",s]}(n,r),[n,r]);return{currentPage:n,totalPages:r,goToPage:i,pageRange:c}}(F,o,x),V=a.useMemo(()=>{if(f)return B;if(!x)return B;const e=(L-1)*o;return B.slice(e,e+o)},[B,x,L,o,f]),Q=a.useMemo(()=>{if(!M)return null;if(!x)return M;const e=(L-1)*o;return M.slice(e,e+o)},[M,x,L,o]),G=a.useMemo(()=>function(e){const s=new Map;for(const t of e)if((t.payload_type??t.type)===D.TRACE&&t.packet_hash){const e=t._traceTag??(t.payload?R(t.payload):null);e&&s.set(t.packet_hash,e)}return s}(V),[V]),O=a.useMemo(()=>function(e){const s=new Map;if(0===e.length)return s;for(let t=0;t{var t,a;if(!s||!e.length)return;const r=(null==(t=e[0])?void 0:t.timestamp)??0,i=r>l.current&&l.current>0;if(l.current=r,!i)return;const c=null==(a=e[0])?void 0:a.packet_hash;if(!c)return;const d=requestAnimationFrame(()=>n(c)),o=setTimeout(()=>n(null),600);return()=>{cancelAnimationFrame(d),clearTimeout(o)}},[e,s]),t}(s,p),q=a.useSyncExternalStore(ft,yt,()=>!0),K=a.useMemo(()=>f&&Q?Q:V,[f,Q,V]),X=N&&K.length>100,Y=q?48:72,J=n({count:X?K.length:0,getScrollElement:()=>P.current,estimateSize:()=>Y,overscan:5}),Z=a.useCallback((e,s)=>{var t,a;const n=e.packet_hash;if(!n)return[e];let l=s;for(;l>0&&(null==(t=V[l-1])?void 0:t.packet_hash)===n;)l--;let r=s;for(;r{var s,t;const a=null==(s=V[e])?void 0:s.packet_hash;if(!a)return e;let n=e;for(;n>0&&(null==(t=V[n-1])?void 0:t.packet_hash)===a;)n--;return n},[V]),se=a.useCallback(e=>{var s,t;const a=null==(s=V[e])?void 0:s.packet_hash;if(!a)return e;let n=e;for(;n{if(m)m(e);else if(void 0!==s){const t=Z(e,s),a=t.indexOf(e);w({packets:t,initialIndex:a>=0?a:0,rowIndex:s})}else w({packets:[e],initialIndex:0,rowIndex:0})},[m,Z]),ae=a.useCallback(()=>{if(!v)return;const e=ee(v.rowIndex)-1;if(e<0)return;const s=V[e];if(!s)return;const t=Z(s,e);w({packets:t,initialIndex:0,rowIndex:e})},[v,V,ee,Z]),ne=a.useCallback(()=>{if(!v)return;const e=se(v.rowIndex)+1;if(e>=V.length)return;const s=V[e];if(!s)return;const t=Z(s,e);w({packets:t,initialIndex:0,rowIndex:e})},[v,V,se,Z]),le=a.useMemo(()=>!!v&&ee(v.rowIndex)>0,[v,ee]),re=a.useMemo(()=>!!v&&se(v.rowIndex)S(s=>({...s,traceTag:e})),[]),ce=a.useCallback(e=>S(s=>({...s,dupeGroup:e})),[]),de=a.useCallback(()=>{S({traceTag:null,dupeGroup:null})},[]),oe=a.useCallback(e=>{const s=T.filter(s=>(s.payload_type??s.type)===D.TRACE&&s.payload&&R(s.payload)===e);if(0===s.length)return;const t=A(s).get(e);(null==t?void 0:t.length)&&C(E(e,t))},[T]),xe=a.useCallback(e=>{const s=T.find(s=>s.packet_hash===e);s&&(C(null),te(s))},[T,te]),me=a.useCallback((e,s,a)=>{const n=q?hs:us;if(a){const{packet:a,dupeCount:l}=e,c=a.packet_hash?G.get(a.packet_hash):void 0,d=null!==_.traceTag&&c===_.traceTag;return t.jsx(n,{packet:a,onClick:e=>te(e,s),localHash:r,neighbors:i,resolveSource:b,isFlashing:p&&W===a.packet_hash,traceTag:c,isTraceHighlighted:d,onTraceHover:ie,onViewTraceReport:oe,dupeCount:l,getDecodedContent:y,onChannelClick:j},`${a.packet_hash}_${a.timestamp}_${s}`)}const l=e,c=l.packet_hash?G.get(l.packet_hash):void 0,d=null!==_.traceTag&&c===_.traceTag,o=O.get(s),x=void 0!==o&&null!==_.dupeGroup&&l.packet_hash===_.dupeGroup;return t.jsx(n,{packet:l,onClick:e=>te(e,s),localHash:r,neighbors:i,resolveSource:b,isFlashing:p&&W===l.packet_hash,traceTag:c,isTraceHighlighted:d,onTraceHover:ie,onViewTraceReport:oe,dupeGroupPosition:o,isDupeGroupHovered:x,onDupeGroupHover:ce,getDecodedContent:y,onChannelClick:j},`${l.packet_hash}_${l.timestamp}_${s}`)},[q,G,_.traceTag,_.dupeGroup,te,r,i,b,p,W,ie,oe,O,ce,y,j]);return t.jsxs("div",{className:e("flex flex-col",u),onMouseLeave:de,children:[X?t.jsx("div",{ref:P,className:"divide-y divide-edge-subtle overflow-auto",style:{maxHeight:600},children:(()=>{if(c&&0===s.length)return t.jsx(Nt,{});if(0===K.length)return t.jsx(bt,{message:h});const e=f&&null!==Q,a=J.getVirtualItems();return t.jsx("div",{style:{height:`${J.getTotalSize()}px`,width:"100%",position:"relative"},children:a.map(s=>{const a=K[s.index];return t.jsx("div",{"data-index":s.index,ref:J.measureElement,style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${s.start}px)`},children:me(a,s.index,e)},s.key)})})})()}):t.jsx("div",{className:"divide-y divide-edge-subtle py-1",children:(()=>{if(c&&0===s.length)return t.jsx(Nt,{});if(0===V.length)return t.jsx(bt,{message:h});const e=f&&null!==Q;return(e?Q:V).map((s,t)=>me(s,t,e))})()}),x&&z>1&&t.jsx("nav",{className:"border-t border-edge-subtle px-4 py-3",children:t.jsxs(Xe,{className:"justify-center",children:[t.jsx(Ye,{onClick:()=>$(L-1),disabled:1===L}),t.jsx(Ze,{children:I.map((e,s)=>"gap"===e?t.jsx(ss,{},`gap-${s}`):t.jsx(es,{page:e,current:e===L,onClick:$},e))}),t.jsx(Je,{onClick:()=>$(L+1),disabled:L===z})]})}),t.jsx(vt,{showPagination:x,currentPage:L,perPage:o,displayCount:Q?Q.length:V.length,totalCount:x?F:s.length,action:g}),!m&&v&&t.jsx(ct,{packets:v.packets,initialIndex:v.initialIndex,onClose:()=>w(null),onNavigatePrev:ae,onNavigateNext:ne,hasPrev:le,hasNext:re,resolveSource:b}),k&&t.jsx(pt,{report:k,onClose:()=>C(null),onViewPacket:xe})]})}export{ds as C,wt as P,rs as g,ts as u}; diff --git a/frontend/dist/assets/PacketObservatory-ChFmVrLE.js b/frontend/dist/assets/PacketObservatory-DF8DSfgt.js similarity index 99% rename from frontend/dist/assets/PacketObservatory-ChFmVrLE.js rename to frontend/dist/assets/PacketObservatory-DF8DSfgt.js index 0e3943eb..55b8ad26 100644 --- a/frontend/dist/assets/PacketObservatory-ChFmVrLE.js +++ b/frontend/dist/assets/PacketObservatory-DF8DSfgt.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/usePipelineStore-D3dOwDkO.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/node-types-CiI69Tya.js","assets/index-D7i6lQrq.js","assets/vendor-charts-C916_-gs.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/geo-utils-DJn8DnxF.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-B2A_8ldG.css"])))=>i.map(i=>d[i]); -import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{ar as s,c2 as r,c3 as n,c4 as a,c5 as l,a8 as o,c6 as c,c7 as i,c8 as d,c9 as p,a7 as u,ca as h,cb as x,cc as m,cd as g,bL as f,ce as v,h as b,af as y,ao as j,av as N,cf as k,cg as w,ch as C,ci as S,cj as _,ck as H,cl as T,cm as $,cn as P,co as L,M,H as D,cp as F,m as R,p as A,cq as z,a3 as E,bc as B}from"./index-D7i6lQrq.js";import{b as O,r as V,c as I}from"./usePipelineStore-D3dOwDkO.js";import{_ as U}from"./cosmograph-DqYT4sUA.js";import{e as q,p as G,a as K,A as W,S as Z,c as Y,f as X,K as Q,H as J,B as ee,R as te,T as se,P as re,h as ne,i as ae,C as le,s as oe,j as ce}from"./primitives-YN2ynYwE.js";import{m as ie,i as de}from"./node-types-CiI69Tya.js";import{a as pe}from"./vendor-core-FtpmsTnh.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";import"./geo-utils-DJn8DnxF.js";import"./payload-decoders-DjZO58V7.js";let ue=null,he=null;"undefined"!=typeof window&&setTimeout(()=>{U(()=>import("./usePipelineStore-D3dOwDkO.js").then(e=>e.d),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])).then(e=>{ue=e}),U(()=>import("./index-D7i6lQrq.js").then(e=>e.dv),__vite__mapDeps([2,7,12,13,14])).then(e=>{he=e})},0);const xe={advertSender:null,advertNodeType:null,advertFlags:null,advertHasLocation:null,advertHasName:null,advertName:null,advertLatitude:null,advertLongitude:null,channelHash:null,byteLength:void 0,hopCount:0,isZeroHop:!0,preComputed:!1};function me(e,t,s,r,n){if(0===t){const a=null==r?void 0:r.get(e);if(a)return{hash:a,confidence:.8};if(n){const r=V(n,e,{position:t,adjacentPrefixes:s});if(r.hash)return{hash:r.hash,confidence:r.confidence}}}else{if(n){const r=V(n,e,{position:t,adjacentPrefixes:s});if(r.hash)return{hash:r.hash,confidence:r.confidence}}const a=null==r?void 0:r.get(e);if(a)return{hash:a,confidence:.6}}return{hash:null,confidence:0}}function ge(t,x,m){const g=e.useRef({parse:0,decode:0,enrich:0,traceIndex:0,total:0}),f=e.useMemo(()=>t?function(e){var t;const s=e.raw_packet;if(!s||s.length<2)return null;const r=s.replace(/\s/g,""),n=Math.floor(r.length/2),a=(null==(t=r.match(/.{1,2}/g))?void 0:t.join(" "))??"";let l="";for(let o=0;o=32&&e<=126?String.fromCharCode(e):"·"}return{hexBytes:a,utf8:l,byteCount:n}}(t):null,[t]),v=e.useMemo(()=>{if(!x||x.length<4)return g.current.parse=0,g.current.decode=0,null;const e=performance.now(),t=G(x),s=performance.now()-e;return t?(g.current.parse=s,g.current.decode=0,{protocolPacket:t.packet,display:{headerFields:t.headerFields,transportCodesHex:t.transportCodesHex,pathLengthHex:t.pathLengthHex,pathDataHex:t.pathDataHex,payloadHex:t.payloadHex,payloadByteOffset:t.payloadStartByte,pathByteOffset:t.pathByteOffset,pathLenByteOffset:t.pathLenByteOffset},decoded:t.decoded,error:null}):(g.current.parse=s,g.current.decode=0,{protocolPacket:null,display:null,decoded:null,error:"Packet.fromHex() returned failure"})},[x]),b=e.useMemo(()=>{if(!t)return g.current.enrich=0,xe;const e=performance.now();if(void 0!==t._advertSender)return g.current.enrich=performance.now()-e,{advertSender:t._advertSender??null,advertNodeType:t._advertNodeType??null,advertFlags:t._advertFlags??null,advertHasLocation:t._advertHasLocation??null,advertHasName:t._advertHasName??null,advertName:t._advertName??null,advertLatitude:t._advertLatitude??null,advertLongitude:t._advertLongitude??null,channelHash:t._channelHash??null,byteLength:t._byteLength,hopCount:t._hopCount??0,isZeroHop:t._isZeroHop??!0,preComputed:!0};const s=t.type??t.payload_type,o=r(x,s),c=n(x,s),i=a(x,t),d=l(t);return g.current.enrich=performance.now()-e,{...o,channelHash:c,byteLength:i,...d,preComputed:!1}},[t,x]),y=e.useRef({fingerprint:"",index:new Map}),j=e.useMemo(()=>{const e=performance.now(),{index:t,fingerprint:r}=function(e){const t=new Map;let r=0,n="";for(const a of e){if((a.type??a.payload_type)!==s.TRACE)continue;r++,n=a.packet_hash;const e=a._traceTag??(a.payload?q(a.payload):null);if(!e)continue;let l=t.get(e);l||(l=[],t.set(e,l)),l.push(a)}return{index:t,fingerprint:`${r}:${n}`}}(m);return g.current.traceIndex=performance.now()-e,r===y.current.fingerprint?y.current.index:(y.current={fingerprint:r,index:t},t)},[m]),N=e.useMemo(()=>{const e=g.current;return{parse:e.parse,decode:e.decode,enrich:e.enrich,traceIndex:e.traceIndex,total:e.parse+e.decode+e.enrich+e.traceIndex}},[v,b,j]);if(!t)return null;const k=x?v?v.error:"rawHex too short":"No raw_packet (warm-tier)",w=(null==v?void 0:v.protocolPacket)??null,C=w?w.payloadVersion:null,S=0===C,_=1===C,H=function(e,t){const r=e.type??e.payload_type,n=u(r),a=o(e.route),l=r===s.ADVERT,h=r===s.TRACE,x=r===s.PATH,m=r===s.GRP_TXT||r===s.GRP_DATA,g=c(e.snr,e.rssi),f=(null==g?void 0:g.finalGrade)??"critical",v=i(e.route),b=d(e.route),y=p(e.route),j=null==e.route?"unknown":v?"flood":b?"direct":"unknown",N=y?`transport-${j}`:j,k=!!t.advertSender;let w="none";k?w="pubkey":m?w="encrypted":e.src_hash&&(w="prefix");const C=de(r),S=null!=t.advertNodeType?ie(t.advertNodeType):"unknown",_="unknown"!==C?C:S,H=e.packet_origin??"rx",T=Math.floor(Date.now()/1e3)-e.timestamp,$=T<10?"live":T<300?"recent":T<3600?"warm":T<86400?"stale":"historic",P=e.path_length??(Array.isArray(e.original_path)?e.original_path.length:void 0),L=Array.isArray(e.original_path)&&e.original_path.length>0,M=P??0,D=t.byteLength??(e.raw_packet?Math.floor(e.raw_packet.length/2):0),F=function(e){const t=e.type??e.payload_type,r=e.duplicates??[],n=e.is_duplicate,a=r.length;let l=null,o=null;if(a>0){const t=[e.rssi,...r.map(e=>e.rssi).filter(e=>null!=e)],s=[e.snr,...r.map(e=>e.snr).filter(e=>null!=e)];t.length>1&&(l=[Math.min(...t),Math.max(...t)]),s.length>1&&(o=[Math.min(...s),Math.max(...s)])}return{isDuplicate:n,dupeCount:a,rssiRange:l,snrRange:o,hashIncludesPathLen:t===s.TRACE}}(e);return{pType:r,payloadTypeName:n,routeTypeName:a,isAdvert:l,isTrace:h,isPath:x,isGrp:m,signalClass:f,routeClass:N,isFlood:v,isDirect:b,hasTransport:y,senderTier:w,hasPubkey:k,inferredType:C,advertType:S,effectiveType:_,origin:H,age:$,pathLen:P,pathAvail:L,pathHopCount:M,byteLen:D,dupeAnalysis:F}}(t,b);let T=null;return H.isTrace&&(T=function(e){var t,s,r,n,a,l;const o=K(e);if(!o||0===o.pathHashes.length)return null;const{pathHashes:c,snrValues:i}=o;if(c.length<2)return null;if(!ue||!he)return null;const d=ue.usePipelineStore.getState().srcHashResolverMap,p=ue.usePipelineStore.getState().neighborContext,u=(null==p?void 0:p.hashToName)??new Map,x=he.useStore.getState().stats,m=(null==x?void 0:x.neighbors)??{},g=null==x?void 0:x.local_hash,f=null==(s=null==(t=null==x?void 0:x.config)?void 0:t.repeater)?void 0:s.latitude,v=null==(n=null==(r=null==x?void 0:x.config)?void 0:r.repeater)?void 0:n.longitude,b=Object.keys(m).length>0?O([],m,g,f,v):null,y=[];for(let j=0;j0?[c[j-1].toUpperCase()]:[]],d,b),n=me(t,j+1,[e,...j+20?y:null}(t)),{wire:f,display:(null==v?void 0:v.display)??null,parseError:k,protocolPacket:w,decoded:(null==v?void 0:v.decoded)??null,payloadVersion:C,isV1:S,isV2:_,enrichment:b,traceTagIndex:j,analysis:H,traceHopDetail:T,timing:N}}function fe({options:e,nextFn:s}){var r;const n=e.find(e=>e.active),a=(null==n?void 0:n.color)??"green",l=(null==(r=W[a])?void 0:r.stem)??"bg-edge-subtle";return t.jsxs("div",{className:"flex flex-col items-start py-1 gap-0 px-2",children:[t.jsx("div",{className:`w-px h-2 ml-4 ${l}`}),t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-md overflow-hidden w-full",children:[e.map((e,s)=>{const r=W[e.color??"green"]??W.green;return t.jsxs("div",{className:`flex items-center gap-1.5 px-2 py-px font-mono text-[10px] leading-relaxed transition-opacity ${e.active?r.row:"opacity-25"}`,children:[t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${e.active?r.dot:"border border-zinc-500/40"}`}),t.jsx("span",{className:"w-16 shrink-0 font-medium "+(e.active?"text-fg-primary":"text-fg-muted"),children:e.label}),e.detail&&t.jsx("span",{className:e.active?"text-fg-primary/70":"text-fg-muted",children:e.detail})]},s)}),s&&t.jsx("div",{className:"flex items-center px-2 py-0.5 border-t border-edge-subtle",children:t.jsxs("span",{className:"text-[10px] text-fg-muted font-mono",children:["→ ",s]})})]}),t.jsx("div",{className:`w-px h-2 ml-4 ${l}`})]})}function ve({tokens:e,nextFn:s}){var r;const n=e.find(e=>e.active),a=(null==n?void 0:n.color)??"green",l=(null==(r=W[a])?void 0:r.stem)??"bg-edge-subtle";return t.jsxs("div",{className:"flex flex-col items-start py-1 gap-0 px-2",children:[t.jsx("div",{className:`w-px h-2 ml-4 ${l}`}),t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-md overflow-hidden w-full",children:[e.map((e,s)=>{const r=W[e.color??"green"]??W.green;return t.jsxs("div",{className:`flex items-center gap-1 px-2 py-px font-mono text-[10px] leading-relaxed transition-opacity ${e.active?r.row:"opacity-25"}`,children:[t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${e.active?r.dot:"border border-zinc-500/40"}`}),t.jsx("span",{className:"text-fg-muted shrink-0",children:e.fn}),t.jsxs("span",{className:e.active?"text-fg-primary":"text-fg-muted",children:["(",e.value??"",")"]})]},s)}),s&&t.jsx("div",{className:"flex items-center px-2 py-0.5 border-t border-edge-subtle",children:t.jsxs("span",{className:"text-[10px] text-fg-muted font-mono",children:["→ ",s]})})]}),t.jsx("div",{className:`w-px h-2 ml-4 ${l}`})]})}const be={0:"border-l-sys-green",1:"border-l-sys-blue",2:"border-l-sys-teal",3:"border-l-sys-purple"};function ye({stage:e,name:s,fn:r,verdict:n,timeMs:a,skipped:l,skipReason:o,children:c}){const i=be[e]??"";return t.jsx(t.Fragment,{children:t.jsx(x,{defaultOpen:!l,children:t.jsxs("div",{className:`surface-base rounded-lg border border-edge-subtle overflow-hidden border-l-2 ${i}`,children:[t.jsxs(m,{className:"px-3 py-2 w-full",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsx("span",{className:"font-mono text-xs font-bold text-sys-blue shrink-0",children:e}),t.jsx("span",{className:"font-mono text-xs font-medium text-fg-primary truncate",children:s}),r&&!n&&t.jsx("span",{className:"font-mono text-[11px] text-fg-muted truncate hidden sm:inline",children:r}),n&&t.jsx("span",{className:"font-mono text-[11px] text-fg-muted/70 truncate hidden sm:inline",children:n})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[l&&t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-zinc-500/20 text-fg-muted",children:"N/A"}),null!=a&&!l&&t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:a<1?`${(1e3*a).toFixed(0)}µs`:`${a.toFixed(2)}ms`})]})]}),t.jsx(g,{children:t.jsx("div",{className:"px-3 pb-3 font-mono text-xs",children:l?t.jsx("p",{className:"text-fg-muted italic",children:o??"Not applicable for this packet type"}):c})})]})})})}const je={connected:"green",degraded:"amber",offline:"red"};function Ne({packet:e,isSynthetic:s}){const r=f(e=>e.wsState),n=f(e=>e.health),a=function(e,t){return t?"manual":e._stripped?"bulk-tier":v.isConnected()?"ws-push":"rest-poll"}(e,s),l=[{label:"ws-push",detail:"wsConnected && onPacket()",active:"ws-push"===a,color:"green"},{label:"rest-poll",detail:"!wsConnected, 3s interval",active:"rest-poll"===a,color:"amber"},{label:"catchup",detail:"wsReconnected, delta > 50",active:"catchup"===a,color:"amber"},{label:"bulk-tier",detail:"user extends time range → gzip",active:"bulk-tier"===a,color:"blue"},{label:"manual",detail:"hex input — no transport",active:"manual"===a,color:"zinc"}],o=[{fn:"transport",value:a,group:"transport",color:"ws-push"===a?"green":"bulk-tier"===a?"blue":"amber"},{fn:"tier",value:e._stripped?"WARM":"HOT",group:"transport",color:"blue"},{fn:"wsState",value:r,group:"transport",color:"connected"===r?"green":"amber"},{fn:"health",value:n,group:"transport",color:je[n]}],c=s?"manual hex input":`${a} (${n})`;return t.jsx(ye,{stage:0,name:"TRANSPORT",fn:"websocketService / useStore.startPolling",verdict:c,children:s?t.jsx("p",{className:"text-fg-muted italic",children:"Manual hex input — no transport context"}):t.jsx(Z,{prefix:"transport",children:t.jsxs("div",{className:"space-y-0",children:[t.jsx(fe,{options:l,nextFn:"ingest()"}),t.jsx(Y,{tokens:o})]})})})}function ke({start:e,end:s}){const r=null!=s&&s!==e?`[${e}..${s}]`:`[${e}]`;return t.jsx("span",{className:"text-fg-muted text-[9px] font-mono mr-1 select-none",children:r})}const we={advert:"decodeAdvert()",ack:"decodeAck()",path:"decodePath()",trace:"decodeTraceWithSnr()",txt_msg:"decodeTextMessage()",grp_txt:"decodeGroupText()",grp_data:"decodeGroupData()",multipart:"decodeMultipart()",control:"decodeControl()",req:"decodeRequest()",response:"decodeResponse()",anon_req:"decodeAnonReq()",generic:"decodeGeneric()"};function Ce({rawHex:e,display:s,protocolPacket:r,parseError:n,parseTimeMs:a,payloadVersion:l,isV1:o,isV2:c}){return t.jsx("dl",{className:"space-y-0.5",children:s&&r&&e?t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"A. Parse — Packet.fromHex()"}),a>0&&t.jsx("div",{className:"flex justify-end",children:t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:a<1?`${(1e3*a).toFixed(0)}µs`:`${a.toFixed(2)}ms`})}),t.jsxs(Q,{label:"header byte",children:[t.jsx(ke,{start:0}),t.jsx(J,{value:e.slice(0,2)})," ",t.jsx(ee,{value:parseInt(e.slice(0,2),16)})]}),s.headerFields.map(e=>t.jsx(Q,{label:` ${e.field}`,children:t.jsx(te,{raw:t.jsxs("span",{className:"text-[10px]",children:["bits[",e.bits,"] = ",e.binary]}),children:t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber",children:e.value})})},e.field)),t.jsx(Q,{label:" version",children:null!=l?t.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[t.jsx(se,{fn:"payloadVer",value:`${l}`,color:"amber"}),t.jsx(b,{color:o?"green":c?"blue":"zinc",children:o?"v1":c?"v2":`v${l}`}),o&&t.jsx("span",{className:"text-fg-muted text-[10px]",children:"1-byte hashes, 2-byte MAC"}),c&&t.jsx("span",{className:"text-sys-blue text-[10px]",children:"2-byte hashes, 4-byte MAC (speculative)"})]}):t.jsx("span",{className:"text-fg-muted",children:"unknown"})}),t.jsx(X,{title:"Wire Framing"}),t.jsx(Q,{label:"transportCodes",children:s.transportCodesHex?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:1,end:4}),t.jsx(se,{fn:"transport",value:s.transportCodesHex,color:"amber"})]}):t.jsx("span",{className:"text-fg-muted",children:"N/A (non-transport route)"})}),t.jsx(Q,{label:"pathLen",children:t.jsx(te,{raw:t.jsxs(t.Fragment,{children:[t.jsx(ke,{start:s.pathLenByteOffset}),t.jsx(J,{value:s.pathLengthHex})]}),children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:s.pathLenByteOffset}),t.jsx(se,{fn:"pathLen",value:`${r.pathLen} hop${1!==r.pathLen?"s":""}`,color:"amber"})]})})}),t.jsx(Q,{label:"path",children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[r.pathLen>0&&t.jsx(ke,{start:s.pathByteOffset,end:s.pathByteOffset+r.pathLen-1}),t.jsx(re,{hops:r.pathHexArray,hexPrefix:s.pathDataHex||void 0})]})}),t.jsx(Q,{label:"payloadLen",children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:s.payloadByteOffset,end:s.payloadByteOffset+s.payloadHex.length/2-1}),t.jsx(se,{fn:"payloadLen",value:s.payloadHex.length/2+" bytes",color:"amber"})]})}),t.jsx(Q,{label:"payloadHex",children:t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber break-all",children:s.payloadHex})})]}):t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"A. Parse"}),t.jsxs(Q,{label:"result",children:[t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber",children:"Skipped"}),t.jsx("span",{className:"ml-1 text-fg-muted",children:n??"No raw_packet (warm-tier)"})]})]})})}function Se({decoded:e,packet:s}){if(!e)return t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"B. Decode"}),t.jsx("p",{className:"text-fg-muted italic text-[10px]",children:"No decoded payload"})]});const r=we[e.type]??`decode${e.type}()`;return t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"B. Decode — decodePayload()"}),t.jsx(Z,{prefix:"decodePayload",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsx(Q,{label:"dispatched",children:r}),t.jsx(X,{}),t.jsx(_e,{decoded:e,packet:s})]})})]})}function _e({decoded:e,packet:s}){switch(e.type){case"advert":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"publicKey",children:t.jsx(te,{raw:t.jsx("span",{className:"text-[10px] break-all",children:e.publicKey}),children:t.jsx(se,{fn:"publicKey",value:e.publicKey,color:"green"})})}),t.jsx(Q,{label:"timestamp",children:t.jsx(se,{fn:"timestamp",value:String(e.timestamp),color:"green"})}),t.jsx(Q,{label:"flags",children:t.jsx(te,{raw:t.jsx(J,{value:e.flags}),children:t.jsx(se,{fn:"flags",value:e.flagsDescription,color:"green"})})}),t.jsx(Q,{label:"nodeType",children:t.jsx(se,{fn:"nodeType",value:e.nodeType,color:"green"})}),null!=e.latitude&&t.jsx(Q,{label:"latitude",children:t.jsx(se,{fn:"lat",value:e.latitude.toFixed(6),color:"green"})}),null!=e.longitude&&t.jsx(Q,{label:"longitude",children:t.jsx(se,{fn:"lon",value:e.longitude.toFixed(6),color:"green"})}),e.name&&t.jsx(Q,{label:"name",children:t.jsx(se,{fn:"name",value:e.name,color:"green"})})]});case"ack":return t.jsx(Q,{label:"crc",children:t.jsx(te,{raw:t.jsx("span",{className:"text-[10px]",children:e.crc}),children:t.jsx(se,{fn:"crc",value:e.crc,color:"green"})})});case"trace":{const r=(null==s?void 0:s.src_hash)?s.src_hash.replace(/^0x/i,"").slice(0,2).toUpperCase():null;return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"traceTag",children:t.jsx(se,{fn:"traceTag",value:e.traceTag,color:"green"})}),t.jsx(Q,{label:"authCode",children:t.jsx(se,{fn:"authCode",value:String(e.authCode),color:"green"})}),t.jsx(Q,{label:"flags",children:t.jsx(J,{value:e.flags})}),t.jsx(Q,{label:"target path",children:e.pathHashes.length>0?t.jsx(re,{hops:e.pathHashes.map(e=>e.toUpperCase()),color:"green"}):t.jsx("span",{className:"text-fg-muted italic",children:"∅ empty"})}),t.jsx(Q,{label:"complete",children:e.isComplete?t.jsxs("span",{className:"text-sys-green",children:["✓ all ",e.pathHashes.length," hops reported SNR"]}):t.jsxs("span",{className:"text-sys-amber",children:["✗ ",e.snrValues.length,"/",e.pathHashes.length," hops reported"]})}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1 text-[10px]",children:"Directional Edge SNR — per-hop link quality"}),0===e.snrValues.length?t.jsx("p",{className:"text-fg-muted italic text-[11px] ml-2",children:"No SNR values in path field"}):t.jsx("div",{className:"space-y-0.5 ml-2",children:e.snrValues.map((s,n)=>{var a,l,o,c,i;const d=(null==(a=e.pathHashes[n])?void 0:a.toUpperCase())??"??",p=0===n?r??"SRC":(null==(l=e.pathHashes[n-1])?void 0:l.toUpperCase())??"??",u=null==(i=null==(c=null==(o=N.getState().stats)?void 0:o.config)?void 0:c.radio)?void 0:i.spreading_factor,x=h(s,u);return t.jsxs("div",{className:"flex items-center gap-1.5 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted w-3 text-right",children:n}),t.jsx("span",{className:"text-fg-primary",children:p}),t.jsx("span",{className:"text-fg-muted",children:"→"}),t.jsx("span",{className:"text-fg-primary",children:d}),t.jsx("span",{className:"text-fg-muted",children:"@"}),t.jsxs("span",{className:"font-bold text-sys-green",children:[s>0?"+":"",s.toFixed(1)," dB"]}),t.jsx(b,{color:"green",children:x})]},n)})})]})]})}case"path":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"pathLength",children:t.jsx(se,{fn:"pathLength",value:String(e.pathLength),color:"green"})}),t.jsx(Q,{label:"path",children:e.path&&e.path.length>0?t.jsx(re,{hops:e.path.map(e=>e.toUpperCase()),color:"green"}):t.jsx("span",{className:"text-fg-muted italic",children:"∅ empty"})}),null!=e.extraType&&t.jsx(Q,{label:"extraType",children:t.jsx(se,{fn:"extraType",value:e.extraTypeName??String(e.extraType),color:"purple"})}),e.extraData&&t.jsxs(Q,{label:"extraData",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.extraData}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.extraData.length/2,"B)"]})]})]});case"txt_msg":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"srcHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.srcHash}),children:t.jsx(se,{fn:"srcHash",value:e.srcHash,color:"green"})})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsx(Q,{label:"timestamp",children:t.jsx(se,{fn:"timestamp",value:String(e.timestamp),color:"green"})}),t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:e.text,color:"green"})}),t.jsx(Q,{label:"encrypted",children:t.jsx(se,{fn:"encrypted",value:String(e.encrypted),color:"green"})})]});case"grp_txt":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channelHash",children:t.jsx(J,{value:e.channelHash})}),e.channelName&&t.jsx(Q,{label:"channelName",children:t.jsx(se,{fn:"channel",value:e.channelName,color:"green"})}),t.jsx(Q,{label:"decrypted",children:t.jsx(se,{fn:"decrypted",value:String(e.decrypted),color:"green"})}),e.text&&t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:e.text,color:"green"})}),e.senderName&&t.jsx(Q,{label:"senderName",children:t.jsx(se,{fn:"sender",value:e.senderName,color:"green"})}),e.macCorrupted&&t.jsx(Q,{label:"macCorrupted",children:t.jsx(se,{fn:"macCorrupted",value:"true",color:"green"})})]});case"grp_data":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channelHash",children:t.jsx(J,{value:e.channelHash})}),t.jsx(Q,{label:"dataLength",children:e.dataLength}),t.jsx(Q,{label:"decrypted",children:String(e.decrypted)})]});case"multipart":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"messageId",children:e.messageId}),t.jsxs(Q,{label:"part",children:[e.partNumber+1," / ",e.totalParts]})]});case"control":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"controlType",children:t.jsx(te,{raw:t.jsx(J,{value:e.controlType}),children:t.jsx(se,{fn:"controlType",value:e.subtypeName,color:"green"})})}),t.jsx(Q,{label:"subtype",children:t.jsx(se,{fn:"subtype",value:`0x${e.subtype.toString(16).padStart(2,"0")}`,color:"green"})}),t.jsx(Q,{label:"subtypeFlags",children:t.jsx(se,{fn:"subtypeFlags",value:`0x${e.subtypeFlags.toString(16).padStart(2,"0")}`,color:"green"})}),e.dataLength>0&&t.jsxs(Q,{label:"data",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.dataHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.dataLength,"B)"]})]})]});case"req":case"response":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"srcHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.srcHash}),children:t.jsx(se,{fn:"srcHash",value:e.srcHash,color:"green"})})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsxs(Q,{label:"ciphertext",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.ciphertextHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.ciphertextLength,"B)"]})]})]});case"anon_req":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"senderPubKey",children:t.jsx("span",{className:"break-all text-[10px] font-mono text-sys-green",children:e.senderPublicKey})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsxs(Q,{label:"ciphertext",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.ciphertextHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.ciphertextLength,"B)"]})]})]});case"generic":return t.jsxs(t.Fragment,{children:[t.jsxs(Q,{label:"payloadType",children:[t.jsx(ne,{value:e.payloadType})," (",e.payloadTypeName,")"]}),t.jsx(Q,{label:"length",children:e.length}),t.jsx(Q,{label:"rawHex",children:t.jsx("span",{className:"break-all",children:e.rawHex})})]});default:return t.jsx("p",{className:"text-fg-muted",children:"Unknown decoded type"})}}function He({protocolPacket:s,packetHash:r}){const n=null==s?void 0:s.payloadType,a=n===k||n===w,l=e.useMemo(()=>{if(!a||!s)return null;const e=s.payload;return e.length<4?null:{channelHash:e[0],mac:e.slice(1,3),ciphertext:e.slice(3)}},[s,a]),[o,c]=e.useState("pending"),[i,d]=e.useState([]),[p,u]=e.useState(0);e.useEffect(()=>{if(!l)return void c(null);let e=!1;return(async()=>{const t=performance.now(),s=await C(l.channelHash,l.mac,l.ciphertext);e||(c(s),u(performance.now()-t));const r=await S(l.channelHash);e||d(r)})(),()=>{e=!0}},[l]);const[h,x]=e.useState(""),[m,g]=e.useState(null),[f,v]=e.useState(!1),b=e.useCallback(async()=>{if(l&&h.trim()){v(!0);try{const e=await y(h.trim(),l.channelHash,l.mac,l.ciphertext);if(e.success){const t=new TextDecoder("utf-8",{fatal:!1}).decode(e.result.plaintext.slice(5));g({success:!0,text:t})}else g({success:!1,error:e.error})}catch(e){g({success:!1,error:String(e)})}finally{v(!1)}}},[l,h]),N=j(r);return a&&l?t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"C. Decrypt — tryDecryptGroupMessage()"}),p>0&&t.jsx("div",{className:"flex justify-end",children:t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:p<1?`${(1e3*p).toFixed(0)}µs`:`${p.toFixed(2)}ms`})}),t.jsx(Z,{prefix:"tryDecryptGroupMessage",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsx(Q,{label:"channelHash",children:t.jsx(se,{fn:"channelHash",value:`0x${l.channelHash.toString(16).toUpperCase().padStart(2,"0")}`,color:"teal"})}),t.jsx(Q,{label:"mac",children:t.jsx(se,{fn:"mac",value:Array.from(l.mac).map(e=>e.toString(16).padStart(2,"0")).join(""),color:"teal"})}),t.jsx(Q,{label:"cipherLen",children:t.jsx(se,{fn:"cipherLen",value:`${l.ciphertext.length}B`,color:"teal"})}),t.jsx(Q,{label:"candidates",children:t.jsx(se,{fn:"candidates",value:i.length>0?`${i.length} names`:"0",color:i.length>0?"teal":"zinc"})}),i.length>0&&t.jsxs("details",{className:"mt-1",children:[t.jsx("summary",{className:"text-fg-muted cursor-pointer hover:text-fg-primary text-[10px]",children:"show candidate names"}),t.jsx("div",{className:"mt-1 text-[10px] text-fg-muted break-all max-h-24 overflow-y-auto",children:i.join(", ")})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"Result:"}),"pending"===o?t.jsx("p",{className:"text-fg-muted italic",children:"decrypting…"}):o?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channel",children:t.jsx(se,{fn:"channel",value:o.channelName,color:"teal"})}),t.jsx(Q,{label:"plaintext",children:t.jsx(se,{fn:"plaintext",value:new TextDecoder("utf-8",{fatal:!1}).decode(o.plaintext.slice(5)).trim()||"(empty)",color:"teal"})}),t.jsx(Q,{label:"macValid",children:t.jsx(se,{fn:"macValid",value:o.macCorrupted?"false":"true",color:"teal"})})]}):t.jsxs(Q,{label:"decrypt",children:[t.jsx(se,{fn:"decrypt",value:"failed",color:"red"}),t.jsx("span",{className:"text-fg-muted ml-1",children:"channel not in known list"})]})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"testChannelName() — manual test:"}),t.jsxs("div",{className:"flex gap-1.5 items-center",children:[t.jsx("input",{type:"text",value:h,onChange:e=>{x(e.target.value),g(null)},onKeyDown:e=>"Enter"===e.key&&b(),placeholder:"channel name",className:"surface-input px-2 py-1 rounded text-[11px] font-mono text-fg-primary w-40"}),t.jsx("button",{onClick:b,disabled:f||!h.trim(),className:"px-2 py-1 rounded text-[10px] font-mono bg-sys-blue/20 text-sys-blue hover:bg-sys-blue/30 disabled:opacity-40 transition-colors",children:f?"…":"Try"})]}),m&&t.jsx("div",{className:"mt-1",children:m.success?t.jsx(Q,{label:"result",children:t.jsx(se,{fn:"plaintext",value:m.text??"(empty)",color:"teal"})}):t.jsx(Q,{label:"error",children:t.jsx(se,{fn:"error",value:m.error??"unknown",color:"red"})})})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"useDecodedMessage() store result:"}),N?N.decoded?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channel",children:t.jsx(se,{fn:"channel",value:N.decoded.channelName??"?",color:"teal"})}),t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:N.decoded.text,color:"teal"})})]}):t.jsx(Q,{label:"decrypt",children:t.jsx(se,{fn:"decrypt",value:"failed",color:"red"})}):t.jsx(Q,{label:"decrypt",children:t.jsx(se,{fn:"decrypt",value:"pending",color:"zinc"})})]})]})})]}):null}function Te(e){const{rawHex:s,display:r,protocolPacket:n,decoded:a,parseError:l,parseTimeMs:o,payloadVersion:c,isV1:i,isV2:d,packetHash:p,packet:u}=e,h=!!s&&s.length>=4;return t.jsxs(x,{children:[t.jsx(m,{className:"w-full mt-2 mb-1",children:t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsx("span",{className:"text-[10px] font-mono text-fg-muted",children:"🔬"}),t.jsx("span",{className:"text-[10px] font-mono font-medium text-fg-muted",children:"Wire Inspection"}),t.jsx("span",{className:"text-[9px] text-fg-muted/50",children:"observatory diagnostic — not a runtime stage"})]})}),t.jsx(g,{children:t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-lg p-3 space-y-1 bg-surface/30",children:[t.jsx("p",{className:"text-[9px] text-fg-muted/50 mb-2",children:"The backend parsed these fields server-side. This panel verifies the wire-level encoding client-side."}),h?t.jsxs(t.Fragment,{children:[t.jsx(Ce,{rawHex:s,display:r,protocolPacket:n,parseError:l,parseTimeMs:o,payloadVersion:c,isV1:i,isV2:d}),t.jsx(Se,{decoded:a,packet:u}),t.jsx(He,{protocolPacket:n,packetHash:p})]}):t.jsx("p",{className:"text-fg-muted italic text-[10px]",children:l??"No raw_packet — wire inspection unavailable (warm-tier packet)"})]})})]})}function $e(e){if(!e)return[{fn:"decode",value:"no raw_packet",group:"decode",color:"zinc"}];switch(e.type){case"advert":{const t=e,s=[{fn:"decode.nodeType",value:t.nodeType,group:"decode",color:"blue"}];return t.name&&s.push({fn:"decode.name",value:t.name,group:"decode",color:"blue"}),null!=t.latitude&&null!=t.longitude&&s.push({fn:"decode.location",value:`${t.latitude.toFixed(4)}, ${t.longitude.toFixed(4)}`,group:"decode",color:"blue"}),s.push({fn:"decode.publicKey",value:t.publicKey,group:"decode",color:"blue"}),s}case"trace":{const t=e;return[{fn:"decode.traceTag",value:t.traceTag,group:"decode",color:"blue"},{fn:"decode.hops",value:t.pathHashes.length>0?t.pathString:"empty",group:"decode",color:"blue"},{fn:"decode.snr",value:t.snrValues.length>0?`${t.snrValues.length} values`:"none",group:"decode",color:t.snrValues.length>0?"blue":"zinc"},{fn:"decode.complete",value:t.isComplete?"yes":"partial",group:"decode",color:t.isComplete?"green":"amber"}]}case"path":{const t=e,s=[{fn:"decode.pathLength",value:String(t.pathLength),group:"decode",color:"blue"},{fn:"decode.path",value:t.path.length>0?t.pathString:"empty",group:"decode",color:"blue"}];return null!=t.extraType&&s.push({fn:"decode.extraType",value:t.extraTypeName??String(t.extraType),group:"decode",color:"purple"}),t.extraData&&s.push({fn:"decode.extraData",value:t.extraData.length/2+"B",group:"decode",color:"purple"}),s}case"ack":return[{fn:"decode.crc",value:e.crc,group:"decode",color:"blue"}];case"grp_txt":return[{fn:"decode.channelHash",value:e.channelHash,group:"decode",color:"blue"},{fn:"decode.encrypted",value:"true — decrypt at cascade",group:"decode",color:"zinc"}];case"grp_data":{const t=e;return[{fn:"decode.channelHash",value:t.channelHash,group:"decode",color:"blue"},{fn:"decode.dataLength",value:`${t.dataLength}B`,group:"decode",color:"blue"}]}case"txt_msg":{const t=e;return[{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.encrypted",value:t.encrypted?"true":"false",group:"decode",color:t.encrypted?"zinc":"green"},...t.encrypted?[]:[{fn:"decode.text",value:t.text,group:"decode",color:"blue"}]]}case"multipart":{const t=e;return[{fn:"decode.part",value:`${t.partNumber+1}/${t.totalParts}`,group:"decode",color:"blue"},{fn:"decode.msgId",value:t.messageId,group:"decode",color:"blue"}]}case"control":{const t=e;return[{fn:"decode.subtype",value:t.subtypeName,group:"decode",color:"blue"},{fn:"decode.subtypeFlags",value:`0x${t.subtypeFlags.toString(16)}`,group:"decode",color:"blue"},{fn:"decode.dataLength",value:`${t.dataLength}B`,group:"decode",color:"blue"}]}case"req":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"response":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"anon_req":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.senderPubKey",value:t.senderPublicKey,group:"decode",color:"green"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"generic":return[{fn:"decode.raw",value:`${e.length}B`,group:"decode",color:"zinc"}];default:return[]}}function Pe({packet:s,pipeline:r,rawHex:n,traceTagIndex:a,neighbors:l}){const{enrichment:o,timing:c,display:i,protocolPacket:d,decoded:p,parseError:u,payloadVersion:h,isV1:x,isV2:m,analysis:g}=r,f=(s.type??s.payload_type)===_,v=g.dupeAnalysis,y=e.useRef(0),j=e.useMemo(()=>{if(!f)return null;const e=performance.now(),t=function(e,t,s){let r=e._traceTag;if(!r&&e.payload&&(r=q(e.payload)),!r)return{traceTag:null,siblingCount:0,isLocallyOriginated:!1,method:"none",confidence:"none",inferredSrc:null,inferredName:null,evidence:[],thisPathLen:0,minPathLen:0,firstHopPrefix:null,evidence:["no traceTag — cannot correlate"]};const n=t.get(r)??[],a=e=>null!=e.path_length?e.path_length:Array.isArray(e.original_path)?e.original_path.length:0,l=a(e),o=n.length>0?Math.min(...n.map(a)):l,c=e.payload?e.payload.slice(18):"",i=c.length>=2?c.slice(0,2).toUpperCase():null,d=[];if(d.push(`traceTag: ${r}`),d.push(`siblings: ${n.length} observation${1!==n.length?"s":""}`),"tx_local"===e.packet_origin)return d.push("packet_origin = tx_local → we initiated this trace"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!0,method:"tx_local",confidence:"certain",inferredSrc:"LOCAL",inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i};const p=n.find(e=>"tx_local"===e.packet_origin);if(p)return d.push(`sibling (hash ${p.packet_hash}) has packet_origin = tx_local`),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!0,method:"tx_local",confidence:"certain",inferredSrc:"LOCAL",inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i};if(d.push(`this observation: path_len=${l}, min across siblings: ${o}`),i){if(d.push(`first hop in target path: ${i}`),0===l)return d.push("path_len = 0 → heard directly from initiator (no SNR appended yet)"),d.push("initiator is a direct RF neighbor"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"min_path_len",confidence:"speculative",inferredSrc:null,inferredName:null,evidence:[...d,"initiator is within direct RF range (zero forwarding hops)"],thisPathLen:l,minPathLen:o,firstHopPrefix:i};const e=Object.entries(s).filter(([e])=>e.replace(/^0x/i,"").slice(0,2).toUpperCase()===i);if(1===e.length){const[t,s]=e[0],a=s.name||s.node_name||null;return d.push(`first hop ${i} → unique neighbor: ${a??t}`),d.push("initiator is whoever sent TO this first hop"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"first_hop_neighbor",confidence:"likely",inferredSrc:i,inferredName:a,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i}}e.length>1?d.push(`first hop ${i} matches ${e.length} neighbors (ambiguous)`):d.push(`first hop ${i} is not a known neighbor`)}return d.push("insufficient data to identify initiator"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"none",confidence:"none",inferredSrc:null,inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i}}(s,a,l);return y.current=performance.now()-e,t},[s,a,l,f]),N=c.enrich+y.current,k=[];g.byteLen&&k.push(`${g.byteLen}B`),k.push(g.payloadTypeName),o.advertName&&k.push(`"${o.advertName}"`),o.isZeroHop?k.push("zero-hop"):g.pathHopCount>0&&k.push(`${g.pathHopCount}h`),k.push(`${s.rssi}dBm`),v.isDuplicate&&k.push("DUPE");const w=k.join(" — ");return t.jsxs(ye,{stage:1,name:"INGEST",fn:o.preComputed?"PacketCache.mergePackets()":"extractAdvertData() + extractHopData() + ...",verdict:w,timeMs:N,children:[t.jsx(Te,{rawHex:n,display:i,protocolPacket:d,decoded:p,parseError:u,parseTimeMs:c.parse,payloadVersion:h,isV1:x,isV2:m,packetHash:s.packet_hash,packet:s}),t.jsx(X,{title:"Cache Enrichment"}),t.jsx(Z,{prefix:"packetCache",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsxs("div",{className:"mb-1.5",children:[o.preComputed?t.jsx(b,{color:"green",children:"PacketCache"}):t.jsx(b,{color:"amber",children:"computed"}),t.jsx("span",{className:"text-[10px] text-fg-muted ml-1.5",children:o.preComputed?"pre-enriched by real pipeline":"synthetic — computed on the fly"})]}),t.jsxs("div",{className:"flex flex-wrap gap-x-2 gap-y-1 mb-1",children:[t.jsx(se,{fn:"_byteLength",value:null!=o.byteLength?`${o.byteLength}B`:void 0,color:"blue"}),t.jsx(se,{fn:"_hopCount",value:String(o.hopCount),color:"blue"}),t.jsx(se,{fn:"_isZeroHop",value:String(o.isZeroHop),color:o.isZeroHop?"green":"blue"}),o.isZeroHop&&t.jsx(b,{color:"blue",children:"direct"}),null!=o.channelHash&&t.jsx(se,{fn:"_channelHash",value:o.channelHash,color:"blue"}),f&&s._traceTag&&t.jsx(se,{fn:"_traceTag",value:s._traceTag,color:"blue"})]}),o.advertSender||null!=o.advertNodeType||null!=o.advertName?t.jsxs("div",{className:"mt-1 mb-1",children:[t.jsx("p",{className:"text-[10px] text-sys-blue font-medium mb-0.5",children:"ADVERT Enrichment"}),t.jsxs("div",{className:"flex flex-wrap gap-x-2 gap-y-1",children:[o.advertSender&&t.jsx(se,{fn:"_advertSender",value:o.advertSender.slice(0,16)+"…",color:"blue"}),null!=o.advertNodeType&&t.jsx(se,{fn:"_advertNodeType",value:ie(o.advertNodeType),color:"blue"}),null!=o.advertName&&t.jsx(se,{fn:"_advertName",value:o.advertName,color:"blue"}),null!=o.advertFlags&&t.jsx(se,{fn:"_advertFlags",value:`0x${o.advertFlags.toString(16).padStart(2,"0")}`,color:"blue"}),null!=o.advertHasLocation&&t.jsx(se,{fn:"_advertHasLocation",value:String(o.advertHasLocation),color:"blue"}),null!=o.advertHasName&&t.jsx(se,{fn:"_advertHasName",value:String(o.advertHasName),color:"blue"}),null!=o.advertLatitude&&null!=o.advertLongitude&&t.jsx(se,{fn:"location",value:`${o.advertLatitude.toFixed(4)}, ${o.advertLongitude.toFixed(4)}`,color:"blue"})]})]}):t.jsx("p",{className:"text-[10px] text-fg-muted/30 mb-1",children:"ADVERT fields: N/A (non-ADVERT packet)"}),t.jsx(X,{title:"Payload Decode"}),t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full shrink-0 "+(p?"bg-sys-blue":"bg-zinc-500/40")}),t.jsx("span",{className:"font-mono text-[10px] font-medium text-fg-primary",children:"decodePayload()"}),t.jsx("span",{className:"text-[9px] text-fg-muted",children:"sync — wire data only, no crypto"})]}),t.jsx("div",{className:"ml-3",children:p?t.jsx("div",{className:"flex flex-wrap gap-x-1.5 gap-y-1",children:$e(p).map((e,s)=>t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5",children:t.jsx(se,{fn:e.fn,value:e.value,color:e.color})},s))}):t.jsx(ae,{children:"no raw_packet — warm-tier packet, decode unavailable"})})]}),t.jsx(X,{}),t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted",children:"dupe:"}),v.isDuplicate?t.jsx(se,{fn:"is_duplicate",value:"true",color:"purple"}):t.jsx(ae,{children:"none"}),v.dupeCount>0&&t.jsx(se,{fn:"dupeCount",value:`×${v.dupeCount}`,color:"purple"}),v.rssiRange&&t.jsxs(ae,{c:"text-fg-primary",children:["Δ",Math.abs(v.rssiRange[1]-v.rssiRange[0]),"dB RSSI"]})]}),j&&t.jsxs(t.Fragment,{children:[t.jsx(X,{}),t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted",children:"TRACE SRC:"}),j.inferredSrc?t.jsxs(t.Fragment,{children:[t.jsx(se,{fn:"inferredSrc",value:j.inferredSrc,color:"purple"}),j.inferredName&&t.jsx(se,{fn:"name",value:j.inferredName,color:"purple"})]}):t.jsx(ae,{children:"unresolvable"}),t.jsx(le,{color:"purple",children:j.method}),t.jsxs(ae,{children:["(",j.confidence,")"]}),t.jsxs(ae,{children:["siblings=",j.siblingCount]})]})]}),(()=>{const e=null!=g.pType?`0x${g.pType.toString(16).toUpperCase().padStart(2,"0")}`:void 0,r=null!=s.route?`0x${s.route.toString(16).toUpperCase().padStart(2,"0")}`:void 0,n=$e(p),a="excellent"===g.signalClass||"good"===g.signalClass?"green":"fair"===g.signalClass?"amber":"red",l="pubkey"===g.senderTier?"green":"prefix"===g.senderTier?"amber":"encrypted"===g.senderTier?"teal":"zinc",c=[{fn:"type",value:g.payloadTypeName,raw:e,group:"wire",color:"blue"},{fn:"route",value:g.routeTypeName,raw:r,group:"wire",color:"blue"},{fn:"src_hash",value:s.src_hash||void 0,group:"wire",color:"blue"},{fn:"rssi",value:`${s.rssi}dBm`,group:"wire",color:"blue"},{fn:"snr",value:`${s.snr}dB`,group:"wire",color:"blue"},{fn:"_byteLength",value:g.byteLen?`${g.byteLen}B`:void 0,group:"enrichment",color:"blue"},{fn:"_hopCount",value:String(o.hopCount),group:"enrichment",color:"blue"},{fn:"_isZeroHop",value:String(o.isZeroHop),group:"enrichment",color:"blue"},{fn:"_advertSender",value:o.advertSender||void 0,group:"enrichment",color:"blue"},{fn:"_advertNodeType",value:"unknown"!==g.advertType?g.advertType:void 0,group:"enrichment",color:"blue"},{fn:"_advertName",value:o.advertName||void 0,group:"enrichment",color:"blue"},{fn:"_channelHash",value:o.channelHash||void 0,group:"enrichment",color:"blue"},...n,{fn:"is_duplicate",value:String(v.isDuplicate),group:"analysis",color:"purple"},(null==j?void 0:j.inferredSrc)?{fn:"traceSrc",value:j.inferredSrc,group:"analysis",color:"purple"}:{fn:"traceSrc"},{fn:"_signalClass",value:g.signalClass,group:"analysis",color:a},{fn:"_routeClass",value:g.routeClass,group:"analysis",color:"purple"},{fn:"_senderTier",value:g.senderTier,group:"analysis",color:l},{fn:"_origin",value:g.origin,group:"analysis",color:"tx_local"===g.origin?"green":"tx_forward"===g.origin?"amber":"purple"},{fn:"_pathAvail",value:g.pathAvail?`${g.pathHopCount} hops`:"none",group:"analysis",color:g.pathAvail?"green":"zinc"},{fn:"_age",value:g.age,group:"analysis",color:"live"===g.age||"recent"===g.age?"green":"zinc"},...v.dupeCount>0?[{fn:"_dupeCount",value:`×${v.dupeCount}`,group:"analysis",color:"purple"},...v.rssiRange?[{fn:"_multipath",value:`Δ${Math.abs(v.rssiRange[1]-v.rssiRange[0])}dB`,group:"analysis",color:Math.abs(v.rssiRange[1]-v.rssiRange[0])>6?"amber":"green"}]:[]]:[],...null!=s.lbt_attempts?[{fn:"_lbt",value:`${s.lbt_attempts} attempt${1!==s.lbt_attempts?"s":""}`,group:"analysis",color:(s.lbt_attempts??0)>1?"amber":"green"}]:[],...s.drop_reason?[{fn:"_dropReason",value:s.drop_reason,group:"analysis",color:"red"}]:[]];return t.jsx(Y,{tokens:c})})()]})})]})}function Le(e){switch(e){case"excellent":case"good":return"green";case"fair":return"amber";case"poor":case"critical":return"red";default:return"zinc"}}function Me(e){return`${Math.round(100*e)}%`}function De(e,t,s){return e||(t?t.slice(0,12):`~${s}`)}function Fe({hops:e}){return 0===e.length?null:t.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/40",children:[t.jsx("p",{className:"text-[9px] text-fg-muted/40 uppercase tracking-widest font-mono mb-1.5",children:"per-hop trace inspection"}),t.jsx("div",{className:"space-y-1",children:e.map(e=>t.jsx(Z,{prefix:`trace.hop[${e.hopIndex}]`,children:t.jsxs("div",{className:"border border-edge-subtle/40 rounded px-2 py-1.5",children:[t.jsxs(Q,{label:"link",children:[t.jsx(re,{hops:[e.fromPrefix,e.toPrefix],color:"blue"}),t.jsx("span",{className:"ml-1.5",children:t.jsx(le,{color:Le(e.quality),children:e.quality})})]}),t.jsx(Q,{label:"snr",children:t.jsx(te,{raw:t.jsx("span",{className:"text-sys-blue",children:e.snrRaw}),children:t.jsx(se,{fn:"snr",value:`${e.snrRaw.toFixed(1)} dB`,color:Le(e.quality)})})}),t.jsxs(Q,{label:"from",children:[t.jsx(se,{fn:"resolve",value:De(e.fromName,e.fromHash,e.fromPrefix),color:e.fromHash?e.fromConfidence>=.8?"green":"amber":"purple"}),t.jsx("span",{className:"ml-1",children:t.jsx(se,{fn:"conf",value:Me(e.fromConfidence),color:"zinc"})})]}),t.jsxs(Q,{label:"to",children:[t.jsx(se,{fn:"resolve",value:De(e.toName,e.toHash,e.toPrefix),color:e.toHash?e.toConfidence>=.8?"green":"amber":"purple"}),t.jsx("span",{className:"ml-1",children:t.jsx(se,{fn:"conf",value:Me(e.toConfidence),color:"zinc"})})]})]})},e.hopIndex))}),t.jsx(Y,{label:"trace contributes",tokens:Re(e)})]})}function Re(e){const t=e.reduce((e,t)=>e+(t.fromHash?1:0)+(t.toHash?1:0),0),s=2*e.length,r=s-t,n=e.length>0?e.reduce((e,t)=>e+t.snrRaw,0)/e.length:0;return[{fn:"hops",value:String(e.length),group:"wire",color:"blue"},{fn:"resolved",value:`${t}/${s}`,group:"worker",color:"green"},...r>0?[{fn:"ghosts",value:String(r),group:"worker",color:"purple"}]:[],{fn:"avgSnr",value:`${n.toFixed(1)} dB`,group:"analysis",color:n>=5?"green":n>=0?"amber":"red"}]}function Ae(e){if(!e)return"never";const t=Math.floor((Date.now()-e)/1e3);return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:`${Math.floor(t/3600)}h ago`}function ze({packet:e,decrypted:r,pipeline:n}){var a;const l=H(e=>e.isComputing),o=H(e=>e.lastUpdated),c=H(e=>e.lastComputeTimeMs),i=H(e=>e.topology.edges.length),d=H(e=>e.topology.discoveredNodes.length),p=T(),u=$(),h=P(),f=L(e=>e.isComputing),v=L(e=>e.nodeCount),b=M(e=>e.progress),y=M(e=>e.initialDecodeComplete),j=e.type??e.payload_type,N=j===s.GRP_TXT||j===s.GRP_DATA,k=j===s.TRACE,w=j===s.PATH,C=N,S=[{label:"full",detail:"all GRP_TXT → decryption worker",active:C&&y,color:"teal"},{label:"quick",detail:"100 most recent (initial load)",active:C&&!y,color:"amber"},{label:"skip",detail:"non-GRP or catchup path",active:!C,color:"zinc"}],_=function(e){if(!e)return[];const t=e.decoded;if(!t)return[{fn:"decrypt.result",value:"failed",group:"crypto",color:"red"}];if(!t.decrypted)return[{fn:"decrypt.result",value:"no key match",group:"crypto",color:"zinc"}];const s=[];return t.channelName&&s.push({fn:"decrypt.channelName",value:t.channelName,group:"crypto",color:"teal"}),t.senderName&&s.push({fn:"decrypt.senderName",value:t.senderName,group:"crypto",color:"teal"}),t.text&&s.push({fn:"decrypt.text",value:t.text,group:"crypto",color:"teal"}),t.timestamp&&s.push({fn:"decrypt.timestamp",value:new Date(1e3*t.timestamp).toISOString().slice(11,19),group:"crypto",color:"teal"}),t.macCorrupted&&s.push({fn:"decrypt.macCorrupted",value:"true",group:"crypto",color:"amber"}),s}(r),D=!0===(null==(a=null==r?void 0:r.decoded)?void 0:a.decrypted),F=`topo ${l?"○":"✓"} ${l?"running":`${i}e ${d}g`} · spark ${f?"○":"✓"} ${f?"running":`${v}n`} · decrypt ${C?D?"decrypted":b.isDecoding?`${b.percent}%`:"pending":"N/A"}`;return t.jsx(ye,{stage:2,name:"CASCADE",fn:"hydrateDownstream()",verdict:F,children:t.jsx(Z,{prefix:"cascade",children:t.jsxs("div",{className:"space-y-0",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 py-1.5 text-[11px] font-mono",children:[t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(l?"bg-sys-amber animate-pulse":"bg-sys-green")}),t.jsx("span",{className:"text-fg-primary",children:"topology"}),t.jsxs("span",{className:"text-fg-muted",children:[i,"e ",d,"g"]}),(k||w)&&t.jsx("span",{className:"text-sys-green text-[9px]",children:"↑signal"})]}),t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(f?"bg-sys-amber animate-pulse":"bg-sys-green")}),t.jsx("span",{className:"text-fg-primary",children:"sparkline"}),t.jsxs("span",{className:"text-fg-muted",children:[v,"n"]})]}),t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(b.isDecoding?"bg-sys-amber animate-pulse":C?"bg-sys-teal":"bg-zinc-500/40")}),t.jsx("span",{className:"text-fg-primary",children:"decrypt"}),t.jsx("span",{className:C?"text-sys-teal":"text-fg-muted",children:C?D?"decrypted":b.isDecoding?`${b.percent}%`:"pending":"N/A"})]})]}),t.jsxs(x,{defaultOpen:k||w,children:[t.jsx(m,{className:"text-[10px] w-full border-t border-edge-subtle pt-1.5",children:t.jsx("span",{className:"font-mono text-fg-muted/50",children:"topology detail…"})}),t.jsx(g,{children:t.jsxs("div",{className:"ml-3 pb-2",children:[t.jsx(Q,{label:"status",children:t.jsx(se,{fn:"isComputing",value:l?"running":"idle",color:l?"amber":"green"})}),t.jsxs(Q,{label:"last",children:[t.jsx(se,{fn:"lastUpdated",value:Ae(o),color:"zinc"}),c>0&&t.jsxs("span",{className:"ml-2 text-fg-muted text-[10px]",children:["(",c<1e3?`${c.toFixed(0)}ms`:`${(c/1e3).toFixed(1)}s`,")"]})]}),t.jsxs(Q,{label:"output",children:[t.jsx(se,{fn:"edges",value:String(i),color:"green"}),t.jsx(se,{fn:"ghostNodes",value:String(d),color:"purple"})]}),u&&t.jsxs(t.Fragment,{children:[t.jsxs(Q,{label:"trace links",children:[t.jsx(se,{fn:"directed",value:String(p.totalDirectedLinks),color:"teal"}),t.jsx(se,{fn:"bidir",value:String(p.bidirectionalLinks),color:"teal"}),t.jsx(se,{fn:"traces",value:String(p.totalTraces),color:"zinc"})]}),t.jsxs(Q,{label:"trace SNR",children:[t.jsx(se,{fn:"mean",value:`${p.meanSnr.toFixed(1)} dB`,color:p.meanSnr>=5?"green":p.meanSnr>=0?"amber":"red"}),t.jsx(se,{fn:"median",value:`${p.medianSnr.toFixed(1)} dB`,color:"zinc"}),t.jsx(se,{fn:"confidence",value:`${Math.round(100*p.avgConfidence)}%`,color:"zinc"})]}),k&&t.jsxs(Q,{label:"quality",children:[t.jsx(se,{fn:"excellent",value:String(p.qualityCounts.excellent),color:"green"}),t.jsx(se,{fn:"good",value:String(p.qualityCounts.good),color:"green"}),t.jsx(se,{fn:"fair",value:String(p.qualityCounts.fair),color:"amber"}),t.jsx(se,{fn:"poor",value:String(p.qualityCounts.poor),color:"red"}),t.jsx(se,{fn:"critical",value:String(p.qualityCounts.critical),color:"red"})]}),h.confirmedResolutions.size>0&&t.jsxs(Q,{label:"feedback",children:[t.jsx(se,{fn:"feedback.confirmed",value:String(h.confirmedResolutions.size),color:"teal"}),t.jsx(se,{fn:"feedback.links",value:String(h.confirmedLinks.length),color:"teal"})]})]}),k&&(null==n?void 0:n.traceHopDetail)&&t.jsx(Fe,{hops:n.traceHopDetail})]})})]}),C&&t.jsx("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:t.jsxs("div",{className:"ml-3",children:[t.jsx(Q,{label:"mode",children:t.jsx(fe,{options:S,nextFn:"queueDecryption()"})}),t.jsx(Q,{label:"result",children:t.jsx(se,{fn:"decrypt",value:D?"decrypted":r?"failed":"pending",color:D?"teal":r?"red":"zinc"})}),D&&t.jsx("div",{className:"mt-1 flex flex-wrap gap-x-1.5 gap-y-1",children:_.map((e,s)=>t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5",children:t.jsx(se,{fn:e.fn,value:e.value,color:e.color})},s))})]})}),(()=>{const e=[{fn:"topology.edges",value:String(i),group:"worker",color:"green"},{fn:"topology.ghostNodes",value:String(d),group:"worker",color:"purple"},{fn:"sparkline.nodes",value:`${v}`,group:"worker",color:"green"},...u?[{fn:"trace.directedLinks",value:String(p.totalDirectedLinks),group:"worker",color:"teal"},{fn:"trace.meanSnr",value:`${p.meanSnr.toFixed(1)} dB`,group:"worker",color:"teal"}]:[],..._];return t.jsx(Y,{tokens:e})})()]})})})}function Ee({packet:s,pipeline:r,resolved:n,resolveTimeMs:a,advertName:l,neighbors:o,decrypted:c}){var i,d;const p=I(e=>e.neighborContext),u=I(e=>e.topologyProfiles),h=I(e=>e.config),{analysis:f}=r,v=n??{hash:null,type:"unknown",name:null,confident:!1},y=s.src_hash?D(s.src_hash):"",j=y?p.prefixIndex.get(y)??[]:[],N=y?u.get(y)??[]:[],k=f.pType??-1,w=k>=0?k.toString(16).toUpperCase().padStart(2,"0"):"??",C=f.inferredType,S=f.advertType,_=f.effectiveType,H=null!=s._advertNodeType?s._advertNodeType.toString(16).padStart(2,"0").toUpperCase():"",T=(null==(i=null==c?void 0:c.decoded)?void 0:i.senderName)??null,$=function(e,t,s,r){var n;const a=e.src_hash?D(e.src_hash):"";if(e._advertSender&&t.hash&&t.confident)return{tier:1,label:"_advertSender → pubkey",detail:"ADVERT carried full 32-byte public key — definitive match"};if(r&&t.confident&&(null==(n=t.name)?void 0:n.toLowerCase())===r.toLowerCase())return{tier:1.5,label:"decrypt.senderName → nameToHash",detail:`Decrypted sender name “${r}” matched neighbor — high-confidence`};if(a&&s.crossClassPrefixes.has(a))return{tier:2,label:"cross-class prefix",detail:"Prefix has mixed types (repeater + non-repeater); payload type narrows to one class"};if(t.confident){const e=s.prefixIndex.get(a);return 1===(null==e?void 0:e.length)?{tier:3,label:"single candidate",detail:"Only one node matches this prefix — unambiguous"}:{tier:3,label:"resolver",detail:"Multi-signal scoring selected best candidate from collision set"}}return{tier:4,label:"ambiguous",detail:"Cannot confidently resolve — multiple same-class candidates, insufficient scoring separation"}}(s,v,p,T),P=e.useMemo(()=>function(e,t){const s=e.original_path??e.forwarded_path,r=new Set;if(s&&Array.isArray(s))for(const n of s){const e=String(n).toUpperCase().slice(0,2);e.length>=2&&e!==t&&r.add(e)}return r}(s,y),[s,y]),L=f.pathLen,M=e.useMemo(()=>function(e,t,s,r,n,a,l){const o=Math.floor(Date.now()/1e3),c=new Map(s.map(e=>[e.hash,e]));return e.map(e=>{const s=t[e.hash],i=c.get(e.hash);let d=!0,p="";"unknown"!==r?"unknown"!==e.type&&e.type!==r?(d=!1,p=`${e.type} ≠ required ${r}`):p=e.type===r?"type matches":"type unknown — not ruled out":p="payload ambiguous — all types eligible";const u=!!(null==s?void 0:s.zero_hop),h=(null==s?void 0:s.last_seen)??0;let x=0;if(u&&h>0){const e=(o-h)/3600;x=50*Math.exp(-e/l)}let m=0;if(h>0){const e=(o-h)/3600;m=Math.exp(-e/a)}const g=20*m,f=!(!(null==s?void 0:s.latitude)||!(null==s?void 0:s.longitude)||0===s.latitude&&0===s.longitude),v=f?5:0,b=(null==i?void 0:i.advertCount)??0,y=Math.min(2*b,30),j=(null==i?void 0:i.forwarderPrefixes.size)??0,N=Math.min(3*j,15);let k=0;if(i&&i.totalForwarderObservations>0&&n.size>0){let e=0;for(const t of n)i.forwarderPrefixes.has(t)&&e++;k=e/n.size}const w=x+g+v+y+N;return{hash:e.hash,name:e.name,type:e.type,roleCompatible:d,roleReason:p,zeroHop:u,zeroHopScore:x,lastSeen:h,recencyScore:m,recencyPoints:g,hasGps:f,gpsScore:v,advertCount:b,advertScore:y,topoWidth:j,topoScore:N,affinity:k,total:w}}).sort((e,t)=>t.total-e.total)}(j,o,N,_,P,h.recencyDecayHours,h.zeroHopDecayHours),[j,o,N,_,P,h.recencyDecayHours,h.zeroHopDecayHours]),F=M.filter(e=>!e.roleCompatible),R=M.filter(e=>e.roleCompatible),A=s._advertSender?p.pubKeyMap.get(s._advertSender)??null:null,z=1===$.tier,E=[{fn:"src_hash",value:y||"",active:!!y,color:"blue"},{fn:"_advertSender",value:s._advertSender?s._advertSender.slice(0,12)+"…":"",active:!!s._advertSender,color:"blue"},{fn:"_advertNodeType",value:H?`0x${H}`:"",active:null!=s._advertNodeType,color:"blue"},{fn:"path_length",value:null!=L?0===L?"zero-hop":String(L):"",active:null!=L,color:"blue"},{fn:"decrypt.senderName",value:T??"",active:!!T,color:"teal"}],B=[{label:"hit",detail:"pubKeyMap.get(_advertSender) → definitive",active:!!A,color:"green"},{label:"miss",detail:s._advertSender?"pubkey not in neighbor table":"no _advertSender",active:!A,color:"zinc"}],O=[{label:"payload",detail:`inferDeviceType(0x${w}) → ${C}`,active:"unknown"!==C,color:"amber"},{label:"flags",detail:H?`mapAdvertTypeCode(0x${H}) → ${S}`:"no _advertNodeType",active:"unknown"===C&&"unknown"!==S,color:"green"},{label:"ambiguous",detail:"all types eligible",active:"unknown"===_,color:"zinc"}],V=`→ ${v.name??(null==(d=v.hash)?void 0:d.slice(0,12))??"?"} (${v.confident?"confident":"ambiguous"}, Tier ${$.tier})`;return t.jsx(ye,{stage:3,name:"RESOLVE",fn:"usePipelineStore.resolveSource()",verdict:V,timeMs:a,children:t.jsx(Z,{prefix:"resolvePacketSource",children:t.jsxs("div",{className:"space-y-0",children:[t.jsx("div",{className:"pt-1 pb-1",children:t.jsx(ve,{tokens:E,nextFn:"resolvePacketSource()"})}),s.src_hash?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"1"})," ","PUBKEY LOOKUP"]}),t.jsx(fe,{options:B,nextFn:"pubKeyMap.get()"}),t.jsx("div",{className:"ml-3 mt-1",children:A?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"resolved",children:t.jsx(se,{fn:"hash",value:A,color:"green"})}),l&&t.jsxs(Q,{label:"name",children:[t.jsx(se,{fn:"name",value:l,color:"green"}),v.name&&l===v.name&&t.jsx(ae,{c:"text-sys-green ml-1",children:"✓ neighbor match"})]}),t.jsxs(Q,{label:"result",children:[t.jsx(b,{color:"green",children:"Tier 1"}),t.jsx(ae,{c:"text-fg-primary ml-1",children:"definitive — scoring bypassed"})]})]}):s._advertSender?t.jsx(Q,{label:"status",children:t.jsx(ae,{c:"text-sys-amber",children:"✗ pubkey not in neighbor table"})}):t.jsx(Q,{label:"status",children:t.jsx(ae,{children:"no _advertSender — skip to prefix resolution"})})})]}),z?t.jsx("div",{className:"border-t border-edge-subtle py-2",children:t.jsx("p",{className:"text-[11px] text-fg-muted/40 font-mono ml-3",children:"Steps 2–5 bypassed — pubkey definitive"})}):t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"2"})," ","CANDIDATE POOL — ",j.length," node",1!==j.length?"s":"",' match "',y,'"']}),t.jsxs("div",{className:"space-y-0.5 ml-3",children:[M.map(e=>t.jsxs("div",{className:"flex gap-2 items-center text-[11px]",children:[t.jsx("span",{className:"break-all text-[10px]",children:e.hash}),t.jsx(b,{color:"zinc",children:e.type||"unknown"}),e.name&&t.jsx(ae,{children:e.name})]},e.hash)),0===j.length&&t.jsx(ae,{children:"no known nodes for this prefix"})]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"3"})," ","TYPE INFERENCE"]}),t.jsx(fe,{options:O,nextFn:"effectiveType()"}),t.jsx("div",{className:"ml-3 mt-1",children:t.jsx(Q,{label:"effective",children:t.jsx(se,{fn:"effectiveType",value:_,color:"unknown"!==_?"unknown"!==C?"amber":"green":"zinc"})})})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"4"})," ","ROLE-TYPE SCRUB"]}),t.jsx("div",{className:"space-y-0.5 ml-3",children:M.map(e=>t.jsxs("div",{className:"flex gap-2 items-center text-[11px]",children:[t.jsx("span",{className:e.roleCompatible?"text-sys-green":"text-sys-red",children:e.roleCompatible?"✓":"✗"}),t.jsx("span",{className:"break-all text-[10px] "+(e.roleCompatible?"":"line-through text-fg-muted"),children:e.hash}),t.jsx(b,{color:e.roleCompatible?"zinc":"red",children:e.type||"unknown"}),t.jsx(ae,{c:e.roleCompatible?"text-fg-muted":"text-sys-red",children:e.roleReason})]},e.hash))}),F.length>0&&t.jsxs("p",{className:"text-[10px] text-fg-muted mt-1 ml-3",children:[F.length," eliminated, ",R.length," surviving"]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"5"})," ","CANDIDATE SCORING"]}),0===R.length?t.jsx("p",{className:"text-fg-muted italic ml-3",children:"No surviving candidates"}):1===R.length?t.jsxs("div",{className:"ml-3 text-[11px]",children:[t.jsxs("div",{className:"flex gap-2 items-center",children:[t.jsx(ae,{c:"text-sys-green",children:"→"}),t.jsx("span",{className:"break-all text-[10px]",children:R[0].hash}),R[0].name&&t.jsx(ae,{c:"text-fg-muted ml-1",children:R[0].name})]}),t.jsx("p",{className:"text-fg-muted ml-4",children:"single survivor — scoring not needed"})]}):t.jsxs(x,{children:[t.jsx(m,{className:"text-[10px] ml-3",children:t.jsxs("span",{className:"font-mono text-fg-muted/50",children:[R.length," candidates scored…"]})}),t.jsx(g,{children:t.jsx("div",{className:"space-y-2 ml-3 mt-1",children:R.map(e=>{const s=e.hash===v.hash;return t.jsxs("div",{className:"text-[11px] leading-relaxed rounded px-2 py-1 "+(s?"bg-sys-green/8 border border-sys-green/20":"bg-zinc-500/5"),children:[t.jsxs("div",{className:"flex gap-2 items-center mb-0.5",children:[t.jsx(ae,{c:s?"text-sys-green":"text-fg-muted",children:s?"→":" "}),t.jsx("span",{className:"break-all text-[10px] "+(s?"text-fg-primary":"text-fg-muted"),children:e.hash}),t.jsx(b,{color:s?"green":"zinc",children:e.type||"unknown"}),e.name&&t.jsx(ae,{children:e.name})]}),t.jsxs("div",{className:"ml-4 flex flex-wrap gap-x-3 gap-y-0.5",children:[t.jsxs("span",{children:[t.jsx(ae,{children:"zero_hop:"})," ",t.jsx(ae,{c:e.zeroHop?"text-sys-green":"text-fg-muted",children:e.zeroHop?"✓":"✗"})," ",t.jsxs(b,{color:oe(e.zeroHopScore),children:["+",e.zeroHopScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"recency:"})," ",t.jsx(ae,{c:"text-fg-primary",children:ce(e.lastSeen)})," ",t.jsxs(b,{color:oe(e.recencyPoints),children:["+",e.recencyPoints.toFixed(1)]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"gps:"})," ",t.jsx(ae,{c:e.hasGps?"text-sys-green":"text-fg-muted",children:e.hasGps?"✓":"✗"})," ",t.jsxs(b,{color:oe(e.gpsScore),children:["+",e.gpsScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"adverts:"})," ",t.jsx(ae,{c:"text-fg-primary",children:e.advertCount})," ",t.jsxs(b,{color:oe(e.advertScore),children:["+",e.advertScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"topo:"})," ",t.jsx(ae,{c:"text-fg-primary",children:e.topoWidth})," ",t.jsxs(b,{color:oe(e.topoScore),children:["+",e.topoScore]})]})]}),t.jsxs("div",{className:"ml-4 mt-0.5",children:[t.jsx(ae,{children:"score ≈"})," ",t.jsx(ae,{c:"text-fg-primary font-bold",children:e.total.toFixed(1)})]})]},e.hash)})})})]})]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-green font-bold",children:"✓"})," ","RESOLUTION"]}),t.jsxs("div",{className:"ml-3",children:[t.jsx(Q,{label:"hash",children:v.hash?t.jsx(se,{fn:"resolved.hash",value:v.hash,color:"green"}):t.jsx(ae,{children:"null"})}),t.jsx(Q,{label:"type",children:t.jsx(se,{fn:"resolved.type",value:v.type,color:v.confident?"green":"zinc"})}),t.jsx(Q,{label:"name",children:v.name?t.jsx(se,{fn:"resolved.name",value:v.name,color:v.confident?"green":"amber"}):t.jsx(ae,{children:"null"})}),t.jsx(Q,{label:"confident",children:t.jsx(ae,{c:v.confident?"text-sys-green":"text-sys-red",children:String(v.confident)})}),t.jsxs(Q,{label:"tier",children:[t.jsx(b,{color:$.tier<=2?"green":3===$.tier?"amber":"red",children:$.tier}),t.jsx(ae,{c:"text-fg-primary ml-1",children:$.label})]})]})]})]}):t.jsx("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx(ae,{c:"text-sys-amber",children:"⚠ no src_hash"}),T&&t.jsx(se,{fn:"decrypt.senderName",value:T,color:"teal"}),v.confident?t.jsxs(ae,{c:"text-sys-green",children:["→ resolved via ",$.label]}):t.jsx(ae,{c:"text-sys-red",children:"ambiguous"})]})}),(()=>{const e=[{fn:"resolved.hash",value:v.hash??"null",group:"resolution",color:v.confident?"green":"zinc"},{fn:"resolved.type",value:v.type,group:"resolution",color:"unknown"!==v.type?v.confident?"green":"amber":"zinc"},{fn:"resolved.name",value:v.name??"null",group:"resolution",color:v.confident?"green":v.name?"amber":"zinc"},{fn:"resolved.confident",value:String(v.confident),group:"resolution",color:v.confident?"green":"red"}];return t.jsx(Y,{tokens:e})})()]})})})}const Be=[{id:"packet-parse",label:"Packet Parse",inputs:["rawPacket"],outputs:["parsedPacket","decoded","headerFields"],emits:[{fn:"routeType",group:"wire",color:"blue"},{fn:"payloadType",group:"wire",color:"blue"},{fn:"pathLength",group:"wire",color:"blue"},{fn:"version",group:"wire",color:"blue"}],async:!1,observatoryStage:0},{id:"enrichment",label:"Ingestion Enrichment",inputs:["parsedPacket"],outputs:["advertSender","channelHash","hopData","byteLength"],emits:[{fn:"_advertSender",group:"enrichment",color:"blue"},{fn:"_advertNodeType",group:"enrichment",color:"blue"},{fn:"_channelHash",group:"enrichment",color:"blue"},{fn:"_hopCount",group:"enrichment",color:"blue"},{fn:"_isZeroHop",group:"enrichment",color:"blue"},{fn:"_byteLength",group:"enrichment",color:"blue"}],async:!1,observatoryStage:1},{id:"topology",label:"Topology Analysis",inputs:["packets","neighbors","srcHashResolver"],outputs:["edges","nodeMetrics","pathHealth","ghostNodes","centrality","loops"],emits:[{fn:"edges",group:"worker",color:"green"},{fn:"ghostNodes",group:"worker",color:"purple"},{fn:"loops",group:"analysis",color:"amber"},{fn:"nodeMetrics",group:"worker",color:"green"},{fn:"pathHealth",group:"worker",color:"green"},{fn:"centrality",group:"worker",color:"green"}],async:!0,worker:"topology.worker.ts",observatoryStage:2},{id:"trace-enrichment",label:"Trace Link Quality",inputs:["packets","prefixLookup","srcHashResolver","edges","pathHealth","nodeMetrics"],outputs:["traceLinks","traceLinkSummary","traceDisambiguationFeedback"],emits:[{fn:"traceLinks.directed",group:"worker",color:"teal"},{fn:"traceLinks.bidir",group:"worker",color:"teal"},{fn:"traceSummary.meanSnr",group:"analysis",color:"green"},{fn:"traceSummary.medianSnr",group:"analysis",color:"zinc"},{fn:"traceSummary.confidence",group:"analysis",color:"zinc"},{fn:"feedback.confirmed",group:"worker",color:"teal"},{fn:"feedback.links",group:"worker",color:"teal"}],async:!1,observatoryStage:2},{id:"disambiguation",label:"Source Disambiguation",inputs:["packets","neighbors","decodedMessages"],outputs:["srcHashResolverMap","neighborContext"],emits:[{fn:"resolvedHash",group:"resolution",color:"purple"},{fn:"resolvedName",group:"resolution",color:"purple"},{fn:"resolvedType",group:"resolution",color:"purple"},{fn:"confidence",group:"resolution",color:"green"}],async:!1,observatoryStage:3},{id:"sparkline",label:"Sparkline Computation",inputs:["packets","neighbors"],outputs:["sparklineData"],emits:[{fn:"sparklines",group:"worker",color:"blue"}],async:!0,worker:"sparkline.worker.ts"},{id:"decryption",label:"Channel Decryption",inputs:["packets","channelKeys"],outputs:["decodedMessages"],emits:[{fn:"decrypt.text",group:"crypto",color:"teal"},{fn:"decrypt.senderName",group:"crypto",color:"teal"},{fn:"decrypt.channelName",group:"crypto",color:"teal"},{fn:"decrypt.macCorrupted",group:"crypto",color:"amber"}],async:!0,worker:"decryption.worker.ts",observatoryStage:2},{id:"decoded-content",label:"Decoded Content Policy",inputs:["decodedMessages","packets"],outputs:["decodedContent","contentInheritance"],emits:[{fn:"content.senderName",group:"crypto",color:"teal"},{fn:"content.text",group:"crypto",color:"teal"},{fn:"content.channelName",group:"crypto",color:"teal"},{fn:"content.corrupted",group:"crypto",color:"amber"},{fn:"content.inherited",group:"analysis",color:"purple"}],async:!1}],Oe=new Map(Be.map(e=>[e.id,e])),Ve=new Map;for(const pt of Be)for(const e of pt.emits)Ve.set(e.fn,pt);const Ie=new Map;for(const pt of Be)for(const e of pt.outputs)Ie.set(e,pt);const Ue={0:"text-sys-green",1:"text-sys-blue",2:"text-sys-teal",3:"text-sys-purple"};function qe({stage:e,isActive:s,onClick:r}){const n=null!=e.observatoryStage?Ue[e.observatoryStage]??"text-fg-muted":"text-fg-muted/40";return t.jsxs("button",{type:"button",onClick:r,className:`\n flex items-center gap-1.5 w-full px-1.5 py-1 rounded transition-base text-left\n ${s?"bg-sys-blue/10 ring-1 ring-sys-blue/30":"hover:bg-zinc-500/5"}\n `,children:[t.jsx("span",{className:`font-mono text-[9px] font-bold w-3 shrink-0 text-center ${n}`,children:e.observatoryStage??"·"}),t.jsx("span",{className:"font-mono text-[9px] text-fg-primary truncate flex-1",children:e.label}),e.async&&t.jsx("span",{className:"font-mono text-[7px] px-1 py-px rounded bg-sys-amber/15 text-sys-amber shrink-0 leading-tight",children:"⚡"}),e.emits.length>0&&t.jsxs("span",{className:"flex items-center gap-px shrink-0",children:[e.emits.slice(0,6).map(e=>{var s;return t.jsx("span",{className:`inline-block w-1 h-1 rounded-full ${(null==(s=W[e.color])?void 0:s.dot)??"bg-zinc-500"}`,title:`${e.fn} [${e.group}]`},e.fn)}),e.emits.length>6&&t.jsxs("span",{className:"font-mono text-[7px] text-fg-muted/40 ml-0.5",children:["+",e.emits.length-6]})]})]})}function Ge({activeStageId:s,onStageClick:r}){const n=e.useMemo(()=>function(){const e=new Map,t=new Map;for(const n of Be)e.has(n.id)||e.set(n.id,0),t.has(n.id)||t.set(n.id,new Set);for(const n of Be)for(const s of n.inputs){const r=Ie.get(s);if(r&&r.id!==n.id){const s=t.get(r.id);s.has(n.id)||(s.add(n.id),e.set(n.id,(e.get(n.id)??0)+1))}}const s=[];for(const[n,a]of e)0===a&&s.push(n);const r=[];for(;s.length>0;){const n=s.shift(),a=Oe.get(n);a&&r.push(a);for(const r of t.get(n)??[]){const t=(e.get(r)??1)-1;e.set(r,t),0===t&&s.push(r)}}for(const n of Be)r.includes(n)||r.push(n);return r}(),[]),a=e.useMemo(()=>{const e=new Map;for(const s of n){const t=s.observatoryStage??"other";let r=e.get(t);r||(r=[],e.set(t,r)),r.push(s)}const t=[];for(const s of[0,1,2,3,"other"]){const r=e.get(s);(null==r?void 0:r.length)&&t.push({key:s,stages:r})}return t},[n]);return t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-2",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[t.jsx("span",{className:"font-mono text-[8px] text-fg-muted/40 uppercase tracking-widest",children:"Pipeline DAG"}),t.jsxs("span",{className:"font-mono text-[8px] text-fg-muted/30",children:[n.length," stages"]})]}),t.jsx("div",{className:"space-y-px",children:a.map((e,n)=>t.jsxs("div",{children:[n>0&&t.jsx("div",{className:"flex items-center pl-2.5 py-px",children:t.jsx("svg",{width:"6",height:"8",viewBox:"0 0 6 8",className:"text-fg-muted/20",children:t.jsx("path",{d:"M3 0 L3 6 M1 4 L3 6 L5 4",fill:"none",stroke:"currentColor",strokeWidth:"1"})})}),e.stages.map(e=>t.jsx(qe,{stage:e,isActive:s===e.id,onClick:r?()=>r(e.id):void 0},e.id))]},String(e.key)))})]})}const Ke={status:"idle",lastDurationMs:null,lastTs:null,runCount:0};function We(e,t,s){var r,n,a;switch(e.type){case"transport:ws:state":t.wsState=(null==(r=e.data)?void 0:r.state)??s.wsState;break;case"transport:ws:packet":t.wsPacketCount=(t.wsPacketCount??s.wsPacketCount)+1;break;case"transport:ws:stats":t.wsStatsCount=(t.wsStatsCount??s.wsStatsCount)+1;break;case"transport:rest:stats":t.restStatsCount=(t.restStatsCount??s.restStatsCount)+1;break;case"transport:rest:packets":t.restPacketsCount=(t.restPacketsCount??s.restPacketsCount)+1;break;case"store:packets:ws-merge":t.wsMergeCount=(t.wsMergeCount??s.wsMergeCount)+1;break;case"cascade:hydrate":t.lastHydrateTs=e.ts,t.hydrateCount=(t.hydrateCount??s.hydrateCount)+1;break;case"worker:topology:start":case"worker:sparkline:start":{const r=e.type.split(":")[1],n=t.workers??s.workers,a=n[r]??{...Ke};t.workers={...n,[r]:{...a,status:"running",lastTs:e.ts}}}break;case"worker:topology:done":case"worker:sparkline:done":{const r=e.type.split(":")[1],a=t.workers??s.workers,l=a[r]??{...Ke},o=(null==(n=e.data)?void 0:n.ms)??null;t.workers={...a,[r]:{...l,status:"done",lastDurationMs:o,lastTs:e.ts,runCount:l.runCount+1}}}break;case"worker:decryption:batch":{const r=t.workers??s.workers,n=r.decryption??{...Ke},l=(null==(a=e.data)?void 0:a.ms)??null;t.workers={...r,decryption:{...n,status:"done",lastDurationMs:l,lastTs:e.ts,runCount:n.runCount+1}}}break;case"pipeline:disambig:recompute":t.disambigCount=(t.disambigCount??s.disambigCount)+1}}const Ze=pe(e=>({events:[],eventCount:0,wsState:"disconnected",wsPacketCount:0,wsStatsCount:0,restStatsCount:0,restPacketsCount:0,workers:{topology:{...Ke},sparkline:{...Ke},decryption:{...Ke}},wsMergeCount:0,lastHydrateTs:null,hydrateCount:0,disambigCount:0,lastDisambigMs:null,_pushBatch:t=>e(e=>{if(0===t.length)return e;let s=[...e.events,...t];s.length>200&&(s=s.slice(s.length-200));const r={events:s,eventCount:e.eventCount+t.length};for(const n of t)We(n,r,e);return r}),clear:()=>e({events:[],eventCount:0,wsState:"disconnected",wsPacketCount:0,wsStatsCount:0,restStatsCount:0,restPacketsCount:0,workers:{topology:{...Ke},sparkline:{...Ke},decryption:{...Ke}},wsMergeCount:0,lastHydrateTs:null,hydrateCount:0,disambigCount:0,lastDisambigMs:null})}));let Ye=null,Xe=[],Qe=null;function Je(){if(Qe=null,0===Xe.length)return;const e=Xe;Xe=[],Ze.getState()._pushBatch(e)}function et(e){switch(e){case"active":return"●";case"skipped":return"○";case"inferred":return"◌"}}function tt(e){switch(e){case"active":return"text-sys-green";case"skipped":return"text-fg-muted/30";case"inferred":return"text-sys-amber"}}function st(e){switch(e){case"transport":return"text-sys-blue";case"store":return"text-sys-amber";case"worker":return"text-sys-violet";case"pipeline":return"text-sys-green";case"consumer":return"text-sys-teal"}}const rt=[],nt=["transport","store","worker","pipeline","consumer"],at={transport:"Transport",store:"Store",worker:"Workers",pipeline:"Pipeline",consumer:"Consumers"};function lt(e){return e.replace("transport:","").replace("store:packets:","").replace("cascade:","").replace("worker:","w:").replace("pipeline:","p:").replace("packet","pkt").replace("sparkline","spark").replace("topology","topo").replace("decryption","dec").replace("disambig","dis").replace("recompute","recomp")}const ot=e.memo(function({event:e}){const s=`${(e.ts/1e3).toFixed(1)}s`,r=e.data?Object.entries(e.data).map(([e,t])=>{var s;return`${e}=${"number"==typeof t?(null==(s=t.toFixed)?void 0:s.call(t,1))??t:t}`}).join(" "):"";return t.jsxs("div",{className:"flex gap-2 text-[9px] font-mono leading-tight",children:[t.jsx("span",{className:"text-fg-muted/40 w-12 shrink-0 text-right",children:s}),t.jsx("span",{className:"w-20 shrink-0 "+(n=e.type,n.startsWith("transport:")?"text-sys-blue":n.startsWith("store:")||n.startsWith("cascade:")?"text-sys-amber":n.startsWith("worker:")?"text-sys-violet":n.startsWith("pipeline:")?"text-sys-green":"text-fg-muted"),children:lt(e.type)}),t.jsx("span",{className:"text-fg-muted/60 truncate",children:r})]});var n});function ct({packet:s,pipeline:r,resolved:n,decrypted:a,isSynthetic:l,liveMode:o}){const[c,i]=e.useState(!1);e.useEffect(()=>{if(c)return Ye||(Xe=[],Ye=F.subscribe(e=>{Xe.push(e),null===Qe&&(Qe=requestAnimationFrame(Je))})),()=>{!function(){if(null==Ye||Ye(),Ye=null,null!==Qe&&(cancelAnimationFrame(Qe),Qe=null),Xe.length>0){const e=Xe;Xe=[],Ze.getState()._pushBatch(e)}}()}},[c]);const d=null==r?void 0:r.analysis,p=e.useMemo(()=>s&&d?function(e,t,s,r,n){var a,l;const o=[];if(n?o.push({label:"Hex Input",detail:"Manual hex — no transport",status:"skipped",lane:"transport"}):"live"===t.age||"recent"===t.age?o.push({label:"WebSocket",detail:"ws:packet → real-time push",status:"active",lane:"transport"}):o.push({label:"REST Poll",detail:"fetchPackets → packetCache.poll()",status:"inferred",lane:"transport"}),!n){o.push({label:"Cache Merge",detail:"packetCache.mergePacketsDirectly()",status:"active",lane:"store"});const e="live"===t.age||"recent"===t.age;o.push({label:"Flash",detail:e?"flashReceived++ → sidebar blink":"Not newest — no flash",status:e?"active":"skipped",lane:"store"}),o.push({label:"Hydrate Cascade",detail:"hydrateDownstream() → schedule workers",status:"active",lane:"store"})}const c=t.pathAvail||t.pathHopCount>0;o.push({label:"Topology Worker",detail:c?`Path data (${t.pathHopCount} hops) → edge extraction`:"No path data — still included in batch recompute",status:"active",lane:"worker"}),o.push({label:"Sparkline Worker",detail:`Contributes to sparkline for src ${(null==(a=e.src_hash)?void 0:a.slice(0,4))??"??"}`,status:"active",lane:"worker"});const i=t.isGrp;o.push({label:"Decryption Worker",detail:i?"GRP_TXT → queued for channel key search"+(r?" → decrypted ✓":""):`${t.payloadTypeName} — not encrypted, skipped`,status:i?"active":"skipped",lane:"worker"}),o.push({label:"Source Disambiguation",detail:s?`→ ${s.name??(null==(l=s.hash)?void 0:l.slice(0,8))??"?"} (${s.type}${s.confident?", confident":", ambiguous"})`:"Pending recompute",status:s?"active":"inferred",lane:"pipeline"}),t.isAdvert&&o.push({label:"ADVERT Discovery",detail:"pubkey → extended hash-to-type + name extraction",status:"active",lane:"pipeline"}),i&&(null==r?void 0:r.decoded)&&o.push({label:"Decoded Content Policy",detail:`macCorrupted=${r.decoded.macCorrupted?"true":"false"} → cross-hash inheritance`,status:"active",lane:"pipeline"});const d=["Packets","Dashboard","Statistics"];return c&&d.push("Map","Graph"),t.isTrace&&d.push("Trace Detail"),o.push({label:"Page Hydration",detail:d.join(", "),status:"active",lane:"consumer"}),o}(s,d,n,a,l):null,[s,d,n,a,l]),u=e.useMemo(()=>{if(!p)return null;const e=new Map;for(const t of p){let s=e.get(t.lane);s||(s=[],e.set(t.lane,s)),s.push(t)}return e},[p]),h=Ze(e=>c?e.events:rt),f=Ze(e=>c?e.eventCount:0),v=Ze(e=>e.clear),b=e.useRef(null);e.useEffect(()=>{c&&b.current&&(b.current.scrollTop=b.current.scrollHeight)},[f,c]);const y=(null==p?void 0:p.filter(e=>"active"===e.status).length)??0,j=(null==p?void 0:p.length)??0;return t.jsxs(x,{defaultOpen:!0,children:[t.jsx(m,{className:"text-[10px]",children:t.jsxs("span",{className:"flex items-center gap-2 font-mono",children:[t.jsx("span",{className:"text-sys-green",children:"CFT"}),t.jsx("span",{className:"text-fg-muted/40",children:"Control Flow Trace"}),s&&t.jsxs("span",{className:"text-fg-muted/30",children:["— ",y,"/",j," stages active"]})]})}),t.jsx(g,{children:t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3 space-y-3",children:[s?u?t.jsx("div",{className:"space-y-2",children:nt.map(e=>{const s=u.get(e);return s?t.jsxs("div",{children:[t.jsx("div",{className:`text-[8px] uppercase tracking-widest font-mono mb-0.5 ${st(e)}`,children:at[e]}),s.map((e,s)=>t.jsxs("div",{className:"flex items-start gap-1.5 text-[10px] font-mono leading-snug ml-1",children:[t.jsx("span",{className:`shrink-0 ${tt(e.status)}`,children:et(e.status)}),t.jsx("span",{className:"text-fg-primary",children:e.label}),t.jsx("span",{className:"text-fg-muted/50 truncate",children:e.detail})]},s))]},e):null})}):null:t.jsx("div",{className:"text-[9px] text-fg-muted/30 font-mono py-2 text-center",children:"Select a packet to trace its flow"}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 flex items-center gap-2",children:[t.jsx("button",{onClick:()=>i(e=>!e),className:"px-2 py-0.5 rounded text-[9px] font-mono transition-colors "+(c?"bg-sys-green/20 text-sys-green":"bg-zinc-500/20 text-fg-muted hover:text-fg-primary"),children:c?"● LIVE":"○ LIVE"}),t.jsx("span",{className:"text-[9px] text-fg-muted/40 font-mono",children:c?`${f} events`:"Subscribe to all pipeline events"}),c&&t.jsx("button",{onClick:v,className:"text-[9px] text-fg-muted/40 hover:text-fg-muted font-mono transition-colors ml-auto",children:"clear"})]}),c&&t.jsx("div",{ref:b,className:"max-h-32 overflow-y-auto space-y-px",children:0===h.length?t.jsx("div",{className:"text-[9px] text-fg-muted/30 font-mono py-1 text-center",children:"Waiting for events…"}):h.map((e,s)=>t.jsx(ot,{event:e},`${e.ts}-${s}`))})]})})]})}function it(e){const t=u(e.type??e.payload_type??-1).padEnd(7),s=e.packet_hash.slice(0,8),r=(e.src_hash??"—").replace(/^0x/i,"").slice(0,4).toUpperCase(),n=null!=e._hopCount?`${e._hopCount}h`:"",a=B(e.timestamp);return`${s} ${t} ←${r} ${e.rssi}dBm ${n} ${a}`}function dt(){const s=R(),r=A(),n=z(),a=(null==r?void 0:r.neighbors)??{},l=I(e=>e.resolveSource),o=I(e=>e.config),c=I(e=>e.setConfig),[i,d]=e.useState(-1),p=e.useMemo(()=>{let e=s;return-1!==i&&(e=s.filter(e=>(e.type??e.payload_type)===i)),e.slice(-50).reverse()},[s,i]),[u,h]=e.useState(""),[f,v]=e.useState(""),[b,y]=e.useState(!1),N=e.useRef(n);e.useEffect(()=>{b&&n!==N.current&&p.length>0&&(h(p[0].packet_hash),v("")),N.current=n},[n,b,p]),e.useEffect(()=>{!u&&p.length>0&&!f&&h(p[0].packet_hash)},[u,p,f]);const k=e.useMemo(()=>f.trim()?null:p.find(e=>e.packet_hash===u)??null,[u,p,f]),w=e.useMemo(()=>{const e=f.replace(/\s+/g,"").trim();return e?{packet_hash:"manual-hex-input",timestamp:0,rssi:0,snr:0,transmitted:!1,drop_reason:null,is_duplicate:!1,raw_packet:e}:null},[f]),C=k??w,S=!!f.trim(),_=f.trim().replace(/\s+/g,"")||(null==C?void 0:C.raw_packet),H=ge(C,_,s),T=(null==H?void 0:H.enrichment)??xe,$=j((null==C?void 0:C.packet_hash)??""),P=e.useRef(0),L=e.useMemo(()=>{if(!C)return null;const e=performance.now(),t=l(C);return P.current=performance.now()-e,t},[C,l]);return t.jsxs("div",{className:"max-w-[960px] mx-auto",children:[t.jsxs("div",{className:"mb-3",children:[t.jsx("h1",{className:"text-sm font-bold text-fg-primary tracking-wide font-mono",children:"PACKET OBSERVATORY"}),t.jsx("p",{className:"text-[11px] text-fg-muted font-mono",children:"Pipeline introspection — select a packet to trace its journey"})]}),t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3 mb-3",children:[t.jsxs("div",{className:"flex gap-2 items-center flex-wrap",children:[t.jsxs("select",{value:i,onChange:e=>{d(Number(e.target.value)),h("")},className:"surface-input px-2 py-1 rounded text-[11px] font-mono text-fg-primary w-36",children:[t.jsx("option",{value:-1,children:"ALL TYPES"}),Object.entries(E).map(([e,s])=>t.jsxs("option",{value:Number(e),children:["0x",Number(e).toString(16).toUpperCase().padStart(2,"0")," ",s]},e))]}),t.jsxs("select",{value:u,onChange:e=>{h(e.target.value),v("")},className:"surface-input flex-1 min-w-0 px-2 py-1 rounded text-[11px] font-mono text-fg-primary truncate",children:[p.map((e,s)=>t.jsx("option",{value:e.packet_hash,children:it(e)},`${e.packet_hash}-${s}`)),0===p.length&&t.jsxs("option",{value:"",children:["No packets",-1!==i?" matching filter":" loaded"]})]}),t.jsx("button",{onClick:()=>y(e=>!e),className:"px-2 py-1 rounded text-[11px] font-mono transition-colors shrink-0 "+(b?"bg-sys-green/20 text-sys-green":"bg-zinc-500/20 text-fg-muted hover:text-fg-primary"),children:b?"● LIVE":"○ LIVE"})]}),t.jsxs(x,{children:[t.jsx(m,{className:"text-[10px] text-fg-muted/50 hover:text-fg-muted mt-1.5",children:t.jsx("span",{className:"font-mono",children:"Paste hex…"})}),t.jsx(g,{children:t.jsx("textarea",{value:f,onChange:e=>v(e.target.value),placeholder:"Paste raw packet hex (overrides dropdown)",rows:2,className:"surface-input w-full mt-1 px-2 py-1 rounded text-[11px] font-mono text-fg-primary resize-y"})})]})]}),t.jsxs(x,{children:[t.jsx(m,{className:"text-[11px] mb-3 w-full",children:t.jsxs("span",{className:"flex items-center gap-2 font-mono",children:[t.jsx("span",{className:"text-fg-muted/50",children:"⚙"}),t.jsx("span",{className:"text-fg-muted/50",children:"Pipeline Config & Dev Tools"}),t.jsxs("span",{className:"text-fg-muted/30 text-[10px]",children:["disambig=",o.disambiguationEnabled?"on":"off"," mac=",o.macCorruptedPolicy," decay=",o.recencyDecayHours,"h"]})]})}),t.jsx(g,{children:t.jsxs("div",{className:"space-y-3 mb-4",children:[t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3",children:[t.jsx("h2",{className:"text-[10px] text-fg-muted/50 uppercase tracking-widest font-mono mb-2",children:"Pipeline Config"}),t.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1.5",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Disambiguation"}),t.jsx("button",{onClick:()=>c({disambiguationEnabled:!o.disambiguationEnabled}),className:"px-2 py-0.5 rounded text-[11px] font-mono transition-colors "+(o.disambiguationEnabled?"bg-sys-green/20 text-sys-green":"bg-sys-red/20 text-sys-red"),children:o.disambiguationEnabled?"● ON":"○ OFF"})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"MAC policy"}),t.jsxs("select",{value:o.macCorruptedPolicy,onChange:e=>c({macCorruptedPolicy:e.target.value}),className:"surface-input px-1.5 py-0.5 rounded text-[11px] font-mono text-fg-primary",children:[t.jsx("option",{value:"strict",children:"strict (drop)"}),t.jsx("option",{value:"name-only",children:"name-only"}),t.jsx("option",{value:"permissive",children:"permissive"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Recency decay"}),t.jsx("input",{type:"range",min:1,max:48,step:1,value:o.recencyDecayHours,onChange:e=>c({recencyDecayHours:Number(e.target.value)}),className:"flex-1 h-1 accent-sys-blue"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-primary w-8 text-right",children:[o.recencyDecayHours,"h"]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Zero-hop decay"}),t.jsx("input",{type:"range",min:12,max:168,step:6,value:o.zeroHopDecayHours,onChange:e=>c({zeroHopDecayHours:Number(e.target.value)}),className:"flex-1 h-1 accent-sys-blue"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-primary w-10 text-right",children:[o.zeroHopDecayHours,"h"]})]})]})]}),t.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[t.jsx(ct,{packet:C,pipeline:H,resolved:L,decrypted:$??null,isSynthetic:S,liveMode:b}),t.jsx(Ge,{})]})]})})]}),C?t.jsxs("div",{className:"space-y-1",children:[t.jsx(Ne,{packet:C,isSynthetic:S}),t.jsx(Pe,{packet:C,pipeline:H,rawHex:_,traceTagIndex:(null==H?void 0:H.traceTagIndex)??new Map,neighbors:a}),t.jsx(ze,{packet:C,decrypted:$??void 0,pipeline:H}),t.jsx(Ee,{packet:C,pipeline:H,resolved:L,decrypted:$??void 0,resolveTimeMs:P.current,neighbors:a,advertName:T.advertName})]}):t.jsx("div",{className:"surface-base rounded-lg border border-edge-subtle p-8 text-center",children:t.jsx("p",{className:"text-fg-muted text-xs",children:"Select a packet from the dropdown or paste hex above"})})]})}export{dt as default}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/usePipelineStore-CLEA3Bev.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/node-types-DRVunROD.js","assets/index-CkRTgHHA.js","assets/vendor-charts-C916_-gs.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/geo-utils-DJn8DnxF.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-BawBpZYt.css"])))=>i.map(i=>d[i]); +import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{ar as s,c2 as r,c3 as n,c4 as a,c5 as l,a8 as o,c6 as c,c7 as i,c8 as d,c9 as p,a7 as u,ca as h,cb as x,cc as m,cd as g,bL as f,ce as v,h as b,af as y,ao as j,av as N,cf as k,cg as w,ch as C,ci as S,cj as _,ck as H,cl as T,cm as $,cn as P,co as L,M,H as D,cp as F,m as R,p as A,cq as z,a3 as E,bc as B}from"./index-CkRTgHHA.js";import{b as O,r as V,c as I}from"./usePipelineStore-CLEA3Bev.js";import{_ as U}from"./cosmograph-DqYT4sUA.js";import{e as q,p as G,a as K,A as W,S as Z,c as Y,f as X,K as Q,H as J,B as ee,R as te,T as se,P as re,h as ne,i as ae,C as le,s as oe,j as ce}from"./primitives-Bgn6Ik6L.js";import{m as ie,i as de}from"./node-types-DRVunROD.js";import{a as pe}from"./vendor-core-FtpmsTnh.js";import"./vendor-virt-BytWoLhu.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";import"./geo-utils-DJn8DnxF.js";import"./payload-decoders-_TRhCJrs.js";let ue=null,he=null;"undefined"!=typeof window&&setTimeout(()=>{U(()=>import("./usePipelineStore-CLEA3Bev.js").then(e=>e.d),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])).then(e=>{ue=e}),U(()=>import("./index-CkRTgHHA.js").then(e=>e.dv),__vite__mapDeps([2,7,12,13,14])).then(e=>{he=e})},0);const xe={advertSender:null,advertNodeType:null,advertFlags:null,advertHasLocation:null,advertHasName:null,advertName:null,advertLatitude:null,advertLongitude:null,channelHash:null,byteLength:void 0,hopCount:0,isZeroHop:!0,preComputed:!1};function me(e,t,s,r,n){if(0===t){const a=null==r?void 0:r.get(e);if(a)return{hash:a,confidence:.8};if(n){const r=V(n,e,{position:t,adjacentPrefixes:s});if(r.hash)return{hash:r.hash,confidence:r.confidence}}}else{if(n){const r=V(n,e,{position:t,adjacentPrefixes:s});if(r.hash)return{hash:r.hash,confidence:r.confidence}}const a=null==r?void 0:r.get(e);if(a)return{hash:a,confidence:.6}}return{hash:null,confidence:0}}function ge(t,x,m){const g=e.useRef({parse:0,decode:0,enrich:0,traceIndex:0,total:0}),f=e.useMemo(()=>t?function(e){var t;const s=e.raw_packet;if(!s||s.length<2)return null;const r=s.replace(/\s/g,""),n=Math.floor(r.length/2),a=(null==(t=r.match(/.{1,2}/g))?void 0:t.join(" "))??"";let l="";for(let o=0;o=32&&e<=126?String.fromCharCode(e):"·"}return{hexBytes:a,utf8:l,byteCount:n}}(t):null,[t]),v=e.useMemo(()=>{if(!x||x.length<4)return g.current.parse=0,g.current.decode=0,null;const e=performance.now(),t=G(x),s=performance.now()-e;return t?(g.current.parse=s,g.current.decode=0,{protocolPacket:t.packet,display:{headerFields:t.headerFields,transportCodesHex:t.transportCodesHex,pathLengthHex:t.pathLengthHex,pathDataHex:t.pathDataHex,payloadHex:t.payloadHex,payloadByteOffset:t.payloadStartByte,pathByteOffset:t.pathByteOffset,pathLenByteOffset:t.pathLenByteOffset},decoded:t.decoded,error:null}):(g.current.parse=s,g.current.decode=0,{protocolPacket:null,display:null,decoded:null,error:"Packet.fromHex() returned failure"})},[x]),b=e.useMemo(()=>{if(!t)return g.current.enrich=0,xe;const e=performance.now();if(void 0!==t._advertSender)return g.current.enrich=performance.now()-e,{advertSender:t._advertSender??null,advertNodeType:t._advertNodeType??null,advertFlags:t._advertFlags??null,advertHasLocation:t._advertHasLocation??null,advertHasName:t._advertHasName??null,advertName:t._advertName??null,advertLatitude:t._advertLatitude??null,advertLongitude:t._advertLongitude??null,channelHash:t._channelHash??null,byteLength:t._byteLength,hopCount:t._hopCount??0,isZeroHop:t._isZeroHop??!0,preComputed:!0};const s=t.type??t.payload_type,o=r(x,s),c=n(x,s),i=a(x,t),d=l(t);return g.current.enrich=performance.now()-e,{...o,channelHash:c,byteLength:i,...d,preComputed:!1}},[t,x]),y=e.useRef({fingerprint:"",index:new Map}),j=e.useMemo(()=>{const e=performance.now(),{index:t,fingerprint:r}=function(e){const t=new Map;let r=0,n="";for(const a of e){if((a.type??a.payload_type)!==s.TRACE)continue;r++,n=a.packet_hash;const e=a._traceTag??(a.payload?q(a.payload):null);if(!e)continue;let l=t.get(e);l||(l=[],t.set(e,l)),l.push(a)}return{index:t,fingerprint:`${r}:${n}`}}(m);return g.current.traceIndex=performance.now()-e,r===y.current.fingerprint?y.current.index:(y.current={fingerprint:r,index:t},t)},[m]),N=e.useMemo(()=>{const e=g.current;return{parse:e.parse,decode:e.decode,enrich:e.enrich,traceIndex:e.traceIndex,total:e.parse+e.decode+e.enrich+e.traceIndex}},[v,b,j]);if(!t)return null;const k=x?v?v.error:"rawHex too short":"No raw_packet (warm-tier)",w=(null==v?void 0:v.protocolPacket)??null,C=w?w.payloadVersion:null,S=0===C,_=1===C,H=function(e,t){const r=e.type??e.payload_type,n=u(r),a=o(e.route),l=r===s.ADVERT,h=r===s.TRACE,x=r===s.PATH,m=r===s.GRP_TXT||r===s.GRP_DATA,g=c(e.snr,e.rssi),f=(null==g?void 0:g.finalGrade)??"critical",v=i(e.route),b=d(e.route),y=p(e.route),j=null==e.route?"unknown":v?"flood":b?"direct":"unknown",N=y?`transport-${j}`:j,k=!!t.advertSender;let w="none";k?w="pubkey":m?w="encrypted":e.src_hash&&(w="prefix");const C=de(r),S=null!=t.advertNodeType?ie(t.advertNodeType):"unknown",_="unknown"!==C?C:S,H=e.packet_origin??"rx",T=Math.floor(Date.now()/1e3)-e.timestamp,$=T<10?"live":T<300?"recent":T<3600?"warm":T<86400?"stale":"historic",P=e.path_length??(Array.isArray(e.original_path)?e.original_path.length:void 0),L=Array.isArray(e.original_path)&&e.original_path.length>0,M=P??0,D=t.byteLength??(e.raw_packet?Math.floor(e.raw_packet.length/2):0),F=function(e){const t=e.type??e.payload_type,r=e.duplicates??[],n=e.is_duplicate,a=r.length;let l=null,o=null;if(a>0){const t=[e.rssi,...r.map(e=>e.rssi).filter(e=>null!=e)],s=[e.snr,...r.map(e=>e.snr).filter(e=>null!=e)];t.length>1&&(l=[Math.min(...t),Math.max(...t)]),s.length>1&&(o=[Math.min(...s),Math.max(...s)])}return{isDuplicate:n,dupeCount:a,rssiRange:l,snrRange:o,hashIncludesPathLen:t===s.TRACE}}(e);return{pType:r,payloadTypeName:n,routeTypeName:a,isAdvert:l,isTrace:h,isPath:x,isGrp:m,signalClass:f,routeClass:N,isFlood:v,isDirect:b,hasTransport:y,senderTier:w,hasPubkey:k,inferredType:C,advertType:S,effectiveType:_,origin:H,age:$,pathLen:P,pathAvail:L,pathHopCount:M,byteLen:D,dupeAnalysis:F}}(t,b);let T=null;return H.isTrace&&(T=function(e){var t,s,r,n,a,l;const o=K(e);if(!o||0===o.pathHashes.length)return null;const{pathHashes:c,snrValues:i}=o;if(c.length<2)return null;if(!ue||!he)return null;const d=ue.usePipelineStore.getState().srcHashResolverMap,p=ue.usePipelineStore.getState().neighborContext,u=(null==p?void 0:p.hashToName)??new Map,x=he.useStore.getState().stats,m=(null==x?void 0:x.neighbors)??{},g=null==x?void 0:x.local_hash,f=null==(s=null==(t=null==x?void 0:x.config)?void 0:t.repeater)?void 0:s.latitude,v=null==(n=null==(r=null==x?void 0:x.config)?void 0:r.repeater)?void 0:n.longitude,b=Object.keys(m).length>0?O([],m,g,f,v):null,y=[];for(let j=0;j0?[c[j-1].toUpperCase()]:[]],d,b),n=me(t,j+1,[e,...j+20?y:null}(t)),{wire:f,display:(null==v?void 0:v.display)??null,parseError:k,protocolPacket:w,decoded:(null==v?void 0:v.decoded)??null,payloadVersion:C,isV1:S,isV2:_,enrichment:b,traceTagIndex:j,analysis:H,traceHopDetail:T,timing:N}}function fe({options:e,nextFn:s}){var r;const n=e.find(e=>e.active),a=(null==n?void 0:n.color)??"green",l=(null==(r=W[a])?void 0:r.stem)??"bg-edge-subtle";return t.jsxs("div",{className:"flex flex-col items-start py-1 gap-0 px-2",children:[t.jsx("div",{className:`w-px h-2 ml-4 ${l}`}),t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-md overflow-hidden w-full",children:[e.map((e,s)=>{const r=W[e.color??"green"]??W.green;return t.jsxs("div",{className:`flex items-center gap-1.5 px-2 py-px font-mono text-[10px] leading-relaxed transition-opacity ${e.active?r.row:"opacity-25"}`,children:[t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${e.active?r.dot:"border border-zinc-500/40"}`}),t.jsx("span",{className:"w-16 shrink-0 font-medium "+(e.active?"text-fg-primary":"text-fg-muted"),children:e.label}),e.detail&&t.jsx("span",{className:e.active?"text-fg-primary/70":"text-fg-muted",children:e.detail})]},s)}),s&&t.jsx("div",{className:"flex items-center px-2 py-0.5 border-t border-edge-subtle",children:t.jsxs("span",{className:"text-[10px] text-fg-muted font-mono",children:["→ ",s]})})]}),t.jsx("div",{className:`w-px h-2 ml-4 ${l}`})]})}function ve({tokens:e,nextFn:s}){var r;const n=e.find(e=>e.active),a=(null==n?void 0:n.color)??"green",l=(null==(r=W[a])?void 0:r.stem)??"bg-edge-subtle";return t.jsxs("div",{className:"flex flex-col items-start py-1 gap-0 px-2",children:[t.jsx("div",{className:`w-px h-2 ml-4 ${l}`}),t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-md overflow-hidden w-full",children:[e.map((e,s)=>{const r=W[e.color??"green"]??W.green;return t.jsxs("div",{className:`flex items-center gap-1 px-2 py-px font-mono text-[10px] leading-relaxed transition-opacity ${e.active?r.row:"opacity-25"}`,children:[t.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${e.active?r.dot:"border border-zinc-500/40"}`}),t.jsx("span",{className:"text-fg-muted shrink-0",children:e.fn}),t.jsxs("span",{className:e.active?"text-fg-primary":"text-fg-muted",children:["(",e.value??"",")"]})]},s)}),s&&t.jsx("div",{className:"flex items-center px-2 py-0.5 border-t border-edge-subtle",children:t.jsxs("span",{className:"text-[10px] text-fg-muted font-mono",children:["→ ",s]})})]}),t.jsx("div",{className:`w-px h-2 ml-4 ${l}`})]})}const be={0:"border-l-sys-green",1:"border-l-sys-blue",2:"border-l-sys-teal",3:"border-l-sys-purple"};function ye({stage:e,name:s,fn:r,verdict:n,timeMs:a,skipped:l,skipReason:o,children:c}){const i=be[e]??"";return t.jsx(t.Fragment,{children:t.jsx(x,{defaultOpen:!l,children:t.jsxs("div",{className:`surface-base rounded-lg border border-edge-subtle overflow-hidden border-l-2 ${i}`,children:[t.jsxs(m,{className:"px-3 py-2 w-full",children:[t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsx("span",{className:"font-mono text-xs font-bold text-sys-blue shrink-0",children:e}),t.jsx("span",{className:"font-mono text-xs font-medium text-fg-primary truncate",children:s}),r&&!n&&t.jsx("span",{className:"font-mono text-[11px] text-fg-muted truncate hidden sm:inline",children:r}),n&&t.jsx("span",{className:"font-mono text-[11px] text-fg-muted/70 truncate hidden sm:inline",children:n})]}),t.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[l&&t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-zinc-500/20 text-fg-muted",children:"N/A"}),null!=a&&!l&&t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:a<1?`${(1e3*a).toFixed(0)}µs`:`${a.toFixed(2)}ms`})]})]}),t.jsx(g,{children:t.jsx("div",{className:"px-3 pb-3 font-mono text-xs",children:l?t.jsx("p",{className:"text-fg-muted italic",children:o??"Not applicable for this packet type"}):c})})]})})})}const je={connected:"green",degraded:"amber",offline:"red"};function Ne({packet:e,isSynthetic:s}){const r=f(e=>e.wsState),n=f(e=>e.health),a=function(e,t){return t?"manual":e._stripped?"bulk-tier":v.isConnected()?"ws-push":"rest-poll"}(e,s),l=[{label:"ws-push",detail:"wsConnected && onPacket()",active:"ws-push"===a,color:"green"},{label:"rest-poll",detail:"!wsConnected, 3s interval",active:"rest-poll"===a,color:"amber"},{label:"catchup",detail:"wsReconnected, delta > 50",active:"catchup"===a,color:"amber"},{label:"bulk-tier",detail:"user extends time range → gzip",active:"bulk-tier"===a,color:"blue"},{label:"manual",detail:"hex input — no transport",active:"manual"===a,color:"zinc"}],o=[{fn:"transport",value:a,group:"transport",color:"ws-push"===a?"green":"bulk-tier"===a?"blue":"amber"},{fn:"tier",value:e._stripped?"WARM":"HOT",group:"transport",color:"blue"},{fn:"wsState",value:r,group:"transport",color:"connected"===r?"green":"amber"},{fn:"health",value:n,group:"transport",color:je[n]}],c=s?"manual hex input":`${a} (${n})`;return t.jsx(ye,{stage:0,name:"TRANSPORT",fn:"websocketService / useStore.startPolling",verdict:c,children:s?t.jsx("p",{className:"text-fg-muted italic",children:"Manual hex input — no transport context"}):t.jsx(Z,{prefix:"transport",children:t.jsxs("div",{className:"space-y-0",children:[t.jsx(fe,{options:l,nextFn:"ingest()"}),t.jsx(Y,{tokens:o})]})})})}function ke({start:e,end:s}){const r=null!=s&&s!==e?`[${e}..${s}]`:`[${e}]`;return t.jsx("span",{className:"text-fg-muted text-[9px] font-mono mr-1 select-none",children:r})}const we={advert:"decodeAdvert()",ack:"decodeAck()",path:"decodePath()",trace:"decodeTraceWithSnr()",txt_msg:"decodeTextMessage()",grp_txt:"decodeGroupText()",grp_data:"decodeGroupData()",multipart:"decodeMultipart()",control:"decodeControl()",req:"decodeRequest()",response:"decodeResponse()",anon_req:"decodeAnonReq()",generic:"decodeGeneric()"};function Ce({rawHex:e,display:s,protocolPacket:r,parseError:n,parseTimeMs:a,payloadVersion:l,isV1:o,isV2:c}){return t.jsx("dl",{className:"space-y-0.5",children:s&&r&&e?t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"A. Parse — Packet.fromHex()"}),a>0&&t.jsx("div",{className:"flex justify-end",children:t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:a<1?`${(1e3*a).toFixed(0)}µs`:`${a.toFixed(2)}ms`})}),t.jsxs(Q,{label:"header byte",children:[t.jsx(ke,{start:0}),t.jsx(J,{value:e.slice(0,2)})," ",t.jsx(ee,{value:parseInt(e.slice(0,2),16)})]}),s.headerFields.map(e=>t.jsx(Q,{label:` ${e.field}`,children:t.jsx(te,{raw:t.jsxs("span",{className:"text-[10px]",children:["bits[",e.bits,"] = ",e.binary]}),children:t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber",children:e.value})})},e.field)),t.jsx(Q,{label:" version",children:null!=l?t.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[t.jsx(se,{fn:"payloadVer",value:`${l}`,color:"amber"}),t.jsx(b,{color:o?"green":c?"blue":"zinc",children:o?"v1":c?"v2":`v${l}`}),o&&t.jsx("span",{className:"text-fg-muted text-[10px]",children:"1-byte hashes, 2-byte MAC"}),c&&t.jsx("span",{className:"text-sys-blue text-[10px]",children:"2-byte hashes, 4-byte MAC (speculative)"})]}):t.jsx("span",{className:"text-fg-muted",children:"unknown"})}),t.jsx(X,{title:"Wire Framing"}),t.jsx(Q,{label:"transportCodes",children:s.transportCodesHex?t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:1,end:4}),t.jsx(se,{fn:"transport",value:s.transportCodesHex,color:"amber"})]}):t.jsx("span",{className:"text-fg-muted",children:"N/A (non-transport route)"})}),t.jsx(Q,{label:"pathLen",children:t.jsx(te,{raw:t.jsxs(t.Fragment,{children:[t.jsx(ke,{start:s.pathLenByteOffset}),t.jsx(J,{value:s.pathLengthHex})]}),children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:s.pathLenByteOffset}),t.jsx(se,{fn:"pathLen",value:`${r.pathLen} hop${1!==r.pathLen?"s":""}`,color:"amber"})]})})}),t.jsx(Q,{label:"path",children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[r.pathLen>0&&t.jsx(ke,{start:s.pathByteOffset,end:s.pathByteOffset+r.pathLen-1}),t.jsx(re,{hops:r.pathHexArray,hexPrefix:s.pathDataHex||void 0})]})}),t.jsx(Q,{label:"payloadLen",children:t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx(ke,{start:s.payloadByteOffset,end:s.payloadByteOffset+s.payloadHex.length/2-1}),t.jsx(se,{fn:"payloadLen",value:s.payloadHex.length/2+" bytes",color:"amber"})]})}),t.jsx(Q,{label:"payloadHex",children:t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber break-all",children:s.payloadHex})})]}):t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"A. Parse"}),t.jsxs(Q,{label:"result",children:[t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-2 py-0.5 font-mono text-[11px] text-sys-amber",children:"Skipped"}),t.jsx("span",{className:"ml-1 text-fg-muted",children:n??"No raw_packet (warm-tier)"})]})]})})}function Se({decoded:e,packet:s}){if(!e)return t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"B. Decode"}),t.jsx("p",{className:"text-fg-muted italic text-[10px]",children:"No decoded payload"})]});const r=we[e.type]??`decode${e.type}()`;return t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"B. Decode — decodePayload()"}),t.jsx(Z,{prefix:"decodePayload",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsx(Q,{label:"dispatched",children:r}),t.jsx(X,{}),t.jsx(_e,{decoded:e,packet:s})]})})]})}function _e({decoded:e,packet:s}){switch(e.type){case"advert":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"publicKey",children:t.jsx(te,{raw:t.jsx("span",{className:"text-[10px] break-all",children:e.publicKey}),children:t.jsx(se,{fn:"publicKey",value:e.publicKey,color:"green"})})}),t.jsx(Q,{label:"timestamp",children:t.jsx(se,{fn:"timestamp",value:String(e.timestamp),color:"green"})}),t.jsx(Q,{label:"flags",children:t.jsx(te,{raw:t.jsx(J,{value:e.flags}),children:t.jsx(se,{fn:"flags",value:e.flagsDescription,color:"green"})})}),t.jsx(Q,{label:"nodeType",children:t.jsx(se,{fn:"nodeType",value:e.nodeType,color:"green"})}),null!=e.latitude&&t.jsx(Q,{label:"latitude",children:t.jsx(se,{fn:"lat",value:e.latitude.toFixed(6),color:"green"})}),null!=e.longitude&&t.jsx(Q,{label:"longitude",children:t.jsx(se,{fn:"lon",value:e.longitude.toFixed(6),color:"green"})}),e.name&&t.jsx(Q,{label:"name",children:t.jsx(se,{fn:"name",value:e.name,color:"green"})})]});case"ack":return t.jsx(Q,{label:"crc",children:t.jsx(te,{raw:t.jsx("span",{className:"text-[10px]",children:e.crc}),children:t.jsx(se,{fn:"crc",value:e.crc,color:"green"})})});case"trace":{const r=(null==s?void 0:s.src_hash)?s.src_hash.replace(/^0x/i,"").slice(0,2).toUpperCase():null;return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"traceTag",children:t.jsx(se,{fn:"traceTag",value:e.traceTag,color:"green"})}),t.jsx(Q,{label:"authCode",children:t.jsx(se,{fn:"authCode",value:String(e.authCode),color:"green"})}),t.jsx(Q,{label:"flags",children:t.jsx(J,{value:e.flags})}),t.jsx(Q,{label:"target path",children:e.pathHashes.length>0?t.jsx(re,{hops:e.pathHashes.map(e=>e.toUpperCase()),color:"green"}):t.jsx("span",{className:"text-fg-muted italic",children:"∅ empty"})}),t.jsx(Q,{label:"complete",children:e.isComplete?t.jsxs("span",{className:"text-sys-green",children:["✓ all ",e.pathHashes.length," hops reported SNR"]}):t.jsxs("span",{className:"text-sys-amber",children:["✗ ",e.snrValues.length,"/",e.pathHashes.length," hops reported"]})}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1 text-[10px]",children:"Directional Edge SNR — per-hop link quality"}),0===e.snrValues.length?t.jsx("p",{className:"text-fg-muted italic text-[11px] ml-2",children:"No SNR values in path field"}):t.jsx("div",{className:"space-y-0.5 ml-2",children:e.snrValues.map((s,n)=>{var a,l,o,c,i;const d=(null==(a=e.pathHashes[n])?void 0:a.toUpperCase())??"??",p=0===n?r??"SRC":(null==(l=e.pathHashes[n-1])?void 0:l.toUpperCase())??"??",u=null==(i=null==(c=null==(o=N.getState().stats)?void 0:o.config)?void 0:c.radio)?void 0:i.spreading_factor,x=h(s,u);return t.jsxs("div",{className:"flex items-center gap-1.5 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted w-3 text-right",children:n}),t.jsx("span",{className:"text-fg-primary",children:p}),t.jsx("span",{className:"text-fg-muted",children:"→"}),t.jsx("span",{className:"text-fg-primary",children:d}),t.jsx("span",{className:"text-fg-muted",children:"@"}),t.jsxs("span",{className:"font-bold text-sys-green",children:[s>0?"+":"",s.toFixed(1)," dB"]}),t.jsx(b,{color:"green",children:x})]},n)})})]})]})}case"path":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"pathLength",children:t.jsx(se,{fn:"pathLength",value:String(e.pathLength),color:"green"})}),t.jsx(Q,{label:"path",children:e.path&&e.path.length>0?t.jsx(re,{hops:e.path.map(e=>e.toUpperCase()),color:"green"}):t.jsx("span",{className:"text-fg-muted italic",children:"∅ empty"})}),null!=e.extraType&&t.jsx(Q,{label:"extraType",children:t.jsx(se,{fn:"extraType",value:e.extraTypeName??String(e.extraType),color:"purple"})}),e.extraData&&t.jsxs(Q,{label:"extraData",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.extraData}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.extraData.length/2,"B)"]})]})]});case"txt_msg":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"srcHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.srcHash}),children:t.jsx(se,{fn:"srcHash",value:e.srcHash,color:"green"})})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsx(Q,{label:"timestamp",children:t.jsx(se,{fn:"timestamp",value:String(e.timestamp),color:"green"})}),t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:e.text,color:"green"})}),t.jsx(Q,{label:"encrypted",children:t.jsx(se,{fn:"encrypted",value:String(e.encrypted),color:"green"})})]});case"grp_txt":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channelHash",children:t.jsx(J,{value:e.channelHash})}),e.channelName&&t.jsx(Q,{label:"channelName",children:t.jsx(se,{fn:"channel",value:e.channelName,color:"green"})}),t.jsx(Q,{label:"decrypted",children:t.jsx(se,{fn:"decrypted",value:String(e.decrypted),color:"green"})}),e.text&&t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:e.text,color:"green"})}),e.senderName&&t.jsx(Q,{label:"senderName",children:t.jsx(se,{fn:"sender",value:e.senderName,color:"green"})}),e.macCorrupted&&t.jsx(Q,{label:"macCorrupted",children:t.jsx(se,{fn:"macCorrupted",value:"true",color:"green"})})]});case"grp_data":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channelHash",children:t.jsx(J,{value:e.channelHash})}),t.jsx(Q,{label:"dataLength",children:e.dataLength}),t.jsx(Q,{label:"decrypted",children:String(e.decrypted)})]});case"multipart":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"messageId",children:e.messageId}),t.jsxs(Q,{label:"part",children:[e.partNumber+1," / ",e.totalParts]})]});case"control":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"controlType",children:t.jsx(te,{raw:t.jsx(J,{value:e.controlType}),children:t.jsx(se,{fn:"controlType",value:e.subtypeName,color:"green"})})}),t.jsx(Q,{label:"subtype",children:t.jsx(se,{fn:"subtype",value:`0x${e.subtype.toString(16).padStart(2,"0")}`,color:"green"})}),t.jsx(Q,{label:"subtypeFlags",children:t.jsx(se,{fn:"subtypeFlags",value:`0x${e.subtypeFlags.toString(16).padStart(2,"0")}`,color:"green"})}),e.dataLength>0&&t.jsxs(Q,{label:"data",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.dataHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.dataLength,"B)"]})]})]});case"req":case"response":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"srcHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.srcHash}),children:t.jsx(se,{fn:"srcHash",value:e.srcHash,color:"green"})})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsxs(Q,{label:"ciphertext",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.ciphertextHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.ciphertextLength,"B)"]})]})]});case"anon_req":return t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"destHash",children:t.jsx(te,{raw:t.jsx(J,{value:e.destHash}),children:t.jsx(se,{fn:"destHash",value:e.destHash,color:"green"})})}),t.jsx(Q,{label:"senderPubKey",children:t.jsx("span",{className:"break-all text-[10px] font-mono text-sys-green",children:e.senderPublicKey})}),t.jsx(Q,{label:"cipherMac",children:t.jsx(se,{fn:"cipherMac",value:e.cipherMac,color:"purple"})}),t.jsxs(Q,{label:"ciphertext",children:[t.jsx("span",{className:"break-all text-[10px] font-mono",children:e.ciphertextHex}),t.jsxs("span",{className:"text-fg-muted ml-1",children:["(",e.ciphertextLength,"B)"]})]})]});case"generic":return t.jsxs(t.Fragment,{children:[t.jsxs(Q,{label:"payloadType",children:[t.jsx(ne,{value:e.payloadType})," (",e.payloadTypeName,")"]}),t.jsx(Q,{label:"length",children:e.length}),t.jsx(Q,{label:"rawHex",children:t.jsx("span",{className:"break-all",children:e.rawHex})})]});default:return t.jsx("p",{className:"text-fg-muted",children:"Unknown decoded type"})}}function He({protocolPacket:s,packetHash:r}){const n=null==s?void 0:s.payloadType,a=n===k||n===w,l=e.useMemo(()=>{if(!a||!s)return null;const e=s.payload;return e.length<4?null:{channelHash:e[0],mac:e.slice(1,3),ciphertext:e.slice(3)}},[s,a]),[o,c]=e.useState("pending"),[i,d]=e.useState([]),[p,u]=e.useState(0);e.useEffect(()=>{if(!l)return void c(null);let e=!1;return(async()=>{const t=performance.now(),s=await C(l.channelHash,l.mac,l.ciphertext);e||(c(s),u(performance.now()-t));const r=await S(l.channelHash);e||d(r)})(),()=>{e=!0}},[l]);const[h,x]=e.useState(""),[m,g]=e.useState(null),[f,v]=e.useState(!1),b=e.useCallback(async()=>{if(l&&h.trim()){v(!0);try{const e=await y(h.trim(),l.channelHash,l.mac,l.ciphertext);if(e.success){const t=new TextDecoder("utf-8",{fatal:!1}).decode(e.result.plaintext.slice(5));g({success:!0,text:t})}else g({success:!1,error:e.error})}catch(e){g({success:!1,error:String(e)})}finally{v(!1)}}},[l,h]),N=j(r);return a&&l?t.jsxs(t.Fragment,{children:[t.jsx(X,{title:"C. Decrypt — tryDecryptGroupMessage()"}),p>0&&t.jsx("div",{className:"flex justify-end",children:t.jsx("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-sys-green/15 text-sys-green",children:p<1?`${(1e3*p).toFixed(0)}µs`:`${p.toFixed(2)}ms`})}),t.jsx(Z,{prefix:"tryDecryptGroupMessage",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsx(Q,{label:"channelHash",children:t.jsx(se,{fn:"channelHash",value:`0x${l.channelHash.toString(16).toUpperCase().padStart(2,"0")}`,color:"teal"})}),t.jsx(Q,{label:"mac",children:t.jsx(se,{fn:"mac",value:Array.from(l.mac).map(e=>e.toString(16).padStart(2,"0")).join(""),color:"teal"})}),t.jsx(Q,{label:"cipherLen",children:t.jsx(se,{fn:"cipherLen",value:`${l.ciphertext.length}B`,color:"teal"})}),t.jsx(Q,{label:"candidates",children:t.jsx(se,{fn:"candidates",value:i.length>0?`${i.length} names`:"0",color:i.length>0?"teal":"zinc"})}),i.length>0&&t.jsxs("details",{className:"mt-1",children:[t.jsx("summary",{className:"text-fg-muted cursor-pointer hover:text-fg-primary text-[10px]",children:"show candidate names"}),t.jsx("div",{className:"mt-1 text-[10px] text-fg-muted break-all max-h-24 overflow-y-auto",children:i.join(", ")})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"Result:"}),"pending"===o?t.jsx("p",{className:"text-fg-muted italic",children:"decrypting…"}):o?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channel",children:t.jsx(se,{fn:"channel",value:o.channelName,color:"teal"})}),t.jsx(Q,{label:"plaintext",children:t.jsx(se,{fn:"plaintext",value:new TextDecoder("utf-8",{fatal:!1}).decode(o.plaintext.slice(5)).trim()||"(empty)",color:"teal"})}),t.jsx(Q,{label:"macValid",children:t.jsx(se,{fn:"macValid",value:o.macCorrupted?"false":"true",color:"teal"})})]}):t.jsxs(Q,{label:"decrypt",children:[t.jsx(se,{fn:"decrypt",value:"failed",color:"red"}),t.jsx("span",{className:"text-fg-muted ml-1",children:"channel not in known list"})]})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"testChannelName() — manual test:"}),t.jsxs("div",{className:"flex gap-1.5 items-center",children:[t.jsx("input",{type:"text",value:h,onChange:e=>{x(e.target.value),g(null)},onKeyDown:e=>"Enter"===e.key&&b(),placeholder:"channel name",className:"surface-input px-2 py-1 rounded text-[11px] font-mono text-fg-primary w-40"}),t.jsx("button",{onClick:b,disabled:f||!h.trim(),className:"px-2 py-1 rounded text-[10px] font-mono bg-sys-blue/20 text-sys-blue hover:bg-sys-blue/30 disabled:opacity-40 transition-colors",children:f?"…":"Try"})]}),m&&t.jsx("div",{className:"mt-1",children:m.success?t.jsx(Q,{label:"result",children:t.jsx(se,{fn:"plaintext",value:m.text??"(empty)",color:"teal"})}):t.jsx(Q,{label:"error",children:t.jsx(se,{fn:"error",value:m.error??"unknown",color:"red"})})})]}),t.jsx(X,{}),t.jsxs("div",{children:[t.jsx("p",{className:"text-fg-muted mb-1",children:"useDecodedMessage() store result:"}),N?N.decoded?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"channel",children:t.jsx(se,{fn:"channel",value:N.decoded.channelName??"?",color:"teal"})}),t.jsx(Q,{label:"text",children:t.jsx(se,{fn:"text",value:N.decoded.text,color:"teal"})})]}):t.jsx(Q,{label:"decrypt",children:t.jsx(se,{fn:"decrypt",value:"failed",color:"red"})}):t.jsx(Q,{label:"decrypt",children:t.jsx(se,{fn:"decrypt",value:"pending",color:"zinc"})})]})]})})]}):null}function Te(e){const{rawHex:s,display:r,protocolPacket:n,decoded:a,parseError:l,parseTimeMs:o,payloadVersion:c,isV1:i,isV2:d,packetHash:p,packet:u}=e,h=!!s&&s.length>=4;return t.jsxs(x,{children:[t.jsx(m,{className:"w-full mt-2 mb-1",children:t.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[t.jsx("span",{className:"text-[10px] font-mono text-fg-muted",children:"🔬"}),t.jsx("span",{className:"text-[10px] font-mono font-medium text-fg-muted",children:"Wire Inspection"}),t.jsx("span",{className:"text-[9px] text-fg-muted/50",children:"observatory diagnostic — not a runtime stage"})]})}),t.jsx(g,{children:t.jsxs("div",{className:"border border-dashed border-edge-subtle rounded-lg p-3 space-y-1 bg-surface/30",children:[t.jsx("p",{className:"text-[9px] text-fg-muted/50 mb-2",children:"The backend parsed these fields server-side. This panel verifies the wire-level encoding client-side."}),h?t.jsxs(t.Fragment,{children:[t.jsx(Ce,{rawHex:s,display:r,protocolPacket:n,parseError:l,parseTimeMs:o,payloadVersion:c,isV1:i,isV2:d}),t.jsx(Se,{decoded:a,packet:u}),t.jsx(He,{protocolPacket:n,packetHash:p})]}):t.jsx("p",{className:"text-fg-muted italic text-[10px]",children:l??"No raw_packet — wire inspection unavailable (warm-tier packet)"})]})})]})}function $e(e){if(!e)return[{fn:"decode",value:"no raw_packet",group:"decode",color:"zinc"}];switch(e.type){case"advert":{const t=e,s=[{fn:"decode.nodeType",value:t.nodeType,group:"decode",color:"blue"}];return t.name&&s.push({fn:"decode.name",value:t.name,group:"decode",color:"blue"}),null!=t.latitude&&null!=t.longitude&&s.push({fn:"decode.location",value:`${t.latitude.toFixed(4)}, ${t.longitude.toFixed(4)}`,group:"decode",color:"blue"}),s.push({fn:"decode.publicKey",value:t.publicKey,group:"decode",color:"blue"}),s}case"trace":{const t=e;return[{fn:"decode.traceTag",value:t.traceTag,group:"decode",color:"blue"},{fn:"decode.hops",value:t.pathHashes.length>0?t.pathString:"empty",group:"decode",color:"blue"},{fn:"decode.snr",value:t.snrValues.length>0?`${t.snrValues.length} values`:"none",group:"decode",color:t.snrValues.length>0?"blue":"zinc"},{fn:"decode.complete",value:t.isComplete?"yes":"partial",group:"decode",color:t.isComplete?"green":"amber"}]}case"path":{const t=e,s=[{fn:"decode.pathLength",value:String(t.pathLength),group:"decode",color:"blue"},{fn:"decode.path",value:t.path.length>0?t.pathString:"empty",group:"decode",color:"blue"}];return null!=t.extraType&&s.push({fn:"decode.extraType",value:t.extraTypeName??String(t.extraType),group:"decode",color:"purple"}),t.extraData&&s.push({fn:"decode.extraData",value:t.extraData.length/2+"B",group:"decode",color:"purple"}),s}case"ack":return[{fn:"decode.crc",value:e.crc,group:"decode",color:"blue"}];case"grp_txt":return[{fn:"decode.channelHash",value:e.channelHash,group:"decode",color:"blue"},{fn:"decode.encrypted",value:"true — decrypt at cascade",group:"decode",color:"zinc"}];case"grp_data":{const t=e;return[{fn:"decode.channelHash",value:t.channelHash,group:"decode",color:"blue"},{fn:"decode.dataLength",value:`${t.dataLength}B`,group:"decode",color:"blue"}]}case"txt_msg":{const t=e;return[{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.encrypted",value:t.encrypted?"true":"false",group:"decode",color:t.encrypted?"zinc":"green"},...t.encrypted?[]:[{fn:"decode.text",value:t.text,group:"decode",color:"blue"}]]}case"multipart":{const t=e;return[{fn:"decode.part",value:`${t.partNumber+1}/${t.totalParts}`,group:"decode",color:"blue"},{fn:"decode.msgId",value:t.messageId,group:"decode",color:"blue"}]}case"control":{const t=e;return[{fn:"decode.subtype",value:t.subtypeName,group:"decode",color:"blue"},{fn:"decode.subtypeFlags",value:`0x${t.subtypeFlags.toString(16)}`,group:"decode",color:"blue"},{fn:"decode.dataLength",value:`${t.dataLength}B`,group:"decode",color:"blue"}]}case"req":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"response":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.srcHash",value:t.srcHash,group:"decode",color:"blue"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"anon_req":{const t=e;return[{fn:"decode.destHash",value:t.destHash,group:"decode",color:"blue"},{fn:"decode.senderPubKey",value:t.senderPublicKey,group:"decode",color:"green"},{fn:"decode.cipherMac",value:t.cipherMac,group:"decode",color:"purple"},{fn:"decode.ciphertext",value:`${t.ciphertextLength}B`,group:"decode",color:"zinc"}]}case"generic":return[{fn:"decode.raw",value:`${e.length}B`,group:"decode",color:"zinc"}];default:return[]}}function Pe({packet:s,pipeline:r,rawHex:n,traceTagIndex:a,neighbors:l}){const{enrichment:o,timing:c,display:i,protocolPacket:d,decoded:p,parseError:u,payloadVersion:h,isV1:x,isV2:m,analysis:g}=r,f=(s.type??s.payload_type)===_,v=g.dupeAnalysis,y=e.useRef(0),j=e.useMemo(()=>{if(!f)return null;const e=performance.now(),t=function(e,t,s){let r=e._traceTag;if(!r&&e.payload&&(r=q(e.payload)),!r)return{traceTag:null,siblingCount:0,isLocallyOriginated:!1,method:"none",confidence:"none",inferredSrc:null,inferredName:null,evidence:[],thisPathLen:0,minPathLen:0,firstHopPrefix:null,evidence:["no traceTag — cannot correlate"]};const n=t.get(r)??[],a=e=>null!=e.path_length?e.path_length:Array.isArray(e.original_path)?e.original_path.length:0,l=a(e),o=n.length>0?Math.min(...n.map(a)):l,c=e.payload?e.payload.slice(18):"",i=c.length>=2?c.slice(0,2).toUpperCase():null,d=[];if(d.push(`traceTag: ${r}`),d.push(`siblings: ${n.length} observation${1!==n.length?"s":""}`),"tx_local"===e.packet_origin)return d.push("packet_origin = tx_local → we initiated this trace"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!0,method:"tx_local",confidence:"certain",inferredSrc:"LOCAL",inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i};const p=n.find(e=>"tx_local"===e.packet_origin);if(p)return d.push(`sibling (hash ${p.packet_hash}) has packet_origin = tx_local`),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!0,method:"tx_local",confidence:"certain",inferredSrc:"LOCAL",inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i};if(d.push(`this observation: path_len=${l}, min across siblings: ${o}`),i){if(d.push(`first hop in target path: ${i}`),0===l)return d.push("path_len = 0 → heard directly from initiator (no SNR appended yet)"),d.push("initiator is a direct RF neighbor"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"min_path_len",confidence:"speculative",inferredSrc:null,inferredName:null,evidence:[...d,"initiator is within direct RF range (zero forwarding hops)"],thisPathLen:l,minPathLen:o,firstHopPrefix:i};const e=Object.entries(s).filter(([e])=>e.replace(/^0x/i,"").slice(0,2).toUpperCase()===i);if(1===e.length){const[t,s]=e[0],a=s.name||s.node_name||null;return d.push(`first hop ${i} → unique neighbor: ${a??t}`),d.push("initiator is whoever sent TO this first hop"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"first_hop_neighbor",confidence:"likely",inferredSrc:i,inferredName:a,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i}}e.length>1?d.push(`first hop ${i} matches ${e.length} neighbors (ambiguous)`):d.push(`first hop ${i} is not a known neighbor`)}return d.push("insufficient data to identify initiator"),{traceTag:r,siblingCount:n.length,isLocallyOriginated:!1,method:"none",confidence:"none",inferredSrc:null,inferredName:null,evidence:d,thisPathLen:l,minPathLen:o,firstHopPrefix:i}}(s,a,l);return y.current=performance.now()-e,t},[s,a,l,f]),N=c.enrich+y.current,k=[];g.byteLen&&k.push(`${g.byteLen}B`),k.push(g.payloadTypeName),o.advertName&&k.push(`"${o.advertName}"`),o.isZeroHop?k.push("zero-hop"):g.pathHopCount>0&&k.push(`${g.pathHopCount}h`),k.push(`${s.rssi}dBm`),v.isDuplicate&&k.push("DUPE");const w=k.join(" — ");return t.jsxs(ye,{stage:1,name:"INGEST",fn:o.preComputed?"PacketCache.mergePackets()":"extractAdvertData() + extractHopData() + ...",verdict:w,timeMs:N,children:[t.jsx(Te,{rawHex:n,display:i,protocolPacket:d,decoded:p,parseError:u,parseTimeMs:c.parse,payloadVersion:h,isV1:x,isV2:m,packetHash:s.packet_hash,packet:s}),t.jsx(X,{title:"Cache Enrichment"}),t.jsx(Z,{prefix:"packetCache",children:t.jsxs("dl",{className:"space-y-0.5",children:[t.jsxs("div",{className:"mb-1.5",children:[o.preComputed?t.jsx(b,{color:"green",children:"PacketCache"}):t.jsx(b,{color:"amber",children:"computed"}),t.jsx("span",{className:"text-[10px] text-fg-muted ml-1.5",children:o.preComputed?"pre-enriched by real pipeline":"synthetic — computed on the fly"})]}),t.jsxs("div",{className:"flex flex-wrap gap-x-2 gap-y-1 mb-1",children:[t.jsx(se,{fn:"_byteLength",value:null!=o.byteLength?`${o.byteLength}B`:void 0,color:"blue"}),t.jsx(se,{fn:"_hopCount",value:String(o.hopCount),color:"blue"}),t.jsx(se,{fn:"_isZeroHop",value:String(o.isZeroHop),color:o.isZeroHop?"green":"blue"}),o.isZeroHop&&t.jsx(b,{color:"blue",children:"direct"}),null!=o.channelHash&&t.jsx(se,{fn:"_channelHash",value:o.channelHash,color:"blue"}),f&&s._traceTag&&t.jsx(se,{fn:"_traceTag",value:s._traceTag,color:"blue"})]}),o.advertSender||null!=o.advertNodeType||null!=o.advertName?t.jsxs("div",{className:"mt-1 mb-1",children:[t.jsx("p",{className:"text-[10px] text-sys-blue font-medium mb-0.5",children:"ADVERT Enrichment"}),t.jsxs("div",{className:"flex flex-wrap gap-x-2 gap-y-1",children:[o.advertSender&&t.jsx(se,{fn:"_advertSender",value:o.advertSender.slice(0,16)+"…",color:"blue"}),null!=o.advertNodeType&&t.jsx(se,{fn:"_advertNodeType",value:ie(o.advertNodeType),color:"blue"}),null!=o.advertName&&t.jsx(se,{fn:"_advertName",value:o.advertName,color:"blue"}),null!=o.advertFlags&&t.jsx(se,{fn:"_advertFlags",value:`0x${o.advertFlags.toString(16).padStart(2,"0")}`,color:"blue"}),null!=o.advertHasLocation&&t.jsx(se,{fn:"_advertHasLocation",value:String(o.advertHasLocation),color:"blue"}),null!=o.advertHasName&&t.jsx(se,{fn:"_advertHasName",value:String(o.advertHasName),color:"blue"}),null!=o.advertLatitude&&null!=o.advertLongitude&&t.jsx(se,{fn:"location",value:`${o.advertLatitude.toFixed(4)}, ${o.advertLongitude.toFixed(4)}`,color:"blue"})]})]}):t.jsx("p",{className:"text-[10px] text-fg-muted/30 mb-1",children:"ADVERT fields: N/A (non-ADVERT packet)"}),t.jsx(X,{title:"Payload Decode"}),t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full shrink-0 "+(p?"bg-sys-blue":"bg-zinc-500/40")}),t.jsx("span",{className:"font-mono text-[10px] font-medium text-fg-primary",children:"decodePayload()"}),t.jsx("span",{className:"text-[9px] text-fg-muted",children:"sync — wire data only, no crypto"})]}),t.jsx("div",{className:"ml-3",children:p?t.jsx("div",{className:"flex flex-wrap gap-x-1.5 gap-y-1",children:$e(p).map((e,s)=>t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5",children:t.jsx(se,{fn:e.fn,value:e.value,color:e.color})},s))}):t.jsx(ae,{children:"no raw_packet — warm-tier packet, decode unavailable"})})]}),t.jsx(X,{}),t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted",children:"dupe:"}),v.isDuplicate?t.jsx(se,{fn:"is_duplicate",value:"true",color:"purple"}):t.jsx(ae,{children:"none"}),v.dupeCount>0&&t.jsx(se,{fn:"dupeCount",value:`×${v.dupeCount}`,color:"purple"}),v.rssiRange&&t.jsxs(ae,{c:"text-fg-primary",children:["Δ",Math.abs(v.rssiRange[1]-v.rssiRange[0]),"dB RSSI"]})]}),j&&t.jsxs(t.Fragment,{children:[t.jsx(X,{}),t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx("span",{className:"text-fg-muted",children:"TRACE SRC:"}),j.inferredSrc?t.jsxs(t.Fragment,{children:[t.jsx(se,{fn:"inferredSrc",value:j.inferredSrc,color:"purple"}),j.inferredName&&t.jsx(se,{fn:"name",value:j.inferredName,color:"purple"})]}):t.jsx(ae,{children:"unresolvable"}),t.jsx(le,{color:"purple",children:j.method}),t.jsxs(ae,{children:["(",j.confidence,")"]}),t.jsxs(ae,{children:["siblings=",j.siblingCount]})]})]}),(()=>{const e=null!=g.pType?`0x${g.pType.toString(16).toUpperCase().padStart(2,"0")}`:void 0,r=null!=s.route?`0x${s.route.toString(16).toUpperCase().padStart(2,"0")}`:void 0,n=$e(p),a="excellent"===g.signalClass||"good"===g.signalClass?"green":"fair"===g.signalClass?"amber":"red",l="pubkey"===g.senderTier?"green":"prefix"===g.senderTier?"amber":"encrypted"===g.senderTier?"teal":"zinc",c=[{fn:"type",value:g.payloadTypeName,raw:e,group:"wire",color:"blue"},{fn:"route",value:g.routeTypeName,raw:r,group:"wire",color:"blue"},{fn:"src_hash",value:s.src_hash||void 0,group:"wire",color:"blue"},{fn:"rssi",value:`${s.rssi}dBm`,group:"wire",color:"blue"},{fn:"snr",value:`${s.snr}dB`,group:"wire",color:"blue"},{fn:"_byteLength",value:g.byteLen?`${g.byteLen}B`:void 0,group:"enrichment",color:"blue"},{fn:"_hopCount",value:String(o.hopCount),group:"enrichment",color:"blue"},{fn:"_isZeroHop",value:String(o.isZeroHop),group:"enrichment",color:"blue"},{fn:"_advertSender",value:o.advertSender||void 0,group:"enrichment",color:"blue"},{fn:"_advertNodeType",value:"unknown"!==g.advertType?g.advertType:void 0,group:"enrichment",color:"blue"},{fn:"_advertName",value:o.advertName||void 0,group:"enrichment",color:"blue"},{fn:"_channelHash",value:o.channelHash||void 0,group:"enrichment",color:"blue"},...n,{fn:"is_duplicate",value:String(v.isDuplicate),group:"analysis",color:"purple"},(null==j?void 0:j.inferredSrc)?{fn:"traceSrc",value:j.inferredSrc,group:"analysis",color:"purple"}:{fn:"traceSrc"},{fn:"_signalClass",value:g.signalClass,group:"analysis",color:a},{fn:"_routeClass",value:g.routeClass,group:"analysis",color:"purple"},{fn:"_senderTier",value:g.senderTier,group:"analysis",color:l},{fn:"_origin",value:g.origin,group:"analysis",color:"tx_local"===g.origin?"green":"tx_forward"===g.origin?"amber":"purple"},{fn:"_pathAvail",value:g.pathAvail?`${g.pathHopCount} hops`:"none",group:"analysis",color:g.pathAvail?"green":"zinc"},{fn:"_age",value:g.age,group:"analysis",color:"live"===g.age||"recent"===g.age?"green":"zinc"},...v.dupeCount>0?[{fn:"_dupeCount",value:`×${v.dupeCount}`,group:"analysis",color:"purple"},...v.rssiRange?[{fn:"_multipath",value:`Δ${Math.abs(v.rssiRange[1]-v.rssiRange[0])}dB`,group:"analysis",color:Math.abs(v.rssiRange[1]-v.rssiRange[0])>6?"amber":"green"}]:[]]:[],...null!=s.lbt_attempts?[{fn:"_lbt",value:`${s.lbt_attempts} attempt${1!==s.lbt_attempts?"s":""}`,group:"analysis",color:(s.lbt_attempts??0)>1?"amber":"green"}]:[],...s.drop_reason?[{fn:"_dropReason",value:s.drop_reason,group:"analysis",color:"red"}]:[]];return t.jsx(Y,{tokens:c})})()]})})]})}function Le(e){switch(e){case"excellent":case"good":return"green";case"fair":return"amber";case"poor":case"critical":return"red";default:return"zinc"}}function Me(e){return`${Math.round(100*e)}%`}function De(e,t,s){return e||(t?t.slice(0,12):`~${s}`)}function Fe({hops:e}){return 0===e.length?null:t.jsxs("div",{className:"mt-2 pt-2 border-t border-edge-subtle/40",children:[t.jsx("p",{className:"text-[9px] text-fg-muted/40 uppercase tracking-widest font-mono mb-1.5",children:"per-hop trace inspection"}),t.jsx("div",{className:"space-y-1",children:e.map(e=>t.jsx(Z,{prefix:`trace.hop[${e.hopIndex}]`,children:t.jsxs("div",{className:"border border-edge-subtle/40 rounded px-2 py-1.5",children:[t.jsxs(Q,{label:"link",children:[t.jsx(re,{hops:[e.fromPrefix,e.toPrefix],color:"blue"}),t.jsx("span",{className:"ml-1.5",children:t.jsx(le,{color:Le(e.quality),children:e.quality})})]}),t.jsx(Q,{label:"snr",children:t.jsx(te,{raw:t.jsx("span",{className:"text-sys-blue",children:e.snrRaw}),children:t.jsx(se,{fn:"snr",value:`${e.snrRaw.toFixed(1)} dB`,color:Le(e.quality)})})}),t.jsxs(Q,{label:"from",children:[t.jsx(se,{fn:"resolve",value:De(e.fromName,e.fromHash,e.fromPrefix),color:e.fromHash?e.fromConfidence>=.8?"green":"amber":"purple"}),t.jsx("span",{className:"ml-1",children:t.jsx(se,{fn:"conf",value:Me(e.fromConfidence),color:"zinc"})})]}),t.jsxs(Q,{label:"to",children:[t.jsx(se,{fn:"resolve",value:De(e.toName,e.toHash,e.toPrefix),color:e.toHash?e.toConfidence>=.8?"green":"amber":"purple"}),t.jsx("span",{className:"ml-1",children:t.jsx(se,{fn:"conf",value:Me(e.toConfidence),color:"zinc"})})]})]})},e.hopIndex))}),t.jsx(Y,{label:"trace contributes",tokens:Re(e)})]})}function Re(e){const t=e.reduce((e,t)=>e+(t.fromHash?1:0)+(t.toHash?1:0),0),s=2*e.length,r=s-t,n=e.length>0?e.reduce((e,t)=>e+t.snrRaw,0)/e.length:0;return[{fn:"hops",value:String(e.length),group:"wire",color:"blue"},{fn:"resolved",value:`${t}/${s}`,group:"worker",color:"green"},...r>0?[{fn:"ghosts",value:String(r),group:"worker",color:"purple"}]:[],{fn:"avgSnr",value:`${n.toFixed(1)} dB`,group:"analysis",color:n>=5?"green":n>=0?"amber":"red"}]}function Ae(e){if(!e)return"never";const t=Math.floor((Date.now()-e)/1e3);return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:`${Math.floor(t/3600)}h ago`}function ze({packet:e,decrypted:r,pipeline:n}){var a;const l=H(e=>e.isComputing),o=H(e=>e.lastUpdated),c=H(e=>e.lastComputeTimeMs),i=H(e=>e.topology.edges.length),d=H(e=>e.topology.discoveredNodes.length),p=T(),u=$(),h=P(),f=L(e=>e.isComputing),v=L(e=>e.nodeCount),b=M(e=>e.progress),y=M(e=>e.initialDecodeComplete),j=e.type??e.payload_type,N=j===s.GRP_TXT||j===s.GRP_DATA,k=j===s.TRACE,w=j===s.PATH,C=N,S=[{label:"full",detail:"all GRP_TXT → decryption worker",active:C&&y,color:"teal"},{label:"quick",detail:"100 most recent (initial load)",active:C&&!y,color:"amber"},{label:"skip",detail:"non-GRP or catchup path",active:!C,color:"zinc"}],_=function(e){if(!e)return[];const t=e.decoded;if(!t)return[{fn:"decrypt.result",value:"failed",group:"crypto",color:"red"}];if(!t.decrypted)return[{fn:"decrypt.result",value:"no key match",group:"crypto",color:"zinc"}];const s=[];return t.channelName&&s.push({fn:"decrypt.channelName",value:t.channelName,group:"crypto",color:"teal"}),t.senderName&&s.push({fn:"decrypt.senderName",value:t.senderName,group:"crypto",color:"teal"}),t.text&&s.push({fn:"decrypt.text",value:t.text,group:"crypto",color:"teal"}),t.timestamp&&s.push({fn:"decrypt.timestamp",value:new Date(1e3*t.timestamp).toISOString().slice(11,19),group:"crypto",color:"teal"}),t.macCorrupted&&s.push({fn:"decrypt.macCorrupted",value:"true",group:"crypto",color:"amber"}),s}(r),D=!0===(null==(a=null==r?void 0:r.decoded)?void 0:a.decrypted),F=`topo ${l?"○":"✓"} ${l?"running":`${i}e ${d}g`} · spark ${f?"○":"✓"} ${f?"running":`${v}n`} · decrypt ${C?D?"decrypted":b.isDecoding?`${b.percent}%`:"pending":"N/A"}`;return t.jsx(ye,{stage:2,name:"CASCADE",fn:"hydrateDownstream()",verdict:F,children:t.jsx(Z,{prefix:"cascade",children:t.jsxs("div",{className:"space-y-0",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 py-1.5 text-[11px] font-mono",children:[t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(l?"bg-sys-amber animate-pulse":"bg-sys-green")}),t.jsx("span",{className:"text-fg-primary",children:"topology"}),t.jsxs("span",{className:"text-fg-muted",children:[i,"e ",d,"g"]}),(k||w)&&t.jsx("span",{className:"text-sys-green text-[9px]",children:"↑signal"})]}),t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(f?"bg-sys-amber animate-pulse":"bg-sys-green")}),t.jsx("span",{className:"text-fg-primary",children:"sparkline"}),t.jsxs("span",{className:"text-fg-muted",children:[v,"n"]})]}),t.jsxs("span",{className:"inline-flex items-center gap-1",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full "+(b.isDecoding?"bg-sys-amber animate-pulse":C?"bg-sys-teal":"bg-zinc-500/40")}),t.jsx("span",{className:"text-fg-primary",children:"decrypt"}),t.jsx("span",{className:C?"text-sys-teal":"text-fg-muted",children:C?D?"decrypted":b.isDecoding?`${b.percent}%`:"pending":"N/A"})]})]}),t.jsxs(x,{defaultOpen:k||w,children:[t.jsx(m,{className:"text-[10px] w-full border-t border-edge-subtle pt-1.5",children:t.jsx("span",{className:"font-mono text-fg-muted/50",children:"topology detail…"})}),t.jsx(g,{children:t.jsxs("div",{className:"ml-3 pb-2",children:[t.jsx(Q,{label:"status",children:t.jsx(se,{fn:"isComputing",value:l?"running":"idle",color:l?"amber":"green"})}),t.jsxs(Q,{label:"last",children:[t.jsx(se,{fn:"lastUpdated",value:Ae(o),color:"zinc"}),c>0&&t.jsxs("span",{className:"ml-2 text-fg-muted text-[10px]",children:["(",c<1e3?`${c.toFixed(0)}ms`:`${(c/1e3).toFixed(1)}s`,")"]})]}),t.jsxs(Q,{label:"output",children:[t.jsx(se,{fn:"edges",value:String(i),color:"green"}),t.jsx(se,{fn:"ghostNodes",value:String(d),color:"purple"})]}),u&&t.jsxs(t.Fragment,{children:[t.jsxs(Q,{label:"trace links",children:[t.jsx(se,{fn:"directed",value:String(p.totalDirectedLinks),color:"teal"}),t.jsx(se,{fn:"bidir",value:String(p.bidirectionalLinks),color:"teal"}),t.jsx(se,{fn:"traces",value:String(p.totalTraces),color:"zinc"})]}),t.jsxs(Q,{label:"trace SNR",children:[t.jsx(se,{fn:"mean",value:`${p.meanSnr.toFixed(1)} dB`,color:p.meanSnr>=5?"green":p.meanSnr>=0?"amber":"red"}),t.jsx(se,{fn:"median",value:`${p.medianSnr.toFixed(1)} dB`,color:"zinc"}),t.jsx(se,{fn:"confidence",value:`${Math.round(100*p.avgConfidence)}%`,color:"zinc"})]}),k&&t.jsxs(Q,{label:"quality",children:[t.jsx(se,{fn:"excellent",value:String(p.qualityCounts.excellent),color:"green"}),t.jsx(se,{fn:"good",value:String(p.qualityCounts.good),color:"green"}),t.jsx(se,{fn:"fair",value:String(p.qualityCounts.fair),color:"amber"}),t.jsx(se,{fn:"poor",value:String(p.qualityCounts.poor),color:"red"}),t.jsx(se,{fn:"critical",value:String(p.qualityCounts.critical),color:"red"})]}),h.confirmedResolutions.size>0&&t.jsxs(Q,{label:"feedback",children:[t.jsx(se,{fn:"feedback.confirmed",value:String(h.confirmedResolutions.size),color:"teal"}),t.jsx(se,{fn:"feedback.links",value:String(h.confirmedLinks.length),color:"teal"})]})]}),k&&(null==n?void 0:n.traceHopDetail)&&t.jsx(Fe,{hops:n.traceHopDetail})]})})]}),C&&t.jsx("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:t.jsxs("div",{className:"ml-3",children:[t.jsx(Q,{label:"mode",children:t.jsx(fe,{options:S,nextFn:"queueDecryption()"})}),t.jsx(Q,{label:"result",children:t.jsx(se,{fn:"decrypt",value:D?"decrypted":r?"failed":"pending",color:D?"teal":r?"red":"zinc"})}),D&&t.jsx("div",{className:"mt-1 flex flex-wrap gap-x-1.5 gap-y-1",children:_.map((e,s)=>t.jsx("span",{className:"inline-block border border-edge-subtle rounded px-1.5 py-0.5",children:t.jsx(se,{fn:e.fn,value:e.value,color:e.color})},s))})]})}),(()=>{const e=[{fn:"topology.edges",value:String(i),group:"worker",color:"green"},{fn:"topology.ghostNodes",value:String(d),group:"worker",color:"purple"},{fn:"sparkline.nodes",value:`${v}`,group:"worker",color:"green"},...u?[{fn:"trace.directedLinks",value:String(p.totalDirectedLinks),group:"worker",color:"teal"},{fn:"trace.meanSnr",value:`${p.meanSnr.toFixed(1)} dB`,group:"worker",color:"teal"}]:[],..._];return t.jsx(Y,{tokens:e})})()]})})})}function Ee({packet:s,pipeline:r,resolved:n,resolveTimeMs:a,advertName:l,neighbors:o,decrypted:c}){var i,d;const p=I(e=>e.neighborContext),u=I(e=>e.topologyProfiles),h=I(e=>e.config),{analysis:f}=r,v=n??{hash:null,type:"unknown",name:null,confident:!1},y=s.src_hash?D(s.src_hash):"",j=y?p.prefixIndex.get(y)??[]:[],N=y?u.get(y)??[]:[],k=f.pType??-1,w=k>=0?k.toString(16).toUpperCase().padStart(2,"0"):"??",C=f.inferredType,S=f.advertType,_=f.effectiveType,H=null!=s._advertNodeType?s._advertNodeType.toString(16).padStart(2,"0").toUpperCase():"",T=(null==(i=null==c?void 0:c.decoded)?void 0:i.senderName)??null,$=function(e,t,s,r){var n;const a=e.src_hash?D(e.src_hash):"";if(e._advertSender&&t.hash&&t.confident)return{tier:1,label:"_advertSender → pubkey",detail:"ADVERT carried full 32-byte public key — definitive match"};if(r&&t.confident&&(null==(n=t.name)?void 0:n.toLowerCase())===r.toLowerCase())return{tier:1.5,label:"decrypt.senderName → nameToHash",detail:`Decrypted sender name “${r}” matched neighbor — high-confidence`};if(a&&s.crossClassPrefixes.has(a))return{tier:2,label:"cross-class prefix",detail:"Prefix has mixed types (repeater + non-repeater); payload type narrows to one class"};if(t.confident){const e=s.prefixIndex.get(a);return 1===(null==e?void 0:e.length)?{tier:3,label:"single candidate",detail:"Only one node matches this prefix — unambiguous"}:{tier:3,label:"resolver",detail:"Multi-signal scoring selected best candidate from collision set"}}return{tier:4,label:"ambiguous",detail:"Cannot confidently resolve — multiple same-class candidates, insufficient scoring separation"}}(s,v,p,T),P=e.useMemo(()=>function(e,t){const s=e.original_path??e.forwarded_path,r=new Set;if(s&&Array.isArray(s))for(const n of s){const e=String(n).toUpperCase().slice(0,2);e.length>=2&&e!==t&&r.add(e)}return r}(s,y),[s,y]),L=f.pathLen,M=e.useMemo(()=>function(e,t,s,r,n,a,l){const o=Math.floor(Date.now()/1e3),c=new Map(s.map(e=>[e.hash,e]));return e.map(e=>{const s=t[e.hash],i=c.get(e.hash);let d=!0,p="";"unknown"!==r?"unknown"!==e.type&&e.type!==r?(d=!1,p=`${e.type} ≠ required ${r}`):p=e.type===r?"type matches":"type unknown — not ruled out":p="payload ambiguous — all types eligible";const u=!!(null==s?void 0:s.zero_hop),h=(null==s?void 0:s.last_seen)??0;let x=0;if(u&&h>0){const e=(o-h)/3600;x=50*Math.exp(-e/l)}let m=0;if(h>0){const e=(o-h)/3600;m=Math.exp(-e/a)}const g=20*m,f=!(!(null==s?void 0:s.latitude)||!(null==s?void 0:s.longitude)||0===s.latitude&&0===s.longitude),v=f?5:0,b=(null==i?void 0:i.advertCount)??0,y=Math.min(2*b,30),j=(null==i?void 0:i.forwarderPrefixes.size)??0,N=Math.min(3*j,15);let k=0;if(i&&i.totalForwarderObservations>0&&n.size>0){let e=0;for(const t of n)i.forwarderPrefixes.has(t)&&e++;k=e/n.size}const w=x+g+v+y+N;return{hash:e.hash,name:e.name,type:e.type,roleCompatible:d,roleReason:p,zeroHop:u,zeroHopScore:x,lastSeen:h,recencyScore:m,recencyPoints:g,hasGps:f,gpsScore:v,advertCount:b,advertScore:y,topoWidth:j,topoScore:N,affinity:k,total:w}}).sort((e,t)=>t.total-e.total)}(j,o,N,_,P,h.recencyDecayHours,h.zeroHopDecayHours),[j,o,N,_,P,h.recencyDecayHours,h.zeroHopDecayHours]),F=M.filter(e=>!e.roleCompatible),R=M.filter(e=>e.roleCompatible),A=s._advertSender?p.pubKeyMap.get(s._advertSender)??null:null,z=1===$.tier,E=[{fn:"src_hash",value:y||"",active:!!y,color:"blue"},{fn:"_advertSender",value:s._advertSender?s._advertSender.slice(0,12)+"…":"",active:!!s._advertSender,color:"blue"},{fn:"_advertNodeType",value:H?`0x${H}`:"",active:null!=s._advertNodeType,color:"blue"},{fn:"path_length",value:null!=L?0===L?"zero-hop":String(L):"",active:null!=L,color:"blue"},{fn:"decrypt.senderName",value:T??"",active:!!T,color:"teal"}],B=[{label:"hit",detail:"pubKeyMap.get(_advertSender) → definitive",active:!!A,color:"green"},{label:"miss",detail:s._advertSender?"pubkey not in neighbor table":"no _advertSender",active:!A,color:"zinc"}],O=[{label:"payload",detail:`inferDeviceType(0x${w}) → ${C}`,active:"unknown"!==C,color:"amber"},{label:"flags",detail:H?`mapAdvertTypeCode(0x${H}) → ${S}`:"no _advertNodeType",active:"unknown"===C&&"unknown"!==S,color:"green"},{label:"ambiguous",detail:"all types eligible",active:"unknown"===_,color:"zinc"}],V=`→ ${v.name??(null==(d=v.hash)?void 0:d.slice(0,12))??"?"} (${v.confident?"confident":"ambiguous"}, Tier ${$.tier})`;return t.jsx(ye,{stage:3,name:"RESOLVE",fn:"usePipelineStore.resolveSource()",verdict:V,timeMs:a,children:t.jsx(Z,{prefix:"resolvePacketSource",children:t.jsxs("div",{className:"space-y-0",children:[t.jsx("div",{className:"pt-1 pb-1",children:t.jsx(ve,{tokens:E,nextFn:"resolvePacketSource()"})}),s.src_hash?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"1"})," ","PUBKEY LOOKUP"]}),t.jsx(fe,{options:B,nextFn:"pubKeyMap.get()"}),t.jsx("div",{className:"ml-3 mt-1",children:A?t.jsxs(t.Fragment,{children:[t.jsx(Q,{label:"resolved",children:t.jsx(se,{fn:"hash",value:A,color:"green"})}),l&&t.jsxs(Q,{label:"name",children:[t.jsx(se,{fn:"name",value:l,color:"green"}),v.name&&l===v.name&&t.jsx(ae,{c:"text-sys-green ml-1",children:"✓ neighbor match"})]}),t.jsxs(Q,{label:"result",children:[t.jsx(b,{color:"green",children:"Tier 1"}),t.jsx(ae,{c:"text-fg-primary ml-1",children:"definitive — scoring bypassed"})]})]}):s._advertSender?t.jsx(Q,{label:"status",children:t.jsx(ae,{c:"text-sys-amber",children:"✗ pubkey not in neighbor table"})}):t.jsx(Q,{label:"status",children:t.jsx(ae,{children:"no _advertSender — skip to prefix resolution"})})})]}),z?t.jsx("div",{className:"border-t border-edge-subtle py-2",children:t.jsx("p",{className:"text-[11px] text-fg-muted/40 font-mono ml-3",children:"Steps 2–5 bypassed — pubkey definitive"})}):t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"2"})," ","CANDIDATE POOL — ",j.length," node",1!==j.length?"s":"",' match "',y,'"']}),t.jsxs("div",{className:"space-y-0.5 ml-3",children:[M.map(e=>t.jsxs("div",{className:"flex gap-2 items-center text-[11px]",children:[t.jsx("span",{className:"break-all text-[10px]",children:e.hash}),t.jsx(b,{color:"zinc",children:e.type||"unknown"}),e.name&&t.jsx(ae,{children:e.name})]},e.hash)),0===j.length&&t.jsx(ae,{children:"no known nodes for this prefix"})]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"3"})," ","TYPE INFERENCE"]}),t.jsx(fe,{options:O,nextFn:"effectiveType()"}),t.jsx("div",{className:"ml-3 mt-1",children:t.jsx(Q,{label:"effective",children:t.jsx(se,{fn:"effectiveType",value:_,color:"unknown"!==_?"unknown"!==C?"amber":"green":"zinc"})})})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"4"})," ","ROLE-TYPE SCRUB"]}),t.jsx("div",{className:"space-y-0.5 ml-3",children:M.map(e=>t.jsxs("div",{className:"flex gap-2 items-center text-[11px]",children:[t.jsx("span",{className:e.roleCompatible?"text-sys-green":"text-sys-red",children:e.roleCompatible?"✓":"✗"}),t.jsx("span",{className:"break-all text-[10px] "+(e.roleCompatible?"":"line-through text-fg-muted"),children:e.hash}),t.jsx(b,{color:e.roleCompatible?"zinc":"red",children:e.type||"unknown"}),t.jsx(ae,{c:e.roleCompatible?"text-fg-muted":"text-sys-red",children:e.roleReason})]},e.hash))}),F.length>0&&t.jsxs("p",{className:"text-[10px] text-fg-muted mt-1 ml-3",children:[F.length," eliminated, ",R.length," surviving"]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-blue font-bold",children:"5"})," ","CANDIDATE SCORING"]}),0===R.length?t.jsx("p",{className:"text-fg-muted italic ml-3",children:"No surviving candidates"}):1===R.length?t.jsxs("div",{className:"ml-3 text-[11px]",children:[t.jsxs("div",{className:"flex gap-2 items-center",children:[t.jsx(ae,{c:"text-sys-green",children:"→"}),t.jsx("span",{className:"break-all text-[10px]",children:R[0].hash}),R[0].name&&t.jsx(ae,{c:"text-fg-muted ml-1",children:R[0].name})]}),t.jsx("p",{className:"text-fg-muted ml-4",children:"single survivor — scoring not needed"})]}):t.jsxs(x,{children:[t.jsx(m,{className:"text-[10px] ml-3",children:t.jsxs("span",{className:"font-mono text-fg-muted/50",children:[R.length," candidates scored…"]})}),t.jsx(g,{children:t.jsx("div",{className:"space-y-2 ml-3 mt-1",children:R.map(e=>{const s=e.hash===v.hash;return t.jsxs("div",{className:"text-[11px] leading-relaxed rounded px-2 py-1 "+(s?"bg-sys-green/8 border border-sys-green/20":"bg-zinc-500/5"),children:[t.jsxs("div",{className:"flex gap-2 items-center mb-0.5",children:[t.jsx(ae,{c:s?"text-sys-green":"text-fg-muted",children:s?"→":" "}),t.jsx("span",{className:"break-all text-[10px] "+(s?"text-fg-primary":"text-fg-muted"),children:e.hash}),t.jsx(b,{color:s?"green":"zinc",children:e.type||"unknown"}),e.name&&t.jsx(ae,{children:e.name})]}),t.jsxs("div",{className:"ml-4 flex flex-wrap gap-x-3 gap-y-0.5",children:[t.jsxs("span",{children:[t.jsx(ae,{children:"zero_hop:"})," ",t.jsx(ae,{c:e.zeroHop?"text-sys-green":"text-fg-muted",children:e.zeroHop?"✓":"✗"})," ",t.jsxs(b,{color:oe(e.zeroHopScore),children:["+",e.zeroHopScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"recency:"})," ",t.jsx(ae,{c:"text-fg-primary",children:ce(e.lastSeen)})," ",t.jsxs(b,{color:oe(e.recencyPoints),children:["+",e.recencyPoints.toFixed(1)]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"gps:"})," ",t.jsx(ae,{c:e.hasGps?"text-sys-green":"text-fg-muted",children:e.hasGps?"✓":"✗"})," ",t.jsxs(b,{color:oe(e.gpsScore),children:["+",e.gpsScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"adverts:"})," ",t.jsx(ae,{c:"text-fg-primary",children:e.advertCount})," ",t.jsxs(b,{color:oe(e.advertScore),children:["+",e.advertScore]})]}),t.jsxs("span",{children:[t.jsx(ae,{children:"topo:"})," ",t.jsx(ae,{c:"text-fg-primary",children:e.topoWidth})," ",t.jsxs(b,{color:oe(e.topoScore),children:["+",e.topoScore]})]})]}),t.jsxs("div",{className:"ml-4 mt-0.5",children:[t.jsx(ae,{children:"score ≈"})," ",t.jsx(ae,{c:"text-fg-primary font-bold",children:e.total.toFixed(1)})]})]},e.hash)})})})]})]})]}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:[t.jsxs("p",{className:"text-fg-muted mb-1",children:[t.jsx(ae,{c:"text-sys-green font-bold",children:"✓"})," ","RESOLUTION"]}),t.jsxs("div",{className:"ml-3",children:[t.jsx(Q,{label:"hash",children:v.hash?t.jsx(se,{fn:"resolved.hash",value:v.hash,color:"green"}):t.jsx(ae,{children:"null"})}),t.jsx(Q,{label:"type",children:t.jsx(se,{fn:"resolved.type",value:v.type,color:v.confident?"green":"zinc"})}),t.jsx(Q,{label:"name",children:v.name?t.jsx(se,{fn:"resolved.name",value:v.name,color:v.confident?"green":"amber"}):t.jsx(ae,{children:"null"})}),t.jsx(Q,{label:"confident",children:t.jsx(ae,{c:v.confident?"text-sys-green":"text-sys-red",children:String(v.confident)})}),t.jsxs(Q,{label:"tier",children:[t.jsx(b,{color:$.tier<=2?"green":3===$.tier?"amber":"red",children:$.tier}),t.jsx(ae,{c:"text-fg-primary ml-1",children:$.label})]})]})]})]}):t.jsx("div",{className:"border-t border-edge-subtle pt-2 pb-2",children:t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] font-mono",children:[t.jsx(ae,{c:"text-sys-amber",children:"⚠ no src_hash"}),T&&t.jsx(se,{fn:"decrypt.senderName",value:T,color:"teal"}),v.confident?t.jsxs(ae,{c:"text-sys-green",children:["→ resolved via ",$.label]}):t.jsx(ae,{c:"text-sys-red",children:"ambiguous"})]})}),(()=>{const e=[{fn:"resolved.hash",value:v.hash??"null",group:"resolution",color:v.confident?"green":"zinc"},{fn:"resolved.type",value:v.type,group:"resolution",color:"unknown"!==v.type?v.confident?"green":"amber":"zinc"},{fn:"resolved.name",value:v.name??"null",group:"resolution",color:v.confident?"green":v.name?"amber":"zinc"},{fn:"resolved.confident",value:String(v.confident),group:"resolution",color:v.confident?"green":"red"}];return t.jsx(Y,{tokens:e})})()]})})})}const Be=[{id:"packet-parse",label:"Packet Parse",inputs:["rawPacket"],outputs:["parsedPacket","decoded","headerFields"],emits:[{fn:"routeType",group:"wire",color:"blue"},{fn:"payloadType",group:"wire",color:"blue"},{fn:"pathLength",group:"wire",color:"blue"},{fn:"version",group:"wire",color:"blue"}],async:!1,observatoryStage:0},{id:"enrichment",label:"Ingestion Enrichment",inputs:["parsedPacket"],outputs:["advertSender","channelHash","hopData","byteLength"],emits:[{fn:"_advertSender",group:"enrichment",color:"blue"},{fn:"_advertNodeType",group:"enrichment",color:"blue"},{fn:"_channelHash",group:"enrichment",color:"blue"},{fn:"_hopCount",group:"enrichment",color:"blue"},{fn:"_isZeroHop",group:"enrichment",color:"blue"},{fn:"_byteLength",group:"enrichment",color:"blue"}],async:!1,observatoryStage:1},{id:"topology",label:"Topology Analysis",inputs:["packets","neighbors","srcHashResolver"],outputs:["edges","nodeMetrics","pathHealth","ghostNodes","centrality","loops"],emits:[{fn:"edges",group:"worker",color:"green"},{fn:"ghostNodes",group:"worker",color:"purple"},{fn:"loops",group:"analysis",color:"amber"},{fn:"nodeMetrics",group:"worker",color:"green"},{fn:"pathHealth",group:"worker",color:"green"},{fn:"centrality",group:"worker",color:"green"}],async:!0,worker:"topology.worker.ts",observatoryStage:2},{id:"trace-enrichment",label:"Trace Link Quality",inputs:["packets","prefixLookup","srcHashResolver","edges","pathHealth","nodeMetrics"],outputs:["traceLinks","traceLinkSummary","traceDisambiguationFeedback"],emits:[{fn:"traceLinks.directed",group:"worker",color:"teal"},{fn:"traceLinks.bidir",group:"worker",color:"teal"},{fn:"traceSummary.meanSnr",group:"analysis",color:"green"},{fn:"traceSummary.medianSnr",group:"analysis",color:"zinc"},{fn:"traceSummary.confidence",group:"analysis",color:"zinc"},{fn:"feedback.confirmed",group:"worker",color:"teal"},{fn:"feedback.links",group:"worker",color:"teal"}],async:!1,observatoryStage:2},{id:"disambiguation",label:"Source Disambiguation",inputs:["packets","neighbors","decodedMessages"],outputs:["srcHashResolverMap","neighborContext"],emits:[{fn:"resolvedHash",group:"resolution",color:"purple"},{fn:"resolvedName",group:"resolution",color:"purple"},{fn:"resolvedType",group:"resolution",color:"purple"},{fn:"confidence",group:"resolution",color:"green"}],async:!1,observatoryStage:3},{id:"sparkline",label:"Sparkline Computation",inputs:["packets","neighbors"],outputs:["sparklineData"],emits:[{fn:"sparklines",group:"worker",color:"blue"}],async:!0,worker:"sparkline.worker.ts"},{id:"decryption",label:"Channel Decryption",inputs:["packets","channelKeys"],outputs:["decodedMessages"],emits:[{fn:"decrypt.text",group:"crypto",color:"teal"},{fn:"decrypt.senderName",group:"crypto",color:"teal"},{fn:"decrypt.channelName",group:"crypto",color:"teal"},{fn:"decrypt.macCorrupted",group:"crypto",color:"amber"}],async:!0,worker:"decryption.worker.ts",observatoryStage:2},{id:"decoded-content",label:"Decoded Content Policy",inputs:["decodedMessages","packets"],outputs:["decodedContent","contentInheritance"],emits:[{fn:"content.senderName",group:"crypto",color:"teal"},{fn:"content.text",group:"crypto",color:"teal"},{fn:"content.channelName",group:"crypto",color:"teal"},{fn:"content.corrupted",group:"crypto",color:"amber"},{fn:"content.inherited",group:"analysis",color:"purple"}],async:!1}],Oe=new Map(Be.map(e=>[e.id,e])),Ve=new Map;for(const pt of Be)for(const e of pt.emits)Ve.set(e.fn,pt);const Ie=new Map;for(const pt of Be)for(const e of pt.outputs)Ie.set(e,pt);const Ue={0:"text-sys-green",1:"text-sys-blue",2:"text-sys-teal",3:"text-sys-purple"};function qe({stage:e,isActive:s,onClick:r}){const n=null!=e.observatoryStage?Ue[e.observatoryStage]??"text-fg-muted":"text-fg-muted/40";return t.jsxs("button",{type:"button",onClick:r,className:`\n flex items-center gap-1.5 w-full px-1.5 py-1 rounded transition-base text-left\n ${s?"bg-sys-blue/10 ring-1 ring-sys-blue/30":"hover:bg-zinc-500/5"}\n `,children:[t.jsx("span",{className:`font-mono text-[9px] font-bold w-3 shrink-0 text-center ${n}`,children:e.observatoryStage??"·"}),t.jsx("span",{className:"font-mono text-[9px] text-fg-primary truncate flex-1",children:e.label}),e.async&&t.jsx("span",{className:"font-mono text-[7px] px-1 py-px rounded bg-sys-amber/15 text-sys-amber shrink-0 leading-tight",children:"⚡"}),e.emits.length>0&&t.jsxs("span",{className:"flex items-center gap-px shrink-0",children:[e.emits.slice(0,6).map(e=>{var s;return t.jsx("span",{className:`inline-block w-1 h-1 rounded-full ${(null==(s=W[e.color])?void 0:s.dot)??"bg-zinc-500"}`,title:`${e.fn} [${e.group}]`},e.fn)}),e.emits.length>6&&t.jsxs("span",{className:"font-mono text-[7px] text-fg-muted/40 ml-0.5",children:["+",e.emits.length-6]})]})]})}function Ge({activeStageId:s,onStageClick:r}){const n=e.useMemo(()=>function(){const e=new Map,t=new Map;for(const n of Be)e.has(n.id)||e.set(n.id,0),t.has(n.id)||t.set(n.id,new Set);for(const n of Be)for(const s of n.inputs){const r=Ie.get(s);if(r&&r.id!==n.id){const s=t.get(r.id);s.has(n.id)||(s.add(n.id),e.set(n.id,(e.get(n.id)??0)+1))}}const s=[];for(const[n,a]of e)0===a&&s.push(n);const r=[];for(;s.length>0;){const n=s.shift(),a=Oe.get(n);a&&r.push(a);for(const r of t.get(n)??[]){const t=(e.get(r)??1)-1;e.set(r,t),0===t&&s.push(r)}}for(const n of Be)r.includes(n)||r.push(n);return r}(),[]),a=e.useMemo(()=>{const e=new Map;for(const s of n){const t=s.observatoryStage??"other";let r=e.get(t);r||(r=[],e.set(t,r)),r.push(s)}const t=[];for(const s of[0,1,2,3,"other"]){const r=e.get(s);(null==r?void 0:r.length)&&t.push({key:s,stages:r})}return t},[n]);return t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-2",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[t.jsx("span",{className:"font-mono text-[8px] text-fg-muted/40 uppercase tracking-widest",children:"Pipeline DAG"}),t.jsxs("span",{className:"font-mono text-[8px] text-fg-muted/30",children:[n.length," stages"]})]}),t.jsx("div",{className:"space-y-px",children:a.map((e,n)=>t.jsxs("div",{children:[n>0&&t.jsx("div",{className:"flex items-center pl-2.5 py-px",children:t.jsx("svg",{width:"6",height:"8",viewBox:"0 0 6 8",className:"text-fg-muted/20",children:t.jsx("path",{d:"M3 0 L3 6 M1 4 L3 6 L5 4",fill:"none",stroke:"currentColor",strokeWidth:"1"})})}),e.stages.map(e=>t.jsx(qe,{stage:e,isActive:s===e.id,onClick:r?()=>r(e.id):void 0},e.id))]},String(e.key)))})]})}const Ke={status:"idle",lastDurationMs:null,lastTs:null,runCount:0};function We(e,t,s){var r,n,a;switch(e.type){case"transport:ws:state":t.wsState=(null==(r=e.data)?void 0:r.state)??s.wsState;break;case"transport:ws:packet":t.wsPacketCount=(t.wsPacketCount??s.wsPacketCount)+1;break;case"transport:ws:stats":t.wsStatsCount=(t.wsStatsCount??s.wsStatsCount)+1;break;case"transport:rest:stats":t.restStatsCount=(t.restStatsCount??s.restStatsCount)+1;break;case"transport:rest:packets":t.restPacketsCount=(t.restPacketsCount??s.restPacketsCount)+1;break;case"store:packets:ws-merge":t.wsMergeCount=(t.wsMergeCount??s.wsMergeCount)+1;break;case"cascade:hydrate":t.lastHydrateTs=e.ts,t.hydrateCount=(t.hydrateCount??s.hydrateCount)+1;break;case"worker:topology:start":case"worker:sparkline:start":{const r=e.type.split(":")[1],n=t.workers??s.workers,a=n[r]??{...Ke};t.workers={...n,[r]:{...a,status:"running",lastTs:e.ts}}}break;case"worker:topology:done":case"worker:sparkline:done":{const r=e.type.split(":")[1],a=t.workers??s.workers,l=a[r]??{...Ke},o=(null==(n=e.data)?void 0:n.ms)??null;t.workers={...a,[r]:{...l,status:"done",lastDurationMs:o,lastTs:e.ts,runCount:l.runCount+1}}}break;case"worker:decryption:batch":{const r=t.workers??s.workers,n=r.decryption??{...Ke},l=(null==(a=e.data)?void 0:a.ms)??null;t.workers={...r,decryption:{...n,status:"done",lastDurationMs:l,lastTs:e.ts,runCount:n.runCount+1}}}break;case"pipeline:disambig:recompute":t.disambigCount=(t.disambigCount??s.disambigCount)+1}}const Ze=pe(e=>({events:[],eventCount:0,wsState:"disconnected",wsPacketCount:0,wsStatsCount:0,restStatsCount:0,restPacketsCount:0,workers:{topology:{...Ke},sparkline:{...Ke},decryption:{...Ke}},wsMergeCount:0,lastHydrateTs:null,hydrateCount:0,disambigCount:0,lastDisambigMs:null,_pushBatch:t=>e(e=>{if(0===t.length)return e;let s=[...e.events,...t];s.length>200&&(s=s.slice(s.length-200));const r={events:s,eventCount:e.eventCount+t.length};for(const n of t)We(n,r,e);return r}),clear:()=>e({events:[],eventCount:0,wsState:"disconnected",wsPacketCount:0,wsStatsCount:0,restStatsCount:0,restPacketsCount:0,workers:{topology:{...Ke},sparkline:{...Ke},decryption:{...Ke}},wsMergeCount:0,lastHydrateTs:null,hydrateCount:0,disambigCount:0,lastDisambigMs:null})}));let Ye=null,Xe=[],Qe=null;function Je(){if(Qe=null,0===Xe.length)return;const e=Xe;Xe=[],Ze.getState()._pushBatch(e)}function et(e){switch(e){case"active":return"●";case"skipped":return"○";case"inferred":return"◌"}}function tt(e){switch(e){case"active":return"text-sys-green";case"skipped":return"text-fg-muted/30";case"inferred":return"text-sys-amber"}}function st(e){switch(e){case"transport":return"text-sys-blue";case"store":return"text-sys-amber";case"worker":return"text-sys-violet";case"pipeline":return"text-sys-green";case"consumer":return"text-sys-teal"}}const rt=[],nt=["transport","store","worker","pipeline","consumer"],at={transport:"Transport",store:"Store",worker:"Workers",pipeline:"Pipeline",consumer:"Consumers"};function lt(e){return e.replace("transport:","").replace("store:packets:","").replace("cascade:","").replace("worker:","w:").replace("pipeline:","p:").replace("packet","pkt").replace("sparkline","spark").replace("topology","topo").replace("decryption","dec").replace("disambig","dis").replace("recompute","recomp")}const ot=e.memo(function({event:e}){const s=`${(e.ts/1e3).toFixed(1)}s`,r=e.data?Object.entries(e.data).map(([e,t])=>{var s;return`${e}=${"number"==typeof t?(null==(s=t.toFixed)?void 0:s.call(t,1))??t:t}`}).join(" "):"";return t.jsxs("div",{className:"flex gap-2 text-[9px] font-mono leading-tight",children:[t.jsx("span",{className:"text-fg-muted/40 w-12 shrink-0 text-right",children:s}),t.jsx("span",{className:"w-20 shrink-0 "+(n=e.type,n.startsWith("transport:")?"text-sys-blue":n.startsWith("store:")||n.startsWith("cascade:")?"text-sys-amber":n.startsWith("worker:")?"text-sys-violet":n.startsWith("pipeline:")?"text-sys-green":"text-fg-muted"),children:lt(e.type)}),t.jsx("span",{className:"text-fg-muted/60 truncate",children:r})]});var n});function ct({packet:s,pipeline:r,resolved:n,decrypted:a,isSynthetic:l,liveMode:o}){const[c,i]=e.useState(!1);e.useEffect(()=>{if(c)return Ye||(Xe=[],Ye=F.subscribe(e=>{Xe.push(e),null===Qe&&(Qe=requestAnimationFrame(Je))})),()=>{!function(){if(null==Ye||Ye(),Ye=null,null!==Qe&&(cancelAnimationFrame(Qe),Qe=null),Xe.length>0){const e=Xe;Xe=[],Ze.getState()._pushBatch(e)}}()}},[c]);const d=null==r?void 0:r.analysis,p=e.useMemo(()=>s&&d?function(e,t,s,r,n){var a,l;const o=[];if(n?o.push({label:"Hex Input",detail:"Manual hex — no transport",status:"skipped",lane:"transport"}):"live"===t.age||"recent"===t.age?o.push({label:"WebSocket",detail:"ws:packet → real-time push",status:"active",lane:"transport"}):o.push({label:"REST Poll",detail:"fetchPackets → packetCache.poll()",status:"inferred",lane:"transport"}),!n){o.push({label:"Cache Merge",detail:"packetCache.mergePacketsDirectly()",status:"active",lane:"store"});const e="live"===t.age||"recent"===t.age;o.push({label:"Flash",detail:e?"flashReceived++ → sidebar blink":"Not newest — no flash",status:e?"active":"skipped",lane:"store"}),o.push({label:"Hydrate Cascade",detail:"hydrateDownstream() → schedule workers",status:"active",lane:"store"})}const c=t.pathAvail||t.pathHopCount>0;o.push({label:"Topology Worker",detail:c?`Path data (${t.pathHopCount} hops) → edge extraction`:"No path data — still included in batch recompute",status:"active",lane:"worker"}),o.push({label:"Sparkline Worker",detail:`Contributes to sparkline for src ${(null==(a=e.src_hash)?void 0:a.slice(0,4))??"??"}`,status:"active",lane:"worker"});const i=t.isGrp;o.push({label:"Decryption Worker",detail:i?"GRP_TXT → queued for channel key search"+(r?" → decrypted ✓":""):`${t.payloadTypeName} — not encrypted, skipped`,status:i?"active":"skipped",lane:"worker"}),o.push({label:"Source Disambiguation",detail:s?`→ ${s.name??(null==(l=s.hash)?void 0:l.slice(0,8))??"?"} (${s.type}${s.confident?", confident":", ambiguous"})`:"Pending recompute",status:s?"active":"inferred",lane:"pipeline"}),t.isAdvert&&o.push({label:"ADVERT Discovery",detail:"pubkey → extended hash-to-type + name extraction",status:"active",lane:"pipeline"}),i&&(null==r?void 0:r.decoded)&&o.push({label:"Decoded Content Policy",detail:`macCorrupted=${r.decoded.macCorrupted?"true":"false"} → cross-hash inheritance`,status:"active",lane:"pipeline"});const d=["Packets","Dashboard","Statistics"];return c&&d.push("Map","Graph"),t.isTrace&&d.push("Trace Detail"),o.push({label:"Page Hydration",detail:d.join(", "),status:"active",lane:"consumer"}),o}(s,d,n,a,l):null,[s,d,n,a,l]),u=e.useMemo(()=>{if(!p)return null;const e=new Map;for(const t of p){let s=e.get(t.lane);s||(s=[],e.set(t.lane,s)),s.push(t)}return e},[p]),h=Ze(e=>c?e.events:rt),f=Ze(e=>c?e.eventCount:0),v=Ze(e=>e.clear),b=e.useRef(null);e.useEffect(()=>{c&&b.current&&(b.current.scrollTop=b.current.scrollHeight)},[f,c]);const y=(null==p?void 0:p.filter(e=>"active"===e.status).length)??0,j=(null==p?void 0:p.length)??0;return t.jsxs(x,{defaultOpen:!0,children:[t.jsx(m,{className:"text-[10px]",children:t.jsxs("span",{className:"flex items-center gap-2 font-mono",children:[t.jsx("span",{className:"text-sys-green",children:"CFT"}),t.jsx("span",{className:"text-fg-muted/40",children:"Control Flow Trace"}),s&&t.jsxs("span",{className:"text-fg-muted/30",children:["— ",y,"/",j," stages active"]})]})}),t.jsx(g,{children:t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3 space-y-3",children:[s?u?t.jsx("div",{className:"space-y-2",children:nt.map(e=>{const s=u.get(e);return s?t.jsxs("div",{children:[t.jsx("div",{className:`text-[8px] uppercase tracking-widest font-mono mb-0.5 ${st(e)}`,children:at[e]}),s.map((e,s)=>t.jsxs("div",{className:"flex items-start gap-1.5 text-[10px] font-mono leading-snug ml-1",children:[t.jsx("span",{className:`shrink-0 ${tt(e.status)}`,children:et(e.status)}),t.jsx("span",{className:"text-fg-primary",children:e.label}),t.jsx("span",{className:"text-fg-muted/50 truncate",children:e.detail})]},s))]},e):null})}):null:t.jsx("div",{className:"text-[9px] text-fg-muted/30 font-mono py-2 text-center",children:"Select a packet to trace its flow"}),t.jsxs("div",{className:"border-t border-edge-subtle pt-2 flex items-center gap-2",children:[t.jsx("button",{onClick:()=>i(e=>!e),className:"px-2 py-0.5 rounded text-[9px] font-mono transition-colors "+(c?"bg-sys-green/20 text-sys-green":"bg-zinc-500/20 text-fg-muted hover:text-fg-primary"),children:c?"● LIVE":"○ LIVE"}),t.jsx("span",{className:"text-[9px] text-fg-muted/40 font-mono",children:c?`${f} events`:"Subscribe to all pipeline events"}),c&&t.jsx("button",{onClick:v,className:"text-[9px] text-fg-muted/40 hover:text-fg-muted font-mono transition-colors ml-auto",children:"clear"})]}),c&&t.jsx("div",{ref:b,className:"max-h-32 overflow-y-auto space-y-px",children:0===h.length?t.jsx("div",{className:"text-[9px] text-fg-muted/30 font-mono py-1 text-center",children:"Waiting for events…"}):h.map((e,s)=>t.jsx(ot,{event:e},`${e.ts}-${s}`))})]})})]})}function it(e){const t=u(e.type??e.payload_type??-1).padEnd(7),s=e.packet_hash.slice(0,8),r=(e.src_hash??"—").replace(/^0x/i,"").slice(0,4).toUpperCase(),n=null!=e._hopCount?`${e._hopCount}h`:"",a=B(e.timestamp);return`${s} ${t} ←${r} ${e.rssi}dBm ${n} ${a}`}function dt(){const s=R(),r=A(),n=z(),a=(null==r?void 0:r.neighbors)??{},l=I(e=>e.resolveSource),o=I(e=>e.config),c=I(e=>e.setConfig),[i,d]=e.useState(-1),p=e.useMemo(()=>{let e=s;return-1!==i&&(e=s.filter(e=>(e.type??e.payload_type)===i)),e.slice(-50).reverse()},[s,i]),[u,h]=e.useState(""),[f,v]=e.useState(""),[b,y]=e.useState(!1),N=e.useRef(n);e.useEffect(()=>{b&&n!==N.current&&p.length>0&&(h(p[0].packet_hash),v("")),N.current=n},[n,b,p]),e.useEffect(()=>{!u&&p.length>0&&!f&&h(p[0].packet_hash)},[u,p,f]);const k=e.useMemo(()=>f.trim()?null:p.find(e=>e.packet_hash===u)??null,[u,p,f]),w=e.useMemo(()=>{const e=f.replace(/\s+/g,"").trim();return e?{packet_hash:"manual-hex-input",timestamp:0,rssi:0,snr:0,transmitted:!1,drop_reason:null,is_duplicate:!1,raw_packet:e}:null},[f]),C=k??w,S=!!f.trim(),_=f.trim().replace(/\s+/g,"")||(null==C?void 0:C.raw_packet),H=ge(C,_,s),T=(null==H?void 0:H.enrichment)??xe,$=j((null==C?void 0:C.packet_hash)??""),P=e.useRef(0),L=e.useMemo(()=>{if(!C)return null;const e=performance.now(),t=l(C);return P.current=performance.now()-e,t},[C,l]);return t.jsxs("div",{className:"max-w-[960px] mx-auto",children:[t.jsxs("div",{className:"mb-3",children:[t.jsx("h1",{className:"text-sm font-bold text-fg-primary tracking-wide font-mono",children:"PACKET OBSERVATORY"}),t.jsx("p",{className:"text-[11px] text-fg-muted font-mono",children:"Pipeline introspection — select a packet to trace its journey"})]}),t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3 mb-3",children:[t.jsxs("div",{className:"flex gap-2 items-center flex-wrap",children:[t.jsxs("select",{value:i,onChange:e=>{d(Number(e.target.value)),h("")},className:"surface-input px-2 py-1 rounded text-[11px] font-mono text-fg-primary w-36",children:[t.jsx("option",{value:-1,children:"ALL TYPES"}),Object.entries(E).map(([e,s])=>t.jsxs("option",{value:Number(e),children:["0x",Number(e).toString(16).toUpperCase().padStart(2,"0")," ",s]},e))]}),t.jsxs("select",{value:u,onChange:e=>{h(e.target.value),v("")},className:"surface-input flex-1 min-w-0 px-2 py-1 rounded text-[11px] font-mono text-fg-primary truncate",children:[p.map((e,s)=>t.jsx("option",{value:e.packet_hash,children:it(e)},`${e.packet_hash}-${s}`)),0===p.length&&t.jsxs("option",{value:"",children:["No packets",-1!==i?" matching filter":" loaded"]})]}),t.jsx("button",{onClick:()=>y(e=>!e),className:"px-2 py-1 rounded text-[11px] font-mono transition-colors shrink-0 "+(b?"bg-sys-green/20 text-sys-green":"bg-zinc-500/20 text-fg-muted hover:text-fg-primary"),children:b?"● LIVE":"○ LIVE"})]}),t.jsxs(x,{children:[t.jsx(m,{className:"text-[10px] text-fg-muted/50 hover:text-fg-muted mt-1.5",children:t.jsx("span",{className:"font-mono",children:"Paste hex…"})}),t.jsx(g,{children:t.jsx("textarea",{value:f,onChange:e=>v(e.target.value),placeholder:"Paste raw packet hex (overrides dropdown)",rows:2,className:"surface-input w-full mt-1 px-2 py-1 rounded text-[11px] font-mono text-fg-primary resize-y"})})]})]}),t.jsxs(x,{children:[t.jsx(m,{className:"text-[11px] mb-3 w-full",children:t.jsxs("span",{className:"flex items-center gap-2 font-mono",children:[t.jsx("span",{className:"text-fg-muted/50",children:"⚙"}),t.jsx("span",{className:"text-fg-muted/50",children:"Pipeline Config & Dev Tools"}),t.jsxs("span",{className:"text-fg-muted/30 text-[10px]",children:["disambig=",o.disambiguationEnabled?"on":"off"," mac=",o.macCorruptedPolicy," decay=",o.recencyDecayHours,"h"]})]})}),t.jsx(g,{children:t.jsxs("div",{className:"space-y-3 mb-4",children:[t.jsxs("div",{className:"surface-base rounded-lg border border-edge-subtle p-3",children:[t.jsx("h2",{className:"text-[10px] text-fg-muted/50 uppercase tracking-widest font-mono mb-2",children:"Pipeline Config"}),t.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1.5",children:[t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Disambiguation"}),t.jsx("button",{onClick:()=>c({disambiguationEnabled:!o.disambiguationEnabled}),className:"px-2 py-0.5 rounded text-[11px] font-mono transition-colors "+(o.disambiguationEnabled?"bg-sys-green/20 text-sys-green":"bg-sys-red/20 text-sys-red"),children:o.disambiguationEnabled?"● ON":"○ OFF"})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"MAC policy"}),t.jsxs("select",{value:o.macCorruptedPolicy,onChange:e=>c({macCorruptedPolicy:e.target.value}),className:"surface-input px-1.5 py-0.5 rounded text-[11px] font-mono text-fg-primary",children:[t.jsx("option",{value:"strict",children:"strict (drop)"}),t.jsx("option",{value:"name-only",children:"name-only"}),t.jsx("option",{value:"permissive",children:"permissive"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Recency decay"}),t.jsx("input",{type:"range",min:1,max:48,step:1,value:o.recencyDecayHours,onChange:e=>c({recencyDecayHours:Number(e.target.value)}),className:"flex-1 h-1 accent-sys-blue"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-primary w-8 text-right",children:[o.recencyDecayHours,"h"]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("label",{className:"text-[11px] text-fg-muted w-24 shrink-0",children:"Zero-hop decay"}),t.jsx("input",{type:"range",min:12,max:168,step:6,value:o.zeroHopDecayHours,onChange:e=>c({zeroHopDecayHours:Number(e.target.value)}),className:"flex-1 h-1 accent-sys-blue"}),t.jsxs("span",{className:"text-[11px] font-mono text-fg-primary w-10 text-right",children:[o.zeroHopDecayHours,"h"]})]})]})]}),t.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[t.jsx(ct,{packet:C,pipeline:H,resolved:L,decrypted:$??null,isSynthetic:S,liveMode:b}),t.jsx(Ge,{})]})]})})]}),C?t.jsxs("div",{className:"space-y-1",children:[t.jsx(Ne,{packet:C,isSynthetic:S}),t.jsx(Pe,{packet:C,pipeline:H,rawHex:_,traceTagIndex:(null==H?void 0:H.traceTagIndex)??new Map,neighbors:a}),t.jsx(ze,{packet:C,decrypted:$??void 0,pipeline:H}),t.jsx(Ee,{packet:C,pipeline:H,resolved:L,decrypted:$??void 0,resolveTimeMs:P.current,neighbors:a,advertName:T.advertName})]}):t.jsx("div",{className:"surface-base rounded-lg border border-edge-subtle p-8 text-center",children:t.jsx("p",{className:"text-fg-muted text-xs",children:"Select a packet from the dropdown or paste hex above"})})]})}export{dt as default}; diff --git a/frontend/dist/assets/Packets-BgwWZIr7.js b/frontend/dist/assets/Packets-DNzcKpej.js similarity index 93% rename from frontend/dist/assets/Packets-BgwWZIr7.js rename to frontend/dist/assets/Packets-DNzcKpej.js index 75a7a588..aaa39c87 100644 --- a/frontend/dist/assets/Packets-BgwWZIr7.js +++ b/frontend/dist/assets/Packets-DNzcKpej.js @@ -1 +1 @@ -import{r as e,j as a,H as s,k as l,B as t,U as i,f as r}from"./vendor-react-alRNW2nb.js";import{c as o}from"./vendor-core-FtpmsTnh.js";import{m as n,p as c,t as d,v as m,W as u,a1 as p,D as x,a3 as h,a4 as b,B as g,q as v,T as j}from"./index-D7i6lQrq.js";import{C as f,a as y,V as N,A as w,Q as S,o as k,U as C,Y as P,h as M,X as R}from"./vendor-icons-TO0PZKGR.js";import{g as L,u as D,P as F}from"./PacketList-BfWkNwPj.js";import{u as A,a as T}from"./usePipelineStore-D3dOwDkO.js";import{c as _,a as H,A as V}from"./AnalyzerFilterPanel-DfkXd7UH.js";import{u as z,r as B}from"./consumer-registry-KuOoZhsq.js";import{P as q,a as K,B as O,C as E}from"./PageLayout-QhCLxU34.js";import{T as G}from"./TimeRangeStepper-B5GfHny9.js";import{R as I}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./primitives-YN2ynYwE.js";import"./payload-decoders-DjZO58V7.js";import"./badge-colors-BxLppqaF.js";import"./chat-utils-DbM_TyxC.js";import"./SignalIndicator-fAt1Aewy.js";import"./DataBox-DpDXI-WX.js";import"./useMapViewStore-1yyjXCM8.js";import"./node-types-CiI69Tya.js";import"./geo-utils-DJn8DnxF.js";function U({options:r,value:n,onChange:c,defaultValue:d,displayValue:m,filter:u,placeholder:p,disabled:x,invalid:h,name:b,"aria-label":g,className:v,children:j}){const[y,N]=e.useState(""),w=m??(e=>null!=e?String(e):""),S=u??((e,a)=>w(e).toLowerCase().includes(a.toLowerCase())),k=e.useMemo(()=>y?r.filter(e=>S(e,y)):r,[r,y,S]);return a.jsx(s,{value:n,onChange:c,defaultValue:d,disabled:x,name:b,onClose:()=>N(""),children:a.jsxs("div",{className:o("relative",v),children:[a.jsxs("div",{className:"relative",children:[a.jsx(l,{"aria-label":g,displayValue:w,onChange:e=>N(e.target.value),placeholder:p,className:o(["w-full radius-inner py-2 pl-3 pr-10","text-sm text-fg-primary placeholder:text-fg-muted","bg-input-bg",h?"border border-sys-red":"border border-input-border","ring-focus-inset","hover:border-edge-strong","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-colors"])}),a.jsx(t,{className:"absolute inset-y-0 right-0 flex items-center pr-3 group",children:a.jsx(f,{className:"w-4 h-4 text-fg-muted transition-transform duration-200 group-data-[open]:rotate-180"})})]}),a.jsx(i,{anchor:"bottom start",transition:!0,className:o(["w-[var(--input-width)] min-w-[180px]","max-h-60 overflow-y-auto overscroll-contain scroll-py-1","radius-inset p-1 mt-1","surface-elevated","focus:outline-none","transition-opacity","data-[closed]:opacity-0","data-[enter]:duration-150 data-[leave]:duration-100","z-50"]),children:0===k.length&&""!==y?a.jsx("div",{className:"px-3 py-2 text-sm text-fg-muted",children:"No results found"}):k.map((s,l)=>a.jsx(e.Fragment,{children:j(s)},l))})]})})}function W({value:s,disabled:l,className:t,children:i}){return a.jsx(r,{as:e.Fragment,value:s,disabled:l,children:({selected:e,focus:s})=>a.jsxs("div",{className:o("flex items-center gap-2 px-3 py-2 radius-control cursor-default","text-sm",s&&"bg-sys-blue text-white",!s&&"text-fg-primary",e&&!s&&"text-sys-blue",l&&"opacity-50 cursor-not-allowed",t),children:[a.jsx("span",{className:"w-4 flex-shrink-0",children:e&&a.jsx(y,{className:"w-4 h-4"})}),a.jsx("span",{className:"truncate flex-1",children:i})]})})}function J({className:e,...s}){return a.jsx("span",{...s,className:o("truncate",e)})}function Q({value:e,onChange:s,options:l,placeholder:t,disabled:i,className:r,"aria-label":o}){const n=l.find(a=>a.value===e);return a.jsx(U,{options:l,value:n,onChange:e=>{e&&s(e.value)},displayValue:e=>(null==e?void 0:e.label)??"",filter:(e,a)=>e.label.toLowerCase().includes(a.toLowerCase()),placeholder:t,disabled:i,className:r,"aria-label":o,children:e=>a.jsx(W,{value:e,disabled:e.disabled,children:a.jsx(J,{children:e.label})})})}const Y=[{target:"PacketStats",fn:"type",minStage:1}];function X({icon:e,label:s,value:l,color:t,percentage:i}){return a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:o("p-1.5 rounded-md",t),children:e}),a.jsxs("div",{className:"flex flex-col",children:[a.jsx("span",{className:"text-sm font-semibold text-fg-primary",children:l.toLocaleString()}),a.jsxs("span",{className:"text-xs text-fg-muted leading-tight",children:[s,void 0!==i&&a.jsxs("span",{className:"ml-1 opacity-70",children:["(",i,"%)"]})]})]})]})}B(Y);const Z=e.memo(function({packets:s}){z(Y);const l=e.useMemo(()=>{let e=0,a=0,l=0;const t=new Set;let i=0,r=0;for(const c of s){switch(L(c)){case"forward":e++;break;case"dropped":a++;break;case"duplicate":l++}c.src_hash&&t.add(c.src_hash),c.rssi&&(i+=c.rssi,r++)}const o=s.length,n=r>0?Math.round(i/r):0;return{total:o,rx:o,fwd:e,dropped:a,duplicate:l,uniqueSources:t.size,avgRssi:n,rxPercent:100,fwdPercent:o>0?Math.round(e/o*100):0,droppedPercent:o>0?Math.round(a/o*100):0}},[s]);return 0===s.length?null:a.jsx("div",{className:"surface-base depth-raised rounded-2xl p-3 pr-4",children:a.jsxs("div",{className:"grid grid-cols-2 gap-3 sm:flex sm:items-center sm:justify-between sm:gap-6",children:[a.jsx(X,{icon:a.jsx(N,{className:"w-3.5 h-3.5 text-sys-blue"}),label:"Received",value:l.rx,color:"bg-sys-blue/10",percentage:l.rxPercent}),a.jsx(X,{icon:a.jsx(w,{className:"w-3.5 h-3.5 text-sys-green"}),label:"Forwarded",value:l.fwd,color:"bg-sys-green/10",percentage:l.fwdPercent}),a.jsx(X,{icon:a.jsx(S,{className:"w-3.5 h-3.5 text-sys-red"}),label:"Dropped",value:l.dropped,color:"bg-sys-red/10",percentage:l.droppedPercent}),a.jsx(X,{icon:a.jsx(k,{className:"w-3.5 h-3.5 text-fg-muted"}),label:"Duplicates",value:l.duplicate,color:"bg-subtle-fill"}),a.jsxs("div",{className:"hidden sm:flex items-center gap-6 ml-auto",children:[a.jsx(X,{icon:a.jsx(C,{className:"w-3.5 h-3.5 text-sys-indigo"}),label:"Sources",value:l.uniqueSources,color:"bg-sys-indigo/10"}),a.jsxs("div",{className:"flex flex-col items-end pr-1",children:[a.jsxs("span",{className:"type-data-sm text-fg-secondary",children:[l.avgRssi," dBm"]}),a.jsx("span",{className:"text-xs text-fg-muted",children:"Avg Signal"})]})]})]})})});function $(){const s=n(),l=c(),t=A(),i=D(e=>e.requestChannel),r=d(),f=null==l?void 0:l.local_hash,y=null==l?void 0:l.neighbors,N=m(),w=u(),S=p().isBackgroundLoading&&N>=5,[k,C]=e.useState(!1),[z,B]=e.useState(!0),U=e.useCallback(e=>B(e),[]),[W,J]=e.useState({limit:500,status:"all"}),[Y,X]=e.useState(_),$=e.useMemo(()=>{const e=Math.floor(Date.now()/1e3);return{start:e-60*x[N].minutes,end:e}},[N]),ee=e.useMemo(()=>{const e=(null==l?void 0:l.neighbors)??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!r.has(e)))},[null==l?void 0:l.neighbors,r]),ae=T(),[se,le]=e.useState(Date.now);e.useEffect(()=>{W.timeRange&&W.timeRange>0&&queueMicrotask(()=>le(Date.now()))},[W.timeRange,s]);const te=e.useMemo(()=>H(s,Y,ae,$),[s,Y,ae,$]),ie=e.useMemo(()=>{const e=W.limit??500;return[...te.length<=e?te:te.slice(-e)].sort((e,a)=>(a.timestamp??0)-(e.timestamp??0))},[te,W.limit]),re=0===s.length,oe=e.useMemo(()=>{let e=ie;if(void 0!==W.type){const a=h[W.type];e=e.filter(e=>{const s=e.type??e.payload_type,l=e.payload_type_name;return s===W.type||l===a})}if(void 0!==W.route){const a=b[W.route];e=e.filter(e=>{const s=e.route??e.route_type,l=e.route_type_name;return s===W.route||l===a})}if(W.status&&"all"!==W.status&&(e=e.filter(e=>L(e)===W.status)),void 0!==W.signalMin&&(e=e.filter(e=>e.rssi>=W.signalMin)),W.timeRange&&W.timeRange>0){const a=se/1e3-3600*W.timeRange;e=e.filter(e=>e.timestamp>=a)}return e},[ie,W.type,W.route,W.status,W.signalMin,W.timeRange,se]),ne=(e,a)=>J(s=>({...s,[e]:a})),ce=void 0!==W.type||void 0!==W.route||W.status&&"all"!==W.status||void 0!==W.signalMin||W.timeRange&&W.timeRange>0;return a.jsxs(q,{children:[a.jsx(K,{title:"Packet History",icon:a.jsx(M,{}),controls:a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsxs(g,{outline:!0,color:ce?"primary":"muted",onClick:()=>C(!k),className:"sm:hidden",children:[a.jsx(P,{"data-slot":"icon"}),ce&&a.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-sys-blue"})]}),a.jsx(G,{ranges:x,selectedIndex:N,onSelect:w,isPending:S})]})}),a.jsxs(O,{children:[a.jsx(I,{template:"auto",className:"relative z-10",children:a.jsx(E,{neomorphic:!0,className:"overflow-visible",children:a.jsx(V,{parentStartTs:$.start,parentEndTs:$.end,neighbors:ee,filter:Y,onChange:X})})}),a.jsxs(E,{neomorphic:!0,noPadding:!0,className:o("overflow-hidden transition-all duration-200",k?"max-h-96 opacity-100":"max-h-0 opacity-0 sm:max-h-96 sm:opacity-100"),children:[a.jsx(v,{listHeader:!0,icon:a.jsx(P,{className:"icon-sm"}),title:"Filters",actions:ce?a.jsxs(g,{plain:!0,color:"muted",onClick:()=>J({limit:W.limit,status:"all"}),className:"!text-xs !py-0.5 !px-1.5",children:[a.jsx(R,{"data-slot":"icon",className:"!w-3 !h-3"}),"Clear"]}):void 0}),a.jsx("div",{className:"p-3 sm:p-4",children:a.jsxs("div",{className:"grid grid-cols-2 sm:flex sm:flex-wrap gap-3",children:[a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Type"}),a.jsx(Q,{value:W.type??"",onChange:e=>ne("type",""===e?void 0:Number(e)),options:[{value:"",label:"All Types"},...Object.entries(h).map(([e,a])=>({value:Number(e),label:a}))],placeholder:"Search types...","aria-label":"Filter by packet type"})]}),a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Route"}),a.jsx(Q,{value:W.route??"",onChange:e=>ne("route",""===e?void 0:Number(e)),options:[{value:"",label:"All Routes"},...Object.entries(b).map(([e,a])=>({value:Number(e),label:a}))],placeholder:"Search routes...","aria-label":"Filter by route type"})]}),a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Status"}),a.jsx(Q,{value:W.status??"all",onChange:e=>ne("status",e),options:[{value:"all",label:"All Status"},{value:"rx",label:"Received"},{value:"forward",label:"Forwarded"},{value:"dropped",label:"Dropped"},{value:"duplicate",label:"Duplicate"}],placeholder:"Search status...","aria-label":"Filter by status"})]}),a.jsxs("div",{className:"flex-1 min-w-[120px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Time"}),a.jsx(Q,{value:W.timeRange??0,onChange:e=>ne("timeRange",0===e?void 0:e),options:[{value:0,label:"All Time"},{value:1,label:"Last 1h"},{value:6,label:"Last 6h"},{value:24,label:"Last 24h"},{value:168,label:"Last 7d"}],placeholder:"Search time...","aria-label":"Filter by time range"})]}),a.jsxs("div",{className:"flex-1 min-w-[130px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Signal"}),a.jsx(Q,{value:W.signalMin??"",onChange:e=>ne("signalMin",""===e?void 0:Number(e)),options:[{value:"",label:"Any Signal"},{value:-90,label:"Strong (≥-90)"},{value:-100,label:"Good (≥-100)"},{value:-110,label:"Fair (≥-110)"},{value:-120,label:"Weak (≥-120)"}],placeholder:"Search signal...","aria-label":"Filter by signal strength"})]}),a.jsxs("div",{className:"flex-1 min-w-[100px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Limit"}),a.jsx(Q,{value:W.limit??500,onChange:e=>ne("limit",e),options:[{value:100,label:"100"},{value:200,label:"200"},{value:500,label:"500"},{value:1e3,label:"1K"},{value:2e3,label:"2K"},{value:5e3,label:"5K"},{value:1e4,label:"10K"}],placeholder:"Limit...","aria-label":"Packet limit"})]}),a.jsxs("div",{className:"flex-1 min-w-[100px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Per Page"}),a.jsx(Q,{value:W.perPage??50,onChange:e=>ne("perPage",e),options:[{value:25,label:"25"},{value:50,label:"50"},{value:100,label:"100"},{value:200,label:"200"},{value:500,label:"500"}],placeholder:"Per page...","aria-label":"Packets per page"})]})]})})]}),a.jsx(Z,{packets:oe}),a.jsxs(E,{neomorphic:!0,noPadding:!0,className:"!overflow-visible",children:[a.jsx(v,{listHeader:!0,icon:a.jsx(M,{className:"icon-sm"}),title:"Packet History",actions:a.jsx(j,{enabled:z,onChange:U,label:"Hide Dupes",size:"sm"})}),a.jsx(F,{packets:oe,allPackets:s,localHash:f,neighbors:y,resolveSource:ae,getDecodedContent:t,onChannelClick:i,loading:re,showPagination:!0,perPage:W.perPage??50,hideDupes:z,emptyMessage:"No packets found"})]})]})]})}export{$ as default}; +import{r as e,j as a,H as s,k as l,B as t,U as i,f as r}from"./vendor-react-alRNW2nb.js";import{c as o}from"./vendor-core-FtpmsTnh.js";import{m as n,p as c,t as d,v as m,W as u,a1 as p,D as x,a3 as h,a4 as b,B as g,q as v,T as j}from"./index-CkRTgHHA.js";import{C as f,a as y,V as N,A as w,Q as S,o as k,U as C,Y as P,h as M,X as R}from"./vendor-icons-TO0PZKGR.js";import{g as L,u as D,P as F}from"./PacketList-BJFBF77t.js";import{u as A,a as T}from"./usePipelineStore-CLEA3Bev.js";import{c as _,a as H,A as V}from"./AnalyzerFilterPanel-o1lp_Gs8.js";import{u as z,r as B}from"./consumer-registry-BUFl6buY.js";import{P as q,a as K,B as O,C as E}from"./PageLayout-BWMUVZgC.js";import{T as G}from"./TimeRangeStepper-CsLZzi5t.js";import{R as I}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./primitives-Bgn6Ik6L.js";import"./payload-decoders-_TRhCJrs.js";import"./badge-colors-BxLppqaF.js";import"./chat-utils-mqGCinix.js";import"./SignalIndicator-Bdj3-1hL.js";import"./DataBox-DpDXI-WX.js";import"./useMapViewStore-sFZdb1_p.js";import"./node-types-DRVunROD.js";import"./geo-utils-DJn8DnxF.js";function U({options:r,value:n,onChange:c,defaultValue:d,displayValue:m,filter:u,placeholder:p,disabled:x,invalid:h,name:b,"aria-label":g,className:v,children:j}){const[y,N]=e.useState(""),w=m??(e=>null!=e?String(e):""),S=u??((e,a)=>w(e).toLowerCase().includes(a.toLowerCase())),k=e.useMemo(()=>y?r.filter(e=>S(e,y)):r,[r,y,S]);return a.jsx(s,{value:n,onChange:c,defaultValue:d,disabled:x,name:b,onClose:()=>N(""),children:a.jsxs("div",{className:o("relative",v),children:[a.jsxs("div",{className:"relative",children:[a.jsx(l,{"aria-label":g,displayValue:w,onChange:e=>N(e.target.value),placeholder:p,className:o(["w-full radius-inner py-2 pl-3 pr-10","text-sm text-fg-primary placeholder:text-fg-muted","bg-input-bg",h?"border border-sys-red":"border border-input-border","ring-focus-inset","hover:border-edge-strong","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-colors"])}),a.jsx(t,{className:"absolute inset-y-0 right-0 flex items-center pr-3 group",children:a.jsx(f,{className:"w-4 h-4 text-fg-muted transition-transform duration-200 group-data-[open]:rotate-180"})})]}),a.jsx(i,{anchor:"bottom start",transition:!0,className:o(["w-[var(--input-width)] min-w-[180px]","max-h-60 overflow-y-auto overscroll-contain scroll-py-1","radius-inset p-1 mt-1","surface-elevated","focus:outline-none","transition-opacity","data-[closed]:opacity-0","data-[enter]:duration-150 data-[leave]:duration-100","z-50"]),children:0===k.length&&""!==y?a.jsx("div",{className:"px-3 py-2 text-sm text-fg-muted",children:"No results found"}):k.map((s,l)=>a.jsx(e.Fragment,{children:j(s)},l))})]})})}function W({value:s,disabled:l,className:t,children:i}){return a.jsx(r,{as:e.Fragment,value:s,disabled:l,children:({selected:e,focus:s})=>a.jsxs("div",{className:o("flex items-center gap-2 px-3 py-2 radius-control cursor-default","text-sm",s&&"bg-sys-blue text-white",!s&&"text-fg-primary",e&&!s&&"text-sys-blue",l&&"opacity-50 cursor-not-allowed",t),children:[a.jsx("span",{className:"w-4 flex-shrink-0",children:e&&a.jsx(y,{className:"w-4 h-4"})}),a.jsx("span",{className:"truncate flex-1",children:i})]})})}function J({className:e,...s}){return a.jsx("span",{...s,className:o("truncate",e)})}function Q({value:e,onChange:s,options:l,placeholder:t,disabled:i,className:r,"aria-label":o}){const n=l.find(a=>a.value===e);return a.jsx(U,{options:l,value:n,onChange:e=>{e&&s(e.value)},displayValue:e=>(null==e?void 0:e.label)??"",filter:(e,a)=>e.label.toLowerCase().includes(a.toLowerCase()),placeholder:t,disabled:i,className:r,"aria-label":o,children:e=>a.jsx(W,{value:e,disabled:e.disabled,children:a.jsx(J,{children:e.label})})})}const Y=[{target:"PacketStats",fn:"type",minStage:1}];function X({icon:e,label:s,value:l,color:t,percentage:i}){return a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:o("p-1.5 rounded-md",t),children:e}),a.jsxs("div",{className:"flex flex-col",children:[a.jsx("span",{className:"text-sm font-semibold text-fg-primary",children:l.toLocaleString()}),a.jsxs("span",{className:"text-xs text-fg-muted leading-tight",children:[s,void 0!==i&&a.jsxs("span",{className:"ml-1 opacity-70",children:["(",i,"%)"]})]})]})]})}B(Y);const Z=e.memo(function({packets:s}){z(Y);const l=e.useMemo(()=>{let e=0,a=0,l=0;const t=new Set;let i=0,r=0;for(const c of s){switch(L(c)){case"forward":e++;break;case"dropped":a++;break;case"duplicate":l++}c.src_hash&&t.add(c.src_hash),c.rssi&&(i+=c.rssi,r++)}const o=s.length,n=r>0?Math.round(i/r):0;return{total:o,rx:o,fwd:e,dropped:a,duplicate:l,uniqueSources:t.size,avgRssi:n,rxPercent:100,fwdPercent:o>0?Math.round(e/o*100):0,droppedPercent:o>0?Math.round(a/o*100):0}},[s]);return 0===s.length?null:a.jsx("div",{className:"surface-base depth-raised rounded-2xl p-3 pr-4",children:a.jsxs("div",{className:"grid grid-cols-2 gap-3 sm:flex sm:items-center sm:justify-between sm:gap-6",children:[a.jsx(X,{icon:a.jsx(N,{className:"w-3.5 h-3.5 text-sys-blue"}),label:"Received",value:l.rx,color:"bg-sys-blue/10",percentage:l.rxPercent}),a.jsx(X,{icon:a.jsx(w,{className:"w-3.5 h-3.5 text-sys-green"}),label:"Forwarded",value:l.fwd,color:"bg-sys-green/10",percentage:l.fwdPercent}),a.jsx(X,{icon:a.jsx(S,{className:"w-3.5 h-3.5 text-sys-red"}),label:"Dropped",value:l.dropped,color:"bg-sys-red/10",percentage:l.droppedPercent}),a.jsx(X,{icon:a.jsx(k,{className:"w-3.5 h-3.5 text-fg-muted"}),label:"Duplicates",value:l.duplicate,color:"bg-subtle-fill"}),a.jsxs("div",{className:"hidden sm:flex items-center gap-6 ml-auto",children:[a.jsx(X,{icon:a.jsx(C,{className:"w-3.5 h-3.5 text-sys-indigo"}),label:"Sources",value:l.uniqueSources,color:"bg-sys-indigo/10"}),a.jsxs("div",{className:"flex flex-col items-end pr-1",children:[a.jsxs("span",{className:"type-data-sm text-fg-secondary",children:[l.avgRssi," dBm"]}),a.jsx("span",{className:"text-xs text-fg-muted",children:"Avg Signal"})]})]})]})})});function $(){const s=n(),l=c(),t=A(),i=D(e=>e.requestChannel),r=d(),f=null==l?void 0:l.local_hash,y=null==l?void 0:l.neighbors,N=m(),w=u(),S=p().isBackgroundLoading&&N>=5,[k,C]=e.useState(!1),[z,B]=e.useState(!0),U=e.useCallback(e=>B(e),[]),[W,J]=e.useState({limit:500,status:"all"}),[Y,X]=e.useState(_),$=e.useMemo(()=>{const e=Math.floor(Date.now()/1e3);return{start:e-60*x[N].minutes,end:e}},[N]),ee=e.useMemo(()=>{const e=(null==l?void 0:l.neighbors)??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!r.has(e)))},[null==l?void 0:l.neighbors,r]),ae=T(),[se,le]=e.useState(Date.now);e.useEffect(()=>{W.timeRange&&W.timeRange>0&&queueMicrotask(()=>le(Date.now()))},[W.timeRange,s]);const te=e.useMemo(()=>H(s,Y,ae,$),[s,Y,ae,$]),ie=e.useMemo(()=>{const e=W.limit??500;return[...te.length<=e?te:te.slice(-e)].sort((e,a)=>(a.timestamp??0)-(e.timestamp??0))},[te,W.limit]),re=0===s.length,oe=e.useMemo(()=>{let e=ie;if(void 0!==W.type){const a=h[W.type];e=e.filter(e=>{const s=e.type??e.payload_type,l=e.payload_type_name;return s===W.type||l===a})}if(void 0!==W.route){const a=b[W.route];e=e.filter(e=>{const s=e.route??e.route_type,l=e.route_type_name;return s===W.route||l===a})}if(W.status&&"all"!==W.status&&(e=e.filter(e=>L(e)===W.status)),void 0!==W.signalMin&&(e=e.filter(e=>e.rssi>=W.signalMin)),W.timeRange&&W.timeRange>0){const a=se/1e3-3600*W.timeRange;e=e.filter(e=>e.timestamp>=a)}return e},[ie,W.type,W.route,W.status,W.signalMin,W.timeRange,se]),ne=(e,a)=>J(s=>({...s,[e]:a})),ce=void 0!==W.type||void 0!==W.route||W.status&&"all"!==W.status||void 0!==W.signalMin||W.timeRange&&W.timeRange>0;return a.jsxs(q,{children:[a.jsx(K,{title:"Packet History",icon:a.jsx(M,{}),controls:a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsxs(g,{outline:!0,color:ce?"primary":"muted",onClick:()=>C(!k),className:"sm:hidden",children:[a.jsx(P,{"data-slot":"icon"}),ce&&a.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-sys-blue"})]}),a.jsx(G,{ranges:x,selectedIndex:N,onSelect:w,isPending:S})]})}),a.jsxs(O,{children:[a.jsx(I,{template:"auto",className:"relative z-10",children:a.jsx(E,{neomorphic:!0,className:"overflow-visible",children:a.jsx(V,{parentStartTs:$.start,parentEndTs:$.end,neighbors:ee,filter:Y,onChange:X})})}),a.jsxs(E,{neomorphic:!0,noPadding:!0,className:o("overflow-hidden transition-all duration-200",k?"max-h-96 opacity-100":"max-h-0 opacity-0 sm:max-h-96 sm:opacity-100"),children:[a.jsx(v,{listHeader:!0,icon:a.jsx(P,{className:"icon-sm"}),title:"Filters",actions:ce?a.jsxs(g,{plain:!0,color:"muted",onClick:()=>J({limit:W.limit,status:"all"}),className:"!text-xs !py-0.5 !px-1.5",children:[a.jsx(R,{"data-slot":"icon",className:"!w-3 !h-3"}),"Clear"]}):void 0}),a.jsx("div",{className:"p-3 sm:p-4",children:a.jsxs("div",{className:"grid grid-cols-2 sm:flex sm:flex-wrap gap-3",children:[a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Type"}),a.jsx(Q,{value:W.type??"",onChange:e=>ne("type",""===e?void 0:Number(e)),options:[{value:"",label:"All Types"},...Object.entries(h).map(([e,a])=>({value:Number(e),label:a}))],placeholder:"Search types...","aria-label":"Filter by packet type"})]}),a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Route"}),a.jsx(Q,{value:W.route??"",onChange:e=>ne("route",""===e?void 0:Number(e)),options:[{value:"",label:"All Routes"},...Object.entries(b).map(([e,a])=>({value:Number(e),label:a}))],placeholder:"Search routes...","aria-label":"Filter by route type"})]}),a.jsxs("div",{className:"flex-1 min-w-[140px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Status"}),a.jsx(Q,{value:W.status??"all",onChange:e=>ne("status",e),options:[{value:"all",label:"All Status"},{value:"rx",label:"Received"},{value:"forward",label:"Forwarded"},{value:"dropped",label:"Dropped"},{value:"duplicate",label:"Duplicate"}],placeholder:"Search status...","aria-label":"Filter by status"})]}),a.jsxs("div",{className:"flex-1 min-w-[120px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Time"}),a.jsx(Q,{value:W.timeRange??0,onChange:e=>ne("timeRange",0===e?void 0:e),options:[{value:0,label:"All Time"},{value:1,label:"Last 1h"},{value:6,label:"Last 6h"},{value:24,label:"Last 24h"},{value:168,label:"Last 7d"}],placeholder:"Search time...","aria-label":"Filter by time range"})]}),a.jsxs("div",{className:"flex-1 min-w-[130px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Signal"}),a.jsx(Q,{value:W.signalMin??"",onChange:e=>ne("signalMin",""===e?void 0:Number(e)),options:[{value:"",label:"Any Signal"},{value:-90,label:"Strong (≥-90)"},{value:-100,label:"Good (≥-100)"},{value:-110,label:"Fair (≥-110)"},{value:-120,label:"Weak (≥-120)"}],placeholder:"Search signal...","aria-label":"Filter by signal strength"})]}),a.jsxs("div",{className:"flex-1 min-w-[100px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Limit"}),a.jsx(Q,{value:W.limit??500,onChange:e=>ne("limit",e),options:[{value:100,label:"100"},{value:200,label:"200"},{value:500,label:"500"},{value:1e3,label:"1K"},{value:2e3,label:"2K"},{value:5e3,label:"5K"},{value:1e4,label:"10K"}],placeholder:"Limit...","aria-label":"Packet limit"})]}),a.jsxs("div",{className:"flex-1 min-w-[100px]",children:[a.jsx("label",{className:"type-micro block mb-1",children:"Per Page"}),a.jsx(Q,{value:W.perPage??50,onChange:e=>ne("perPage",e),options:[{value:25,label:"25"},{value:50,label:"50"},{value:100,label:"100"},{value:200,label:"200"},{value:500,label:"500"}],placeholder:"Per page...","aria-label":"Packets per page"})]})]})})]}),a.jsx(Z,{packets:oe}),a.jsxs(E,{neomorphic:!0,noPadding:!0,className:"!overflow-visible",children:[a.jsx(v,{listHeader:!0,icon:a.jsx(M,{className:"icon-sm"}),title:"Packet History",actions:a.jsx(j,{enabled:z,onChange:U,label:"Hide Dupes",size:"sm"})}),a.jsx(F,{packets:oe,allPackets:s,localHash:f,neighbors:y,resolveSource:ae,getDecodedContent:t,onChannelClick:i,loading:re,showPagination:!0,perPage:W.perPage??50,hideDupes:z,emptyMessage:"No packets found"})]})]})]})}export{$ as default}; diff --git a/frontend/dist/assets/PageLayout-QhCLxU34.js b/frontend/dist/assets/PageLayout-BWMUVZgC.js similarity index 93% rename from frontend/dist/assets/PageLayout-QhCLxU34.js rename to frontend/dist/assets/PageLayout-BWMUVZgC.js index 6f20281e..cfc3e86d 100644 --- a/frontend/dist/assets/PageLayout-QhCLxU34.js +++ b/frontend/dist/assets/PageLayout-BWMUVZgC.js @@ -1 +1 @@ -import{j as e}from"./vendor-react-alRNW2nb.js";import{c as s}from"./vendor-core-FtpmsTnh.js";import{e as i}from"./index-D7i6lQrq.js";function n({children:i,className:n}){return e.jsx("div",{className:s("section-gap",n),children:i})}function a({children:i,className:n}){return e.jsx("div",{className:s("bento-section",n),children:i})}function t({title:s,icon:i,controls:n,subtitle:a}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 min-h-9",children:[e.jsxs("h1",{className:"type-title text-fg-primary flex items-baseline gap-2 sm:gap-3 min-w-0",children:[i&&e.jsx("span",{className:"text-icon-page-title flex-shrink-0 translate-y-[0.1em] [&>svg]:h-[1em] [&>svg]:w-[1em] [&>svg]:stroke-[1.5]",children:i}),e.jsx("span",{className:"truncate",children:s})]}),n&&e.jsx("div",{className:"flex items-center gap-2 flex-shrink-0",children:n})]}),a&&e.jsx("div",{children:a})]})}function r({size:s,...n}){return e.jsx(i,{...n})}export{a as B,r as C,n as P,t as a}; +import{j as e}from"./vendor-react-alRNW2nb.js";import{c as s}from"./vendor-core-FtpmsTnh.js";import{e as i}from"./index-CkRTgHHA.js";function n({children:i,className:n}){return e.jsx("div",{className:s("section-gap",n),children:i})}function a({children:i,className:n}){return e.jsx("div",{className:s("bento-section",n),children:i})}function t({title:s,icon:i,controls:n,subtitle:a}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 min-h-9",children:[e.jsxs("h1",{className:"type-title text-fg-primary flex items-baseline gap-2 sm:gap-3 min-w-0",children:[i&&e.jsx("span",{className:"text-icon-page-title flex-shrink-0 translate-y-[0.1em] [&>svg]:h-[1em] [&>svg]:w-[1em] [&>svg]:stroke-[1.5]",children:i}),e.jsx("span",{className:"truncate",children:s})]}),n&&e.jsx("div",{className:"flex items-center gap-2 flex-shrink-0",children:n})]}),a&&e.jsx("div",{children:a})]})}function r({size:s,...n}){return e.jsx(i,{...n})}export{a as B,r as C,n as P,t as a}; diff --git a/frontend/dist/assets/PathMapMapLibre-Copwhk_5.js b/frontend/dist/assets/PathMapMapLibre-_vG9wINu.js similarity index 99% rename from frontend/dist/assets/PathMapMapLibre-Copwhk_5.js rename to frontend/dist/assets/PathMapMapLibre-_vG9wINu.js index 701c3659..08ce3df9 100644 --- a/frontend/dist/assets/PathMapMapLibre-Copwhk_5.js +++ b/frontend/dist/assets/PathMapMapLibre-_vG9wINu.js @@ -1 +1 @@ -import{r as e,j as o}from"./vendor-react-alRNW2nb.js";import{M as t,S as r,L as n,a as s,P as i}from"./maplibre-gl-BwLPRSIs.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{u as l,B as d}from"./BasemapLayer-CSqjQAiA.js";import{ag as c,ab as u,db as m,Z as p,ai as h,h as g,dc as f}from"./index-D7i6lQrq.js";import{bn as x,K as b}from"./vendor-icons-TO0PZKGR.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const v={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"},y={nodeColor:"#4338CA",localColor:"#4F46E5",hubColor:"#6366F1",edgeColor:"#3B3F4A",ambiguousColor:"#F9D26F",highlightColor:"#B49DFF",sourceColor:"#39D98A",destinationColor:"#B49DFF"};function C(e,o){if(!e)return o;if(e.startsWith("#"))return e;const t=f(e);return t?`#${t.r.toString(16).padStart(2,"0")}${t.g.toString(16).padStart(2,"0")}${t.b.toString(16).padStart(2,"0")}`:o}function j(){if("undefined"==typeof document)return y;const e=document.documentElement,o=getComputedStyle(e);return{nodeColor:C(o.getPropertyValue("--map-node-stroke").trim(),y.nodeColor),localColor:C(o.getPropertyValue("--map-local-color").trim(),y.localColor),hubColor:C(o.getPropertyValue("--map-hub-color").trim(),y.hubColor),edgeColor:C(o.getPropertyValue("--map-edge-rest").trim(),y.edgeColor),ambiguousColor:C(o.getPropertyValue("--sys-indigo").trim(),y.ambiguousColor),highlightColor:C(o.getPropertyValue("--sys-blue").trim(),y.highlightColor),sourceColor:C(o.getPropertyValue("--sys-green").trim(),y.sourceColor),destinationColor:C(o.getPropertyValue("--sys-blue").trim(),y.destinationColor)}}function k({prefix:t,isLocal:r,isSource:n,isDestination:s,isLastHop:i,isHighlighted:l,isWardrive:d,candidate:c,onHover:u,onLeave:m,onClick:p}){const[h,f]=e.useState(!1),v=e.useCallback(()=>{f(!0),u()},[u]),y=e.useCallback(()=>{f(!1),m()},[m]);return d?o.jsxs("div",{className:a("flex items-center cursor-pointer","transition-all duration-150",l&&"ring-2 ring-sys-blue/50 rounded-full",h&&"relative z-50"),onMouseEnter:v,onMouseLeave:y,onClick:p,style:{pointerEvents:"auto"},children:[o.jsx("div",{className:a("flex items-center justify-center","w-7 h-7 rounded-full","bg-sys-orange text-white","shadow-lg border-2 border-sys-orange/50","transition-transform duration-150",h&&"scale-110"),children:o.jsx(x,{className:"w-4 h-4",strokeWidth:2.5})}),h&&o.jsxs(g,{color:"orange",filled:!0,className:"ml-1 type-data-xs shadow-lg",children:[t,c.name&&o.jsx("span",{className:"ml-1 opacity-75",children:c.name})]})]}):o.jsx("div",{className:a("flex items-center cursor-pointer","transition-all duration-150",l&&"ring-2 ring-sys-blue/50 rounded",h&&"relative z-50"),onMouseEnter:v,onMouseLeave:y,onClick:p,style:{pointerEvents:"auto"},children:o.jsxs(g,{color:d?"orange":r?"amber":n?"green":i?"amber":s?"purple":"blue",filled:!0,className:"type-data-xs shadow-lg border border-current/30",children:[r&&o.jsx(b,{className:"w-2.5 h-2.5 mr-1"}),t,h&&c.name&&o.jsx("span",{className:"ml-1 opacity-75",children:c.name})]})})}function N({hopNumber:e,snr:t,edgeColor:r}){return o.jsxs("div",{className:"flex flex-col items-center gap-0.5 pointer-events-none",children:[o.jsx("span",{className:"w-3.5 h-3.5 rounded-full flex items-center justify-center font-mono font-bold tabular-nums shadow-md",style:{backgroundColor:r||p[500],color:"#fff",fontSize:"8px",lineHeight:1,textShadow:"0 1px 1px rgba(0,0,0,0.4)"},children:e}),void 0!==t&&o.jsx(g,{color:"zinc",compact:!0,className:"!text-[9px] font-mono tabular-nums shadow-sm",children:t.toFixed(1)})]})}function S({resolvedPath:a,localNode:g,hubNodes:f=[],hoveredHopIndex:x,onHoverHop:b,traceSnr:y}){const C=void 0!==y&&y.length>0,S=e.useRef(null),w=l(),F=c(),L=e.useMemo(()=>new Set(f),[f]),[M,P]=e.useState(null),D=u(),[E,H]=e.useState(!1),[$,W]=e.useState(0);e.useEffect(()=>{var e;const o=null==(e=S.current)?void 0:e.getMap();if(!o)return;const t=o.getCanvas();if(!t)return;const r=e=>{e.preventDefault(),console.warn("[PathMapMapLibre] WebGL context lost")},n=()=>{W(e=>e+1)};return t.addEventListener("webglcontextlost",r),t.addEventListener("webglcontextrestored",n),()=>{t.removeEventListener("webglcontextlost",r),t.removeEventListener("webglcontextrestored",n)}},[$]);const{positions:V,markers:B,edges:I}=e.useMemo(()=>{const e=[],o=[],t=[],r=[];let n=0,s=!1;return a.hops.forEach((i,a)=>{const l=i.candidates.filter(e=>{return o=e.latitude,t=e.longitude,0!==o||0!==t;var o,t});if(0===l.length)return;const d=[...l].sort((e,o)=>o.probability-e.probability)[0],c=[d.longitude,d.latitude];if(r.push(c),r.length>=2){const e=r[r.length-2],o=r.length-2,n=null==y?void 0:y[o],i=c[0]-e[0],a=c[1]-e[1],l=Math.atan2(i,a)*(180/Math.PI),d=j();let u;u=s?"#F97316":void 0!==n?m()[h(n,F)]||p[500]:d.edgeColor,t.push({from:e,to:c,snrFwd:n,midpoint:[(e[0]+c[0])/2,(e[1]+c[1])/2],bearing:l,color:u,isFromWardrive:s})}const u=!0===i.isSource,g=!0===i.isDestination,f=!0===d.isWardrive;s=f,l.forEach((t,r)=>{const s=[t.latitude,t.longitude];e.push(s);const d=0===r;o.push({position:s,prefix:i.prefix,confidence:i.confidence,candidateCount:l.length,hopIndex:a,candidate:t,isHub:L.has(t.hash),isPrimary:d,isSource:u,isDestination:g,validIndex:n})}),n++}),{positions:e,markers:o,edges:t}},[a,L,y,F]),A=e.useMemo(()=>I.map(e=>({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:[e.from,e.to]}}]})),[I]),z=e.useMemo(()=>{const e=B.filter(e=>e.isPrimary&&(e.confidence>=.5||e.isSource||e.isDestination));if(0===e.length)return null;let o=1/0,t=-1/0,r=1/0,n=-1/0;for(const s of e){const[e,i]=s.position;et&&(t=e),in&&(n=i)}return[[r,o],[n,t]]},[B]),R=e.useMemo(()=>{if(0===V.length)return g?[g.longitude,g.latitude]:[0,0];let e=0,o=0;for(const[t,r]of V)e+=t,o+=r;return[o/V.length,e/V.length]},[V,g]),Z=e.useCallback(()=>{var e;const o=null==(e=S.current)?void 0:e.getMap();o&&z?(o.fitBounds(z,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:15,duration:0}),setTimeout(()=>{H(!0)},50)):H(!0)},[z]),O=e.useMemo(()=>z?`${z[0][0].toFixed(5)},${z[0][1].toFixed(5)},${z[1][0].toFixed(5)},${z[1][1].toFixed(5)}`:"",[z]);e.useEffect(()=>{var e;if(!E)return;const o=null==(e=S.current)?void 0:e.getMap();o&&z&&o.fitBounds(z,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:15,duration:300})},[O,E,z]);const T=D&&E,G=e.useCallback(e=>{P({longitude:e.position[1],latitude:e.position[0],marker:e})},[]);return 0===V.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted text-sm bg-elevated",children:"No mappable path data"}):o.jsxs("div",{className:"h-full w-full relative",children:[!T&&o.jsx("div",{className:"absolute inset-0 bg-elevated flex items-center justify-center pointer-events-none",children:o.jsx("div",{className:"w-5 h-5 border-2 border-text-muted/30 border-t-text-muted rounded-full animate-spin"})}),o.jsx("div",{className:"h-full w-full transition-opacity duration-300 ease-out",style:{opacity:T?1:0},children:o.jsxs(t,{ref:S,initialViewState:{longitude:R[0],latitude:R[1],zoom:10},onLoad:Z,style:{height:"100%",width:"100%"},mapStyle:v,attributionControl:!1,children:[o.jsx(d,{mode:w}),I.map((e,t)=>o.jsx(r,{id:`edge-${t}`,type:"geojson",data:A[t],children:o.jsx(n,{id:`edge-line-${t}`,type:"line",paint:{"line-color":e.color,"line-width":4,"line-opacity":1},layout:{"line-cap":"round","line-join":"round"}})},`edge-${t}`)),I.map((e,t)=>o.jsx(s,{longitude:e.midpoint[0],latitude:e.midpoint[1],anchor:"center",children:o.jsx(N,{hopNumber:t+1,snr:C?e.snrFwd:void 0,edgeColor:e.color})},`hop-${t}`)),(()=>{const e=B.filter(e=>e.isPrimary),t=e.length>1?e.length-2:-1;return e.map((e,r)=>{const n=x===e.hopIndex,i=r===t&&!e.candidate.isLocal&&!e.isDestination;return o.jsx(s,{longitude:e.position[1],latitude:e.position[0],anchor:"center",children:o.jsx(k,{prefix:e.prefix,isLocal:e.candidate.isLocal||!1,isSource:e.isSource,isDestination:e.isDestination,isLastHop:i,isHighlighted:n,isWardrive:e.candidate.isWardrive||!1,candidate:e.candidate,onHover:()=>null==b?void 0:b(e.hopIndex),onLeave:()=>null==b?void 0:b(null),onClick:()=>G(e)})},`${e.hopIndex}-${e.candidate.hash}`)})})(),M&&o.jsx(i,{longitude:M.longitude,latitude:M.latitude,anchor:"bottom",offset:[0,-12],closeOnClick:!1,onClose:()=>P(null),className:"maplibre-popup",children:o.jsxs("div",{className:"text-xs",children:[o.jsxs("div",{className:"flex items-center gap-1.5",children:[o.jsx("span",{className:"font-semibold",children:M.marker.candidate.name}),(()=>{const e=j();return o.jsxs(o.Fragment,{children:[M.marker.isSource&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.sourceColor,color:"#000"},children:"SRC"}),M.marker.isDestination&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.destinationColor,color:"#000"},children:"DST"}),M.marker.isHub&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.hubColor,color:"#000"},children:"HUB"}),M.marker.candidate.isLocal&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.localColor,color:"#fff"},children:"LOCAL"}),M.marker.candidate.isWardrive&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:"#F97316",color:"#fff"},children:"WARDRIVE"})]})})()]}),o.jsxs("div",{className:"text-fg-muted type-data-xs",children:[M.marker.prefix," • ",M.marker.candidate.hash.slice(0,10),"..."]}),!M.marker.isPrimary&&M.marker.candidateCount>1&&o.jsxs("div",{style:{color:j().ambiguousColor},children:["Alternative (",(100*M.marker.candidate.probability).toFixed(0),"%)"]}),M.marker.isPrimary&&M.marker.candidateCount>1&&o.jsxs("div",{className:"text-fg-muted",children:[M.marker.candidateCount," candidates"]})]})})]},$)})]})}export{S as default}; +import{r as e,j as o}from"./vendor-react-alRNW2nb.js";import{M as t,S as r,L as n,a as s,P as i}from"./maplibre-gl-BwLPRSIs.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{u as l,B as d}from"./BasemapLayer-CSqjQAiA.js";import{ag as c,ab as u,db as m,Z as p,ai as h,h as g,dc as f}from"./index-CkRTgHHA.js";import{bn as x,K as b}from"./vendor-icons-TO0PZKGR.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const v={version:8,sources:{},layers:[],glyphs:"https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf"},y={nodeColor:"#4338CA",localColor:"#4F46E5",hubColor:"#6366F1",edgeColor:"#3B3F4A",ambiguousColor:"#F9D26F",highlightColor:"#B49DFF",sourceColor:"#39D98A",destinationColor:"#B49DFF"};function C(e,o){if(!e)return o;if(e.startsWith("#"))return e;const t=f(e);return t?`#${t.r.toString(16).padStart(2,"0")}${t.g.toString(16).padStart(2,"0")}${t.b.toString(16).padStart(2,"0")}`:o}function j(){if("undefined"==typeof document)return y;const e=document.documentElement,o=getComputedStyle(e);return{nodeColor:C(o.getPropertyValue("--map-node-stroke").trim(),y.nodeColor),localColor:C(o.getPropertyValue("--map-local-color").trim(),y.localColor),hubColor:C(o.getPropertyValue("--map-hub-color").trim(),y.hubColor),edgeColor:C(o.getPropertyValue("--map-edge-rest").trim(),y.edgeColor),ambiguousColor:C(o.getPropertyValue("--sys-indigo").trim(),y.ambiguousColor),highlightColor:C(o.getPropertyValue("--sys-blue").trim(),y.highlightColor),sourceColor:C(o.getPropertyValue("--sys-green").trim(),y.sourceColor),destinationColor:C(o.getPropertyValue("--sys-blue").trim(),y.destinationColor)}}function k({prefix:t,isLocal:r,isSource:n,isDestination:s,isLastHop:i,isHighlighted:l,isWardrive:d,candidate:c,onHover:u,onLeave:m,onClick:p}){const[h,f]=e.useState(!1),v=e.useCallback(()=>{f(!0),u()},[u]),y=e.useCallback(()=>{f(!1),m()},[m]);return d?o.jsxs("div",{className:a("flex items-center cursor-pointer","transition-all duration-150",l&&"ring-2 ring-sys-blue/50 rounded-full",h&&"relative z-50"),onMouseEnter:v,onMouseLeave:y,onClick:p,style:{pointerEvents:"auto"},children:[o.jsx("div",{className:a("flex items-center justify-center","w-7 h-7 rounded-full","bg-sys-orange text-white","shadow-lg border-2 border-sys-orange/50","transition-transform duration-150",h&&"scale-110"),children:o.jsx(x,{className:"w-4 h-4",strokeWidth:2.5})}),h&&o.jsxs(g,{color:"orange",filled:!0,className:"ml-1 type-data-xs shadow-lg",children:[t,c.name&&o.jsx("span",{className:"ml-1 opacity-75",children:c.name})]})]}):o.jsx("div",{className:a("flex items-center cursor-pointer","transition-all duration-150",l&&"ring-2 ring-sys-blue/50 rounded",h&&"relative z-50"),onMouseEnter:v,onMouseLeave:y,onClick:p,style:{pointerEvents:"auto"},children:o.jsxs(g,{color:d?"orange":r?"amber":n?"green":i?"amber":s?"purple":"blue",filled:!0,className:"type-data-xs shadow-lg border border-current/30",children:[r&&o.jsx(b,{className:"w-2.5 h-2.5 mr-1"}),t,h&&c.name&&o.jsx("span",{className:"ml-1 opacity-75",children:c.name})]})})}function N({hopNumber:e,snr:t,edgeColor:r}){return o.jsxs("div",{className:"flex flex-col items-center gap-0.5 pointer-events-none",children:[o.jsx("span",{className:"w-3.5 h-3.5 rounded-full flex items-center justify-center font-mono font-bold tabular-nums shadow-md",style:{backgroundColor:r||p[500],color:"#fff",fontSize:"8px",lineHeight:1,textShadow:"0 1px 1px rgba(0,0,0,0.4)"},children:e}),void 0!==t&&o.jsx(g,{color:"zinc",compact:!0,className:"!text-[9px] font-mono tabular-nums shadow-sm",children:t.toFixed(1)})]})}function S({resolvedPath:a,localNode:g,hubNodes:f=[],hoveredHopIndex:x,onHoverHop:b,traceSnr:y}){const C=void 0!==y&&y.length>0,S=e.useRef(null),w=l(),F=c(),L=e.useMemo(()=>new Set(f),[f]),[M,P]=e.useState(null),D=u(),[E,H]=e.useState(!1),[$,W]=e.useState(0);e.useEffect(()=>{var e;const o=null==(e=S.current)?void 0:e.getMap();if(!o)return;const t=o.getCanvas();if(!t)return;const r=e=>{e.preventDefault(),console.warn("[PathMapMapLibre] WebGL context lost")},n=()=>{W(e=>e+1)};return t.addEventListener("webglcontextlost",r),t.addEventListener("webglcontextrestored",n),()=>{t.removeEventListener("webglcontextlost",r),t.removeEventListener("webglcontextrestored",n)}},[$]);const{positions:V,markers:B,edges:I}=e.useMemo(()=>{const e=[],o=[],t=[],r=[];let n=0,s=!1;return a.hops.forEach((i,a)=>{const l=i.candidates.filter(e=>{return o=e.latitude,t=e.longitude,0!==o||0!==t;var o,t});if(0===l.length)return;const d=[...l].sort((e,o)=>o.probability-e.probability)[0],c=[d.longitude,d.latitude];if(r.push(c),r.length>=2){const e=r[r.length-2],o=r.length-2,n=null==y?void 0:y[o],i=c[0]-e[0],a=c[1]-e[1],l=Math.atan2(i,a)*(180/Math.PI),d=j();let u;u=s?"#F97316":void 0!==n?m()[h(n,F)]||p[500]:d.edgeColor,t.push({from:e,to:c,snrFwd:n,midpoint:[(e[0]+c[0])/2,(e[1]+c[1])/2],bearing:l,color:u,isFromWardrive:s})}const u=!0===i.isSource,g=!0===i.isDestination,f=!0===d.isWardrive;s=f,l.forEach((t,r)=>{const s=[t.latitude,t.longitude];e.push(s);const d=0===r;o.push({position:s,prefix:i.prefix,confidence:i.confidence,candidateCount:l.length,hopIndex:a,candidate:t,isHub:L.has(t.hash),isPrimary:d,isSource:u,isDestination:g,validIndex:n})}),n++}),{positions:e,markers:o,edges:t}},[a,L,y,F]),A=e.useMemo(()=>I.map(e=>({type:"FeatureCollection",features:[{type:"Feature",properties:{},geometry:{type:"LineString",coordinates:[e.from,e.to]}}]})),[I]),z=e.useMemo(()=>{const e=B.filter(e=>e.isPrimary&&(e.confidence>=.5||e.isSource||e.isDestination));if(0===e.length)return null;let o=1/0,t=-1/0,r=1/0,n=-1/0;for(const s of e){const[e,i]=s.position;et&&(t=e),in&&(n=i)}return[[r,o],[n,t]]},[B]),R=e.useMemo(()=>{if(0===V.length)return g?[g.longitude,g.latitude]:[0,0];let e=0,o=0;for(const[t,r]of V)e+=t,o+=r;return[o/V.length,e/V.length]},[V,g]),Z=e.useCallback(()=>{var e;const o=null==(e=S.current)?void 0:e.getMap();o&&z?(o.fitBounds(z,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:15,duration:0}),setTimeout(()=>{H(!0)},50)):H(!0)},[z]),O=e.useMemo(()=>z?`${z[0][0].toFixed(5)},${z[0][1].toFixed(5)},${z[1][0].toFixed(5)},${z[1][1].toFixed(5)}`:"",[z]);e.useEffect(()=>{var e;if(!E)return;const o=null==(e=S.current)?void 0:e.getMap();o&&z&&o.fitBounds(z,{padding:{top:50,bottom:50,left:50,right:50},maxZoom:15,duration:300})},[O,E,z]);const T=D&&E,G=e.useCallback(e=>{P({longitude:e.position[1],latitude:e.position[0],marker:e})},[]);return 0===V.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted text-sm bg-elevated",children:"No mappable path data"}):o.jsxs("div",{className:"h-full w-full relative",children:[!T&&o.jsx("div",{className:"absolute inset-0 bg-elevated flex items-center justify-center pointer-events-none",children:o.jsx("div",{className:"w-5 h-5 border-2 border-text-muted/30 border-t-text-muted rounded-full animate-spin"})}),o.jsx("div",{className:"h-full w-full transition-opacity duration-300 ease-out",style:{opacity:T?1:0},children:o.jsxs(t,{ref:S,initialViewState:{longitude:R[0],latitude:R[1],zoom:10},onLoad:Z,style:{height:"100%",width:"100%"},mapStyle:v,attributionControl:!1,children:[o.jsx(d,{mode:w}),I.map((e,t)=>o.jsx(r,{id:`edge-${t}`,type:"geojson",data:A[t],children:o.jsx(n,{id:`edge-line-${t}`,type:"line",paint:{"line-color":e.color,"line-width":4,"line-opacity":1},layout:{"line-cap":"round","line-join":"round"}})},`edge-${t}`)),I.map((e,t)=>o.jsx(s,{longitude:e.midpoint[0],latitude:e.midpoint[1],anchor:"center",children:o.jsx(N,{hopNumber:t+1,snr:C?e.snrFwd:void 0,edgeColor:e.color})},`hop-${t}`)),(()=>{const e=B.filter(e=>e.isPrimary),t=e.length>1?e.length-2:-1;return e.map((e,r)=>{const n=x===e.hopIndex,i=r===t&&!e.candidate.isLocal&&!e.isDestination;return o.jsx(s,{longitude:e.position[1],latitude:e.position[0],anchor:"center",children:o.jsx(k,{prefix:e.prefix,isLocal:e.candidate.isLocal||!1,isSource:e.isSource,isDestination:e.isDestination,isLastHop:i,isHighlighted:n,isWardrive:e.candidate.isWardrive||!1,candidate:e.candidate,onHover:()=>null==b?void 0:b(e.hopIndex),onLeave:()=>null==b?void 0:b(null),onClick:()=>G(e)})},`${e.hopIndex}-${e.candidate.hash}`)})})(),M&&o.jsx(i,{longitude:M.longitude,latitude:M.latitude,anchor:"bottom",offset:[0,-12],closeOnClick:!1,onClose:()=>P(null),className:"maplibre-popup",children:o.jsxs("div",{className:"text-xs",children:[o.jsxs("div",{className:"flex items-center gap-1.5",children:[o.jsx("span",{className:"font-semibold",children:M.marker.candidate.name}),(()=>{const e=j();return o.jsxs(o.Fragment,{children:[M.marker.isSource&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.sourceColor,color:"#000"},children:"SRC"}),M.marker.isDestination&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.destinationColor,color:"#000"},children:"DST"}),M.marker.isHub&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.hubColor,color:"#000"},children:"HUB"}),M.marker.candidate.isLocal&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:e.localColor,color:"#fff"},children:"LOCAL"}),M.marker.candidate.isWardrive&&o.jsx("span",{className:"px-1 py-0.5 text-[8px] font-bold rounded",style:{backgroundColor:"#F97316",color:"#fff"},children:"WARDRIVE"})]})})()]}),o.jsxs("div",{className:"text-fg-muted type-data-xs",children:[M.marker.prefix," • ",M.marker.candidate.hash.slice(0,10),"..."]}),!M.marker.isPrimary&&M.marker.candidateCount>1&&o.jsxs("div",{style:{color:j().ambiguousColor},children:["Alternative (",(100*M.marker.candidate.probability).toFixed(0),"%)"]}),M.marker.isPrimary&&M.marker.candidateCount>1&&o.jsxs("div",{className:"text-fg-muted",children:[M.marker.candidateCount," candidates"]})]})})]},$)})]})}export{S as default}; diff --git a/frontend/dist/assets/RoomServer-COraO77j.js b/frontend/dist/assets/RoomServer-BvhmmII2.js similarity index 98% rename from frontend/dist/assets/RoomServer-COraO77j.js rename to frontend/dist/assets/RoomServer-BvhmmII2.js index 39ee551c..ce986df8 100644 --- a/frontend/dist/assets/RoomServer-COraO77j.js +++ b/frontend/dist/assets/RoomServer-BvhmmII2.js @@ -1 +1 @@ -import{j as e,W as s,Z as t,M as a,r as n}from"./vendor-react-alRNW2nb.js";import{C as l,P as i,a as r,B as o}from"./PageLayout-QhCLxU34.js";import{R as d,C as c}from"./Grid-m53vqd2Y.js";import{Y as m,bG as u,_ as x,h as p,I as h,bT as g,B as v,bb as f,q as j,bU as y,bV as b,bW as N,bX as k,bY as w,bZ as C,b_ as _,b$ as S,c0 as M,c1 as T,p as R,m as A,av as D}from"./index-D7i6lQrq.js";import{c as E,m as L}from"./node-types-CiI69Tya.js";import{c as $}from"./vendor-core-FtpmsTnh.js";import{j as F,bc as I,R as P,b7 as O,bd as K,a1 as z,as as U,l as q,C as B,be as G,bf as V,bg as H,a as Y,bh as W,B as Z,b8 as X,o as J,U as Q,k as ee}from"./vendor-icons-TO0PZKGR.js";import{L as se,a as te,b as ae}from"./listbox-BG13Q7Di.js";import{S as ne,K as le}from"./KeycapButton-B1_-eSeA.js";import{C as ie}from"./ConfirmModal-XwU3yUZY.js";import{S as re,C as oe}from"./ChatBubble-BkCCRzh5.js";import{e as de,g as ce,a as me}from"./chat-utils-DbM_TyxC.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./keycap-sfx-Bpx9zhkt.js";function ue({disabled:t,className:a,children:n}){return e.jsx(s,{disabled:t,className:$("flex flex-col gap-2",a),children:n})}function xe({required:s,className:a,children:n,...l}){return e.jsxs(t,{className:$("text-sm font-medium text-fg-primary select-none","data-[disabled]:opacity-50",l.title&&"cursor-help",a),...l,children:[n,s&&e.jsx("span",{className:"text-sys-red ml-0.5","aria-hidden":"true",children:"*"})]})}function pe({className:s,children:t,...n}){return e.jsx(a,{className:$("text-sm text-fg-muted","data-[disabled]:opacity-50",s),...n,children:t})}function he({icon:s,title:t,description:a,onClick:n,accent:l}){return e.jsxs("button",{onClick:n,className:$("flex flex-col items-center gap-3 p-6 rounded-2xl text-center","ring-1 ring-edge-subtle hover:ring-2 transition-all duration-150","w-full max-w-[260px]","primary"===l?"hover:ring-sys-blue hover:bg-sys-blue/5":"hover:ring-sys-indigo hover:bg-sys-indigo/5"),children:[e.jsx("div",{className:$("p-3 rounded-xl","primary"===l?"bg-sys-blue/10 text-sys-blue":"bg-sys-indigo/10 text-sys-indigo"),children:s}),e.jsx("p",{className:"type-body-sm font-medium text-fg-primary",children:t}),e.jsx("p",{className:"type-data-xs text-fg-muted leading-relaxed",children:a})]})}function ge({onCreateRoom:s}){return e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 px-4",children:[e.jsx(F,{className:"w-12 h-12 text-fg-muted opacity-30 mb-4"}),e.jsx("p",{className:"type-subheading text-fg-secondary mb-1",children:"Add a Room Server"}),e.jsx("p",{className:"type-body-sm text-fg-muted mb-8",children:"Choose how this device should operate."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center gap-4",children:[e.jsx(he,{icon:e.jsx(I,{className:"w-6 h-6"}),title:"Repeater + Room Server",description:"Keep forwarding packets and add group messaging.",onClick:()=>s("hybrid"),accent:"primary"}),e.jsx(he,{icon:e.jsx(P,{className:"w-6 h-6"}),title:"Dedicated Room Server",description:"Stop repeating. Focus entirely on room server duties.",onClick:()=>s("dedicated"),accent:"secondary"})]})]})}function ve({rooms:s,selected:t,onSelect:a,onAdd:n}){const l=n?e.jsx("button",{onClick:n,className:$("flex items-center justify-center px-2 py-1 rounded-md","text-fg-muted hover:text-fg-primary hover:bg-surface/60","transition-all duration-150"),title:"Add room server",children:e.jsx(O,{className:"w-4 h-4"})}):null;return s.length<=1?l:s.length<=3?e.jsxs("div",{className:"flex items-center gap-0.5 p-0.5 rounded-lg bg-subtle-fill",children:[s.map(s=>e.jsx("button",{onClick:()=>a(s.room_name),className:$("px-3 py-1 rounded-md text-sm font-medium transition-all duration-150",s.room_name===t?"bg-surface text-fg-primary shadow-sm":"text-fg-muted hover:text-fg-secondary"),children:s.room_name},s.room_name)),l]}):e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(se,{value:t??"",onChange:a,children:s.map(s=>e.jsx(te,{value:s.room_name,children:e.jsx(ae,{children:s.room_name})},s.room_name))}),l]})}function fe({open:s,onClose:t,mode:a,identity:l,repeaterConfig:i,onCreate:r,onUpdate:o,onDelete:d,onSendAdvert:c}){var f,j,y,b,N,k,w,C,_;const S="edit"===a&&l,M=`${s}-${(null==l?void 0:l.name)??""}-${a}`,[T,R]=n.useState(""),[A,D]=n.useState(""),[E,L]=n.useState(!1),[$,F]=n.useState(""),[I,P]=n.useState(""),[O,B]=n.useState(""),[G,V]=n.useState(""),[H,Y]=n.useState(!1),[W,Z]=n.useState(!1),[X,J]=n.useState(!1),[Q,ee]=n.useState(null),[se,te]=n.useState(M);if(M!==se)if(te(M),ee(null),Y(!1),Z(!1),J(!1),S)R((null==(f=l.settings)?void 0:f.node_name)??l.name),D(l.identity_key??""),L(!1),F((null==(j=l.settings)?void 0:j.admin_password)??""),P((null==(y=l.settings)?void 0:y.guest_password)??""),B((null==(N=null==(b=l.settings)?void 0:b.latitude)?void 0:N.toString())??""),V((null==(w=null==(k=l.settings)?void 0:k.longitude)?void 0:w.toString())??"");else{const e=i;R(""),D(""),L(!1),F(""),P(""),B(null!=(null==(C=null==e?void 0:e.repeater)?void 0:C.latitude)?e.repeater.latitude.toString():""),V(null!=(null==(_=null==e?void 0:e.repeater)?void 0:_.longitude)?e.repeater.longitude.toString():"")}const ae=n.useCallback(()=>{const e={};return T&&(e.node_name=T),$&&(e.admin_password=$),I&&(e.guest_password=I),""!==O&&(e.latitude=parseFloat(O)),""!==G&&(e.longitude=parseFloat(G)),e},[T,$,I,O,G]),ne=n.useCallback(async()=>{if(!T.trim())return void ee("Room name is required");Y(!0),ee(null);const e=S?l.name:function(e){if(!e)return"";const s=e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");return s?`${s}-room`:""}(T);let s;if(S)s=await o({name:l.name,settings:ae()});else{const t={name:e,type:"room_server",settings:ae()};A.trim()&&(t.identity_key=A.trim()),s=await r(t)}Y(!1),s?t():ee("Failed to save. Check that the name is unique and passwords differ.")},[T,S,l,ae,r,o,t]),le=n.useCallback(async()=>{if(!S)return;Z(!0);const e=await d(l.name);Z(!1),e&&t()},[S,l,d,t]),ie=n.useCallback(async()=>{S&&(J(!0),await c(l.name),J(!1))},[S,l,c]);return e.jsxs(m,{open:s,onClose:t,size:"md",children:[e.jsx(u,{icon:S?void 0:e.jsx(K,{className:"w-5 h-5"}),title:S?"Edit Room Server":"Add Room Server",onClose:t}),e.jsx(x,{children:e.jsxs("div",{className:"space-y-5",children:[S&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(p,{color:l.registered?"green":"red",children:l.registered?"Active":"Inactive"}),l.identity_key&&e.jsxs("span",{className:"type-data-xs text-fg-muted truncate",title:l.identity_key,children:["Key: ",l.identity_key.slice(0,16),"…"]})]}),e.jsxs(ue,{children:[e.jsx(xe,{title:"What people see on the mesh",children:"Room Name"}),e.jsx(h,{value:T,onChange:e=>R(e.target.value),placeholder:"Room Name"})]}),!S&&e.jsxs(ue,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(xe,{title:"The unique hex public ID",children:["Identity Key ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx("button",{type:"button",onClick:()=>L(e=>!e),className:"type-data-xs text-fg-muted underline hover:text-fg-secondary",children:E?"Hide":"Show"})]}),E&&e.jsxs(e.Fragment,{children:[e.jsx(h,{value:A,onChange:e=>D(e.target.value),placeholder:"Leave empty to auto-generate"}),e.jsx(pe,{children:"Leave empty to automatically generate a secure key"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(z,{className:"inline w-3.5 h-3.5 -mt-0.5 mr-1 text-fg-muted"}),"Latitude"]}),e.jsx(h,{type:"number",step:"any",value:O,onChange:e=>B(e.target.value),placeholder:"0"})]}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(z,{className:"inline w-3.5 h-3.5 -mt-0.5 mr-1 text-fg-muted"}),"Longitude"]}),e.jsx(h,{type:"number",step:"any",value:G,onChange:e=>V(e.target.value),placeholder:"0"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs(ue,{children:[e.jsxs(xe,{title:"Full access to room server",children:["Admin Password ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx(h,{type:"password",value:$,onChange:e=>F(e.target.value),placeholder:"None Set"})]}),e.jsxs(ue,{children:[e.jsxs(xe,{title:"Can post and read, but not administer the room",children:["Guest Password ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx(h,{type:"password",value:I,onChange:e=>P(e.target.value),placeholder:"None Set"})]})]}),Q&&e.jsx("p",{className:"type-data-xs text-sys-red",children:Q})]})}),e.jsxs(g,{children:[S&&e.jsxs("div",{className:"flex items-center gap-2 mr-auto",children:[e.jsxs(v,{color:"danger",plain:!0,onClick:le,disabled:W,children:[e.jsx(U,{"data-slot":"icon"}),W?"Deleting…":"Delete"]}),e.jsxs(v,{color:"primary",plain:!0,onClick:ie,disabled:X,children:[e.jsx(q,{"data-slot":"icon"}),X?"Sending…":"Send Advert"]})]}),e.jsx(v,{plain:!0,onClick:t,children:"Cancel"}),e.jsx(v,{color:"primary",onClick:ne,disabled:H,children:H?"Saving…":S?"Save Changes":"Create"})]})]})}const je=n.createContext(null),ye="room-tui";function be({children:s}){const[t,a]=n.useState(()=>"0"!==localStorage.getItem(ye)),l=n.useCallback(()=>{a(e=>{const s=!e;return localStorage.setItem(ye,s?"1":"0"),s})},[]);return e.jsx(je.Provider,{value:{terminalMode:t,toggleTerminalMode:l},children:s})}function Ne(){const e=n.useContext(je);if(!e)throw new Error("useTerminalMode must be used within RoomTerminalProvider");return e}const ke=e=>"server"===e.author_pubkey||"system"===e.author_pubkey;function we({messages:s,onDelete:t,terminalMode:a,serverName:l}){const i=n.useRef(null),[r,o]=n.useState(!1),d=n.useMemo(()=>[...s].sort((e,s)=>e.post_timestamp-s.post_timestamp),[s]);n.useEffect(()=>{!r&&i.current&&(i.current.scrollTop=0)},[d.length,r]);const c=n.useCallback(()=>{i.current&&o(i.current.scrollTop<-100)},[]),m=n.useCallback(()=>{i.current&&i.current.scrollTo({top:0,behavior:"smooth"}),o(!1)},[]);return 0===d.length?e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center py-12 min-h-0"+(a?" font-mono":""),children:a?e.jsx("p",{className:"text-sm font-mono",style:{color:"var(--tui-accent)",opacity:.4},children:"> no messages in buffer_"}):e.jsxs(e.Fragment,{children:[e.jsx(F,{className:"w-10 h-10 text-fg-muted opacity-20 mb-2"}),e.jsx("p",{className:"type-data-sm text-fg-muted",children:"No messages yet"})]})}):a?e.jsxs("div",{className:"relative flex-1 min-h-0",children:[e.jsx("div",{ref:i,onScroll:c,className:"h-full overflow-y-auto scroll-smooth p-4 font-mono text-sm leading-relaxed flex flex-col-reverse",children:e.jsx("div",{children:d.map(s=>{const a=ke(s),n=new Date(1e3*s.post_timestamp).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),i=a?"SYS":s.author_name||s.author_prefix,r=!a&&l&&i===l;return e.jsxs("div",{className:"group flex items-start gap-0 -mx-4 px-4 py-px",style:{"--tw-hover-bg":"var(--tui-hover-bg)"},onMouseEnter:e=>e.currentTarget.style.background="var(--tui-hover-bg)",onMouseLeave:e=>e.currentTarget.style.background="",children:[e.jsxs("span",{className:"select-none shrink-0",style:{color:"var(--tui-muted)"},children:["[",n,"]"]}),e.jsxs("span",{className:"mx-1.5 shrink-0",style:{color:r?"var(--tui-accent-local)":"var(--tui-accent)"},children:["<",i,">"]}),e.jsx("span",{style:{color:a?"var(--tui-system)":r?"var(--tui-body)":"var(--tui-accent)"},className:a?"italic":"",children:s.message_text}),e.jsx("button",{onClick:()=>t(s.id),className:"opacity-0 group-hover:opacity-100 ml-auto pl-2 shrink-0 transition-colors",style:{color:"var(--tui-muted)"},onMouseEnter:e=>e.currentTarget.style.color="var(--tui-danger)",onMouseLeave:e=>e.currentTarget.style.color="var(--tui-muted)",title:"Delete",children:"×"})]},s.id)})})}),r&&e.jsxs("button",{onClick:m,className:"absolute bottom-3 left-1/2 -translate-x-1/2 flex items-center gap-1.5 px-3 py-1 font-mono text-xs transition-colors duration-150",style:{background:"var(--tui-hover-bg)",border:"1px solid var(--tui-muted)",color:"var(--tui-accent)"},children:[e.jsx(B,{className:"w-3 h-3"}),"↓ scroll"]})]}):e.jsxs("div",{className:"relative flex-1 min-h-0",children:[e.jsx("div",{ref:i,onScroll:c,className:"h-full overflow-y-auto scroll-smooth flex flex-col-reverse",children:e.jsx("div",{className:"space-y-3 p-4",children:d.map(s=>ke(s)?e.jsx(re,{text:s.message_text},s.id):e.jsx(oe,{senderName:s.author_name||s.author_prefix,text:s.message_text,timestamp:s.post_timestamp,bubbleAccessory:e.jsx("button",{onClick:()=>t(s.id),className:"opacity-0 group-hover:opacity-100 transition-opacity duration-150 p-1 text-fg-muted hover:text-sys-red flex-shrink-0",title:"Delete message",children:e.jsx(U,{className:"w-3.5 h-3.5"})})},s.id))})}),r&&e.jsxs("button",{onClick:m,className:"absolute bottom-3 left-1/2 -translate-x-1/2 flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-surface/90 backdrop-blur-sm ring-1 ring-edge-subtle shadow-md text-fg-secondary hover:text-fg-primary transition-colors duration-150",children:[e.jsx(B,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"type-data-xs",children:"New messages"})]})]})}function Ce({roomName:s,onSend:t,disabled:a,terminalMode:l}){const[i,r]=n.useState(""),[o,d]=n.useState(!1),c=n.useRef(null),m=n.useCallback(async()=>{var e;const s=i.trim();if(!s||o)return;d(!0);const a=await t(s);d(!1),a&&(r(""),null==(e=c.current)||e.focus())},[i,o,t]),u=n.useCallback(e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),m())},[m]);return l?e.jsxs("div",{className:"flex items-center gap-0 px-4 py-2 type-data-sm",children:[e.jsx("input",{ref:c,type:"text",value:i,onChange:e=>r(e.target.value),onKeyDown:u,placeholder:"type message...",disabled:a||o,className:"flex-1 bg-transparent outline-none ring-0 shadow-none border-none focus:outline-none focus:ring-0 font-mono tui-input",style:{color:"var(--tui-body)"}}),e.jsx("button",{onClick:m,disabled:!i.trim()||o||a,className:"transition-colors duration-100 px-1 font-mono text-xs disabled:opacity-30",style:{color:"var(--tui-accent)"},title:"Send",children:"[↵]"})]}):e.jsxs("div",{className:"flex items-center gap-2 p-3 border-t border-edge-subtle",children:[e.jsx("input",{ref:c,type:"text",value:i,onChange:e=>r(e.target.value),onKeyDown:u,placeholder:`Message ${s}…`,disabled:a||o,className:"flex-1 surface-input radius-inner px-3 py-2 type-body-sm text-fg-primary placeholder:text-fg-muted outline-none ring-focus"}),e.jsx("button",{onClick:m,disabled:!i.trim()||o||a,className:"p-2 rounded-lg text-sys-blue hover:bg-sys-blue/10 disabled:opacity-30 disabled:hover:bg-transparent transition-colors duration-150",title:"Send message",children:e.jsx(q,{className:"w-4.5 h-4.5"})})]})}function _e({selectedName:s,selectedIdentity:t,messages:a,onSend:i,onDelete:r,onClear:o}){var d;const{terminalMode:c,toggleTerminalMode:m}=Ne(),[u,x]=n.useState(!1),p=(null==(d=null==t?void 0:t.settings)?void 0:d.node_name)??s??void 0,h=n.useCallback(()=>{x(!1),o()},[o]);return c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-col h-full gap-1.5",children:[e.jsxs("div",{className:"card-terminal-header flex-shrink-0",children:[e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:"chat",minChars:7,size:24})}),e.jsx("div",{className:"card-terminal-ridge flex-1"}),e.jsxs("div",{className:"header-well",children:[e.jsx(le,{icon:e.jsx(G,{className:"!w-5.5 !h-5.5 translate-y-px"}),onClick:m,title:"Exit terminal mode"}),a.length>0&&e.jsx(le,{icon:e.jsx("span",{className:"text-[13px] font-bold font-mono leading-none translate-y-px",children:"DEL"}),onClick:()=>x(!0),title:"Clear all messages",variant:"red",iconActiveColor:f.red})]})]}),e.jsx(l,{noPadding:!0,className:"flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",children:e.jsxs("div",{className:"card-terminal-well flex-1 min-h-0 flex flex-col overflow-hidden",children:[e.jsx(we,{messages:a,onDelete:r,terminalMode:!0,serverName:p}),e.jsx("div",{className:"card-terminal-divider"}),s&&e.jsx(Ce,{roomName:s,onSend:i,disabled:!(null==t?void 0:t.registered),terminalMode:!0})]})})]}),e.jsx(ie,{isOpen:u,title:"Clear All Messages",message:`This will permanently delete all ${a.length} message${1===a.length?"":"s"} from this room. This cannot be undone.`,confirmLabel:"Clear Messages",variant:"danger",onConfirm:h,onCancel:()=>x(!1)})]}):e.jsxs(e.Fragment,{children:[e.jsxs(l,{noPadding:!0,className:"flex flex-col h-full overflow-hidden",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(V,{className:"icon-sm"}),title:"Messages",actions:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(v,{plain:!0,onClick:m,title:"Terminal mode",children:e.jsx(G,{"data-slot":"icon",className:"!w-5 !h-5 translate-y-px"})}),a.length>0&&e.jsx(v,{plain:!0,onClick:()=>x(!0),title:"Clear all messages",children:e.jsx("span",{"data-slot":"icon",className:"text-[12px] font-bold font-mono leading-none translate-y-px text-sys-red",children:"DEL"})})]})}),e.jsx(we,{messages:a,onDelete:r,terminalMode:!1,serverName:p}),s&&e.jsx(Ce,{roomName:s,onSend:i,disabled:!(null==t?void 0:t.registered),terminalMode:!1})]}),e.jsx(ie,{isOpen:u,title:"Clear All Messages",message:`This will permanently delete all ${a.length} message${1===a.length?"":"s"} from this room. This cannot be undone.`,confirmLabel:"Clear Messages",variant:"danger",onConfirm:h,onCancel:()=>x(!1)})]})}function Se({pubkey:s,className:t}){const[a,l]=n.useState(!1),i=n.useCallback(()=>{navigator.clipboard.writeText(s),l(!0),setTimeout(()=>l(!1),1500)},[s]);return e.jsxs("button",{onClick:i,title:a?"Copied!":"Copy public key",className:`inline-flex items-center gap-1 type-data-xs leading-tight text-fg-muted hover:text-fg-secondary transition-colors duration-150 cursor-copy ${t??""}`,children:[e.jsx("span",{className:"truncate min-w-0",children:s.slice(0,8)}),a&&e.jsx(Y,{className:"w-2.5 h-2.5 text-sys-green flex-shrink-0"})]})}const Me=n.memo(function({client:s,resolvedName:t,onRemove:a}){const n=s.name||t,l=0===s.unsynced_count,i=s.last_activity?new Date(1e3*s.last_activity).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"Never",{emoji:r,cleanName:o}=n?de(n):{emoji:null,cleanName:s.pubkey_prefix},d=n?ce(o):void 0,c=n?me(n):s.pubkey_prefix.slice(0,2).toUpperCase();return e.jsxs("div",{className:"group flex items-center gap-3 px-3 py-2.5 radius-inner row-hover transition-base",children:[e.jsxs("div",{className:"relative flex-shrink-0",children:[e.jsx("div",{className:$("w-8 h-8 rounded-full flex items-center justify-center",!d&&"bg-sys-blue/12"),style:d?{backgroundColor:d}:void 0,children:r?e.jsx("span",{className:"text-base leading-none",children:r}):e.jsx("span",{className:$("leading-none",d?"text-white text-[11px] font-bold tracking-tight":"text-sys-blue font-mono text-[11px]"),children:c})}),e.jsx("span",{className:"absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-sm ring-2 ring-surface "+(l?"bg-sys-green":"bg-sys-indigo")})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[n?e.jsx("p",{className:"text-[13px] font-medium leading-tight text-fg-primary truncate",children:n}):e.jsx("p",{className:"font-mono text-[13px] leading-tight text-fg-primary truncate",children:s.pubkey_prefix}),e.jsxs("div",{className:"flex items-center gap-1.5 mt-0.5",children:[n&&e.jsx(Se,{pubkey:s.pubkey}),n&&e.jsx("span",{className:"text-xs text-fg-muted/40",children:"·"}),e.jsxs("span",{className:"text-xs leading-tight text-fg-muted truncate",children:[!l&&e.jsxs("span",{className:"text-sys-indigo",children:[s.unsynced_count," unsynced · "]}),i]})]})]}),e.jsx("button",{onClick:()=>a(s.pubkey),className:"opacity-0 group-hover:opacity-100 transition-opacity duration-150 p-1.5 -mr-1 rounded-md text-fg-muted hover:text-sys-red hover:bg-sys-red/8",title:"Remove client",children:e.jsx(H,{className:"w-3.5 h-3.5"})})]})});function Te({clients:s,onRemove:t,messages:a,terminalMode:l}){const i=n.useMemo(()=>{const e=new Map;if(!a)return e;for(let s=a.length-1;s>=0;s--){const t=a[s];t.author_name&&t.author_pubkey&&"server"!==t.author_pubkey&&"system"!==t.author_pubkey&&e.set(t.author_pubkey,t.author_name)}return e},[a]);return 0===s.length?l?e.jsx("p",{className:"type-data-sm text-left px-4 py-4",style:{color:"var(--tui-accent)"},children:"< NO CLIENTS CONNECTED >"}):e.jsx("p",{className:"type-data-xs text-fg-muted text-center py-4",children:"No clients connected"}):l?e.jsx("div",{className:"type-data-sm pt-2",children:s.map(s=>{const a=s.name||i.get(s.pubkey),n=0===s.unsynced_count,l=s.pubkey_prefix;return e.jsxs("div",{className:"group flex items-center gap-0 -mx-0 px-4 py-0.5",onMouseEnter:e=>e.currentTarget.style.background="var(--tui-hover-bg)",onMouseLeave:e=>e.currentTarget.style.background="",children:[e.jsx("span",{style:{color:n?"var(--tui-accent)":"var(--tui-warn)"},children:"■"}),e.jsx("span",{className:"ml-2 shrink-0",style:{color:"var(--tui-accent)"},children:a||l}),a&&e.jsxs("span",{className:"ml-1.5 shrink-0",style:{color:"var(--tui-accent)"},children:["[",l,"]"]}),!n&&e.jsxs("span",{className:"ml-1.5",style:{color:"var(--tui-warn)"},children:[s.unsynced_count,"unsync"]}),e.jsx("button",{onClick:()=>t(s.pubkey),className:"opacity-0 group-hover:opacity-100 ml-auto pl-2 shrink-0 transition-colors",style:{color:"var(--tui-muted)"},onMouseEnter:e=>e.currentTarget.style.color="var(--tui-danger)",onMouseLeave:e=>e.currentTarget.style.color="var(--tui-muted)",title:"Remove",children:"×"})]},s.pubkey)})}):e.jsx("div",{className:"space-y-0.5 pt-1",children:s.map(s=>e.jsx(Me,{client:s,resolvedName:i.get(s.pubkey),onRemove:t},s.pubkey))})}function Re({name:s,onSend:t}){const{terminalMode:a}=Ne(),[l,i]=n.useState("idle"),r=n.useRef(),o=n.useCallback(async()=>{if("sending"===l)return;i("sending");const e=await t(s);i(e?"sent":"idle"),e&&(r.current=setTimeout(()=>i("idle"),2e3))},[s,t,l]);return n.useEffect(()=>()=>clearTimeout(r.current),[]),a?e.jsxs("button",{className:"btn-terminal",onClick:o,disabled:"sending"===l,children:["idle"===l&&"[ send_advert ]","sending"===l&&"[ broadcasting... ]","sent"===l&&"[ sent ✓ ]"]}):e.jsxs(v,{color:"sent"===l?"success":"primary",className:"w-full",onClick:o,disabled:"sending"===l,children:[e.jsx(W,{"data-slot":"icon"}),"idle"===l&&"Send Advert","sending"===l&&"Broadcasting…","sent"===l&&"Advert Sent"]})}function Ae({identity:s,onSendAdvert:t}){var a,l,i,r,o,d,c,m,u,x,h,g,v,f,y,b,N,k,w,C,_,S,M,T,R,A,D,E,L,$;const{terminalMode:F}=Ne(),[I,P]=n.useState(!1),O=n.useCallback(()=>{(null==s?void 0:s.identity_key)&&(navigator.clipboard.writeText(s.identity_key),P(!0),setTimeout(()=>P(!1),1500))},[null==s?void 0:s.identity_key]);return F?s?e.jsxs("div",{className:"space-y-1",children:[(null==(a=s.settings)?void 0:a.node_name)&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"node"}),e.jsx("span",{style:{color:"var(--tui-accent)"},children:s.settings.node_name})]}),(s.address||(null==(l=s.runtime)?void 0:l.address))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"addr"}),e.jsx("span",{style:{color:"var(--tui-accent)"},children:s.address||(null==(i=s.runtime)?void 0:i.address)})]}),s.identity_key&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"key"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"truncate max-w-[140px]",style:{color:"var(--tui-accent)"},title:s.identity_key,children:[s.identity_key.slice(0,16),"…"]}),e.jsx("button",{type:"button",onClick:O,className:"text-xs",style:{color:"var(--tui-muted)"},children:I?"[copied ✓]":"[copy]"})]})]}),(null!=(null==(r=s.settings)?void 0:r.latitude)||null!=(null==(o=s.settings)?void 0:o.longitude))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"loc"}),e.jsxs("span",{style:{color:"var(--tui-accent)"},title:`${(null==(d=s.settings)?void 0:d.latitude)??"—"}, ${(null==(c=s.settings)?void 0:c.longitude)??"—"}`,children:[(null==(u=null==(m=s.settings)?void 0:m.latitude)?void 0:u.toFixed(4))??"—",", ",(null==(h=null==(x=s.settings)?void 0:x.longitude)?void 0:h.toFixed(4))??"—"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"pass"}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{style:{color:(null==(g=s.settings)?void 0:g.admin_password)?"var(--tui-accent)":"var(--tui-muted)"},children:(null==(v=s.settings)?void 0:v.admin_password)?"[✓ admin]":"[— admin]"}),e.jsx("span",{style:{color:(null==(f=s.settings)?void 0:f.guest_password)?"var(--tui-accent)":"var(--tui-muted)"},children:(null==(y=s.settings)?void 0:y.guest_password)?"[✓ guest]":"[— guest]"})]})]})]}):e.jsx("span",{style:{color:"var(--tui-muted)"},children:"no identity configured"}):e.jsxs("div",{className:"flex-shrink-0 border-t border-edge-subtle",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(Z,{className:"icon-sm"}),title:"Room Info"}),s?e.jsxs("div",{className:"space-y-2 px-4 py-3",children:[(null==(b=s.settings)?void 0:b.node_name)&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Node"}),e.jsx("span",{className:"type-data-sm text-fg-primary",children:s.settings.node_name})]}),(s.address||(null==(N=s.runtime)?void 0:N.address))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Address"}),e.jsx("span",{className:"type-data-sm font-mono text-fg-primary",children:s.address||(null==(k=s.runtime)?void 0:k.address)})]}),s.identity_key&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"type-data-xs text-fg-muted flex items-center gap-1",title:"The unique hex public ID",children:[e.jsx(X,{className:"w-3 h-3"}),"Key"]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("span",{className:"type-data-sm font-mono text-fg-primary truncate max-w-[140px]",title:s.identity_key,children:[s.identity_key.slice(0,16),"…"]}),e.jsx("button",{type:"button",onClick:O,className:"inline-flex items-center gap-0.5",children:e.jsx(p,{color:I?"green":"zinc",children:I?e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"w-3 h-3"}),"Copied"]}):e.jsxs(e.Fragment,{children:[e.jsx(J,{className:"w-3 h-3"}),"Copy"]})})})]})]}),(null!=(null==(w=s.settings)?void 0:w.latitude)||null!=(null==(C=s.settings)?void 0:C.longitude))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"type-data-xs text-fg-muted flex items-center gap-1",children:[e.jsx(z,{className:"w-3 h-3"}),"Location"]}),e.jsxs("span",{className:"type-data-sm font-mono text-fg-primary",title:`${(null==(_=s.settings)?void 0:_.latitude)??"—"}, ${(null==(S=s.settings)?void 0:S.longitude)??"—"}`,children:[(null==(T=null==(M=s.settings)?void 0:M.latitude)?void 0:T.toFixed(4))??"—",", ",(null==(A=null==(R=s.settings)?void 0:R.longitude)?void 0:A.toFixed(4))??"—"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Passwords"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(p,{color:(null==(D=s.settings)?void 0:D.admin_password)?"green":"zinc",children:[(null==(E=s.settings)?void 0:E.admin_password)&&e.jsx(Y,{className:"w-3 h-3"}),"Admin"]}),e.jsxs(p,{color:(null==(L=s.settings)?void 0:L.guest_password)?"green":"zinc",children:[(null==($=s.settings)?void 0:$.guest_password)&&e.jsx(Y,{className:"w-3 h-3"}),"Guest"]})]})]}),e.jsx("div",{className:"pt-3",children:e.jsx(Re,{name:s.name,onSend:t})})]}):e.jsx("p",{className:"type-data-xs text-fg-muted text-center py-3",children:"No identity configured"})]})}function De({selectedIdentity:s,clients:t,messages:a,onSendAdvert:i}){const{terminalMode:r}=Ne(),o=n.useCallback(async e=>{y.setState(s=>({clients:s.clients.filter(s=>s.pubkey!==e)})),await b({public_key:e})},[]);return r?e.jsxs("div",{className:"flex flex-col h-full gap-1.5",children:[s&&e.jsx("div",{className:"hidden lg:block",children:e.jsx("div",{className:"card-terminal-header flex-shrink-0",children:e.jsx("div",{className:"header-well flex-1",children:e.jsx(le,{icon:e.jsx(W,{}),onPress:()=>i(s.name),title:"Send room server advert",indicators:[{label:"ADVERTISE",trackPress:!0},{label:"ACTIVE",active:s.registered}]})})})}),e.jsxs("div",{className:"flex flex-col flex-1 min-h-0 gap-1.5",children:[e.jsx("div",{className:"card-terminal-header flex-shrink-0",children:e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:`OnLInE ${String(t.length).padStart(3,"0")}`,size:24})})}),e.jsx(l,{noPadding:!0,className:"!h-auto flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",children:e.jsx("div",{className:"card-terminal-well flex-1 min-h-0 overflow-y-auto",children:e.jsx(Te,{clients:t,onRemove:o,messages:a,terminalMode:!0})})}),e.jsxs("div",{className:"card-terminal-header flex-shrink-0",children:[e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:"StAtUS "+((null==s?void 0:s.registered)?"On":"OFF"),size:24})}),s&&e.jsx("div",{className:"lg:hidden flex-1 flex min-w-0",children:e.jsx("div",{className:"header-well flex-1 !flex-shrink",children:e.jsx(le,{icon:e.jsx(W,{}),onPress:()=>i(s.name),title:"Send room server advert",className:"flex-row-reverse",indicators:[{label:"ACTIVE",active:s.registered},{label:"ADVERTISE",trackPress:!0}]})})})]}),e.jsx(l,{noPadding:!0,className:"!h-auto flex-shrink-0 overflow-hidden card-terminal",children:e.jsx("div",{className:"card-terminal-well px-4 py-3 type-data-sm",children:e.jsx(Ae,{identity:s,onSendAdvert:i})})})]})]}):e.jsxs(l,{compact:!0,className:"flex-1 min-h-0 flex flex-col overflow-hidden",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(Q,{className:"icon-sm"}),title:"Clients",actions:t.length>0?e.jsx("span",{className:"type-data-xs text-fg-muted",children:t.length}):void 0}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:e.jsx(Te,{clients:t,onRemove:o,messages:a,terminalMode:!1})}),e.jsx(Ae,{identity:s,onSendAdvert:i})]})}function Ee(){const s=N(),t=k(),a=w(),l=C(),m=_(),u=S(),x=M(),p=T(),h=R(),g=A(),f=(se=n.useMemo(()=>(null==h?void 0:h.neighbors)??{},[null==h?void 0:h.neighbors]),te=g,n.useMemo(()=>{const e=new Map;for(const[t,a]of Object.entries(se)){const s=a.name||a.node_name||null,{type:n}=E(a);e.set(t.toLowerCase(),{name:s,type:n})}const s=new Map;for(let t=te.length-1;t>=0;t--){const e=te[t];if(!e._advertSender)continue;const a=e._advertSender.toLowerCase();if(s.has(a))continue;const n=e._advertName??null,l=null!=e._advertNodeType?L(e._advertNodeType):"companion";s.set(a,{name:n,type:l})}return function(t){const a=t.toLowerCase(),n=e.get(a);if(null==n?void 0:n.name)return n;const l=s.get(a);return(null==l?void 0:l.name)?l:n||l||{name:null,type:"companion"}}},[se,te])),j=n.useMemo(()=>u.map(e=>{if(e.name)return e;const s=f(e.pubkey);return s.name?{...e,name:s.name}:e}),[u,f]),b=n.useMemo(()=>m.map(e=>{if(e.author_name||"server"===e.author_pubkey||"system"===e.author_pubkey)return e;const s=f(e.author_pubkey);return s.name?{...e,author_name:s.name}:e}),[m,f]),{selectRoom:$,postMessage:I,deleteMessage:P,clearMessages:O,createRoom:K,updateRoom:z,deleteRoom:U,sendAdvert:q,markAsRead:B,startActivePolling:G}=y.getState(),[H,Y]=n.useState(!1),[W,Z]=n.useState("create"),[X,J]=n.useState("hybrid");var se,te;n.useEffect(()=>{B()},[t,B]),n.useEffect(()=>G(),[G]);const ae=n.useCallback(async e=>!!t&&I({room_name:t,message:e,author_pubkey:"server"}),[t,I]),ne=n.useCallback((e="hybrid")=>{J(e),Z("create"),Y(!0)},[]),le=n.useCallback(()=>{Z("edit"),Y(!0)},[]),ie=e.jsxs("div",{className:"flex items-center gap-2 sm:gap-4 flex-shrink-0",children:[a&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${a.total_messages} message${1!==a.total_messages?"s":""} in this room`,children:[e.jsx(V,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:a.total_messages})]}),e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${a.total_clients} client${1!==a.total_clients?"s":""} connected`,children:[e.jsx(Q,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:a.total_clients})]})]}),e.jsx(ve,{rooms:s,selected:t,onSelect:$,onAdd:()=>ne("hybrid")}),s.length>0&&e.jsx(v,{plain:!0,onClick:le,title:"Manage room server",children:e.jsx(ee,{"data-slot":"icon"})})]});return 0!==s.length||0!==x.length||p?e.jsx(be,{children:e.jsxs(i,{children:[e.jsx(r,{title:"Room Server",icon:e.jsx(F,{}),controls:ie}),e.jsx(o,{children:e.jsxs(d,{template:"hero-tall",className:"!h-[calc(100vh-11rem)] !min-h-[400px]",children:[e.jsx(c,{span:12,lg:8,className:"h-full",children:e.jsx(_e,{selectedName:t,selectedIdentity:l,messages:b,onSend:ae,onDelete:P,onClear:O})}),e.jsx(c,{span:12,lg:4,className:"h-full",children:e.jsx(De,{selectedIdentity:l,clients:j,messages:b,onSendAdvert:q})})]})}),e.jsx(fe,{open:H,onClose:()=>Y(!1),mode:W,identity:l,repeaterConfig:null==h?void 0:h.config,onCreate:K,onUpdate:z,onDelete:U,onSendAdvert:q})]})}):e.jsx(be,{children:e.jsxs(i,{children:[e.jsx(r,{title:"Room Server",icon:e.jsx(F,{})}),e.jsx(ge,{onCreateRoom:e=>ne(e)}),e.jsx(fe,{open:H,onClose:()=>Y(!1),mode:"create",repeaterConfig:null==h?void 0:h.config,onCreate:async e=>{const s=await K(e);return s&&"dedicated"===X&&(await D.getState().setMode("monitor"),D.getState().clearModeMutation()),s},onUpdate:z,onDelete:U,onSendAdvert:q})]})})}export{Ee as default}; +import{j as e,W as s,Z as t,M as a,r as n}from"./vendor-react-alRNW2nb.js";import{C as l,P as i,a as r,B as o}from"./PageLayout-BWMUVZgC.js";import{R as d,C as c}from"./Grid-m53vqd2Y.js";import{Y as m,bG as u,_ as x,h as p,I as h,bT as g,B as v,bb as f,q as j,bU as y,bV as b,bW as N,bX as k,bY as w,bZ as C,b_ as _,b$ as S,c0 as M,c1 as T,p as R,m as A,av as D}from"./index-CkRTgHHA.js";import{c as E,m as L}from"./node-types-DRVunROD.js";import{c as $}from"./vendor-core-FtpmsTnh.js";import{j as F,bc as I,R as P,b7 as O,bd as K,a1 as z,as as U,l as q,C as B,be as G,bf as V,bg as H,a as Y,bh as W,B as Z,b8 as X,o as J,U as Q,k as ee}from"./vendor-icons-TO0PZKGR.js";import{L as se,a as te,b as ae}from"./listbox-DrzA7Ewq.js";import{S as ne,K as le}from"./KeycapButton-DdWNfiky.js";import{C as ie}from"./ConfirmModal-B6Rz8ROW.js";import{S as re,C as oe}from"./ChatBubble-OmHlf-X1.js";import{e as de,g as ce,a as me}from"./chat-utils-mqGCinix.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./keycap-sfx-Bpx9zhkt.js";function ue({disabled:t,className:a,children:n}){return e.jsx(s,{disabled:t,className:$("flex flex-col gap-2",a),children:n})}function xe({required:s,className:a,children:n,...l}){return e.jsxs(t,{className:$("text-sm font-medium text-fg-primary select-none","data-[disabled]:opacity-50",l.title&&"cursor-help",a),...l,children:[n,s&&e.jsx("span",{className:"text-sys-red ml-0.5","aria-hidden":"true",children:"*"})]})}function pe({className:s,children:t,...n}){return e.jsx(a,{className:$("text-sm text-fg-muted","data-[disabled]:opacity-50",s),...n,children:t})}function he({icon:s,title:t,description:a,onClick:n,accent:l}){return e.jsxs("button",{onClick:n,className:$("flex flex-col items-center gap-3 p-6 rounded-2xl text-center","ring-1 ring-edge-subtle hover:ring-2 transition-all duration-150","w-full max-w-[260px]","primary"===l?"hover:ring-sys-blue hover:bg-sys-blue/5":"hover:ring-sys-indigo hover:bg-sys-indigo/5"),children:[e.jsx("div",{className:$("p-3 rounded-xl","primary"===l?"bg-sys-blue/10 text-sys-blue":"bg-sys-indigo/10 text-sys-indigo"),children:s}),e.jsx("p",{className:"type-body-sm font-medium text-fg-primary",children:t}),e.jsx("p",{className:"type-data-xs text-fg-muted leading-relaxed",children:a})]})}function ge({onCreateRoom:s}){return e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 px-4",children:[e.jsx(F,{className:"w-12 h-12 text-fg-muted opacity-30 mb-4"}),e.jsx("p",{className:"type-subheading text-fg-secondary mb-1",children:"Add a Room Server"}),e.jsx("p",{className:"type-body-sm text-fg-muted mb-8",children:"Choose how this device should operate."}),e.jsxs("div",{className:"flex flex-col sm:flex-row items-center gap-4",children:[e.jsx(he,{icon:e.jsx(I,{className:"w-6 h-6"}),title:"Repeater + Room Server",description:"Keep forwarding packets and add group messaging.",onClick:()=>s("hybrid"),accent:"primary"}),e.jsx(he,{icon:e.jsx(P,{className:"w-6 h-6"}),title:"Dedicated Room Server",description:"Stop repeating. Focus entirely on room server duties.",onClick:()=>s("dedicated"),accent:"secondary"})]})]})}function ve({rooms:s,selected:t,onSelect:a,onAdd:n}){const l=n?e.jsx("button",{onClick:n,className:$("flex items-center justify-center px-2 py-1 rounded-md","text-fg-muted hover:text-fg-primary hover:bg-surface/60","transition-all duration-150"),title:"Add room server",children:e.jsx(O,{className:"w-4 h-4"})}):null;return s.length<=1?l:s.length<=3?e.jsxs("div",{className:"flex items-center gap-0.5 p-0.5 rounded-lg bg-subtle-fill",children:[s.map(s=>e.jsx("button",{onClick:()=>a(s.room_name),className:$("px-3 py-1 rounded-md text-sm font-medium transition-all duration-150",s.room_name===t?"bg-surface text-fg-primary shadow-sm":"text-fg-muted hover:text-fg-secondary"),children:s.room_name},s.room_name)),l]}):e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(se,{value:t??"",onChange:a,children:s.map(s=>e.jsx(te,{value:s.room_name,children:e.jsx(ae,{children:s.room_name})},s.room_name))}),l]})}function fe({open:s,onClose:t,mode:a,identity:l,repeaterConfig:i,onCreate:r,onUpdate:o,onDelete:d,onSendAdvert:c}){var f,j,y,b,N,k,w,C,_;const S="edit"===a&&l,M=`${s}-${(null==l?void 0:l.name)??""}-${a}`,[T,R]=n.useState(""),[A,D]=n.useState(""),[E,L]=n.useState(!1),[$,F]=n.useState(""),[I,P]=n.useState(""),[O,B]=n.useState(""),[G,V]=n.useState(""),[H,Y]=n.useState(!1),[W,Z]=n.useState(!1),[X,J]=n.useState(!1),[Q,ee]=n.useState(null),[se,te]=n.useState(M);if(M!==se)if(te(M),ee(null),Y(!1),Z(!1),J(!1),S)R((null==(f=l.settings)?void 0:f.node_name)??l.name),D(l.identity_key??""),L(!1),F((null==(j=l.settings)?void 0:j.admin_password)??""),P((null==(y=l.settings)?void 0:y.guest_password)??""),B((null==(N=null==(b=l.settings)?void 0:b.latitude)?void 0:N.toString())??""),V((null==(w=null==(k=l.settings)?void 0:k.longitude)?void 0:w.toString())??"");else{const e=i;R(""),D(""),L(!1),F(""),P(""),B(null!=(null==(C=null==e?void 0:e.repeater)?void 0:C.latitude)?e.repeater.latitude.toString():""),V(null!=(null==(_=null==e?void 0:e.repeater)?void 0:_.longitude)?e.repeater.longitude.toString():"")}const ae=n.useCallback(()=>{const e={};return T&&(e.node_name=T),$&&(e.admin_password=$),I&&(e.guest_password=I),""!==O&&(e.latitude=parseFloat(O)),""!==G&&(e.longitude=parseFloat(G)),e},[T,$,I,O,G]),ne=n.useCallback(async()=>{if(!T.trim())return void ee("Room name is required");Y(!0),ee(null);const e=S?l.name:function(e){if(!e)return"";const s=e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");return s?`${s}-room`:""}(T);let s;if(S)s=await o({name:l.name,settings:ae()});else{const t={name:e,type:"room_server",settings:ae()};A.trim()&&(t.identity_key=A.trim()),s=await r(t)}Y(!1),s?t():ee("Failed to save. Check that the name is unique and passwords differ.")},[T,S,l,ae,r,o,t]),le=n.useCallback(async()=>{if(!S)return;Z(!0);const e=await d(l.name);Z(!1),e&&t()},[S,l,d,t]),ie=n.useCallback(async()=>{S&&(J(!0),await c(l.name),J(!1))},[S,l,c]);return e.jsxs(m,{open:s,onClose:t,size:"md",children:[e.jsx(u,{icon:S?void 0:e.jsx(K,{className:"w-5 h-5"}),title:S?"Edit Room Server":"Add Room Server",onClose:t}),e.jsx(x,{children:e.jsxs("div",{className:"space-y-5",children:[S&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(p,{color:l.registered?"green":"red",children:l.registered?"Active":"Inactive"}),l.identity_key&&e.jsxs("span",{className:"type-data-xs text-fg-muted truncate",title:l.identity_key,children:["Key: ",l.identity_key.slice(0,16),"…"]})]}),e.jsxs(ue,{children:[e.jsx(xe,{title:"What people see on the mesh",children:"Room Name"}),e.jsx(h,{value:T,onChange:e=>R(e.target.value),placeholder:"Room Name"})]}),!S&&e.jsxs(ue,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(xe,{title:"The unique hex public ID",children:["Identity Key ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx("button",{type:"button",onClick:()=>L(e=>!e),className:"type-data-xs text-fg-muted underline hover:text-fg-secondary",children:E?"Hide":"Show"})]}),E&&e.jsxs(e.Fragment,{children:[e.jsx(h,{value:A,onChange:e=>D(e.target.value),placeholder:"Leave empty to auto-generate"}),e.jsx(pe,{children:"Leave empty to automatically generate a secure key"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(z,{className:"inline w-3.5 h-3.5 -mt-0.5 mr-1 text-fg-muted"}),"Latitude"]}),e.jsx(h,{type:"number",step:"any",value:O,onChange:e=>B(e.target.value),placeholder:"0"})]}),e.jsxs(ue,{children:[e.jsxs(xe,{children:[e.jsx(z,{className:"inline w-3.5 h-3.5 -mt-0.5 mr-1 text-fg-muted"}),"Longitude"]}),e.jsx(h,{type:"number",step:"any",value:G,onChange:e=>V(e.target.value),placeholder:"0"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs(ue,{children:[e.jsxs(xe,{title:"Full access to room server",children:["Admin Password ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx(h,{type:"password",value:$,onChange:e=>F(e.target.value),placeholder:"None Set"})]}),e.jsxs(ue,{children:[e.jsxs(xe,{title:"Can post and read, but not administer the room",children:["Guest Password ",e.jsx("span",{className:"text-fg-muted font-normal",children:"(Optional)"})]}),e.jsx(h,{type:"password",value:I,onChange:e=>P(e.target.value),placeholder:"None Set"})]})]}),Q&&e.jsx("p",{className:"type-data-xs text-sys-red",children:Q})]})}),e.jsxs(g,{children:[S&&e.jsxs("div",{className:"flex items-center gap-2 mr-auto",children:[e.jsxs(v,{color:"danger",plain:!0,onClick:le,disabled:W,children:[e.jsx(U,{"data-slot":"icon"}),W?"Deleting…":"Delete"]}),e.jsxs(v,{color:"primary",plain:!0,onClick:ie,disabled:X,children:[e.jsx(q,{"data-slot":"icon"}),X?"Sending…":"Send Advert"]})]}),e.jsx(v,{plain:!0,onClick:t,children:"Cancel"}),e.jsx(v,{color:"primary",onClick:ne,disabled:H,children:H?"Saving…":S?"Save Changes":"Create"})]})]})}const je=n.createContext(null),ye="room-tui";function be({children:s}){const[t,a]=n.useState(()=>"0"!==localStorage.getItem(ye)),l=n.useCallback(()=>{a(e=>{const s=!e;return localStorage.setItem(ye,s?"1":"0"),s})},[]);return e.jsx(je.Provider,{value:{terminalMode:t,toggleTerminalMode:l},children:s})}function Ne(){const e=n.useContext(je);if(!e)throw new Error("useTerminalMode must be used within RoomTerminalProvider");return e}const ke=e=>"server"===e.author_pubkey||"system"===e.author_pubkey;function we({messages:s,onDelete:t,terminalMode:a,serverName:l}){const i=n.useRef(null),[r,o]=n.useState(!1),d=n.useMemo(()=>[...s].sort((e,s)=>e.post_timestamp-s.post_timestamp),[s]);n.useEffect(()=>{!r&&i.current&&(i.current.scrollTop=0)},[d.length,r]);const c=n.useCallback(()=>{i.current&&o(i.current.scrollTop<-100)},[]),m=n.useCallback(()=>{i.current&&i.current.scrollTo({top:0,behavior:"smooth"}),o(!1)},[]);return 0===d.length?e.jsx("div",{className:"flex-1 flex flex-col items-center justify-center py-12 min-h-0"+(a?" font-mono":""),children:a?e.jsx("p",{className:"text-sm font-mono",style:{color:"var(--tui-accent)",opacity:.4},children:"> no messages in buffer_"}):e.jsxs(e.Fragment,{children:[e.jsx(F,{className:"w-10 h-10 text-fg-muted opacity-20 mb-2"}),e.jsx("p",{className:"type-data-sm text-fg-muted",children:"No messages yet"})]})}):a?e.jsxs("div",{className:"relative flex-1 min-h-0",children:[e.jsx("div",{ref:i,onScroll:c,className:"h-full overflow-y-auto scroll-smooth p-4 font-mono text-sm leading-relaxed flex flex-col-reverse",children:e.jsx("div",{children:d.map(s=>{const a=ke(s),n=new Date(1e3*s.post_timestamp).toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),i=a?"SYS":s.author_name||s.author_prefix,r=!a&&l&&i===l;return e.jsxs("div",{className:"group flex items-start gap-0 -mx-4 px-4 py-px",style:{"--tw-hover-bg":"var(--tui-hover-bg)"},onMouseEnter:e=>e.currentTarget.style.background="var(--tui-hover-bg)",onMouseLeave:e=>e.currentTarget.style.background="",children:[e.jsxs("span",{className:"select-none shrink-0",style:{color:"var(--tui-muted)"},children:["[",n,"]"]}),e.jsxs("span",{className:"mx-1.5 shrink-0",style:{color:r?"var(--tui-accent-local)":"var(--tui-accent)"},children:["<",i,">"]}),e.jsx("span",{style:{color:a?"var(--tui-system)":r?"var(--tui-body)":"var(--tui-accent)"},className:a?"italic":"",children:s.message_text}),e.jsx("button",{onClick:()=>t(s.id),className:"opacity-0 group-hover:opacity-100 ml-auto pl-2 shrink-0 transition-colors",style:{color:"var(--tui-muted)"},onMouseEnter:e=>e.currentTarget.style.color="var(--tui-danger)",onMouseLeave:e=>e.currentTarget.style.color="var(--tui-muted)",title:"Delete",children:"×"})]},s.id)})})}),r&&e.jsxs("button",{onClick:m,className:"absolute bottom-3 left-1/2 -translate-x-1/2 flex items-center gap-1.5 px-3 py-1 font-mono text-xs transition-colors duration-150",style:{background:"var(--tui-hover-bg)",border:"1px solid var(--tui-muted)",color:"var(--tui-accent)"},children:[e.jsx(B,{className:"w-3 h-3"}),"↓ scroll"]})]}):e.jsxs("div",{className:"relative flex-1 min-h-0",children:[e.jsx("div",{ref:i,onScroll:c,className:"h-full overflow-y-auto scroll-smooth flex flex-col-reverse",children:e.jsx("div",{className:"space-y-3 p-4",children:d.map(s=>ke(s)?e.jsx(re,{text:s.message_text},s.id):e.jsx(oe,{senderName:s.author_name||s.author_prefix,text:s.message_text,timestamp:s.post_timestamp,bubbleAccessory:e.jsx("button",{onClick:()=>t(s.id),className:"opacity-0 group-hover:opacity-100 transition-opacity duration-150 p-1 text-fg-muted hover:text-sys-red flex-shrink-0",title:"Delete message",children:e.jsx(U,{className:"w-3.5 h-3.5"})})},s.id))})}),r&&e.jsxs("button",{onClick:m,className:"absolute bottom-3 left-1/2 -translate-x-1/2 flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-surface/90 backdrop-blur-sm ring-1 ring-edge-subtle shadow-md text-fg-secondary hover:text-fg-primary transition-colors duration-150",children:[e.jsx(B,{className:"w-3.5 h-3.5"}),e.jsx("span",{className:"type-data-xs",children:"New messages"})]})]})}function Ce({roomName:s,onSend:t,disabled:a,terminalMode:l}){const[i,r]=n.useState(""),[o,d]=n.useState(!1),c=n.useRef(null),m=n.useCallback(async()=>{var e;const s=i.trim();if(!s||o)return;d(!0);const a=await t(s);d(!1),a&&(r(""),null==(e=c.current)||e.focus())},[i,o,t]),u=n.useCallback(e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),m())},[m]);return l?e.jsxs("div",{className:"flex items-center gap-0 px-4 py-2 type-data-sm",children:[e.jsx("input",{ref:c,type:"text",value:i,onChange:e=>r(e.target.value),onKeyDown:u,placeholder:"type message...",disabled:a||o,className:"flex-1 bg-transparent outline-none ring-0 shadow-none border-none focus:outline-none focus:ring-0 font-mono tui-input",style:{color:"var(--tui-body)"}}),e.jsx("button",{onClick:m,disabled:!i.trim()||o||a,className:"transition-colors duration-100 px-1 font-mono text-xs disabled:opacity-30",style:{color:"var(--tui-accent)"},title:"Send",children:"[↵]"})]}):e.jsxs("div",{className:"flex items-center gap-2 p-3 border-t border-edge-subtle",children:[e.jsx("input",{ref:c,type:"text",value:i,onChange:e=>r(e.target.value),onKeyDown:u,placeholder:`Message ${s}…`,disabled:a||o,className:"flex-1 surface-input radius-inner px-3 py-2 type-body-sm text-fg-primary placeholder:text-fg-muted outline-none ring-focus"}),e.jsx("button",{onClick:m,disabled:!i.trim()||o||a,className:"p-2 rounded-lg text-sys-blue hover:bg-sys-blue/10 disabled:opacity-30 disabled:hover:bg-transparent transition-colors duration-150",title:"Send message",children:e.jsx(q,{className:"w-4.5 h-4.5"})})]})}function _e({selectedName:s,selectedIdentity:t,messages:a,onSend:i,onDelete:r,onClear:o}){var d;const{terminalMode:c,toggleTerminalMode:m}=Ne(),[u,x]=n.useState(!1),p=(null==(d=null==t?void 0:t.settings)?void 0:d.node_name)??s??void 0,h=n.useCallback(()=>{x(!1),o()},[o]);return c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-col h-full gap-1.5",children:[e.jsxs("div",{className:"card-terminal-header flex-shrink-0",children:[e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:"chat",minChars:7,size:24})}),e.jsx("div",{className:"card-terminal-ridge flex-1"}),e.jsxs("div",{className:"header-well",children:[e.jsx(le,{icon:e.jsx(G,{className:"!w-5.5 !h-5.5 translate-y-px"}),onClick:m,title:"Exit terminal mode"}),a.length>0&&e.jsx(le,{icon:e.jsx("span",{className:"text-[13px] font-bold font-mono leading-none translate-y-px",children:"DEL"}),onClick:()=>x(!0),title:"Clear all messages",variant:"red",iconActiveColor:f.red})]})]}),e.jsx(l,{noPadding:!0,className:"flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",children:e.jsxs("div",{className:"card-terminal-well flex-1 min-h-0 flex flex-col overflow-hidden",children:[e.jsx(we,{messages:a,onDelete:r,terminalMode:!0,serverName:p}),e.jsx("div",{className:"card-terminal-divider"}),s&&e.jsx(Ce,{roomName:s,onSend:i,disabled:!(null==t?void 0:t.registered),terminalMode:!0})]})})]}),e.jsx(ie,{isOpen:u,title:"Clear All Messages",message:`This will permanently delete all ${a.length} message${1===a.length?"":"s"} from this room. This cannot be undone.`,confirmLabel:"Clear Messages",variant:"danger",onConfirm:h,onCancel:()=>x(!1)})]}):e.jsxs(e.Fragment,{children:[e.jsxs(l,{noPadding:!0,className:"flex flex-col h-full overflow-hidden",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(V,{className:"icon-sm"}),title:"Messages",actions:e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(v,{plain:!0,onClick:m,title:"Terminal mode",children:e.jsx(G,{"data-slot":"icon",className:"!w-5 !h-5 translate-y-px"})}),a.length>0&&e.jsx(v,{plain:!0,onClick:()=>x(!0),title:"Clear all messages",children:e.jsx("span",{"data-slot":"icon",className:"text-[12px] font-bold font-mono leading-none translate-y-px text-sys-red",children:"DEL"})})]})}),e.jsx(we,{messages:a,onDelete:r,terminalMode:!1,serverName:p}),s&&e.jsx(Ce,{roomName:s,onSend:i,disabled:!(null==t?void 0:t.registered),terminalMode:!1})]}),e.jsx(ie,{isOpen:u,title:"Clear All Messages",message:`This will permanently delete all ${a.length} message${1===a.length?"":"s"} from this room. This cannot be undone.`,confirmLabel:"Clear Messages",variant:"danger",onConfirm:h,onCancel:()=>x(!1)})]})}function Se({pubkey:s,className:t}){const[a,l]=n.useState(!1),i=n.useCallback(()=>{navigator.clipboard.writeText(s),l(!0),setTimeout(()=>l(!1),1500)},[s]);return e.jsxs("button",{onClick:i,title:a?"Copied!":"Copy public key",className:`inline-flex items-center gap-1 type-data-xs leading-tight text-fg-muted hover:text-fg-secondary transition-colors duration-150 cursor-copy ${t??""}`,children:[e.jsx("span",{className:"truncate min-w-0",children:s.slice(0,8)}),a&&e.jsx(Y,{className:"w-2.5 h-2.5 text-sys-green flex-shrink-0"})]})}const Me=n.memo(function({client:s,resolvedName:t,onRemove:a}){const n=s.name||t,l=0===s.unsynced_count,i=s.last_activity?new Date(1e3*s.last_activity).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"Never",{emoji:r,cleanName:o}=n?de(n):{emoji:null,cleanName:s.pubkey_prefix},d=n?ce(o):void 0,c=n?me(n):s.pubkey_prefix.slice(0,2).toUpperCase();return e.jsxs("div",{className:"group flex items-center gap-3 px-3 py-2.5 radius-inner row-hover transition-base",children:[e.jsxs("div",{className:"relative flex-shrink-0",children:[e.jsx("div",{className:$("w-8 h-8 rounded-full flex items-center justify-center",!d&&"bg-sys-blue/12"),style:d?{backgroundColor:d}:void 0,children:r?e.jsx("span",{className:"text-base leading-none",children:r}):e.jsx("span",{className:$("leading-none",d?"text-white text-[11px] font-bold tracking-tight":"text-sys-blue font-mono text-[11px]"),children:c})}),e.jsx("span",{className:"absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-sm ring-2 ring-surface "+(l?"bg-sys-green":"bg-sys-indigo")})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[n?e.jsx("p",{className:"text-[13px] font-medium leading-tight text-fg-primary truncate",children:n}):e.jsx("p",{className:"font-mono text-[13px] leading-tight text-fg-primary truncate",children:s.pubkey_prefix}),e.jsxs("div",{className:"flex items-center gap-1.5 mt-0.5",children:[n&&e.jsx(Se,{pubkey:s.pubkey}),n&&e.jsx("span",{className:"text-xs text-fg-muted/40",children:"·"}),e.jsxs("span",{className:"text-xs leading-tight text-fg-muted truncate",children:[!l&&e.jsxs("span",{className:"text-sys-indigo",children:[s.unsynced_count," unsynced · "]}),i]})]})]}),e.jsx("button",{onClick:()=>a(s.pubkey),className:"opacity-0 group-hover:opacity-100 transition-opacity duration-150 p-1.5 -mr-1 rounded-md text-fg-muted hover:text-sys-red hover:bg-sys-red/8",title:"Remove client",children:e.jsx(H,{className:"w-3.5 h-3.5"})})]})});function Te({clients:s,onRemove:t,messages:a,terminalMode:l}){const i=n.useMemo(()=>{const e=new Map;if(!a)return e;for(let s=a.length-1;s>=0;s--){const t=a[s];t.author_name&&t.author_pubkey&&"server"!==t.author_pubkey&&"system"!==t.author_pubkey&&e.set(t.author_pubkey,t.author_name)}return e},[a]);return 0===s.length?l?e.jsx("p",{className:"type-data-sm text-left px-4 py-4",style:{color:"var(--tui-accent)"},children:"< NO CLIENTS CONNECTED >"}):e.jsx("p",{className:"type-data-xs text-fg-muted text-center py-4",children:"No clients connected"}):l?e.jsx("div",{className:"type-data-sm pt-2",children:s.map(s=>{const a=s.name||i.get(s.pubkey),n=0===s.unsynced_count,l=s.pubkey_prefix;return e.jsxs("div",{className:"group flex items-center gap-0 -mx-0 px-4 py-0.5",onMouseEnter:e=>e.currentTarget.style.background="var(--tui-hover-bg)",onMouseLeave:e=>e.currentTarget.style.background="",children:[e.jsx("span",{style:{color:n?"var(--tui-accent)":"var(--tui-warn)"},children:"■"}),e.jsx("span",{className:"ml-2 shrink-0",style:{color:"var(--tui-accent)"},children:a||l}),a&&e.jsxs("span",{className:"ml-1.5 shrink-0",style:{color:"var(--tui-accent)"},children:["[",l,"]"]}),!n&&e.jsxs("span",{className:"ml-1.5",style:{color:"var(--tui-warn)"},children:[s.unsynced_count,"unsync"]}),e.jsx("button",{onClick:()=>t(s.pubkey),className:"opacity-0 group-hover:opacity-100 ml-auto pl-2 shrink-0 transition-colors",style:{color:"var(--tui-muted)"},onMouseEnter:e=>e.currentTarget.style.color="var(--tui-danger)",onMouseLeave:e=>e.currentTarget.style.color="var(--tui-muted)",title:"Remove",children:"×"})]},s.pubkey)})}):e.jsx("div",{className:"space-y-0.5 pt-1",children:s.map(s=>e.jsx(Me,{client:s,resolvedName:i.get(s.pubkey),onRemove:t},s.pubkey))})}function Re({name:s,onSend:t}){const{terminalMode:a}=Ne(),[l,i]=n.useState("idle"),r=n.useRef(),o=n.useCallback(async()=>{if("sending"===l)return;i("sending");const e=await t(s);i(e?"sent":"idle"),e&&(r.current=setTimeout(()=>i("idle"),2e3))},[s,t,l]);return n.useEffect(()=>()=>clearTimeout(r.current),[]),a?e.jsxs("button",{className:"btn-terminal",onClick:o,disabled:"sending"===l,children:["idle"===l&&"[ send_advert ]","sending"===l&&"[ broadcasting... ]","sent"===l&&"[ sent ✓ ]"]}):e.jsxs(v,{color:"sent"===l?"success":"primary",className:"w-full",onClick:o,disabled:"sending"===l,children:[e.jsx(W,{"data-slot":"icon"}),"idle"===l&&"Send Advert","sending"===l&&"Broadcasting…","sent"===l&&"Advert Sent"]})}function Ae({identity:s,onSendAdvert:t}){var a,l,i,r,o,d,c,m,u,x,h,g,v,f,y,b,N,k,w,C,_,S,M,T,R,A,D,E,L,$;const{terminalMode:F}=Ne(),[I,P]=n.useState(!1),O=n.useCallback(()=>{(null==s?void 0:s.identity_key)&&(navigator.clipboard.writeText(s.identity_key),P(!0),setTimeout(()=>P(!1),1500))},[null==s?void 0:s.identity_key]);return F?s?e.jsxs("div",{className:"space-y-1",children:[(null==(a=s.settings)?void 0:a.node_name)&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"node"}),e.jsx("span",{style:{color:"var(--tui-accent)"},children:s.settings.node_name})]}),(s.address||(null==(l=s.runtime)?void 0:l.address))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"addr"}),e.jsx("span",{style:{color:"var(--tui-accent)"},children:s.address||(null==(i=s.runtime)?void 0:i.address)})]}),s.identity_key&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"key"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"truncate max-w-[140px]",style:{color:"var(--tui-accent)"},title:s.identity_key,children:[s.identity_key.slice(0,16),"…"]}),e.jsx("button",{type:"button",onClick:O,className:"text-xs",style:{color:"var(--tui-muted)"},children:I?"[copied ✓]":"[copy]"})]})]}),(null!=(null==(r=s.settings)?void 0:r.latitude)||null!=(null==(o=s.settings)?void 0:o.longitude))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"loc"}),e.jsxs("span",{style:{color:"var(--tui-accent)"},title:`${(null==(d=s.settings)?void 0:d.latitude)??"—"}, ${(null==(c=s.settings)?void 0:c.longitude)??"—"}`,children:[(null==(u=null==(m=s.settings)?void 0:m.latitude)?void 0:u.toFixed(4))??"—",", ",(null==(h=null==(x=s.settings)?void 0:x.longitude)?void 0:h.toFixed(4))??"—"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{style:{color:"var(--tui-muted)"},children:"pass"}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{style:{color:(null==(g=s.settings)?void 0:g.admin_password)?"var(--tui-accent)":"var(--tui-muted)"},children:(null==(v=s.settings)?void 0:v.admin_password)?"[✓ admin]":"[— admin]"}),e.jsx("span",{style:{color:(null==(f=s.settings)?void 0:f.guest_password)?"var(--tui-accent)":"var(--tui-muted)"},children:(null==(y=s.settings)?void 0:y.guest_password)?"[✓ guest]":"[— guest]"})]})]})]}):e.jsx("span",{style:{color:"var(--tui-muted)"},children:"no identity configured"}):e.jsxs("div",{className:"flex-shrink-0 border-t border-edge-subtle",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(Z,{className:"icon-sm"}),title:"Room Info"}),s?e.jsxs("div",{className:"space-y-2 px-4 py-3",children:[(null==(b=s.settings)?void 0:b.node_name)&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Node"}),e.jsx("span",{className:"type-data-sm text-fg-primary",children:s.settings.node_name})]}),(s.address||(null==(N=s.runtime)?void 0:N.address))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Address"}),e.jsx("span",{className:"type-data-sm font-mono text-fg-primary",children:s.address||(null==(k=s.runtime)?void 0:k.address)})]}),s.identity_key&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"type-data-xs text-fg-muted flex items-center gap-1",title:"The unique hex public ID",children:[e.jsx(X,{className:"w-3 h-3"}),"Key"]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("span",{className:"type-data-sm font-mono text-fg-primary truncate max-w-[140px]",title:s.identity_key,children:[s.identity_key.slice(0,16),"…"]}),e.jsx("button",{type:"button",onClick:O,className:"inline-flex items-center gap-0.5",children:e.jsx(p,{color:I?"green":"zinc",children:I?e.jsxs(e.Fragment,{children:[e.jsx(Y,{className:"w-3 h-3"}),"Copied"]}):e.jsxs(e.Fragment,{children:[e.jsx(J,{className:"w-3 h-3"}),"Copy"]})})})]})]}),(null!=(null==(w=s.settings)?void 0:w.latitude)||null!=(null==(C=s.settings)?void 0:C.longitude))&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"type-data-xs text-fg-muted flex items-center gap-1",children:[e.jsx(z,{className:"w-3 h-3"}),"Location"]}),e.jsxs("span",{className:"type-data-sm font-mono text-fg-primary",title:`${(null==(_=s.settings)?void 0:_.latitude)??"—"}, ${(null==(S=s.settings)?void 0:S.longitude)??"—"}`,children:[(null==(T=null==(M=s.settings)?void 0:M.latitude)?void 0:T.toFixed(4))??"—",", ",(null==(A=null==(R=s.settings)?void 0:R.longitude)?void 0:A.toFixed(4))??"—"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Passwords"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(p,{color:(null==(D=s.settings)?void 0:D.admin_password)?"green":"zinc",children:[(null==(E=s.settings)?void 0:E.admin_password)&&e.jsx(Y,{className:"w-3 h-3"}),"Admin"]}),e.jsxs(p,{color:(null==(L=s.settings)?void 0:L.guest_password)?"green":"zinc",children:[(null==($=s.settings)?void 0:$.guest_password)&&e.jsx(Y,{className:"w-3 h-3"}),"Guest"]})]})]}),e.jsx("div",{className:"pt-3",children:e.jsx(Re,{name:s.name,onSend:t})})]}):e.jsx("p",{className:"type-data-xs text-fg-muted text-center py-3",children:"No identity configured"})]})}function De({selectedIdentity:s,clients:t,messages:a,onSendAdvert:i}){const{terminalMode:r}=Ne(),o=n.useCallback(async e=>{y.setState(s=>({clients:s.clients.filter(s=>s.pubkey!==e)})),await b({public_key:e})},[]);return r?e.jsxs("div",{className:"flex flex-col h-full gap-1.5",children:[s&&e.jsx("div",{className:"hidden lg:block",children:e.jsx("div",{className:"card-terminal-header flex-shrink-0",children:e.jsx("div",{className:"header-well flex-1",children:e.jsx(le,{icon:e.jsx(W,{}),onPress:()=>i(s.name),title:"Send room server advert",indicators:[{label:"ADVERTISE",trackPress:!0},{label:"ACTIVE",active:s.registered}]})})})}),e.jsxs("div",{className:"flex flex-col flex-1 min-h-0 gap-1.5",children:[e.jsx("div",{className:"card-terminal-header flex-shrink-0",children:e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:`OnLInE ${String(t.length).padStart(3,"0")}`,size:24})})}),e.jsx(l,{noPadding:!0,className:"!h-auto flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",children:e.jsx("div",{className:"card-terminal-well flex-1 min-h-0 overflow-y-auto",children:e.jsx(Te,{clients:t,onRemove:o,messages:a,terminalMode:!0})})}),e.jsxs("div",{className:"card-terminal-header flex-shrink-0",children:[e.jsx("span",{className:"seven-seg-panel",children:e.jsx(ne,{text:"StAtUS "+((null==s?void 0:s.registered)?"On":"OFF"),size:24})}),s&&e.jsx("div",{className:"lg:hidden flex-1 flex min-w-0",children:e.jsx("div",{className:"header-well flex-1 !flex-shrink",children:e.jsx(le,{icon:e.jsx(W,{}),onPress:()=>i(s.name),title:"Send room server advert",className:"flex-row-reverse",indicators:[{label:"ACTIVE",active:s.registered},{label:"ADVERTISE",trackPress:!0}]})})})]}),e.jsx(l,{noPadding:!0,className:"!h-auto flex-shrink-0 overflow-hidden card-terminal",children:e.jsx("div",{className:"card-terminal-well px-4 py-3 type-data-sm",children:e.jsx(Ae,{identity:s,onSendAdvert:i})})})]})]}):e.jsxs(l,{compact:!0,className:"flex-1 min-h-0 flex flex-col overflow-hidden",children:[e.jsx(j,{listHeader:!0,icon:e.jsx(Q,{className:"icon-sm"}),title:"Clients",actions:t.length>0?e.jsx("span",{className:"type-data-xs text-fg-muted",children:t.length}):void 0}),e.jsx("div",{className:"flex-1 min-h-0 overflow-y-auto",children:e.jsx(Te,{clients:t,onRemove:o,messages:a,terminalMode:!1})}),e.jsx(Ae,{identity:s,onSendAdvert:i})]})}function Ee(){const s=N(),t=k(),a=w(),l=C(),m=_(),u=S(),x=M(),p=T(),h=R(),g=A(),f=(se=n.useMemo(()=>(null==h?void 0:h.neighbors)??{},[null==h?void 0:h.neighbors]),te=g,n.useMemo(()=>{const e=new Map;for(const[t,a]of Object.entries(se)){const s=a.name||a.node_name||null,{type:n}=E(a);e.set(t.toLowerCase(),{name:s,type:n})}const s=new Map;for(let t=te.length-1;t>=0;t--){const e=te[t];if(!e._advertSender)continue;const a=e._advertSender.toLowerCase();if(s.has(a))continue;const n=e._advertName??null,l=null!=e._advertNodeType?L(e._advertNodeType):"companion";s.set(a,{name:n,type:l})}return function(t){const a=t.toLowerCase(),n=e.get(a);if(null==n?void 0:n.name)return n;const l=s.get(a);return(null==l?void 0:l.name)?l:n||l||{name:null,type:"companion"}}},[se,te])),j=n.useMemo(()=>u.map(e=>{if(e.name)return e;const s=f(e.pubkey);return s.name?{...e,name:s.name}:e}),[u,f]),b=n.useMemo(()=>m.map(e=>{if(e.author_name||"server"===e.author_pubkey||"system"===e.author_pubkey)return e;const s=f(e.author_pubkey);return s.name?{...e,author_name:s.name}:e}),[m,f]),{selectRoom:$,postMessage:I,deleteMessage:P,clearMessages:O,createRoom:K,updateRoom:z,deleteRoom:U,sendAdvert:q,markAsRead:B,startActivePolling:G}=y.getState(),[H,Y]=n.useState(!1),[W,Z]=n.useState("create"),[X,J]=n.useState("hybrid");var se,te;n.useEffect(()=>{B()},[t,B]),n.useEffect(()=>G(),[G]);const ae=n.useCallback(async e=>!!t&&I({room_name:t,message:e,author_pubkey:"server"}),[t,I]),ne=n.useCallback((e="hybrid")=>{J(e),Z("create"),Y(!0)},[]),le=n.useCallback(()=>{Z("edit"),Y(!0)},[]),ie=e.jsxs("div",{className:"flex items-center gap-2 sm:gap-4 flex-shrink-0",children:[a&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${a.total_messages} message${1!==a.total_messages?"s":""} in this room`,children:[e.jsx(V,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:a.total_messages})]}),e.jsxs("span",{className:"data-box flex items-center gap-1.5 cursor-default",title:`${a.total_clients} client${1!==a.total_clients?"s":""} connected`,children:[e.jsx(Q,{className:"w-3.5 h-3.5 text-fg-secondary"}),e.jsx("span",{children:a.total_clients})]})]}),e.jsx(ve,{rooms:s,selected:t,onSelect:$,onAdd:()=>ne("hybrid")}),s.length>0&&e.jsx(v,{plain:!0,onClick:le,title:"Manage room server",children:e.jsx(ee,{"data-slot":"icon"})})]});return 0!==s.length||0!==x.length||p?e.jsx(be,{children:e.jsxs(i,{children:[e.jsx(r,{title:"Room Server",icon:e.jsx(F,{}),controls:ie}),e.jsx(o,{children:e.jsxs(d,{template:"hero-tall",className:"!h-[calc(100vh-11rem)] !min-h-[400px]",children:[e.jsx(c,{span:12,lg:8,className:"h-full",children:e.jsx(_e,{selectedName:t,selectedIdentity:l,messages:b,onSend:ae,onDelete:P,onClear:O})}),e.jsx(c,{span:12,lg:4,className:"h-full",children:e.jsx(De,{selectedIdentity:l,clients:j,messages:b,onSendAdvert:q})})]})}),e.jsx(fe,{open:H,onClose:()=>Y(!1),mode:W,identity:l,repeaterConfig:null==h?void 0:h.config,onCreate:K,onUpdate:z,onDelete:U,onSendAdvert:q})]})}):e.jsx(be,{children:e.jsxs(i,{children:[e.jsx(r,{title:"Room Server",icon:e.jsx(F,{})}),e.jsx(ge,{onCreateRoom:e=>ne(e)}),e.jsx(fe,{open:H,onClose:()=>Y(!1),mode:"create",repeaterConfig:null==h?void 0:h.config,onCreate:async e=>{const s=await K(e);return s&&"dedicated"===X&&(await D.getState().setMode("monitor"),D.getState().clearModeMutation()),s},onUpdate:z,onDelete:U,onSendAdvert:q})]})})}export{Ee as default}; diff --git a/frontend/dist/assets/Sessions-C8xhZKXf.js b/frontend/dist/assets/Sessions-DBjQm7_J.js similarity index 98% rename from frontend/dist/assets/Sessions-C8xhZKXf.js rename to frontend/dist/assets/Sessions-DBjQm7_J.js index 76e824b3..f505720f 100644 --- a/frontend/dist/assets/Sessions-C8xhZKXf.js +++ b/frontend/dist/assets/Sessions-DBjQm7_J.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{d9 as t,da as l,bD as i,B as n,bV as d,aW as c}from"./index-D7i6lQrq.js";import{C as r}from"./ConfirmModal-XwU3yUZY.js";import{D as o}from"./DataBox-DpDXI-WX.js";import{P as m,a as x,B as u,C as h}from"./PageLayout-QhCLxU34.js";import{L as p,a as j,aX as y,U as f,bi as b,bj as g,a2 as N,bk as v,bl as w,bm as _,a3 as k,ae as C,b5 as S,j as A,as as L}from"./vendor-icons-TO0PZKGR.js";import{R,C as M}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const D=[{id:"overview",label:"Overview",icon:v},{id:"clients",label:"Authenticated Clients",icon:w},{id:"identities",label:"By Identity",icon:_}];function I(e){return e?new Date(1e3*e).toLocaleString():"Never"}function P(e){if(!e)return"Never";const s=Date.now()-1e3*e,a=Math.floor(s/6e4),t=Math.floor(s/36e5),l=Math.floor(s/864e5);return a<1?"Just now":a<60?`${a}m ago`:t<24?`${t}h ago`:l<365?`${l}d ago`:`${Math.floor(l/365)}y ago`}function F({label:e,value:a,icon:t}){return s.jsxs(h,{neomorphic:!0,children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[t&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:t}),s.jsx("span",{className:"type-micro",children:e})]}),s.jsx(c,{centered:!0,children:s.jsx("span",{className:"type-data-xl text-fg-primary font-mono font-normal tabular-nums",children:a})})]})}function K({identity:e}){const t="repeater"===e.type;return s.jsxs("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4",children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-3",children:[s.jsx("span",{className:"icon-sm text-icon-card-title",children:t?s.jsx(S,{className:"w-4 h-4"}):s.jsx(A,{className:"w-4 h-4"})}),s.jsx("span",{className:"type-micro",children:e.name}),s.jsx(o,{copy:!0,size:"compact",truncate:[8,6],color:"text-fg-muted",children:e.hash}),s.jsx("span",{className:"data-box data-box-compact data-box-outlined ml-auto",style:{"--data-box-accent":t?"var(--sys-blue)":"var(--sys-pink)"},children:e.type})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Max Clients"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",children:e.max_clients})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Authenticated"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",children:e.authenticated_clients})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Admin Password"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",style:{"--data-box-color":e.has_admin_password?"var(--sys-green)":"var(--sys-red)"},children:e.has_admin_password?"✓ Set":"✗ Not Set"})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Guest Password"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",style:{"--data-box-color":e.has_guest_password?"var(--sys-green)":"var(--sys-red)"},children:e.has_guest_password?"✓ Set":"✗ Not Set"})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Read-Only Access"}),s.jsx("div",{className:a("data-box data-box-fill data-box-left",e.allow_read_only?"text-sys-green":"text-sys-red"),children:e.allow_read_only?"Allowed":"Disabled"})]})]})]})}function $({client:e,onRemove:t}){return s.jsx("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4 transition-base hover:bg-subtle-fill-strong",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0 grid grid-cols-1 sm:grid-cols-5 gap-2 sm:gap-4 items-center",children:[s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Client"}),s.jsx("span",{className:"type-data-sm text-fg-primary font-mono truncate block",children:e.public_key})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Address"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-mono truncate block",children:e.address})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Identity"}),s.jsx("span",{className:"type-data-sm text-fg-primary block truncate",children:e.identity_name}),s.jsx("span",{className:"type-data-xs text-fg-muted block truncate",children:e.identity_hash})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Permissions"}),s.jsx("span",{className:a("type-data-xs px-2 py-0.5 rounded-full font-medium inline-block","admin"===e.permissions?"bg-sys-green/15 text-sys-green":"bg-sys-amber/15 text-sys-amber"),children:e.permissions})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Last Activity"}),s.jsx("span",{className:"type-data-xs text-fg-muted",children:P(e.last_activity)})]})]}),s.jsxs(n,{color:"danger",outline:!0,onClick:t,className:"flex-shrink-0",children:[s.jsx(L,{"data-slot":"icon"}),"Remove"]})]})})}function B({client:e,onRemove:t}){return s.jsx("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4 transition-base hover:bg-subtle-fill-strong",children:s.jsxs("div",{className:"flex items-start justify-between gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[s.jsx("span",{className:a("type-data-xs px-2 py-0.5 rounded-full font-medium","admin"===e.permissions?"bg-sys-green/15 text-sys-green":"bg-sys-amber/15 text-sys-amber"),children:e.permissions}),s.jsx("span",{className:"type-data-sm text-fg-primary font-mono truncate",children:e.public_key})]}),s.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 text-sm",children:[s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Address: "}),s.jsx("span",{className:"text-fg-primary/90 font-mono",children:e.address})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Identity: "}),s.jsxs("span",{className:"text-fg-primary/90",children:[e.identity_name," (",e.identity_hash,")"]})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Last Activity: "}),s.jsx("span",{className:"text-fg-primary/90",children:I(e.last_activity)})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Last Login: "}),s.jsx("span",{className:"text-fg-primary/90",children:I(e.last_login_success)})]})]})]}),s.jsx(n,{color:"danger",outline:!0,onClick:t,className:"flex-shrink-0",children:s.jsx(L,{"data-slot":"icon"})})]})})}function G(){const[c,o]=e.useState("overview"),[v,w]=e.useState(!0),[_,S]=e.useState(!1),[A,L]=e.useState("idle"),[I,P]=e.useState(null),[G,E]=e.useState(null),[H,O]=e.useState([]),[T,U]=e.useState(null),[z,J]=e.useState(null),[V,W]=e.useState(null),[X,q]=e.useState(!1),Q=(null==G?void 0:G.acls)??[],Y=e.useMemo(()=>z?H.filter(e=>e.identity_name===z):H,[H,z]),Z=e.useCallback(async()=>{P(null);try{const[e,s,a]=await Promise.all([t(),l(),i()]);e.success&&e.data&&E(e.data),s.success&&s.data&&O(s.data.clients||[]),a.success&&a.data&&U(a.data)}catch(e){P(e instanceof Error?e.message:"Failed to load session data")}},[]);e.useEffect(()=>{Z().finally(()=>w(!1))},[Z]);const ee=async()=>{S(!0),L("loading"),await Z(),S(!1),L("success"),setTimeout(()=>L("idle"),1500)};return s.jsxs(m,{children:[s.jsx(x,{title:"Sessions",icon:s.jsx(f,{}),controls:s.jsxs(n,{color:"success"===A?"success":"primary",outline:!0,onClick:ee,disabled:_,children:["loading"===A?s.jsx(p,{"data-slot":"icon",className:"animate-spin"}):"success"===A?s.jsx(j,{"data-slot":"icon"}):s.jsx(y,{"data-slot":"icon"}),"success"===A?"Done":"Refresh"]}),subtitle:s.jsx("p",{className:"type-body-sm text-fg-muted",children:"Manage authenticated clients and access control lists"})}),s.jsxs(u,{children:[T&&s.jsxs(R,{template:"widget",children:[s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Identities",value:T.total_identities,icon:s.jsx(f,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Authenticated",value:T.total_clients,icon:s.jsx(b,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Admin",value:T.admin_clients,icon:s.jsx(g,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Guest",value:T.guest_clients,icon:s.jsx(N,{className:"w-4 h-4"})})})]}),s.jsx(R,{template:"auto",children:s.jsxs(h,{neomorphic:!0,children:[s.jsx("div",{className:"flex flex-wrap gap-1 mb-5",children:s.jsx("div",{className:"toggle-group",children:D.map(e=>{const t=c===e.id;return s.jsxs("button",{onClick:()=>o(e.id),className:a("toggle-group-item flex items-center gap-1.5",t&&"active"),children:[s.jsx(e.icon,{className:"w-3.5 h-3.5"}),e.label]},e.id)})})}),s.jsx("div",{className:"min-h-[300px]",children:v?s.jsxs("div",{className:"flex items-center justify-center py-12",children:[s.jsx(p,{className:"w-6 h-6 animate-spin text-sys-blue mr-3"}),s.jsx("span",{className:"type-body text-fg-muted",children:"Loading session data..."})]}):I?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-12 h-12 rounded-full bg-sys-red/10 mx-auto mb-3 flex items-center justify-center",children:s.jsx(k,{className:"w-6 h-6 text-sys-red"})}),s.jsx("p",{className:"type-body text-sys-red mb-2",children:"Failed to load session data"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:I}),s.jsx(n,{color:"primary",outline:!0,onClick:ee,children:"Retry"})]}):s.jsxs(s.Fragment,{children:["overview"===c&&s.jsx("div",{className:"space-y-4",children:0===Q.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(g,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No identities configured"})]}):Q.map(e=>s.jsx(K,{identity:e},e.hash))}),"clients"===c&&s.jsxs("div",{className:"space-y-3",children:[H.length>0&&s.jsxs("div",{className:"hidden sm:grid grid-cols-5 gap-4 px-4 pb-2 border-b border-edge-subtle",children:[s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Client"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Address"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Identity"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Permissions"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Last Activity"})]}),0===H.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(f,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No authenticated clients"})]}):H.map(e=>s.jsx($,{client:e,onRemove:()=>W({publicKey:e.public_key_full,identityHash:e.identity_hash,displayKey:e.public_key})},e.public_key_full))]}),"identities"===c&&s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Filter by Identity"}),s.jsxs("select",{value:z??"",onChange:e=>J(e.target.value||null),className:"w-full sm:w-auto bg-subtle-fill border border-edge-subtle radius-inner px-4 py-2 type-data text-fg-primary focus:outline-none focus:border-sys-blue/50 transition-colors",children:[s.jsx("option",{value:"",children:"All Identities"}),Q.map(e=>s.jsxs("option",{value:e.name,children:[e.name," (",e.authenticated_clients," clients)"]},e.name))]})]}),0===Y.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(C,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:z?"No clients for selected identity":"No clients found"})]}):s.jsx("div",{className:"space-y-3",children:Y.map(e=>s.jsx(B,{client:e,onRemove:()=>W({publicKey:e.public_key_full,identityHash:e.identity_hash,displayKey:e.public_key})},e.public_key_full))})]})]})})]})})]}),s.jsx(r,{isOpen:!!V,title:"Remove Client",message:`Are you sure you want to remove client '${null==V?void 0:V.displayKey}' from the ACL? This will disconnect the client.`,confirmLabel:X?"Removing...":"Remove",cancelLabel:"Cancel",variant:"danger",onConfirm:async()=>{if(V){q(!0);try{const e=await d({public_key:V.publicKey,identity_hash:V.identityHash});e.success?await Z():P(`Failed to remove client: ${e.error}`)}catch(e){P(e instanceof Error?e.message:"Failed to remove client")}finally{q(!1),W(null)}}},onCancel:()=>W(null)})]})}export{G as default}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{d9 as t,da as l,bD as i,B as n,bV as d,aW as c}from"./index-CkRTgHHA.js";import{C as r}from"./ConfirmModal-B6Rz8ROW.js";import{D as o}from"./DataBox-DpDXI-WX.js";import{P as m,a as x,B as u,C as h}from"./PageLayout-BWMUVZgC.js";import{L as p,a as j,aX as y,U as f,bi as b,bj as g,a2 as N,bk as v,bl as w,bm as _,a3 as k,ae as C,b5 as S,j as A,as as L}from"./vendor-icons-TO0PZKGR.js";import{R,C as M}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const D=[{id:"overview",label:"Overview",icon:v},{id:"clients",label:"Authenticated Clients",icon:w},{id:"identities",label:"By Identity",icon:_}];function I(e){return e?new Date(1e3*e).toLocaleString():"Never"}function P(e){if(!e)return"Never";const s=Date.now()-1e3*e,a=Math.floor(s/6e4),t=Math.floor(s/36e5),l=Math.floor(s/864e5);return a<1?"Just now":a<60?`${a}m ago`:t<24?`${t}h ago`:l<365?`${l}d ago`:`${Math.floor(l/365)}y ago`}function F({label:e,value:a,icon:t}){return s.jsxs(h,{neomorphic:!0,children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-2 sm:mb-3",children:[t&&s.jsx("span",{className:"icon-sm text-icon-card-title",children:t}),s.jsx("span",{className:"type-micro",children:e})]}),s.jsx(c,{centered:!0,children:s.jsx("span",{className:"type-data-xl text-fg-primary font-mono font-normal tabular-nums",children:a})})]})}function K({identity:e}){const t="repeater"===e.type;return s.jsxs("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4",children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2 mb-3",children:[s.jsx("span",{className:"icon-sm text-icon-card-title",children:t?s.jsx(S,{className:"w-4 h-4"}):s.jsx(A,{className:"w-4 h-4"})}),s.jsx("span",{className:"type-micro",children:e.name}),s.jsx(o,{copy:!0,size:"compact",truncate:[8,6],color:"text-fg-muted",children:e.hash}),s.jsx("span",{className:"data-box data-box-compact data-box-outlined ml-auto",style:{"--data-box-accent":t?"var(--sys-blue)":"var(--sys-pink)"},children:e.type})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Max Clients"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",children:e.max_clients})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Authenticated"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",children:e.authenticated_clients})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Admin Password"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",style:{"--data-box-color":e.has_admin_password?"var(--sys-green)":"var(--sys-red)"},children:e.has_admin_password?"✓ Set":"✗ Not Set"})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Guest Password"}),s.jsx("div",{className:"data-box data-box-fill data-box-left",style:{"--data-box-color":e.has_guest_password?"var(--sys-green)":"var(--sys-red)"},children:e.has_guest_password?"✓ Set":"✗ Not Set"})]}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsx("div",{className:"data-box-label",children:"Read-Only Access"}),s.jsx("div",{className:a("data-box data-box-fill data-box-left",e.allow_read_only?"text-sys-green":"text-sys-red"),children:e.allow_read_only?"Allowed":"Disabled"})]})]})]})}function $({client:e,onRemove:t}){return s.jsx("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4 transition-base hover:bg-subtle-fill-strong",children:s.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0 grid grid-cols-1 sm:grid-cols-5 gap-2 sm:gap-4 items-center",children:[s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Client"}),s.jsx("span",{className:"type-data-sm text-fg-primary font-mono truncate block",children:e.public_key})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Address"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-mono truncate block",children:e.address})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Identity"}),s.jsx("span",{className:"type-data-sm text-fg-primary block truncate",children:e.identity_name}),s.jsx("span",{className:"type-data-xs text-fg-muted block truncate",children:e.identity_hash})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Permissions"}),s.jsx("span",{className:a("type-data-xs px-2 py-0.5 rounded-full font-medium inline-block","admin"===e.permissions?"bg-sys-green/15 text-sys-green":"bg-sys-amber/15 text-sys-amber"),children:e.permissions})]}),s.jsxs("div",{className:"sm:col-span-1",children:[s.jsx("span",{className:"type-data-xs text-fg-muted block sm:hidden mb-0.5",children:"Last Activity"}),s.jsx("span",{className:"type-data-xs text-fg-muted",children:P(e.last_activity)})]})]}),s.jsxs(n,{color:"danger",outline:!0,onClick:t,className:"flex-shrink-0",children:[s.jsx(L,{"data-slot":"icon"}),"Remove"]})]})})}function B({client:e,onRemove:t}){return s.jsx("div",{className:"bg-subtle-fill/80 radius-inner depth-stroke-raised p-4 transition-base hover:bg-subtle-fill-strong",children:s.jsxs("div",{className:"flex items-start justify-between gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[s.jsx("span",{className:a("type-data-xs px-2 py-0.5 rounded-full font-medium","admin"===e.permissions?"bg-sys-green/15 text-sys-green":"bg-sys-amber/15 text-sys-amber"),children:e.permissions}),s.jsx("span",{className:"type-data-sm text-fg-primary font-mono truncate",children:e.public_key})]}),s.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2 text-sm",children:[s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Address: "}),s.jsx("span",{className:"text-fg-primary/90 font-mono",children:e.address})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Identity: "}),s.jsxs("span",{className:"text-fg-primary/90",children:[e.identity_name," (",e.identity_hash,")"]})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Last Activity: "}),s.jsx("span",{className:"text-fg-primary/90",children:I(e.last_activity)})]}),s.jsxs("div",{children:[s.jsx("span",{className:"text-fg-muted",children:"Last Login: "}),s.jsx("span",{className:"text-fg-primary/90",children:I(e.last_login_success)})]})]})]}),s.jsx(n,{color:"danger",outline:!0,onClick:t,className:"flex-shrink-0",children:s.jsx(L,{"data-slot":"icon"})})]})})}function G(){const[c,o]=e.useState("overview"),[v,w]=e.useState(!0),[_,S]=e.useState(!1),[A,L]=e.useState("idle"),[I,P]=e.useState(null),[G,E]=e.useState(null),[H,O]=e.useState([]),[T,U]=e.useState(null),[z,J]=e.useState(null),[V,W]=e.useState(null),[X,q]=e.useState(!1),Q=(null==G?void 0:G.acls)??[],Y=e.useMemo(()=>z?H.filter(e=>e.identity_name===z):H,[H,z]),Z=e.useCallback(async()=>{P(null);try{const[e,s,a]=await Promise.all([t(),l(),i()]);e.success&&e.data&&E(e.data),s.success&&s.data&&O(s.data.clients||[]),a.success&&a.data&&U(a.data)}catch(e){P(e instanceof Error?e.message:"Failed to load session data")}},[]);e.useEffect(()=>{Z().finally(()=>w(!1))},[Z]);const ee=async()=>{S(!0),L("loading"),await Z(),S(!1),L("success"),setTimeout(()=>L("idle"),1500)};return s.jsxs(m,{children:[s.jsx(x,{title:"Sessions",icon:s.jsx(f,{}),controls:s.jsxs(n,{color:"success"===A?"success":"primary",outline:!0,onClick:ee,disabled:_,children:["loading"===A?s.jsx(p,{"data-slot":"icon",className:"animate-spin"}):"success"===A?s.jsx(j,{"data-slot":"icon"}):s.jsx(y,{"data-slot":"icon"}),"success"===A?"Done":"Refresh"]}),subtitle:s.jsx("p",{className:"type-body-sm text-fg-muted",children:"Manage authenticated clients and access control lists"})}),s.jsxs(u,{children:[T&&s.jsxs(R,{template:"widget",children:[s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Identities",value:T.total_identities,icon:s.jsx(f,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Authenticated",value:T.total_clients,icon:s.jsx(b,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Admin",value:T.admin_clients,icon:s.jsx(g,{className:"w-4 h-4"})})}),s.jsx(M,{span:6,md:3,children:s.jsx(F,{label:"Guest",value:T.guest_clients,icon:s.jsx(N,{className:"w-4 h-4"})})})]}),s.jsx(R,{template:"auto",children:s.jsxs(h,{neomorphic:!0,children:[s.jsx("div",{className:"flex flex-wrap gap-1 mb-5",children:s.jsx("div",{className:"toggle-group",children:D.map(e=>{const t=c===e.id;return s.jsxs("button",{onClick:()=>o(e.id),className:a("toggle-group-item flex items-center gap-1.5",t&&"active"),children:[s.jsx(e.icon,{className:"w-3.5 h-3.5"}),e.label]},e.id)})})}),s.jsx("div",{className:"min-h-[300px]",children:v?s.jsxs("div",{className:"flex items-center justify-center py-12",children:[s.jsx(p,{className:"w-6 h-6 animate-spin text-sys-blue mr-3"}),s.jsx("span",{className:"type-body text-fg-muted",children:"Loading session data..."})]}):I?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-12 h-12 rounded-full bg-sys-red/10 mx-auto mb-3 flex items-center justify-center",children:s.jsx(k,{className:"w-6 h-6 text-sys-red"})}),s.jsx("p",{className:"type-body text-sys-red mb-2",children:"Failed to load session data"}),s.jsx("p",{className:"type-body-sm text-fg-muted mb-4",children:I}),s.jsx(n,{color:"primary",outline:!0,onClick:ee,children:"Retry"})]}):s.jsxs(s.Fragment,{children:["overview"===c&&s.jsx("div",{className:"space-y-4",children:0===Q.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(g,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No identities configured"})]}):Q.map(e=>s.jsx(K,{identity:e},e.hash))}),"clients"===c&&s.jsxs("div",{className:"space-y-3",children:[H.length>0&&s.jsxs("div",{className:"hidden sm:grid grid-cols-5 gap-4 px-4 pb-2 border-b border-edge-subtle",children:[s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Client"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Address"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Identity"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Permissions"}),s.jsx("span",{className:"type-data-xs text-fg-muted font-medium",children:"Last Activity"})]}),0===H.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(f,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:"No authenticated clients"})]}):H.map(e=>s.jsx($,{client:e,onRemove:()=>W({publicKey:e.public_key_full,identityHash:e.identity_hash,displayKey:e.public_key})},e.public_key_full))]}),"identities"===c&&s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"type-label text-fg-muted block mb-2",children:"Filter by Identity"}),s.jsxs("select",{value:z??"",onChange:e=>J(e.target.value||null),className:"w-full sm:w-auto bg-subtle-fill border border-edge-subtle radius-inner px-4 py-2 type-data text-fg-primary focus:outline-none focus:border-sys-blue/50 transition-colors",children:[s.jsx("option",{value:"",children:"All Identities"}),Q.map(e=>s.jsxs("option",{value:e.name,children:[e.name," (",e.authenticated_clients," clients)"]},e.name))]})]}),0===Y.length?s.jsxs("div",{className:"text-center py-12",children:[s.jsx("div",{className:"w-14 h-14 rounded-full bg-subtle-fill mx-auto mb-4 flex items-center justify-center",children:s.jsx(C,{className:"w-7 h-7 text-fg-muted/50"})}),s.jsx("p",{className:"type-body text-fg-muted",children:z?"No clients for selected identity":"No clients found"})]}):s.jsx("div",{className:"space-y-3",children:Y.map(e=>s.jsx(B,{client:e,onRemove:()=>W({publicKey:e.public_key_full,identityHash:e.identity_hash,displayKey:e.public_key})},e.public_key_full))})]})]})})]})})]}),s.jsx(r,{isOpen:!!V,title:"Remove Client",message:`Are you sure you want to remove client '${null==V?void 0:V.displayKey}' from the ACL? This will disconnect the client.`,confirmLabel:X?"Removing...":"Remove",cancelLabel:"Cancel",variant:"danger",onConfirm:async()=>{if(V){q(!0);try{const e=await d({public_key:V.publicKey,identity_hash:V.identityHash});e.success?await Z():P(`Failed to remove client: ${e.error}`)}catch(e){P(e instanceof Error?e.message:"Failed to remove client")}finally{q(!1),W(null)}}},onCancel:()=>W(null)})]})}export{G as default}; diff --git a/frontend/dist/assets/SignalIndicator-fAt1Aewy.js b/frontend/dist/assets/SignalIndicator-Bdj3-1hL.js similarity index 98% rename from frontend/dist/assets/SignalIndicator-fAt1Aewy.js rename to frontend/dist/assets/SignalIndicator-Bdj3-1hL.js index 26293414..6a45a8cf 100644 --- a/frontend/dist/assets/SignalIndicator-fAt1Aewy.js +++ b/frontend/dist/assets/SignalIndicator-Bdj3-1hL.js @@ -1 +1 @@ -import{r as e,j as r}from"./vendor-react-alRNW2nb.js";import{c as a}from"./vendor-core-FtpmsTnh.js";import{aE as t,aF as s,aG as n}from"./index-D7i6lQrq.js";import{ax as o,ay as c,az as i,aA as l,ab as d}from"./vendor-icons-TO0PZKGR.js";const x={excellent:"color(display-p3 0.00 1.00 0.00)",good:"color(display-p3 0.55 0.90 0.15)",fair:"color(display-p3 1.00 0.85 0.00)",weak:"color(display-p3 1.00 0.55 0.15)",poor:"color(display-p3 1.00 0.20 0.20)"},p={excellent:"#4ADE80",good:"#A3E635",fair:"#FACC15",weak:"#FB923C",poor:"#EF4444"};function u(e){return e>=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"weak":"poor"}function f(e,r,a=!0){return r?a?{backgroundColor:p[e],"--p3-color":x[e]}:{backgroundColor:"rgba(255, 255, 255, 0.25)"}:{backgroundColor:"rgba(255, 255, 255, 0.1)"}}function g(e,r=!0){return e&&r?"signal-bar-active":""}function m({rssi:e,className:t="w-4 h-4"}){const s=u(e),n=function(e){switch(e){case"excellent":return"text-signal-excellent";case"good":return"text-signal-good";case"fair":return"text-signal-fair";case"weak":return"text-signal-poor";case"poor":return"text-signal-critical";default:return"text-fg-muted"}}(s),x=a(n,t);switch(s){case"excellent":return r.jsx(d,{className:x});case"good":return r.jsx(l,{className:x});case"fair":return r.jsx(i,{className:x});case"weak":return r.jsx(c,{className:x});default:return r.jsx(o,{className:x})}}const h=e.memo(function({rssi:e,snr:t,compact:s=!1,showValues:o=!0,radioConfig:c,nfPenalty:i=0,validated:l=!0}){const d=void 0!==t?function(e,r,a,t=0){const s=n(r,e,a,t);return s?function(e){switch(e){case"excellent":return"excellent";case"good":return"good";case"fair":return"fair";case"poor":return"weak";case"critical":return"poor"}}(s.finalGrade):u(e)}(e,t,c,i):u(e),x={excellent:4,good:3,fair:2,weak:1,poor:0}[d];return s?r.jsxs("div",{className:"flex items-center gap-1.5",children:[o&&r.jsx("span",{className:a("type-data-xs w-[32px] text-left",l?"text-fg-secondary":"text-fg-muted"),children:e}),r.jsx("div",{className:"flex items-center gap-[2px] h-3 w-[14px]",children:Array.from({length:4}).map((e,t)=>r.jsx("div",{className:a("w-[3px] h-full rounded-[1px] transition-colors",g(tr.jsx("div",{className:a("w-[3px] h-full rounded-[1px] transition-colors",g(t=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"weak":"poor"}function f(e,r,a=!0){return r?a?{backgroundColor:p[e],"--p3-color":x[e]}:{backgroundColor:"rgba(255, 255, 255, 0.25)"}:{backgroundColor:"rgba(255, 255, 255, 0.1)"}}function g(e,r=!0){return e&&r?"signal-bar-active":""}function m({rssi:e,className:t="w-4 h-4"}){const s=u(e),n=function(e){switch(e){case"excellent":return"text-signal-excellent";case"good":return"text-signal-good";case"fair":return"text-signal-fair";case"weak":return"text-signal-poor";case"poor":return"text-signal-critical";default:return"text-fg-muted"}}(s),x=a(n,t);switch(s){case"excellent":return r.jsx(d,{className:x});case"good":return r.jsx(l,{className:x});case"fair":return r.jsx(i,{className:x});case"weak":return r.jsx(c,{className:x});default:return r.jsx(o,{className:x})}}const h=e.memo(function({rssi:e,snr:t,compact:s=!1,showValues:o=!0,radioConfig:c,nfPenalty:i=0,validated:l=!0}){const d=void 0!==t?function(e,r,a,t=0){const s=n(r,e,a,t);return s?function(e){switch(e){case"excellent":return"excellent";case"good":return"good";case"fair":return"fair";case"poor":return"weak";case"critical":return"poor"}}(s.finalGrade):u(e)}(e,t,c,i):u(e),x={excellent:4,good:3,fair:2,weak:1,poor:0}[d];return s?r.jsxs("div",{className:"flex items-center gap-1.5",children:[o&&r.jsx("span",{className:a("type-data-xs w-[32px] text-left",l?"text-fg-secondary":"text-fg-muted"),children:e}),r.jsx("div",{className:"flex items-center gap-[2px] h-3 w-[14px]",children:Array.from({length:4}).map((e,t)=>r.jsx("div",{className:a("w-[3px] h-full rounded-[1px] transition-colors",g(tr.jsx("div",{className:a("w-[3px] h-full rounded-[1px] transition-colors",g(t((t,s,a)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[s]=a)(t,"symbol"!=typeof s?s+"":s,a);import{r as s,j as a}from"./vendor-react-alRNW2nb.js";import{c as n,a3 as l,aH as i,aI as r,aJ as o,aK as c,h as d,aL as m,aM as u,u as h,aN as x,aO as p,aP as g,aQ as f,aR as b,ag as y,aS as j,ai as v,aT as N,aU as w,q as k,aV as M,aW as S,p as C,t as T,r as A,m as F,a0 as P,a1 as L,v as R,W as $,aX as D,aY as _,aZ as z,a_ as E}from"./index-D7i6lQrq.js";import{c as H}from"./vendor-core-FtpmsTnh.js";import{a4 as B,aB as O,u as W,aC as q,aD as I,aE as G,aF as V,aG as Y,H as K,I as X,a3 as U,aH as J,a7 as Q,g as Z,ak as ee,R as te}from"./vendor-icons-TO0PZKGR.js";import{u as se,h as ae,r as ne}from"./consumer-registry-KuOoZhsq.js";import{e as le}from"./easing-GXZYrvDD.js";import{T as ie}from"./TimeRangeStepper-B5GfHny9.js";import{C as re,P as oe,a as ce,B as de}from"./PageLayout-QhCLxU34.js";import{D as me}from"./DataBox-DpDXI-WX.js";import{A as ue}from"./AnimatedNumber-Dx2y1t97.js";import{C as he}from"./CollisionExplorerModal-B2vZL8RO.js";import{L as xe}from"./LightSparkline-BAD3v4m9.js";import{c as pe,a as ge,A as fe}from"./AnalyzerFilterPanel-DfkXd7UH.js";import{a as be}from"./usePipelineStore-D3dOwDkO.js";import{R as ye,C as je}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./maplibre-gl-BwLPRSIs.js";import"./BasemapLayer-CSqjQAiA.js";import"./node-types-CiI69Tya.js";import"./geo-utils-DJn8DnxF.js";const ve={useAbsoluteThresholds:!0,baselinePercentile:6,spikePercentile:50,baselineDbm:-107,spikeDbm:-100,mergeGapSeconds:45,minSequenceLength:16,similarityToleranceDbm:5};function Ne(e,t){if(0===e.length)return 0;const s=t/100*(e.length-1),a=Math.floor(s),n=Math.ceil(s);return a===n?e[a]:e[a]+(e[n]-e[a])*(s-a)}function we(e){if(0===e.length)return{median:0,p90:0,p95:0,p99:0,max:0,min:0};const t=[...e].sort((e,t)=>e-t);return{median:Ne(t,50),p90:Ne(t,90),p95:Ne(t,95),p99:Ne(t,99),max:t[t.length-1],min:t[0]}}function ke(e,t,s){const a=s-t;if(0===a)return"moderate";const n=(e-t)/a;return n>.66?"critical":n>.33?"severe":"moderate"}const Me=Object.entries(l).map(([e,t])=>{const s=parseInt(e,10);return{typeNum:s,key:`TYPE_${s}`,label:t}});function Se({sortedTypes:e,highlightedType:t,onTypeHover:l,aggregateShares:i,hoverData:r}){const o=s.useMemo(()=>{if(!r)return null;const e=new Map;for(const t of r.items)e.set(t.key,t.value);return e},[r]),c=null!==o,d=s.useMemo(()=>{const t=new Set(e.map(e=>e.key));return[...e.map(e=>({typeNum:e.typeNum,key:e.key,label:e.label})),...Me.filter(e=>!t.has(e.key))]},[e]);return a.jsxs("div",{className:"flex-shrink-0 pt-2 sm:pt-3 mt-1 sm:mt-2 px-0 sm:pr-0",children:[a.jsxs("div",{className:"flex items-center gap-2 mx-0 sm:ml-9 sm:mr-0 mb-1 sm:mb-1.5 type-data-xs",children:[a.jsx("span",{className:"text-fg-muted",children:"Packet Types"}),c&&(null==r?void 0:r.timeLabel)&&a.jsx("span",{className:"text-sys-indigo tabular-nums",children:r.timeLabel})]}),a.jsx("div",{className:"flex flex-wrap gap-x-3 sm:gap-x-4 gap-y-1 type-data-xs mx-0 sm:ml-9 sm:mr-0",onMouseLeave:()=>l(null),children:d.map(e=>{const s=n(e.typeNum),r=(null==o?void 0:o.get(e.key))??0,d=i.get(e.key)??0,m=c?r:d,u=m>1e-4,h=i.has(e.key),x=t===e.key,p=t&&!x||c&&r<=1e-4||!c&&!t&&!h;return a.jsxs("div",{className:H("flex items-center gap-1.5 transition-opacity cursor-pointer hover:opacity-80",p&&"opacity-30"),onMouseEnter:()=>l(e.key),children:[a.jsx("div",{className:"shrink-0 w-3 h-3 rounded-xs",style:{backgroundColor:s}}),a.jsx("span",{className:"text-fg-secondary whitespace-nowrap",children:e.label}),u&&a.jsxs("span",{className:H("tabular-nums",c?"text-fg-primary":"text-fg-muted"),children:[(100*m).toFixed(1),"%"]})]},e.key)})})]})}const Ce='ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace';function Te(e,t,s,a,n){const l=e.reduce((e,t)=>e+t,0);if(l<=0||0===e.length)return[];const i=e.map((e,t)=>t).sort((t,s)=>e[s]-e[t]),r=i.map(t=>e[t]),o=new Array(e.length);return Ae(r,i,l,t,s,a,n,o),o}function Ae(e,t,s,a,n,l,i,r){if(0===e.length)return;if(1===e.length)return void(r[t[0]]={x:a,y:n,w:l,h:i,index:t[0]});const o=l*i/s,c=l>=i,d=c?i:l;let m=0,u=1/0,h=0;for(let y=0;ys?a/s:s/a,n>s?n/s:s/n);if(!(l<=u))break;u=l,h=y+1,m=t}const x=d>0?m*o/d:0;let p=0;for(let y=0;y0?e[y]/m:0)*d;r[t[y]]=c?{x:a,y:n+p,w:x,h:s,index:t[y]}:{x:a+p,y:n,w:s,h:x,index:t[y]},p+=s}const g=e.slice(h),f=t.slice(h),b=s-m;c?Ae(g,f,b,a+x,n,l-x,i,r):Ae(g,f,b,a,n+x,l,i-x,r)}function Fe(e,t,s,a,l,i){for(const r of t){const t=s[r.index];if(!t)continue;const o=2*i,c=r.x*i+o/2,d=r.y*i+o/2,m=r.w*i-o,u=r.h*i-o;if(m<=0||u<=0)continue;const h=n(t.typeNum),x=null!==l&&l!==r.index;e.save(),e.globalAlpha=x?.4:1;const p=3*i;e.beginPath(),e.moveTo(c+p,d),e.lineTo(c+m-p,d),e.quadraticCurveTo(c+m,d,c+m,d+p),e.lineTo(c+m,d+u-p),e.quadraticCurveTo(c+m,d+u,c+m-p,d+u),e.lineTo(c+p,d+u),e.quadraticCurveTo(c,d+u,c,d+u-p),e.lineTo(c,d+p),e.quadraticCurveTo(c,d,c+p,d),e.closePath(),e.fillStyle=h,e.fill(),e.strokeStyle="rgba(0,0,0,0.2)",e.lineWidth=1*i,e.stroke();const g=4*i,f=r.w>36&&r.h>20,b=r.w>36&&r.h>32;if(f){const s=11*i;if(b){const n=a>0?t.size/a*100:0;e.font=`500 ${8*i}px ${Ce}`,e.fillStyle="rgba(0,0,0,0.6)",e.textBaseline="alphabetic",e.textAlign="left",e.fillText(`${n.toFixed(1)}%`,c+g,d+u-g-s)}e.font=`600 ${9*i}px ${Ce}`,e.fillStyle="rgba(0,0,0,0.85)",e.textBaseline="alphabetic",e.textAlign="left",e.fillText(t.name,c+g,d+u-g)}e.restore()}}function Pe({data:e,total:t,color:s,position:n,containerWidth:l,isAirtime:i}){if(!e||!n)return null;const r=(e.value/t*100).toFixed(1),o=l-n.x<184?Math.max(8,n.x-160-8):n.x+16;return a.jsx("div",{className:"absolute z-50 pointer-events-none",style:{left:o,top:Math.max(8,n.y-60)},children:a.jsxs("div",{className:"bg-tooltip-bg border border-edge-subtle rounded-lg px-3 py-2 shadow-xl min-w-[140px]",children:[a.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[a.jsx("span",{className:"w-2.5 h-2.5 rounded-sm flex-shrink-0",style:{backgroundColor:s}}),a.jsx("span",{className:"type-data-sm font-semibold text-fg-primary",children:e.name})]}),a.jsxs("div",{className:"space-y-0.5 type-data-xs text-fg-muted",children:[a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:i?"Airtime":"Count"}),a.jsx("span",{className:"text-fg-primary tabular-nums font-medium",children:i?Le(e.value):e.value.toLocaleString()})]}),a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:"Share"}),a.jsxs("span",{className:"text-fg-primary tabular-nums font-medium",children:[r,"%"]})]}),a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:"Total"}),a.jsx("span",{className:"text-fg-primary tabular-nums font-medium",children:i?Le(t):t.toLocaleString()})]})]})]})})}function Le(e){return e>=6e4?`${(e/6e4).toFixed(1)}m`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${Math.round(e)}ms`}function Re({sortedTypes:e,aggregateShares:t,mode:l="share"}){var i,r,o;const[c,d]=s.useState(null),[m,u]=s.useState(null),[h,x]=s.useState(0),[p,g]=s.useState(null),f=s.useRef(null),b=s.useRef(null),y=s.useRef([]),j="airtime"===l,v=s.useMemo(()=>e.reduce((e,t)=>e+(j?t.totalAirtime:t.totalCount),0),[e,j]),N=s.useMemo(()=>e.map((e,t)=>({name:e.label,size:j?e.totalAirtime:e.totalCount,index:t,typeNum:e.typeNum,key:e.key})),[e,j]);s.useEffect(()=>{const e=b.current;if(!e)return;const t=e.parentElement;if(!t)return;const s=t.getBoundingClientRect(),a=s.width,n=s.height;if(a<=0||n<=0)return;const l=window.devicePixelRatio||1;e.width=Math.floor(a*l),e.height=Math.floor(n*l),e.style.width=`${a}px`,e.style.height=`${n}px`;const i=Te(N.map(e=>e.size),0,0,a,n);y.current=i;const r=e.getContext("2d");r&&(r.clearRect(0,0,e.width,e.height),Fe(r,i,N,v,c,l))},[N,v,c]),s.useEffect(()=>{const e=f.current;if(!e)return;const t=new ResizeObserver(()=>{const t=b.current;if(!t)return;const s=e.getBoundingClientRect(),a=s.width,n=s.height;if(a<=0||n<=0)return;const l=window.devicePixelRatio||1;t.width=Math.floor(a*l),t.height=Math.floor(n*l),t.style.width=`${a}px`,t.style.height=`${n}px`;const i=Te(N.map(e=>e.size),0,0,a,n);y.current=i;const r=t.getContext("2d");r&&(r.clearRect(0,0,t.width,t.height),Fe(r,i,N,v,c,l))});return t.observe(e),()=>t.disconnect()},[N,v]);const w=s.useCallback(e=>{const t=f.current;if(!t)return;const s=t.getBoundingClientRect(),a=e.clientX-s.left,n=e.clientY-s.top,l=function(e,t,s){for(const a of e)if(t>=a.x&&t<=a.x+a.w&&s>=a.y&&s<=a.y+a.h)return a.index;return null}(y.current,a,n);d(l),null!==l?(x(s.width),u({x:a,y:n})):u(null)},[]),k=s.useCallback(()=>{d(null),u(null)},[]),M=s.useCallback(e=>{if(g(e),e){const t=N.findIndex(t=>t.key===e);d(t>=0?t:null)}else d(null)},[N]),S=null!==c?{name:(null==(i=N[c])?void 0:i.name)??"",value:(null==(r=N[c])?void 0:r.size)??0}:null,C=null!==c?n(null==(o=N[c])?void 0:o.typeNum):"";return 0===e.length||0===v?a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet type data available"})]}):a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsx("div",{className:"flex-1 min-h-0 relative",children:a.jsxs("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},ref:f,onMouseMove:w,onMouseLeave:k,children:[a.jsx("canvas",{ref:b,className:"absolute inset-0",style:{cursor:"default"}}),a.jsx(Pe,{data:S,total:v,color:C,position:m,containerWidth:h,isAirtime:j})]})}),a.jsx("div",{style:{minHeight:80},children:a.jsx(Se,{sortedTypes:e,highlightedType:p,onTypeHover:M,aggregateShares:t})})]})}function $e(e){return e>=1e9?`${(e/1e9).toFixed(1)} Gb`:e>=1e6?`${(e/1e6).toFixed(1)} Mb`:e>=1e3?`${(e/1e3).toFixed(1)} Kb`:`${e.toFixed(0)} B`}function De({packets:e,mode:t,startTs:n,endTs:l,radioConfig:m,bucketCount:u,lockedYMax:h,legendMinH:x}){const p=s.useMemo(()=>i(),[]),g=p.blue,f=p.red,b=p.yellow,[y,j]=s.useState(null),{trendData:v,totals:N}=s.useMemo(()=>{if(0===e.length)return{trendData:[],totals:{rxBytes:0,txBytes:0,rxAirtime:0,txAirtime:0}};const s=l-n,a=Math.min(Math.ceil(s/300),u),i=s/a,c=[];let d=0,h=0,x=0,p=0;for(const t of e){const e=t.timestamp;if(e=l)continue;const s=r(t),a=o(t,{spreadingFactor:m.sf,bandwidthHz:m.bw,codingRate:m.cr,preambleLength:m.preamble}),i={timestamp:e,rxAirtime:0,txAirtime:0,rxBytes:0,txBytes:0};t.transmitted?(i.txAirtime=a,i.txBytes=s,h+=s,p+=a):(i.rxAirtime=a,i.rxBytes=s,d+=s,x+=a),c.push(i)}c.sort((e,t)=>e.timestamp-t.timestamp);const g=new Float64Array(c.length+1),f=new Float64Array(c.length+1),b=new Float64Array(c.length+1),y=new Float64Array(c.length+1),j=new Float64Array(c.length);for(let e=0;e{let t=0,s=j.length;for(;t>>1;j[a]0?e:null,tx:t>0?t:null})}else{const e=(g[r]-g[l])/w*100,t=(f[r]-f[l])/w*100;N.push({timestamp:s,rx:e>0?e:null,tx:t>0?t:null})}}const k=2/31;let M=null;return{trendData:N.map(e=>{const t=e.rx;return null!==t&&t>0&&(M=null===M?t:k*t+(1-k)*M),{...e,rxSmooth:null!==M&&M>0?M:null}}),totals:{rxBytes:d,txBytes:h,rxAirtime:x,txAirtime:p}}},[e,n,l,u,t,m]),w=s.useMemo(()=>{if(0===v.length)return"share"===t?100:10;let e=0;for(const t of v){const s=t.rx??0,a=t.tx??0;s>e&&(e=s),a>e&&(e=a)}const s=1.1*e;return"share"===t?s<=100?100:s<=500?100*Math.ceil(s/100):s<=1e3?200*Math.ceil(s/200):s<=5e3?500*Math.ceil(s/500):s<=1e4?1e3*Math.ceil(s/1e3):5e3*Math.ceil(s/5e3):Math.max(1,Math.ceil(s))},[v,t]),k=h??w,M=s.useMemo(()=>{if(null!==y&&v[y]){const e=v[y],s=e.rx??0,a=e.tx??0;return"share"===t?{rx:$e(s),tx:$e(a),total:$e(s+a),isHovered:!0}:{rx:`${s.toFixed(2)}%`,tx:`${a.toFixed(2)}%`,total:`${(s+a).toFixed(2)}%`,isHovered:!0}}if("share"===t)return{rx:$e(N.rxBytes),tx:$e(N.txBytes),total:$e(N.rxBytes+N.txBytes),isHovered:!1};{let e=0,t=0,s=0;for(const l of v)null===l.rx&&null===l.tx||(e+=l.rx??0,t+=l.tx??0,s++);const a=s>0?e/s:0,n=s>0?t/s:0;return{rx:`${a.toFixed(2)}%`,tx:`${n.toFixed(2)}%`,total:`${(a+n).toFixed(2)}%`,isHovered:!1}}},[y,v,N,t]),S=s.useMemo(()=>{const e=l-n,t=e/3600;return[0,.25,.5,.75,1].map(s=>{const a=new Date(1e3*(n+e*s)),l=a.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}),i=a.toLocaleDateString([],{weekday:"short"});return{pct:s,label:t>=24?`${i} ${l}`:l,mobileHidden:.25===s||.75===s}})},[n,l]),C=s.useCallback(e=>{j(e)},[]);if(0===v.length)return a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]});const T=s.useMemo(()=>"airtime"===t?k<=5?1:k<=10?2:k<=20?5:Math.ceil(k/5):k<=100?25:k<=500?100:k<=1e3?200:k<=5e3?1e3:k<=1e4?2e3:1e3*Math.ceil(k/5e3),[k,t]),A=s.useMemo(()=>{const e=[];for(let s=0;s<=k;s+=T){const a=100*(1-s/k);let n;n="airtime"===t?`${s}%`:s>=1e6?`${(s/1e6).toFixed(1)}M`:s>=1e3?`${(s/1e3).toFixed(0)}K`:`${s}`,e.push({pos:a,label:n})}return e},[k,T,t]);return a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:A.map((e,t)=>a.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:0===t?"translateY(-100%)":t===A.length-1?"none":"translateY(-50%)",right:0},children:e.label},t))}),a.jsx("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:a.jsx(c,{data:v,yAxisMode:"share"===t?"share":"airtime",yMax:k,onHover:C,startTs:n,endTs:l,externalAxes:!0})}),a.jsx("div",{className:"absolute left-0 right-0 bottom-0 flex items-center pointer-events-none",style:{left:32,height:20,paddingTop:4},children:S.map((e,t)=>a.jsx("span",{className:"absolute type-data-xs text-fg-muted/60 tabular-nums "+(e.mobileHidden?"hidden sm:inline":""),style:{left:100*e.pct+"%",transform:0===e.pct?"translateX(0)":1===e.pct?"translateX(-100%)":"translateX(-50%)"},children:e.label},t))})]}),a.jsxs("div",{className:"flex items-end justify-between pb-1",style:{minHeight:x},children:[a.jsxs("div",{className:"flex items-center gap-3 sm:gap-5 type-data-sm pl-2 sm:pl-11",children:[a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx("div",{className:"w-4 sm:w-5 h-[2px] rounded-full",style:{backgroundColor:g}}),a.jsx("span",{className:"text-fg-secondary",children:"RX"})]}),a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx("div",{className:"w-4 sm:w-5 h-[2px] rounded-full",style:{backgroundColor:f}}),a.jsx("span",{className:"text-fg-secondary",children:"TX"})]}),a.jsxs("div",{className:"hidden sm:flex items-center gap-1.5",children:[a.jsx("div",{className:"w-5 h-[2px] rounded-full",style:{backgroundColor:b}}),a.jsx("span",{className:"text-fg-secondary",children:"Avg"})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-4 sm:gap-8",children:[a.jsxs("div",{className:"flex items-end gap-2",children:[a.jsx("div",{className:"type-data-xl text-fg-primary",children:M.rx}),a.jsx(d,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"RX"})]}),a.jsxs("div",{className:"flex items-end gap-2",children:[a.jsx("div",{className:"type-data-xl text-fg-primary",children:M.tx}),a.jsx(d,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"TX"})]})]})]})]})}const _e=m,ze=new class{constructor(){t(this,"worker",null),t(this,"listeners",new Set),t(this,"currentResult",null),t(this,"isComputing",!1),t(this,"debounceTimer",null),t(this,"debounceMs",250),t(this,"lastCacheKey",null)}ensureWorker(){if(this.worker)return this.worker;if("undefined"==typeof window)return null;try{this.worker=new Worker(new URL("/assets/bucketing.worker-Dmsaoaph.js",import.meta.url),{type:"module"}),this.worker.onmessage=e=>{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[BucketingService] Worker error:",e),this.isComputing=!1,this.notifyListeners()}}catch(e){console.error("[BucketingService] Failed to initialize worker:",e)}return this.worker}handleWorkerMessage(e){if(this.isComputing=!1,"error"===e.type)return this.currentResult=null,void this.notifyListeners();const t=e.payload;this.currentResult={points:t.points,rawValues:t.rawValues,packetTypes:t.packetTypes,timestamps:t.timestamps,count:t.count,minTime:t.minTime,maxTime:t.maxTime,minValue:t.minValue,maxValue:t.maxValue,rawMinValue:t.rawMinValue,rawMaxValue:t.rawMaxValue,unit:"%",stats:{p5:t.p5,p50:t.p50,p95:t.p95,uniqueValues:t.uniqueValues,topValues:t.topValues}},this.notifyListeners()}notifyListeners(){for(const t of this.listeners)try{t(this.currentResult,this.isComputing)}catch(e){console.error("[BucketingService] Listener error:",e)}}isCacheHit(e){return!(!this.lastCacheKey||!this.currentResult)&&this.lastCacheKey.startTs===e.startTs&&this.lastCacheKey.endTs===e.endTs&&this.lastCacheKey.mode===e.mode&&this.lastCacheKey.packetCount===e.packetCount}compute(e,t,s,a,n){if(0===e.length||!n)return this.currentResult=null,void this.notifyListeners();const l={startTs:t,endTs:s,mode:a,packetCount:e.length};this.isCacheHit(l)||(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.computeInternal(e,t,s,a,n,l)},this.debounceMs))}computeInternal(e,t,s,a,n,l){const i=this.ensureWorker();if(!i)return;const c=e.length,d=new Float64Array(c),m=new Float64Array(c),u=new Uint16Array(c),h=new Uint8Array(c),x={spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble};for(let g=0;g{this.listeners.delete(e)}}clear(){this.currentResult=null,this.lastCacheKey=null,this.notifyListeners()}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}};function Ee({mode:e,packets:t,startTs:n,endTs:l,radioConfig:i,sortedTypes:r,aggregateShares:c,noiseFloorAnomalies:d,showNoiseFloorOverlay:m,overlayOpacity:h=.5,startLabel:x,endLabel:p,lockedYMax:g,legendMinH:f,dotSize:b,dotOpacity:y}){const[j,v]=s.useState(null),[N,w]=s.useState(null),k=s.useMemo(()=>(l-n)/3600,[n,l]),M=s.useCallback(e=>{w(e)},[]),S=function(e,t,a,n,l){const[i,r]=s.useState(()=>ze.getResult());return s.useEffect(()=>ze.subscribe(e=>{r(e)}),[]),s.useEffect(()=>{ze.compute(e,t,a,n,l)},[e,t,a,n,l]),i}(t,n,l,"share"===e?"share":"airtime",i),[C,T]=s.useState(null),A=s.useCallback((e,t)=>{v(e),T(t??null)},[]),F=s.useMemo(()=>{if(null===C||!S||0===S.count)return null;const e=n+C*(l-n);let t;t=k>=168?75:k>=72?35:k>=24?15:k>=3?10:5;const s=60*t/2;return{start:e-s,end:e+s}},[C,S,n,l,k]),P=s.useMemo(()=>F?new Date((F.start+F.end)/2*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}):null,[F]),L=s.useMemo(()=>{if(null===j||!F)return null;const s=P??"",{start:a,end:n}=F,l=t.filter(e=>e.timestamp>=a&&e.timestamp({key:e.key,label:e.label,value:0,color:_e(e.typeNum)}))};const c=new Map,d=new Map;let m=0,u=0;for(const e of l){const t=`TYPE_${e.type??e.payload_type??-1}`;if(c.set(t,(c.get(t)??0)+1),m++,i){const s=o(e,{spreadingFactor:i.sf,bandwidthHz:i.bw,codingRate:i.cr,preambleLength:i.preamble});d.set(t,(d.get(t)??0)+s),u+=s}}const h=r.map(t=>{let s;return s="airtime"===e?u>0?(d.get(t.key)??0)/u:0:m>0?(c.get(t.key)??0)/m:0,{key:t.key,label:t.label,value:s,color:_e(t.typeNum)}});return{timestamp:(a+n)/2,timeLabel:s,items:h}},[j,F,P,t,r,e,i]),R="share"===e,$=g??(null==S?void 0:S.maxValue)??(R?200:10),D=s.useMemo(()=>{if(!R)return 5;const e=[10,20,25,50,100,200,250,500,1e3],t=$/4.5;for(const s of e)if(s>=t)return s;return $>5e3?1e3*Math.ceil(t/1e3):100*Math.ceil(t/100)},[$,R]),_=s.useMemo(()=>{const e=[];for(let t=0;t<=$;t+=D){const s=100*(1-t/$);e.push({pos:s,label:R?`${t}B`:`${t}%`})}return e},[$,D,R]);return S&&0!==S.count?a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:_.map((e,t)=>a.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:0===t?"translateY(-100%)":t===_.length-1?"none":"translateY(-50%)",right:0},children:e.label},t))}),a.jsxs("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:[a.jsx(u,{scatterData:S,yAxisMode:"share"===e?"share":"airtime",onHover:A,noiseFloorAnomalies:d,showNoiseFloorOverlay:m,overlayOpacity:h,highlightedType:N,timeRangeHours:k,yAxisMaxOverride:g,dotSize:b,dotOpacity:y,startTs:n,endTs:l,externalAxes:!0}),P&&a.jsx("div",{className:"absolute top-1 right-1 px-2 py-0.5 bg-elevated/90 rounded type-data-xs text-sys-indigo pointer-events-none z-10",children:P})]}),x&&p&&a.jsxs("div",{className:"absolute left-0 right-0 bottom-0 flex justify-between pointer-events-none type-data-xs text-fg-muted/60",style:{left:32,height:20,paddingTop:4},children:[a.jsx("span",{children:x}),a.jsx("span",{children:p})]})]}),a.jsx("div",{style:{minHeight:f},children:a.jsx(Se,{sortedTypes:r,highlightedType:N,onTypeHover:M,aggregateShares:c,hoverData:L})})]}):a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]})}function He({mode:e,onChange:t}){return a.jsxs("div",{className:"toggle-group toggle-group-sm",children:[a.jsx("button",{onClick:()=>t("share"),className:"toggle-group-item "+("share"===e?"active":""),children:"Total"}),a.jsx("button",{onClick:()=>t("airtime"),className:"toggle-group-item "+("airtime"===e?"active":""),children:"Airtime"})]})}function Be({smoothing:e,onChange:t}){return a.jsxs("div",{className:"toggle-group toggle-group-sm",children:[a.jsx("button",{onClick:()=>t("stats"),className:"toggle-group-item "+("stats"===e?"active":""),title:"Statistics view (scatter plot)",children:a.jsx(q,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("trend"),className:"toggle-group-item "+("trend"===e?"active":""),title:"Trend line chart",children:a.jsx(I,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("ema"),className:"toggle-group-item "+("ema"===e?"active":""),title:"Stacked area (moderate smoothing)",children:a.jsx(B,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("ultra"),className:"toggle-group-item "+("ultra"===e?"active":""),title:"Stacked area (heavy smoothing)",children:a.jsx(G,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("mosaic"),className:"toggle-group-item "+("mosaic"===e?"active":""),title:"Mosaic view (treemap)",children:a.jsx(V,{className:"w-3.5 h-3.5"})})]})}function Oe({enabled:e,onChange:t,anomalyCount:s=0,showTuning:n=!1,onTuningChange:l}){return a.jsxs("div",{className:"relative inline-flex items-center gap-1",children:[e&&l&&a.jsx("button",{onClick:()=>l(!n),className:"toggle-group toggle-group-sm "+(n?"active":""),title:n?"Hide tuning panel":"Show tuning panel",children:a.jsx("span",{className:"toggle-group-item "+(n?"active":""),children:a.jsx(O,{className:"w-3.5 h-3.5"})})}),a.jsx("button",{onClick:()=>t(!e),className:"toggle-group toggle-group-sm "+(e?"active":""),title:e?"Hide noise floor anomalies":"Show noise floor anomalies",children:a.jsx("span",{className:"toggle-group-item "+(e?"active":""),children:a.jsx(W,{className:"w-3.5 h-3.5"})})}),s>0&&a.jsx("span",{className:"absolute -top-2 -right-2 min-w-[18px] h-[18px] px-1 rounded-full bg-sys-red text-white text-xs font-bold flex items-center justify-center pointer-events-none z-10",children:s>99?"99+":s})]})}const We=[{target:"PacketAnalyzer",fn:"type",minStage:1},{target:"PacketAnalyzer",fn:"airtime",minStage:1,when:ae}];ne(We);const qe={sf:10,bw:25e4,cr:5,preamble:8};function Ie(e,t){const s=new Date(1e3*e),a=e=>e.toString().padStart(2,"0"),n=`${a(s.getHours())}:${a(s.getMinutes())}`;return t<24?n:`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][s.getMonth()]} ${s.getDate()} ${n}`}function Ge(e){return l[e]??`TYPE_${e.toString(16).toUpperCase()}`}function Ve(e,t,s,a){const n=2*a+1;let l=0;for(let i=0;i<=a;i++)l+=e[Math.min(i,s-1)];for(let i=0;i{const t=Math.abs(e.length-F.current);if(0===t&&C.length>0)return;A.current&&clearTimeout(A.current);const s=t>100?50:500;return A.current=setTimeout(()=>{F.current=e.length,T(e)},s),()=>{A.current&&clearTimeout(A.current)}},[e,C.length]);const P=s.useMemo(()=>function(e,t){const s=new Map;for(const n of e){const e=n.type??n.payload_type??-1,a=o(n,{spreadingFactor:t.sf,bandwidthHz:t.bw,codingRate:t.cr,preambleLength:t.preamble}),l=s.get(e)??{count:0,airtime:0};s.set(e,{count:l.count+1,airtime:l.airtime+a})}const a=[];for(const[n,l]of s)a.push({typeNum:n,key:`TYPE_${n}`,label:Ge(n),totalCount:l.count,totalAirtime:l.airtime});return a.sort((e,t)=>t.totalCount-e.totalCount)}(C,u),[C,u]),L=s.useMemo(()=>{if("ema"!==g&&"ultra"!==g)return 0;const e=(i-l)/m,{handleSize:t}=Xe(g,e,m);return t},[g,l,i,m]),R=s.useMemo(()=>function(e,t,s,a,n,l,i=0){const r=s-t,c=r/a,d=1e3*c,m=r/3600,u=t-i*c,h=s+i*c,x=a+2*i,p=[];for(let o=0;o=24?t.toLocaleDateString([],{weekday:"short",hour:"2-digit",minute:"2-digit",hour12:!1}):t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}),counts:{},shares:{},airtimes:{},total:0,totalAirtime:0,bucketDurationMs:d};for(const a of l)s.counts[a.key]=0,s.airtimes[a.key]=0;p.push(s)}for(const g of e){const e=g.timestamp;if(e=h)continue;const t=Math.min(Math.floor((e-u)/c),x-1),s=`TYPE_${g.type??g.payload_type??-1}`;p[t].counts[s]=(p[t].counts[s]??0)+1,p[t].total++;const a=o(g,{spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble});p[t].airtimes[s]=(p[t].airtimes[s]??0)+a,p[t].totalAirtime+=a}for(const o of p)for(const e of l)o.shares[e.key]=o.total>0?o.counts[e.key]/o.total*100:0;return{buckets:p,visibleStart:i,visibleEnd:i+a}}(C,l,i,m,u,P,L),[C,l,i,m,u,P,L]),$=s.useMemo(()=>P.reduce((e,t)=>e+t.totalCount,0),[P]),D=s.useMemo(()=>P.reduce((e,t)=>e+t.totalAirtime,0),[P]),{sortedTypes:_,aggregateShares:z}=s.useMemo(()=>{const e=new Map,t="share"===p?$:D;if(t>0)for(const s of P){const a="share"===p?s.totalCount:s.totalAirtime;e.set(s.key,a/t)}return{sortedTypes:[...P].sort((t,s)=>(e.get(s.key)??0)-(e.get(t.key)??0)),aggregateShares:e}},[P,$,D,p]),E=s.useMemo(()=>function(e,t,s,a="ultra",n,l,i){var r;const{buckets:o,visibleStart:c,visibleEnd:d}=e,m=o.length,u=s.length,h=d-c;if(0===m||0===u)return[];const x=i&&void 0!==n&&void 0!==l?(l-n)/i:(null==(r=o[0])?void 0:r.bucketDurationMs)?o[0].bucketDurationMs/1e3:240,p=Array.from({length:u},()=>new Array(m).fill(0));for(let N=0;N0)for(let t=0;t0)for(let a=0;a0?p.map(e=>function(e,t){const s=e.length;if(0===s)return[];if(t<.5)return[...e];const a=Math.sqrt(12*t*t/3+1);let n=Math.floor(a);n%2==0&&n--;const l=n+2,i=(12*t*t-3*n*n-12*n-9)/(-4*n-4),r=Math.round(i),o=[r>0?n:l,r>1?n:l,r>2?n:l];let c=new Float32Array(e);const d=new Float32Array(s);for(const m of o){Ve(c,d,s,(m-1)/2);const e=c;c=d,d.set(e)}return Array.from(c)}(e,g)):p.map(e=>function(e,t){if(0===e.length)return[];if(t<=1)return[...e];const s=e.length,a=new Float32Array(s),n=Math.floor(t/2);let l=0,i=0;for(let r=0;r<=Math.min(n,s-1);r++)l+=e[r],i++;for(let r=0;r=0&&(l-=e[t],i--),o0){const t=1/e;for(let e=0;e360?Math.ceil(h/360):1,j=Math.ceil(h/y),v=[];for(let N=0;N0){const e=1/l;for(let t=0;tk(e),[]),O=s.useCallback(e=>S(e),[]),W=s.useCallback(e=>k(e),[]),q=s.useMemo(()=>{if(null===M||!E[M])return null;const e=E[M];return{timestamp:e.timestamp,timeLabel:e.time,items:_.map(t=>({key:t.key,label:t.label,value:e[t.key]??0,color:n(t.typeNum)}))}},[M,E,_]),I=s.useMemo(()=>({timestamps:E.map(e=>e.timestamp),series:_.map(e=>({key:e.key,label:e.label,color:n(e.typeNum),values:E.map(t=>t[e.key]??0)}))}),[E,_]),G=t&&void 0!==c&&void 0!==d&&(l!==c||i!==d),V=s.useMemo(()=>{if(G&&t&&void 0!==c&&void 0!==d)return function(e,t,s,a,n){const l=Math.max(1,Math.ceil((s-t)/300));if("airtime"===a){const a=new Float64Array(l);for(const r of e){const e=r.timestamp;e=s||(a[Math.min(Math.floor((e-t)/300),l-1)]+=o(r,{spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble}))}let i=0;for(let e=0;ei&&(i=t)}return Math.max(1,Math.ceil(1.1*i))}{let a=0;for(const n of e){const e=n.timestamp;if(e=s)continue;const l=r(n);l>a&&(a=l)}return a<=200?200:50*Math.ceil(1.1*a/50)}}(t,c,d,p,u)},[G,t,c,d,p,u]);if(0===C.length)return 0===e.length?a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]}):null;if("mosaic"===g)return a.jsx(Re,{sortedTypes:_,aggregateShares:z,mode:p});const Y=(i-l)/3600,K=Ie(l,Y),X=Ie(i,Y);return"stats"===g?a.jsx(Ee,{mode:p,packets:C,startTs:l,endTs:i,radioConfig:u,sortedTypes:_,aggregateShares:z,noiseFloorAnomalies:f,showNoiseFloorOverlay:b,overlayOpacity:y,startLabel:K,endLabel:X,lockedYMax:V,legendMinH:80,dotSize:j,dotOpacity:v}):"trend"===g?a.jsx(De,{packets:C,mode:p,startTs:l,endTs:i,radioConfig:u,bucketCount:m,lockedYMax:V,legendMinH:80}):a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:[0,20,40,60,80,100].map((e,t,s)=>a.jsxs("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:100*(1-e/100)+"%",transform:0===t?"translateY(-100%)":t===s.length-1?"none":"translateY(-50%)",right:0},children:[e,"%"]},e))}),a.jsx("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:a.jsx(x,{timestamps:I.timestamps,series:I.series,highlightedKey:w,cursorColor:N.cursor,onHover:O,onSeriesHover:W,overlayLine:null,startTs:l,endTs:i,externalAxes:!0})}),a.jsxs("div",{className:"absolute left-0 right-0 bottom-0 flex justify-between pointer-events-none type-data-xs text-fg-muted/60",style:{left:32,height:20,paddingTop:4},children:[a.jsx("span",{children:K}),a.jsx("span",{children:X})]})]}),a.jsx("div",{style:{minHeight:80},children:a.jsx(Se,{sortedTypes:_,highlightedType:w,onTypeHover:H,aggregateShares:z,hoverData:q})})]})}),Je={"1x":1,"2x":2,"4x":4,"8x":8,"16x":16,"36x":36},Qe=[1,5,10,25,50,100,150],Ze=22.5*Math.PI/180,et=Math.sin(Ze),tt=Math.cos(Ze);function st(e,t,s,a){const n=Math.PI/180,l=(a-t)*n,i=e*n,r=s*n,o=Math.sin(l)*Math.cos(r),c=Math.cos(i)*Math.sin(r)-Math.sin(i)*Math.cos(r)*Math.cos(l);return(180*Math.atan2(o,c)/Math.PI+360)%360}function at(e,t,s,a){const n=Math.PI/180,l=(s-e)*n,i=(a-t)*n,r=Math.sin(l/2)**2+Math.cos(e*n)*Math.cos(s*n)*Math.sin(i/2)**2;return 12742*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))}const nt=[{min:10,label:"Excellent"},{min:7,label:"Very Good"},{min:4,label:"Good"},{min:1,label:"Fair+"},{min:-2,label:"Fair"},{min:-5,label:"Fair-"},{min:-8,label:"Poor"},{min:-11,label:"Bad"},{min:-1/0,label:"Critical"}];function lt(e,t,s){return t[v(e,s)]||"#808080"}const it=s.memo(function({neighbors:e,quickNeighbors:t,localLat:n,localLon:l,onStatsChange:r,title:o,badge:c,stats:m}){const[u,h]=s.useState(null),[x,v]=s.useState(new Set),[N,w]=s.useState({width:0,height:0}),[k,M]=s.useState("1x"),[S,C]=s.useState(1),T=s.useRef(null),A=s.useRef({}),F=s.useRef(null),P=s.useRef(S);P.current=S;const L=p(),R=g(),$=f(),D=b(),_=i(),z=y(),E=D?$.primary:$.secondary,H=D?.15:.4,B=D?.08:.25,O=D?_.blue:$.primary;s.useEffect(()=>{const e=F.current;if(!e)return;const t=new ResizeObserver(e=>{for(const t of e){const{width:e,height:s}=t.contentRect;e>0&&s>0&&w({width:e,height:s})}});t.observe(e);const s=e.getBoundingClientRect();return s.width>0&&s.height>0&&w({width:s.width,height:s.height}),()=>t.disconnect()},[]);const W=s.useMemo(()=>{const e=new Set;if(t)for(const s of t)e.add(s.hash);return e},[t]),q=s.useMemo(()=>{const e=new Map;if(t)for(const s of t)e.set(s.hash,{snr:s.avgSnr,rssi:s.avgRssi});return e},[t]),{processedNeighbors:I,maxDistance:G,totalNeighbors:V,zeroHopCount:K}=s.useMemo(()=>{const t=[];for(const[a,i]of Object.entries(e)){if(!i.latitude||!i.longitude||0===i.latitude||0===i.longitude)continue;if(!W.has(a))continue;const e=st(n,l,i.latitude,i.longitude),s=at(n,l,i.latitude,i.longitude),r=q.get(a);t.push({hash:a.slice(0,8),name:i.node_name||i.name||"Unknown",snr:(null==r?void 0:r.snr)??i.snr??null,rssi:(null==r?void 0:r.rssi)??i.rssi??null,bearing:e,distance:s,normalizedDistance:0,lastSeen:i.last_seen,isZeroHop:!0})}const s=1.08*(t.length>0?Math.max(...t.map(e=>e.distance)):0);return t.sort((e,t)=>(e.snr??-1/0)-(t.snr??-1/0)),{processedNeighbors:t,maxDistance:s,totalNeighbors:t.length,zeroHopCount:t.length}},[e,n,l,W,q]);s.useEffect(()=>{null==r||r({zeroHopCount:K,totalCount:V,maxDistanceKm:G})},[K,V,G]),s.useEffect(()=>{const e=Je[k],t=P.current;T.current&&cancelAnimationFrame(T.current);const s=performance.now(),a=n=>{const l=n-s,i=Math.min(l/400,1),r=le(i);C(t+(e-t)*r),T.current=i<1?requestAnimationFrame(a):null};return T.current=requestAnimationFrame(a),()=>{T.current&&cancelAnimationFrame(T.current)}},[k]);const X=G/S,U=s.useMemo(()=>Qe.filter(e=>e<=1.1*X),[X]);s.useEffect(()=>{const e=[];for(const s of I){const t=A.current[s.hash];void 0!==t&&t!==s.lastSeen&&e.push(s.hash),A.current[s.hash]=s.lastSeen}if(0===e.length)return;queueMicrotask(()=>{v(t=>new Set([...t,...e]))});const t=setTimeout(()=>{v(t=>{const s=new Set(t);return e.forEach(e=>s.delete(e)),s})},600);return()=>clearTimeout(t)},[I]);const J=0!==n&&0!==l,Q=s.useMemo(()=>{const{width:e,height:t}=N,s=e/2,a=t/2,n=Math.min(e,t),l=Math.max(10,n/2-6);return{width:e,height:t,centerX:s,centerY:a,radius:Math.max(10,l-8),labelRadius:l}},[N]),{width:Z,height:ee,centerX:te,centerY:se,radius:ae,labelRadius:ne}=Q,ie=s.useId(),re=s.useCallback((e,t)=>{const s=e*Math.PI/180;return{x:te+ae*t*Math.sin(s),y:se-ae*t*Math.cos(s)}},[te,se,ae]),oe=s.useCallback(e=>{const t={N:0,NE:45,E:90,SE:135,S:180,SW:225,W:270,NW:315}[e]*Math.PI/180;return{x:te+ne*Math.sin(t),y:se-ne*Math.cos(t)}},[te,se,ne]),ce=s.useCallback(e=>{h(e)},[]),de=s.useCallback(e=>{M(e)},[]),me=s.useCallback(e=>G<=0?0:e/G*S,[G,S]),ue=e=>`${e}km`,he=s.useMemo(()=>{const e=[{x:te,y:se-ne},{x:te+ne*Math.SQRT1_2,y:se-ne*Math.SQRT1_2}],t=U.map(e=>{const t=e/G*S;return{km:e,scale:t,lx:te+ae*t*et,ly:se-ae*t*tt}}).filter(e=>e.scale<=1.05&&e.scale>=.02).sort((e,t)=>t.km-e.km),s=[];for(const a of t){const t=s.some(e=>{const t=e.lx-a.lx,s=e.ly-a.ly;return Math.sqrt(t*t+s*s)<28}),n=e.some(e=>{const t=e.x-a.lx,s=e.y-a.ly;return Math.sqrt(t*t+s*s)<28});t||n||s.push(a)}return s},[U,G,S,te,se,ae,ne]),xe=N.width>0&&N.height>0;return J?0===V?a.jsxs("div",{ref:F,className:"flex flex-col items-center justify-center h-full text-fg-secondary",children:[a.jsx(Y,{className:"w-8 h-8 mb-2 opacity-50"}),a.jsx("p",{children:"No nodes with location data"})]}):a.jsxs("div",{className:"flex h-full w-full overflow-visible",children:[a.jsxs("div",{ref:F,className:"relative flex-1 min-w-0 h-full overflow-visible -ml-4 sm:-ml-5",children:[xe&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"absolute depth-raised",style:{left:te-ae-8-4,top:se-ae-8-4,width:2*(ae+8)+8,height:2*(ae+8)+8,borderRadius:"50%",padding:4,boxSizing:"border-box",backgroundColor:D?"var(--zinc-925)":"var(--zinc-75)"}}),a.jsxs("svg",{width:Z,height:ee,className:"absolute inset-0 z-0",style:{overflow:"visible"},children:[a.jsxs("defs",{children:[a.jsx("style",{children:"\n @keyframes neighbor-blink-scale {\n 0%, 100% {\n transform: scale(1);\n opacity: 0;\n }\n 50% {\n transform: scale(1.3);\n opacity: 0.8;\n }\n }\n .neighbor-blink-ring {\n transform-origin: center;\n animation: neighbor-blink-scale 600ms ease-out forwards;\n }\n "}),a.jsx("clipPath",{id:ie,children:a.jsx("circle",{cx:te,cy:se,r:ae})})]}),(()=>{const e=ae+8+12,t=D?"rgba(255, 255, 255, 0.12)":"rgba(0, 0, 0, 0.15)",s=D?"rgba(59, 130, 246, 0.4)":"rgba(59, 130, 246, 0.5)",n=[45,135,225,315];return a.jsxs("g",{className:"radar-frame","aria-hidden":"true",children:[a.jsx("circle",{cx:te,cy:se,r:e,fill:"none",stroke:t,strokeWidth:1,strokeDasharray:"2 6"}),n.map(t=>{const n=t*Math.PI/180,l=Math.cos(n),i=Math.sin(n),r=e+4,o=e+4+16,c=te+r*i,d=se-r*l,m=te+o*i,u=se-o*l;return a.jsxs("g",{children:[a.jsx("line",{x1:c,y1:d,x2:m,y2:u,stroke:s,strokeWidth:1}),a.jsx("line",{x1:m-4*l,y1:u-4*i,x2:m+4*l,y2:u+4*i,stroke:s,strokeWidth:1})]},`corner-${t}`)}),[0,90,180,270].map(s=>{const n=s*Math.PI/180,l=te+(e-6)*Math.sin(n),i=se-(e-6)*Math.cos(n),r=te+(e+2)*Math.sin(n),o=se-(e+2)*Math.cos(n);return a.jsx("line",{x1:l,y1:i,x2:r,y2:o,stroke:t,strokeWidth:1},`tick-cardinal-${s}`)}),n.map(s=>{const n=s*Math.PI/180,l=te+(e-4)*Math.sin(n),i=se-(e-4)*Math.cos(n),r=te+(e+1)*Math.sin(n),o=se-(e+1)*Math.cos(n);return a.jsx("line",{x1:l,y1:i,x2:r,y2:o,stroke:t,strokeWidth:1},`tick-intercardinal-${s}`)})]})})(),(()=>{const e=[(ae+8+4)/ae,...U.map(e=>me(e)).filter(e=>e>.02&&e<=1.05).sort((e,t)=>t-e),0];return e.slice(0,-1).map((t,s)=>{const n=e[s+1],l=ae*t,i=ae*n,r=l-i;return r<=0||s%2!=0?null:a.jsx("circle",{cx:te,cy:se,r:(l+i)/2,fill:"none",stroke:"var(--subtle-fill)",strokeWidth:r,opacity:.8},`band-${s}`)})})(),U.map(e=>{const t=me(e);if(t>1.05||t<.02)return null;const s=he.some(t=>t.km===e),n=te+ae*t*et,l=se-ae*t*tt;return a.jsxs("g",{children:[a.jsx("circle",{cx:te,cy:se,r:ae*t,fill:"none",stroke:E,strokeOpacity:H,strokeWidth:1}),s&&a.jsx("text",{x:n+4,y:l-2,textAnchor:"start",dominantBaseline:"auto",fill:$.secondary,fontSize:10,fontFamily:j,children:ue(e)})]},`ring-${e}`)}),["N","E","S","W"].map(e=>{const t={N:0,E:90,S:180,W:270}[e]*Math.PI/180;return a.jsx("line",{x1:te,y1:se,x2:te+ae*Math.sin(t),y2:se-ae*Math.cos(t),stroke:E,strokeOpacity:H,strokeWidth:1,strokeDasharray:"4 4"},e)}),["NE","SE","SW","NW"].map(e=>{const t={NE:45,SE:135,SW:225,NW:315}[e]*Math.PI/180;return a.jsx("line",{x1:te,y1:se,x2:te+ae*Math.sin(t),y2:se-ae*Math.cos(t),stroke:E,strokeOpacity:B,strokeWidth:1,strokeDasharray:"4 4"},`diag-${e}`)}),["N","E","S","W"].map(e=>{const t=oe(e),s="E"===e?"end":"W"===e?"start":"middle",n="N"===e?"hanging":"S"===e?"auto":"middle";return a.jsx("text",{x:t.x,y:t.y,textAnchor:s,dominantBaseline:n,fill:O,fontSize:10,fontWeight:700,fontFamily:j,"aria-hidden":"true",children:e},e)}),["NE","SE","SW","NW"].map(e=>{const t=oe(e),s="NE"===e||"SE"===e?"end":"start",n="NE"===e||"NW"===e?"hanging":"auto";return a.jsx("text",{x:t.x,y:t.y,textAnchor:s,dominantBaseline:n,fill:O,fontSize:9,fontWeight:600,fontFamily:j,"aria-hidden":"true",children:e},e)}),a.jsx("circle",{cx:te,cy:se,r:5,fill:R.chart6,stroke:D?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",strokeWidth:1,role:"img","aria-label":"Local node"}),a.jsx("g",{clipPath:`url(#${ie})`,children:I.map(e=>{const t=G>0?e.distance/G*S:0;if(t>1)return null;const{x:s,y:n}=re(e.bearing,t),l=null!==e.snr?lt(e.snr,L,z):"#808080",i=(null==u?void 0:u.hash)===e.hash,r=x.has(e.hash);return a.jsxs("g",{role:"img","aria-label":`${e.name}: ${e.distance.toFixed(1)}km ${e.bearing.toFixed(0)}°`,children:[r&&a.jsx("circle",{cx:s,cy:n,r:10.5,fill:"none",stroke:D?"rgba(255,255,255,0.9)":"rgba(0,0,0,0.7)",strokeWidth:2,className:"neighbor-blink-ring"}),i&&a.jsx("circle",{cx:s,cy:n,r:10.5,fill:l,opacity:.3}),a.jsx("circle",{cx:s,cy:n,r:i?7:5,fill:l,stroke:D?"rgba(0,0,0,0.5)":"rgba(0,0,0,0.25)",strokeWidth:1,style:{cursor:"pointer",transition:"r 0.15s"},onMouseEnter:()=>ce(e),onMouseLeave:()=>ce(null)})]},e.hash)})})]})]}),u&&a.jsxs("div",{className:"absolute bg-tooltip-bg border border-edge-subtle rounded-lg px-3 py-2 text-sm pointer-events-none z-10 shadow-xl",style:{left:"50%",bottom:8,transform:"translateX(-50%)"},children:[a.jsx("div",{className:"font-medium text-fg-primary",children:u.name}),a.jsx("div",{className:"type-data-xs text-fg-secondary",children:u.hash}),null!==u.snr?a.jsx("div",{className:"flex gap-3 mt-1 text-xs",children:a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"SNR:"})," ",a.jsxs("span",{className:"tabular-nums",style:{color:lt(u.snr,L,z)},children:[u.snr.toFixed(1)," dB"]}),a.jsxs("span",{className:"text-fg-secondary ml-1",children:["(",(pe=u.snr,(null==(ge=nt.find(e=>pe>=e.min))?void 0:ge.label)??"Critical"),")"]})]})}):a.jsx("div",{className:"text-xs text-fg-secondary mt-1",children:"No SNR data"}),a.jsxs("div",{className:"flex gap-3 text-xs",children:[a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"Distance:"})," ",a.jsxs("span",{className:"tabular-nums text-fg-primary",children:[u.distance.toFixed(2)," km"]})]}),a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"Bearing:"})," ",a.jsxs("span",{className:"tabular-nums text-fg-primary",children:[u.bearing.toFixed(0),"°"]})]})]})]})]}),a.jsxs("div",{className:"flex flex-col gap-1 px-1.5 py-2 flex-shrink-0 depth-raised radius-inset self-stretch",style:{width:"calc(100% / 6)"},children:[o&&a.jsxs("div",{className:"flex flex-col items-center gap-1 pb-2 border-b border-edge-subtle mb-1",children:[a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:a.jsx(Y,{className:"w-3.5 h-3.5"})}),c&&a.jsx(d,{color:"zinc",children:c})]}),a.jsx("span",{className:"type-micro text-center text-[10px] leading-tight",children:o})]}),a.jsx("div",{className:"flex flex-col gap-1 flex-1",role:"group","aria-label":"Zoom level",children:["1x","2x","4x","8x","16x","36x"].map(e=>a.jsx("button",{onClick:()=>de(e),"aria-pressed":k===e,className:"flex flex-1 items-center justify-center min-w-[44px] sm:min-w-[32px] text-xs font-medium radius-inner depth-stroke-raised transition-colors "+(k===e?"bg-sys-blue/20 text-sys-blue":"bg-subtle-fill/80 text-fg-secondary hover:bg-subtle-fill-strong hover:text-fg-primary"),children:e},e))})]})]}):a.jsxs("div",{ref:F,className:"flex flex-col items-center justify-center h-full text-fg-secondary",children:[a.jsx(Y,{className:"w-8 h-8 mb-2 opacity-50"}),a.jsx("p",{children:"Local node coordinates not configured"}),a.jsx("p",{className:"text-xs mt-1",children:"Set latitude/longitude in config to enable"})]});var pe,ge}),rt={repeater:"var(--sys-blue)",companion:"var(--sys-cyan)",room_server:"var(--sys-indigo)"};function ot(e){if(e.contact_type){const t=e.contact_type.toLowerCase();if("repeater"===t||"rep"===t)return"repeater";if("room server"===t||"room_server"===t||"room"===t||"server"===t)return"room_server";if("companion"===t||"client"===t||"cli"===t)return"companion"}return e.is_repeater?"repeater":"companion"}const ct=s.memo(function({neighbors:e}){const t=s.useMemo(()=>{const t={repeater:0,companion:0,room_server:0};for(const a of Object.values(e)){const e=ot(a);t[e]=(t[e]||0)+1}const s=Object.values(t).reduce((e,t)=>e+t,0);return{items:[{label:"Repeaters",count:t.repeater,percent:0,color:rt.repeater},{label:"Companions",count:t.companion,percent:0,color:rt.companion},{label:"Room Servers",count:t.room_server,percent:0,color:rt.room_server}].map(e=>({...e,percent:s>0?e.count/s*100:0})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count),total:s}},[e]);return 0===t.total?a.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted type-body-sm",children:"No neighbors discovered yet"}):a.jsxs("div",{className:"h-full flex flex-col",children:[a.jsx("div",{className:"flex-1 flex flex-col justify-evenly",children:t.items.map(e=>a.jsxs("div",{className:"flex flex-col gap-1.5",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx("span",{className:"type-data-sm text-fg-secondary",children:e.label}),a.jsxs("span",{className:"type-data-sm text-fg-secondary tabular-nums",children:[e.count," ",a.jsxs("span",{className:"text-fg-secondary/60",children:["(",e.percent.toFixed(0),"%)"]})]})]}),a.jsx("div",{className:"h-2.5 bg-subtle-fill/80 overflow-hidden rounded-full depth-stroke-inset",children:a.jsx("div",{className:"h-full rounded-full transition-all duration-500 ease-out",style:{width:`${e.percent}%`,backgroundColor:e.color,minWidth:e.count>0?"4px":"0"}})})]},e.label))}),a.jsxs("div",{className:"flex items-center justify-between pt-2 border-t border-edge-subtle",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Total Nodes"}),a.jsx("span",{className:"type-data-sm text-fg-primary font-medium tabular-nums",children:t.total})]})]})});function dt({children:e,minHeight:t="100%",rootMargin:n="200px 0px",keepMounted:l=!0,className:i=""}){const r=s.useRef(null),[o,c]=s.useState(!1),[d,m]=s.useState(!1);s.useEffect(()=>{const e=r.current;if(!e)return;const t=new IntersectionObserver(([e])=>{const t=e.isIntersecting;m(t),t&&c(!0)},{rootMargin:n,threshold:0});return t.observe(e),()=>{t.disconnect()}},[n]);const u=d||l&&o;return a.jsx("div",{ref:r,className:`h-full w-full ${i}`,style:{minHeight:t},children:u?e:a.jsx("div",{className:"h-full w-full flex items-center justify-center text-fg-muted/50",children:a.jsx("div",{className:"animate-pulse text-xs",children:"Loading chart..."})})})}const mt=[{target:"DisambiguationCard",fn:"disambiguation.collisions",minStage:2}];ne(mt);const ut={excellent:"text-signal-excellent",good:"text-signal-good",fair:"text-signal-fair",poor:"text-sys-blue"},ht={excellent:"bg-signal-excellent/10",good:"bg-signal-good/10",fair:"bg-signal-fair/10",poor:"bg-sys-blue/10"};function xt(){se(mt);const e=N(),t=w(),[n,l]=s.useState(null),i=s.useCallback((e,t)=>{l({prefix:e,candidateHashes:t})},[]),r=s.useCallback(()=>{l(null)},[]);if(!t)return a.jsxs(re,{neomorphic:!0,children:[a.jsx(k,{icon:a.jsx(K,{}),title:"Prefix Conflicts"}),a.jsx("div",{className:"flex-1 flex items-center justify-center",children:a.jsxs("div",{className:"text-center text-fg-secondary",children:[a.jsx(X,{className:"w-8 h-8 mx-auto mb-2 opacity-50"}),a.jsx("p",{className:"type-data-xs",children:"No topology data available"}),a.jsx("p",{className:"type-data-xs opacity-70",children:"Run deep analysis to see stats"})]})})]});const o=(c=e.avgConfidence)>=.9?"excellent":c>=.7?"good":c>=.5?"fair":"poor";var c;const m=(u=e.collisionRate)<=10?"excellent":u<=25?"good":"poor";var u;const h="poor"===o||"poor"===m?"poor":"fair"===o||"fair"===m?"fair":"good"===o||"good"===m?"good":"excellent",x="excellent"===h||"good"===h?J:U;return a.jsxs(re,{neomorphic:!0,className:"flex flex-col overflow-hidden",children:[a.jsx(k,{icon:a.jsx(K,{}),title:"Prefix Conflicts",badgeColor:"zinc",actions:"poor"===h?a.jsxs(d,{color:"red",children:[a.jsx(U,{className:"w-3 h-3"}),"Needs Attention"]}):a.jsxs("div",{className:`flex items-center gap-1.5 px-2.5 py-1 rounded-full ${ht[h]}`,children:[a.jsx(x,{className:`w-3.5 h-3.5 ${ut[h]}`}),a.jsx("span",{className:`type-data-xs font-medium ${ut[h]}`,children:"excellent"===h?"Excellent":"good"===h?"Good":"Fair"})]})}),a.jsxs("div",{className:"flex-1 flex flex-col min-h-0",children:[a.jsxs("div",{className:"flex gap-2 sm:gap-3 py-3 sm:py-4",children:[a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Total unique 2-character prefixes observed in packet paths.",children:[a.jsx("span",{className:"type-data-xl text-fg-primary",children:a.jsx(ue,{value:e.totalPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Prefixes"})]}),a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Prefixes that map to exactly one known node. No disambiguation needed.",children:[a.jsx("span",{className:"type-data-xl text-fg-primary",children:a.jsx(ue,{value:e.unambiguousPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Unique"})]}),a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Prefixes matching multiple known nodes. Click a prefix below to explore candidates.",children:[a.jsx("span",{className:"type-data-xl "+(e.collisionPrefixes>0?"text-sys-blue":"text-fg-primary"),children:a.jsx(ue,{value:e.collisionPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro mt-0.5 sm:mt-1 "+(e.collisionPrefixes>0?"text-sys-blue":"text-fg-muted"),children:"Conflicts"})]})]}),e.highCollisionPrefixes.length>0&&a.jsxs("div",{className:"pt-2",children:[a.jsx("div",{className:"type-data-xs text-fg-secondary mb-1.5",children:"Problem Prefixes"}),a.jsx("div",{className:"flex flex-wrap gap-1.5 content-start",children:e.highCollisionPrefixes.map(({prefix:e,candidateCount:t,candidateHashes:s})=>a.jsxs("button",{type:"button",onClick:()=>i(e,s),className:"inline-flex items-center gap-0.5 group",title:`${t} candidates - click to explore`,children:[a.jsx(me,{children:e}),a.jsxs("span",{className:"text-fg-muted type-data-xs group-hover:text-fg-secondary transition-colors",children:["×",t]})]},e))})]}),0===e.lowConfidencePrefixes.length&&0===e.collisionPrefixes&&a.jsx("div",{className:"flex-1 flex items-center",children:a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx(J,{className:"w-3.5 h-3.5 text-signal-excellent"}),a.jsx("span",{className:"type-data-xs text-signal-excellent",children:"All prefixes uniquely identified"})]})}),a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 mt-auto pt-1.5",children:[a.jsxs("div",{className:"flex items-center gap-2 cursor-help",title:"Average confidence score across all disambiguated prefixes. Higher = more certain node identification.",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Confidence"}),a.jsxs("span",{className:`data-box ${ut[o]}`,children:[(100*e.avgConfidence).toFixed(1),"%"]})]}),a.jsxs("div",{className:"flex items-center gap-2 cursor-help",title:"Percentage of 2-character prefixes that match multiple known nodes. Lower is better.",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Collisions"}),a.jsxs("span",{className:`data-box ${ut[m]}`,children:[e.collisionRate.toFixed(1),"%"]})]})]})]}),a.jsx(he,{isOpen:!!n,prefix:(null==n?void 0:n.prefix)||"",candidateHashes:(null==n?void 0:n.candidateHashes)||[],onClose:r})]})}const pt=[{target:"PacketHealth",fn:"type",minStage:1},{target:"PacketHealth",fn:"duplicates",minStage:1}];ne(pt);const gt=new Set(["Duplicate","Empty payload","Path too long","Unknown"]),ft={excellent:"bg-status-success",good:"bg-sys-blue",fair:"bg-status-warning",poor:"bg-status-danger"};function bt({packets:e,rangeMinutes:t,rangeHours:n,timeRangeLabel:l,isLoaded:i=!0}){se(pt);const r=s.useMemo(()=>function(e,t){const s=Date.now()/1e3,a=60*t,n=s-a,l=a/24,i=new Array(24).fill(0),r=new Array(24).fill(0);let o=0,c=0,d=0,m=0;for(const h of e){if("tx_local"===h.packet_origin)continue;const e=h.timestamp;if(es)continue;o++;const t=Math.min(23,Math.floor((e-n)/l));r[t]++,h.transmitted||"tx_forward"===h.packet_origin?(c++,i[t]++):(h.is_duplicate||"Duplicate"===h.drop_reason)&&d++,h.drop_reason&>.has(h.drop_reason)&&m++}const u=[];for(let h=0;h<24;h++){const e=r[h],t=i[h];u.push({count:e>0?Math.round(t/e*100):0,timestamp:1e3*(n+h*l)})}return{totalRx:o,forwarded:c,duplicates:d,waste:m,efficiency:o>0?c/o*100:0,duplicateRate:o>0?d/o*100:0,wasteRate:o>0?m/o*100:0,sparkline:u}}(e,t),[e,t]),[o,c]=s.useState(null),d=s.useCallback(async()=>{try{const e=await M(n);e.success&&e.data&&c(e.data.count)}catch{}},[n]);s.useEffect(()=>{d()},[d]);const m=(u=r.efficiency)>=90?"excellent":u>=75?"good":u>=60?"fair":"poor";var u;const h=r.totalRx>0;return a.jsx(re,{neomorphic:!0,isLoaded:i,skeletonType:"chart",children:i&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(Q,{}),title:"Packet Health",badge:l,badgeColor:"zinc"}),a.jsx(S,{children:a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex items-baseline gap-2",children:[a.jsxs("div",{className:"type-data-xl text-fg-primary",children:[h?a.jsx(ue,{value:Math.round(10*r.efficiency)/10,className:"font-mono tabular-nums",priority:"medium",format:{minimumFractionDigits:1,maximumFractionDigits:1}}):a.jsx("span",{className:"opacity-30",children:"—"}),a.jsx("span",{className:"type-data-sm text-fg-muted ml-0.5",children:"%"})]}),h&&a.jsx("div",{className:`w-2 h-2 rounded-full ${ft[m]}`})]}),a.jsx("div",{className:"type-micro mb-2 cursor-help",title:"Forwarded packets / total received. CRC failures, garbled packets, and RF collisions that destroy packets before reaching software are not included in this ratio — see CRC Errors for hardware-level failures.",children:"FORWARDING RATE"}),a.jsx("div",{className:"flex-1 min-h-[28px] max-h-[48px] mb-2",children:a.jsx(xe,{data:r.sparkline,width:9999,height:36,color:"var(--sys-blue)",className:"w-full"})}),a.jsxs("div",{className:"flex gap-2 sm:gap-3 mt-auto",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"data-box-label",children:"Dupes"}),a.jsx("div",{className:"data-box data-box-fill data-box-left",children:h?`${r.duplicateRate.toFixed(1)}%`:"—"})]}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"data-box-label",children:"Waste"}),a.jsx("div",{className:"data-box data-box-fill data-box-left",children:h?`${r.wasteRate.toFixed(1)}%`:"—"})]}),null!==o&&o>0&&a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsxs("div",{className:"data-box-label flex items-center gap-1",children:[a.jsx(U,{className:"w-3 h-3 text-status-warning"}),"CRC"]}),a.jsx("div",{className:"data-box data-box-fill data-box-left text-status-warning",children:o})]})]})]})})]})})}function yt(){var e,t,n,l,i,r,o,c,d,m,u,h,x,p,g,f,b;const y=C(),j=T(),v=A(),N=F(),w=P(),M=L(),S=null!==y&&w,H=s.useRef(!1);S&&!H.current&&(H.current=!0);const O=H.current,W=R(),q=$(),I=D(),[G,V]=s.useState(null),[,Y]=s.useState(null),[K]=s.useState(null),[X,U]=s.useState(()=>{const e=localStorage.getItem("statistics-view-mode");return"share"===e||"airtime"===e?e:"airtime"});s.useEffect(()=>{localStorage.setItem("statistics-view-mode",X)},[X]);const[J,Q]=s.useState(()=>{const e=localStorage.getItem("statistics-smoothing-mode");return["ema","ultra","mosaic","stats","trend"].includes(e)?e:"stats"});s.useEffect(()=>{localStorage.setItem("statistics-smoothing-mode",J)},[J]);const[se,ae]=s.useState(!1),[ne,le]=s.useState(!1),[me,ue]=s.useState(ve),[he,xe]=s.useState(.5),[Me,Se]=s.useState(pe),[Ce,Te]=s.useState(.8),[Ae,Fe]=s.useState(50),Pe=s.useMemo(()=>({0:0,1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9}[W]??3),[W]),Le=_[Pe].hours,Re=60*Le,$e=_[Pe],De=z(Le),_e=M.isBackgroundLoading,ze=s.useCallback(e=>{q({0:1,1:2,2:3,3:4,4:5,5:6,6:7,7:8,8:9,9:10}[e]??4)},[q]),Ee=s.useMemo(()=>{var e;if(!(null==(e=null==y?void 0:y.config)?void 0:e.radio))return null;const t=y.config.radio;return{sf:t.spreading_factor??10,bw:t.bandwidth??25e4,cr:t.coding_rate??5,preamble:t.preamble_length??8}},[null==(t=null==(e=null==y?void 0:y.config)?void 0:e.radio)?void 0:t.spreading_factor,null==(l=null==(n=null==y?void 0:y.config)?void 0:n.radio)?void 0:l.bandwidth,null==(r=null==(i=null==y?void 0:y.config)?void 0:i.radio)?void 0:r.coding_rate,null==(c=null==(o=null==y?void 0:y.config)?void 0:o.radio)?void 0:c.preamble_length]),We=s.useMemo(()=>0===I.length?{timestamps:[],values:[]}:{timestamps:I.map(e=>e.timestamp),values:I.map(e=>e.noise_floor_dbm)},[I]),qe=s.useMemo(()=>{if(I.length<10)return{anomalies:[],debug:void 0};const e=function(e,t={}){const s={...ve,...t};if(e.length<10)return{anomalies:[],thresholds:we([]),totalSamples:e.length,anomalySamples:0};const a=e.map(e=>e.noise_floor_dbm),n=we(a),l=[...a].sort((e,t)=>e-t);let i,r;s.useAbsoluteThresholds?(i=s.baselineDbm,r=s.spikeDbm):(i=Ne(l,s.baselinePercentile),r=Ne(l,s.spikePercentile));const o=[...e].sort((e,t)=>e.timestamp-t.timestamp),c=[];let d=null,m=0;for(const u of o)if(u.noise_floor_dbm>i&&u.noise_floor_dbme+t,0)/d.values.length):(d.values.length>=s.minSequenceLength&&c.push(d),d={startTs:u.timestamp,endTs:u.timestamp,values:[u.noise_floor_dbm],timestamps:[u.timestamp],rollingAvg:u.noise_floor_dbm})}else d={startTs:u.timestamp,endTs:u.timestamp,values:[u.noise_floor_dbm],timestamps:[u.timestamp],rollingAvg:u.noise_floor_dbm};else d&&d.values.length>=s.minSequenceLength&&c.push(d),d=null;return d&&d.values.length>=s.minSequenceLength&&c.push(d),0===c.length?{anomalies:[],thresholds:n,totalSamples:e.length,anomalySamples:m,debug:{baselineCutoff:i,spikeCutoff:r,midBandSamples:m}}:{anomalies:c.map(e=>{const t=Math.max(...e.values),s=e.values.reduce((e,t)=>e+t,0)/e.values.length;return{startTs:e.startTs,endTs:e.endTs,peakValue:t,avgValue:s,severity:ke(s,i,r),sampleCount:e.values.length}}),thresholds:n,totalSamples:e.length,anomalySamples:m,debug:{baselineCutoff:i,spikeCutoff:r,midBandSamples:m}}}(I,me);return{anomalies:e.anomalies,debug:e.debug}},[I,me]),Ie=qe.anomalies,Ge=s.useMemo(()=>{const e=(null==y?void 0:y.neighbors)??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!j.has(e)))},[null==y?void 0:y.neighbors,j]),Ve=s.useMemo(()=>{const e=Date.now()/1e3-3600*Le;return Object.fromEntries(Object.entries(Ge).filter(([,t])=>t.last_seen>=e))},[Ge,Le]),Ye=s.useMemo(()=>{const e=60*Re/De,t=Math.floor(Date.now()/1e3),s=Math.floor(t/e)*e;return{start:s-60*Re,end:s}},[Re,De]),Ke=Me.timeStart??Ye.start,Xe=Me.timeEnd??Ye.end,Je=z((Xe-Ke)/3600),Qe=be(),Ze=s.useMemo(()=>ge(N,Me,Qe,Ye),[N,Me,Qe,Ye]);return a.jsxs(oe,{children:[a.jsx(ce,{title:"Statistics",icon:a.jsx(Z,{}),controls:a.jsx(ie,{ranges:_,selectedIndex:Pe,onSelect:ze,isPending:_e})}),K&&a.jsx(re,{className:"border border-sys-red/50 bg-sys-red/10",children:a.jsx("p",{className:"text-sys-red",children:K})}),se&&ne&&a.jsxs(re,{className:"border border-sys-indigo/30 bg-surface/50",children:[a.jsxs("div",{className:"flex items-center justify-between mb-3",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"type-label",children:"Anomaly Detection Tuning"}),a.jsxs("span",{className:"type-data-xs text-fg-muted",children:["(",$e.label,")"]})]}),a.jsx("button",{onClick:()=>ue(e=>({...e,useAbsoluteThresholds:!e.useAbsoluteThresholds})),className:"type-data-xs px-2 py-1 rounded transition-colors "+(me.useAbsoluteThresholds?"bg-sys-indigo/30 text-sys-indigo":"bg-elevated text-fg-muted hover:text-fg-secondary"),children:me.useAbsoluteThresholds?"Absolute dBm":"Percentile"})]}),a.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Baseline"}),a.jsxs("span",{className:"ml-2 type-data-sm text-status-warning",children:[(null==(m=null==(d=qe.debug)?void 0:d.baselineCutoff)?void 0:m.toFixed(1))??"—"," dBm"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Spike"}),a.jsxs("span",{className:"ml-2 type-data-sm text-status-warning",children:[(null==(h=null==(u=qe.debug)?void 0:u.spikeCutoff)?void 0:h.toFixed(1))??"—"," dBm"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Mid-band"}),a.jsx("span",{className:"ml-2 type-data-sm text-sys-indigo",children:(null==(x=qe.debug)?void 0:x.midBandSamples)??0})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Anomalies"}),a.jsx("span",{className:"ml-2 type-data-sm text-status-danger",children:Ie.length})]})]}),a.jsxs("div",{className:"mt-4 pt-4 border-t border-edge-subtle space-y-4",children:[me.useAbsoluteThresholds?a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Baseline (",me.baselineDbm," dBm)"]}),a.jsx("input",{type:"range",min:"-120",max:"-60",value:me.baselineDbm,onChange:e=>ue(t=>({...t,baselineDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Spike (",me.spikeDbm," dBm)"]}),a.jsx("input",{type:"range",min:"-100",max:"-20",value:me.spikeDbm,onChange:e=>ue(t=>({...t,spikeDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Merge Gap (",me.mergeGapSeconds,"s)"]}),a.jsx("input",{type:"range",min:"5",max:"120",step:"5",value:me.mergeGapSeconds,onChange:e=>ue(t=>({...t,mergeGapSeconds:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Min Sequence (",me.minSequenceLength,")"]}),a.jsx("input",{type:"range",min:"2",max:"20",value:me.minSequenceLength,onChange:e=>ue(t=>({...t,minSequenceLength:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Similarity (±",me.similarityToleranceDbm," dBm)"]}),a.jsx("input",{type:"range",min:"1",max:"15",value:me.similarityToleranceDbm,onChange:e=>ue(t=>({...t,similarityToleranceDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Opacity (",Math.round(100*he),"%)"]}),a.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:he,onChange:e=>xe(Number(e.target.value)),className:"w-full accent-sys-indigo"})]})]})]}):a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Baseline (P",me.baselinePercentile,")"]}),a.jsx("input",{type:"range",min:"1",max:"50",value:me.baselinePercentile,onChange:e=>ue(t=>({...t,baselinePercentile:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Spike (P",me.spikePercentile,")"]}),a.jsx("input",{type:"range",min:"50",max:"99",value:me.spikePercentile,onChange:e=>ue(t=>({...t,spikePercentile:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Merge Gap (",me.mergeGapSeconds,"s)"]}),a.jsx("input",{type:"range",min:"5",max:"120",step:"5",value:me.mergeGapSeconds,onChange:e=>ue(t=>({...t,mergeGapSeconds:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Min Sequence (",me.minSequenceLength,")"]}),a.jsx("input",{type:"range",min:"2",max:"20",value:me.minSequenceLength,onChange:e=>ue(t=>({...t,minSequenceLength:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Similarity (±",me.similarityToleranceDbm," dBm)"]}),a.jsx("input",{type:"range",min:"1",max:"15",value:me.similarityToleranceDbm,onChange:e=>ue(t=>({...t,similarityToleranceDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Opacity (",Math.round(100*he),"%)"]}),a.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:he,onChange:e=>xe(Number(e.target.value)),className:"w-full accent-sys-indigo"})]})]})]}),a.jsxs("div",{className:"mt-4 p-3 bg-elevated radius-inner",children:[a.jsx("div",{className:"type-micro mb-1",children:"Config output"}),a.jsxs("div",{className:"type-data-sm text-status-success",children:[me.useAbsoluteThresholds?`useAbsoluteThresholds: true, baselineDbm: ${me.baselineDbm}, spikeDbm: ${me.spikeDbm}`:`useAbsoluteThresholds: false, baselinePercentile: ${me.baselinePercentile}, spikePercentile: ${me.spikePercentile}`,", mergeGapSeconds: ",me.mergeGapSeconds,", minSequenceLength: ",me.minSequenceLength,", similarityToleranceDbm: ",me.similarityToleranceDbm]})]})]})]}),a.jsxs(de,{children:[a.jsx("div",{className:"sm:hidden",children:_e&&a.jsx(ye,{template:"auto",children:a.jsx(re,{className:"border border-sys-blue/30 bg-sys-blue/5",children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsxs("div",{className:"relative flex h-3 w-3",children:[a.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-sys-blue opacity-75"}),a.jsx("span",{className:"relative inline-flex rounded-full h-3 w-3 bg-sys-blue"})]}),a.jsxs("div",{className:"flex-1",children:[a.jsxs("p",{className:"type-body-sm text-fg-primary",children:["Loading ",$e.label," data..."]}),M.loadProgress&&a.jsxs("p",{className:"type-data-xs text-fg-muted mt-0.5",children:[M.loadProgress.loaded.toLocaleString()," packets (",M.loadProgress.percent,"%)"]})]})]})})})}),O?a.jsxs(a.Fragment,{children:[a.jsx(ye,{template:"hero-auto",children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(B,{}),title:"Packet Analyzer",badge:$e.label,badgeColor:"zinc",stackActionsOnMobile:!0,actions:a.jsxs("div",{className:"flex flex-wrap items-center gap-2 justify-end",children:["stats"===J&&a.jsx(Oe,{enabled:se,onChange:ae,anomalyCount:Ie.length,showTuning:ne,onTuningChange:le}),a.jsx(Be,{smoothing:J,onChange:Q}),a.jsx(He,{mode:X,onChange:U})]})}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(Ue,{packets:Ze,allPackets:N,startTs:Ke,endTs:Xe,parentStartTs:Ye.start,parentEndTs:Ye.end,bucketCount:Je,radioConfig:Ee??void 0,mode:X,smoothing:J,noiseFloorAnomalies:Ie,showNoiseFloorOverlay:se,overlayOpacity:he,dotSize:Ce,dotOpacity:Ae/100})})]})})}),a.jsx(ye,{template:"auto",className:"relative z-10",children:a.jsx(re,{neomorphic:!0,noPadding:!0,isLoaded:O,className:"overflow-visible",children:O&&a.jsx(fe,{parentStartTs:Ye.start,parentEndTs:Ye.end,neighbors:Ge,filter:Me,onChange:Se,..."stats"===J?{scatterDotSize:Ce,onScatterDotSizeChange:Te,scatterOpacity:Ae,onScatterOpacityChange:Fe}:{}})})}),a.jsxs(ye,{template:"panel",children:[a.jsx(je,{span:12,md:6,children:a.jsx(re,{neomorphic:!1,isLoaded:O,skeletonType:"chart",noPadding:O,className:"!bg-transparent !ring-0 !shadow-none !overflow-visible -mx-4 sm:mx-0 !px-0 !pr-0",children:O&&a.jsx(dt,{children:a.jsx(it,{neighbors:Ve,quickNeighbors:v,localLat:(null==(g=null==(p=null==y?void 0:y.config)?void 0:p.repeater)?void 0:g.latitude)??0,localLon:(null==(b=null==(f=null==y?void 0:y.config)?void 0:f.repeater)?void 0:b.longitude)??0,onStatsChange:Y,title:"Link Quality",badge:$e.label})})})}),a.jsx(je,{span:12,md:6,children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(ee,{}),title:"Network Composition",badge:$e.label,badgeColor:"zinc"}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(dt,{children:a.jsx(ct,{neighbors:Ve})})})]})})})]}),a.jsxs(ye,{template:"panel",children:[a.jsx(je,{span:12,md:6,children:a.jsx(xt,{})}),a.jsx(je,{span:12,md:6,children:a.jsx(bt,{packets:N,rangeMinutes:Re,rangeHours:Le,timeRangeLabel:$e.label,isLoaded:O})})]}),a.jsx(ye,{template:"panel",children:a.jsx(je,{span:12,children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(te,{}),title:"NOISE FLOOR dBm",stackActionsOnMobile:!0,actions:G?a.jsxs("div",{className:"flex items-center gap-2 sm:gap-3",children:[a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["min ",a.jsx("span",{className:"data-box",children:G.min.toFixed(0)})]}),a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["avg ",a.jsx("span",{className:"data-box",children:G.avg.toFixed(0)})]}),a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["max ",a.jsx("span",{className:"data-box",children:G.max.toFixed(0)})]})]}):null}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(dt,{children:a.jsx(E,{timestamps:We.timestamps,values:We.values,onStatsChange:V})})})]})})})})]}):a.jsx(ye,{template:"auto",children:a.jsx(re,{neomorphic:!0,className:"text-center py-12",children:a.jsx("div",{className:"animate-pulse text-fg-muted",children:"Loading statistics..."})})})]})]})}export{yt as default}; +var e=Object.defineProperty,t=(t,s,a)=>((t,s,a)=>s in t?e(t,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[s]=a)(t,"symbol"!=typeof s?s+"":s,a);import{r as s,j as a}from"./vendor-react-alRNW2nb.js";import{c as n,a3 as l,aH as i,aI as r,aJ as o,aK as c,h as d,aL as m,aM as u,u as h,aN as x,aO as p,aP as g,aQ as f,aR as b,ag as y,aS as j,ai as v,aT as N,aU as w,q as k,aV as M,aW as S,p as C,t as T,r as A,m as F,a0 as P,a1 as L,v as R,W as $,aX as D,aY as _,aZ as z,a_ as E}from"./index-CkRTgHHA.js";import{c as H}from"./vendor-core-FtpmsTnh.js";import{a4 as B,aB as O,u as W,aC as q,aD as I,aE as G,aF as V,aG as Y,H as K,I as X,a3 as U,aH as J,a7 as Q,g as Z,ak as ee,R as te}from"./vendor-icons-TO0PZKGR.js";import{u as se,h as ae,r as ne}from"./consumer-registry-BUFl6buY.js";import{e as le}from"./easing-GXZYrvDD.js";import{T as ie}from"./TimeRangeStepper-CsLZzi5t.js";import{C as re,P as oe,a as ce,B as de}from"./PageLayout-BWMUVZgC.js";import{D as me}from"./DataBox-DpDXI-WX.js";import{A as ue}from"./AnimatedNumber-DACuG-ay.js";import{C as he}from"./CollisionExplorerModal-BUHEIiWh.js";import{L as xe}from"./LightSparkline-BAD3v4m9.js";import{c as pe,a as ge,A as fe}from"./AnalyzerFilterPanel-o1lp_Gs8.js";import{a as be}from"./usePipelineStore-CLEA3Bev.js";import{R as ye,C as je}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";import"./maplibre-gl-BwLPRSIs.js";import"./BasemapLayer-CSqjQAiA.js";import"./node-types-DRVunROD.js";import"./geo-utils-DJn8DnxF.js";const ve={useAbsoluteThresholds:!0,baselinePercentile:6,spikePercentile:50,baselineDbm:-107,spikeDbm:-100,mergeGapSeconds:45,minSequenceLength:16,similarityToleranceDbm:5};function Ne(e,t){if(0===e.length)return 0;const s=t/100*(e.length-1),a=Math.floor(s),n=Math.ceil(s);return a===n?e[a]:e[a]+(e[n]-e[a])*(s-a)}function we(e){if(0===e.length)return{median:0,p90:0,p95:0,p99:0,max:0,min:0};const t=[...e].sort((e,t)=>e-t);return{median:Ne(t,50),p90:Ne(t,90),p95:Ne(t,95),p99:Ne(t,99),max:t[t.length-1],min:t[0]}}function ke(e,t,s){const a=s-t;if(0===a)return"moderate";const n=(e-t)/a;return n>.66?"critical":n>.33?"severe":"moderate"}const Me=Object.entries(l).map(([e,t])=>{const s=parseInt(e,10);return{typeNum:s,key:`TYPE_${s}`,label:t}});function Se({sortedTypes:e,highlightedType:t,onTypeHover:l,aggregateShares:i,hoverData:r}){const o=s.useMemo(()=>{if(!r)return null;const e=new Map;for(const t of r.items)e.set(t.key,t.value);return e},[r]),c=null!==o,d=s.useMemo(()=>{const t=new Set(e.map(e=>e.key));return[...e.map(e=>({typeNum:e.typeNum,key:e.key,label:e.label})),...Me.filter(e=>!t.has(e.key))]},[e]);return a.jsxs("div",{className:"flex-shrink-0 pt-2 sm:pt-3 mt-1 sm:mt-2 px-0 sm:pr-0",children:[a.jsxs("div",{className:"flex items-center gap-2 mx-0 sm:ml-9 sm:mr-0 mb-1 sm:mb-1.5 type-data-xs",children:[a.jsx("span",{className:"text-fg-muted",children:"Packet Types"}),c&&(null==r?void 0:r.timeLabel)&&a.jsx("span",{className:"text-sys-indigo tabular-nums",children:r.timeLabel})]}),a.jsx("div",{className:"flex flex-wrap gap-x-3 sm:gap-x-4 gap-y-1 type-data-xs mx-0 sm:ml-9 sm:mr-0",onMouseLeave:()=>l(null),children:d.map(e=>{const s=n(e.typeNum),r=(null==o?void 0:o.get(e.key))??0,d=i.get(e.key)??0,m=c?r:d,u=m>1e-4,h=i.has(e.key),x=t===e.key,p=t&&!x||c&&r<=1e-4||!c&&!t&&!h;return a.jsxs("div",{className:H("flex items-center gap-1.5 transition-opacity cursor-pointer hover:opacity-80",p&&"opacity-30"),onMouseEnter:()=>l(e.key),children:[a.jsx("div",{className:"shrink-0 w-3 h-3 rounded-xs",style:{backgroundColor:s}}),a.jsx("span",{className:"text-fg-secondary whitespace-nowrap",children:e.label}),u&&a.jsxs("span",{className:H("tabular-nums",c?"text-fg-primary":"text-fg-muted"),children:[(100*m).toFixed(1),"%"]})]},e.key)})})]})}const Ce='ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace';function Te(e,t,s,a,n){const l=e.reduce((e,t)=>e+t,0);if(l<=0||0===e.length)return[];const i=e.map((e,t)=>t).sort((t,s)=>e[s]-e[t]),r=i.map(t=>e[t]),o=new Array(e.length);return Ae(r,i,l,t,s,a,n,o),o}function Ae(e,t,s,a,n,l,i,r){if(0===e.length)return;if(1===e.length)return void(r[t[0]]={x:a,y:n,w:l,h:i,index:t[0]});const o=l*i/s,c=l>=i,d=c?i:l;let m=0,u=1/0,h=0;for(let y=0;ys?a/s:s/a,n>s?n/s:s/n);if(!(l<=u))break;u=l,h=y+1,m=t}const x=d>0?m*o/d:0;let p=0;for(let y=0;y0?e[y]/m:0)*d;r[t[y]]=c?{x:a,y:n+p,w:x,h:s,index:t[y]}:{x:a+p,y:n,w:s,h:x,index:t[y]},p+=s}const g=e.slice(h),f=t.slice(h),b=s-m;c?Ae(g,f,b,a+x,n,l-x,i,r):Ae(g,f,b,a,n+x,l,i-x,r)}function Fe(e,t,s,a,l,i){for(const r of t){const t=s[r.index];if(!t)continue;const o=2*i,c=r.x*i+o/2,d=r.y*i+o/2,m=r.w*i-o,u=r.h*i-o;if(m<=0||u<=0)continue;const h=n(t.typeNum),x=null!==l&&l!==r.index;e.save(),e.globalAlpha=x?.4:1;const p=3*i;e.beginPath(),e.moveTo(c+p,d),e.lineTo(c+m-p,d),e.quadraticCurveTo(c+m,d,c+m,d+p),e.lineTo(c+m,d+u-p),e.quadraticCurveTo(c+m,d+u,c+m-p,d+u),e.lineTo(c+p,d+u),e.quadraticCurveTo(c,d+u,c,d+u-p),e.lineTo(c,d+p),e.quadraticCurveTo(c,d,c+p,d),e.closePath(),e.fillStyle=h,e.fill(),e.strokeStyle="rgba(0,0,0,0.2)",e.lineWidth=1*i,e.stroke();const g=4*i,f=r.w>36&&r.h>20,b=r.w>36&&r.h>32;if(f){const s=11*i;if(b){const n=a>0?t.size/a*100:0;e.font=`500 ${8*i}px ${Ce}`,e.fillStyle="rgba(0,0,0,0.6)",e.textBaseline="alphabetic",e.textAlign="left",e.fillText(`${n.toFixed(1)}%`,c+g,d+u-g-s)}e.font=`600 ${9*i}px ${Ce}`,e.fillStyle="rgba(0,0,0,0.85)",e.textBaseline="alphabetic",e.textAlign="left",e.fillText(t.name,c+g,d+u-g)}e.restore()}}function Pe({data:e,total:t,color:s,position:n,containerWidth:l,isAirtime:i}){if(!e||!n)return null;const r=(e.value/t*100).toFixed(1),o=l-n.x<184?Math.max(8,n.x-160-8):n.x+16;return a.jsx("div",{className:"absolute z-50 pointer-events-none",style:{left:o,top:Math.max(8,n.y-60)},children:a.jsxs("div",{className:"bg-tooltip-bg border border-edge-subtle rounded-lg px-3 py-2 shadow-xl min-w-[140px]",children:[a.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[a.jsx("span",{className:"w-2.5 h-2.5 rounded-sm flex-shrink-0",style:{backgroundColor:s}}),a.jsx("span",{className:"type-data-sm font-semibold text-fg-primary",children:e.name})]}),a.jsxs("div",{className:"space-y-0.5 type-data-xs text-fg-muted",children:[a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:i?"Airtime":"Count"}),a.jsx("span",{className:"text-fg-primary tabular-nums font-medium",children:i?Le(e.value):e.value.toLocaleString()})]}),a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:"Share"}),a.jsxs("span",{className:"text-fg-primary tabular-nums font-medium",children:[r,"%"]})]}),a.jsxs("div",{className:"flex justify-between gap-4",children:[a.jsx("span",{children:"Total"}),a.jsx("span",{className:"text-fg-primary tabular-nums font-medium",children:i?Le(t):t.toLocaleString()})]})]})]})})}function Le(e){return e>=6e4?`${(e/6e4).toFixed(1)}m`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${Math.round(e)}ms`}function Re({sortedTypes:e,aggregateShares:t,mode:l="share"}){var i,r,o;const[c,d]=s.useState(null),[m,u]=s.useState(null),[h,x]=s.useState(0),[p,g]=s.useState(null),f=s.useRef(null),b=s.useRef(null),y=s.useRef([]),j="airtime"===l,v=s.useMemo(()=>e.reduce((e,t)=>e+(j?t.totalAirtime:t.totalCount),0),[e,j]),N=s.useMemo(()=>e.map((e,t)=>({name:e.label,size:j?e.totalAirtime:e.totalCount,index:t,typeNum:e.typeNum,key:e.key})),[e,j]);s.useEffect(()=>{const e=b.current;if(!e)return;const t=e.parentElement;if(!t)return;const s=t.getBoundingClientRect(),a=s.width,n=s.height;if(a<=0||n<=0)return;const l=window.devicePixelRatio||1;e.width=Math.floor(a*l),e.height=Math.floor(n*l),e.style.width=`${a}px`,e.style.height=`${n}px`;const i=Te(N.map(e=>e.size),0,0,a,n);y.current=i;const r=e.getContext("2d");r&&(r.clearRect(0,0,e.width,e.height),Fe(r,i,N,v,c,l))},[N,v,c]),s.useEffect(()=>{const e=f.current;if(!e)return;const t=new ResizeObserver(()=>{const t=b.current;if(!t)return;const s=e.getBoundingClientRect(),a=s.width,n=s.height;if(a<=0||n<=0)return;const l=window.devicePixelRatio||1;t.width=Math.floor(a*l),t.height=Math.floor(n*l),t.style.width=`${a}px`,t.style.height=`${n}px`;const i=Te(N.map(e=>e.size),0,0,a,n);y.current=i;const r=t.getContext("2d");r&&(r.clearRect(0,0,t.width,t.height),Fe(r,i,N,v,c,l))});return t.observe(e),()=>t.disconnect()},[N,v]);const w=s.useCallback(e=>{const t=f.current;if(!t)return;const s=t.getBoundingClientRect(),a=e.clientX-s.left,n=e.clientY-s.top,l=function(e,t,s){for(const a of e)if(t>=a.x&&t<=a.x+a.w&&s>=a.y&&s<=a.y+a.h)return a.index;return null}(y.current,a,n);d(l),null!==l?(x(s.width),u({x:a,y:n})):u(null)},[]),k=s.useCallback(()=>{d(null),u(null)},[]),M=s.useCallback(e=>{if(g(e),e){const t=N.findIndex(t=>t.key===e);d(t>=0?t:null)}else d(null)},[N]),S=null!==c?{name:(null==(i=N[c])?void 0:i.name)??"",value:(null==(r=N[c])?void 0:r.size)??0}:null,C=null!==c?n(null==(o=N[c])?void 0:o.typeNum):"";return 0===e.length||0===v?a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet type data available"})]}):a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsx("div",{className:"flex-1 min-h-0 relative",children:a.jsxs("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},ref:f,onMouseMove:w,onMouseLeave:k,children:[a.jsx("canvas",{ref:b,className:"absolute inset-0",style:{cursor:"default"}}),a.jsx(Pe,{data:S,total:v,color:C,position:m,containerWidth:h,isAirtime:j})]})}),a.jsx("div",{style:{minHeight:80},children:a.jsx(Se,{sortedTypes:e,highlightedType:p,onTypeHover:M,aggregateShares:t})})]})}function $e(e){return e>=1e9?`${(e/1e9).toFixed(1)} Gb`:e>=1e6?`${(e/1e6).toFixed(1)} Mb`:e>=1e3?`${(e/1e3).toFixed(1)} Kb`:`${e.toFixed(0)} B`}function De({packets:e,mode:t,startTs:n,endTs:l,radioConfig:m,bucketCount:u,lockedYMax:h,legendMinH:x}){const p=s.useMemo(()=>i(),[]),g=p.blue,f=p.red,b=p.yellow,[y,j]=s.useState(null),{trendData:v,totals:N}=s.useMemo(()=>{if(0===e.length)return{trendData:[],totals:{rxBytes:0,txBytes:0,rxAirtime:0,txAirtime:0}};const s=l-n,a=Math.min(Math.ceil(s/300),u),i=s/a,c=[];let d=0,h=0,x=0,p=0;for(const t of e){const e=t.timestamp;if(e=l)continue;const s=r(t),a=o(t,{spreadingFactor:m.sf,bandwidthHz:m.bw,codingRate:m.cr,preambleLength:m.preamble}),i={timestamp:e,rxAirtime:0,txAirtime:0,rxBytes:0,txBytes:0};t.transmitted?(i.txAirtime=a,i.txBytes=s,h+=s,p+=a):(i.rxAirtime=a,i.rxBytes=s,d+=s,x+=a),c.push(i)}c.sort((e,t)=>e.timestamp-t.timestamp);const g=new Float64Array(c.length+1),f=new Float64Array(c.length+1),b=new Float64Array(c.length+1),y=new Float64Array(c.length+1),j=new Float64Array(c.length);for(let e=0;e{let t=0,s=j.length;for(;t>>1;j[a]0?e:null,tx:t>0?t:null})}else{const e=(g[r]-g[l])/w*100,t=(f[r]-f[l])/w*100;N.push({timestamp:s,rx:e>0?e:null,tx:t>0?t:null})}}const k=2/31;let M=null;return{trendData:N.map(e=>{const t=e.rx;return null!==t&&t>0&&(M=null===M?t:k*t+(1-k)*M),{...e,rxSmooth:null!==M&&M>0?M:null}}),totals:{rxBytes:d,txBytes:h,rxAirtime:x,txAirtime:p}}},[e,n,l,u,t,m]),w=s.useMemo(()=>{if(0===v.length)return"share"===t?100:10;let e=0;for(const t of v){const s=t.rx??0,a=t.tx??0;s>e&&(e=s),a>e&&(e=a)}const s=1.1*e;return"share"===t?s<=100?100:s<=500?100*Math.ceil(s/100):s<=1e3?200*Math.ceil(s/200):s<=5e3?500*Math.ceil(s/500):s<=1e4?1e3*Math.ceil(s/1e3):5e3*Math.ceil(s/5e3):Math.max(1,Math.ceil(s))},[v,t]),k=h??w,M=s.useMemo(()=>{if(null!==y&&v[y]){const e=v[y],s=e.rx??0,a=e.tx??0;return"share"===t?{rx:$e(s),tx:$e(a),total:$e(s+a),isHovered:!0}:{rx:`${s.toFixed(2)}%`,tx:`${a.toFixed(2)}%`,total:`${(s+a).toFixed(2)}%`,isHovered:!0}}if("share"===t)return{rx:$e(N.rxBytes),tx:$e(N.txBytes),total:$e(N.rxBytes+N.txBytes),isHovered:!1};{let e=0,t=0,s=0;for(const l of v)null===l.rx&&null===l.tx||(e+=l.rx??0,t+=l.tx??0,s++);const a=s>0?e/s:0,n=s>0?t/s:0;return{rx:`${a.toFixed(2)}%`,tx:`${n.toFixed(2)}%`,total:`${(a+n).toFixed(2)}%`,isHovered:!1}}},[y,v,N,t]),S=s.useMemo(()=>{const e=l-n,t=e/3600;return[0,.25,.5,.75,1].map(s=>{const a=new Date(1e3*(n+e*s)),l=a.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}),i=a.toLocaleDateString([],{weekday:"short"});return{pct:s,label:t>=24?`${i} ${l}`:l,mobileHidden:.25===s||.75===s}})},[n,l]),C=s.useCallback(e=>{j(e)},[]);if(0===v.length)return a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]});const T=s.useMemo(()=>"airtime"===t?k<=5?1:k<=10?2:k<=20?5:Math.ceil(k/5):k<=100?25:k<=500?100:k<=1e3?200:k<=5e3?1e3:k<=1e4?2e3:1e3*Math.ceil(k/5e3),[k,t]),A=s.useMemo(()=>{const e=[];for(let s=0;s<=k;s+=T){const a=100*(1-s/k);let n;n="airtime"===t?`${s}%`:s>=1e6?`${(s/1e6).toFixed(1)}M`:s>=1e3?`${(s/1e3).toFixed(0)}K`:`${s}`,e.push({pos:a,label:n})}return e},[k,T,t]);return a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:A.map((e,t)=>a.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:0===t?"translateY(-100%)":t===A.length-1?"none":"translateY(-50%)",right:0},children:e.label},t))}),a.jsx("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:a.jsx(c,{data:v,yAxisMode:"share"===t?"share":"airtime",yMax:k,onHover:C,startTs:n,endTs:l,externalAxes:!0})}),a.jsx("div",{className:"absolute left-0 right-0 bottom-0 flex items-center pointer-events-none",style:{left:32,height:20,paddingTop:4},children:S.map((e,t)=>a.jsx("span",{className:"absolute type-data-xs text-fg-muted/60 tabular-nums "+(e.mobileHidden?"hidden sm:inline":""),style:{left:100*e.pct+"%",transform:0===e.pct?"translateX(0)":1===e.pct?"translateX(-100%)":"translateX(-50%)"},children:e.label},t))})]}),a.jsxs("div",{className:"flex items-end justify-between pb-1",style:{minHeight:x},children:[a.jsxs("div",{className:"flex items-center gap-3 sm:gap-5 type-data-sm pl-2 sm:pl-11",children:[a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx("div",{className:"w-4 sm:w-5 h-[2px] rounded-full",style:{backgroundColor:g}}),a.jsx("span",{className:"text-fg-secondary",children:"RX"})]}),a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx("div",{className:"w-4 sm:w-5 h-[2px] rounded-full",style:{backgroundColor:f}}),a.jsx("span",{className:"text-fg-secondary",children:"TX"})]}),a.jsxs("div",{className:"hidden sm:flex items-center gap-1.5",children:[a.jsx("div",{className:"w-5 h-[2px] rounded-full",style:{backgroundColor:b}}),a.jsx("span",{className:"text-fg-secondary",children:"Avg"})]})]}),a.jsxs("div",{className:"flex flex-wrap gap-4 sm:gap-8",children:[a.jsxs("div",{className:"flex items-end gap-2",children:[a.jsx("div",{className:"type-data-xl text-fg-primary",children:M.rx}),a.jsx(d,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"RX"})]}),a.jsxs("div",{className:"flex items-end gap-2",children:[a.jsx("div",{className:"type-data-xl text-fg-primary",children:M.tx}),a.jsx(d,{color:"zinc",className:"mb-0.5 sm:mb-1",children:"TX"})]})]})]})]})}const _e=m,ze=new class{constructor(){t(this,"worker",null),t(this,"listeners",new Set),t(this,"currentResult",null),t(this,"isComputing",!1),t(this,"debounceTimer",null),t(this,"debounceMs",250),t(this,"lastCacheKey",null)}ensureWorker(){if(this.worker)return this.worker;if("undefined"==typeof window)return null;try{this.worker=new Worker(new URL("/assets/bucketing.worker-Dmsaoaph.js",import.meta.url),{type:"module"}),this.worker.onmessage=e=>{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[BucketingService] Worker error:",e),this.isComputing=!1,this.notifyListeners()}}catch(e){console.error("[BucketingService] Failed to initialize worker:",e)}return this.worker}handleWorkerMessage(e){if(this.isComputing=!1,"error"===e.type)return this.currentResult=null,void this.notifyListeners();const t=e.payload;this.currentResult={points:t.points,rawValues:t.rawValues,packetTypes:t.packetTypes,timestamps:t.timestamps,count:t.count,minTime:t.minTime,maxTime:t.maxTime,minValue:t.minValue,maxValue:t.maxValue,rawMinValue:t.rawMinValue,rawMaxValue:t.rawMaxValue,unit:"%",stats:{p5:t.p5,p50:t.p50,p95:t.p95,uniqueValues:t.uniqueValues,topValues:t.topValues}},this.notifyListeners()}notifyListeners(){for(const t of this.listeners)try{t(this.currentResult,this.isComputing)}catch(e){console.error("[BucketingService] Listener error:",e)}}isCacheHit(e){return!(!this.lastCacheKey||!this.currentResult)&&this.lastCacheKey.startTs===e.startTs&&this.lastCacheKey.endTs===e.endTs&&this.lastCacheKey.mode===e.mode&&this.lastCacheKey.packetCount===e.packetCount}compute(e,t,s,a,n){if(0===e.length||!n)return this.currentResult=null,void this.notifyListeners();const l={startTs:t,endTs:s,mode:a,packetCount:e.length};this.isCacheHit(l)||(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.computeInternal(e,t,s,a,n,l)},this.debounceMs))}computeInternal(e,t,s,a,n,l){const i=this.ensureWorker();if(!i)return;const c=e.length,d=new Float64Array(c),m=new Float64Array(c),u=new Uint16Array(c),h=new Uint8Array(c),x={spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble};for(let g=0;g{this.listeners.delete(e)}}clear(){this.currentResult=null,this.lastCacheKey=null,this.notifyListeners()}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}};function Ee({mode:e,packets:t,startTs:n,endTs:l,radioConfig:i,sortedTypes:r,aggregateShares:c,noiseFloorAnomalies:d,showNoiseFloorOverlay:m,overlayOpacity:h=.5,startLabel:x,endLabel:p,lockedYMax:g,legendMinH:f,dotSize:b,dotOpacity:y}){const[j,v]=s.useState(null),[N,w]=s.useState(null),k=s.useMemo(()=>(l-n)/3600,[n,l]),M=s.useCallback(e=>{w(e)},[]),S=function(e,t,a,n,l){const[i,r]=s.useState(()=>ze.getResult());return s.useEffect(()=>ze.subscribe(e=>{r(e)}),[]),s.useEffect(()=>{ze.compute(e,t,a,n,l)},[e,t,a,n,l]),i}(t,n,l,"share"===e?"share":"airtime",i),[C,T]=s.useState(null),A=s.useCallback((e,t)=>{v(e),T(t??null)},[]),F=s.useMemo(()=>{if(null===C||!S||0===S.count)return null;const e=n+C*(l-n);let t;t=k>=168?75:k>=72?35:k>=24?15:k>=3?10:5;const s=60*t/2;return{start:e-s,end:e+s}},[C,S,n,l,k]),P=s.useMemo(()=>F?new Date((F.start+F.end)/2*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}):null,[F]),L=s.useMemo(()=>{if(null===j||!F)return null;const s=P??"",{start:a,end:n}=F,l=t.filter(e=>e.timestamp>=a&&e.timestamp({key:e.key,label:e.label,value:0,color:_e(e.typeNum)}))};const c=new Map,d=new Map;let m=0,u=0;for(const e of l){const t=`TYPE_${e.type??e.payload_type??-1}`;if(c.set(t,(c.get(t)??0)+1),m++,i){const s=o(e,{spreadingFactor:i.sf,bandwidthHz:i.bw,codingRate:i.cr,preambleLength:i.preamble});d.set(t,(d.get(t)??0)+s),u+=s}}const h=r.map(t=>{let s;return s="airtime"===e?u>0?(d.get(t.key)??0)/u:0:m>0?(c.get(t.key)??0)/m:0,{key:t.key,label:t.label,value:s,color:_e(t.typeNum)}});return{timestamp:(a+n)/2,timeLabel:s,items:h}},[j,F,P,t,r,e,i]),R="share"===e,$=g??(null==S?void 0:S.maxValue)??(R?200:10),D=s.useMemo(()=>{if(!R)return 5;const e=[10,20,25,50,100,200,250,500,1e3],t=$/4.5;for(const s of e)if(s>=t)return s;return $>5e3?1e3*Math.ceil(t/1e3):100*Math.ceil(t/100)},[$,R]),_=s.useMemo(()=>{const e=[];for(let t=0;t<=$;t+=D){const s=100*(1-t/$);e.push({pos:s,label:R?`${t}B`:`${t}%`})}return e},[$,D,R]);return S&&0!==S.count?a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:_.map((e,t)=>a.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:0===t?"translateY(-100%)":t===_.length-1?"none":"translateY(-50%)",right:0},children:e.label},t))}),a.jsxs("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:[a.jsx(u,{scatterData:S,yAxisMode:"share"===e?"share":"airtime",onHover:A,noiseFloorAnomalies:d,showNoiseFloorOverlay:m,overlayOpacity:h,highlightedType:N,timeRangeHours:k,yAxisMaxOverride:g,dotSize:b,dotOpacity:y,startTs:n,endTs:l,externalAxes:!0}),P&&a.jsx("div",{className:"absolute top-1 right-1 px-2 py-0.5 bg-elevated/90 rounded type-data-xs text-sys-indigo pointer-events-none z-10",children:P})]}),x&&p&&a.jsxs("div",{className:"absolute left-0 right-0 bottom-0 flex justify-between pointer-events-none type-data-xs text-fg-muted/60",style:{left:32,height:20,paddingTop:4},children:[a.jsx("span",{children:x}),a.jsx("span",{children:p})]})]}),a.jsx("div",{style:{minHeight:f},children:a.jsx(Se,{sortedTypes:r,highlightedType:N,onTypeHover:M,aggregateShares:c,hoverData:L})})]}):a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]})}function He({mode:e,onChange:t}){return a.jsxs("div",{className:"toggle-group toggle-group-sm",children:[a.jsx("button",{onClick:()=>t("share"),className:"toggle-group-item "+("share"===e?"active":""),children:"Total"}),a.jsx("button",{onClick:()=>t("airtime"),className:"toggle-group-item "+("airtime"===e?"active":""),children:"Airtime"})]})}function Be({smoothing:e,onChange:t}){return a.jsxs("div",{className:"toggle-group toggle-group-sm",children:[a.jsx("button",{onClick:()=>t("stats"),className:"toggle-group-item "+("stats"===e?"active":""),title:"Statistics view (scatter plot)",children:a.jsx(q,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("trend"),className:"toggle-group-item "+("trend"===e?"active":""),title:"Trend line chart",children:a.jsx(I,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("ema"),className:"toggle-group-item "+("ema"===e?"active":""),title:"Stacked area (moderate smoothing)",children:a.jsx(B,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("ultra"),className:"toggle-group-item "+("ultra"===e?"active":""),title:"Stacked area (heavy smoothing)",children:a.jsx(G,{className:"w-3.5 h-3.5"})}),a.jsx("button",{onClick:()=>t("mosaic"),className:"toggle-group-item "+("mosaic"===e?"active":""),title:"Mosaic view (treemap)",children:a.jsx(V,{className:"w-3.5 h-3.5"})})]})}function Oe({enabled:e,onChange:t,anomalyCount:s=0,showTuning:n=!1,onTuningChange:l}){return a.jsxs("div",{className:"relative inline-flex items-center gap-1",children:[e&&l&&a.jsx("button",{onClick:()=>l(!n),className:"toggle-group toggle-group-sm "+(n?"active":""),title:n?"Hide tuning panel":"Show tuning panel",children:a.jsx("span",{className:"toggle-group-item "+(n?"active":""),children:a.jsx(O,{className:"w-3.5 h-3.5"})})}),a.jsx("button",{onClick:()=>t(!e),className:"toggle-group toggle-group-sm "+(e?"active":""),title:e?"Hide noise floor anomalies":"Show noise floor anomalies",children:a.jsx("span",{className:"toggle-group-item "+(e?"active":""),children:a.jsx(W,{className:"w-3.5 h-3.5"})})}),s>0&&a.jsx("span",{className:"absolute -top-2 -right-2 min-w-[18px] h-[18px] px-1 rounded-full bg-sys-red text-white text-xs font-bold flex items-center justify-center pointer-events-none z-10",children:s>99?"99+":s})]})}const We=[{target:"PacketAnalyzer",fn:"type",minStage:1},{target:"PacketAnalyzer",fn:"airtime",minStage:1,when:ae}];ne(We);const qe={sf:10,bw:25e4,cr:5,preamble:8};function Ie(e,t){const s=new Date(1e3*e),a=e=>e.toString().padStart(2,"0"),n=`${a(s.getHours())}:${a(s.getMinutes())}`;return t<24?n:`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][s.getMonth()]} ${s.getDate()} ${n}`}function Ge(e){return l[e]??`TYPE_${e.toString(16).toUpperCase()}`}function Ve(e,t,s,a){const n=2*a+1;let l=0;for(let i=0;i<=a;i++)l+=e[Math.min(i,s-1)];for(let i=0;i{const t=Math.abs(e.length-F.current);if(0===t&&C.length>0)return;A.current&&clearTimeout(A.current);const s=t>100?50:500;return A.current=setTimeout(()=>{F.current=e.length,T(e)},s),()=>{A.current&&clearTimeout(A.current)}},[e,C.length]);const P=s.useMemo(()=>function(e,t){const s=new Map;for(const n of e){const e=n.type??n.payload_type??-1,a=o(n,{spreadingFactor:t.sf,bandwidthHz:t.bw,codingRate:t.cr,preambleLength:t.preamble}),l=s.get(e)??{count:0,airtime:0};s.set(e,{count:l.count+1,airtime:l.airtime+a})}const a=[];for(const[n,l]of s)a.push({typeNum:n,key:`TYPE_${n}`,label:Ge(n),totalCount:l.count,totalAirtime:l.airtime});return a.sort((e,t)=>t.totalCount-e.totalCount)}(C,u),[C,u]),L=s.useMemo(()=>{if("ema"!==g&&"ultra"!==g)return 0;const e=(i-l)/m,{handleSize:t}=Xe(g,e,m);return t},[g,l,i,m]),R=s.useMemo(()=>function(e,t,s,a,n,l,i=0){const r=s-t,c=r/a,d=1e3*c,m=r/3600,u=t-i*c,h=s+i*c,x=a+2*i,p=[];for(let o=0;o=24?t.toLocaleDateString([],{weekday:"short",hour:"2-digit",minute:"2-digit",hour12:!1}):t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1}),counts:{},shares:{},airtimes:{},total:0,totalAirtime:0,bucketDurationMs:d};for(const a of l)s.counts[a.key]=0,s.airtimes[a.key]=0;p.push(s)}for(const g of e){const e=g.timestamp;if(e=h)continue;const t=Math.min(Math.floor((e-u)/c),x-1),s=`TYPE_${g.type??g.payload_type??-1}`;p[t].counts[s]=(p[t].counts[s]??0)+1,p[t].total++;const a=o(g,{spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble});p[t].airtimes[s]=(p[t].airtimes[s]??0)+a,p[t].totalAirtime+=a}for(const o of p)for(const e of l)o.shares[e.key]=o.total>0?o.counts[e.key]/o.total*100:0;return{buckets:p,visibleStart:i,visibleEnd:i+a}}(C,l,i,m,u,P,L),[C,l,i,m,u,P,L]),$=s.useMemo(()=>P.reduce((e,t)=>e+t.totalCount,0),[P]),D=s.useMemo(()=>P.reduce((e,t)=>e+t.totalAirtime,0),[P]),{sortedTypes:_,aggregateShares:z}=s.useMemo(()=>{const e=new Map,t="share"===p?$:D;if(t>0)for(const s of P){const a="share"===p?s.totalCount:s.totalAirtime;e.set(s.key,a/t)}return{sortedTypes:[...P].sort((t,s)=>(e.get(s.key)??0)-(e.get(t.key)??0)),aggregateShares:e}},[P,$,D,p]),E=s.useMemo(()=>function(e,t,s,a="ultra",n,l,i){var r;const{buckets:o,visibleStart:c,visibleEnd:d}=e,m=o.length,u=s.length,h=d-c;if(0===m||0===u)return[];const x=i&&void 0!==n&&void 0!==l?(l-n)/i:(null==(r=o[0])?void 0:r.bucketDurationMs)?o[0].bucketDurationMs/1e3:240,p=Array.from({length:u},()=>new Array(m).fill(0));for(let N=0;N0)for(let t=0;t0)for(let a=0;a0?p.map(e=>function(e,t){const s=e.length;if(0===s)return[];if(t<.5)return[...e];const a=Math.sqrt(12*t*t/3+1);let n=Math.floor(a);n%2==0&&n--;const l=n+2,i=(12*t*t-3*n*n-12*n-9)/(-4*n-4),r=Math.round(i),o=[r>0?n:l,r>1?n:l,r>2?n:l];let c=new Float32Array(e);const d=new Float32Array(s);for(const m of o){Ve(c,d,s,(m-1)/2);const e=c;c=d,d.set(e)}return Array.from(c)}(e,g)):p.map(e=>function(e,t){if(0===e.length)return[];if(t<=1)return[...e];const s=e.length,a=new Float32Array(s),n=Math.floor(t/2);let l=0,i=0;for(let r=0;r<=Math.min(n,s-1);r++)l+=e[r],i++;for(let r=0;r=0&&(l-=e[t],i--),o0){const t=1/e;for(let e=0;e360?Math.ceil(h/360):1,j=Math.ceil(h/y),v=[];for(let N=0;N0){const e=1/l;for(let t=0;tk(e),[]),O=s.useCallback(e=>S(e),[]),W=s.useCallback(e=>k(e),[]),q=s.useMemo(()=>{if(null===M||!E[M])return null;const e=E[M];return{timestamp:e.timestamp,timeLabel:e.time,items:_.map(t=>({key:t.key,label:t.label,value:e[t.key]??0,color:n(t.typeNum)}))}},[M,E,_]),I=s.useMemo(()=>({timestamps:E.map(e=>e.timestamp),series:_.map(e=>({key:e.key,label:e.label,color:n(e.typeNum),values:E.map(t=>t[e.key]??0)}))}),[E,_]),G=t&&void 0!==c&&void 0!==d&&(l!==c||i!==d),V=s.useMemo(()=>{if(G&&t&&void 0!==c&&void 0!==d)return function(e,t,s,a,n){const l=Math.max(1,Math.ceil((s-t)/300));if("airtime"===a){const a=new Float64Array(l);for(const r of e){const e=r.timestamp;e=s||(a[Math.min(Math.floor((e-t)/300),l-1)]+=o(r,{spreadingFactor:n.sf,bandwidthHz:n.bw,codingRate:n.cr,preambleLength:n.preamble}))}let i=0;for(let e=0;ei&&(i=t)}return Math.max(1,Math.ceil(1.1*i))}{let a=0;for(const n of e){const e=n.timestamp;if(e=s)continue;const l=r(n);l>a&&(a=l)}return a<=200?200:50*Math.ceil(1.1*a/50)}}(t,c,d,p,u)},[G,t,c,d,p,u]);if(0===C.length)return 0===e.length?a.jsxs("div",{className:"h-full flex items-center justify-center text-fg-muted",children:[a.jsx(B,{className:"w-6 h-6 mr-2 opacity-50"}),a.jsx("span",{children:"No packet data available"})]}):null;if("mosaic"===g)return a.jsx(Re,{sortedTypes:_,aggregateShares:z,mode:p});const Y=(i-l)/3600,K=Ie(l,Y),X=Ie(i,Y);return"stats"===g?a.jsx(Ee,{mode:p,packets:C,startTs:l,endTs:i,radioConfig:u,sortedTypes:_,aggregateShares:z,noiseFloorAnomalies:f,showNoiseFloorOverlay:b,overlayOpacity:y,startLabel:K,endLabel:X,lockedYMax:V,legendMinH:80,dotSize:j,dotOpacity:v}):"trend"===g?a.jsx(De,{packets:C,mode:p,startTs:l,endTs:i,radioConfig:u,bucketCount:m,lockedYMax:V,legendMinH:80}):a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex-1 min-h-0 relative",children:[a.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},children:[0,20,40,60,80,100].map((e,t,s)=>a.jsxs("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:100*(1-e/100)+"%",transform:0===t?"translateY(-100%)":t===s.length-1?"none":"translateY(-50%)",right:0},children:[e,"%"]},e))}),a.jsx("div",{className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:a.jsx(x,{timestamps:I.timestamps,series:I.series,highlightedKey:w,cursorColor:N.cursor,onHover:O,onSeriesHover:W,overlayLine:null,startTs:l,endTs:i,externalAxes:!0})}),a.jsxs("div",{className:"absolute left-0 right-0 bottom-0 flex justify-between pointer-events-none type-data-xs text-fg-muted/60",style:{left:32,height:20,paddingTop:4},children:[a.jsx("span",{children:K}),a.jsx("span",{children:X})]})]}),a.jsx("div",{style:{minHeight:80},children:a.jsx(Se,{sortedTypes:_,highlightedType:w,onTypeHover:H,aggregateShares:z,hoverData:q})})]})}),Je={"1x":1,"2x":2,"4x":4,"8x":8,"16x":16,"36x":36},Qe=[1,5,10,25,50,100,150],Ze=22.5*Math.PI/180,et=Math.sin(Ze),tt=Math.cos(Ze);function st(e,t,s,a){const n=Math.PI/180,l=(a-t)*n,i=e*n,r=s*n,o=Math.sin(l)*Math.cos(r),c=Math.cos(i)*Math.sin(r)-Math.sin(i)*Math.cos(r)*Math.cos(l);return(180*Math.atan2(o,c)/Math.PI+360)%360}function at(e,t,s,a){const n=Math.PI/180,l=(s-e)*n,i=(a-t)*n,r=Math.sin(l/2)**2+Math.cos(e*n)*Math.cos(s*n)*Math.sin(i/2)**2;return 12742*Math.atan2(Math.sqrt(r),Math.sqrt(1-r))}const nt=[{min:10,label:"Excellent"},{min:7,label:"Very Good"},{min:4,label:"Good"},{min:1,label:"Fair+"},{min:-2,label:"Fair"},{min:-5,label:"Fair-"},{min:-8,label:"Poor"},{min:-11,label:"Bad"},{min:-1/0,label:"Critical"}];function lt(e,t,s){return t[v(e,s)]||"#808080"}const it=s.memo(function({neighbors:e,quickNeighbors:t,localLat:n,localLon:l,onStatsChange:r,title:o,badge:c,stats:m}){const[u,h]=s.useState(null),[x,v]=s.useState(new Set),[N,w]=s.useState({width:0,height:0}),[k,M]=s.useState("1x"),[S,C]=s.useState(1),T=s.useRef(null),A=s.useRef({}),F=s.useRef(null),P=s.useRef(S);P.current=S;const L=p(),R=g(),$=f(),D=b(),_=i(),z=y(),E=D?$.primary:$.secondary,H=D?.15:.4,B=D?.08:.25,O=D?_.blue:$.primary;s.useEffect(()=>{const e=F.current;if(!e)return;const t=new ResizeObserver(e=>{for(const t of e){const{width:e,height:s}=t.contentRect;e>0&&s>0&&w({width:e,height:s})}});t.observe(e);const s=e.getBoundingClientRect();return s.width>0&&s.height>0&&w({width:s.width,height:s.height}),()=>t.disconnect()},[]);const W=s.useMemo(()=>{const e=new Set;if(t)for(const s of t)e.add(s.hash);return e},[t]),q=s.useMemo(()=>{const e=new Map;if(t)for(const s of t)e.set(s.hash,{snr:s.avgSnr,rssi:s.avgRssi});return e},[t]),{processedNeighbors:I,maxDistance:G,totalNeighbors:V,zeroHopCount:K}=s.useMemo(()=>{const t=[];for(const[a,i]of Object.entries(e)){if(!i.latitude||!i.longitude||0===i.latitude||0===i.longitude)continue;if(!W.has(a))continue;const e=st(n,l,i.latitude,i.longitude),s=at(n,l,i.latitude,i.longitude),r=q.get(a);t.push({hash:a.slice(0,8),name:i.node_name||i.name||"Unknown",snr:(null==r?void 0:r.snr)??i.snr??null,rssi:(null==r?void 0:r.rssi)??i.rssi??null,bearing:e,distance:s,normalizedDistance:0,lastSeen:i.last_seen,isZeroHop:!0})}const s=1.08*(t.length>0?Math.max(...t.map(e=>e.distance)):0);return t.sort((e,t)=>(e.snr??-1/0)-(t.snr??-1/0)),{processedNeighbors:t,maxDistance:s,totalNeighbors:t.length,zeroHopCount:t.length}},[e,n,l,W,q]);s.useEffect(()=>{null==r||r({zeroHopCount:K,totalCount:V,maxDistanceKm:G})},[K,V,G]),s.useEffect(()=>{const e=Je[k],t=P.current;T.current&&cancelAnimationFrame(T.current);const s=performance.now(),a=n=>{const l=n-s,i=Math.min(l/400,1),r=le(i);C(t+(e-t)*r),T.current=i<1?requestAnimationFrame(a):null};return T.current=requestAnimationFrame(a),()=>{T.current&&cancelAnimationFrame(T.current)}},[k]);const X=G/S,U=s.useMemo(()=>Qe.filter(e=>e<=1.1*X),[X]);s.useEffect(()=>{const e=[];for(const s of I){const t=A.current[s.hash];void 0!==t&&t!==s.lastSeen&&e.push(s.hash),A.current[s.hash]=s.lastSeen}if(0===e.length)return;queueMicrotask(()=>{v(t=>new Set([...t,...e]))});const t=setTimeout(()=>{v(t=>{const s=new Set(t);return e.forEach(e=>s.delete(e)),s})},600);return()=>clearTimeout(t)},[I]);const J=0!==n&&0!==l,Q=s.useMemo(()=>{const{width:e,height:t}=N,s=e/2,a=t/2,n=Math.min(e,t),l=Math.max(10,n/2-6);return{width:e,height:t,centerX:s,centerY:a,radius:Math.max(10,l-8),labelRadius:l}},[N]),{width:Z,height:ee,centerX:te,centerY:se,radius:ae,labelRadius:ne}=Q,ie=s.useId(),re=s.useCallback((e,t)=>{const s=e*Math.PI/180;return{x:te+ae*t*Math.sin(s),y:se-ae*t*Math.cos(s)}},[te,se,ae]),oe=s.useCallback(e=>{const t={N:0,NE:45,E:90,SE:135,S:180,SW:225,W:270,NW:315}[e]*Math.PI/180;return{x:te+ne*Math.sin(t),y:se-ne*Math.cos(t)}},[te,se,ne]),ce=s.useCallback(e=>{h(e)},[]),de=s.useCallback(e=>{M(e)},[]),me=s.useCallback(e=>G<=0?0:e/G*S,[G,S]),ue=e=>`${e}km`,he=s.useMemo(()=>{const e=[{x:te,y:se-ne},{x:te+ne*Math.SQRT1_2,y:se-ne*Math.SQRT1_2}],t=U.map(e=>{const t=e/G*S;return{km:e,scale:t,lx:te+ae*t*et,ly:se-ae*t*tt}}).filter(e=>e.scale<=1.05&&e.scale>=.02).sort((e,t)=>t.km-e.km),s=[];for(const a of t){const t=s.some(e=>{const t=e.lx-a.lx,s=e.ly-a.ly;return Math.sqrt(t*t+s*s)<28}),n=e.some(e=>{const t=e.x-a.lx,s=e.y-a.ly;return Math.sqrt(t*t+s*s)<28});t||n||s.push(a)}return s},[U,G,S,te,se,ae,ne]),xe=N.width>0&&N.height>0;return J?0===V?a.jsxs("div",{ref:F,className:"flex flex-col items-center justify-center h-full text-fg-secondary",children:[a.jsx(Y,{className:"w-8 h-8 mb-2 opacity-50"}),a.jsx("p",{children:"No nodes with location data"})]}):a.jsxs("div",{className:"flex h-full w-full overflow-visible",children:[a.jsxs("div",{ref:F,className:"relative flex-1 min-w-0 h-full overflow-visible -ml-4 sm:-ml-5",children:[xe&&a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"absolute depth-raised",style:{left:te-ae-8-4,top:se-ae-8-4,width:2*(ae+8)+8,height:2*(ae+8)+8,borderRadius:"50%",padding:4,boxSizing:"border-box",backgroundColor:D?"var(--zinc-925)":"var(--zinc-75)"}}),a.jsxs("svg",{width:Z,height:ee,className:"absolute inset-0 z-0",style:{overflow:"visible"},children:[a.jsxs("defs",{children:[a.jsx("style",{children:"\n @keyframes neighbor-blink-scale {\n 0%, 100% {\n transform: scale(1);\n opacity: 0;\n }\n 50% {\n transform: scale(1.3);\n opacity: 0.8;\n }\n }\n .neighbor-blink-ring {\n transform-origin: center;\n animation: neighbor-blink-scale 600ms ease-out forwards;\n }\n "}),a.jsx("clipPath",{id:ie,children:a.jsx("circle",{cx:te,cy:se,r:ae})})]}),(()=>{const e=ae+8+12,t=D?"rgba(255, 255, 255, 0.12)":"rgba(0, 0, 0, 0.15)",s=D?"rgba(59, 130, 246, 0.4)":"rgba(59, 130, 246, 0.5)",n=[45,135,225,315];return a.jsxs("g",{className:"radar-frame","aria-hidden":"true",children:[a.jsx("circle",{cx:te,cy:se,r:e,fill:"none",stroke:t,strokeWidth:1,strokeDasharray:"2 6"}),n.map(t=>{const n=t*Math.PI/180,l=Math.cos(n),i=Math.sin(n),r=e+4,o=e+4+16,c=te+r*i,d=se-r*l,m=te+o*i,u=se-o*l;return a.jsxs("g",{children:[a.jsx("line",{x1:c,y1:d,x2:m,y2:u,stroke:s,strokeWidth:1}),a.jsx("line",{x1:m-4*l,y1:u-4*i,x2:m+4*l,y2:u+4*i,stroke:s,strokeWidth:1})]},`corner-${t}`)}),[0,90,180,270].map(s=>{const n=s*Math.PI/180,l=te+(e-6)*Math.sin(n),i=se-(e-6)*Math.cos(n),r=te+(e+2)*Math.sin(n),o=se-(e+2)*Math.cos(n);return a.jsx("line",{x1:l,y1:i,x2:r,y2:o,stroke:t,strokeWidth:1},`tick-cardinal-${s}`)}),n.map(s=>{const n=s*Math.PI/180,l=te+(e-4)*Math.sin(n),i=se-(e-4)*Math.cos(n),r=te+(e+1)*Math.sin(n),o=se-(e+1)*Math.cos(n);return a.jsx("line",{x1:l,y1:i,x2:r,y2:o,stroke:t,strokeWidth:1},`tick-intercardinal-${s}`)})]})})(),(()=>{const e=[(ae+8+4)/ae,...U.map(e=>me(e)).filter(e=>e>.02&&e<=1.05).sort((e,t)=>t-e),0];return e.slice(0,-1).map((t,s)=>{const n=e[s+1],l=ae*t,i=ae*n,r=l-i;return r<=0||s%2!=0?null:a.jsx("circle",{cx:te,cy:se,r:(l+i)/2,fill:"none",stroke:"var(--subtle-fill)",strokeWidth:r,opacity:.8},`band-${s}`)})})(),U.map(e=>{const t=me(e);if(t>1.05||t<.02)return null;const s=he.some(t=>t.km===e),n=te+ae*t*et,l=se-ae*t*tt;return a.jsxs("g",{children:[a.jsx("circle",{cx:te,cy:se,r:ae*t,fill:"none",stroke:E,strokeOpacity:H,strokeWidth:1}),s&&a.jsx("text",{x:n+4,y:l-2,textAnchor:"start",dominantBaseline:"auto",fill:$.secondary,fontSize:10,fontFamily:j,children:ue(e)})]},`ring-${e}`)}),["N","E","S","W"].map(e=>{const t={N:0,E:90,S:180,W:270}[e]*Math.PI/180;return a.jsx("line",{x1:te,y1:se,x2:te+ae*Math.sin(t),y2:se-ae*Math.cos(t),stroke:E,strokeOpacity:H,strokeWidth:1,strokeDasharray:"4 4"},e)}),["NE","SE","SW","NW"].map(e=>{const t={NE:45,SE:135,SW:225,NW:315}[e]*Math.PI/180;return a.jsx("line",{x1:te,y1:se,x2:te+ae*Math.sin(t),y2:se-ae*Math.cos(t),stroke:E,strokeOpacity:B,strokeWidth:1,strokeDasharray:"4 4"},`diag-${e}`)}),["N","E","S","W"].map(e=>{const t=oe(e),s="E"===e?"end":"W"===e?"start":"middle",n="N"===e?"hanging":"S"===e?"auto":"middle";return a.jsx("text",{x:t.x,y:t.y,textAnchor:s,dominantBaseline:n,fill:O,fontSize:10,fontWeight:700,fontFamily:j,"aria-hidden":"true",children:e},e)}),["NE","SE","SW","NW"].map(e=>{const t=oe(e),s="NE"===e||"SE"===e?"end":"start",n="NE"===e||"NW"===e?"hanging":"auto";return a.jsx("text",{x:t.x,y:t.y,textAnchor:s,dominantBaseline:n,fill:O,fontSize:9,fontWeight:600,fontFamily:j,"aria-hidden":"true",children:e},e)}),a.jsx("circle",{cx:te,cy:se,r:5,fill:R.chart6,stroke:D?"rgba(255,255,255,0.3)":"rgba(0,0,0,0.2)",strokeWidth:1,role:"img","aria-label":"Local node"}),a.jsx("g",{clipPath:`url(#${ie})`,children:I.map(e=>{const t=G>0?e.distance/G*S:0;if(t>1)return null;const{x:s,y:n}=re(e.bearing,t),l=null!==e.snr?lt(e.snr,L,z):"#808080",i=(null==u?void 0:u.hash)===e.hash,r=x.has(e.hash);return a.jsxs("g",{role:"img","aria-label":`${e.name}: ${e.distance.toFixed(1)}km ${e.bearing.toFixed(0)}°`,children:[r&&a.jsx("circle",{cx:s,cy:n,r:10.5,fill:"none",stroke:D?"rgba(255,255,255,0.9)":"rgba(0,0,0,0.7)",strokeWidth:2,className:"neighbor-blink-ring"}),i&&a.jsx("circle",{cx:s,cy:n,r:10.5,fill:l,opacity:.3}),a.jsx("circle",{cx:s,cy:n,r:i?7:5,fill:l,stroke:D?"rgba(0,0,0,0.5)":"rgba(0,0,0,0.25)",strokeWidth:1,style:{cursor:"pointer",transition:"r 0.15s"},onMouseEnter:()=>ce(e),onMouseLeave:()=>ce(null)})]},e.hash)})})]})]}),u&&a.jsxs("div",{className:"absolute bg-tooltip-bg border border-edge-subtle rounded-lg px-3 py-2 text-sm pointer-events-none z-10 shadow-xl",style:{left:"50%",bottom:8,transform:"translateX(-50%)"},children:[a.jsx("div",{className:"font-medium text-fg-primary",children:u.name}),a.jsx("div",{className:"type-data-xs text-fg-secondary",children:u.hash}),null!==u.snr?a.jsx("div",{className:"flex gap-3 mt-1 text-xs",children:a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"SNR:"})," ",a.jsxs("span",{className:"tabular-nums",style:{color:lt(u.snr,L,z)},children:[u.snr.toFixed(1)," dB"]}),a.jsxs("span",{className:"text-fg-secondary ml-1",children:["(",(pe=u.snr,(null==(ge=nt.find(e=>pe>=e.min))?void 0:ge.label)??"Critical"),")"]})]})}):a.jsx("div",{className:"text-xs text-fg-secondary mt-1",children:"No SNR data"}),a.jsxs("div",{className:"flex gap-3 text-xs",children:[a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"Distance:"})," ",a.jsxs("span",{className:"tabular-nums text-fg-primary",children:[u.distance.toFixed(2)," km"]})]}),a.jsxs("span",{children:[a.jsx("span",{className:"text-fg-secondary",children:"Bearing:"})," ",a.jsxs("span",{className:"tabular-nums text-fg-primary",children:[u.bearing.toFixed(0),"°"]})]})]})]})]}),a.jsxs("div",{className:"flex flex-col gap-1 px-1.5 py-2 flex-shrink-0 depth-raised radius-inset self-stretch",style:{width:"calc(100% / 6)"},children:[o&&a.jsxs("div",{className:"flex flex-col items-center gap-1 pb-2 border-b border-edge-subtle mb-1",children:[a.jsxs("div",{className:"flex items-center gap-1",children:[a.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:a.jsx(Y,{className:"w-3.5 h-3.5"})}),c&&a.jsx(d,{color:"zinc",children:c})]}),a.jsx("span",{className:"type-micro text-center text-[10px] leading-tight",children:o})]}),a.jsx("div",{className:"flex flex-col gap-1 flex-1",role:"group","aria-label":"Zoom level",children:["1x","2x","4x","8x","16x","36x"].map(e=>a.jsx("button",{onClick:()=>de(e),"aria-pressed":k===e,className:"flex flex-1 items-center justify-center min-w-[44px] sm:min-w-[32px] text-xs font-medium radius-inner depth-stroke-raised transition-colors "+(k===e?"bg-sys-blue/20 text-sys-blue":"bg-subtle-fill/80 text-fg-secondary hover:bg-subtle-fill-strong hover:text-fg-primary"),children:e},e))})]})]}):a.jsxs("div",{ref:F,className:"flex flex-col items-center justify-center h-full text-fg-secondary",children:[a.jsx(Y,{className:"w-8 h-8 mb-2 opacity-50"}),a.jsx("p",{children:"Local node coordinates not configured"}),a.jsx("p",{className:"text-xs mt-1",children:"Set latitude/longitude in config to enable"})]});var pe,ge}),rt={repeater:"var(--sys-blue)",companion:"var(--sys-cyan)",room_server:"var(--sys-indigo)"};function ot(e){if(e.contact_type){const t=e.contact_type.toLowerCase();if("repeater"===t||"rep"===t)return"repeater";if("room server"===t||"room_server"===t||"room"===t||"server"===t)return"room_server";if("companion"===t||"client"===t||"cli"===t)return"companion"}return e.is_repeater?"repeater":"companion"}const ct=s.memo(function({neighbors:e}){const t=s.useMemo(()=>{const t={repeater:0,companion:0,room_server:0};for(const a of Object.values(e)){const e=ot(a);t[e]=(t[e]||0)+1}const s=Object.values(t).reduce((e,t)=>e+t,0);return{items:[{label:"Repeaters",count:t.repeater,percent:0,color:rt.repeater},{label:"Companions",count:t.companion,percent:0,color:rt.companion},{label:"Room Servers",count:t.room_server,percent:0,color:rt.room_server}].map(e=>({...e,percent:s>0?e.count/s*100:0})).filter(e=>e.count>0).sort((e,t)=>t.count-e.count),total:s}},[e]);return 0===t.total?a.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted type-body-sm",children:"No neighbors discovered yet"}):a.jsxs("div",{className:"h-full flex flex-col",children:[a.jsx("div",{className:"flex-1 flex flex-col justify-evenly",children:t.items.map(e=>a.jsxs("div",{className:"flex flex-col gap-1.5",children:[a.jsxs("div",{className:"flex items-center justify-between",children:[a.jsx("span",{className:"type-data-sm text-fg-secondary",children:e.label}),a.jsxs("span",{className:"type-data-sm text-fg-secondary tabular-nums",children:[e.count," ",a.jsxs("span",{className:"text-fg-secondary/60",children:["(",e.percent.toFixed(0),"%)"]})]})]}),a.jsx("div",{className:"h-2.5 bg-subtle-fill/80 overflow-hidden rounded-full depth-stroke-inset",children:a.jsx("div",{className:"h-full rounded-full transition-all duration-500 ease-out",style:{width:`${e.percent}%`,backgroundColor:e.color,minWidth:e.count>0?"4px":"0"}})})]},e.label))}),a.jsxs("div",{className:"flex items-center justify-between pt-2 border-t border-edge-subtle",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Total Nodes"}),a.jsx("span",{className:"type-data-sm text-fg-primary font-medium tabular-nums",children:t.total})]})]})});function dt({children:e,minHeight:t="100%",rootMargin:n="200px 0px",keepMounted:l=!0,className:i=""}){const r=s.useRef(null),[o,c]=s.useState(!1),[d,m]=s.useState(!1);s.useEffect(()=>{const e=r.current;if(!e)return;const t=new IntersectionObserver(([e])=>{const t=e.isIntersecting;m(t),t&&c(!0)},{rootMargin:n,threshold:0});return t.observe(e),()=>{t.disconnect()}},[n]);const u=d||l&&o;return a.jsx("div",{ref:r,className:`h-full w-full ${i}`,style:{minHeight:t},children:u?e:a.jsx("div",{className:"h-full w-full flex items-center justify-center text-fg-muted/50",children:a.jsx("div",{className:"animate-pulse text-xs",children:"Loading chart..."})})})}const mt=[{target:"DisambiguationCard",fn:"disambiguation.collisions",minStage:2}];ne(mt);const ut={excellent:"text-signal-excellent",good:"text-signal-good",fair:"text-signal-fair",poor:"text-sys-blue"},ht={excellent:"bg-signal-excellent/10",good:"bg-signal-good/10",fair:"bg-signal-fair/10",poor:"bg-sys-blue/10"};function xt(){se(mt);const e=N(),t=w(),[n,l]=s.useState(null),i=s.useCallback((e,t)=>{l({prefix:e,candidateHashes:t})},[]),r=s.useCallback(()=>{l(null)},[]);if(!t)return a.jsxs(re,{neomorphic:!0,children:[a.jsx(k,{icon:a.jsx(K,{}),title:"Prefix Conflicts"}),a.jsx("div",{className:"flex-1 flex items-center justify-center",children:a.jsxs("div",{className:"text-center text-fg-secondary",children:[a.jsx(X,{className:"w-8 h-8 mx-auto mb-2 opacity-50"}),a.jsx("p",{className:"type-data-xs",children:"No topology data available"}),a.jsx("p",{className:"type-data-xs opacity-70",children:"Run deep analysis to see stats"})]})})]});const o=(c=e.avgConfidence)>=.9?"excellent":c>=.7?"good":c>=.5?"fair":"poor";var c;const m=(u=e.collisionRate)<=10?"excellent":u<=25?"good":"poor";var u;const h="poor"===o||"poor"===m?"poor":"fair"===o||"fair"===m?"fair":"good"===o||"good"===m?"good":"excellent",x="excellent"===h||"good"===h?J:U;return a.jsxs(re,{neomorphic:!0,className:"flex flex-col overflow-hidden",children:[a.jsx(k,{icon:a.jsx(K,{}),title:"Prefix Conflicts",badgeColor:"zinc",actions:"poor"===h?a.jsxs(d,{color:"red",children:[a.jsx(U,{className:"w-3 h-3"}),"Needs Attention"]}):a.jsxs("div",{className:`flex items-center gap-1.5 px-2.5 py-1 rounded-full ${ht[h]}`,children:[a.jsx(x,{className:`w-3.5 h-3.5 ${ut[h]}`}),a.jsx("span",{className:`type-data-xs font-medium ${ut[h]}`,children:"excellent"===h?"Excellent":"good"===h?"Good":"Fair"})]})}),a.jsxs("div",{className:"flex-1 flex flex-col min-h-0",children:[a.jsxs("div",{className:"flex gap-2 sm:gap-3 py-3 sm:py-4",children:[a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Total unique 2-character prefixes observed in packet paths.",children:[a.jsx("span",{className:"type-data-xl text-fg-primary",children:a.jsx(ue,{value:e.totalPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Prefixes"})]}),a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Prefixes that map to exactly one known node. No disambiguation needed.",children:[a.jsx("span",{className:"type-data-xl text-fg-primary",children:a.jsx(ue,{value:e.unambiguousPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro text-fg-muted mt-0.5 sm:mt-1",children:"Unique"})]}),a.jsxs("div",{className:"flex-1 flex flex-col radius-inner depth-stroke-raised bg-subtle-fill/80 px-3 py-2.5 sm:py-3 cursor-help",title:"Prefixes matching multiple known nodes. Click a prefix below to explore candidates.",children:[a.jsx("span",{className:"type-data-xl "+(e.collisionPrefixes>0?"text-sys-blue":"text-fg-primary"),children:a.jsx(ue,{value:e.collisionPrefixes,priority:"low"})}),a.jsx("span",{className:"type-micro mt-0.5 sm:mt-1 "+(e.collisionPrefixes>0?"text-sys-blue":"text-fg-muted"),children:"Conflicts"})]})]}),e.highCollisionPrefixes.length>0&&a.jsxs("div",{className:"pt-2",children:[a.jsx("div",{className:"type-data-xs text-fg-secondary mb-1.5",children:"Problem Prefixes"}),a.jsx("div",{className:"flex flex-wrap gap-1.5 content-start",children:e.highCollisionPrefixes.map(({prefix:e,candidateCount:t,candidateHashes:s})=>a.jsxs("button",{type:"button",onClick:()=>i(e,s),className:"inline-flex items-center gap-0.5 group",title:`${t} candidates - click to explore`,children:[a.jsx(me,{children:e}),a.jsxs("span",{className:"text-fg-muted type-data-xs group-hover:text-fg-secondary transition-colors",children:["×",t]})]},e))})]}),0===e.lowConfidencePrefixes.length&&0===e.collisionPrefixes&&a.jsx("div",{className:"flex-1 flex items-center",children:a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx(J,{className:"w-3.5 h-3.5 text-signal-excellent"}),a.jsx("span",{className:"type-data-xs text-signal-excellent",children:"All prefixes uniquely identified"})]})}),a.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 mt-auto pt-1.5",children:[a.jsxs("div",{className:"flex items-center gap-2 cursor-help",title:"Average confidence score across all disambiguated prefixes. Higher = more certain node identification.",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Confidence"}),a.jsxs("span",{className:`data-box ${ut[o]}`,children:[(100*e.avgConfidence).toFixed(1),"%"]})]}),a.jsxs("div",{className:"flex items-center gap-2 cursor-help",title:"Percentage of 2-character prefixes that match multiple known nodes. Lower is better.",children:[a.jsx("span",{className:"type-data-xs text-fg-secondary",children:"Collisions"}),a.jsxs("span",{className:`data-box ${ut[m]}`,children:[e.collisionRate.toFixed(1),"%"]})]})]})]}),a.jsx(he,{isOpen:!!n,prefix:(null==n?void 0:n.prefix)||"",candidateHashes:(null==n?void 0:n.candidateHashes)||[],onClose:r})]})}const pt=[{target:"PacketHealth",fn:"type",minStage:1},{target:"PacketHealth",fn:"duplicates",minStage:1}];ne(pt);const gt=new Set(["Duplicate","Empty payload","Path too long","Unknown"]),ft={excellent:"bg-status-success",good:"bg-sys-blue",fair:"bg-status-warning",poor:"bg-status-danger"};function bt({packets:e,rangeMinutes:t,rangeHours:n,timeRangeLabel:l,isLoaded:i=!0}){se(pt);const r=s.useMemo(()=>function(e,t){const s=Date.now()/1e3,a=60*t,n=s-a,l=a/24,i=new Array(24).fill(0),r=new Array(24).fill(0);let o=0,c=0,d=0,m=0;for(const h of e){if("tx_local"===h.packet_origin)continue;const e=h.timestamp;if(es)continue;o++;const t=Math.min(23,Math.floor((e-n)/l));r[t]++,h.transmitted||"tx_forward"===h.packet_origin?(c++,i[t]++):(h.is_duplicate||"Duplicate"===h.drop_reason)&&d++,h.drop_reason&>.has(h.drop_reason)&&m++}const u=[];for(let h=0;h<24;h++){const e=r[h],t=i[h];u.push({count:e>0?Math.round(t/e*100):0,timestamp:1e3*(n+h*l)})}return{totalRx:o,forwarded:c,duplicates:d,waste:m,efficiency:o>0?c/o*100:0,duplicateRate:o>0?d/o*100:0,wasteRate:o>0?m/o*100:0,sparkline:u}}(e,t),[e,t]),[o,c]=s.useState(null),d=s.useCallback(async()=>{try{const e=await M(n);e.success&&e.data&&c(e.data.count)}catch{}},[n]);s.useEffect(()=>{d()},[d]);const m=(u=r.efficiency)>=90?"excellent":u>=75?"good":u>=60?"fair":"poor";var u;const h=r.totalRx>0;return a.jsx(re,{neomorphic:!0,isLoaded:i,skeletonType:"chart",children:i&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(Q,{}),title:"Packet Health",badge:l,badgeColor:"zinc"}),a.jsx(S,{children:a.jsxs("div",{className:"flex flex-col h-full",children:[a.jsxs("div",{className:"flex items-baseline gap-2",children:[a.jsxs("div",{className:"type-data-xl text-fg-primary",children:[h?a.jsx(ue,{value:Math.round(10*r.efficiency)/10,className:"font-mono tabular-nums",priority:"medium",format:{minimumFractionDigits:1,maximumFractionDigits:1}}):a.jsx("span",{className:"opacity-30",children:"—"}),a.jsx("span",{className:"type-data-sm text-fg-muted ml-0.5",children:"%"})]}),h&&a.jsx("div",{className:`w-2 h-2 rounded-full ${ft[m]}`})]}),a.jsx("div",{className:"type-micro mb-2 cursor-help",title:"Forwarded packets / total received. CRC failures, garbled packets, and RF collisions that destroy packets before reaching software are not included in this ratio — see CRC Errors for hardware-level failures.",children:"FORWARDING RATE"}),a.jsx("div",{className:"flex-1 min-h-[28px] max-h-[48px] mb-2",children:a.jsx(xe,{data:r.sparkline,width:9999,height:36,color:"var(--sys-blue)",className:"w-full"})}),a.jsxs("div",{className:"flex gap-2 sm:gap-3 mt-auto",children:[a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"data-box-label",children:"Dupes"}),a.jsx("div",{className:"data-box data-box-fill data-box-left",children:h?`${r.duplicateRate.toFixed(1)}%`:"—"})]}),a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsx("div",{className:"data-box-label",children:"Waste"}),a.jsx("div",{className:"data-box data-box-fill data-box-left",children:h?`${r.wasteRate.toFixed(1)}%`:"—"})]}),null!==o&&o>0&&a.jsxs("div",{className:"flex-1 min-w-0",children:[a.jsxs("div",{className:"data-box-label flex items-center gap-1",children:[a.jsx(U,{className:"w-3 h-3 text-status-warning"}),"CRC"]}),a.jsx("div",{className:"data-box data-box-fill data-box-left text-status-warning",children:o})]})]})]})})]})})}function yt(){var e,t,n,l,i,r,o,c,d,m,u,h,x,p,g,f,b;const y=C(),j=T(),v=A(),N=F(),w=P(),M=L(),S=null!==y&&w,H=s.useRef(!1);S&&!H.current&&(H.current=!0);const O=H.current,W=R(),q=$(),I=D(),[G,V]=s.useState(null),[,Y]=s.useState(null),[K]=s.useState(null),[X,U]=s.useState(()=>{const e=localStorage.getItem("statistics-view-mode");return"share"===e||"airtime"===e?e:"airtime"});s.useEffect(()=>{localStorage.setItem("statistics-view-mode",X)},[X]);const[J,Q]=s.useState(()=>{const e=localStorage.getItem("statistics-smoothing-mode");return["ema","ultra","mosaic","stats","trend"].includes(e)?e:"stats"});s.useEffect(()=>{localStorage.setItem("statistics-smoothing-mode",J)},[J]);const[se,ae]=s.useState(!1),[ne,le]=s.useState(!1),[me,ue]=s.useState(ve),[he,xe]=s.useState(.5),[Me,Se]=s.useState(pe),[Ce,Te]=s.useState(.8),[Ae,Fe]=s.useState(50),Pe=s.useMemo(()=>({0:0,1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9}[W]??3),[W]),Le=_[Pe].hours,Re=60*Le,$e=_[Pe],De=z(Le),_e=M.isBackgroundLoading,ze=s.useCallback(e=>{q({0:1,1:2,2:3,3:4,4:5,5:6,6:7,7:8,8:9,9:10}[e]??4)},[q]),Ee=s.useMemo(()=>{var e;if(!(null==(e=null==y?void 0:y.config)?void 0:e.radio))return null;const t=y.config.radio;return{sf:t.spreading_factor??10,bw:t.bandwidth??25e4,cr:t.coding_rate??5,preamble:t.preamble_length??8}},[null==(t=null==(e=null==y?void 0:y.config)?void 0:e.radio)?void 0:t.spreading_factor,null==(l=null==(n=null==y?void 0:y.config)?void 0:n.radio)?void 0:l.bandwidth,null==(r=null==(i=null==y?void 0:y.config)?void 0:i.radio)?void 0:r.coding_rate,null==(c=null==(o=null==y?void 0:y.config)?void 0:o.radio)?void 0:c.preamble_length]),We=s.useMemo(()=>0===I.length?{timestamps:[],values:[]}:{timestamps:I.map(e=>e.timestamp),values:I.map(e=>e.noise_floor_dbm)},[I]),qe=s.useMemo(()=>{if(I.length<10)return{anomalies:[],debug:void 0};const e=function(e,t={}){const s={...ve,...t};if(e.length<10)return{anomalies:[],thresholds:we([]),totalSamples:e.length,anomalySamples:0};const a=e.map(e=>e.noise_floor_dbm),n=we(a),l=[...a].sort((e,t)=>e-t);let i,r;s.useAbsoluteThresholds?(i=s.baselineDbm,r=s.spikeDbm):(i=Ne(l,s.baselinePercentile),r=Ne(l,s.spikePercentile));const o=[...e].sort((e,t)=>e.timestamp-t.timestamp),c=[];let d=null,m=0;for(const u of o)if(u.noise_floor_dbm>i&&u.noise_floor_dbme+t,0)/d.values.length):(d.values.length>=s.minSequenceLength&&c.push(d),d={startTs:u.timestamp,endTs:u.timestamp,values:[u.noise_floor_dbm],timestamps:[u.timestamp],rollingAvg:u.noise_floor_dbm})}else d={startTs:u.timestamp,endTs:u.timestamp,values:[u.noise_floor_dbm],timestamps:[u.timestamp],rollingAvg:u.noise_floor_dbm};else d&&d.values.length>=s.minSequenceLength&&c.push(d),d=null;return d&&d.values.length>=s.minSequenceLength&&c.push(d),0===c.length?{anomalies:[],thresholds:n,totalSamples:e.length,anomalySamples:m,debug:{baselineCutoff:i,spikeCutoff:r,midBandSamples:m}}:{anomalies:c.map(e=>{const t=Math.max(...e.values),s=e.values.reduce((e,t)=>e+t,0)/e.values.length;return{startTs:e.startTs,endTs:e.endTs,peakValue:t,avgValue:s,severity:ke(s,i,r),sampleCount:e.values.length}}),thresholds:n,totalSamples:e.length,anomalySamples:m,debug:{baselineCutoff:i,spikeCutoff:r,midBandSamples:m}}}(I,me);return{anomalies:e.anomalies,debug:e.debug}},[I,me]),Ie=qe.anomalies,Ge=s.useMemo(()=>{const e=(null==y?void 0:y.neighbors)??{};return Object.fromEntries(Object.entries(e).filter(([e])=>!j.has(e)))},[null==y?void 0:y.neighbors,j]),Ve=s.useMemo(()=>{const e=Date.now()/1e3-3600*Le;return Object.fromEntries(Object.entries(Ge).filter(([,t])=>t.last_seen>=e))},[Ge,Le]),Ye=s.useMemo(()=>{const e=60*Re/De,t=Math.floor(Date.now()/1e3),s=Math.floor(t/e)*e;return{start:s-60*Re,end:s}},[Re,De]),Ke=Me.timeStart??Ye.start,Xe=Me.timeEnd??Ye.end,Je=z((Xe-Ke)/3600),Qe=be(),Ze=s.useMemo(()=>ge(N,Me,Qe,Ye),[N,Me,Qe,Ye]);return a.jsxs(oe,{children:[a.jsx(ce,{title:"Statistics",icon:a.jsx(Z,{}),controls:a.jsx(ie,{ranges:_,selectedIndex:Pe,onSelect:ze,isPending:_e})}),K&&a.jsx(re,{className:"border border-sys-red/50 bg-sys-red/10",children:a.jsx("p",{className:"text-sys-red",children:K})}),se&&ne&&a.jsxs(re,{className:"border border-sys-indigo/30 bg-surface/50",children:[a.jsxs("div",{className:"flex items-center justify-between mb-3",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"type-label",children:"Anomaly Detection Tuning"}),a.jsxs("span",{className:"type-data-xs text-fg-muted",children:["(",$e.label,")"]})]}),a.jsx("button",{onClick:()=>ue(e=>({...e,useAbsoluteThresholds:!e.useAbsoluteThresholds})),className:"type-data-xs px-2 py-1 rounded transition-colors "+(me.useAbsoluteThresholds?"bg-sys-indigo/30 text-sys-indigo":"bg-elevated text-fg-muted hover:text-fg-secondary"),children:me.useAbsoluteThresholds?"Absolute dBm":"Percentile"})]}),a.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Baseline"}),a.jsxs("span",{className:"ml-2 type-data-sm text-status-warning",children:[(null==(m=null==(d=qe.debug)?void 0:d.baselineCutoff)?void 0:m.toFixed(1))??"—"," dBm"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Spike"}),a.jsxs("span",{className:"ml-2 type-data-sm text-status-warning",children:[(null==(h=null==(u=qe.debug)?void 0:u.spikeCutoff)?void 0:h.toFixed(1))??"—"," dBm"]})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Mid-band"}),a.jsx("span",{className:"ml-2 type-data-sm text-sys-indigo",children:(null==(x=qe.debug)?void 0:x.midBandSamples)??0})]}),a.jsxs("div",{children:[a.jsx("span",{className:"type-micro",children:"Anomalies"}),a.jsx("span",{className:"ml-2 type-data-sm text-status-danger",children:Ie.length})]})]}),a.jsxs("div",{className:"mt-4 pt-4 border-t border-edge-subtle space-y-4",children:[me.useAbsoluteThresholds?a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Baseline (",me.baselineDbm," dBm)"]}),a.jsx("input",{type:"range",min:"-120",max:"-60",value:me.baselineDbm,onChange:e=>ue(t=>({...t,baselineDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Spike (",me.spikeDbm," dBm)"]}),a.jsx("input",{type:"range",min:"-100",max:"-20",value:me.spikeDbm,onChange:e=>ue(t=>({...t,spikeDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Merge Gap (",me.mergeGapSeconds,"s)"]}),a.jsx("input",{type:"range",min:"5",max:"120",step:"5",value:me.mergeGapSeconds,onChange:e=>ue(t=>({...t,mergeGapSeconds:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Min Sequence (",me.minSequenceLength,")"]}),a.jsx("input",{type:"range",min:"2",max:"20",value:me.minSequenceLength,onChange:e=>ue(t=>({...t,minSequenceLength:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Similarity (±",me.similarityToleranceDbm," dBm)"]}),a.jsx("input",{type:"range",min:"1",max:"15",value:me.similarityToleranceDbm,onChange:e=>ue(t=>({...t,similarityToleranceDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Opacity (",Math.round(100*he),"%)"]}),a.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:he,onChange:e=>xe(Number(e.target.value)),className:"w-full accent-sys-indigo"})]})]})]}):a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Baseline (P",me.baselinePercentile,")"]}),a.jsx("input",{type:"range",min:"1",max:"50",value:me.baselinePercentile,onChange:e=>ue(t=>({...t,baselinePercentile:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Spike (P",me.spikePercentile,")"]}),a.jsx("input",{type:"range",min:"50",max:"99",value:me.spikePercentile,onChange:e=>ue(t=>({...t,spikePercentile:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Merge Gap (",me.mergeGapSeconds,"s)"]}),a.jsx("input",{type:"range",min:"5",max:"120",step:"5",value:me.mergeGapSeconds,onChange:e=>ue(t=>({...t,mergeGapSeconds:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]})]}),a.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Min Sequence (",me.minSequenceLength,")"]}),a.jsx("input",{type:"range",min:"2",max:"20",value:me.minSequenceLength,onChange:e=>ue(t=>({...t,minSequenceLength:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Similarity (±",me.similarityToleranceDbm," dBm)"]}),a.jsx("input",{type:"range",min:"1",max:"15",value:me.similarityToleranceDbm,onChange:e=>ue(t=>({...t,similarityToleranceDbm:Number(e.target.value)})),className:"w-full accent-sys-indigo"})]}),a.jsxs("div",{children:[a.jsxs("label",{className:"type-micro block mb-1",children:["Opacity (",Math.round(100*he),"%)"]}),a.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:he,onChange:e=>xe(Number(e.target.value)),className:"w-full accent-sys-indigo"})]})]})]}),a.jsxs("div",{className:"mt-4 p-3 bg-elevated radius-inner",children:[a.jsx("div",{className:"type-micro mb-1",children:"Config output"}),a.jsxs("div",{className:"type-data-sm text-status-success",children:[me.useAbsoluteThresholds?`useAbsoluteThresholds: true, baselineDbm: ${me.baselineDbm}, spikeDbm: ${me.spikeDbm}`:`useAbsoluteThresholds: false, baselinePercentile: ${me.baselinePercentile}, spikePercentile: ${me.spikePercentile}`,", mergeGapSeconds: ",me.mergeGapSeconds,", minSequenceLength: ",me.minSequenceLength,", similarityToleranceDbm: ",me.similarityToleranceDbm]})]})]})]}),a.jsxs(de,{children:[a.jsx("div",{className:"sm:hidden",children:_e&&a.jsx(ye,{template:"auto",children:a.jsx(re,{className:"border border-sys-blue/30 bg-sys-blue/5",children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsxs("div",{className:"relative flex h-3 w-3",children:[a.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-sys-blue opacity-75"}),a.jsx("span",{className:"relative inline-flex rounded-full h-3 w-3 bg-sys-blue"})]}),a.jsxs("div",{className:"flex-1",children:[a.jsxs("p",{className:"type-body-sm text-fg-primary",children:["Loading ",$e.label," data..."]}),M.loadProgress&&a.jsxs("p",{className:"type-data-xs text-fg-muted mt-0.5",children:[M.loadProgress.loaded.toLocaleString()," packets (",M.loadProgress.percent,"%)"]})]})]})})})}),O?a.jsxs(a.Fragment,{children:[a.jsx(ye,{template:"hero-auto",children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(B,{}),title:"Packet Analyzer",badge:$e.label,badgeColor:"zinc",stackActionsOnMobile:!0,actions:a.jsxs("div",{className:"flex flex-wrap items-center gap-2 justify-end",children:["stats"===J&&a.jsx(Oe,{enabled:se,onChange:ae,anomalyCount:Ie.length,showTuning:ne,onTuningChange:le}),a.jsx(Be,{smoothing:J,onChange:Q}),a.jsx(He,{mode:X,onChange:U})]})}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(Ue,{packets:Ze,allPackets:N,startTs:Ke,endTs:Xe,parentStartTs:Ye.start,parentEndTs:Ye.end,bucketCount:Je,radioConfig:Ee??void 0,mode:X,smoothing:J,noiseFloorAnomalies:Ie,showNoiseFloorOverlay:se,overlayOpacity:he,dotSize:Ce,dotOpacity:Ae/100})})]})})}),a.jsx(ye,{template:"auto",className:"relative z-10",children:a.jsx(re,{neomorphic:!0,noPadding:!0,isLoaded:O,className:"overflow-visible",children:O&&a.jsx(fe,{parentStartTs:Ye.start,parentEndTs:Ye.end,neighbors:Ge,filter:Me,onChange:Se,..."stats"===J?{scatterDotSize:Ce,onScatterDotSizeChange:Te,scatterOpacity:Ae,onScatterOpacityChange:Fe}:{}})})}),a.jsxs(ye,{template:"panel",children:[a.jsx(je,{span:12,md:6,children:a.jsx(re,{neomorphic:!1,isLoaded:O,skeletonType:"chart",noPadding:O,className:"!bg-transparent !ring-0 !shadow-none !overflow-visible -mx-4 sm:mx-0 !px-0 !pr-0",children:O&&a.jsx(dt,{children:a.jsx(it,{neighbors:Ve,quickNeighbors:v,localLat:(null==(g=null==(p=null==y?void 0:y.config)?void 0:p.repeater)?void 0:g.latitude)??0,localLon:(null==(b=null==(f=null==y?void 0:y.config)?void 0:f.repeater)?void 0:b.longitude)??0,onStatsChange:Y,title:"Link Quality",badge:$e.label})})})}),a.jsx(je,{span:12,md:6,children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(ee,{}),title:"Network Composition",badge:$e.label,badgeColor:"zinc"}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(dt,{children:a.jsx(ct,{neighbors:Ve})})})]})})})]}),a.jsxs(ye,{template:"panel",children:[a.jsx(je,{span:12,md:6,children:a.jsx(xt,{})}),a.jsx(je,{span:12,md:6,children:a.jsx(bt,{packets:N,rangeMinutes:Re,rangeHours:Le,timeRangeLabel:$e.label,isLoaded:O})})]}),a.jsx(ye,{template:"panel",children:a.jsx(je,{span:12,children:a.jsx(re,{neomorphic:!0,isLoaded:O,skeletonType:"chart",children:O&&a.jsxs(a.Fragment,{children:[a.jsx(k,{icon:a.jsx(te,{}),title:"NOISE FLOOR dBm",stackActionsOnMobile:!0,actions:G?a.jsxs("div",{className:"flex items-center gap-2 sm:gap-3",children:[a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["min ",a.jsx("span",{className:"data-box",children:G.min.toFixed(0)})]}),a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["avg ",a.jsx("span",{className:"data-box",children:G.avg.toFixed(0)})]}),a.jsxs("span",{className:"type-data-xs text-fg-muted whitespace-nowrap",children:["max ",a.jsx("span",{className:"data-box",children:G.max.toFixed(0)})]})]}):null}),a.jsx("div",{className:"flex-1 min-h-0",children:a.jsx(dt,{children:a.jsx(E,{timestamps:We.timestamps,values:We.values,onStatsChange:V})})})]})})})})]}):a.jsx(ye,{template:"auto",children:a.jsx(re,{neomorphic:!0,className:"text-center py-12",children:a.jsx("div",{className:"animate-pulse text-fg-muted",children:"Loading statistics..."})})})]})]})}export{yt as default}; diff --git a/frontend/dist/assets/System-ClKsjWUq.js b/frontend/dist/assets/System-RKAKlnZ6.js similarity index 99% rename from frontend/dist/assets/System-ClKsjWUq.js rename to frontend/dist/assets/System-RKAKlnZ6.js index bc8b5604..60487ec6 100644 --- a/frontend/dist/assets/System-ClKsjWUq.js +++ b/frontend/dist/assets/System-RKAKlnZ6.js @@ -1 +1 @@ -import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{bf as r,bb as n,d as a,q as l,bg as o,bh as i,bi as c,bj as d,bk as m,aH as u,B as x,bl as p,bm as h}from"./index-D7i6lQrq.js";import{C as f,P as g,a as y,B as j}from"./PageLayout-QhCLxU34.js";import{u as b}from"./vendor-charts-C916_-gs.js";import{a3 as v,$ as w,ak as N,V as M,aV as R,a7 as k,aW as C,aX as S,aY as F}from"./vendor-icons-TO0PZKGR.js";import{R as _,C as B}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const P=[{pos:0,color:r(n.purple)},{pos:.25,color:r(n.indigo)},{pos:.5,color:r(n.cyan)},{pos:.75,color:r(n.amber)},{pos:1,color:r(n.red)}];function $(e){const s=Math.max(0,Math.min(1,e));let t=P[0],r=P[P.length-1];for(let l=0;l=P[l].pos&&s<=P[l+1].pos){t=P[l],r=P[l+1];break}const n=r.pos-t.pos,a=n>0?(s-t.pos)/n:0;return function(e,s,t){const r=2.2,n=1/r,a=Math.pow(e.r/255,r),l=Math.pow(e.g/255,r),o=Math.pow(e.b/255,r),i=Math.pow(s.r/255,r),c=Math.pow(s.g/255,r),d=Math.pow(s.b/255,r);return{r:Math.round(255*Math.pow(a+t*(i-a),n)),g:Math.round(255*Math.pow(l+t*(c-l),n)),b:Math.round(255*Math.pow(o+t*(d-o),n))}}(t.color,r.color,a)}const E=a.hero;function T(){const e=getComputedStyle(document.documentElement);return{fontFamily:e.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',textPrimary:e.getPropertyValue("--text-primary").trim()||"#FFFFFF",textMuted:e.getPropertyValue("--text-muted").trim()||"#727272",gridColor:e.getPropertyValue("--chart-grid").trim()||"rgba(255, 255, 255, 0.06)"}}const A=e.memo(function({data:t,cpuColor:r,memoryColor:n}){const a=e.useRef(null),l=e.useRef(null),o=e.useRef([]),i=e.useRef(r),c=e.useRef(n),d=e.useRef(null),m=e.useRef(t.length);e.useLayoutEffect(()=>{i.current=r,c.current=n}),e.useEffect(()=>{d.current=T()},[]);const u=e.useMemo(()=>function(e){const s=[],t=Math.max(0,E-e.length);for(let n=0;n{o.current=u},[u]);const x=e.useMemo(()=>[u.map(e=>e.timestamp),new Array(u.length).fill(1)],[u]),p=e.useMemo(()=>({hooks:{draw:e=>{const s=d.current||T();!function(e,s,t,r,n){if(0===s.length)return;const a=e.ctx,{left:l,top:o,width:i,height:c}=e.bbox,d=window.devicePixelRatio||1;if(i<=0||c<=0)return;const m=s.length;if(0===m)return;const u=i/m,x=e=>l+(e+.5)*u,p=e=>{const s=Math.min(Math.max(e/100,0),1);return o+c*(1-s)};a.save(),a.strokeStyle=n.textPrimary,a.globalAlpha=.1,a.lineWidth=1*d,a.setLineDash([4*d,4*d]);for(const b of[25,50,75]){const e=Math.round(p(b))+.5;a.beginPath(),a.moveTo(Math.round(l),e),a.lineTo(Math.round(l+i),e),a.stroke()}a.restore(),a.save(),a.font=`bold ${10*d}px ${n.fontFamily}`,a.fillStyle=n.textMuted,a.textBaseline="middle",a.textAlign="left";const h=8*d;for(const b of[0,25,50,75,100]){const e=p(b),s=Math.max(o+h,Math.min(o+c-h,e));a.fillText(`${b}%`,4*d,s)}a.restore(),a.save();for(let b=0;b0){const e=s[m-1];(null==e?void 0:e.time)&&(a.textAlign="right",a.fillText(e.time,x(m-1),y))}a.restore()}(e,o.current,i.current,c.current,s)}}}),[]),h=e.useMemo(()=>({width:400,height:240,padding:[4,8,4,36],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!1},y:{range:[0,100]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[p]}),[p]);return e.useEffect(()=>{const e=a.current;if(!e||0===u.length)return;const s=m.current,r=t.length,n=Math.abs(r-s);if(!(!l.current||n>50||s>0&&n/s>.2)&&l.current)return l.current.setData(x),void(m.current=r);l.current&&l.current.destroy();const o=e.getBoundingClientRect(),i=Math.floor(o.width)||400,c=Math.floor(o.height)||240,d=new b({...h,width:i,height:c},x,e);return l.current=d,m.current=r,()=>{d.destroy(),l.current=null}},[h,x,u.length,t.length]),e.useEffect(()=>{const e=a.current;if(!e)return;const s=new ResizeObserver(e=>{const s=e[0];if(!s||!l.current)return;const{width:t,height:r}=s.contentRect;t>0&&r>0&&l.current.setSize({width:Math.floor(t),height:Math.floor(r)})});return s.observe(e),()=>{s.disconnect()}},[]),e.useEffect(()=>{l.current&&l.current.redraw()},[r,n,u]),0===t.length?s.jsx("div",{className:"flex-1 min-h-[180px] flex items-center justify-center text-fg-muted",children:"Collecting data..."}):s.jsx("div",{className:"relative flex-1 min-h-[180px]",children:s.jsx("div",{ref:a,className:"absolute inset-0 radius-inner overflow-hidden"})})}),L=e.memo(function({data:t,color:r,flipped:n=!1,fixedSlots:a}){const l=e.useRef(null),o=e.useRef(null),i=e.useRef(t),c=e.useRef(r),d=e.useRef(n),m=e.useRef(a);e.useLayoutEffect(()=>{i.current=t,c.current=r,d.current=n,m.current=a});const u=e.useMemo(()=>[Array.from({length:a},(e,s)=>s),new Array(a).fill(1)],[a]),x=e.useMemo(()=>({hooks:{draw:e=>{!function(e,s,t,r,n){const a=e.ctx,{left:l,top:o,width:i,height:c}=e.bbox;if(i<=0||c<=0)return;const d=[...Array(Math.max(0,n-s.length)).fill(0),...s.slice(-n)],m=Math.max(...d,1),u=d.length,x=i/u,p=.03*c;a.save();for(let h=0;h({width:400,height:40,padding:[0,0,0,0],legend:{show:!1},cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1,label:""}],plugins:[x]}),[x]);return e.useEffect(()=>{const e=l.current;if(!e)return;o.current&&o.current.destroy();const s=e.getBoundingClientRect(),t=Math.floor(s.width)||400,r=Math.floor(s.height)||40,n=new b({...p,width:t,height:r},u,e);return o.current=n,()=>{n.destroy(),o.current=null}},[p,u]),e.useEffect(()=>{const e=l.current;if(!e)return;const s=new ResizeObserver(e=>{const s=e[0];if(!s||!o.current)return;const{width:t,height:r}=s.contentRect;t>0&&r>0&&o.current.setSize({width:Math.floor(t),height:Math.floor(r)})});return s.observe(e),()=>{s.disconnect()}},[]),e.useEffect(()=>{o.current&&o.current.redraw()},[t,r,n]),s.jsx("div",{ref:l,className:"w-full h-full"})}),D={warning:80,danger:95},G={warning:85,danger:95},O={warning:70,danger:85},U=[{threshold:30,color:"var(--sys-cyan)"},{threshold:50,color:"var(--sys-blue)"},{threshold:65,color:"var(--sys-indigo)"},{threshold:80,color:"var(--signal-poor)"}];function V(e,s,t){const r=t-s,n={cold:(30-s)/r*100,normal:(50-s)/r*100,warm:(65-s)/r*100,hot:(80-s)/r*100};return`linear-gradient(to right, ${[{pos:0,color:"var(--sys-cyan)"},{pos:n.cold,color:"var(--sys-cyan)"},{pos:n.cold,color:"var(--sys-blue)"},{pos:n.normal,color:"var(--sys-blue)"},{pos:n.normal,color:"var(--sys-indigo)"},{pos:n.warm,color:"var(--sys-indigo)"},{pos:n.warm,color:"var(--signal-poor)"},{pos:n.hot,color:"var(--signal-poor)"},{pos:n.hot,color:"var(--sys-red)"},{pos:100,color:"var(--sys-red)"}].map(s=>{const t=e>0?s.pos/e*100:0;return`${s.color} ${Math.min(t,100)}%`}).join(", ")})`}function H(e,s){return e>=s.danger?"danger":e>=s.warning?"warning":"none"}function W(e){let s="none";for(const t of Object.values(e)){const e=H(t,O);if("danger"===e)return"danger";"warning"===e&&(s="warning")}return s}function z(e){let s,t,r;return e>=1073741824?(s=e/1073741824,t="GB/s"):e>=1048576?(s=e/1048576,t="MB/s"):e>=1024?(s=e/1024,t="KB/s"):(s=e,t="B/s"),r=s>=100?s.toFixed(0):s.toFixed(1),`${r} ${t}`}function I(e){return e>=1073741824?{value:(e/1073741824).toFixed(1),unit:"GiB"}:e>=1048576?{value:(e/1048576).toFixed(1),unit:"MiB"}:e>=1024?{value:(e/1024).toFixed(1),unit:"KiB"}:{value:String(e),unit:"B"}}const X=e.memo(function({level:e}){return"none"===e?null:s.jsxs("span",{className:t("inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium","danger"===e&&"bg-sys-red/20 text-sys-red","warning"===e&&"bg-sys-indigo/20 text-sys-indigo"),children:[s.jsx(v,{className:"w-3 h-3"}),"danger"===e?"High":"Warn"]})}),J=e.memo(function({value:e,max:t=100,width:r=10,color:n="primary"}){const a=Math.min(e/t,1),l=Math.round(a*r),o=r-l,i="■".repeat(l),c="·".repeat(o),d={primary:"text-sys-blue",secondary:"text-sys-indigo",success:"text-sys-green",danger:"text-sys-red"}[n];return s.jsxs("span",{className:"font-mono text-[10px] tracking-tight",children:[s.jsx("span",{className:d,children:i}),s.jsx("span",{className:"text-fg-muted/40",children:c})]})}),K=e.memo(function({index:e,usage:r}){const n=r>90?"danger":r>70?"secondary":"primary";return s.jsxs("div",{className:"flex items-center gap-1 type-data-xs",children:[s.jsxs("span",{className:"text-fg-muted w-5",children:["C",e]}),s.jsx(J,{value:r,width:8,color:n}),s.jsxs("span",{className:t("w-7 text-right tabular-nums",r>90?"text-sys-red":r>70?"text-sys-indigo":"text-sys-green"),children:[r.toFixed(0),"%"]})]})}),Y=e.memo(function({pid:e,name:r,cpu:n,mem:a,isTopCpu:l=!1,isTopMem:o=!1}){return s.jsxs("div",{className:"flex items-center gap-2 py-1 type-data-sm hover:bg-subtle-fill -mx-1 px-1 rounded",children:[s.jsx("span",{className:"text-fg-muted w-10 sm:w-14 tabular-nums",children:e}),s.jsx("span",{className:"flex-1 truncate text-fg-primary",children:r}),s.jsx("span",{className:"hidden sm:inline-flex",children:s.jsx(J,{value:n,max:100,width:6,color:n>50?"danger":n>20?"secondary":"success"})}),s.jsx("span",{className:t("w-10 sm:w-12 text-right tabular-nums",l?"text-fg-primary":n>50?"text-sys-red":n>20?"text-sys-indigo":"text-fg-muted"),children:n.toFixed(1)}),s.jsx("span",{className:t("w-10 sm:w-12 text-right tabular-nums",o?"text-fg-primary":a>50?"text-sys-red":a>20?"text-sys-indigo":"text-fg-muted"),children:a.toFixed(1)})]})}),q=e.memo(function({value:e,label:t,min:r=20,max:n=100}){const a=Math.min(Math.max((e-r)/(n-r)*100,0),100),l=function(e){return e<30?{text:"Cool",color:"text-sys-cyan"}:e<50?{text:"Normal",color:"text-sys-blue"}:e<65?{text:"Warm",color:"text-sys-indigo"}:e<80?{text:"Hot",color:"text-signal-poor"}:{text:"Danger",color:"text-sys-red"}}(e),o=n-r;return s.jsxs("div",{className:"space-y-1.5",children:[s.jsxs("div",{className:"flex justify-between items-center",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:t}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:l.text}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded type-data-sm",children:[s.jsx("span",{className:l.color,children:e.toFixed(1)}),s.jsx("span",{className:"text-fg-primary",children:"°C"})]})]})]}),s.jsxs("div",{className:"relative h-3 rounded-full bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 rounded-full transition-all duration-300 ease-out",style:{background:V(a,r,n),width:`${a}%`}}),s.jsx("div",{className:"absolute inset-0 flex items-center pointer-events-none",children:U.map(({threshold:e,color:t})=>{const n=(e-r)/o*100;return n<0||n>100?null:s.jsx("div",{className:"absolute w-px h-full",style:{left:`${n}%`,backgroundColor:t}},e)})})]})]})});e.memo(function({data:e,color:t,flipped:r=!1,fixedSlots:n}){const a=[...Array(Math.max(0,n-e.length)).fill(0),...e.slice(-n)],l=Math.max(...a,1),o=a.map(e=>0===e?0:Math.max(e/l*100,3));return s.jsx("div",{className:"w-full h-full flex items-end",style:{transform:r?"scaleY(-1)":void 0},children:o.map((e,r)=>s.jsx("div",{className:"flex-1 min-w-0",style:{height:e>0?`${e}%`:"0%",backgroundColor:e>0?t:"transparent"}},r))})});const Q=e.memo(function({networkHistory:e,txRate:t,rxRate:r,totalBytesSent:n,totalBytesRecv:a,cpuColor:o,memoryColor:i,networkSlots:c}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(N,{}),title:"Network",actions:s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx(w,{className:"w-3.5 h-3.5",style:{color:i}}),s.jsx("span",{className:"type-data-xs",style:{color:i},children:"TX"}),s.jsx("span",{className:"px-2 py-1 bg-subtle-fill-strong rounded type-data-sm text-fg-primary",children:z(t)})]})}),s.jsxs("div",{className:"flex flex-col h-[120px]",children:[s.jsx("div",{className:"h-[60px]",children:s.jsx(L,{data:e.map((e,s,t)=>{if(0===s)return 0;const r=(e.timestamp-t[s-1].timestamp)/1e3;return r>0?(e.bytesSent-t[s-1].bytesSent)/r:0}),color:i,fixedSlots:c})}),s.jsx("div",{className:"h-[60px]",children:s.jsx(L,{data:e.map((e,s,t)=>{if(0===s)return 0;const r=(e.timestamp-t[s-1].timestamp)/1e3;return r>0?(e.bytesRecv-t[s-1].bytesRecv)/r:0}),color:o,flipped:!0,fixedSlots:c})})]}),s.jsxs("div",{className:"pt-2 flex flex-wrap justify-between items-center gap-2 type-data-sm",children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"text-fg-muted",children:"Total"}),s.jsxs("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums",children:[s.jsx("span",{style:{color:i},children:I(n).value})," ",s.jsx("span",{className:"text-fg-muted",children:I(n).unit})]}),s.jsxs("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums",children:[s.jsx("span",{style:{color:o},children:I(a).value})," ",s.jsx("span",{className:"text-fg-muted",children:I(a).unit})]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx(M,{className:"w-3.5 h-3.5",style:{color:o}}),s.jsx("span",{className:"type-data-xs",style:{color:o},children:"RX"}),s.jsx("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:z(r)})]})]})]})}),Z=e.memo(function({temperatures:e}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(R,{}),title:"Temperature",actions:e&&s.jsx(X,{level:W(e)})}),s.jsx("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:e&&Object.keys(e).length>0?s.jsxs("div",{className:"space-y-3",children:[void 0!==e.cpu_thermal&&s.jsx(q,{value:e.cpu_thermal,label:"CPU",min:20,max:100}),Object.entries(e).filter(([e])=>"cpu_thermal"!==e).slice(0,2).map(([e,t])=>s.jsx(q,{value:t,label:e.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),min:20,max:100},e))]}):s.jsxs("div",{className:"flex items-center justify-center text-fg-muted text-sm",children:[s.jsx(k,{className:"w-4 h-4 mr-2"}),"No sensors"]})})]})}),ee=e.memo(function({usagePercent:e,used:t,available:r,memoryColor:n}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"Memory",actions:s.jsxs("span",{className:"px-2 py-0.5 bg-subtle-fill-strong rounded type-data",style:{color:n},children:[e.toFixed(0),"%"]})}),s.jsxs("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:[s.jsxs("div",{className:"flex gap-1 h-12 radius-inner bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"h-full transition-all duration-300 bg-sys-blue",style:{width:`${e}%`}}),s.jsx("div",{className:"h-full transition-all duration-300 bg-subtle-fill/80",style:{width:100-e+"%"}})]}),s.jsxs("div",{className:"flex items-center justify-between type-data-xs pt-2",children:[s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-sys-blue"}),s.jsx("span",{className:"text-fg-muted",children:"Used"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:[(t/1048576).toFixed(0)," MB"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-subtle-fill-strong depth-stroke-raised"}),s.jsx("span",{className:"text-fg-muted",children:"Avail"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-muted",children:[(r/1048576).toFixed(0)," MB"]})]})]})]})]})}),se=e.memo(function({usagePercent:e,used:t,free:r,cpuColor:n}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(C,{}),title:"Disk",actions:s.jsxs("span",{className:"px-2 py-0.5 bg-subtle-fill-strong rounded type-data",style:{color:n},children:[e.toFixed(0),"%"]})}),s.jsxs("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:[s.jsxs("div",{className:"flex gap-1 h-12 radius-inner bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"h-full transition-all duration-300 bg-sys-blue",style:{width:`${e}%`}}),s.jsx("div",{className:"h-full transition-all duration-300 bg-subtle-fill/80",style:{width:100-e+"%"}})]}),s.jsxs("div",{className:"flex items-center justify-between type-data-xs pt-2",children:[s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-sys-blue"}),s.jsx("span",{className:"text-fg-muted",children:"Used"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:[(t/1073741824).toFixed(1)," GB"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-subtle-fill-strong depth-stroke-raised"}),s.jsx("span",{className:"text-fg-muted",children:"Free"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-muted",children:[(r/1073741824).toFixed(1)," GB"]})]})]})]})]})}),te=e.memo(function({processes:e}){if(0===e.length)return null;const t=e.slice(0,10),r=Math.max(...t.map(e=>e.cpu_percent)),n=Math.max(...t.map(e=>e.memory_percent));return s.jsx(f,{neomorphic:!0,noPadding:!0,children:s.jsxs("div",{className:"px-4 py-3",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"Processes"}),s.jsxs("div",{className:"flex items-center gap-2 py-1.5 type-data-sm text-fg-muted",children:[s.jsx("span",{className:"w-10 sm:w-14",children:"PID"}),s.jsx("span",{className:"flex-1",children:"Program"}),s.jsx("span",{className:"hidden sm:block w-[52px]"}),s.jsx("span",{className:"w-10 sm:w-12 text-right",children:"CPU%"}),s.jsx("span",{className:"w-10 sm:w-12 text-right",children:"MEM%"})]}),t.map(e=>s.jsx(Y,{pid:e.pid,name:e.name,cpu:e.cpu_percent,mem:e.memory_percent,isTopCpu:e.cpu_percent===r&&r>0,isTopMem:e.memory_percent===n&&n>0},e.pid))]})})}),re=a.hero;function ne(){var r;const n=o(),b=i(),v=c(),w=d(),N=m(),[M,R]=e.useState([]),[C,P]=e.useState(!1),[$,E]=e.useState([]),[T,L]=e.useState(0),[O,U]=e.useState(0),V=e.useRef(null),W=u(),z=W.blue,I=W.amber,J=function(){const[s,t]=e.useState("undefined"!=typeof window&&window.matchMedia("(max-width: 767px)").matches);return e.useEffect(()=>{const e=window.matchMedia("(max-width: 767px)");t(e.matches);const s=e=>t(e.matches);return e.addEventListener("change",s),()=>e.removeEventListener("change",s)},[]),s?a.hero:40}();return e.useEffect(()=>{if(!n)return;const e=Date.now(),s={timestamp:e,bytesRecv:n.network.bytes_recv,bytesSent:n.network.bytes_sent};if(V.current){const t=(e-V.current.timestamp)/1e3;if(t>0){const e=(s.bytesRecv-V.current.bytesRecv)/t,r=(s.bytesSent-V.current.bytesSent)/t;e>=0&&r>=0&&(L(e),U(r))}}V.current=s,E(e=>[...e,s].slice(-re))},[n]),e.useEffect(()=>{let e=!0;const s=async()=>{var s;const t=await h();e&&t.success&&(null==(s=t.data)?void 0:s.processes)&&R(t.data.processes)};s();const t=setInterval(s,5e3);return()=>{e=!1,clearInterval(t)}},[]),s.jsxs(g,{children:[s.jsx(y,{title:"System Stats",icon:s.jsx(F,{}),controls:s.jsxs(x,{color:"muted",onClick:async()=>{var e;P(!0),await w();const s=await h();s.success&&(null==(e=s.data)?void 0:e.processes)&&R(s.data.processes),P(!1)},disabled:C,children:[s.jsx(S,{"data-slot":"icon",className:t(C&&"animate-spin")}),"Refresh"]})}),s.jsxs(j,{children:[v&&s.jsx(f,{className:"border border-sys-red/50 bg-sys-red/10",children:s.jsx("p",{className:"text-sys-red",children:v})}),b?s.jsx(f,{neomorphic:!0,className:"p-12 text-center",children:s.jsx("div",{className:"animate-pulse text-fg-muted",children:"Loading system stats..."})}):n?s.jsxs(s.Fragment,{children:[s.jsx(_,{template:"hero",children:s.jsxs(f,{neomorphic:!0,className:"pb-2 sm:pb-3",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"System Resources",stackActionsOnMobile:!0,actions:s.jsxs("div",{className:"flex items-center gap-2 sm:gap-4 flex-wrap",children:[(null==(r=n.system)?void 0:r.uptime)&&s.jsx("span",{className:"px-2 py-0.5 bg-subtle-fill rounded type-data-sm text-fg-primary",children:p(n.system.uptime)}),s.jsx(X,{level:H(n.cpu.usage_percent,D)}),s.jsx(X,{level:H(n.memory.usage_percent,G)}),s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:"CPU"}),s.jsxs("span",{className:"text-sm sm:text-base font-mono font-semibold tabular-nums",style:{color:z},children:[n.cpu.usage_percent.toFixed(0),"%"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:"MEM"}),s.jsxs("span",{className:"text-sm sm:text-base font-mono font-semibold tabular-nums",style:{color:I},children:[n.memory.usage_percent.toFixed(0),"%"]})]})]})}),s.jsx("div",{className:"flex-1 min-h-0 flex flex-col",children:s.jsx(A,{data:N,cpuColor:z,memoryColor:I})}),n.cpu.per_core_percent&&n.cpu.per_core_percent.length>0&&s.jsx("div",{className:"mt-3 pt-3 border-t border-edge-subtle",children:s.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-x-3 gap-y-0.5",children:n.cpu.per_core_percent.map((e,t)=>s.jsx(K,{index:t,usage:e},t))})})]})}),s.jsxs(_,{template:"compact",children:[s.jsx(B,{span:12,md:6,children:s.jsx(Q,{networkHistory:$,txRate:O,rxRate:T,totalBytesSent:n.network.bytes_sent,totalBytesRecv:n.network.bytes_recv,cpuColor:z,memoryColor:I,networkSlots:J})}),s.jsx(B,{span:12,md:6,children:s.jsx(Z,{temperatures:n.temperatures})})]}),s.jsxs(_,{template:"compact",children:[s.jsx(B,{span:12,sm:6,children:s.jsx(ee,{usagePercent:n.memory.usage_percent,used:n.memory.used,available:n.memory.available,memoryColor:I})}),s.jsx(B,{span:12,sm:6,children:s.jsx(se,{usagePercent:n.disk.usage_percent,used:n.disk.used,free:n.disk.free,cpuColor:z})})]}),s.jsx(_,{template:"auto",children:s.jsx(te,{processes:M})})]}):null]})]})}export{ne as default}; +import{r as e,j as s}from"./vendor-react-alRNW2nb.js";import{c as t}from"./vendor-core-FtpmsTnh.js";import{bf as r,bb as n,d as a,q as l,bg as o,bh as i,bi as c,bj as d,bk as m,aH as u,B as x,bl as p,bm as h}from"./index-CkRTgHHA.js";import{C as f,P as g,a as y,B as j}from"./PageLayout-BWMUVZgC.js";import{u as b}from"./vendor-charts-C916_-gs.js";import{a3 as v,$ as w,ak as N,V as M,aV as R,a7 as k,aW as C,aX as S,aY as F}from"./vendor-icons-TO0PZKGR.js";import{R as _,C as B}from"./Grid-m53vqd2Y.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-motion-DNp0Qg4F.js";import"./vendor-fonts-CRZaZSFf.js";const P=[{pos:0,color:r(n.purple)},{pos:.25,color:r(n.indigo)},{pos:.5,color:r(n.cyan)},{pos:.75,color:r(n.amber)},{pos:1,color:r(n.red)}];function $(e){const s=Math.max(0,Math.min(1,e));let t=P[0],r=P[P.length-1];for(let l=0;l=P[l].pos&&s<=P[l+1].pos){t=P[l],r=P[l+1];break}const n=r.pos-t.pos,a=n>0?(s-t.pos)/n:0;return function(e,s,t){const r=2.2,n=1/r,a=Math.pow(e.r/255,r),l=Math.pow(e.g/255,r),o=Math.pow(e.b/255,r),i=Math.pow(s.r/255,r),c=Math.pow(s.g/255,r),d=Math.pow(s.b/255,r);return{r:Math.round(255*Math.pow(a+t*(i-a),n)),g:Math.round(255*Math.pow(l+t*(c-l),n)),b:Math.round(255*Math.pow(o+t*(d-o),n))}}(t.color,r.color,a)}const E=a.hero;function T(){const e=getComputedStyle(document.documentElement);return{fontFamily:e.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',textPrimary:e.getPropertyValue("--text-primary").trim()||"#FFFFFF",textMuted:e.getPropertyValue("--text-muted").trim()||"#727272",gridColor:e.getPropertyValue("--chart-grid").trim()||"rgba(255, 255, 255, 0.06)"}}const A=e.memo(function({data:t,cpuColor:r,memoryColor:n}){const a=e.useRef(null),l=e.useRef(null),o=e.useRef([]),i=e.useRef(r),c=e.useRef(n),d=e.useRef(null),m=e.useRef(t.length);e.useLayoutEffect(()=>{i.current=r,c.current=n}),e.useEffect(()=>{d.current=T()},[]);const u=e.useMemo(()=>function(e){const s=[],t=Math.max(0,E-e.length);for(let n=0;n{o.current=u},[u]);const x=e.useMemo(()=>[u.map(e=>e.timestamp),new Array(u.length).fill(1)],[u]),p=e.useMemo(()=>({hooks:{draw:e=>{const s=d.current||T();!function(e,s,t,r,n){if(0===s.length)return;const a=e.ctx,{left:l,top:o,width:i,height:c}=e.bbox,d=window.devicePixelRatio||1;if(i<=0||c<=0)return;const m=s.length;if(0===m)return;const u=i/m,x=e=>l+(e+.5)*u,p=e=>{const s=Math.min(Math.max(e/100,0),1);return o+c*(1-s)};a.save(),a.strokeStyle=n.textPrimary,a.globalAlpha=.1,a.lineWidth=1*d,a.setLineDash([4*d,4*d]);for(const b of[25,50,75]){const e=Math.round(p(b))+.5;a.beginPath(),a.moveTo(Math.round(l),e),a.lineTo(Math.round(l+i),e),a.stroke()}a.restore(),a.save(),a.font=`bold ${10*d}px ${n.fontFamily}`,a.fillStyle=n.textMuted,a.textBaseline="middle",a.textAlign="left";const h=8*d;for(const b of[0,25,50,75,100]){const e=p(b),s=Math.max(o+h,Math.min(o+c-h,e));a.fillText(`${b}%`,4*d,s)}a.restore(),a.save();for(let b=0;b0){const e=s[m-1];(null==e?void 0:e.time)&&(a.textAlign="right",a.fillText(e.time,x(m-1),y))}a.restore()}(e,o.current,i.current,c.current,s)}}}),[]),h=e.useMemo(()=>({width:400,height:240,padding:[4,8,4,36],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!1},y:{range:[0,100]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[p]}),[p]);return e.useEffect(()=>{const e=a.current;if(!e||0===u.length)return;const s=m.current,r=t.length,n=Math.abs(r-s);if(!(!l.current||n>50||s>0&&n/s>.2)&&l.current)return l.current.setData(x),void(m.current=r);l.current&&l.current.destroy();const o=e.getBoundingClientRect(),i=Math.floor(o.width)||400,c=Math.floor(o.height)||240,d=new b({...h,width:i,height:c},x,e);return l.current=d,m.current=r,()=>{d.destroy(),l.current=null}},[h,x,u.length,t.length]),e.useEffect(()=>{const e=a.current;if(!e)return;const s=new ResizeObserver(e=>{const s=e[0];if(!s||!l.current)return;const{width:t,height:r}=s.contentRect;t>0&&r>0&&l.current.setSize({width:Math.floor(t),height:Math.floor(r)})});return s.observe(e),()=>{s.disconnect()}},[]),e.useEffect(()=>{l.current&&l.current.redraw()},[r,n,u]),0===t.length?s.jsx("div",{className:"flex-1 min-h-[180px] flex items-center justify-center text-fg-muted",children:"Collecting data..."}):s.jsx("div",{className:"relative flex-1 min-h-[180px]",children:s.jsx("div",{ref:a,className:"absolute inset-0 radius-inner overflow-hidden"})})}),L=e.memo(function({data:t,color:r,flipped:n=!1,fixedSlots:a}){const l=e.useRef(null),o=e.useRef(null),i=e.useRef(t),c=e.useRef(r),d=e.useRef(n),m=e.useRef(a);e.useLayoutEffect(()=>{i.current=t,c.current=r,d.current=n,m.current=a});const u=e.useMemo(()=>[Array.from({length:a},(e,s)=>s),new Array(a).fill(1)],[a]),x=e.useMemo(()=>({hooks:{draw:e=>{!function(e,s,t,r,n){const a=e.ctx,{left:l,top:o,width:i,height:c}=e.bbox;if(i<=0||c<=0)return;const d=[...Array(Math.max(0,n-s.length)).fill(0),...s.slice(-n)],m=Math.max(...d,1),u=d.length,x=i/u,p=.03*c;a.save();for(let h=0;h({width:400,height:40,padding:[0,0,0,0],legend:{show:!1},cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1,label:""}],plugins:[x]}),[x]);return e.useEffect(()=>{const e=l.current;if(!e)return;o.current&&o.current.destroy();const s=e.getBoundingClientRect(),t=Math.floor(s.width)||400,r=Math.floor(s.height)||40,n=new b({...p,width:t,height:r},u,e);return o.current=n,()=>{n.destroy(),o.current=null}},[p,u]),e.useEffect(()=>{const e=l.current;if(!e)return;const s=new ResizeObserver(e=>{const s=e[0];if(!s||!o.current)return;const{width:t,height:r}=s.contentRect;t>0&&r>0&&o.current.setSize({width:Math.floor(t),height:Math.floor(r)})});return s.observe(e),()=>{s.disconnect()}},[]),e.useEffect(()=>{o.current&&o.current.redraw()},[t,r,n]),s.jsx("div",{ref:l,className:"w-full h-full"})}),D={warning:80,danger:95},G={warning:85,danger:95},O={warning:70,danger:85},U=[{threshold:30,color:"var(--sys-cyan)"},{threshold:50,color:"var(--sys-blue)"},{threshold:65,color:"var(--sys-indigo)"},{threshold:80,color:"var(--signal-poor)"}];function V(e,s,t){const r=t-s,n={cold:(30-s)/r*100,normal:(50-s)/r*100,warm:(65-s)/r*100,hot:(80-s)/r*100};return`linear-gradient(to right, ${[{pos:0,color:"var(--sys-cyan)"},{pos:n.cold,color:"var(--sys-cyan)"},{pos:n.cold,color:"var(--sys-blue)"},{pos:n.normal,color:"var(--sys-blue)"},{pos:n.normal,color:"var(--sys-indigo)"},{pos:n.warm,color:"var(--sys-indigo)"},{pos:n.warm,color:"var(--signal-poor)"},{pos:n.hot,color:"var(--signal-poor)"},{pos:n.hot,color:"var(--sys-red)"},{pos:100,color:"var(--sys-red)"}].map(s=>{const t=e>0?s.pos/e*100:0;return`${s.color} ${Math.min(t,100)}%`}).join(", ")})`}function H(e,s){return e>=s.danger?"danger":e>=s.warning?"warning":"none"}function W(e){let s="none";for(const t of Object.values(e)){const e=H(t,O);if("danger"===e)return"danger";"warning"===e&&(s="warning")}return s}function z(e){let s,t,r;return e>=1073741824?(s=e/1073741824,t="GB/s"):e>=1048576?(s=e/1048576,t="MB/s"):e>=1024?(s=e/1024,t="KB/s"):(s=e,t="B/s"),r=s>=100?s.toFixed(0):s.toFixed(1),`${r} ${t}`}function I(e){return e>=1073741824?{value:(e/1073741824).toFixed(1),unit:"GiB"}:e>=1048576?{value:(e/1048576).toFixed(1),unit:"MiB"}:e>=1024?{value:(e/1024).toFixed(1),unit:"KiB"}:{value:String(e),unit:"B"}}const X=e.memo(function({level:e}){return"none"===e?null:s.jsxs("span",{className:t("inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium","danger"===e&&"bg-sys-red/20 text-sys-red","warning"===e&&"bg-sys-indigo/20 text-sys-indigo"),children:[s.jsx(v,{className:"w-3 h-3"}),"danger"===e?"High":"Warn"]})}),J=e.memo(function({value:e,max:t=100,width:r=10,color:n="primary"}){const a=Math.min(e/t,1),l=Math.round(a*r),o=r-l,i="■".repeat(l),c="·".repeat(o),d={primary:"text-sys-blue",secondary:"text-sys-indigo",success:"text-sys-green",danger:"text-sys-red"}[n];return s.jsxs("span",{className:"font-mono text-[10px] tracking-tight",children:[s.jsx("span",{className:d,children:i}),s.jsx("span",{className:"text-fg-muted/40",children:c})]})}),K=e.memo(function({index:e,usage:r}){const n=r>90?"danger":r>70?"secondary":"primary";return s.jsxs("div",{className:"flex items-center gap-1 type-data-xs",children:[s.jsxs("span",{className:"text-fg-muted w-5",children:["C",e]}),s.jsx(J,{value:r,width:8,color:n}),s.jsxs("span",{className:t("w-7 text-right tabular-nums",r>90?"text-sys-red":r>70?"text-sys-indigo":"text-sys-green"),children:[r.toFixed(0),"%"]})]})}),Y=e.memo(function({pid:e,name:r,cpu:n,mem:a,isTopCpu:l=!1,isTopMem:o=!1}){return s.jsxs("div",{className:"flex items-center gap-2 py-1 type-data-sm hover:bg-subtle-fill -mx-1 px-1 rounded",children:[s.jsx("span",{className:"text-fg-muted w-10 sm:w-14 tabular-nums",children:e}),s.jsx("span",{className:"flex-1 truncate text-fg-primary",children:r}),s.jsx("span",{className:"hidden sm:inline-flex",children:s.jsx(J,{value:n,max:100,width:6,color:n>50?"danger":n>20?"secondary":"success"})}),s.jsx("span",{className:t("w-10 sm:w-12 text-right tabular-nums",l?"text-fg-primary":n>50?"text-sys-red":n>20?"text-sys-indigo":"text-fg-muted"),children:n.toFixed(1)}),s.jsx("span",{className:t("w-10 sm:w-12 text-right tabular-nums",o?"text-fg-primary":a>50?"text-sys-red":a>20?"text-sys-indigo":"text-fg-muted"),children:a.toFixed(1)})]})}),q=e.memo(function({value:e,label:t,min:r=20,max:n=100}){const a=Math.min(Math.max((e-r)/(n-r)*100,0),100),l=function(e){return e<30?{text:"Cool",color:"text-sys-cyan"}:e<50?{text:"Normal",color:"text-sys-blue"}:e<65?{text:"Warm",color:"text-sys-indigo"}:e<80?{text:"Hot",color:"text-signal-poor"}:{text:"Danger",color:"text-sys-red"}}(e),o=n-r;return s.jsxs("div",{className:"space-y-1.5",children:[s.jsxs("div",{className:"flex justify-between items-center",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:t}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:l.text}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded type-data-sm",children:[s.jsx("span",{className:l.color,children:e.toFixed(1)}),s.jsx("span",{className:"text-fg-primary",children:"°C"})]})]})]}),s.jsxs("div",{className:"relative h-3 rounded-full bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 rounded-full transition-all duration-300 ease-out",style:{background:V(a,r,n),width:`${a}%`}}),s.jsx("div",{className:"absolute inset-0 flex items-center pointer-events-none",children:U.map(({threshold:e,color:t})=>{const n=(e-r)/o*100;return n<0||n>100?null:s.jsx("div",{className:"absolute w-px h-full",style:{left:`${n}%`,backgroundColor:t}},e)})})]})]})});e.memo(function({data:e,color:t,flipped:r=!1,fixedSlots:n}){const a=[...Array(Math.max(0,n-e.length)).fill(0),...e.slice(-n)],l=Math.max(...a,1),o=a.map(e=>0===e?0:Math.max(e/l*100,3));return s.jsx("div",{className:"w-full h-full flex items-end",style:{transform:r?"scaleY(-1)":void 0},children:o.map((e,r)=>s.jsx("div",{className:"flex-1 min-w-0",style:{height:e>0?`${e}%`:"0%",backgroundColor:e>0?t:"transparent"}},r))})});const Q=e.memo(function({networkHistory:e,txRate:t,rxRate:r,totalBytesSent:n,totalBytesRecv:a,cpuColor:o,memoryColor:i,networkSlots:c}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(N,{}),title:"Network",actions:s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx(w,{className:"w-3.5 h-3.5",style:{color:i}}),s.jsx("span",{className:"type-data-xs",style:{color:i},children:"TX"}),s.jsx("span",{className:"px-2 py-1 bg-subtle-fill-strong rounded type-data-sm text-fg-primary",children:z(t)})]})}),s.jsxs("div",{className:"flex flex-col h-[120px]",children:[s.jsx("div",{className:"h-[60px]",children:s.jsx(L,{data:e.map((e,s,t)=>{if(0===s)return 0;const r=(e.timestamp-t[s-1].timestamp)/1e3;return r>0?(e.bytesSent-t[s-1].bytesSent)/r:0}),color:i,fixedSlots:c})}),s.jsx("div",{className:"h-[60px]",children:s.jsx(L,{data:e.map((e,s,t)=>{if(0===s)return 0;const r=(e.timestamp-t[s-1].timestamp)/1e3;return r>0?(e.bytesRecv-t[s-1].bytesRecv)/r:0}),color:o,flipped:!0,fixedSlots:c})})]}),s.jsxs("div",{className:"pt-2 flex flex-wrap justify-between items-center gap-2 type-data-sm",children:[s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"text-fg-muted",children:"Total"}),s.jsxs("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums",children:[s.jsx("span",{style:{color:i},children:I(n).value})," ",s.jsx("span",{className:"text-fg-muted",children:I(n).unit})]}),s.jsxs("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums",children:[s.jsx("span",{style:{color:o},children:I(a).value})," ",s.jsx("span",{className:"text-fg-muted",children:I(a).unit})]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx(M,{className:"w-3.5 h-3.5",style:{color:o}}),s.jsx("span",{className:"type-data-xs",style:{color:o},children:"RX"}),s.jsx("span",{className:"px-1.5 sm:px-2 py-1 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:z(r)})]})]})]})}),Z=e.memo(function({temperatures:e}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(R,{}),title:"Temperature",actions:e&&s.jsx(X,{level:W(e)})}),s.jsx("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:e&&Object.keys(e).length>0?s.jsxs("div",{className:"space-y-3",children:[void 0!==e.cpu_thermal&&s.jsx(q,{value:e.cpu_thermal,label:"CPU",min:20,max:100}),Object.entries(e).filter(([e])=>"cpu_thermal"!==e).slice(0,2).map(([e,t])=>s.jsx(q,{value:t,label:e.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),min:20,max:100},e))]}):s.jsxs("div",{className:"flex items-center justify-center text-fg-muted text-sm",children:[s.jsx(k,{className:"w-4 h-4 mr-2"}),"No sensors"]})})]})}),ee=e.memo(function({usagePercent:e,used:t,available:r,memoryColor:n}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"Memory",actions:s.jsxs("span",{className:"px-2 py-0.5 bg-subtle-fill-strong rounded type-data",style:{color:n},children:[e.toFixed(0),"%"]})}),s.jsxs("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:[s.jsxs("div",{className:"flex gap-1 h-12 radius-inner bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"h-full transition-all duration-300 bg-sys-blue",style:{width:`${e}%`}}),s.jsx("div",{className:"h-full transition-all duration-300 bg-subtle-fill/80",style:{width:100-e+"%"}})]}),s.jsxs("div",{className:"flex items-center justify-between type-data-xs pt-2",children:[s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-sys-blue"}),s.jsx("span",{className:"text-fg-muted",children:"Used"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:[(t/1048576).toFixed(0)," MB"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-subtle-fill-strong depth-stroke-raised"}),s.jsx("span",{className:"text-fg-muted",children:"Avail"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-muted",children:[(r/1048576).toFixed(0)," MB"]})]})]})]})]})}),se=e.memo(function({usagePercent:e,used:t,free:r,cpuColor:n}){return s.jsxs(f,{neomorphic:!0,className:"flex flex-col",children:[s.jsx(l,{icon:s.jsx(C,{}),title:"Disk",actions:s.jsxs("span",{className:"px-2 py-0.5 bg-subtle-fill-strong rounded type-data",style:{color:n},children:[e.toFixed(0),"%"]})}),s.jsxs("div",{className:"flex-1 flex flex-col justify-center min-h-0",children:[s.jsxs("div",{className:"flex gap-1 h-12 radius-inner bg-subtle-fill/80 depth-stroke-inset overflow-hidden",children:[s.jsx("div",{className:"h-full transition-all duration-300 bg-sys-blue",style:{width:`${e}%`}}),s.jsx("div",{className:"h-full transition-all duration-300 bg-subtle-fill/80",style:{width:100-e+"%"}})]}),s.jsxs("div",{className:"flex items-center justify-between type-data-xs pt-2",children:[s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-sys-blue"}),s.jsx("span",{className:"text-fg-muted",children:"Used"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-primary",children:[(t/1073741824).toFixed(1)," GB"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5",children:[s.jsx("div",{className:"w-2.5 h-2.5 rounded-sm bg-subtle-fill-strong depth-stroke-raised"}),s.jsx("span",{className:"text-fg-muted",children:"Free"}),s.jsxs("span",{className:"px-1.5 py-0.5 bg-subtle-fill-strong rounded tabular-nums text-fg-muted",children:[(r/1073741824).toFixed(1)," GB"]})]})]})]})]})}),te=e.memo(function({processes:e}){if(0===e.length)return null;const t=e.slice(0,10),r=Math.max(...t.map(e=>e.cpu_percent)),n=Math.max(...t.map(e=>e.memory_percent));return s.jsx(f,{neomorphic:!0,noPadding:!0,children:s.jsxs("div",{className:"px-4 py-3",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"Processes"}),s.jsxs("div",{className:"flex items-center gap-2 py-1.5 type-data-sm text-fg-muted",children:[s.jsx("span",{className:"w-10 sm:w-14",children:"PID"}),s.jsx("span",{className:"flex-1",children:"Program"}),s.jsx("span",{className:"hidden sm:block w-[52px]"}),s.jsx("span",{className:"w-10 sm:w-12 text-right",children:"CPU%"}),s.jsx("span",{className:"w-10 sm:w-12 text-right",children:"MEM%"})]}),t.map(e=>s.jsx(Y,{pid:e.pid,name:e.name,cpu:e.cpu_percent,mem:e.memory_percent,isTopCpu:e.cpu_percent===r&&r>0,isTopMem:e.memory_percent===n&&n>0},e.pid))]})})}),re=a.hero;function ne(){var r;const n=o(),b=i(),v=c(),w=d(),N=m(),[M,R]=e.useState([]),[C,P]=e.useState(!1),[$,E]=e.useState([]),[T,L]=e.useState(0),[O,U]=e.useState(0),V=e.useRef(null),W=u(),z=W.blue,I=W.amber,J=function(){const[s,t]=e.useState("undefined"!=typeof window&&window.matchMedia("(max-width: 767px)").matches);return e.useEffect(()=>{const e=window.matchMedia("(max-width: 767px)");t(e.matches);const s=e=>t(e.matches);return e.addEventListener("change",s),()=>e.removeEventListener("change",s)},[]),s?a.hero:40}();return e.useEffect(()=>{if(!n)return;const e=Date.now(),s={timestamp:e,bytesRecv:n.network.bytes_recv,bytesSent:n.network.bytes_sent};if(V.current){const t=(e-V.current.timestamp)/1e3;if(t>0){const e=(s.bytesRecv-V.current.bytesRecv)/t,r=(s.bytesSent-V.current.bytesSent)/t;e>=0&&r>=0&&(L(e),U(r))}}V.current=s,E(e=>[...e,s].slice(-re))},[n]),e.useEffect(()=>{let e=!0;const s=async()=>{var s;const t=await h();e&&t.success&&(null==(s=t.data)?void 0:s.processes)&&R(t.data.processes)};s();const t=setInterval(s,5e3);return()=>{e=!1,clearInterval(t)}},[]),s.jsxs(g,{children:[s.jsx(y,{title:"System Stats",icon:s.jsx(F,{}),controls:s.jsxs(x,{color:"muted",onClick:async()=>{var e;P(!0),await w();const s=await h();s.success&&(null==(e=s.data)?void 0:e.processes)&&R(s.data.processes),P(!1)},disabled:C,children:[s.jsx(S,{"data-slot":"icon",className:t(C&&"animate-spin")}),"Refresh"]})}),s.jsxs(j,{children:[v&&s.jsx(f,{className:"border border-sys-red/50 bg-sys-red/10",children:s.jsx("p",{className:"text-sys-red",children:v})}),b?s.jsx(f,{neomorphic:!0,className:"p-12 text-center",children:s.jsx("div",{className:"animate-pulse text-fg-muted",children:"Loading system stats..."})}):n?s.jsxs(s.Fragment,{children:[s.jsx(_,{template:"hero",children:s.jsxs(f,{neomorphic:!0,className:"pb-2 sm:pb-3",children:[s.jsx(l,{icon:s.jsx(k,{}),title:"System Resources",stackActionsOnMobile:!0,actions:s.jsxs("div",{className:"flex items-center gap-2 sm:gap-4 flex-wrap",children:[(null==(r=n.system)?void 0:r.uptime)&&s.jsx("span",{className:"px-2 py-0.5 bg-subtle-fill rounded type-data-sm text-fg-primary",children:p(n.system.uptime)}),s.jsx(X,{level:H(n.cpu.usage_percent,D)}),s.jsx(X,{level:H(n.memory.usage_percent,G)}),s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:"CPU"}),s.jsxs("span",{className:"text-sm sm:text-base font-mono font-semibold tabular-nums",style:{color:z},children:[n.cpu.usage_percent.toFixed(0),"%"]})]}),s.jsxs("div",{className:"flex items-center gap-1.5 sm:gap-2",children:[s.jsx("span",{className:"type-data-sm text-fg-muted",children:"MEM"}),s.jsxs("span",{className:"text-sm sm:text-base font-mono font-semibold tabular-nums",style:{color:I},children:[n.memory.usage_percent.toFixed(0),"%"]})]})]})}),s.jsx("div",{className:"flex-1 min-h-0 flex flex-col",children:s.jsx(A,{data:N,cpuColor:z,memoryColor:I})}),n.cpu.per_core_percent&&n.cpu.per_core_percent.length>0&&s.jsx("div",{className:"mt-3 pt-3 border-t border-edge-subtle",children:s.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-x-3 gap-y-0.5",children:n.cpu.per_core_percent.map((e,t)=>s.jsx(K,{index:t,usage:e},t))})})]})}),s.jsxs(_,{template:"compact",children:[s.jsx(B,{span:12,md:6,children:s.jsx(Q,{networkHistory:$,txRate:O,rxRate:T,totalBytesSent:n.network.bytes_sent,totalBytesRecv:n.network.bytes_recv,cpuColor:z,memoryColor:I,networkSlots:J})}),s.jsx(B,{span:12,md:6,children:s.jsx(Z,{temperatures:n.temperatures})})]}),s.jsxs(_,{template:"compact",children:[s.jsx(B,{span:12,sm:6,children:s.jsx(ee,{usagePercent:n.memory.usage_percent,used:n.memory.used,available:n.memory.available,memoryColor:I})}),s.jsx(B,{span:12,sm:6,children:s.jsx(se,{usagePercent:n.disk.usage_percent,used:n.disk.used,free:n.disk.free,cpuColor:z})})]}),s.jsx(_,{template:"auto",children:s.jsx(te,{processes:M})})]}):null]})]})}export{ne as default}; diff --git a/frontend/dist/assets/Terminal-Bhtd_bQn.js b/frontend/dist/assets/Terminal-DKt0bGFF.js similarity index 99% rename from frontend/dist/assets/Terminal-Bhtd_bQn.js rename to frontend/dist/assets/Terminal-DKt0bGFF.js index e75276d3..4e0489b3 100644 --- a/frontend/dist/assets/Terminal-Bhtd_bQn.js +++ b/frontend/dist/assets/Terminal-DKt0bGFF.js @@ -1 +1 @@ -var e=Object.defineProperty,t=(t,r,a)=>((t,r,a)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[r]=a)(t,"symbol"!=typeof r?r+"":r,a);import{j as r,r as a,X as s,x as n,d as o}from"./vendor-react-alRNW2nb.js";import{a as i,c}from"./vendor-core-FtpmsTnh.js";import{D as l,o as d,L as u}from"./xterm-WPd9ZkSt.js";import{Z as p,bb as m,bu as h,bv as g,bw as f,bx as y,aG as x,k as v,by as $,bz as b,bA as w,b1 as _,ae as k,bB as C,a4 as S,a3 as j,av as N,bC as T,bD as R,bE as M,bF as E,bm as A,Y as I,bG as F,_ as L,B,bH as D,bI as O,b0 as P,p as U,bJ as H,bK as z,bL as q}from"./index-D7i6lQrq.js";import{h as K,c as W}from"./geo-utils-DJn8DnxF.js";import{a as G}from"./ping-5xLx9WS1.js";import{P as X,c as V}from"./payload-decoders-DjZO58V7.js";import{g as Y,r as J}from"./system-Circh3O5.js";import{g as Q,B as Z,r as ee,T as te}from"./ascii-burst-CXC_pYgi.js";import{P as re,B as ae,C as se}from"./PageLayout-QhCLxU34.js";import{K as ne,S as oe}from"./KeycapButton-B1_-eSeA.js";import{aR as ie,a$ as ce,b0 as le,b1 as de,au as ue,D as pe,b2 as me}from"./vendor-icons-TO0PZKGR.js";import{A as he,m as ge}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";import"./keycap-sfx-Bpx9zhkt.js";class fe{constructor(){t(this,"commands",[])}register(...e){this.commands.push(...e)}find(e){let t;for(const r of this.commands)r.matches(e)&&(!t||r.name.length>t.name.length)&&(t=r);return t}all(){return this.commands}}class ye{constructor(){t(this,"aliases",[]),t(this,"params")}matches(e){const t=e.toLowerCase().trim(),r=e=>t===e||t.startsWith(e+" ");return r(this.name)||this.aliases.some(r)}argsAfterName(e){const t=e.toLowerCase().trim(),r=[this.name,...this.aliases].sort((e,t)=>t.length-e.length);for(const a of r)if(t.startsWith(a))return e.trim().slice(a.length).trim();return e.trim()}}const xe="[",ve=`${xe}0m`,$e=`${xe}1m`,be=`${xe}2m`,we=`${xe}3m`,_e=`${xe}32m`,ke=`${xe}31m`,Ce=`${xe}33m`,Se=`${xe}36m`,je=`${xe}34m`,Ne=`${xe}90m`,Te=`${xe}92m`,Re=`${xe}96m`;function Me(e,t){switch(t){case"success":return`${_e}${e}${ve}`;case"error":return`${ke}${e}${ve}`;case"warning":return`${Ce}${e}${ve}`;case"info":return`${Se}${e}${ve}`;case"value":return`${je}${e}${ve}`;case"system":return`${Ne}${e}${ve}`;default:return e}}function Ee(e){return`${$e}${e}${ve}`}function Ae(e){return`${be}${e}${ve}`}function Ie(e){return`${je}${e}${ve}`}function Fe(e){return`${Ne}${e}${ve}`}function Le(e,t){return`${Ne}${e}: ${ve}${je}${$e}${t}${ve}`}function Be(e,t,r=22){const a=e.split(" "),s=a[0];let n=Se;return"get"===s?n=_e:"set"===s&&(n=Ce),` ${a.length>1?`${n}${$e}${s}${ve} ${je}${a.slice(1).join(" ")}${ve}`:`${n}${$e}${e}${ve}`}${" ".repeat(Math.max(1,r-e.length))}${Ne}${t}${ve}`}function De(e){return`${$e}${je}${e}${ve}`}function Oe(e){return`${Ne}${we}${e}${ve}`}function Pe(e){return`${ke}${$e}●${ve} ${Ne}${e}${ve}`}function Ue(e){const t=e<1e3?`${e.toFixed(0)}ms`:`${(e/1e3).toFixed(1)}s`;return`${function(e){return e<1500?Te:e<4e3?_e:e<8e3?Ce:e<15e3?ke:`${ke}${$e}`}(e)}${t}${ve}`}function He(e){switch(e){case"excellent":return Re;case"good":return _e;case"fair":return Ce;case"poor":return ke;case"critical":return`${ke}${$e}`;default:return Ne}}function ze(e,t){return`${He(t)}${e}${ve}`}function qe(e){return e.replace(/[\p{Emoji_Presentation}\p{Extended_Pictographic}\uFE0F\u200D]/gu,"").trim()}const Ke="\r";function We(e=1){return`[${e}A`}const Ge="[?1049l",Xe="[?25h";function Ve(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function Ye(e){return Ve(e).length}function Je(e,t){let r=0;for(const a of e){const e=Ve(a).length;r+=0===e?1:Math.ceil(e/t)}return r}function Qe(e,t){const r=function(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}(e);return r||t}function Ze(){const e="light"===document.documentElement.dataset.mode,t=Qe("--terminal-bg","#0d0d0d"),r=Qe("--sys-blue",m.blue);if(e){const e="#EFF0F1";return{background:e,foreground:"#111314",cursor:m.blue,cursorAccent:e,selectionBackground:`${m.blue}30`,selectionForeground:"#111314",black:"#111314",red:m.red,green:m.green,yellow:m.amber,blue:m.blue,magenta:m.purple,cyan:m.cyan,white:e,brightBlack:p[500],brightRed:m.red,brightGreen:m.green,brightYellow:m.orange,brightBlue:m.indigo,brightMagenta:m.pink,brightCyan:m.teal,brightWhite:p[600]}}const a=Qe("--text-primary","#e0e0e0"),s=r+"40",n=Qe("--sys-red",m.red),o=Qe("--sys-green",m.green),i=Qe("--sys-purple",m.purple),c=Qe("--sys-blue",m.blue),l=Qe("--sys-cyan",m.cyan),d=Qe("--text-muted",p[500]),u=Qe("--text-secondary",p[400]);return{background:t,foreground:a,cursor:r,cursorAccent:t,selectionBackground:s,selectionForeground:a,black:Qe("--bg-surface",p[900]),red:n,green:o,yellow:i,blue:c,magenta:i,cyan:l,white:a,brightBlack:d,brightRed:n,brightGreen:"#4ADE80",brightYellow:i,brightBlue:c,brightMagenta:i,brightCyan:l,brightWhite:u}}const et="[",tt=`${et}0m`,rt=`${et}1m`,at=`${et}2m`,st=`${et}34m`,nt=`${et}90m`,ot=" ",it=[{label:"INFORMATION",entries:[{cmd:"status",desc:"Repeater status summary",alias:"st"},{cmd:"top",desc:"Live system overview (Ctrl+C to exit)",alias:"htop"},{cmd:"ver",desc:"Version info",alias:"version"},{cmd:"clock",desc:"System UTC time"},{cmd:"uptime",desc:"System uptime"},{cmd:"board",desc:"Board / platform info"},{cmd:"packets",desc:"Packet statistics"},{cmd:"stats-packets",desc:"Packet counters (firmware compat)"},{cmd:"stats-radio",desc:"Radio health stats (firmware compat)"},{cmd:"stats-core",desc:"Engine vitals (firmware compat)"}]},{label:"NETWORK",entries:[{cmd:"neighbors [sort]",desc:"Direct RF neighbors",alias:"nb",sub:"sig · name · rssi · snr · dist · heard"},{cmd:"ping {name}",desc:"Ping neighbor (name or 0xXX)"},{cmd:"identities",desc:"List configured identities",alias:"id ids"},{cmd:"keys",desc:"Transport keys"},{cmd:"acl",desc:"ACL statistics"},{cmd:"rooms",desc:"Room statistics"}]},{label:"RADIO",entries:[{cmd:"get {param}",desc:"Read parameter"},{cmd:"set {param} {value}",desc:"Write parameter"},{cmd:"advert",desc:"Send advertisement"}]},{label:"SYSTEM",entries:[{cmd:"restart",desc:"Restart service",alias:"reboot"},{cmd:"start cap [seconds]",desc:"Start packet capture"},{cmd:"end cap",desc:"Stop capture"},{cmd:"list cap",desc:"List captures"},{cmd:"export cap [id]",desc:"Download capture"}]},{label:"TOOLS",entries:[{cmd:"convert hex {value}",desc:"Hex → base64"},{cmd:"convert base64 {value}",desc:"Base64 → hex"},{cmd:"clear",desc:"Clear terminal",alias:"cls"},{cmd:"help [command]",desc:"Show this help",alias:"? h"}]}],ct=[{cat:"Identity",params:["name","role","lat","lon","public.key"]},{cat:"Radio",params:["radio","freq","tx","bw","sf","cr"]},{cat:"Timing",params:["txdelay","direct.txdelay","rxdelay"]},{cat:"Repeater",params:["mode","duty","repeat","flood.max","advert.interval"]},{cat:"Advanced",params:["multi.acks","int.thresh","agc.reset.interval"]},{cat:"set only",params:["log","prv.key"]}];function lt(e){return`${nt}${"─".repeat(e)}${tt}`}function dt(e){const t=Math.max(3,e-12-8-6);return` ${st}${rt}pymc console${tt} ${lt(t)} ${nt}terminal${tt}`}function ut(e){return` ${nt}${e}${tt}`}function pt(e,t){const r=[],a=e.alias?` ${at}${e.alias}${tt}`:"";return 4+Math.max(e.cmd.length,24)+e.desc.length+(e.alias?2+e.alias.length:0)<=t?r.push(" "+Be(e.cmd,e.desc,24)+a):(r.push(" "+Be(e.cmd,"",24)),r.push(ot+Fe(e.desc)+a)),e.sub&&r.push(`${ot}${Ae("└ "+e.sub)}`),r}function mt(e){return e.split(" · ").map(e=>`${st}${e}${tt}`).join(`${nt} · ${tt}`)}function ht(e,t){const r=[];let a=[],s=0;for(const n of e){const e=a.length>0?3+n.length:n.length;s+e>t&&a.length>0?(r.push(a),a=[n],s=n.length):(a.push(n),s+=e)}return a.length>0&&r.push(a),r}function gt(e){const t=["",ut("GET/SET QUALIFIERS")],r=Math.max(20,e-4-13);for(const a of ct){const e=`${nt}${a.cat.padEnd(13)}${tt}`,s=ht(a.params,r),n=" ".repeat(17);t.push(` ${e}${mt(s[0].join(" · "))}`);for(let r=1;r help for detailed usage")}`]}(r)),e.write(s.join("\n"))}}class yt extends ye{constructor(){super(...arguments),t(this,"name","clear"),t(this,"description","Clear terminal screen"),t(this,"aliases",["cls"])}execute({output:e,rawInput:t}){"help"!==this.argsAfterName(t).toLowerCase().trim()?e.clear():e.write([De("clear"),` ${Fe("Clear all terminal output.")}`,"",Be("clear","clear the screen"),"",De("Aliases"),` ${Fe("cls")}`].join("\n"))}}function xt(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}class vt extends ye{constructor(){super(...arguments),t(this,"name","status"),t(this,"description","Get repeater status summary"),t(this,"aliases",["st"])}async execute({output:e,rawInput:t}){var r,a,s;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("status"),` ${Fe("Show a quick summary of mode, neighbor count, and uptime.")}`,"",Be("status","show summary"),"",De("Aliases"),` ${Fe("st")}`].join("\n"));const n=e.write("processing...","system");try{const t=await g(),o=(null==(a=null==(r=t.config)?void 0:r.repeater)?void 0:a.mode)||"unknown",i=Object.keys(t.neighbors||{}).length,c=Object.values(t.neighbors||{}).filter(e=>e.zero_hop).length,l=(null==(s=t.config)?void 0:s.node_name)||t.node_name||"unknown",d=xt(t.uptime_seconds||0);e.update(n,[`${Ee(l)} ${Fe("repeater")}`,"",` ${Le("Mode",Ie(o))}`,` ${Le("Neighbors",`${Ie(String(c))} direct ${Fe(`${i} total`)}`)}`,` ${Le("RX / TX",`${Ie(String(t.rx_count??0))} / ${Ie(String(t.tx_count??0))}`)}`,` ${Le("Uptime",Ie(d))}`].join("\n"))}catch(o){e.update(n,`Error: ${o instanceof Error?o.message:"Command failed"}`,"error")}}}class $t extends ye{constructor(){super(...arguments),t(this,"name","uptime"),t(this,"description","Show system uptime")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("uptime"),` ${Fe("Display how long the repeater service has been running.")}`,"",Be("uptime","show uptime")].join("\n"));const r=e.write("processing...","system");try{const t=await g();e.update(r,Le("Uptime",Ie(xt(t.uptime_seconds||0))))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class bt extends ye{constructor(){super(...arguments),t(this,"name","packets"),t(this,"description","Show packet statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("packets"),` ${Fe("Display packet counters (received, transmitted, forwarded, dropped).")}`,"",Be("packets","show packet stats")].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a=(t.rx_count??0)+(t.tx_count??0);e.update(r,[De("Packet Stats")+` ${Fe(`${a} total`)}`,"",` ${Le("Received",Ie(String(t.rx_count??0)))}`,` ${Le("Transmitted",Ie(String(t.tx_count??0)))}`,` ${Le("Forwarded",Ie(String(t.forwarded_count??0)))}`,` ${Le("Dropped",Ie(String(t.dropped_count??0)))}`].join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}function wt(e){return e>=1073741824?`${(e/1073741824).toFixed(1)} GB`:e>=1048576?`${(e/1048576).toFixed(0)} MB`:`${(e/1024).toFixed(0)} KB`}function _t(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}class kt extends ye{constructor(){super(...arguments),t(this,"name","board"),t(this,"description","Show board/platform info")}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("board"),` ${Fe("Display platform and hardware information.")}`,"",Be("board","show board info")].join("\n"));const a=e.write("loading...","system");try{const[t,s]=await Promise.all([f(),g()]),n=[];if(n.push(` ${Le("Node",Ie(s.node_name||"Unknown"))}`),n.push(` ${Le("Runtime",Ie(`pyMC_Repeater v${s.version||"?"}`))}`),s.core_version&&n.push(` ${Le("Core",Ie(s.core_version))}`),n.push(""),t.success&&t.data){const e=t.data;n.push(` ${Le("CPU",Ie(`${e.cpu.usage_percent.toFixed(1)}%`))} ${Fe(`${e.cpu.count} core${e.cpu.count>1?"s":""}`)}`),e.cpu.load_avg&&n.push(` ${Le("Load",Ie(`${e.cpu.load_avg["1min"].toFixed(2)} / ${e.cpu.load_avg["5min"].toFixed(2)} / ${e.cpu.load_avg["15min"].toFixed(2)}`))}`);const a=Object.entries(e.temperatures||{});if(a.length>0){const e=a[0];n.push(` ${Le("Temp",Ie(`${e[1].toFixed(1)}°C`))}${a.length>1?` ${Fe(a.slice(1).map(([e,t])=>`${e}: ${t.toFixed(1)}°C`).join(", "))}`:""}`)}n.push(""),n.push(` ${Le("Memory",Ie(`${wt(e.memory.used)} / ${wt(e.memory.total)}`))} ${Fe(`${e.memory.usage_percent.toFixed(0)}%`)}`),n.push(` ${Le("Disk",Ie(`${wt(e.disk.used)} / ${wt(e.disk.total)}`))} ${Fe(`${e.disk.usage_percent.toFixed(0)}%`)}`),n.push(""),(null==(r=e.system)?void 0:r.uptime)&&n.push(` ${Le("System uptime",Ie(_t(e.system.uptime)))}`),n.push(` ${Le("Service uptime",Ie(_t(s.uptime_seconds)))}`),e.network&&n.push(` ${Le("Net TX/RX",Ie(`${wt(e.network.bytes_sent)} / ${wt(e.network.bytes_recv)}`))}`)}else n.push(` ${Le("Platform",Ie("Linux"))}`),n.push(` ${Le("Service uptime",Ie(_t(s.uptime_seconds)))}`),n.push(` ${Fe("Hardware stats unavailable")}`);e.update(a,n.join("\n"),"value")}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Failed to load hardware stats"}`,"error")}}}const Ct="",St="",jt="",Nt="",Tt="",Rt=48;function Mt(e,t,r,a){return s=>{if(s<=0)return 0;if(s>=1)return 1;let n=s;for(let t=0;t<8;t++){const t=3*(1-n)*(1-n)*n*e+3*(1-n)*n*n*r+n*n*n-s,a=3*(1-n)*(1-n)*e+6*(1-n)*n*(r-e)+3*n*n*(1-r);if(Math.abs(a)<1e-7)break;n=Math.max(0,Math.min(1,n-t/a))}return 3*(1-n)*(1-n)*n*t+3*(1-n)*n*n*a+n*n*n}}const Et=Mt(.25,1,.5,1),At=Mt(.4,0,1,1);function It(e,t){const r=e%14;return Math.sin(.45*r+.04*r*r+.25*t)}const Ft=[8,16,32,128],Lt=[1,2,4,64].map((e,t)=>e|Ft[t]);function Bt(e,t,r,a){a<4?e[r]|=Lt[a]:t[r]|=Lt[a-4]}function Dt(e){return e>.8?""+St:e>.6?""+St:e>.4?Tt+St:e>.2?Tt:e>.08?Nt:Nt+jt}function Ot(e,t,r){const a=new Uint8Array(Rt),s=new Uint8Array(Rt),n=new Float32Array(Rt),o=.35*e;for(let i=0;i=t)continue;const l=t-c,d=Math.min(1,l/3),u=Math.min(1,c/2),p=l<5?1+.3*(1-l/5):1,m=Math.min(1,d*u*p);if(m<.04)continue;const h=1+.06*Math.sin(.7*e+.3*c),g=It(c,o)*m*h*3.5+3.5,f=Math.abs(g-3.5)/3.5,y=l<6?1-l/6:0;n[i]=Math.min(1,.65*f+.35*y)*m;const x=Math.max(0,Math.min(7,Math.round(g)));if(g>=3.5){for(let t=3;t<=x;t++)Bt(a,s,i,t);const e=Math.round(.4*(g-3.5));for(let t=Math.max(0,3-e);t<3;t++)Bt(a,s,i,t)}else{for(let t=x;t<=4;t++)Bt(a,s,i,t);const e=Math.round(.4*(3.5-g));for(let t=5;t<=Math.min(7,4+e);t++)Bt(a,s,i,t)}}return{top:a,bot:s,heat:n}}function Pt(e,t,r){const a=new Uint8Array(Rt),s=new Uint8Array(Rt),n=new Float32Array(Rt),o=Math.exp(.5*-t),i=Math.max(0,10-2.5*t),c=.7+.2*t;for(let l=0;l=Rt)continue;const d=o*(1-l/i);if(d<.04)continue;n[t]=d;const u=Math.sin(l*c+.6*r)*d*3.5+3.5,p=Math.max(0,Math.min(7,Math.round(u)));if(u>=3.5)for(let e=3;e<=p;e++)Bt(a,s,t,e);else for(let e=p;e<=4;e++)Bt(a,s,t,e)}return{top:a,bot:s,heat:n}}function Ut(e,t){let r="",a="";for(let s=0;s{a++,e.update(s,Ht(a,t,Date.now()-r).join("\n"))},50);return{id:s,stop:()=>clearInterval(n)}}class qt extends ye{constructor(){super(...arguments),t(this,"name","advert"),t(this,"description","Send repeater advertisement")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("advert"),` ${Fe("Broadcast a repeater advertisement to the mesh network.")}`,"",Be("advert","send advert now"),"",Oe("Adverts announce this repeater's presence to neighbors.")].join("\n"));const r=zt(e,"broadcast");try{const t=await y();r.stop(),t.success?e.update(r.id,`✓ ${Ie("Advert sent")}`,"success"):e.update(r.id,`Error: ${t.error||"Failed"}`,"error")}catch(a){r.stop(),e.update(r.id,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}const Kt=["sig","name","rssi","snr","dist","heard"],Wt={excellent:5,good:4,fair:3,poor:2,critical:1};function Gt(e){const t=Math.floor(Date.now()/1e3-e);return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function Xt(e){return e<1e3?`${Math.round(e)}m`:`${(e/1e3).toFixed(1)}km`}const Vt={excellent:5,good:4,fair:3,poor:2,critical:1};function Yt(e){const t=Vt[e]??0,r=He(e);return(t>0?`${r}${"█".repeat(t)}${ve}`:"")+Fe("⣿".repeat(5-t))}function Jt(e,t=e=>e){return{text:e,color:t}}function Qt(e){return Fe("+"+e.map(e=>"-".repeat(e+2)).join("+")+"+")}function Zt(e,t){const r=e.map((e,r)=>{if(null!=e.rendered){const a=Math.max(0,t[r]-e.text.length);return" "+e.rendered+" ".repeat(a)+" "}return" "+e.color((a=e.text,s=t[r],a.length>=s?a.slice(0,s):a+" ".repeat(s-a.length)))+" ";var a,s});return Fe("|")+r.join(Fe("|"))+Fe("|")}class er extends ye{constructor(){super(...arguments),t(this,"name","neighbors"),t(this,"description","Show direct RF neighbors with signal stats"),t(this,"aliases",["nb","get neighbors","get neighbor"]),t(this,"params","[sig|name|rssi|snr|dist|heard]")}async execute(e){const{output:t,cols:r}=e,a=this.argsAfterName(e.rawInput).toLowerCase().trim();if("help"===a)return void this.printUsage(t);const s=Kt.includes(a)?a:null,n=t.write("processing...","system");try{const e=await g(),a=e.neighbors||{},o=Object.entries(a).filter(([,e])=>e.zero_hop);if(0===o.length){const e=Object.keys(a).length;return void t.update(n,e>0?`No direct neighbors. ${e} relayed neighbor${1!==e?"s":""} known.`:"No neighbors discovered yet.","warning")}const i=function(e){var t;const r=null==(t=e.config)?void 0:t.radio;return(null==r?void 0:r.spreading_factor)&&(null==r?void 0:r.bandwidth)?{sf:r.spreading_factor,bwHz:r.bandwidth}:null}(e),c=function(e){var t;const r=null==(t=e.config)?void 0:t.repeater;return r&&K(r.latitude,r.longitude)?{lat:r.latitude,lon:r.longitude}:null}(e),l=e.noise_floor_dbm;this.sortNeighbors(o,s,i,c,l);const d=s?` ${Ae(`sorted by ${s}`)}`:"",u=[De(`Direct Neighbors (${o.length})`)+d,""];if(r<55)for(const[t,r]of o)u.push(...this.cardLayout(t,r,i,c,l));else{const e=r>=70&&null!=c,t=o.map(([t,r])=>this.buildRow(t,r,i,c,l,e)),a=e?["SIG","NAME","RSSI","SNR","DIST","HEARD"]:["SIG","NAME","RSSI","SNR","HEARD"],s=a.slice(1).map((e,r)=>Math.max(e.length,...t.map(e=>e[r+1].text.length))),n=5,d=s.reduce((e,t)=>e+t+3,0),p=Math.max(4,r-d-n-7),m=[n,Math.min(p,Math.max(4,...t.map(e=>e[1].text.length))),...s.slice(1)];u.push(Qt(m),...t.map(e=>Zt(e,m)),Qt(m),Zt(a.map(e=>Jt(e,Ee)),m),Qt(m)),u.push(this.footer(i,l))}t.update(n,u.join("\n"))}catch(o){t.update(n,`Error: ${o instanceof Error?o.message:"Command failed"}`,"error")}}sortNeighbors(e,t,r,a,s){switch(t){case"sig":e.sort(([,e],[,t])=>(Wt[this.gradeNeighbor(e,r,s)]??0)-(Wt[this.gradeNeighbor(t,r,s)]??0));break;case"name":e.sort(([e,t],[r,a])=>{const s=(t.name||t.node_name||e.slice(0,8)).toLowerCase(),n=(a.name||a.node_name||r.slice(0,8)).toLowerCase();return s.localeCompare(n)});break;case"rssi":e.sort(([,e],[,t])=>(e.rssi??-999)-(t.rssi??-999));break;case"snr":e.sort(([,e],[,t])=>(e.snr??-999)-(t.snr??-999));break;case"dist":e.sort(([,e],[,t])=>(this.distTo(e,a)??1/0)-(this.distTo(t,a)??1/0));break;case"heard":e.sort(([,e],[,t])=>(e.last_seen||0)-(t.last_seen||0));break;default:e.sort(([,e],[,t])=>(t.last_seen||0)-(e.last_seen||0))}}gradeNeighbor(e,t,r){const a=null!=e.rssi?e.rssi-3.5:null,s=null!=r&&r>-100?1:0,n=x(e.snr??null,a,t,s);return(null==n?void 0:n.finalGrade)??"critical"}distTo(e,t){return t&&K(e.latitude,e.longitude)?W(t.lat,t.lon,e.latitude,e.longitude):null}buildRow(e,t,r,a,s,n){const o=this.gradeNeighbor(t,r,s),i=qe(t.name||t.node_name||e.slice(0,8))||e.slice(0,8),c=null!=t.rssi?`${t.rssi} dBm`:"-",l=null!=t.snr?`${t.snr} dB`:"-",d=t.last_seen?Gt(t.last_seen):"-",u=[(p=Yt(o),{text:"|||||",color:e=>e,rendered:p}),Jt(i,Ee),Jt(c,Ie),Jt(l,Ie)];var p;if(n){const e=this.distTo(t,a);u.push(Jt(null!=e?Xt(e):"-",Ae))}return u.push(Jt(d,Ae)),u}cardLayout(e,t,r,a,s){const n=this.gradeNeighbor(t,r,s),o=qe(t.name||t.node_name||e.slice(0,8))||e.slice(0,8),i=null!=t.rssi?`${t.rssi}`:"-",c=null!=t.snr?`${t.snr}`:"-",l=t.last_seen?Gt(t.last_seen):"-",d=this.distTo(t,a),u=null!=d?` ${Fe("dist")} ${Ie(Xt(d))}`:"";return[`${Yt(n)} ${Ee(o)}`,` ${Fe("rssi")} ${Ie(i)} ${Fe("snr")} ${Ie(c)}${u} ${Ae(l)}`,""]}footer(e,t){const r=[];return e&&r.push(`SF${e.sf}/${e.bwHz>=1e3?e.bwHz/1e3+"kHz":e.bwHz+"Hz"}`),r.push("ant 3.5dBi"),null!=t&&r.push(`nf ${t}dBm`),Fe(r.join(" "))}printUsage(e){const t=[De("neighbors"),` ${Fe("Show direct RF neighbors with signal quality, RSSI, SNR, and distance.")}`,"",De("Usage"),Be("neighbors","default sort (most recent)"),Be("neighbors sig","sort by signal grade (weakest first)"),Be("neighbors name","sort alphabetically"),Be("neighbors rssi","sort by RSSI (weakest first)"),Be("neighbors snr","sort by SNR (lowest first)"),Be("neighbors dist","sort by distance (closest first)"),Be("neighbors heard","sort by last seen (oldest first)"),Be("neighbors help","show this help"),"",De("Aliases"),` ${Fe("nb, get neighbors, get neighbor")}`,"",Oe("Signal bars factor radio config, noise floor, and 3.5 dBi antenna gain."),Oe("Only zero-hop (direct RF) neighbors are shown.")];e.write(t.join("\n"))}}class tr extends ye{constructor(){super(...arguments),t(this,"name","get"),t(this,"description","Get repeater parameter"),t(this,"params","{parameter}")}async execute({output:e,rawInput:t}){const r=this.argsAfterName(t).toLowerCase().trim();if("help"===r||!r)return void e.write([De("get"),` ${Fe("Read a repeater configuration parameter.")}`,"",De("Identity"),Be("get name","node name"),Be("get role","node role"),Be("get public.key","public key"),"",De("Location"),Be("get lat","latitude"),Be("get lon","longitude"),"",De("Radio"),Be("get radio","full radio summary"),Be("get freq","frequency (MHz)"),Be("get tx","TX power (dBm)"),Be("get bw","bandwidth (kHz)"),Be("get sf","spreading factor"),Be("get cr","coding rate"),"",De("Timing"),Be("get af","airtime factor (pending backend)"),Be("get txdelay","TX delay factor"),Be("get direct.txdelay","direct TX delay"),Be("get rxdelay","RX delay base"),"",De("Repeater"),Be("get mode","forward or monitor"),Be("get flood.max","max flood hops"),Be("get advert.interval","advert interval"),Be("get duty","duty cycle state"),"",De("Advanced"),Be("get multi.acks","multi-ack count"),Be("get int.thresh","interference threshold (dBm)"),Be("get agc.reset.interval","AGC reset interval")].join("\n"));const a=e.write("processing...","system");try{const t=await g(),{result:s,type:n}=function(e,t){const r=t.config||{},a=r.radio||{},s=r.repeater||{},n=r.delays||{},o=r.duty_cycle||{},i=(e,t)=>({result:Le(e,Ie(t)),type:"value"});switch(e){case"name":return i("name",r.node_name||"Unknown");case"role":return i("role","repeater");case"lat":return i("lat",null!=s.latitude?String(s.latitude):"not set");case"lon":return i("lon",null!=s.longitude?String(s.longitude):"not set");case"freq":return i("freq",a.frequency?`${(a.frequency/1e6).toFixed(3)} MHz`:"?");case"tx":return i("tx",null!=a.tx_power?`${a.tx_power} dBm`:"?");case"bw":return i("bw",a.bandwidth?a.bandwidth/1e3+" kHz":"?");case"sf":return i("sf",String(a.spreading_factor??"?"));case"cr":return i("cr",a.coding_rate?`4/${a.coding_rate}`:"?");case"radio":return a.frequency?{result:[` ${Le("freq",Ie(`${(a.frequency/1e6).toFixed(3)} MHz`))}`,` ${Le("bw",Ie(a.bandwidth/1e3+" kHz"))}`,` ${Le("sf",Ie(String(a.spreading_factor)))}`,` ${Le("cr",Ie(`4/${a.coding_rate}`))}`,` ${Le("tx",Ie(`${a.tx_power} dBm`))}`].join("\n"),type:"value"}:i("radio","?");case"af":case"airtime.factor":return{result:`${Fe("airtime_factor is not yet exposed by the pyMC_Repeater API.")}\n${Fe("Firmware range: 0-9. Controls airtime budget fraction.")}\n${Fe("Tracked in CLI-Alignment.md — needs backend support.")}`,type:"warning"};case"txdelay":return i("txdelay",String(n.tx_delay_factor??"1.0"));case"direct.txdelay":return i("direct.txdelay",String(n.direct_tx_delay_factor??"0.5"));case"rxdelay":return i("rxdelay",String(n.rx_delay_base??"0.0"));case"mode":return i("mode",s.mode||"forward");case"repeat":return i("repeat","forward"===s.mode?"on":"off");case"flood.max":return i("flood.max",String(s.max_flood_hops??"3"));case"flood.advert.interval":return i("flood.advert.interval",null!=s.send_advert_interval_hours?`${s.send_advert_interval_hours}h`:"?");case"advert.interval":return i("advert.interval",null!=s.advert_interval_minutes?`${s.advert_interval_minutes}m`:"120m");case"duty":case"duty.enabled":return i("duty",o.enforcement_enabled?"on":"off");case"duty.max":return i("duty.max",null!=o.max_airtime_percent?`${o.max_airtime_percent}%`:"?");case"multi.acks":return i("multi.acks",String(s.multi_acks??"0"));case"int.thresh":return i("int.thresh",`${s.interference_threshold??-120} dBm`);case"agc.reset.interval":return i("agc.reset.interval",String(s.agc_reset_interval??"0"));case"public.key":return i("public.key",t.public_key||"not available");case"prv.key":return{result:`${Fe("Private key stored in /etc/pymc_repeater/config.yaml")}\n\n ${Le("view",Ie("sudo grep identity_key /etc/pymc_repeater/config.yaml"))}\n ${Le("set",Ie("sudo ./convert_firmware_key.sh <64-byte-hex>"))}`,type:"info"};case"guest.password":case"allow.read.only":return{result:`${Fe("Security settings not exposed via stats API.")}\n${Fe("Check /etc/pymc_repeater/config.yaml")}`,type:"warning"};default:return{result:`Unknown parameter: ${Ie(e)}\n${Fe('Run "get help" to see available parameters.')}`,type:"error"}}}(r,t);e.update(a,s,n)}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}class rr extends ye{constructor(){super(...arguments),t(this,"name","set"),t(this,"description","Set repeater parameter"),t(this,"params","{parameter} {value}")}async execute({output:e,rawInput:t}){var r;const a=this.argsAfterName(t).split(/\s+/),s=null==(r=a[0])?void 0:r.toLowerCase(),n=a.slice(1).join(" ");if("help"===s||!s)return void e.write([De("set"),` ${Fe("Write a repeater configuration parameter.")}`,"",De("Identity"),Be("set name ","node name"),Be("set lat ","latitude (-90 to 90)"),Be("set lon ","longitude (-180 to 180)"),"",De("Radio"),Be("set freq ","frequency"),Be("set tx ","TX power (2-22)"),Be("set bw ","bandwidth"),Be("set sf <5-12>","spreading factor"),Be("set cr <5-8>","coding rate"),"",De("Timing"),Be("set af <0-9>","airtime factor (pending backend)"),Be("set txdelay <0-5>","TX delay factor"),Be("set direct.txdelay <0-5>","direct TX delay"),Be("set rxdelay ","RX delay base"),"",De("Repeater"),Be("set mode ","forward or monitor"),Be("set flood.max <0-64>","max flood hops"),Be("set advert.interval ","advert interval (min)"),Be("set duty ","duty cycle enforcement"),Be("set log ","log level"),"",De("Advanced"),Be("set multi.acks ","multi-ack count"),Be("set int.thresh ","interference threshold"),Be("set agc.reset.interval ","AGC reset interval (x4)"),"",Oe("Some changes require a service restart.")].join("\n"));const o=e.write("processing...","system");try{const{result:r,type:a}=await async function(e,t,r){switch(e){case"mode":return async function(e){const t=e.toLowerCase();return"forward"!==t&&"monitor"!==t?lr('Mode must be "forward" or "monitor"'):(await w(t)).success?cr(`OK - Mode set to ${t}`):lr("Failed")}(t);case"duty":return async function(e){const t="on"===e.toLowerCase()||"1"===e;return(await b(t)).success?cr("OK - Duty cycle "+(t?"enabled":"disabled")):lr("Failed")}(t);case"tx":return ar("tx_power",nr(t,2,22,"TX power must be 2-22 dBm"));case"sf":return ar("spreading_factor",nr(t,5,12,"SF must be 5-12"));case"af":case"airtime.factor":return{result:"Error: airtime_factor is not yet exposed by the pyMC_Repeater API.\nFirmware range: 0-9. Tracked in CLI-Alignment.md — needs backend support.",type:"info"};case"txdelay":return ar("tx_delay_factor",or(t,0,5,"TX delay must be 0.0-5.0"));case"direct.txdelay":return ar("direct_tx_delay_factor",or(t,0,5,"Direct TX delay must be 0.0-5.0"));case"rxdelay":return ar("rx_delay_base",function(e){const t=parseFloat(e);return isNaN(t)||t<0?{ok:!1,error:"Error: RX delay must be >= 0"}:{ok:!0,value:t}}(t));case"flood.max":return ar("max_flood_hops",nr(t,0,64,"Max flood hops must be 0-64"));case"log":return async function(e){const t=e.toUpperCase();if(!["DEBUG","INFO","WARNING","ERROR"].includes(t))return lr("Level must be debug, info, warning, or error");const r=await $(t);return r.success?cr(`OK - Log level set to ${t}`):lr(r.error||"Failed")}(t);case"multi.acks":return ar("multi_acks",nr(t,0,255,"Multi-acks must be 0-255"));case"int.thresh":return ar("interference_threshold",nr(t,-200,0,"Interference threshold must be -200 to 0 dBm"));case"agc.reset.interval":{const e=ir(t);if(!e.ok)return lr(e.error);if(e.value<0)return lr("AGC reset interval must be >= 0");const r=4*Math.floor(e.value/4);return sr("agc_reset_interval",r,`OK - AGC reset interval set to ${r}${r!==e.value?` (rounded from ${e.value})`:""}`)}case"name":{const e=r.trim().substring(r.toLowerCase().indexOf("name")+5).trim();return e?/[\[\]\\/\\:,?*]/.test(e)?lr("Name contains invalid characters: [ ] \\ / : , ? * are not allowed"):ar("node_name",{ok:!0,value:e}):lr("Node name cannot be empty")}case"lat":return ar("latitude",or(t,-90,90,"Latitude must be -90 to 90"));case"lon":return ar("longitude",or(t,-180,180,"Longitude must be -180 to 180"));case"freq":{const e=or(t,100,1e3,"Frequency must be 100-1000 MHz");return e.ok?ar("frequency",{ok:!0,value:1e6*e.value}):lr(e.error)}case"bw":{const e=[7.8,10.4,15.6,20.8,31.25,41.7,62.5,125,250,500],r=parseFloat(t);return isNaN(r)||!e.includes(r)?lr(`BW must be one of: ${e.join(", ")} kHz`):ar("bandwidth",{ok:!0,value:1e3*r})}case"cr":return ar("coding_rate",nr(t,5,8,"Coding rate must be 5-8"));case"advert.interval":{const e=ir(t);return e.ok?0!==e.value&&(e.value<1||e.value>10080)?lr("Advert interval must be 0 (off) or 1-10080 minutes"):sr("advert_interval_minutes",e.value,0===e.value?"OK - Local adverts disabled":`OK - Local advert interval set to ${e.value}m`):lr(e.error)}case"flood.advert.interval":{const e=ir(t);return e.ok?0!==e.value&&(e.value<3||e.value>168)?lr("Flood advert interval must be 0 (off) or 3-168 hours"):sr("flood_advert_interval_hours",e.value,0===e.value?"OK - Flood adverts disabled":`OK - Flood advert interval set to ${e.value}h`):lr(e.error)}case"prv.key":{const e=t.trim();return e?/^[0-9a-fA-F]+$/.test(e)?128!==e.length?lr(`Key must be 64 bytes (128 hex chars), got ${e.length} chars`):{result:`To set this key, run on the Pi:\n\n sudo ./convert_firmware_key.sh ${e}\n\nThen restart: sudo systemctl restart pymc-repeater`,type:"info"}:lr("Private key must be a hex string"):lr("Private key cannot be empty")}default:return lr(`Unknown parameter: ${e}`)}}(s,n,t);e.update(o,r,a)}catch(i){e.update(o,`Error: ${i instanceof Error?i.message:"Command failed"}`,"error")}}}async function ar(e,t){if(!t.ok)return lr(t.error);const r=await v({[e]:t.value});if(!r.success)return lr(r.error||"Failed");let a=`OK - ${e} set to ${t.value}`;return r.restart_required&&(a+="\n⚠ Service restart required for changes to take effect\nRun: sudo systemctl restart pymc_repeater"),cr(a)}async function sr(e,t,r){const a=await v({[e]:t});if(!a.success)return lr(a.error||"Failed");let s=r;return a.restart_required&&(s+="\n⚠ Service restart required for changes to take effect\nRun: sudo systemctl restart pymc_repeater"),cr(s)}function nr(e,t,r,a){const s=parseInt(e);return isNaN(s)||sr?{ok:!1,error:`Error: ${a}`}:{ok:!0,value:s}}function or(e,t,r,a){const s=parseFloat(e);return isNaN(s)||sr?{ok:!1,error:`Error: ${a}`}:{ok:!0,value:s}}function ir(e){const t=parseInt(e);return isNaN(t)?{ok:!1,error:"Error: Expected a number"}:{ok:!0,value:t}}function cr(e){return{result:e,type:"success"}}function lr(e){return{result:`Error: ${e}`,type:"error"}}const dr={excellent:5,good:4,fair:3,poor:2,critical:1};class ur extends ye{constructor(){super(...arguments),t(this,"name","ping"),t(this,"description","Ping neighbor (name or 0xXX)"),t(this,"params","{target} [timeout]")}async execute({output:e,rawInput:t}){var r,a,s,n;const o=this.argsAfterName(t).trim(),i=o.split(/\s+/);if("help"===(null==(r=i[0])?void 0:r.toLowerCase()))return void e.write([De("ping"),` ${Fe("Send a ping to a neighbor and measure round-trip time, signal quality, and path.")}`,"",Be("ping ","ping by node name"),Be("ping 0xAB","ping by hex prefix"),Be("ping 60","ping with custom timeout (seconds)"),"",Oe("Default timeout: 30s. Signal bars factor radio config and noise floor.")].join("\n"));const c=i[i.length-1],l=parseInt(c),d=i.length>1&&!isNaN(l)&&l>0,u=d?i.slice(0,-1).join(" "):o,p=d?l:30;if(!u)return void e.write([De("ping"),` ${Fe("Send a ping to a neighbor and measure round-trip time.")}`,"",Be("ping ","ping by node name"),Be("ping 60","with custom timeout"),"",Oe('Run "ping help" for full usage.')].join("\n"));const m=zt(e,u);try{const[t,r]=await Promise.all([G(u,p),g()]);if(m.stop(),t.success&&t.data){const o=t.data,i=null==(a=r.config)?void 0:a.radio,c=(null==i?void 0:i.spreading_factor)&&(null==i?void 0:i.bandwidth)?{sf:i.spreading_factor,bwHz:i.bandwidth}:null,l=r.noise_floor_dbm,d=null!=l&&l>-100?1:0,u=o.rssi-3.5,p=x(o.snr_db,u,c,d),h=(null==p?void 0:p.finalGrade)??"critical",g=function(e){const t=dr[e]??0,r=He(e);return(t>0?`${r}${"█".repeat(t)}${ve}`:"")+Fe("·".repeat(5-t))}(h),f=(null==(s=o.path)?void 0:s.length)?o.path.length:0,y=(null==(n=o.path)?void 0:n.length)?o.path.join(" > "):"direct",v=h.charAt(0).toUpperCase()+h.slice(1),$=[`${g} ${Ee("Reply from")} ${Ie(o.target_id)}`,"",` ${Le("RTT",Ue(o.rtt_ms))}`,` ${Le("RSSI",`${o.rssi} dBm`)}`,` ${Le("SNR",`${o.snr_db} dB`)}`,` ${Le("Path",y)}${f>0?Fe(` (${f} hop${1!==f?"s":""})`):""}`,` ${Le("Quality",ze(v,h))}`],b=[];c&&b.push(`SF${c.sf}/${c.bwHz>=1e3?c.bwHz/1e3+"kHz":c.bwHz+"Hz"}`),b.push("ant 3.5dBi"),null!=l&&b.push(`nf ${l}dBm`),$.push("",Fe(b.join(" "))),e.update(m.id,$.join("\n"))}else e.update(m.id,t.error||"Ping failed","error")}catch(h){m.stop(),e.update(m.id,`Error: ${h instanceof Error?h.message:"Ping failed"}`,"error")}}}class pr extends ye{constructor(){super(...arguments),t(this,"name","convert"),t(this,"description","Convert between hex and base64"),t(this,"params","hex|base64 {value}")}execute({output:e,args:t}){var r;const a=null==(r=t[1])?void 0:r.toLowerCase(),s=t.slice(2).join(" ").trim();"help"!==a&&(a||s)?"hex"===a?this.hexToBase64(e,s):"base64"===a?this.base64ToHex(e,s):e.write([De("convert"),` ${Fe("Convert between hex and base64 encodings.")}`,"",Be("convert hex ","hex → base64"),Be("convert base64 ","base64 → hex")].join("\n")):e.write([De("convert"),` ${Fe("Convert between hex and base64 encodings.")}`,"",Be("convert hex ","hex → base64"),Be("convert base64 ","base64 → hex"),"",Oe("Example: convert hex 48656C6C6F")].join("\n"))}hexToBase64(e,t){if(t)if(/^[0-9a-fA-F]+$/.test(t))if(t.length%2==0)try{const r=new Uint8Array(t.length/2);for(let e=0;e","error")}base64ToHex(e,t){if(t)try{const r="function"==typeof globalThis.atob?globalThis.atob(t):Buffer.from(t,"base64").toString("binary");let a="";for(let e=0;e","error")}}function mr(){const e=new Date;return`${e.toISOString().slice(0,10)}_${e.toTimeString().slice(0,8).replace(/:/g,"-")}`}function hr(e,t){return`pymc-${e.toISOString().slice(0,10)}-${e.toTimeString().slice(0,5).replace(":","")}-${t}s.json`}const gr=i((e,t)=>({isCapturing:!1,captureStartTime:null,captureStartPacketHashes:new Set,captureTimer:null,reports:[],startCapture:r=>{const{captureTimer:a}=t();a&&clearTimeout(a),e({isCapturing:!0,captureStartTime:new Date,captureStartPacketHashes:new Set(r.map(e=>e.packet_hash))})},stopCapture:r=>{const{isCapturing:a,captureStartTime:s,captureStartPacketHashes:n,captureTimer:o}=t();if(!a||!s)return null;o&&clearTimeout(o);const i=new Date,c=Math.round((i.getTime()-s.getTime())/1e3),l=s.getTime()/1e3,d=r.filter(e=>!n.has(e.packet_hash)&&e.timestamp>=l).sort((e,t)=>e.timestamp-t.timestamp),u={id:mr(),filename:hr(s,c),startTime:s,endTime:i,durationSec:c,packetCount:d.length,packets:d,sizeBytes:500*d.length};return e(e=>({isCapturing:!1,captureStartTime:null,captureStartPacketHashes:new Set,captureTimer:null,reports:[u,...e.reports].slice(0,10)})),u},getReport:e=>t().reports.find(t=>t.id===e),_setTimer:t=>e({captureTimer:t})})),fr=()=>gr(e=>e.reports);function yr(e){var t;return(null==(t=e.match(/.{1,2}/g))?void 0:t.join(" ").toUpperCase())||""}function xr(e){return void 0===e?"UNKNOWN":j[e]??`TYPE_${e}`}function vr(e){return void 0===e?"UNKNOWN":S[e]??`ROUTE_${e}`}function $r(e,t){switch(e){case 4:return function(e){const t=[];let r=0;if(e.length>=32&&(t.push({name:"public_key",offset:r,length:32,bytes:yr(C(e.slice(r,r+32))),decoded:{value:C(e.slice(r,r+32))}}),r+=32),e.length>=r+4){const a=e.slice(r,r+4),s=a[0]|a[1]<<8|a[2]<<16|a[3]<<24;t.push({name:"timestamp",offset:r,length:4,bytes:yr(C(a)),decoded:{value:s>>>0,iso:new Date(1e3*s).toISOString()}}),r+=4}if(e.length>=r+64&&(t.push({name:"signature",offset:r,length:64,bytes:yr(C(e.slice(r,r+64))),decoded:{value:C(e.slice(r,r+64))}}),r+=64),e.length>r){const a=e[r],s=[];if(1&a&&s.push("CHAT_NODE"),2&a&&s.push("REPEATER"),3&a&&s.push("ROOM_SERVER"),16&a&&s.push("HAS_LOCATION"),128&a&&s.push("HAS_NAME"),t.push({name:"flags",offset:r,length:1,bytes:yr(C(e.slice(r,r+1))),decoded:{value:a,binary:a.toString(2).padStart(8,"0"),flags:s}}),r+=1,16&a&&e.length>=r+8){const a=e.slice(r,r+8),s=new ArrayBuffer(8);new Uint8Array(s).set(a);const n=new DataView(s),o=n.getInt32(0,!0),i=n.getInt32(4,!0);t.push({name:"location",offset:r,length:8,bytes:yr(C(a)),decoded:{lat_raw:o,lon_raw:i,latitude:o/1e6,longitude:i/1e6}}),r+=8}if(128&a&&e.length>r){const a=e.slice(r);let s=a.indexOf(0);-1===s&&(s=a.length);const n=(new TextDecoder).decode(a.slice(0,s));t.push({name:"name",offset:r,length:s+(0===a[s]?1:0),bytes:yr(C(a.slice(0,s+1))),decoded:{value:n,encoding:"utf-8",null_terminated:0===a[s]}})}}return t}(t);case 3:return function(e){if(e.length<4)return[];const t=e.slice(0,4),r=t[0]|t[1]<<8|t[2]<<16|t[3]<<24;return[{name:"crc",offset:0,length:4,bytes:yr(C(t)),decoded:{value:r>>>0,hex:(r>>>0).toString(16).toUpperCase().padStart(8,"0"),note:"CRC of the acknowledged packet (little-endian)"}}]}(t);case 9:return function(e){const t=[];if(e.length<9)return t;const r=e.slice(0,4),a=r[0]|r[1]<<8|r[2]<<16|r[3]<<24;t.push({name:"trace_tag",offset:0,length:4,bytes:yr(C(r)),decoded:{value:a>>>0,hex:(a>>>0).toString(16).toUpperCase().padStart(8,"0")}});const s=e.slice(4,8),n=s[0]|s[1]<<8|s[2]<<16|s[3]<<24;if(t.push({name:"auth_code",offset:4,length:4,bytes:yr(C(s)),decoded:{value:n>>>0}}),t.push({name:"flags",offset:8,length:1,bytes:yr(C(e.slice(8,9))),decoded:{value:e[8],binary:e[8].toString(2).padStart(8,"0")}}),e.length>9){const r=e.slice(9),a=Array.from(r).map(e=>e.toString(16).toUpperCase().padStart(2,"0"));t.push({name:"target_path",offset:9,length:r.length,bytes:yr(C(r)),decoded:{hops:a,path_string:a.join("->")}})}return t}(t);case 8:return function(e){if(0===e.length)return[];const t=Array.from(e).map(e=>e.toString(16).toUpperCase().padStart(2,"0"));return[{name:"path_hops",offset:0,length:e.length,bytes:yr(C(e)),decoded:{hops:t,path_string:t.join("->")}}]}(t);case 5:return function(e){const t=[];if(e.length<1)return t;if(t.push({name:"channel_hash",offset:0,length:1,bytes:yr(C(e.slice(0,1))),decoded:{value:e[0].toString(16).toUpperCase().padStart(2,"0")}}),e.length>13){const r=12,a=e.length-1-r;t.push({name:"ciphertext",offset:1,length:a,bytes:yr(C(e.slice(1,1+a))),decoded:{length:a,note:"Encrypted message content"}}),t.push({name:"mac",offset:1+a,length:r,bytes:yr(C(e.slice(-r))),decoded:{note:"Message authentication code"}})}return t}(t);default:return function(e){return 0===e.length?[]:[{name:"raw_data",offset:0,length:e.length,bytes:yr(C(e)),decoded:{length:e.length}}]}(t)}}function br(e){const t=e.type??e.payload_type??0,r=e.route??e.route_type??0,a=e.raw_packet||"";let s,n=null;if(a){const t=X.fromHex(a);if(t.success&&t.packet){const e=t.packet;try{n=V(e)}catch{n=null}const r=k(a);let o=0;const i={offset:0,length:1,bytes:yr(a.slice(0,2)),decoded:{route_type:e.routeType,route_name:e.routeTypeName,payload_type:e.payloadType,payload_name:e.payloadTypeName,version:e.payloadVersion}};o+=1,e.hasTransportCodes()&&(o+=4);const c={offset:o,length:1,bytes:yr(C(r.slice(o,o+1))),decoded:{value:e.pathLen}};o+=1;const l=o,d=r.slice(o,o+e.pathLen),u=Array.from(e.path).map(e=>e.toString(16).toUpperCase().padStart(2,"0")),p=9===e.payloadType,m={offset:l,length:e.pathLen,bytes:yr(C(d)),decoded:{hops:u,path_string:u.length>0?u.join("->"):"(direct)",...p&&{note:"For TRACE packets, path bytes are SNR×4 values, not node hashes",snr_values:Array.from(e.path).map(e=>{let t=e;return t>127&&(t-=256),t/4})}}};o+=e.pathLen,s={header:i,path_length:c,path:m,payload:{offset:o,length:e.payload.length,bytes:yr(e.payloadHex),sections:$r(e.payloadType,e.payload)}}}else s=wr(e)}else s=wr(e);return{timestamp:e.timestamp,packet_hash:e.packet_hash,type:t,type_name:xr(t),route:r,route_name:vr(r),rssi:e.rssi,snr:e.snr,length:e.length??0,src_hash:e.src_hash,dst_hash:e.dst_hash,transmitted:e.transmitted,drop_reason:e.drop_reason,is_duplicate:e.is_duplicate,lbt_attempts:e.lbt_attempts,lbt_backoff_delays_ms:e.lbt_backoff_delays_ms,lbt_channel_busy:e.lbt_channel_busy,raw_packet:a,structure:s,decoded:n}}function wr(e){var t;const r=e.type??e.payload_type??0,a=e.route??e.route_type??0,s=e.original_path??e.forwarded_path??[];return{header:{offset:0,length:1,bytes:"??",decoded:{route_type:a,route_name:vr(a),payload_type:r,payload_name:xr(r),version:0}},path_length:{offset:1,length:1,bytes:s.length.toString(16).toUpperCase().padStart(2,"0"),decoded:{value:s.length}},path:{offset:2,length:s.length,bytes:s.join(" "),decoded:{hops:s,path_string:s.length>0?s.join("->"):"(direct)"}},payload:{offset:2+s.length,length:(null==(t=e.payload)?void 0:t.length)??0,bytes:e.payload??"",sections:e.payload?$r(r,k(e.payload)):[]}}}function _r(e,t){const r=function(e,t){var r;return{capture:{start:e.startTime.toISOString(),end:e.endTime.toISOString(),duration_sec:e.durationSec,packet_count:e.packetCount,node_name:(null==t?void 0:t.node_name)??"unknown",local_hash:(null==t?void 0:t.local_hash)??"unknown",pymc_console_version:_,pymc_repeater_version:(null==t?void 0:t.version)??"unknown",radio_config:(null==(r=null==t?void 0:t.config)?void 0:r.radio)?{frequency:t.config.radio.frequency,tx_power:t.config.radio.tx_power,bandwidth:t.config.radio.bandwidth,spreading_factor:t.config.radio.spreading_factor}:null},packets:e.packets.map(br)}}(e,t),a=JSON.stringify(r,null,2),s=new Blob([a],{type:"application/json"}),n=URL.createObjectURL(s),o=document.createElement("a");o.href=n,o.download=e.filename,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}function kr(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}class Cr extends ye{constructor(){super(...arguments),t(this,"name","cap"),t(this,"description","Packet capture (start/end/list/export)")}matches(e){const t=e.toLowerCase().trim();return"cap"===t||"cap help"===t||t.startsWith("start cap")||t.startsWith("end cap")||t.startsWith("list cap")||t.startsWith("export cap")}async execute({output:e,rawInput:t}){const r=t.toLowerCase().trim();return"cap"===r||"cap help"===r?this.showHelp(e):r.startsWith("start cap")?this.startCapture(e,r):"end cap"===r?this.endCapture(e):"list cap"===r?this.listCaptures(e):r.startsWith("export cap")?this.exportCapture(e,r):void this.showHelp(e)}showHelp(e){const t=gr.getState(),r=t.isCapturing?`\n${Pe('Recording in progress... use "end cap" to stop')}`:"",a=t.reports.length,s=a>0?` (${a} saved)`:"",n=[De("Packet Capture"),"",Be("start cap","Start capture (default: 120s)"),Be("end cap","Stop capture early"),Be("list cap",`List saved captures${s}`),Be("export cap","Download capture by ID"),"",Oe("Captures stored in session memory. JSON includes decoded payloads."),r].filter(Boolean);e.write(n.join("\n"))}startCapture(e,t){const r=t.slice(9).trim(),a=r?parseInt(r):120;if(isNaN(a)||a<1||a>3600)return void e.write("Error: Duration must be 1-3600 seconds","error");const s=gr.getState();if(s.isCapturing)return void e.write('Error: Capture already in progress. Use "end cap" first.',"error");const n=N.getState().packets;s.startCapture(n);let o=a;const i=e.write(Pe(`Capturing... ${o}s remaining`),"system"),c=setInterval(()=>{o--;const t=gr.getState();if(o>=0&&t.isCapturing){const r=N.getState().packets.filter(e=>{if(!t.captureStartTime)return!1;const r=t.captureStartTime.getTime()/1e3;return e.timestamp>=r&&!t.captureStartPacketHashes.has(e.packet_hash)}).length,a=o>0?`${o}s remaining`:"finishing...";e.update(i,Pe(`Capturing... ${a} (${r} captured)`),"system")}},1e3),l=setTimeout(()=>{clearInterval(c);const t=gr.getState();if(t.isCapturing){const r=N.getState().packets,a=t.stopCapture(r);a?e.write(`✓ Capture complete!\n Captured: ${a.packetCount} packets\n Duration: ${a.durationSec}s\n Size: ~${kr(a.sizeBytes)}\n\nRun \`export cap ${a.id}\` to download.`,"value"):e.write("Capture completed with no packets.","warning")}},1e3*a);s._setTimer(l)}endCapture(e){const t=gr.getState();if(!t.isCapturing)return void e.write("No capture in progress.","warning");const r=N.getState().packets,a=t.stopCapture(r);a?e.write(`✓ Capture stopped!\n Captured: ${a.packetCount} packets\n Duration: ${a.durationSec}s\n Size: ~${kr(a.sizeBytes)}\n\nRun \`export cap ${a.id}\` to download.`,"value"):e.write("Capture stopped with no packets.","warning")}listCaptures(e){const{reports:t}=gr.getState();if(0===t.length)return void e.write("No capture reports available.\nStart a capture with: start cap [seconds]","info");const r=t.map((e,t)=>` ${t+1}. ${e.packetCount} pkts • ${e.durationSec}s • ~${kr(e.sizeBytes)} (id: ${e.id})`);e.write(`Capture Reports (${t.length}):\n${r.join("\n")}`,"info")}exportCapture(e,t){const r=t.slice(10).trim(),a=gr.getState(),s=N.getState().stats;if(!r){if(0===a.reports.length)e.write("No capture reports available.\nStart a capture with: start cap [seconds]","info");else{const t=a.reports.map((e,t)=>` ${t+1}. ${e.id}`);e.write(`Usage: export cap \n\nAvailable reports:\n${t.join("\n")}`,"info")}return}let n=a.getReport(r);if(!n){const e=parseInt(r)-1;n=a.reports[e]}n?(_r(n,s),e.write(`✓ Downloading ${n.filename}...`,"value")):e.write(`Error: Report "${r}" not found.\nUse "list cap" to see available reports.`,"error")}}class Sr extends ye{constructor(){super(...arguments),t(this,"name","identities"),t(this,"description","List configured identities"),t(this,"aliases",["id","ids"])}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("identities"),` ${Fe("List all configured repeater and room server identities.")}`,"",Be("identities","list identities"),"",De("Aliases"),` ${Fe("id, ids")}`].join("\n"));const a=e.write("processing...","system");try{const t=await T();if(!t.success||!t.data)return void e.update(a,t.error||"Failed to fetch identities","error");const s=t.data,n=(null==(r=s.configured)?void 0:r.length)?s.configured:s.registered||[];if(0===n.length)return void e.update(a,"No identities configured.","warning");const o=[De(`Identities (${n.length})`),"",...n.map((e,t)=>{var r;const a=e.name||"Unnamed",s=e.type||"unknown",n=(null==(r=e.hash)?void 0:r.slice(0,8))||"—";return` ${Fe(`${t+1}.`)} ${Ee(a)} ${Ae(s)} ${Ie(n)}`})];e.update(a,o.join("\n"))}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}class jr extends ye{constructor(){super(...arguments),t(this,"name","keys"),t(this,"description","List transport keys")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("keys"),` ${Fe("List configured transport encryption keys.")}`,"",Be("keys","list transport keys")].join("\n"));const r=e.write("processing...","system");try{const t=await Y();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch transport keys","error");const a=t.data;if(0===a.length)return void e.update(r,"No transport keys configured.","warning");const s=[De(`Transport Keys (${a.length})`),"",...a.map(e=>{const t=e.parent_id?` ${Ae(`parent: ${e.parent_id}`)}`:"";return` ${Ee(e.name)} ${Le("flood",Ie(e.flood_policy))}${t}`})];e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Nr extends ye{constructor(){super(...arguments),t(this,"name","acl"),t(this,"description","Show ACL statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("acl"),` ${Fe("Display access control list statistics.")}`,"",Be("acl","show ACL stats")].join("\n"));const r=e.write("processing...","system");try{const t=await R();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch ACL stats","error");const a=t.data,s=[De("ACL Stats"),"",` ${Le("Identities",Ie(String(a.total_identities)))}`,` ${Le("Total clients",Ie(String(a.total_clients)))}`,` ${Le("Admin",Ie(String(a.admin_clients)))}`,` ${Le("Guest",Ie(String(a.guest_clients)))}`];if(a.by_identity_type){const e=a.by_identity_type.repeater,t=a.by_identity_type.room_server;e&&s.push(` ${Le("Repeater",`${Ie(String(e.count))} ids ${Fe(`${e.clients} clients`)}`)}`),t&&s.push(` ${Le("Room Server",`${Ie(String(t.count))} ids ${Fe(`${t.clients} clients`)}`)}`)}e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Tr extends ye{constructor(){super(...arguments),t(this,"name","rooms"),t(this,"description","Show room server statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("rooms"),` ${Fe("Display room server statistics and sync status.")}`,"",Be("rooms","list rooms")].join("\n"));const r=e.write("processing...","system");try{const t=await M();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch room stats","error");const a=t.data.rooms||[];if(0===a.length)return void e.update(r,"No room servers configured.","warning");const s=[De(`Rooms (${a.length})`),"",...a.map(e=>[` ${Ee(e.room_name)}`,` ${Le("msgs",Ie(String(e.total_messages)))} ${Le("clients",`${Ie(String(e.active_clients))}${Ae(`/${e.total_clients}`)}`)} ${Le("sync",e.sync_running?Ie("running"):Ae("idle"))}`]).flat()];e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Rr extends ye{constructor(){super(...arguments),t(this,"name","restart"),t(this,"description","Restart pymc-repeater service"),t(this,"aliases",["reboot"])}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("restart"),` ${Fe("Restart the pymc-repeater systemd service.")}`,"",Be("restart","restart the service"),"",De("Aliases"),` ${Fe("reboot")}`,"",Oe("Requires polkit permissions for the web user."),Oe("The page will need a manual refresh after restart.")].join("\n"));const r=e.write("Restarting service...","system");try{const t=await J(AbortSignal.timeout(8e3));if(t.success)return e.update(r,"Service restart initiated.","success"),void(await this.waitForService(e));const a=t.status;if(403===a||401===a)return void e.update(r,"Error: Permission denied.\n\nThe web user needs polkit permissions to restart the service.\nSee: /etc/polkit-1/localauthority/50-local.d/pymc-repeater.pkla","error");e.update(r,t.error||"Restart failed","error")}catch(a){const t=a instanceof Error?a.message:"";t.includes("ERR_NETWORK")||t.includes("ECONNRESET")||t.includes("Failed to fetch")||t.includes("Load failed")||t.includes("network connection was lost")||t.includes("abort")||t.includes("timeout")||a instanceof DOMException&&"TimeoutError"===a.name||a instanceof DOMException&&"AbortError"===a.name?(e.update(r,"Service is restarting (connection dropped).","success"),await this.waitForService(e)):e.update(r,`Error: ${t||"Restart failed"}`,"error")}}waitForService(e){return new Promise(t=>{const r=e.write("Waiting for service...","system");let a=0;setTimeout(()=>{const s=setInterval(async()=>{a++,e.update(r,`Waiting for service... ${a}s`,"system");try{const n=new AbortController,o=setTimeout(()=>n.abort(),3e3);return await fetch(`${E}/api/stats`,{signal:n.signal}),clearTimeout(o),clearInterval(s),e.update(r,`Service connected. (${a+4}s)`,"success"),void t()}catch{}a>=30&&(clearInterval(s),e.update(r,"Service did not respond within 34s. Check manually.","warning"),t())},1e3)},4e3)})}}const Mr="[",Er=`${Mr}0m`,Ar=`${Mr}32m`,Ir=`${Mr}33m`,Fr=`${Mr}31m`,Lr=`${Mr}36m`,Br=`${Mr}90m`,Dr=`${Mr}1m`;function Or(e){return e>=1073741824?`${(e/1073741824).toFixed(1)}G`:e>=1048576?`${(e/1048576).toFixed(0)}M`:e>=1024?`${(e/1024).toFixed(0)}K`:`${e}B`}function Pr(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}function Ur(e,t){const r=" ".repeat(2),a=t-2,s=[];let n="",o=0;for(const i of e){const e=Ye(i);0===o?(n=i,o=e):o+2+e<=a?(n+=" "+i,o+=2+e):(s.push(r+n),n=i,o=e)}return o>0&&s.push(r+n),s}function Hr(e,t,r,a,s){if(!e||!t)return` ${Br}Waiting for data…${Er}`;const n=function(e,t,r){var a,s;const n=e.node_name||"unknown",o=e.version?`v${e.version}`:"",i=(null==(a=t.system)?void 0:a.uptime)?Pr(t.system.uptime):"?",c=Pr(e.uptime_seconds||0),l=Math.max(3,r-4),d=(null==(s=t.cpu.load_avg)?void 0:s["1min"].toFixed(2))??"?",u=t.cpu.load_avg?`${d} ${t.cpu.load_avg["5min"].toFixed(2)} ${t.cpu.load_avg["15min"].toFixed(2)}`:"?",p=r>=60?u:d;return[` ${Lr}${Dr}${n}${Er} ${Br}${o}${Er}`,` ${Br}${"─".repeat(l)}${Er}`,...Ur([Le("Sys",Ie(i)),Le("Svc",Ie(c)),Le("Load",Ie(p))],r)]}(e,t,a),o=function(e,t){const r=Math.max(6,Math.min(30,t-15)),a=t-(15+r)-2,s=[""],n=`${e.cpu.count} core${e.cpu.count>1?"s":""}`,o=`${Or(e.memory.used)}/${Or(e.memory.total)}`,i=`${Or(e.disk.used)}/${Or(e.disk.total)}`,c=(e,t,s)=>{const n=function(e,t){const r=Math.max(0,Math.min(100,e)),a=Math.round(r/100*t),s=t-a,n=r>=90?Fr:r>=70?Ir:Ar;return`[${n}${"█".repeat(a)}${Er}${Br}${"░".repeat(s)}${Er}] ${n}${`${r.toFixed(1)}%`.padStart(6)}${Er}`}(t,r),o=a>=s.length?` ${Ae(s)}`:"";return` ${Fe(e.padEnd(4))}${n}${o}`};s.push(c("CPU",e.cpu.usage_percent,n)),s.push(c("Mem",e.memory.usage_percent,o)),s.push(c("Dsk",e.disk.usage_percent,i));const l=Object.entries(e.temperatures||{});if(l.length>0){const e=l.map(([e,t])=>{return`${Ae(e+":")} ${r=t,r>=80?`${Fr}${Dr}${r.toFixed(1)}°C${Er}`:r>=60?`${Ir}${r.toFixed(1)}°C${Er}`:`${Ar}${r.toFixed(1)}°C${Er}`}`;var r});s.push(...Ur(e,t))}return s}(t,a),i=function(e,t){var r,a;const s=e.neighbors||{},n=Object.keys(s).length,o=Object.values(s).filter(e=>e.zero_hop).length,i=(null==(a=null==(r=e.config)?void 0:r.repeater)?void 0:a.mode)||"?",c=null!=e.noise_floor_dbm?`${e.noise_floor_dbm}dBm`:"?",l=e.duty_cycle_percent??0,d=["",` ${Br}MESH${Er}`];return d.push(...Ur([Le("Mode",Ie(i)),Le("Nbrs",`${Ie(String(o))}${Ae(`/${n}`)}`),Le("Noise",Ie(c)),Le("Air",Ie(`${l.toFixed(1)}%`))],t)),d.push(...Ur([Le("RX",Ie(String(e.rx_count??0))),Le("TX",Ie(String(e.tx_count??0))),Le("FWD",Ie(String(e.forwarded_count??0))),Le("Drop",Ie(String(e.dropped_count??0)))],t)),d.push(...Ur([Le("RX/h",Ie(String(Math.round(e.rx_per_hour??0)))),Le("FWD/h",Ie(String(Math.round(e.forwarded_per_hour??0))))],t)),d}(e,a),c=function(e,t){if(!e.network)return[];const r=["",` ${Br}NET${Er}`];return r.push(...Ur([Le("TX",Ie(Or(e.network.bytes_sent))),Le("RX",Ie(Or(e.network.bytes_recv))),Le("Pkt",`${Ie(String(e.network.packets_sent))}${Ae("/")}${Ie(String(e.network.packets_recv))}`)],t)),r}(t,a),l=["",` ${Br}${(new Date).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})} · Ctrl+C to exit${Er}`],d=[...n,...o,...i,...c,...l],u=s?Je(d,a):0,p=function(e,t,r){if(0===e.length)return[];const a=t>=50,s=t>=50?6:5,n=t>=50?6:5,o=a?7:0,i=Math.max(4,t-2-o-s-n-4),c=t>=50?8:5,l=null!=r?Math.max(0,Math.min(c,r-3)):c;if(l<=0)return[];const d=["",` ${Br}PROCS${Er}`],u=(a?"PID".padEnd(o):"")+"CPU".padStart(s)+"MEM".padStart(n)+" NAME";d.push(` ${Ae(u)}`);for(const p of e.slice(0,l)){const e=a?Ae(String(p.pid).padEnd(o)):"",r=(t>=50?p.cpu_percent.toFixed(1):p.cpu_percent.toFixed(0)).padStart(s),c=(t>=50?p.memory_percent.toFixed(1):p.memory_percent.toFixed(0)).padStart(n),l=p.name.length>i?p.name.slice(0,i-1)+"…":p.name,u=p.cpu_percent>=50?Fr:p.cpu_percent>=20?Ir:"",m=u?`${u}${r}${Er}`:r;d.push(` ${e}${m}${Ae(c)} ${l}`)}return d}(r,a,s?Math.max(0,s-u):void 0),m=[...d.slice(0,-l.length),...p,...l];return s&&m.length>s&&(m.length=s),m.join("\n")}class zr extends ye{constructor(){super(...arguments),t(this,"name","top"),t(this,"description","Live system overview (Ctrl+C to exit)"),t(this,"aliases",["htop"])}async execute({output:e,rawInput:t,cols:r,signal:a}){var s,n;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("top"),` ${Fe("Live-updating system overview combining hardware")}`,` ${Fe("stats, mesh metrics, and running processes.")}`,` ${Fe("Refreshes every 3s. Press Ctrl+C to exit.")}`,"",Be("top","start live display"),"",De("Sections"),` ${Fe("Header Node name, version, uptime, load average")}`,` ${Fe("Gauges CPU, memory, disk usage with bar charts")}`,` ${Fe("Mesh Mode, neighbors, packet counts, airtime")}`,` ${Fe("Network TCP/IP bytes and packet counters")}`,` ${Fe("Processes Top 8 processes by CPU usage")}`,"",De("Aliases"),` ${Fe("htop")}`].join("\n"));let o=null,i=[],c=N.getState().stats;try{const[e,t]=await Promise.all([f(),A()]);e.success&&e.data&&(o=e.data),t.success&&t.data&&(i=t.data.processes.sort((e,t)=>t.cpu_percent-e.cpu_percent))}catch{}if(!a.aborted){null==(s=e.enterFullscreen)||s.call(e);try{const t=e.write(Hr(c,o,i,e.cols??r,e.rows));await new Promise(s=>{if(a.aborted)return void s();const n=setInterval(()=>{if(a.aborted)return clearInterval(n),void s();(async()=>{c=N.getState().stats;try{const[e,t]=await Promise.all([f(),A()]);e.success&&e.data&&(o=e.data),t.success&&t.data&&(i=t.data.processes.sort((e,t)=>t.cpu_percent-e.cpu_percent))}catch{}a.aborted||e.update(t,Hr(c,o,i,e.cols??r,e.rows))})()},3e3);a.addEventListener("abort",()=>{clearInterval(n),s()},{once:!0})})}finally{null==(n=e.exitFullscreen)||n.call(e)}}}}const qr=["DONT PANIC","C0FFEE","FEED C0DE","LOL","I CANNOT DO THAT"];function Kr(){return qr[Math.floor(Math.random()*qr.length)]}const Wr=new EventTarget,Gr="shell-phrase";function Xr(e){Wr.dispatchEvent(new CustomEvent(Gr,{detail:e??Kr()}))}class Vr extends ye{constructor(){super(...arguments),t(this,"name","fortune"),t(this,"description","Display a fortune on the header"),t(this,"aliases",["lol"])}execute({output:e}){const t=Kr();Xr(t),e.write(Fe(` ${t}`))}}const Yr=new EventTarget,Jr="party-time";class Qr extends ye{constructor(){super(...arguments),t(this,"name","partytime"),t(this,"description","Party on, Garth!"),t(this,"aliases",["party","excellent","waynesworld"])}execute({output:e}){Yr.dispatchEvent(new Event(Jr)),Xr("PARTY 0N GARTH"),e.write(Fe(" SCHWING!"))}}class Zr extends ye{constructor(){super(...arguments),t(this,"name","ver"),t(this,"description","Show version info"),t(this,"aliases",["version"])}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("ver"),` ${Fe("Display pyMC_Repeater, core, and console version.")}`,` ${Fe('Equivalent to firmware serial CLI "ver" command.')}`,"",Be("ver","show version"),"",De("Aliases"),` ${Fe("version")}`].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a="0.9.285";e.update(r,[` ${Le("pyMC_Repeater",Ie(`v${t.version||"?"}`))}`,` ${Le("pyMC_Core",Ie(t.core_version||"?"))}`,` ${Le("pyMC_Console",Ie(`v${a}`))}`].join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class ea extends ye{constructor(){super(...arguments),t(this,"name","clock"),t(this,"description","Show system UTC time")}execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("clock"),` ${Fe("Display the current system UTC time.")}`,` ${Fe('Equivalent to firmware serial CLI "clock" command.')}`,` ${Fe("Use to verify NTP sync and correlate packet timestamps.")}`,"",Be("clock","show UTC time")].join("\n"));const r=new Date;e.write([` ${Le("UTC",Ie(r.toUTCString()))}`,` ${Le("ISO",Ie(r.toISOString()))}`,` ${Le("Unix",Ie(String(Math.floor(r.getTime()/1e3))))}`].join("\n"),"value")}}class ta extends ye{constructor(){super(...arguments),t(this,"name","stats-packets"),t(this,"description","Packet counters")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-packets"),` ${Fe("Display packet counters: sent, received, forwarded, dropped.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-packets" command.')}`,"",Be("stats-packets","show packet counters")].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a=t.rx_count??0,s=t.tx_count??0,n=t.forwarded_count??0,o=t.dropped_count??0,i=t.rx_per_hour??0,c=t.forwarded_per_hour??0,l=t.duplicate_cache_size??0;e.update(r,[` ${Ee("Packet Counters")}`,"",` ${Le("RX",Ie(String(a)))} ${Fe(`${i.toFixed(1)}/hr`)}`,` ${Le("TX",Ie(String(s)))}`,` ${Le("Forwarded",Ie(String(n)))} ${Fe(`${c.toFixed(1)}/hr`)}`,` ${Le("Dropped",Ie(String(o)))}`,"",` ${Le("Dup cache",Ie(String(l)))}`].join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}function ra(e){return e>=6e4?`${(e/6e4).toFixed(1)}m`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e.toFixed(0)}ms`}class aa extends ye{constructor(){super(...arguments),t(this,"name","stats-radio"),t(this,"description","Radio health stats")}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-radio"),` ${Fe("Display radio health: airtime, noise floor, duty cycle.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-radio" command.')}`,"",Be("stats-radio","show radio stats")].join("\n"));const a=e.write("processing...","system");try{const t=await g(),s=null==(r=t.config)?void 0:r.radio,n=t.noise_floor_dbm,o=t.airtime_used_ms??0,i=t.airtime_remaining_ms??0,c=t.duty_cycle_percent??0,l=t.utilization_percent??0,d=t.total_airtime_ms??0,u=[` ${Ee("Radio Stats")}`,""];if(s){const e=s.frequency?`${(s.frequency/1e6).toFixed(3)} MHz`:"?",t=s.bandwidth?s.bandwidth/1e3+" kHz":"?";u.push(` ${Le("Radio",Ie(`${e} SF${s.spreading_factor??"?"} BW ${t} CR 4/${s.coding_rate??"?"} ${s.tx_power??"?"} dBm`))}`),u.push("")}u.push(` ${Le("Noise floor",null!=n?Ie(`${n} dBm`):Fe("N/A"))}`),u.push(` ${Le("Airtime used",Ie(ra(o)))} ${Fe(`remaining: ${ra(i)}`)}`),u.push(` ${Le("Total airtime",Ie(ra(d)))}`),u.push(` ${Le("Duty cycle",Ie(`${c.toFixed(1)}%`))}`),u.push(` ${Le("Utilization",Ie(`${l.toFixed(1)}%`))}`),e.update(a,u.join("\n"),"value")}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}function sa(e){return e>=1073741824?`${(e/1073741824).toFixed(1)} GB`:e>=1048576?`${(e/1048576).toFixed(0)} MB`:`${(e/1024).toFixed(0)} KB`}class na extends ye{constructor(){super(...arguments),t(this,"name","stats-core"),t(this,"description","Engine vitals")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-core"),` ${Fe("Display engine vitals: uptime, memory, CPU, queue depth.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-core" command.')}`,` ${Fe("On firmware this shows free heap — here we show Linux process health.")}`,"",Be("stats-core","show core stats")].join("\n"));const r=e.write("processing...","system");try{const[t,a]=await Promise.all([g(),f()]),s=[` ${Ee("Core Stats")}`,"",` ${Le("Uptime",Ie(xt(t.uptime_seconds??0)))}`,` ${Le("Dup cache",Ie(`${t.duplicate_cache_size??0} entries`))} ${Fe(`TTL ${t.cache_ttl??"?"}s`)}`];if(a.success&&a.data){const e=a.data;s.push(""),s.push(` ${Le("CPU",Ie(`${e.cpu.usage_percent.toFixed(1)}%`))} ${Fe(`${e.cpu.count} core${e.cpu.count>1?"s":""}`)}`),e.cpu.load_avg&&s.push(` ${Le("Load",Ie(`${e.cpu.load_avg["1min"].toFixed(2)} / ${e.cpu.load_avg["5min"].toFixed(2)} / ${e.cpu.load_avg["15min"].toFixed(2)}`))}`),s.push(` ${Le("Memory",Ie(`${sa(e.memory.used)} / ${sa(e.memory.total)}`))} ${Fe(`${e.memory.usage_percent.toFixed(0)}%`)}`);const t=Object.entries(e.temperatures||{});t.length>0&&s.push(` ${Le("Temp",Ie(`${t[0][1].toFixed(1)}°C`))}`)}e.update(r,s.join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}const oa=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "],ia=te-1;class ca extends ye{constructor(){super(...arguments),t(this,"name","hello"),t(this,"description","Play the PYMC burst intro"),t(this,"aliases",["hi","intro"])}async execute({output:e,signal:t}){if(t.aborted)return;let r=0;const a=e.write(Q(oa,0).join("\n"));try{await new Promise(s=>{const n=setInterval(()=>{if(t.aborted||r>=ia)return clearInterval(n),t.aborted||e.update(a,Q(oa,ia).join("\n")),void s();r++,e.update(a,Q(oa,r).join("\n"))},Z);t.addEventListener("abort",()=>{clearInterval(n),s()},{once:!0})})}finally{ee()}}}const la=i(e=>({entries:[],commandHistory:[],isInitialized:!1,addEntry:t=>{const r="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),a={...t,id:r,timestamp:Date.now()};return e(e=>({entries:[...e.entries,a]})),r},updateEntry:(t,r)=>{e(e=>({entries:e.entries.map(e=>e.id===t?{...e,...r}:e)}))},addCommand:t=>{e(e=>({commandHistory:[...e.commandHistory,t]}))},clearEntries:()=>{e({entries:[],commandHistory:[]})},setInitialized:t=>{e({isInitialized:t})}}));function da({isOpen:e,onClose:t}){const a=fr(),s=N(e=>e.stats);return r.jsxs(I,{open:e,onClose:t,size:"sm",children:[r.jsx(F,{icon:r.jsx(ie,{size:20}),title:"Download Captures",onClose:t}),r.jsx(L,{className:"flex flex-col gap-2",children:0===a.length?r.jsxs("div",{className:"flex flex-col items-center gap-2 py-6 text-fg-muted",children:[r.jsx(ce,{className:"w-8 h-8 opacity-40"}),r.jsx("p",{className:"text-sm",children:"No captures available."})]}):a.map(e=>r.jsxs("div",{className:"flex items-center gap-3 px-4 py-3 radius-inset bg-elevated/50 border border-edge-subtle",children:[r.jsxs("div",{className:"flex-1 min-w-0",children:[r.jsx("p",{className:"type-label text-fg-primary truncate",children:e.filename}),r.jsxs("p",{className:"text-xs text-fg-muted mt-0.5",children:[e.packetCount," packets · ",e.durationSec,"s · ~",kr(e.sizeBytes)]})]}),r.jsx(B,{plain:!0,color:"primary",onClick:()=>(e=>{const t=a.find(t=>t.id===e);t&&_r(t,s)})(e.id),title:"Download",className:"flex-shrink-0",children:r.jsx(ie,{"data-slot":"icon"})})]},e.id))})]})}function ua(){const e=fr(),[t,s]=a.useState(!1);return r.jsxs(r.Fragment,{children:[r.jsx(ne,{icon:r.jsx(le,{size:20}),onClick:()=>s(!0),title:e.length>0?`Download captures (${e.length})`:"Captures",variant:"red",iconActiveColor:m.red}),r.jsx(da,{isOpen:t,onClose:()=>s(!1)})]})}const pa=[{name:"acl",description:"Access control list statistics — identity and client counts.",body:["```","> acl","ACL Stats",""," Identities 2"," Total clients 5"," Admin 2"," Guest 3"," Repeater 1 ids 3 clients"," Room Server 1 ids 2 clients","```"],searchText:"acl access control list statistics identity client"},{name:"advert",description:"Broadcast a repeater advertisement to the mesh.",body:["```","> advert","✓ Advert sent","```"],searchText:"advert advertisement broadcast mesh"},{name:"board",description:"Hardware and platform info — CPU, memory, disk, temperatures, network I/O.",body:["```","> board"," Node Local-Node"," Runtime pyMC_Repeater v1.0.0"," Core v1.12.0",""," CPU 12.3% 4 cores"," Load 0.42 / 0.38 / 0.35"," Temp 48.2°C",""," Memory 412 MB / 664 MB 62%"," Disk 5.2 GB / 28.7 GB 18%",""," System uptime 14d 3h 22m"," Service uptime 2d 14h 32m"," Net TX/RX 128 MB / 342 MB","```"],searchText:"board hardware platform cpu memory disk temperature network"},{name:"cap",description:"Packet capture — start, stop, list, and export captures.",body:["**Sub-commands:** `start cap [sec]` · `end cap` · `list cap` · `export cap [id]`","","**`start cap [seconds]`** — Begin capture (default 120s, max 3600):","```","> start cap","Capturing... 118s remaining (4 captured)","","✓ Capture complete!"," Captured: 23 packets"," Duration: 120s"," Size: ~14.2 KB","```","","**`end cap`** — Stop capture early:","```","> end cap","✓ Capture stopped!"," Captured: 12 packets","```","","**`list cap`** — List saved captures:","```","> list cap","Capture Reports (2):"," 1. 23 pkts • 120s • ~14.2 KB (id: abc123)"," 2. 12 pkts • 34s • ~7.1 KB (id: def456)","```","","**`export cap [id]`** — Download by ID or index:","```","> export cap 1","✓ Downloading capture-abc123.json...","```"],searchText:"cap capture packet start end list export download diagnostic"},{name:"clear",description:"Clear the terminal screen.",body:["**Alias:** `cls`","```","> clear","```"],searchText:"clear cls screen"},{name:"clock",description:"Current system UTC time. Useful for NTP sync and packet timestamp correlation.",body:["```","> clock"," UTC Wed, 12 Feb 2026 00:01:34 GMT"," ISO 2026-02-12T00:01:34.000Z"," Unix 1770768094","```"],searchText:"clock time utc ntp unix iso timestamp"},{name:"convert",description:"Convert between hex and base64 encodings.",body:["**Usage:** `convert hex ` · `convert base64 `","```","> convert hex 48656C6C6F"," hex 48656C6C6F"," base64 SGVsbG8=","","> convert base64 SGVsbG8="," base64 SGVsbG8="," hex 48656C6C6F","```"],searchText:"convert hex base64 encoding decode"},{name:"get",description:"Read a configuration parameter.",body:[],interactive:"get",searchText:"get read config parameter name role lat lon radio freq tx bw sf cr txdelay mode duty flood advert"},{name:"help",description:"Show all commands, or detailed help for a specific command.",body:["**Alias:** `?` · `h`","```","> help Full command listing","> help ping Detailed help for ping","> ping help Same thing","```"],searchText:"help commands reference guide"},{name:"identities",description:"List all configured repeater and room server identities.",body:["**Alias:** `id` · `ids`","```","> identities","Identities (2)",""," 1. Local-Node repeater 0A1B2C3D"," 2. local-room room_server 0E5F6A7B","```"],searchText:"identities id ids repeater room server identity"},{name:"keys",description:"List configured transport encryption keys.",body:["```","> keys","Transport Keys (1)",""," main-transport flood: allow","```"],searchText:"keys transport encryption"},{name:"neighbors",description:"Direct RF neighbors with signal quality, RSSI, SNR, distance, and last-heard.",body:["**Alias:** `nb`","","**Sort qualifiers:** `sig` · `name` · `rssi` · `snr` · `dist` · `heard`","```","> neighbors","Direct Neighbors (4)","","+-------+-----------+-----------+--------+-------+--------+","| ▁▃▅▇█ | Node-1 | -87 dBm | 8.5 dB | 2.1km | 3m ago |","| ▁▃▅▇. | Relay-2 | -94 dBm | 5.2 dB | 4.8km | 1m ago |","| ▁▃▅.. | Node-3 | -108 dBm | 1.0 dB | 8.3km | 5m ago |","| ▁▃... | Node-4 | -118 dBm | -3 dB | 14km | 12m ago|","+-------+-----------+-----------+--------+-------+--------+","| SIG | NAME | RSSI | SNR | DIST | HEARD |","+-------+-----------+-----------+--------+-------+--------+","SF11/250kHz ant 3.5dBi nf -112dBm","```","","- **sig** — signal grade (weakest first)","- **name** — alphabetical","- **rssi** — RSSI (weakest first)","- **snr** — SNR (lowest first)","- **dist** — distance (closest first)","- **heard** — last seen (oldest first)"],searchText:"neighbors nb signal rssi snr distance sort direct rf"},{name:"packets",description:"Packet counters — received, transmitted, forwarded, dropped.",body:["```","> packets","Packet Stats 1321 total",""," Received 1284"," Transmitted 37"," Forwarded 891"," Dropped 14","```"],searchText:"packets received transmitted forwarded dropped counter"},{name:"ping",description:"Ping a neighbor by name or hex prefix. Shows RTT, signal quality, and path.",body:["**Usage:** `ping [timeout]`","```","> ping Node-1","▁▃▅▇█ Reply from Node-1",""," RTT 342ms"," RSSI -87 dBm"," SNR 8.5 dB"," Path direct"," Quality Excellent","```","","Custom timeout (default 30s):","```","> ping Node-4 60","```"],searchText:"ping rtt round trip time signal quality path neighbor"},{name:"restart",description:"Restart the pymc-repeater systemd service.",body:["**Alias:** `reboot`","```","> restart","Service is restarting (connection dropped).","Waiting for service... 8s","Service connected. (12s)","```","","The terminal polls automatically until the service comes back up."],searchText:"restart reboot service systemd"},{name:"rooms",description:"Room server statistics — message counts, active clients, sync status.",body:["```","> rooms","Rooms (1)",""," Local Room"," msgs 142 clients 3/5 sync running","```"],searchText:"rooms room server messages clients sync"},{name:"set",description:"Write a configuration parameter.",body:[],interactive:"set",searchText:"set write config parameter name lat lon freq tx bw sf cr txdelay mode duty log flood advert"},{name:"stats-core",description:"Engine vitals — uptime, duplicate cache, CPU, memory, temperature.",body:["```","> stats-core"," Core Stats",""," Uptime 2d 14h 32m"," Dup cache 128 entries TTL 900s",""," CPU 12.3% 4 cores"," Load 0.42 / 0.38 / 0.35"," Memory 412 MB / 664 MB 62%"," Temp 48.2°C","```"],searchText:"stats core engine vitals uptime cache cpu memory temperature"},{name:"stats-packets",description:"Firmware-compatible packet counters with rates and duplicate cache depth.",body:["```","> stats-packets"," Packet Counters",""," RX 1284 22.4/hr"," TX 37"," Forwarded 891 15.2/hr"," Dropped 14",""," Dup cache 128","```"],searchText:"stats packets firmware counter rate duplicate cache"},{name:"stats-radio",description:"Radio health — noise floor, airtime, duty cycle, and radio configuration.",body:["```","> stats-radio"," Radio Stats",""," Radio 906.875 MHz SF11 BW 250 kHz CR 4/5 22 dBm",""," Noise floor -112 dBm"," Airtime used 4.2s remaining: 55.8m"," Total airtime 1.2m"," Duty cycle 1.2%"," Utilization 0.8%","```"],searchText:"stats radio noise floor airtime duty cycle utilization"},{name:"status",description:"Quick summary of mode, neighbors, and uptime.",body:["**Alias:** `st`","```","> status","Local-Node repeater",""," Mode forward"," Neighbors 4 direct 12 total"," RX / TX 1284 / 37"," Uptime 2d 14h 32m","```"],searchText:"status st summary mode neighbors uptime"},{name:"top",description:"Live-updating system overview — CPU/memory gauges, mesh counters, processes.",body:["**Alias:** `htop`","","Refreshes every 3s. Press **Ctrl+C** to exit.","```","> top","Local-Node v1.0.0","──────────────────────────────────"," Sys 14d 3h 22m Svc 2d 14h 32m Load 0.42 0.38 0.35",""," CPU [████░░░░░░░░░░░░] 12.3% 4 cores"," Mem [██████████░░░░░░] 62.1% 412M/664M"," Dsk [███░░░░░░░░░░░░░] 18.4% 5.2G/28.7G"," cpu_thermal: 48.2°C",""," MESH"," Mode forward Nbrs 4/12 Noise -112dBm Air 1.2%"," RX 1284 TX 37 FWD 891 Drop 14"," RX/h 22 FWD/h 15",""," PROCS"," CPU MEM NAME"," 8.2 3.1 python3"," 2.1 1.4 cherrypy",""," 14:32:08 · Ctrl+C to exit","```","","Uses alternate screen buffer — scrollback is preserved."],searchText:"top htop live system overview cpu memory gauges mesh processes"},{name:"uptime",description:"How long the repeater service has been running.",body:["```","> uptime","Uptime 2d 14h 32m","```"],searchText:"uptime service running duration"},{name:"ver",description:"Version info for all three components.",body:["**Alias:** `version`","```","> ver"," pyMC_Repeater v1.0.0"," pyMC_Core v1.12.0"," pyMC_Console v1.0.0","```"],searchText:"ver version pymc repeater core console"}],ma=[{param:"name",category:"Identity",example:["> get name","name Local-Node"]},{param:"role",category:"Identity",example:["> get role","role repeater"]},{param:"lat",category:"Identity",example:["> get lat","lat 34.0522"],range:"-90 to 90"},{param:"lon",category:"Identity",example:["> get lon","lon -118.2437"],range:"-180 to 180"},{param:"public.key",category:"Identity",example:["> get public.key","public.key 0A1B2C3D4E5F..."]},{param:"radio",category:"Radio",example:["> get radio"," freq 906.875 MHz"," bw 250 kHz"," sf 11"," cr 4/5"," tx 22 dBm"]},{param:"freq",category:"Radio",example:["> get freq","freq 906.875 MHz"],range:"100–1000 MHz"},{param:"tx",category:"Radio",example:["> get tx","tx 22 dBm"],range:"2–22 dBm"},{param:"bw",category:"Radio",example:["> get bw","bw 250 kHz"],range:"7.8–500 kHz"},{param:"sf",category:"Radio",example:["> get sf","sf 11"],range:"5–12"},{param:"cr",category:"Radio",example:["> get cr","cr 4/5"],range:"5–8"},{param:"af",category:"Timing",example:["> get af","⚠ airtime_factor not yet exposed by pyMC_Repeater API."," Firmware range: 0-9. Tracked in CLI-Alignment.md."],range:"0–9 (pending)"},{param:"txdelay",category:"Timing",example:["> get txdelay","txdelay 1.0"],range:"0.0–5.0"},{param:"direct.txdelay",category:"Timing",example:["> get direct.txdelay","direct.txdelay 0.5"],range:"0.0–5.0"},{param:"rxdelay",category:"Timing",example:["> get rxdelay","rxdelay 0.0"],range:"≥ 0"},{param:"mode",category:"Repeater",example:["> get mode","mode forward"],range:"forward / monitor"},{param:"duty",category:"Repeater",example:["> get duty","duty on"],range:"on / off"},{param:"flood.max",category:"Repeater",example:["> get flood.max","flood.max 3"],range:"0–64"},{param:"advert.interval",category:"Repeater",example:["> get advert.interval","advert.interval 120m"],range:"0 (off) or 1–10080 min"},{param:"multi.acks",category:"Advanced",example:["> get multi.acks","multi.acks 0"],range:"0–255"},{param:"int.thresh",category:"Advanced",example:["> get int.thresh","int.thresh -120 dBm"],range:"-200 to 0 dBm"},{param:"agc.reset.interval",category:"Advanced",example:["> get agc.reset.interval","agc.reset.interval 0"],range:"≥ 0 (×4)"}],ha=[{param:"name",category:"Identity",example:["> set name Local-Node","OK - node_name set to Local-Node"],range:"text (no [ ] \\ / : , ? *)"},{param:"lat",category:"Identity",example:["> set lat 34.0522","OK - latitude set to 34.0522"],range:"-90 to 90"},{param:"lon",category:"Identity",example:["> set lon -118.2437","OK - longitude set to -118.2437"],range:"-180 to 180"},{param:"freq",category:"Radio",example:["> set freq 906.875","OK - frequency set to 906875000"],range:"100–1000 MHz"},{param:"tx",category:"Radio",example:["> set tx 22","OK - tx_power set to 22"],range:"2–22 dBm"},{param:"bw",category:"Radio",example:["> set bw 250","OK - bandwidth set to 250000"],range:"7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250, 500 kHz"},{param:"sf",category:"Radio",example:["> set sf 11","OK - spreading_factor set to 11"],range:"5–12"},{param:"cr",category:"Radio",example:["> set cr 5","OK - coding_rate set to 5"],range:"5–8"},{param:"af",category:"Timing",example:["> set af 2","⚠ airtime_factor not yet exposed by pyMC_Repeater API."," Firmware range: 0-9. Needs backend support."],range:"0–9 (pending)"},{param:"txdelay",category:"Timing",example:["> set txdelay 1.0","OK - tx_delay_factor set to 1"],range:"0.0–5.0"},{param:"direct.txdelay",category:"Timing",example:["> set direct.txdelay 0.5","OK - direct_tx_delay_factor set to 0.5"],range:"0.0–5.0"},{param:"rxdelay",category:"Timing",example:["> set rxdelay 0","OK - rx_delay_base set to 0"],range:"≥ 0"},{param:"mode",category:"Repeater",example:["> set mode forward","OK - Mode set to forward"],range:"forward / monitor"},{param:"flood.max",category:"Repeater",example:["> set flood.max 3","OK - max_flood_hops set to 3"],range:"0–64"},{param:"advert.interval",category:"Repeater",example:["> set advert.interval 120","OK - Local advert interval set to 120m"],range:"0 (off) or 1–10080 min"},{param:"duty",category:"Repeater",example:["> set duty on","OK - Duty cycle enabled"],range:"on / off"},{param:"log",category:"Repeater",example:["> set log info","OK - Log level set to INFO"],range:"debug, info, warning, error"},{param:"multi.acks",category:"Advanced",example:["> set multi.acks 0","OK - multi_acks set to 0"],range:"0–255"},{param:"int.thresh",category:"Advanced",example:["> set int.thresh -120","OK - interference_threshold set to -120"],range:"-200 to 0 dBm"},{param:"agc.reset.interval",category:"Advanced",example:["> set agc.reset.interval 8","OK - AGC reset interval set to 8"],range:"≥ 0 (rounded to ×4)"},{param:"prv.key",category:"Advanced",example:["> set prv.key <128-hex>","To set this key, run on the Pi:",""," sudo ./convert_firmware_key.sh ","","Then restart: sudo systemctl restart pymc-repeater"],range:"128-char hex (SSH only)"}];function ga({mode:e}){const t="get"===e?ma:ha,[s,n]=a.useState(0),o=t[s],i=a.useMemo(()=>{const e=new Map;for(const r of t){const t=e.get(r.category)||[];t.push(r),e.set(r.category,t)}return Array.from(e.entries())},[t]);return r.jsxs("div",{className:"flex flex-col gap-2",children:[r.jsx("div",{className:"flex flex-col gap-1.5",children:i.map(([e,a])=>r.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[r.jsx("span",{className:"text-xs text-fg-muted w-16 shrink-0 text-right pr-1",children:e}),a.map(e=>{const a=t.indexOf(e),o=a===s;return r.jsx("button",{onClick:()=>n(a),className:c("px-1.5 py-0.5 type-data-xs radius-badge transition-colors cursor-pointer",o?"bg-sys-blue text-fg-invert font-semibold":"bg-elevated text-fg-secondary hover:bg-elevated/80 hover:text-sys-blue"),children:e.param},e.param)})]},e))}),r.jsx("pre",{className:"px-3 py-2.5 radius-inner bg-body text-fg-secondary type-code overflow-x-auto border border-edge-subtle",children:o.example.map((e,t)=>r.jsx("div",{children:e||" "},t))}),o.range&&r.jsxs("p",{className:"text-xs text-fg-muted",children:[r.jsx("span",{className:"text-fg-secondary font-medium",children:o.param})," — ",o.range]})]})}function fa(e,t){const a=e.split(/(\*\*[^*]+\*\*)/g);return r.jsx("span",{children:a.map((e,t)=>e.startsWith("**")&&e.endsWith("**")?r.jsx("strong",{className:"text-fg-primary font-semibold",children:e.slice(2,-2)},t):e.split(/(`[^`]+`)/g).map((e,a)=>e.startsWith("`")&&e.endsWith("`")?r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue type-data-xs",children:e.slice(1,-1)},`${t}-${a}`):r.jsx("span",{children:e},`${t}-${a}`)))},t)}function ya({lines:e}){const t=[];let a=0;for(;ar.jsx("div",{children:e||" "},t))},t.length));continue}s.trim()?s.startsWith("- ")?(t.push(r.jsxs("div",{className:"flex gap-2 text-sm text-fg-secondary pl-2 py-0.5",children:[r.jsx("span",{className:"text-fg-muted shrink-0",children:"•"}),r.jsx("span",{children:fa(s.slice(2),0)})]},t.length)),a++):(t.push(r.jsx("p",{className:"text-sm text-fg-secondary py-0.5",children:fa(s,0)},t.length)),a++):(t.push(r.jsx("div",{className:"h-1.5"},t.length)),a++)}return r.jsx(r.Fragment,{children:t})}function xa({isOpen:e,onClose:t,onUseCommand:i}){const[l,d]=a.useState(""),u=a.useMemo(()=>{if(!l.trim())return pa;const e=l.toLowerCase();return pa.filter(t=>t.name.includes(e)||t.searchText.includes(e)||t.description.toLowerCase().includes(e))},[l]),p=l.trim().length>0;return r.jsxs(I,{open:e,onClose:t,size:"3xl",motionPlus:!0,className:"sm:min-w-[540px] md:min-w-[680px]",children:[r.jsx(F,{icon:r.jsx(de,{size:20}),title:"Terminal Command Guide",onClose:t}),r.jsxs(L,{className:"flex flex-col gap-0 !px-0 !py-0",children:[r.jsx("div",{className:"sticky top-0 z-10 px-5 py-3 border-b border-edge-subtle bg-surface/95 backdrop-blur-sm",children:r.jsxs("div",{className:"relative",children:[r.jsx(ue,{size:14,className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-fg-muted"}),r.jsx("input",{type:"text",value:l,onChange:e=>d(e.target.value),placeholder:"Search commands...",className:"w-full pl-8 pr-3 py-1.5 text-sm bg-elevated border border-edge-subtle radius-inner text-fg-primary placeholder:text-fg-muted focus:outline-none focus:ring-1 focus:ring-sys-blue/50",autoFocus:!0})]})}),r.jsxs("div",{className:"overflow-y-auto px-5 py-3 h-[420px] sm:h-[520px] md:h-[600px]",children:[r.jsx(he,{mode:"popLayout",children:0===u.length?r.jsxs(ge.div,{initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:O.normal,ease:D.easeOut},className:"flex flex-col items-center gap-2 py-10 text-fg-muted",children:[r.jsx(ue,{className:"w-6 h-6 opacity-40"}),r.jsxs("p",{className:"text-sm",children:['No commands match "',l,'"']})]},"empty"):r.jsx(ge.div,{initial:!1,className:"flex flex-col gap-1",children:r.jsx(he,{initial:!1,children:u.map(e=>r.jsx(ge.div,{layout:"position",initial:{opacity:0,y:-4},animate:{opacity:1,y:0},exit:{opacity:0,y:-4},transition:P.fade,className:"min-w-0",children:r.jsx(s,{children:({open:t})=>r.jsxs("div",{className:c("radius-inner border transition-colors",t?"border-edge-subtle bg-elevated/50":"border-transparent hover:bg-elevated/30"),children:[r.jsxs("div",{className:"flex items-center w-full min-w-0",children:[r.jsxs(n,{className:"flex items-center gap-3 flex-1 min-w-0 px-3 py-2 text-left cursor-pointer",children:[r.jsx(pe,{size:14,className:c("shrink-0 text-fg-muted transition-transform duration-150",t&&"rotate-90")}),r.jsx("code",{className:"text-sm font-semibold text-sys-blue font-mono shrink-0",children:e.name}),r.jsx("span",{className:"text-xs text-fg-muted truncate min-w-0",children:e.description})]}),i&&r.jsx("button",{onClick:t=>{t.stopPropagation(),i(e.name)},className:"shrink-0 mr-2 px-2 py-0.5 text-xs font-semibold uppercase tracking-wider radius-badge bg-elevated text-fg-muted hover:text-sys-blue hover:bg-elevated/80 transition-colors cursor-pointer",title:`Use "${e.name}" in terminal`,children:"use"})]}),r.jsx(o,{className:"px-3 pb-3 pt-0 pl-9",children:e.interactive?r.jsx(ga,{mode:e.interactive}):r.jsx(ya,{lines:e.body})})]})})},e.name))})},"list")}),r.jsx(he,{children:!p&&r.jsxs(ge.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},exit:{opacity:0,y:6},transition:{duration:O.normal,ease:D.easeOut},className:"mt-4 px-3 py-3 radius-inner border border-edge-subtle bg-elevated/30",children:[r.jsx("p",{className:"text-xs font-semibold text-fg-muted mb-2",children:"Tips"}),r.jsxs("div",{className:"flex flex-col gap-1 text-xs text-fg-muted",children:[r.jsxs("p",{children:["Type ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:" help"})," in the terminal for detailed usage."]}),r.jsxs("p",{children:["Most commands have shorter aliases (e.g. ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"st"}),", ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"nb"}),", ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"id"}),")."]}),r.jsxs("p",{children:["Signal bars ",r.jsx("span",{className:"font-mono",children:"▁▃▅▇█"})," are colored by link quality grade based on RSSI, SNR, and radio config."]}),r.jsx("p",{children:"Captures are stored in browser session only — export before closing the tab."})]})]})})]})]})]})}function va({onUseCommand:e}){const[t,s]=a.useState(!1),n=e?t=>{s(!1),e(t)}:void 0;return r.jsxs(r.Fragment,{children:[r.jsx(ne,{icon:r.jsx(de,{size:17,className:"translate-y-px"}),onClick:()=>s(!0),title:"CLI Command Guide"}),r.jsx(xa,{isOpen:t,onClose:()=>s(!1),onUseCommand:n})]})}const $a=function(){const e=new fe,t=new ft(e);return e.register(t,new yt,new vt,new Zr,new ea,new $t,new bt,new kt,new ta,new aa,new na,new qt,new er,new ur,new tr,new rr,new pr,new Cr,new Sr,new jr,new Nr,new Tr,new Rr,new zr,new Vr,new Qr,new ca),e}(),ba=$a.all().flatMap(e=>[{cmd:e.name,desc:e.description,params:e.params,required:!!e.params},...e.aliases.filter(e=>e.includes(" ")).map(t=>({cmd:t,desc:e.description,params:e.params,required:!!e.params}))]);ba.push({cmd:"start cap",desc:"Start packet capture",params:"[seconds]",required:!0},{cmd:"end cap",desc:"Stop capture"},{cmd:"list cap",desc:"List captures"},{cmd:"export cap",desc:"Download capture",params:"[id]",required:!0});const wa=["sig","name","rssi","snr","dist","heard"],_a={get:["name","role","lat","lon","radio","freq","tx","bw","sf","cr","af","txdelay","direct.txdelay","rxdelay","mode","repeat","flood.max","flood.advert.interval","advert.interval","duty","duty.max","multi.acks","int.thresh","agc.reset.interval","public.key","prv.key"],set:["name","lat","lon","freq","tx","bw","sf","cr","af","txdelay","direct.txdelay","rxdelay","mode","repeat","flood.max","flood.advert.interval","advert.interval","duty","log","multi.acks","int.thresh","agc.reset.interval","prv.key"],convert:["hex","base64"],neighbors:wa,nb:wa,"get neighbors":wa,"get neighbor":wa,"set mode":["forward","monitor"],"set duty":["on","off"],"set repeat":["on","off"],"set tx":["10","14","17","20","22"],"set sf":["7","8","9","10","11","12"],"set bw":["125","250","500"],"set cr":["5","6","7","8"],"set af":["0.5","1.0","1.5","2.0"],"set txdelay":["0.5","0.7","1.0","1.5"],"set direct.txdelay":["0.3","0.5","0.7"],"set log":["debug","info","warning","error"],"start cap":["30","60","120","300"]},ka=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "];function Ca(){return/Android|iPhone|iPad|iPod/i.test(navigator.userAgent)||window.innerWidth<640}function Sa(){const e=U(),{addCommand:t}=la(),s=a.useRef(null),n=a.useRef(null),o=a.useRef(null),i=a.useRef(null),p=a.useRef(""),m=a.useRef(-1),g=a.useRef(""),f=a.useRef(!1),y=a.useRef(null),x=a.useRef(!1),v=a.useRef(!1),$=a.useRef(!1),b=a.useRef([]),w=a.useRef(()=>{}),_=H(),[k,C]=a.useState("C0dE"),[S,j]=a.useState(!1),N=a.useRef(null),T="C0dE",R=a.useCallback(e=>{N.current&&(clearInterval(N.current),N.current=null);const t=T.padEnd(7),r=t+" "+e+" "+t;let a=0;const s=r.length-7;j(!0),C(r.slice(0,7)),N.current=setInterval(()=>{if(a++,a>s)return clearInterval(N.current),N.current=null,j(!1),void C(T);C(r.slice(a,a+7))},280)},[]);a.useEffect(()=>{const e=function(e){const t=t=>e(t.detail);return Wr.addEventListener(Gr,t),()=>Wr.removeEventListener(Gr,t)}(R),t=setInterval(()=>{Math.random()<.02&&R(Kr())},45e3);return()=>{e(),clearInterval(t),N.current&&clearInterval(N.current)}},[R]);const[M,E]=a.useState(!1),A=a.useRef(null);a.useEffect(()=>{const e=(t=()=>{A.current&&clearTimeout(A.current),E(!0),A.current=setTimeout(()=>E(!1),5e3)},Yr.addEventListener(Jr,t),()=>Yr.removeEventListener(Jr,t));var t;return()=>{e(),A.current&&clearTimeout(A.current)}},[]);const[I,F]=a.useState({show:!1,options:[],selectedIndex:0,input:""}),L=a.useRef([]),B=a.useRef(0);a.useEffect(()=>{(null==e?void 0:e.neighbors)&&(b.current=Object.values(e.neighbors).map(e=>e.node_name||e.name).filter(e=>!!e).sort())},[null==e?void 0:e.neighbors]);const D=a.useCallback(()=>{var e;null==(e=n.current)||e.write(`${z()||"user"}@pyMC${ve}: $${ve} `)},[]),O=a.useCallback(()=>{const e=n.current;e&&(e.write(Ke),D(),e.write(p.current))},[D]),P=a.useCallback(e=>{const t=function(e,t){const r=e.toLowerCase(),a=r.trim();if(!a)return[];const s=r.length>a.length&&r.endsWith(" ");if(!a.includes(" ")&&!s)return ba.filter(e=>e.cmd.toLowerCase().startsWith(a));const n=s?a:a.substring(0,a.lastIndexOf(" ")),o=s?"":a.substring(a.lastIndexOf(" ")+1);if("ping"===n&&t.length>0)return t.filter(e=>e.toLowerCase().startsWith(o)).slice(0,10).map(e=>({cmd:`ping ${e}`,desc:`→ ${e}`}));const i=_a[n];if(i){const e=i.filter(e=>e.toLowerCase().startsWith(o)).map(e=>({cmd:`${n} ${e}`,desc:`→ ${e}`}));if(!s&&o){const t=new Set(e.map(e=>e.cmd));for(const r of ba){const s=r.cmd.toLowerCase();s.startsWith(a)&&!t.has(s)&&(e.push(r),t.add(s))}}return e}return ba.filter(e=>e.cmd.toLowerCase().startsWith(a))}(e,b.current);L.current=t,B.current=0;const r=t.length>0&&e.trim().length>0;F({show:r,options:t,selectedIndex:0,input:e.trim()})},[]),K=a.useCallback(()=>{L.current=[],B.current=0,F({show:!1,options:[],selectedIndex:0,input:""})},[]),W=a.useCallback(e=>{var t;const r=L.current[e];r&&(p.current=r.required?r.cmd+" ":r.cmd,O(),r.required?P(p.current):K(),null==(t=n.current)||t.focus())},[O,P,K]),G=a.useCallback(async e=>{const r=n.current;if(!r)return;const a=e.trim();if(!a)return void D();f.current=!0;const s=new AbortController;y.current=s,t(a),m.current=-1;let o=0;const i={get cols(){return r.cols},get rows(){return r.rows},write(e,t="default"){const a=("default"===t?e:Me(e,t)).split("\n");for(const s of a)r.writeln(s);return o=Je(a,r.cols),String(o)},update(e,t,a){if($.current)r.write("");else if(o>0)for(let n=0;n{const t=n.current;if(!t)return;if(!v.current)return;if(f.current){for(let r=0;rrequestAnimationFrame(()=>{var t;return null==(t=document.querySelector(`[data-ac-index="${e}"]`))?void 0:t.scrollIntoView({block:"nearest"})});for(let s=0;s0){const e=L.current[B.current];e&&(p.current=e.cmd,O())}K();const e=p.current;p.current="",t.writeln(""),G(e);continue}if(127!==n&&8!==n)if(3!==n)if(12!==n)if(9!==n)if(27!==n)n>=32&&(p.current+=e[s],t.write(e[s]),m.current=-1,P(p.current));else{if(91===e.charCodeAt(s+1)){const t=e.charCodeAt(s+2);if(s+=2,65===t){if(L.current.length>0){const e=Math.max(B.current-1,0);B.current=e,F(t=>({...t,selectedIndex:e})),a(e)}else r.length>0&&(-1===m.current&&(g.current=p.current),m.current0){const e=Math.min(B.current+1,L.current.length-1);B.current=e,F(t=>({...t,selectedIndex:e})),a(e)}else m.current>0?(m.current--,p.current=r[r.length-1-m.current]||"",O()):0===m.current&&(m.current=-1,p.current=g.current,O());continue}if(67===t||68===t)continue;continue}L.current.length>0&&K()}else L.current.length>0&&W(B.current);else t.clear(),K(),O();else p.current="",K(),t.writeln("^C"),D();else p.current.length>0&&(p.current=p.current.slice(0,-1),t.write("\b \b"),P(p.current))}},[K,P,W,D,O,G]);a.useEffect(()=>{w.current=X},[X]);const V=a.useCallback(async()=>{const e=n.current;if(!e||x.current)return;x.current=!0;const t="",r="",a=ka.length,s=te-1;try{const t=Q(ka,0);for(const r of t)e.writeln(r);await new Promise(t=>{let r=0;const n=setInterval(()=>{if(r>=s)return clearInterval(n),void t();r++,e.write(`[${a}F`);const o=Q(ka,r);for(const t of o)e.write(`${t}\n`)},Z)})}finally{ee()}e.writeln(""),e.write(Fe("● Initializing terminal...")),await new Promise(e=>setTimeout(e,300)),e.write(Ke),e.writeln(`${t}✓ Initializing terminal...${r}`),e.write(Fe("● Connecting to repeater...")),await new Promise(e=>setTimeout(e,500)),e.write(Ke),"connected"===q.getState().health?e.writeln(`${t}✓ Connected to repeater${r}`):e.writeln(`${Ce}~ Connection status unknown${ve}`),e.writeln(Fe("Ready. Type 'help' for commands.")),e.writeln(""),D(),v.current=!0},[D]);a.useEffect(()=>{const e=s.current;if(!e)return;const t=Ca()?12:13,r=new l({theme:Ze(),fontFamily:'"JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',fontSize:t,lineHeight:Ca()?1.1:.65,cursorBlink:!1,cursorStyle:"underline",scrollback:1e4,convertEol:!0,allowTransparency:!0,rightClickSelectsWord:!1}),a=new d;r.loadAddon(a),r.loadAddon(new u),r.open(e),a.fit(),n.current=r,o.current=a;const i=r.onData(e=>w.current(e)),c=function(e){return h.subscribe(()=>{e.options.theme=Ze()})}(r),p=new ResizeObserver(()=>{requestAnimationFrame(()=>a.fit())});return p.observe(e),V(),Ca()||r.focus(),()=>{var e;null==(e=y.current)||e.abort(),$.current&&(r.write(Xe+Ge),$.current=!1),i.dispose(),c(),p.disconnect(),r.dispose(),n.current=null,o.current=null}},[]);const Y=a.useCallback(e=>{const t=e.target.value;t.length>0&&(X(t),e.target.value="")},[X]),J=a.useCallback(e=>{"Enter"===e.key?(e.preventDefault(),X("\r")):"Backspace"===e.key?(e.preventDefault(),X("")):"ArrowUp"===e.key?(e.preventDefault(),X("")):"ArrowDown"===e.key&&(e.preventDefault(),X(""))},[X]),ne=a.useCallback(()=>{var e,t;Ca()?null==(e=i.current)||e.focus():null==(t=n.current)||t.focus()},[]);a.useEffect(()=>{if(!Ca())return;const e=()=>{var e;const t=null==(e=s.current)?void 0:e.querySelector(".xterm-viewport");t&&(t.scrollTop=t.scrollHeight),requestAnimationFrame(()=>{var e;return null==(e=o.current)?void 0:e.fit()})},t=window.visualViewport;if(t){const r=()=>{t.height<.75*window.innerHeight&&e()};return t.addEventListener("resize",r),()=>t.removeEventListener("resize",r)}const r=i.current;if(r){const t=()=>setTimeout(e,300);return r.addEventListener("focus",t),()=>r.removeEventListener("focus",t)}},[]);const ie=a.useCallback(e=>{p.current=e+" ",O(),P(p.current),setTimeout(()=>{var e;null==(e=s.current)||e.click()},400)},[O,P]);return r.jsx(re,{children:r.jsx(ae,{children:r.jsxs("div",{className:"terminal-card flex flex-col gap-1 sm:gap-1.5",children:[r.jsxs("div",{className:"card-terminal-header flex-wrap",children:[r.jsx("span",{className:"seven-seg-panel",children:r.jsx(oe,{text:k,minChars:7,size:24,noCycle:S})}),r.jsx("div",{className:"header-well self-stretch flex-col sm:order-first",children:r.jsxs("div",{className:"indicator-key"+("connected"===_?" indicator-key--active":"degraded"===_?" indicator-key--sending":""),children:[r.jsx("span",{className:"indicator-key__label",children:"ONLINE"}),r.jsx("span",{className:"indicator-key__led"})]})}),r.jsx("div",{className:"card-terminal-ridge flex-1 min-w-4 sm:hidden"}),r.jsxs("div",{className:"header-well flex items-center gap-1 sm:order-last",children:[r.jsx(va,{onUseCommand:ie}),r.jsx(ua,{})]}),r.jsx("div",{className:"card-terminal-ridge flex-1 min-w-8 hidden sm:block"})]}),r.jsx(se,{noPadding:!0,className:"flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",onClick:ne,children:r.jsxs("div",{className:"card-terminal-well flex-1 min-h-0 flex flex-col overflow-hidden",children:[r.jsxs("div",{className:"flex-1 min-h-0 terminal-gutter relative",children:[r.jsx("div",{ref:s,className:"h-full w-full"}),M&&r.jsxs("div",{className:"absolute inset-0 z-10 flex items-center justify-center",onClick:()=>E(!1),children:[r.jsx("div",{className:"absolute inset-0 animate-[partytime-bg_5s_ease-out_forwards]",style:{background:"rgba(0,0,0,0.82)"}}),r.jsxs("div",{className:"relative z-10 animate-[partytime-crt_5s_ease-out_forwards] partytime-glow",children:[r.jsx("img",{src:"/assets/partytime.gif",alt:"No way.",className:"max-h-[60vh] max-w-[70vw] object-contain rounded"}),r.jsx("div",{className:"absolute inset-0 pointer-events-none rounded partytime-scanlines"})]})]})]}),I.show&&I.options.length>0&&r.jsxs("div",{className:"flex-shrink-0 overflow-hidden terminal-completions",style:{borderTop:"1px solid var(--terminal-border)",background:"var(--terminal-bg-input)"},children:[r.jsx("div",{className:"overflow-y-auto",style:{maxHeight:"176px"},children:I.options.map((e,t)=>{const a=t===I.selectedIndex,s=I.input.length;return r.jsxs("div",{"data-ac-index":t,onClick:()=>W(t),className:c("terminal-ac-option",a?"text-sys-blue":"text-fg-primary"),style:{background:a?"var(--terminal-autocomplete-hover)":void 0},onMouseEnter:e=>{a||(e.currentTarget.style.background="var(--terminal-autocomplete-hover)")},onMouseLeave:e=>{a||(e.currentTarget.style.background="")},children:[r.jsx("span",{className:"terminal-ac-option__indicator",children:a?"▸":""}),r.jsxs("span",{className:"terminal-ac-option__cmd",children:[r.jsx("span",{className:"font-semibold text-sys-blue",children:e.cmd.substring(0,s)}),e.cmd.substring(s)]}),r.jsx("span",{className:"terminal-ac-option__desc",children:e.desc})]},e.cmd)})}),r.jsxs("div",{className:"terminal-ac-hints",children:[r.jsx("span",{className:"hidden sm:inline",children:"Tab · ↑↓ · Esc"}),r.jsx("span",{className:"sm:hidden",children:"Tap to select"}),r.jsxs("span",{children:[I.options.length," match",1!==I.options.length?"es":""]})]})]}),r.jsxs("div",{className:"terminal-mobile-input-bar sm:hidden",children:[r.jsx("input",{ref:i,type:"text",className:"terminal-mobile-input",onChange:Y,onKeyDown:J,autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,enterKeyHint:"send","aria-label":"Terminal input",placeholder:"Type command..."}),r.jsx("button",{type:"button",className:"terminal-send-btn",onClick:()=>X("\r"),"aria-label":"Run command",children:r.jsx(me,{})})]}),r.jsxs("div",{className:"terminal-status-bar",children:[r.jsx("span",{className:"hidden sm:inline",children:"↑↓ History · Tab · Esc"}),r.jsx("span",{className:"sm:hidden",children:"Tap input to type"}),(null==e?void 0:e.version)&&r.jsxs("span",{children:["pyMC v",e.version]})]})]})})]})})})}export{Sa as default}; +var e=Object.defineProperty,t=(t,r,a)=>((t,r,a)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[r]=a)(t,"symbol"!=typeof r?r+"":r,a);import{j as r,r as a,X as s,x as n,d as o}from"./vendor-react-alRNW2nb.js";import{a as i,c}from"./vendor-core-FtpmsTnh.js";import{D as l,o as d,L as u}from"./xterm-WPd9ZkSt.js";import{Z as p,bb as m,bu as h,bv as g,bw as f,bx as y,aG as x,k as v,by as $,bz as b,bA as w,b1 as _,ae as k,bB as C,a4 as S,a3 as j,av as N,bC as T,bD as R,bE as M,bF as E,bm as A,Y as I,bG as F,_ as L,B,bH as D,bI as O,b0 as P,p as U,bJ as H,bK as z,bL as q}from"./index-CkRTgHHA.js";import{h as K,c as W}from"./geo-utils-DJn8DnxF.js";import{a as G}from"./ping-DPgnsJJf.js";import{P as X,c as V}from"./payload-decoders-_TRhCJrs.js";import{g as Y,r as J}from"./system-OS35JnnX.js";import{g as Q,B as Z,r as ee,T as te}from"./ascii-burst-CXC_pYgi.js";import{P as re,B as ae,C as se}from"./PageLayout-BWMUVZgC.js";import{K as ne,S as oe}from"./KeycapButton-DdWNfiky.js";import{aR as ie,a$ as ce,b0 as le,b1 as de,au as ue,D as pe,b2 as me}from"./vendor-icons-TO0PZKGR.js";import{A as he,m as ge}from"./vendor-motion-DNp0Qg4F.js";import"./vendor-virt-BytWoLhu.js";import"./cosmograph-DqYT4sUA.js";import"./vendor-charts-C916_-gs.js";import"./vendor-fonts-CRZaZSFf.js";import"./keycap-sfx-Bpx9zhkt.js";class fe{constructor(){t(this,"commands",[])}register(...e){this.commands.push(...e)}find(e){let t;for(const r of this.commands)r.matches(e)&&(!t||r.name.length>t.name.length)&&(t=r);return t}all(){return this.commands}}class ye{constructor(){t(this,"aliases",[]),t(this,"params")}matches(e){const t=e.toLowerCase().trim(),r=e=>t===e||t.startsWith(e+" ");return r(this.name)||this.aliases.some(r)}argsAfterName(e){const t=e.toLowerCase().trim(),r=[this.name,...this.aliases].sort((e,t)=>t.length-e.length);for(const a of r)if(t.startsWith(a))return e.trim().slice(a.length).trim();return e.trim()}}const xe="[",ve=`${xe}0m`,$e=`${xe}1m`,be=`${xe}2m`,we=`${xe}3m`,_e=`${xe}32m`,ke=`${xe}31m`,Ce=`${xe}33m`,Se=`${xe}36m`,je=`${xe}34m`,Ne=`${xe}90m`,Te=`${xe}92m`,Re=`${xe}96m`;function Me(e,t){switch(t){case"success":return`${_e}${e}${ve}`;case"error":return`${ke}${e}${ve}`;case"warning":return`${Ce}${e}${ve}`;case"info":return`${Se}${e}${ve}`;case"value":return`${je}${e}${ve}`;case"system":return`${Ne}${e}${ve}`;default:return e}}function Ee(e){return`${$e}${e}${ve}`}function Ae(e){return`${be}${e}${ve}`}function Ie(e){return`${je}${e}${ve}`}function Fe(e){return`${Ne}${e}${ve}`}function Le(e,t){return`${Ne}${e}: ${ve}${je}${$e}${t}${ve}`}function Be(e,t,r=22){const a=e.split(" "),s=a[0];let n=Se;return"get"===s?n=_e:"set"===s&&(n=Ce),` ${a.length>1?`${n}${$e}${s}${ve} ${je}${a.slice(1).join(" ")}${ve}`:`${n}${$e}${e}${ve}`}${" ".repeat(Math.max(1,r-e.length))}${Ne}${t}${ve}`}function De(e){return`${$e}${je}${e}${ve}`}function Oe(e){return`${Ne}${we}${e}${ve}`}function Pe(e){return`${ke}${$e}●${ve} ${Ne}${e}${ve}`}function Ue(e){const t=e<1e3?`${e.toFixed(0)}ms`:`${(e/1e3).toFixed(1)}s`;return`${function(e){return e<1500?Te:e<4e3?_e:e<8e3?Ce:e<15e3?ke:`${ke}${$e}`}(e)}${t}${ve}`}function He(e){switch(e){case"excellent":return Re;case"good":return _e;case"fair":return Ce;case"poor":return ke;case"critical":return`${ke}${$e}`;default:return Ne}}function ze(e,t){return`${He(t)}${e}${ve}`}function qe(e){return e.replace(/[\p{Emoji_Presentation}\p{Extended_Pictographic}\uFE0F\u200D]/gu,"").trim()}const Ke="\r";function We(e=1){return`[${e}A`}const Ge="[?1049l",Xe="[?25h";function Ve(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function Ye(e){return Ve(e).length}function Je(e,t){let r=0;for(const a of e){const e=Ve(a).length;r+=0===e?1:Math.ceil(e/t)}return r}function Qe(e,t){const r=function(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}(e);return r||t}function Ze(){const e="light"===document.documentElement.dataset.mode,t=Qe("--terminal-bg","#0d0d0d"),r=Qe("--sys-blue",m.blue);if(e){const e="#EFF0F1";return{background:e,foreground:"#111314",cursor:m.blue,cursorAccent:e,selectionBackground:`${m.blue}30`,selectionForeground:"#111314",black:"#111314",red:m.red,green:m.green,yellow:m.amber,blue:m.blue,magenta:m.purple,cyan:m.cyan,white:e,brightBlack:p[500],brightRed:m.red,brightGreen:m.green,brightYellow:m.orange,brightBlue:m.indigo,brightMagenta:m.pink,brightCyan:m.teal,brightWhite:p[600]}}const a=Qe("--text-primary","#e0e0e0"),s=r+"40",n=Qe("--sys-red",m.red),o=Qe("--sys-green",m.green),i=Qe("--sys-purple",m.purple),c=Qe("--sys-blue",m.blue),l=Qe("--sys-cyan",m.cyan),d=Qe("--text-muted",p[500]),u=Qe("--text-secondary",p[400]);return{background:t,foreground:a,cursor:r,cursorAccent:t,selectionBackground:s,selectionForeground:a,black:Qe("--bg-surface",p[900]),red:n,green:o,yellow:i,blue:c,magenta:i,cyan:l,white:a,brightBlack:d,brightRed:n,brightGreen:"#4ADE80",brightYellow:i,brightBlue:c,brightMagenta:i,brightCyan:l,brightWhite:u}}const et="[",tt=`${et}0m`,rt=`${et}1m`,at=`${et}2m`,st=`${et}34m`,nt=`${et}90m`,ot=" ",it=[{label:"INFORMATION",entries:[{cmd:"status",desc:"Repeater status summary",alias:"st"},{cmd:"top",desc:"Live system overview (Ctrl+C to exit)",alias:"htop"},{cmd:"ver",desc:"Version info",alias:"version"},{cmd:"clock",desc:"System UTC time"},{cmd:"uptime",desc:"System uptime"},{cmd:"board",desc:"Board / platform info"},{cmd:"packets",desc:"Packet statistics"},{cmd:"stats-packets",desc:"Packet counters (firmware compat)"},{cmd:"stats-radio",desc:"Radio health stats (firmware compat)"},{cmd:"stats-core",desc:"Engine vitals (firmware compat)"}]},{label:"NETWORK",entries:[{cmd:"neighbors [sort]",desc:"Direct RF neighbors",alias:"nb",sub:"sig · name · rssi · snr · dist · heard"},{cmd:"ping {name}",desc:"Ping neighbor (name or 0xXX)"},{cmd:"identities",desc:"List configured identities",alias:"id ids"},{cmd:"keys",desc:"Transport keys"},{cmd:"acl",desc:"ACL statistics"},{cmd:"rooms",desc:"Room statistics"}]},{label:"RADIO",entries:[{cmd:"get {param}",desc:"Read parameter"},{cmd:"set {param} {value}",desc:"Write parameter"},{cmd:"advert",desc:"Send advertisement"}]},{label:"SYSTEM",entries:[{cmd:"restart",desc:"Restart service",alias:"reboot"},{cmd:"start cap [seconds]",desc:"Start packet capture"},{cmd:"end cap",desc:"Stop capture"},{cmd:"list cap",desc:"List captures"},{cmd:"export cap [id]",desc:"Download capture"}]},{label:"TOOLS",entries:[{cmd:"convert hex {value}",desc:"Hex → base64"},{cmd:"convert base64 {value}",desc:"Base64 → hex"},{cmd:"clear",desc:"Clear terminal",alias:"cls"},{cmd:"help [command]",desc:"Show this help",alias:"? h"}]}],ct=[{cat:"Identity",params:["name","role","lat","lon","public.key"]},{cat:"Radio",params:["radio","freq","tx","bw","sf","cr"]},{cat:"Timing",params:["txdelay","direct.txdelay","rxdelay"]},{cat:"Repeater",params:["mode","duty","repeat","flood.max","advert.interval"]},{cat:"Advanced",params:["multi.acks","int.thresh","agc.reset.interval"]},{cat:"set only",params:["log","prv.key"]}];function lt(e){return`${nt}${"─".repeat(e)}${tt}`}function dt(e){const t=Math.max(3,e-12-8-6);return` ${st}${rt}pymc console${tt} ${lt(t)} ${nt}terminal${tt}`}function ut(e){return` ${nt}${e}${tt}`}function pt(e,t){const r=[],a=e.alias?` ${at}${e.alias}${tt}`:"";return 4+Math.max(e.cmd.length,24)+e.desc.length+(e.alias?2+e.alias.length:0)<=t?r.push(" "+Be(e.cmd,e.desc,24)+a):(r.push(" "+Be(e.cmd,"",24)),r.push(ot+Fe(e.desc)+a)),e.sub&&r.push(`${ot}${Ae("└ "+e.sub)}`),r}function mt(e){return e.split(" · ").map(e=>`${st}${e}${tt}`).join(`${nt} · ${tt}`)}function ht(e,t){const r=[];let a=[],s=0;for(const n of e){const e=a.length>0?3+n.length:n.length;s+e>t&&a.length>0?(r.push(a),a=[n],s=n.length):(a.push(n),s+=e)}return a.length>0&&r.push(a),r}function gt(e){const t=["",ut("GET/SET QUALIFIERS")],r=Math.max(20,e-4-13);for(const a of ct){const e=`${nt}${a.cat.padEnd(13)}${tt}`,s=ht(a.params,r),n=" ".repeat(17);t.push(` ${e}${mt(s[0].join(" · "))}`);for(let r=1;r help for detailed usage")}`]}(r)),e.write(s.join("\n"))}}class yt extends ye{constructor(){super(...arguments),t(this,"name","clear"),t(this,"description","Clear terminal screen"),t(this,"aliases",["cls"])}execute({output:e,rawInput:t}){"help"!==this.argsAfterName(t).toLowerCase().trim()?e.clear():e.write([De("clear"),` ${Fe("Clear all terminal output.")}`,"",Be("clear","clear the screen"),"",De("Aliases"),` ${Fe("cls")}`].join("\n"))}}function xt(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}class vt extends ye{constructor(){super(...arguments),t(this,"name","status"),t(this,"description","Get repeater status summary"),t(this,"aliases",["st"])}async execute({output:e,rawInput:t}){var r,a,s;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("status"),` ${Fe("Show a quick summary of mode, neighbor count, and uptime.")}`,"",Be("status","show summary"),"",De("Aliases"),` ${Fe("st")}`].join("\n"));const n=e.write("processing...","system");try{const t=await g(),o=(null==(a=null==(r=t.config)?void 0:r.repeater)?void 0:a.mode)||"unknown",i=Object.keys(t.neighbors||{}).length,c=Object.values(t.neighbors||{}).filter(e=>e.zero_hop).length,l=(null==(s=t.config)?void 0:s.node_name)||t.node_name||"unknown",d=xt(t.uptime_seconds||0);e.update(n,[`${Ee(l)} ${Fe("repeater")}`,"",` ${Le("Mode",Ie(o))}`,` ${Le("Neighbors",`${Ie(String(c))} direct ${Fe(`${i} total`)}`)}`,` ${Le("RX / TX",`${Ie(String(t.rx_count??0))} / ${Ie(String(t.tx_count??0))}`)}`,` ${Le("Uptime",Ie(d))}`].join("\n"))}catch(o){e.update(n,`Error: ${o instanceof Error?o.message:"Command failed"}`,"error")}}}class $t extends ye{constructor(){super(...arguments),t(this,"name","uptime"),t(this,"description","Show system uptime")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("uptime"),` ${Fe("Display how long the repeater service has been running.")}`,"",Be("uptime","show uptime")].join("\n"));const r=e.write("processing...","system");try{const t=await g();e.update(r,Le("Uptime",Ie(xt(t.uptime_seconds||0))))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class bt extends ye{constructor(){super(...arguments),t(this,"name","packets"),t(this,"description","Show packet statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("packets"),` ${Fe("Display packet counters (received, transmitted, forwarded, dropped).")}`,"",Be("packets","show packet stats")].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a=(t.rx_count??0)+(t.tx_count??0);e.update(r,[De("Packet Stats")+` ${Fe(`${a} total`)}`,"",` ${Le("Received",Ie(String(t.rx_count??0)))}`,` ${Le("Transmitted",Ie(String(t.tx_count??0)))}`,` ${Le("Forwarded",Ie(String(t.forwarded_count??0)))}`,` ${Le("Dropped",Ie(String(t.dropped_count??0)))}`].join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}function wt(e){return e>=1073741824?`${(e/1073741824).toFixed(1)} GB`:e>=1048576?`${(e/1048576).toFixed(0)} MB`:`${(e/1024).toFixed(0)} KB`}function _t(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}class kt extends ye{constructor(){super(...arguments),t(this,"name","board"),t(this,"description","Show board/platform info")}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("board"),` ${Fe("Display platform and hardware information.")}`,"",Be("board","show board info")].join("\n"));const a=e.write("loading...","system");try{const[t,s]=await Promise.all([f(),g()]),n=[];if(n.push(` ${Le("Node",Ie(s.node_name||"Unknown"))}`),n.push(` ${Le("Runtime",Ie(`pyMC_Repeater v${s.version||"?"}`))}`),s.core_version&&n.push(` ${Le("Core",Ie(s.core_version))}`),n.push(""),t.success&&t.data){const e=t.data;n.push(` ${Le("CPU",Ie(`${e.cpu.usage_percent.toFixed(1)}%`))} ${Fe(`${e.cpu.count} core${e.cpu.count>1?"s":""}`)}`),e.cpu.load_avg&&n.push(` ${Le("Load",Ie(`${e.cpu.load_avg["1min"].toFixed(2)} / ${e.cpu.load_avg["5min"].toFixed(2)} / ${e.cpu.load_avg["15min"].toFixed(2)}`))}`);const a=Object.entries(e.temperatures||{});if(a.length>0){const e=a[0];n.push(` ${Le("Temp",Ie(`${e[1].toFixed(1)}°C`))}${a.length>1?` ${Fe(a.slice(1).map(([e,t])=>`${e}: ${t.toFixed(1)}°C`).join(", "))}`:""}`)}n.push(""),n.push(` ${Le("Memory",Ie(`${wt(e.memory.used)} / ${wt(e.memory.total)}`))} ${Fe(`${e.memory.usage_percent.toFixed(0)}%`)}`),n.push(` ${Le("Disk",Ie(`${wt(e.disk.used)} / ${wt(e.disk.total)}`))} ${Fe(`${e.disk.usage_percent.toFixed(0)}%`)}`),n.push(""),(null==(r=e.system)?void 0:r.uptime)&&n.push(` ${Le("System uptime",Ie(_t(e.system.uptime)))}`),n.push(` ${Le("Service uptime",Ie(_t(s.uptime_seconds)))}`),e.network&&n.push(` ${Le("Net TX/RX",Ie(`${wt(e.network.bytes_sent)} / ${wt(e.network.bytes_recv)}`))}`)}else n.push(` ${Le("Platform",Ie("Linux"))}`),n.push(` ${Le("Service uptime",Ie(_t(s.uptime_seconds)))}`),n.push(` ${Fe("Hardware stats unavailable")}`);e.update(a,n.join("\n"),"value")}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Failed to load hardware stats"}`,"error")}}}const Ct="",St="",jt="",Nt="",Tt="",Rt=48;function Mt(e,t,r,a){return s=>{if(s<=0)return 0;if(s>=1)return 1;let n=s;for(let t=0;t<8;t++){const t=3*(1-n)*(1-n)*n*e+3*(1-n)*n*n*r+n*n*n-s,a=3*(1-n)*(1-n)*e+6*(1-n)*n*(r-e)+3*n*n*(1-r);if(Math.abs(a)<1e-7)break;n=Math.max(0,Math.min(1,n-t/a))}return 3*(1-n)*(1-n)*n*t+3*(1-n)*n*n*a+n*n*n}}const Et=Mt(.25,1,.5,1),At=Mt(.4,0,1,1);function It(e,t){const r=e%14;return Math.sin(.45*r+.04*r*r+.25*t)}const Ft=[8,16,32,128],Lt=[1,2,4,64].map((e,t)=>e|Ft[t]);function Bt(e,t,r,a){a<4?e[r]|=Lt[a]:t[r]|=Lt[a-4]}function Dt(e){return e>.8?""+St:e>.6?""+St:e>.4?Tt+St:e>.2?Tt:e>.08?Nt:Nt+jt}function Ot(e,t,r){const a=new Uint8Array(Rt),s=new Uint8Array(Rt),n=new Float32Array(Rt),o=.35*e;for(let i=0;i=t)continue;const l=t-c,d=Math.min(1,l/3),u=Math.min(1,c/2),p=l<5?1+.3*(1-l/5):1,m=Math.min(1,d*u*p);if(m<.04)continue;const h=1+.06*Math.sin(.7*e+.3*c),g=It(c,o)*m*h*3.5+3.5,f=Math.abs(g-3.5)/3.5,y=l<6?1-l/6:0;n[i]=Math.min(1,.65*f+.35*y)*m;const x=Math.max(0,Math.min(7,Math.round(g)));if(g>=3.5){for(let t=3;t<=x;t++)Bt(a,s,i,t);const e=Math.round(.4*(g-3.5));for(let t=Math.max(0,3-e);t<3;t++)Bt(a,s,i,t)}else{for(let t=x;t<=4;t++)Bt(a,s,i,t);const e=Math.round(.4*(3.5-g));for(let t=5;t<=Math.min(7,4+e);t++)Bt(a,s,i,t)}}return{top:a,bot:s,heat:n}}function Pt(e,t,r){const a=new Uint8Array(Rt),s=new Uint8Array(Rt),n=new Float32Array(Rt),o=Math.exp(.5*-t),i=Math.max(0,10-2.5*t),c=.7+.2*t;for(let l=0;l=Rt)continue;const d=o*(1-l/i);if(d<.04)continue;n[t]=d;const u=Math.sin(l*c+.6*r)*d*3.5+3.5,p=Math.max(0,Math.min(7,Math.round(u)));if(u>=3.5)for(let e=3;e<=p;e++)Bt(a,s,t,e);else for(let e=p;e<=4;e++)Bt(a,s,t,e)}return{top:a,bot:s,heat:n}}function Ut(e,t){let r="",a="";for(let s=0;s{a++,e.update(s,Ht(a,t,Date.now()-r).join("\n"))},50);return{id:s,stop:()=>clearInterval(n)}}class qt extends ye{constructor(){super(...arguments),t(this,"name","advert"),t(this,"description","Send repeater advertisement")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("advert"),` ${Fe("Broadcast a repeater advertisement to the mesh network.")}`,"",Be("advert","send advert now"),"",Oe("Adverts announce this repeater's presence to neighbors.")].join("\n"));const r=zt(e,"broadcast");try{const t=await y();r.stop(),t.success?e.update(r.id,`✓ ${Ie("Advert sent")}`,"success"):e.update(r.id,`Error: ${t.error||"Failed"}`,"error")}catch(a){r.stop(),e.update(r.id,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}const Kt=["sig","name","rssi","snr","dist","heard"],Wt={excellent:5,good:4,fair:3,poor:2,critical:1};function Gt(e){const t=Math.floor(Date.now()/1e3-e);return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function Xt(e){return e<1e3?`${Math.round(e)}m`:`${(e/1e3).toFixed(1)}km`}const Vt={excellent:5,good:4,fair:3,poor:2,critical:1};function Yt(e){const t=Vt[e]??0,r=He(e);return(t>0?`${r}${"█".repeat(t)}${ve}`:"")+Fe("⣿".repeat(5-t))}function Jt(e,t=e=>e){return{text:e,color:t}}function Qt(e){return Fe("+"+e.map(e=>"-".repeat(e+2)).join("+")+"+")}function Zt(e,t){const r=e.map((e,r)=>{if(null!=e.rendered){const a=Math.max(0,t[r]-e.text.length);return" "+e.rendered+" ".repeat(a)+" "}return" "+e.color((a=e.text,s=t[r],a.length>=s?a.slice(0,s):a+" ".repeat(s-a.length)))+" ";var a,s});return Fe("|")+r.join(Fe("|"))+Fe("|")}class er extends ye{constructor(){super(...arguments),t(this,"name","neighbors"),t(this,"description","Show direct RF neighbors with signal stats"),t(this,"aliases",["nb","get neighbors","get neighbor"]),t(this,"params","[sig|name|rssi|snr|dist|heard]")}async execute(e){const{output:t,cols:r}=e,a=this.argsAfterName(e.rawInput).toLowerCase().trim();if("help"===a)return void this.printUsage(t);const s=Kt.includes(a)?a:null,n=t.write("processing...","system");try{const e=await g(),a=e.neighbors||{},o=Object.entries(a).filter(([,e])=>e.zero_hop);if(0===o.length){const e=Object.keys(a).length;return void t.update(n,e>0?`No direct neighbors. ${e} relayed neighbor${1!==e?"s":""} known.`:"No neighbors discovered yet.","warning")}const i=function(e){var t;const r=null==(t=e.config)?void 0:t.radio;return(null==r?void 0:r.spreading_factor)&&(null==r?void 0:r.bandwidth)?{sf:r.spreading_factor,bwHz:r.bandwidth}:null}(e),c=function(e){var t;const r=null==(t=e.config)?void 0:t.repeater;return r&&K(r.latitude,r.longitude)?{lat:r.latitude,lon:r.longitude}:null}(e),l=e.noise_floor_dbm;this.sortNeighbors(o,s,i,c,l);const d=s?` ${Ae(`sorted by ${s}`)}`:"",u=[De(`Direct Neighbors (${o.length})`)+d,""];if(r<55)for(const[t,r]of o)u.push(...this.cardLayout(t,r,i,c,l));else{const e=r>=70&&null!=c,t=o.map(([t,r])=>this.buildRow(t,r,i,c,l,e)),a=e?["SIG","NAME","RSSI","SNR","DIST","HEARD"]:["SIG","NAME","RSSI","SNR","HEARD"],s=a.slice(1).map((e,r)=>Math.max(e.length,...t.map(e=>e[r+1].text.length))),n=5,d=s.reduce((e,t)=>e+t+3,0),p=Math.max(4,r-d-n-7),m=[n,Math.min(p,Math.max(4,...t.map(e=>e[1].text.length))),...s.slice(1)];u.push(Qt(m),...t.map(e=>Zt(e,m)),Qt(m),Zt(a.map(e=>Jt(e,Ee)),m),Qt(m)),u.push(this.footer(i,l))}t.update(n,u.join("\n"))}catch(o){t.update(n,`Error: ${o instanceof Error?o.message:"Command failed"}`,"error")}}sortNeighbors(e,t,r,a,s){switch(t){case"sig":e.sort(([,e],[,t])=>(Wt[this.gradeNeighbor(e,r,s)]??0)-(Wt[this.gradeNeighbor(t,r,s)]??0));break;case"name":e.sort(([e,t],[r,a])=>{const s=(t.name||t.node_name||e.slice(0,8)).toLowerCase(),n=(a.name||a.node_name||r.slice(0,8)).toLowerCase();return s.localeCompare(n)});break;case"rssi":e.sort(([,e],[,t])=>(e.rssi??-999)-(t.rssi??-999));break;case"snr":e.sort(([,e],[,t])=>(e.snr??-999)-(t.snr??-999));break;case"dist":e.sort(([,e],[,t])=>(this.distTo(e,a)??1/0)-(this.distTo(t,a)??1/0));break;case"heard":e.sort(([,e],[,t])=>(e.last_seen||0)-(t.last_seen||0));break;default:e.sort(([,e],[,t])=>(t.last_seen||0)-(e.last_seen||0))}}gradeNeighbor(e,t,r){const a=null!=e.rssi?e.rssi-3.5:null,s=null!=r&&r>-100?1:0,n=x(e.snr??null,a,t,s);return(null==n?void 0:n.finalGrade)??"critical"}distTo(e,t){return t&&K(e.latitude,e.longitude)?W(t.lat,t.lon,e.latitude,e.longitude):null}buildRow(e,t,r,a,s,n){const o=this.gradeNeighbor(t,r,s),i=qe(t.name||t.node_name||e.slice(0,8))||e.slice(0,8),c=null!=t.rssi?`${t.rssi} dBm`:"-",l=null!=t.snr?`${t.snr} dB`:"-",d=t.last_seen?Gt(t.last_seen):"-",u=[(p=Yt(o),{text:"|||||",color:e=>e,rendered:p}),Jt(i,Ee),Jt(c,Ie),Jt(l,Ie)];var p;if(n){const e=this.distTo(t,a);u.push(Jt(null!=e?Xt(e):"-",Ae))}return u.push(Jt(d,Ae)),u}cardLayout(e,t,r,a,s){const n=this.gradeNeighbor(t,r,s),o=qe(t.name||t.node_name||e.slice(0,8))||e.slice(0,8),i=null!=t.rssi?`${t.rssi}`:"-",c=null!=t.snr?`${t.snr}`:"-",l=t.last_seen?Gt(t.last_seen):"-",d=this.distTo(t,a),u=null!=d?` ${Fe("dist")} ${Ie(Xt(d))}`:"";return[`${Yt(n)} ${Ee(o)}`,` ${Fe("rssi")} ${Ie(i)} ${Fe("snr")} ${Ie(c)}${u} ${Ae(l)}`,""]}footer(e,t){const r=[];return e&&r.push(`SF${e.sf}/${e.bwHz>=1e3?e.bwHz/1e3+"kHz":e.bwHz+"Hz"}`),r.push("ant 3.5dBi"),null!=t&&r.push(`nf ${t}dBm`),Fe(r.join(" "))}printUsage(e){const t=[De("neighbors"),` ${Fe("Show direct RF neighbors with signal quality, RSSI, SNR, and distance.")}`,"",De("Usage"),Be("neighbors","default sort (most recent)"),Be("neighbors sig","sort by signal grade (weakest first)"),Be("neighbors name","sort alphabetically"),Be("neighbors rssi","sort by RSSI (weakest first)"),Be("neighbors snr","sort by SNR (lowest first)"),Be("neighbors dist","sort by distance (closest first)"),Be("neighbors heard","sort by last seen (oldest first)"),Be("neighbors help","show this help"),"",De("Aliases"),` ${Fe("nb, get neighbors, get neighbor")}`,"",Oe("Signal bars factor radio config, noise floor, and 3.5 dBi antenna gain."),Oe("Only zero-hop (direct RF) neighbors are shown.")];e.write(t.join("\n"))}}class tr extends ye{constructor(){super(...arguments),t(this,"name","get"),t(this,"description","Get repeater parameter"),t(this,"params","{parameter}")}async execute({output:e,rawInput:t}){const r=this.argsAfterName(t).toLowerCase().trim();if("help"===r||!r)return void e.write([De("get"),` ${Fe("Read a repeater configuration parameter.")}`,"",De("Identity"),Be("get name","node name"),Be("get role","node role"),Be("get public.key","public key"),"",De("Location"),Be("get lat","latitude"),Be("get lon","longitude"),"",De("Radio"),Be("get radio","full radio summary"),Be("get freq","frequency (MHz)"),Be("get tx","TX power (dBm)"),Be("get bw","bandwidth (kHz)"),Be("get sf","spreading factor"),Be("get cr","coding rate"),"",De("Timing"),Be("get af","airtime factor (pending backend)"),Be("get txdelay","TX delay factor"),Be("get direct.txdelay","direct TX delay"),Be("get rxdelay","RX delay base"),"",De("Repeater"),Be("get mode","forward or monitor"),Be("get flood.max","max flood hops"),Be("get advert.interval","advert interval"),Be("get duty","duty cycle state"),"",De("Advanced"),Be("get multi.acks","multi-ack count"),Be("get int.thresh","interference threshold (dBm)"),Be("get agc.reset.interval","AGC reset interval")].join("\n"));const a=e.write("processing...","system");try{const t=await g(),{result:s,type:n}=function(e,t){const r=t.config||{},a=r.radio||{},s=r.repeater||{},n=r.delays||{},o=r.duty_cycle||{},i=(e,t)=>({result:Le(e,Ie(t)),type:"value"});switch(e){case"name":return i("name",r.node_name||"Unknown");case"role":return i("role","repeater");case"lat":return i("lat",null!=s.latitude?String(s.latitude):"not set");case"lon":return i("lon",null!=s.longitude?String(s.longitude):"not set");case"freq":return i("freq",a.frequency?`${(a.frequency/1e6).toFixed(3)} MHz`:"?");case"tx":return i("tx",null!=a.tx_power?`${a.tx_power} dBm`:"?");case"bw":return i("bw",a.bandwidth?a.bandwidth/1e3+" kHz":"?");case"sf":return i("sf",String(a.spreading_factor??"?"));case"cr":return i("cr",a.coding_rate?`4/${a.coding_rate}`:"?");case"radio":return a.frequency?{result:[` ${Le("freq",Ie(`${(a.frequency/1e6).toFixed(3)} MHz`))}`,` ${Le("bw",Ie(a.bandwidth/1e3+" kHz"))}`,` ${Le("sf",Ie(String(a.spreading_factor)))}`,` ${Le("cr",Ie(`4/${a.coding_rate}`))}`,` ${Le("tx",Ie(`${a.tx_power} dBm`))}`].join("\n"),type:"value"}:i("radio","?");case"af":case"airtime.factor":return{result:`${Fe("airtime_factor is not yet exposed by the pyMC_Repeater API.")}\n${Fe("Firmware range: 0-9. Controls airtime budget fraction.")}\n${Fe("Tracked in CLI-Alignment.md — needs backend support.")}`,type:"warning"};case"txdelay":return i("txdelay",String(n.tx_delay_factor??"1.0"));case"direct.txdelay":return i("direct.txdelay",String(n.direct_tx_delay_factor??"0.5"));case"rxdelay":return i("rxdelay",String(n.rx_delay_base??"0.0"));case"mode":return i("mode",s.mode||"forward");case"repeat":return i("repeat","forward"===s.mode?"on":"off");case"flood.max":return i("flood.max",String(s.max_flood_hops??"3"));case"flood.advert.interval":return i("flood.advert.interval",null!=s.send_advert_interval_hours?`${s.send_advert_interval_hours}h`:"?");case"advert.interval":return i("advert.interval",null!=s.advert_interval_minutes?`${s.advert_interval_minutes}m`:"120m");case"duty":case"duty.enabled":return i("duty",o.enforcement_enabled?"on":"off");case"duty.max":return i("duty.max",null!=o.max_airtime_percent?`${o.max_airtime_percent}%`:"?");case"multi.acks":return i("multi.acks",String(s.multi_acks??"0"));case"int.thresh":return i("int.thresh",`${s.interference_threshold??-120} dBm`);case"agc.reset.interval":return i("agc.reset.interval",String(s.agc_reset_interval??"0"));case"public.key":return i("public.key",t.public_key||"not available");case"prv.key":return{result:`${Fe("Private key stored in /etc/pymc_repeater/config.yaml")}\n\n ${Le("view",Ie("sudo grep identity_key /etc/pymc_repeater/config.yaml"))}\n ${Le("set",Ie("sudo ./convert_firmware_key.sh <64-byte-hex>"))}`,type:"info"};case"guest.password":case"allow.read.only":return{result:`${Fe("Security settings not exposed via stats API.")}\n${Fe("Check /etc/pymc_repeater/config.yaml")}`,type:"warning"};default:return{result:`Unknown parameter: ${Ie(e)}\n${Fe('Run "get help" to see available parameters.')}`,type:"error"}}}(r,t);e.update(a,s,n)}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}class rr extends ye{constructor(){super(...arguments),t(this,"name","set"),t(this,"description","Set repeater parameter"),t(this,"params","{parameter} {value}")}async execute({output:e,rawInput:t}){var r;const a=this.argsAfterName(t).split(/\s+/),s=null==(r=a[0])?void 0:r.toLowerCase(),n=a.slice(1).join(" ");if("help"===s||!s)return void e.write([De("set"),` ${Fe("Write a repeater configuration parameter.")}`,"",De("Identity"),Be("set name ","node name"),Be("set lat ","latitude (-90 to 90)"),Be("set lon ","longitude (-180 to 180)"),"",De("Radio"),Be("set freq ","frequency"),Be("set tx ","TX power (2-22)"),Be("set bw ","bandwidth"),Be("set sf <5-12>","spreading factor"),Be("set cr <5-8>","coding rate"),"",De("Timing"),Be("set af <0-9>","airtime factor (pending backend)"),Be("set txdelay <0-5>","TX delay factor"),Be("set direct.txdelay <0-5>","direct TX delay"),Be("set rxdelay ","RX delay base"),"",De("Repeater"),Be("set mode ","forward or monitor"),Be("set flood.max <0-64>","max flood hops"),Be("set advert.interval ","advert interval (min)"),Be("set duty ","duty cycle enforcement"),Be("set log ","log level"),"",De("Advanced"),Be("set multi.acks ","multi-ack count"),Be("set int.thresh ","interference threshold"),Be("set agc.reset.interval ","AGC reset interval (x4)"),"",Oe("Some changes require a service restart.")].join("\n"));const o=e.write("processing...","system");try{const{result:r,type:a}=await async function(e,t,r){switch(e){case"mode":return async function(e){const t=e.toLowerCase();return"forward"!==t&&"monitor"!==t?lr('Mode must be "forward" or "monitor"'):(await w(t)).success?cr(`OK - Mode set to ${t}`):lr("Failed")}(t);case"duty":return async function(e){const t="on"===e.toLowerCase()||"1"===e;return(await b(t)).success?cr("OK - Duty cycle "+(t?"enabled":"disabled")):lr("Failed")}(t);case"tx":return ar("tx_power",nr(t,2,22,"TX power must be 2-22 dBm"));case"sf":return ar("spreading_factor",nr(t,5,12,"SF must be 5-12"));case"af":case"airtime.factor":return{result:"Error: airtime_factor is not yet exposed by the pyMC_Repeater API.\nFirmware range: 0-9. Tracked in CLI-Alignment.md — needs backend support.",type:"info"};case"txdelay":return ar("tx_delay_factor",or(t,0,5,"TX delay must be 0.0-5.0"));case"direct.txdelay":return ar("direct_tx_delay_factor",or(t,0,5,"Direct TX delay must be 0.0-5.0"));case"rxdelay":return ar("rx_delay_base",function(e){const t=parseFloat(e);return isNaN(t)||t<0?{ok:!1,error:"Error: RX delay must be >= 0"}:{ok:!0,value:t}}(t));case"flood.max":return ar("max_flood_hops",nr(t,0,64,"Max flood hops must be 0-64"));case"log":return async function(e){const t=e.toUpperCase();if(!["DEBUG","INFO","WARNING","ERROR"].includes(t))return lr("Level must be debug, info, warning, or error");const r=await $(t);return r.success?cr(`OK - Log level set to ${t}`):lr(r.error||"Failed")}(t);case"multi.acks":return ar("multi_acks",nr(t,0,255,"Multi-acks must be 0-255"));case"int.thresh":return ar("interference_threshold",nr(t,-200,0,"Interference threshold must be -200 to 0 dBm"));case"agc.reset.interval":{const e=ir(t);if(!e.ok)return lr(e.error);if(e.value<0)return lr("AGC reset interval must be >= 0");const r=4*Math.floor(e.value/4);return sr("agc_reset_interval",r,`OK - AGC reset interval set to ${r}${r!==e.value?` (rounded from ${e.value})`:""}`)}case"name":{const e=r.trim().substring(r.toLowerCase().indexOf("name")+5).trim();return e?/[\[\]\\/\\:,?*]/.test(e)?lr("Name contains invalid characters: [ ] \\ / : , ? * are not allowed"):ar("node_name",{ok:!0,value:e}):lr("Node name cannot be empty")}case"lat":return ar("latitude",or(t,-90,90,"Latitude must be -90 to 90"));case"lon":return ar("longitude",or(t,-180,180,"Longitude must be -180 to 180"));case"freq":{const e=or(t,100,1e3,"Frequency must be 100-1000 MHz");return e.ok?ar("frequency",{ok:!0,value:1e6*e.value}):lr(e.error)}case"bw":{const e=[7.8,10.4,15.6,20.8,31.25,41.7,62.5,125,250,500],r=parseFloat(t);return isNaN(r)||!e.includes(r)?lr(`BW must be one of: ${e.join(", ")} kHz`):ar("bandwidth",{ok:!0,value:1e3*r})}case"cr":return ar("coding_rate",nr(t,5,8,"Coding rate must be 5-8"));case"advert.interval":{const e=ir(t);return e.ok?0!==e.value&&(e.value<1||e.value>10080)?lr("Advert interval must be 0 (off) or 1-10080 minutes"):sr("advert_interval_minutes",e.value,0===e.value?"OK - Local adverts disabled":`OK - Local advert interval set to ${e.value}m`):lr(e.error)}case"flood.advert.interval":{const e=ir(t);return e.ok?0!==e.value&&(e.value<3||e.value>168)?lr("Flood advert interval must be 0 (off) or 3-168 hours"):sr("flood_advert_interval_hours",e.value,0===e.value?"OK - Flood adverts disabled":`OK - Flood advert interval set to ${e.value}h`):lr(e.error)}case"prv.key":{const e=t.trim();return e?/^[0-9a-fA-F]+$/.test(e)?128!==e.length?lr(`Key must be 64 bytes (128 hex chars), got ${e.length} chars`):{result:`To set this key, run on the Pi:\n\n sudo ./convert_firmware_key.sh ${e}\n\nThen restart: sudo systemctl restart pymc-repeater`,type:"info"}:lr("Private key must be a hex string"):lr("Private key cannot be empty")}default:return lr(`Unknown parameter: ${e}`)}}(s,n,t);e.update(o,r,a)}catch(i){e.update(o,`Error: ${i instanceof Error?i.message:"Command failed"}`,"error")}}}async function ar(e,t){if(!t.ok)return lr(t.error);const r=await v({[e]:t.value});if(!r.success)return lr(r.error||"Failed");let a=`OK - ${e} set to ${t.value}`;return r.restart_required&&(a+="\n⚠ Service restart required for changes to take effect\nRun: sudo systemctl restart pymc_repeater"),cr(a)}async function sr(e,t,r){const a=await v({[e]:t});if(!a.success)return lr(a.error||"Failed");let s=r;return a.restart_required&&(s+="\n⚠ Service restart required for changes to take effect\nRun: sudo systemctl restart pymc_repeater"),cr(s)}function nr(e,t,r,a){const s=parseInt(e);return isNaN(s)||sr?{ok:!1,error:`Error: ${a}`}:{ok:!0,value:s}}function or(e,t,r,a){const s=parseFloat(e);return isNaN(s)||sr?{ok:!1,error:`Error: ${a}`}:{ok:!0,value:s}}function ir(e){const t=parseInt(e);return isNaN(t)?{ok:!1,error:"Error: Expected a number"}:{ok:!0,value:t}}function cr(e){return{result:e,type:"success"}}function lr(e){return{result:`Error: ${e}`,type:"error"}}const dr={excellent:5,good:4,fair:3,poor:2,critical:1};class ur extends ye{constructor(){super(...arguments),t(this,"name","ping"),t(this,"description","Ping neighbor (name or 0xXX)"),t(this,"params","{target} [timeout]")}async execute({output:e,rawInput:t}){var r,a,s,n;const o=this.argsAfterName(t).trim(),i=o.split(/\s+/);if("help"===(null==(r=i[0])?void 0:r.toLowerCase()))return void e.write([De("ping"),` ${Fe("Send a ping to a neighbor and measure round-trip time, signal quality, and path.")}`,"",Be("ping ","ping by node name"),Be("ping 0xAB","ping by hex prefix"),Be("ping 60","ping with custom timeout (seconds)"),"",Oe("Default timeout: 30s. Signal bars factor radio config and noise floor.")].join("\n"));const c=i[i.length-1],l=parseInt(c),d=i.length>1&&!isNaN(l)&&l>0,u=d?i.slice(0,-1).join(" "):o,p=d?l:30;if(!u)return void e.write([De("ping"),` ${Fe("Send a ping to a neighbor and measure round-trip time.")}`,"",Be("ping ","ping by node name"),Be("ping 60","with custom timeout"),"",Oe('Run "ping help" for full usage.')].join("\n"));const m=zt(e,u);try{const[t,r]=await Promise.all([G(u,p),g()]);if(m.stop(),t.success&&t.data){const o=t.data,i=null==(a=r.config)?void 0:a.radio,c=(null==i?void 0:i.spreading_factor)&&(null==i?void 0:i.bandwidth)?{sf:i.spreading_factor,bwHz:i.bandwidth}:null,l=r.noise_floor_dbm,d=null!=l&&l>-100?1:0,u=o.rssi-3.5,p=x(o.snr_db,u,c,d),h=(null==p?void 0:p.finalGrade)??"critical",g=function(e){const t=dr[e]??0,r=He(e);return(t>0?`${r}${"█".repeat(t)}${ve}`:"")+Fe("·".repeat(5-t))}(h),f=(null==(s=o.path)?void 0:s.length)?o.path.length:0,y=(null==(n=o.path)?void 0:n.length)?o.path.join(" > "):"direct",v=h.charAt(0).toUpperCase()+h.slice(1),$=[`${g} ${Ee("Reply from")} ${Ie(o.target_id)}`,"",` ${Le("RTT",Ue(o.rtt_ms))}`,` ${Le("RSSI",`${o.rssi} dBm`)}`,` ${Le("SNR",`${o.snr_db} dB`)}`,` ${Le("Path",y)}${f>0?Fe(` (${f} hop${1!==f?"s":""})`):""}`,` ${Le("Quality",ze(v,h))}`],b=[];c&&b.push(`SF${c.sf}/${c.bwHz>=1e3?c.bwHz/1e3+"kHz":c.bwHz+"Hz"}`),b.push("ant 3.5dBi"),null!=l&&b.push(`nf ${l}dBm`),$.push("",Fe(b.join(" "))),e.update(m.id,$.join("\n"))}else e.update(m.id,t.error||"Ping failed","error")}catch(h){m.stop(),e.update(m.id,`Error: ${h instanceof Error?h.message:"Ping failed"}`,"error")}}}class pr extends ye{constructor(){super(...arguments),t(this,"name","convert"),t(this,"description","Convert between hex and base64"),t(this,"params","hex|base64 {value}")}execute({output:e,args:t}){var r;const a=null==(r=t[1])?void 0:r.toLowerCase(),s=t.slice(2).join(" ").trim();"help"!==a&&(a||s)?"hex"===a?this.hexToBase64(e,s):"base64"===a?this.base64ToHex(e,s):e.write([De("convert"),` ${Fe("Convert between hex and base64 encodings.")}`,"",Be("convert hex ","hex → base64"),Be("convert base64 ","base64 → hex")].join("\n")):e.write([De("convert"),` ${Fe("Convert between hex and base64 encodings.")}`,"",Be("convert hex ","hex → base64"),Be("convert base64 ","base64 → hex"),"",Oe("Example: convert hex 48656C6C6F")].join("\n"))}hexToBase64(e,t){if(t)if(/^[0-9a-fA-F]+$/.test(t))if(t.length%2==0)try{const r=new Uint8Array(t.length/2);for(let e=0;e","error")}base64ToHex(e,t){if(t)try{const r="function"==typeof globalThis.atob?globalThis.atob(t):Buffer.from(t,"base64").toString("binary");let a="";for(let e=0;e","error")}}function mr(){const e=new Date;return`${e.toISOString().slice(0,10)}_${e.toTimeString().slice(0,8).replace(/:/g,"-")}`}function hr(e,t){return`pymc-${e.toISOString().slice(0,10)}-${e.toTimeString().slice(0,5).replace(":","")}-${t}s.json`}const gr=i((e,t)=>({isCapturing:!1,captureStartTime:null,captureStartPacketHashes:new Set,captureTimer:null,reports:[],startCapture:r=>{const{captureTimer:a}=t();a&&clearTimeout(a),e({isCapturing:!0,captureStartTime:new Date,captureStartPacketHashes:new Set(r.map(e=>e.packet_hash))})},stopCapture:r=>{const{isCapturing:a,captureStartTime:s,captureStartPacketHashes:n,captureTimer:o}=t();if(!a||!s)return null;o&&clearTimeout(o);const i=new Date,c=Math.round((i.getTime()-s.getTime())/1e3),l=s.getTime()/1e3,d=r.filter(e=>!n.has(e.packet_hash)&&e.timestamp>=l).sort((e,t)=>e.timestamp-t.timestamp),u={id:mr(),filename:hr(s,c),startTime:s,endTime:i,durationSec:c,packetCount:d.length,packets:d,sizeBytes:500*d.length};return e(e=>({isCapturing:!1,captureStartTime:null,captureStartPacketHashes:new Set,captureTimer:null,reports:[u,...e.reports].slice(0,10)})),u},getReport:e=>t().reports.find(t=>t.id===e),_setTimer:t=>e({captureTimer:t})})),fr=()=>gr(e=>e.reports);function yr(e){var t;return(null==(t=e.match(/.{1,2}/g))?void 0:t.join(" ").toUpperCase())||""}function xr(e){return void 0===e?"UNKNOWN":j[e]??`TYPE_${e}`}function vr(e){return void 0===e?"UNKNOWN":S[e]??`ROUTE_${e}`}function $r(e,t){switch(e){case 4:return function(e){const t=[];let r=0;if(e.length>=32&&(t.push({name:"public_key",offset:r,length:32,bytes:yr(C(e.slice(r,r+32))),decoded:{value:C(e.slice(r,r+32))}}),r+=32),e.length>=r+4){const a=e.slice(r,r+4),s=a[0]|a[1]<<8|a[2]<<16|a[3]<<24;t.push({name:"timestamp",offset:r,length:4,bytes:yr(C(a)),decoded:{value:s>>>0,iso:new Date(1e3*s).toISOString()}}),r+=4}if(e.length>=r+64&&(t.push({name:"signature",offset:r,length:64,bytes:yr(C(e.slice(r,r+64))),decoded:{value:C(e.slice(r,r+64))}}),r+=64),e.length>r){const a=e[r],s=[];if(1&a&&s.push("CHAT_NODE"),2&a&&s.push("REPEATER"),3&a&&s.push("ROOM_SERVER"),16&a&&s.push("HAS_LOCATION"),128&a&&s.push("HAS_NAME"),t.push({name:"flags",offset:r,length:1,bytes:yr(C(e.slice(r,r+1))),decoded:{value:a,binary:a.toString(2).padStart(8,"0"),flags:s}}),r+=1,16&a&&e.length>=r+8){const a=e.slice(r,r+8),s=new ArrayBuffer(8);new Uint8Array(s).set(a);const n=new DataView(s),o=n.getInt32(0,!0),i=n.getInt32(4,!0);t.push({name:"location",offset:r,length:8,bytes:yr(C(a)),decoded:{lat_raw:o,lon_raw:i,latitude:o/1e6,longitude:i/1e6}}),r+=8}if(128&a&&e.length>r){const a=e.slice(r);let s=a.indexOf(0);-1===s&&(s=a.length);const n=(new TextDecoder).decode(a.slice(0,s));t.push({name:"name",offset:r,length:s+(0===a[s]?1:0),bytes:yr(C(a.slice(0,s+1))),decoded:{value:n,encoding:"utf-8",null_terminated:0===a[s]}})}}return t}(t);case 3:return function(e){if(e.length<4)return[];const t=e.slice(0,4),r=t[0]|t[1]<<8|t[2]<<16|t[3]<<24;return[{name:"crc",offset:0,length:4,bytes:yr(C(t)),decoded:{value:r>>>0,hex:(r>>>0).toString(16).toUpperCase().padStart(8,"0"),note:"CRC of the acknowledged packet (little-endian)"}}]}(t);case 9:return function(e){const t=[];if(e.length<9)return t;const r=e.slice(0,4),a=r[0]|r[1]<<8|r[2]<<16|r[3]<<24;t.push({name:"trace_tag",offset:0,length:4,bytes:yr(C(r)),decoded:{value:a>>>0,hex:(a>>>0).toString(16).toUpperCase().padStart(8,"0")}});const s=e.slice(4,8),n=s[0]|s[1]<<8|s[2]<<16|s[3]<<24;if(t.push({name:"auth_code",offset:4,length:4,bytes:yr(C(s)),decoded:{value:n>>>0}}),t.push({name:"flags",offset:8,length:1,bytes:yr(C(e.slice(8,9))),decoded:{value:e[8],binary:e[8].toString(2).padStart(8,"0")}}),e.length>9){const r=e.slice(9),a=Array.from(r).map(e=>e.toString(16).toUpperCase().padStart(2,"0"));t.push({name:"target_path",offset:9,length:r.length,bytes:yr(C(r)),decoded:{hops:a,path_string:a.join("->")}})}return t}(t);case 8:return function(e){if(0===e.length)return[];const t=Array.from(e).map(e=>e.toString(16).toUpperCase().padStart(2,"0"));return[{name:"path_hops",offset:0,length:e.length,bytes:yr(C(e)),decoded:{hops:t,path_string:t.join("->")}}]}(t);case 5:return function(e){const t=[];if(e.length<1)return t;if(t.push({name:"channel_hash",offset:0,length:1,bytes:yr(C(e.slice(0,1))),decoded:{value:e[0].toString(16).toUpperCase().padStart(2,"0")}}),e.length>13){const r=12,a=e.length-1-r;t.push({name:"ciphertext",offset:1,length:a,bytes:yr(C(e.slice(1,1+a))),decoded:{length:a,note:"Encrypted message content"}}),t.push({name:"mac",offset:1+a,length:r,bytes:yr(C(e.slice(-r))),decoded:{note:"Message authentication code"}})}return t}(t);default:return function(e){return 0===e.length?[]:[{name:"raw_data",offset:0,length:e.length,bytes:yr(C(e)),decoded:{length:e.length}}]}(t)}}function br(e){const t=e.type??e.payload_type??0,r=e.route??e.route_type??0,a=e.raw_packet||"";let s,n=null;if(a){const t=X.fromHex(a);if(t.success&&t.packet){const e=t.packet;try{n=V(e)}catch{n=null}const r=k(a);let o=0;const i={offset:0,length:1,bytes:yr(a.slice(0,2)),decoded:{route_type:e.routeType,route_name:e.routeTypeName,payload_type:e.payloadType,payload_name:e.payloadTypeName,version:e.payloadVersion}};o+=1,e.hasTransportCodes()&&(o+=4);const c={offset:o,length:1,bytes:yr(C(r.slice(o,o+1))),decoded:{value:e.pathLen}};o+=1;const l=o,d=r.slice(o,o+e.pathLen),u=Array.from(e.path).map(e=>e.toString(16).toUpperCase().padStart(2,"0")),p=9===e.payloadType,m={offset:l,length:e.pathLen,bytes:yr(C(d)),decoded:{hops:u,path_string:u.length>0?u.join("->"):"(direct)",...p&&{note:"For TRACE packets, path bytes are SNR×4 values, not node hashes",snr_values:Array.from(e.path).map(e=>{let t=e;return t>127&&(t-=256),t/4})}}};o+=e.pathLen,s={header:i,path_length:c,path:m,payload:{offset:o,length:e.payload.length,bytes:yr(e.payloadHex),sections:$r(e.payloadType,e.payload)}}}else s=wr(e)}else s=wr(e);return{timestamp:e.timestamp,packet_hash:e.packet_hash,type:t,type_name:xr(t),route:r,route_name:vr(r),rssi:e.rssi,snr:e.snr,length:e.length??0,src_hash:e.src_hash,dst_hash:e.dst_hash,transmitted:e.transmitted,drop_reason:e.drop_reason,is_duplicate:e.is_duplicate,lbt_attempts:e.lbt_attempts,lbt_backoff_delays_ms:e.lbt_backoff_delays_ms,lbt_channel_busy:e.lbt_channel_busy,raw_packet:a,structure:s,decoded:n}}function wr(e){var t;const r=e.type??e.payload_type??0,a=e.route??e.route_type??0,s=e.original_path??e.forwarded_path??[];return{header:{offset:0,length:1,bytes:"??",decoded:{route_type:a,route_name:vr(a),payload_type:r,payload_name:xr(r),version:0}},path_length:{offset:1,length:1,bytes:s.length.toString(16).toUpperCase().padStart(2,"0"),decoded:{value:s.length}},path:{offset:2,length:s.length,bytes:s.join(" "),decoded:{hops:s,path_string:s.length>0?s.join("->"):"(direct)"}},payload:{offset:2+s.length,length:(null==(t=e.payload)?void 0:t.length)??0,bytes:e.payload??"",sections:e.payload?$r(r,k(e.payload)):[]}}}function _r(e,t){const r=function(e,t){var r;return{capture:{start:e.startTime.toISOString(),end:e.endTime.toISOString(),duration_sec:e.durationSec,packet_count:e.packetCount,node_name:(null==t?void 0:t.node_name)??"unknown",local_hash:(null==t?void 0:t.local_hash)??"unknown",pymc_console_version:_,pymc_repeater_version:(null==t?void 0:t.version)??"unknown",radio_config:(null==(r=null==t?void 0:t.config)?void 0:r.radio)?{frequency:t.config.radio.frequency,tx_power:t.config.radio.tx_power,bandwidth:t.config.radio.bandwidth,spreading_factor:t.config.radio.spreading_factor}:null},packets:e.packets.map(br)}}(e,t),a=JSON.stringify(r,null,2),s=new Blob([a],{type:"application/json"}),n=URL.createObjectURL(s),o=document.createElement("a");o.href=n,o.download=e.filename,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(n)}function kr(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}class Cr extends ye{constructor(){super(...arguments),t(this,"name","cap"),t(this,"description","Packet capture (start/end/list/export)")}matches(e){const t=e.toLowerCase().trim();return"cap"===t||"cap help"===t||t.startsWith("start cap")||t.startsWith("end cap")||t.startsWith("list cap")||t.startsWith("export cap")}async execute({output:e,rawInput:t}){const r=t.toLowerCase().trim();return"cap"===r||"cap help"===r?this.showHelp(e):r.startsWith("start cap")?this.startCapture(e,r):"end cap"===r?this.endCapture(e):"list cap"===r?this.listCaptures(e):r.startsWith("export cap")?this.exportCapture(e,r):void this.showHelp(e)}showHelp(e){const t=gr.getState(),r=t.isCapturing?`\n${Pe('Recording in progress... use "end cap" to stop')}`:"",a=t.reports.length,s=a>0?` (${a} saved)`:"",n=[De("Packet Capture"),"",Be("start cap","Start capture (default: 120s)"),Be("end cap","Stop capture early"),Be("list cap",`List saved captures${s}`),Be("export cap","Download capture by ID"),"",Oe("Captures stored in session memory. JSON includes decoded payloads."),r].filter(Boolean);e.write(n.join("\n"))}startCapture(e,t){const r=t.slice(9).trim(),a=r?parseInt(r):120;if(isNaN(a)||a<1||a>3600)return void e.write("Error: Duration must be 1-3600 seconds","error");const s=gr.getState();if(s.isCapturing)return void e.write('Error: Capture already in progress. Use "end cap" first.',"error");const n=N.getState().packets;s.startCapture(n);let o=a;const i=e.write(Pe(`Capturing... ${o}s remaining`),"system"),c=setInterval(()=>{o--;const t=gr.getState();if(o>=0&&t.isCapturing){const r=N.getState().packets.filter(e=>{if(!t.captureStartTime)return!1;const r=t.captureStartTime.getTime()/1e3;return e.timestamp>=r&&!t.captureStartPacketHashes.has(e.packet_hash)}).length,a=o>0?`${o}s remaining`:"finishing...";e.update(i,Pe(`Capturing... ${a} (${r} captured)`),"system")}},1e3),l=setTimeout(()=>{clearInterval(c);const t=gr.getState();if(t.isCapturing){const r=N.getState().packets,a=t.stopCapture(r);a?e.write(`✓ Capture complete!\n Captured: ${a.packetCount} packets\n Duration: ${a.durationSec}s\n Size: ~${kr(a.sizeBytes)}\n\nRun \`export cap ${a.id}\` to download.`,"value"):e.write("Capture completed with no packets.","warning")}},1e3*a);s._setTimer(l)}endCapture(e){const t=gr.getState();if(!t.isCapturing)return void e.write("No capture in progress.","warning");const r=N.getState().packets,a=t.stopCapture(r);a?e.write(`✓ Capture stopped!\n Captured: ${a.packetCount} packets\n Duration: ${a.durationSec}s\n Size: ~${kr(a.sizeBytes)}\n\nRun \`export cap ${a.id}\` to download.`,"value"):e.write("Capture stopped with no packets.","warning")}listCaptures(e){const{reports:t}=gr.getState();if(0===t.length)return void e.write("No capture reports available.\nStart a capture with: start cap [seconds]","info");const r=t.map((e,t)=>` ${t+1}. ${e.packetCount} pkts • ${e.durationSec}s • ~${kr(e.sizeBytes)} (id: ${e.id})`);e.write(`Capture Reports (${t.length}):\n${r.join("\n")}`,"info")}exportCapture(e,t){const r=t.slice(10).trim(),a=gr.getState(),s=N.getState().stats;if(!r){if(0===a.reports.length)e.write("No capture reports available.\nStart a capture with: start cap [seconds]","info");else{const t=a.reports.map((e,t)=>` ${t+1}. ${e.id}`);e.write(`Usage: export cap \n\nAvailable reports:\n${t.join("\n")}`,"info")}return}let n=a.getReport(r);if(!n){const e=parseInt(r)-1;n=a.reports[e]}n?(_r(n,s),e.write(`✓ Downloading ${n.filename}...`,"value")):e.write(`Error: Report "${r}" not found.\nUse "list cap" to see available reports.`,"error")}}class Sr extends ye{constructor(){super(...arguments),t(this,"name","identities"),t(this,"description","List configured identities"),t(this,"aliases",["id","ids"])}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("identities"),` ${Fe("List all configured repeater and room server identities.")}`,"",Be("identities","list identities"),"",De("Aliases"),` ${Fe("id, ids")}`].join("\n"));const a=e.write("processing...","system");try{const t=await T();if(!t.success||!t.data)return void e.update(a,t.error||"Failed to fetch identities","error");const s=t.data,n=(null==(r=s.configured)?void 0:r.length)?s.configured:s.registered||[];if(0===n.length)return void e.update(a,"No identities configured.","warning");const o=[De(`Identities (${n.length})`),"",...n.map((e,t)=>{var r;const a=e.name||"Unnamed",s=e.type||"unknown",n=(null==(r=e.hash)?void 0:r.slice(0,8))||"—";return` ${Fe(`${t+1}.`)} ${Ee(a)} ${Ae(s)} ${Ie(n)}`})];e.update(a,o.join("\n"))}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}class jr extends ye{constructor(){super(...arguments),t(this,"name","keys"),t(this,"description","List transport keys")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("keys"),` ${Fe("List configured transport encryption keys.")}`,"",Be("keys","list transport keys")].join("\n"));const r=e.write("processing...","system");try{const t=await Y();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch transport keys","error");const a=t.data;if(0===a.length)return void e.update(r,"No transport keys configured.","warning");const s=[De(`Transport Keys (${a.length})`),"",...a.map(e=>{const t=e.parent_id?` ${Ae(`parent: ${e.parent_id}`)}`:"";return` ${Ee(e.name)} ${Le("flood",Ie(e.flood_policy))}${t}`})];e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Nr extends ye{constructor(){super(...arguments),t(this,"name","acl"),t(this,"description","Show ACL statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("acl"),` ${Fe("Display access control list statistics.")}`,"",Be("acl","show ACL stats")].join("\n"));const r=e.write("processing...","system");try{const t=await R();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch ACL stats","error");const a=t.data,s=[De("ACL Stats"),"",` ${Le("Identities",Ie(String(a.total_identities)))}`,` ${Le("Total clients",Ie(String(a.total_clients)))}`,` ${Le("Admin",Ie(String(a.admin_clients)))}`,` ${Le("Guest",Ie(String(a.guest_clients)))}`];if(a.by_identity_type){const e=a.by_identity_type.repeater,t=a.by_identity_type.room_server;e&&s.push(` ${Le("Repeater",`${Ie(String(e.count))} ids ${Fe(`${e.clients} clients`)}`)}`),t&&s.push(` ${Le("Room Server",`${Ie(String(t.count))} ids ${Fe(`${t.clients} clients`)}`)}`)}e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Tr extends ye{constructor(){super(...arguments),t(this,"name","rooms"),t(this,"description","Show room server statistics")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("rooms"),` ${Fe("Display room server statistics and sync status.")}`,"",Be("rooms","list rooms")].join("\n"));const r=e.write("processing...","system");try{const t=await M();if(!t.success||!t.data)return void e.update(r,t.error||"Failed to fetch room stats","error");const a=t.data.rooms||[];if(0===a.length)return void e.update(r,"No room servers configured.","warning");const s=[De(`Rooms (${a.length})`),"",...a.map(e=>[` ${Ee(e.room_name)}`,` ${Le("msgs",Ie(String(e.total_messages)))} ${Le("clients",`${Ie(String(e.active_clients))}${Ae(`/${e.total_clients}`)}`)} ${Le("sync",e.sync_running?Ie("running"):Ae("idle"))}`]).flat()];e.update(r,s.join("\n"))}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class Rr extends ye{constructor(){super(...arguments),t(this,"name","restart"),t(this,"description","Restart pymc-repeater service"),t(this,"aliases",["reboot"])}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("restart"),` ${Fe("Restart the pymc-repeater systemd service.")}`,"",Be("restart","restart the service"),"",De("Aliases"),` ${Fe("reboot")}`,"",Oe("Requires polkit permissions for the web user."),Oe("The page will need a manual refresh after restart.")].join("\n"));const r=e.write("Restarting service...","system");try{const t=await J(AbortSignal.timeout(8e3));if(t.success)return e.update(r,"Service restart initiated.","success"),void(await this.waitForService(e));const a=t.status;if(403===a||401===a)return void e.update(r,"Error: Permission denied.\n\nThe web user needs polkit permissions to restart the service.\nSee: /etc/polkit-1/localauthority/50-local.d/pymc-repeater.pkla","error");e.update(r,t.error||"Restart failed","error")}catch(a){const t=a instanceof Error?a.message:"";t.includes("ERR_NETWORK")||t.includes("ECONNRESET")||t.includes("Failed to fetch")||t.includes("Load failed")||t.includes("network connection was lost")||t.includes("abort")||t.includes("timeout")||a instanceof DOMException&&"TimeoutError"===a.name||a instanceof DOMException&&"AbortError"===a.name?(e.update(r,"Service is restarting (connection dropped).","success"),await this.waitForService(e)):e.update(r,`Error: ${t||"Restart failed"}`,"error")}}waitForService(e){return new Promise(t=>{const r=e.write("Waiting for service...","system");let a=0;setTimeout(()=>{const s=setInterval(async()=>{a++,e.update(r,`Waiting for service... ${a}s`,"system");try{const n=new AbortController,o=setTimeout(()=>n.abort(),3e3);return await fetch(`${E}/api/stats`,{signal:n.signal}),clearTimeout(o),clearInterval(s),e.update(r,`Service connected. (${a+4}s)`,"success"),void t()}catch{}a>=30&&(clearInterval(s),e.update(r,"Service did not respond within 34s. Check manually.","warning"),t())},1e3)},4e3)})}}const Mr="[",Er=`${Mr}0m`,Ar=`${Mr}32m`,Ir=`${Mr}33m`,Fr=`${Mr}31m`,Lr=`${Mr}36m`,Br=`${Mr}90m`,Dr=`${Mr}1m`;function Or(e){return e>=1073741824?`${(e/1073741824).toFixed(1)}G`:e>=1048576?`${(e/1048576).toFixed(0)}M`:e>=1024?`${(e/1024).toFixed(0)}K`:`${e}B`}function Pr(e){const t=Math.floor(e/86400),r=Math.floor(e%86400/3600),a=Math.floor(e%3600/60);return t>0?`${t}d ${r}h ${a}m`:r>0?`${r}h ${a}m`:`${a}m`}function Ur(e,t){const r=" ".repeat(2),a=t-2,s=[];let n="",o=0;for(const i of e){const e=Ye(i);0===o?(n=i,o=e):o+2+e<=a?(n+=" "+i,o+=2+e):(s.push(r+n),n=i,o=e)}return o>0&&s.push(r+n),s}function Hr(e,t,r,a,s){if(!e||!t)return` ${Br}Waiting for data…${Er}`;const n=function(e,t,r){var a,s;const n=e.node_name||"unknown",o=e.version?`v${e.version}`:"",i=(null==(a=t.system)?void 0:a.uptime)?Pr(t.system.uptime):"?",c=Pr(e.uptime_seconds||0),l=Math.max(3,r-4),d=(null==(s=t.cpu.load_avg)?void 0:s["1min"].toFixed(2))??"?",u=t.cpu.load_avg?`${d} ${t.cpu.load_avg["5min"].toFixed(2)} ${t.cpu.load_avg["15min"].toFixed(2)}`:"?",p=r>=60?u:d;return[` ${Lr}${Dr}${n}${Er} ${Br}${o}${Er}`,` ${Br}${"─".repeat(l)}${Er}`,...Ur([Le("Sys",Ie(i)),Le("Svc",Ie(c)),Le("Load",Ie(p))],r)]}(e,t,a),o=function(e,t){const r=Math.max(6,Math.min(30,t-15)),a=t-(15+r)-2,s=[""],n=`${e.cpu.count} core${e.cpu.count>1?"s":""}`,o=`${Or(e.memory.used)}/${Or(e.memory.total)}`,i=`${Or(e.disk.used)}/${Or(e.disk.total)}`,c=(e,t,s)=>{const n=function(e,t){const r=Math.max(0,Math.min(100,e)),a=Math.round(r/100*t),s=t-a,n=r>=90?Fr:r>=70?Ir:Ar;return`[${n}${"█".repeat(a)}${Er}${Br}${"░".repeat(s)}${Er}] ${n}${`${r.toFixed(1)}%`.padStart(6)}${Er}`}(t,r),o=a>=s.length?` ${Ae(s)}`:"";return` ${Fe(e.padEnd(4))}${n}${o}`};s.push(c("CPU",e.cpu.usage_percent,n)),s.push(c("Mem",e.memory.usage_percent,o)),s.push(c("Dsk",e.disk.usage_percent,i));const l=Object.entries(e.temperatures||{});if(l.length>0){const e=l.map(([e,t])=>{return`${Ae(e+":")} ${r=t,r>=80?`${Fr}${Dr}${r.toFixed(1)}°C${Er}`:r>=60?`${Ir}${r.toFixed(1)}°C${Er}`:`${Ar}${r.toFixed(1)}°C${Er}`}`;var r});s.push(...Ur(e,t))}return s}(t,a),i=function(e,t){var r,a;const s=e.neighbors||{},n=Object.keys(s).length,o=Object.values(s).filter(e=>e.zero_hop).length,i=(null==(a=null==(r=e.config)?void 0:r.repeater)?void 0:a.mode)||"?",c=null!=e.noise_floor_dbm?`${e.noise_floor_dbm}dBm`:"?",l=e.duty_cycle_percent??0,d=["",` ${Br}MESH${Er}`];return d.push(...Ur([Le("Mode",Ie(i)),Le("Nbrs",`${Ie(String(o))}${Ae(`/${n}`)}`),Le("Noise",Ie(c)),Le("Air",Ie(`${l.toFixed(1)}%`))],t)),d.push(...Ur([Le("RX",Ie(String(e.rx_count??0))),Le("TX",Ie(String(e.tx_count??0))),Le("FWD",Ie(String(e.forwarded_count??0))),Le("Drop",Ie(String(e.dropped_count??0)))],t)),d.push(...Ur([Le("RX/h",Ie(String(Math.round(e.rx_per_hour??0)))),Le("FWD/h",Ie(String(Math.round(e.forwarded_per_hour??0))))],t)),d}(e,a),c=function(e,t){if(!e.network)return[];const r=["",` ${Br}NET${Er}`];return r.push(...Ur([Le("TX",Ie(Or(e.network.bytes_sent))),Le("RX",Ie(Or(e.network.bytes_recv))),Le("Pkt",`${Ie(String(e.network.packets_sent))}${Ae("/")}${Ie(String(e.network.packets_recv))}`)],t)),r}(t,a),l=["",` ${Br}${(new Date).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})} · Ctrl+C to exit${Er}`],d=[...n,...o,...i,...c,...l],u=s?Je(d,a):0,p=function(e,t,r){if(0===e.length)return[];const a=t>=50,s=t>=50?6:5,n=t>=50?6:5,o=a?7:0,i=Math.max(4,t-2-o-s-n-4),c=t>=50?8:5,l=null!=r?Math.max(0,Math.min(c,r-3)):c;if(l<=0)return[];const d=["",` ${Br}PROCS${Er}`],u=(a?"PID".padEnd(o):"")+"CPU".padStart(s)+"MEM".padStart(n)+" NAME";d.push(` ${Ae(u)}`);for(const p of e.slice(0,l)){const e=a?Ae(String(p.pid).padEnd(o)):"",r=(t>=50?p.cpu_percent.toFixed(1):p.cpu_percent.toFixed(0)).padStart(s),c=(t>=50?p.memory_percent.toFixed(1):p.memory_percent.toFixed(0)).padStart(n),l=p.name.length>i?p.name.slice(0,i-1)+"…":p.name,u=p.cpu_percent>=50?Fr:p.cpu_percent>=20?Ir:"",m=u?`${u}${r}${Er}`:r;d.push(` ${e}${m}${Ae(c)} ${l}`)}return d}(r,a,s?Math.max(0,s-u):void 0),m=[...d.slice(0,-l.length),...p,...l];return s&&m.length>s&&(m.length=s),m.join("\n")}class zr extends ye{constructor(){super(...arguments),t(this,"name","top"),t(this,"description","Live system overview (Ctrl+C to exit)"),t(this,"aliases",["htop"])}async execute({output:e,rawInput:t,cols:r,signal:a}){var s,n;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("top"),` ${Fe("Live-updating system overview combining hardware")}`,` ${Fe("stats, mesh metrics, and running processes.")}`,` ${Fe("Refreshes every 3s. Press Ctrl+C to exit.")}`,"",Be("top","start live display"),"",De("Sections"),` ${Fe("Header Node name, version, uptime, load average")}`,` ${Fe("Gauges CPU, memory, disk usage with bar charts")}`,` ${Fe("Mesh Mode, neighbors, packet counts, airtime")}`,` ${Fe("Network TCP/IP bytes and packet counters")}`,` ${Fe("Processes Top 8 processes by CPU usage")}`,"",De("Aliases"),` ${Fe("htop")}`].join("\n"));let o=null,i=[],c=N.getState().stats;try{const[e,t]=await Promise.all([f(),A()]);e.success&&e.data&&(o=e.data),t.success&&t.data&&(i=t.data.processes.sort((e,t)=>t.cpu_percent-e.cpu_percent))}catch{}if(!a.aborted){null==(s=e.enterFullscreen)||s.call(e);try{const t=e.write(Hr(c,o,i,e.cols??r,e.rows));await new Promise(s=>{if(a.aborted)return void s();const n=setInterval(()=>{if(a.aborted)return clearInterval(n),void s();(async()=>{c=N.getState().stats;try{const[e,t]=await Promise.all([f(),A()]);e.success&&e.data&&(o=e.data),t.success&&t.data&&(i=t.data.processes.sort((e,t)=>t.cpu_percent-e.cpu_percent))}catch{}a.aborted||e.update(t,Hr(c,o,i,e.cols??r,e.rows))})()},3e3);a.addEventListener("abort",()=>{clearInterval(n),s()},{once:!0})})}finally{null==(n=e.exitFullscreen)||n.call(e)}}}}const qr=["DONT PANIC","C0FFEE","FEED C0DE","LOL","I CANNOT DO THAT"];function Kr(){return qr[Math.floor(Math.random()*qr.length)]}const Wr=new EventTarget,Gr="shell-phrase";function Xr(e){Wr.dispatchEvent(new CustomEvent(Gr,{detail:e??Kr()}))}class Vr extends ye{constructor(){super(...arguments),t(this,"name","fortune"),t(this,"description","Display a fortune on the header"),t(this,"aliases",["lol"])}execute({output:e}){const t=Kr();Xr(t),e.write(Fe(` ${t}`))}}const Yr=new EventTarget,Jr="party-time";class Qr extends ye{constructor(){super(...arguments),t(this,"name","partytime"),t(this,"description","Party on, Garth!"),t(this,"aliases",["party","excellent","waynesworld"])}execute({output:e}){Yr.dispatchEvent(new Event(Jr)),Xr("PARTY 0N GARTH"),e.write(Fe(" SCHWING!"))}}class Zr extends ye{constructor(){super(...arguments),t(this,"name","ver"),t(this,"description","Show version info"),t(this,"aliases",["version"])}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("ver"),` ${Fe("Display pyMC_Repeater, core, and console version.")}`,` ${Fe('Equivalent to firmware serial CLI "ver" command.')}`,"",Be("ver","show version"),"",De("Aliases"),` ${Fe("version")}`].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a="0.9.286";e.update(r,[` ${Le("pyMC_Repeater",Ie(`v${t.version||"?"}`))}`,` ${Le("pyMC_Core",Ie(t.core_version||"?"))}`,` ${Le("pyMC_Console",Ie(`v${a}`))}`].join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}class ea extends ye{constructor(){super(...arguments),t(this,"name","clock"),t(this,"description","Show system UTC time")}execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("clock"),` ${Fe("Display the current system UTC time.")}`,` ${Fe('Equivalent to firmware serial CLI "clock" command.')}`,` ${Fe("Use to verify NTP sync and correlate packet timestamps.")}`,"",Be("clock","show UTC time")].join("\n"));const r=new Date;e.write([` ${Le("UTC",Ie(r.toUTCString()))}`,` ${Le("ISO",Ie(r.toISOString()))}`,` ${Le("Unix",Ie(String(Math.floor(r.getTime()/1e3))))}`].join("\n"),"value")}}class ta extends ye{constructor(){super(...arguments),t(this,"name","stats-packets"),t(this,"description","Packet counters")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-packets"),` ${Fe("Display packet counters: sent, received, forwarded, dropped.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-packets" command.')}`,"",Be("stats-packets","show packet counters")].join("\n"));const r=e.write("processing...","system");try{const t=await g(),a=t.rx_count??0,s=t.tx_count??0,n=t.forwarded_count??0,o=t.dropped_count??0,i=t.rx_per_hour??0,c=t.forwarded_per_hour??0,l=t.duplicate_cache_size??0;e.update(r,[` ${Ee("Packet Counters")}`,"",` ${Le("RX",Ie(String(a)))} ${Fe(`${i.toFixed(1)}/hr`)}`,` ${Le("TX",Ie(String(s)))}`,` ${Le("Forwarded",Ie(String(n)))} ${Fe(`${c.toFixed(1)}/hr`)}`,` ${Le("Dropped",Ie(String(o)))}`,"",` ${Le("Dup cache",Ie(String(l)))}`].join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}function ra(e){return e>=6e4?`${(e/6e4).toFixed(1)}m`:e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e.toFixed(0)}ms`}class aa extends ye{constructor(){super(...arguments),t(this,"name","stats-radio"),t(this,"description","Radio health stats")}async execute({output:e,rawInput:t}){var r;if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-radio"),` ${Fe("Display radio health: airtime, noise floor, duty cycle.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-radio" command.')}`,"",Be("stats-radio","show radio stats")].join("\n"));const a=e.write("processing...","system");try{const t=await g(),s=null==(r=t.config)?void 0:r.radio,n=t.noise_floor_dbm,o=t.airtime_used_ms??0,i=t.airtime_remaining_ms??0,c=t.duty_cycle_percent??0,l=t.utilization_percent??0,d=t.total_airtime_ms??0,u=[` ${Ee("Radio Stats")}`,""];if(s){const e=s.frequency?`${(s.frequency/1e6).toFixed(3)} MHz`:"?",t=s.bandwidth?s.bandwidth/1e3+" kHz":"?";u.push(` ${Le("Radio",Ie(`${e} SF${s.spreading_factor??"?"} BW ${t} CR 4/${s.coding_rate??"?"} ${s.tx_power??"?"} dBm`))}`),u.push("")}u.push(` ${Le("Noise floor",null!=n?Ie(`${n} dBm`):Fe("N/A"))}`),u.push(` ${Le("Airtime used",Ie(ra(o)))} ${Fe(`remaining: ${ra(i)}`)}`),u.push(` ${Le("Total airtime",Ie(ra(d)))}`),u.push(` ${Le("Duty cycle",Ie(`${c.toFixed(1)}%`))}`),u.push(` ${Le("Utilization",Ie(`${l.toFixed(1)}%`))}`),e.update(a,u.join("\n"),"value")}catch(s){e.update(a,`Error: ${s instanceof Error?s.message:"Command failed"}`,"error")}}}function sa(e){return e>=1073741824?`${(e/1073741824).toFixed(1)} GB`:e>=1048576?`${(e/1048576).toFixed(0)} MB`:`${(e/1024).toFixed(0)} KB`}class na extends ye{constructor(){super(...arguments),t(this,"name","stats-core"),t(this,"description","Engine vitals")}async execute({output:e,rawInput:t}){if("help"===this.argsAfterName(t).toLowerCase().trim())return void e.write([De("stats-core"),` ${Fe("Display engine vitals: uptime, memory, CPU, queue depth.")}`,` ${Fe('Equivalent to firmware serial CLI "stats-core" command.')}`,` ${Fe("On firmware this shows free heap — here we show Linux process health.")}`,"",Be("stats-core","show core stats")].join("\n"));const r=e.write("processing...","system");try{const[t,a]=await Promise.all([g(),f()]),s=[` ${Ee("Core Stats")}`,"",` ${Le("Uptime",Ie(xt(t.uptime_seconds??0)))}`,` ${Le("Dup cache",Ie(`${t.duplicate_cache_size??0} entries`))} ${Fe(`TTL ${t.cache_ttl??"?"}s`)}`];if(a.success&&a.data){const e=a.data;s.push(""),s.push(` ${Le("CPU",Ie(`${e.cpu.usage_percent.toFixed(1)}%`))} ${Fe(`${e.cpu.count} core${e.cpu.count>1?"s":""}`)}`),e.cpu.load_avg&&s.push(` ${Le("Load",Ie(`${e.cpu.load_avg["1min"].toFixed(2)} / ${e.cpu.load_avg["5min"].toFixed(2)} / ${e.cpu.load_avg["15min"].toFixed(2)}`))}`),s.push(` ${Le("Memory",Ie(`${sa(e.memory.used)} / ${sa(e.memory.total)}`))} ${Fe(`${e.memory.usage_percent.toFixed(0)}%`)}`);const t=Object.entries(e.temperatures||{});t.length>0&&s.push(` ${Le("Temp",Ie(`${t[0][1].toFixed(1)}°C`))}`)}e.update(r,s.join("\n"),"value")}catch(a){e.update(r,`Error: ${a instanceof Error?a.message:"Command failed"}`,"error")}}}const oa=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "],ia=te-1;class ca extends ye{constructor(){super(...arguments),t(this,"name","hello"),t(this,"description","Play the PYMC burst intro"),t(this,"aliases",["hi","intro"])}async execute({output:e,signal:t}){if(t.aborted)return;let r=0;const a=e.write(Q(oa,0).join("\n"));try{await new Promise(s=>{const n=setInterval(()=>{if(t.aborted||r>=ia)return clearInterval(n),t.aborted||e.update(a,Q(oa,ia).join("\n")),void s();r++,e.update(a,Q(oa,r).join("\n"))},Z);t.addEventListener("abort",()=>{clearInterval(n),s()},{once:!0})})}finally{ee()}}}const la=i(e=>({entries:[],commandHistory:[],isInitialized:!1,addEntry:t=>{const r="undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),a={...t,id:r,timestamp:Date.now()};return e(e=>({entries:[...e.entries,a]})),r},updateEntry:(t,r)=>{e(e=>({entries:e.entries.map(e=>e.id===t?{...e,...r}:e)}))},addCommand:t=>{e(e=>({commandHistory:[...e.commandHistory,t]}))},clearEntries:()=>{e({entries:[],commandHistory:[]})},setInitialized:t=>{e({isInitialized:t})}}));function da({isOpen:e,onClose:t}){const a=fr(),s=N(e=>e.stats);return r.jsxs(I,{open:e,onClose:t,size:"sm",children:[r.jsx(F,{icon:r.jsx(ie,{size:20}),title:"Download Captures",onClose:t}),r.jsx(L,{className:"flex flex-col gap-2",children:0===a.length?r.jsxs("div",{className:"flex flex-col items-center gap-2 py-6 text-fg-muted",children:[r.jsx(ce,{className:"w-8 h-8 opacity-40"}),r.jsx("p",{className:"text-sm",children:"No captures available."})]}):a.map(e=>r.jsxs("div",{className:"flex items-center gap-3 px-4 py-3 radius-inset bg-elevated/50 border border-edge-subtle",children:[r.jsxs("div",{className:"flex-1 min-w-0",children:[r.jsx("p",{className:"type-label text-fg-primary truncate",children:e.filename}),r.jsxs("p",{className:"text-xs text-fg-muted mt-0.5",children:[e.packetCount," packets · ",e.durationSec,"s · ~",kr(e.sizeBytes)]})]}),r.jsx(B,{plain:!0,color:"primary",onClick:()=>(e=>{const t=a.find(t=>t.id===e);t&&_r(t,s)})(e.id),title:"Download",className:"flex-shrink-0",children:r.jsx(ie,{"data-slot":"icon"})})]},e.id))})]})}function ua(){const e=fr(),[t,s]=a.useState(!1);return r.jsxs(r.Fragment,{children:[r.jsx(ne,{icon:r.jsx(le,{size:20}),onClick:()=>s(!0),title:e.length>0?`Download captures (${e.length})`:"Captures",variant:"red",iconActiveColor:m.red}),r.jsx(da,{isOpen:t,onClose:()=>s(!1)})]})}const pa=[{name:"acl",description:"Access control list statistics — identity and client counts.",body:["```","> acl","ACL Stats",""," Identities 2"," Total clients 5"," Admin 2"," Guest 3"," Repeater 1 ids 3 clients"," Room Server 1 ids 2 clients","```"],searchText:"acl access control list statistics identity client"},{name:"advert",description:"Broadcast a repeater advertisement to the mesh.",body:["```","> advert","✓ Advert sent","```"],searchText:"advert advertisement broadcast mesh"},{name:"board",description:"Hardware and platform info — CPU, memory, disk, temperatures, network I/O.",body:["```","> board"," Node Local-Node"," Runtime pyMC_Repeater v1.0.0"," Core v1.12.0",""," CPU 12.3% 4 cores"," Load 0.42 / 0.38 / 0.35"," Temp 48.2°C",""," Memory 412 MB / 664 MB 62%"," Disk 5.2 GB / 28.7 GB 18%",""," System uptime 14d 3h 22m"," Service uptime 2d 14h 32m"," Net TX/RX 128 MB / 342 MB","```"],searchText:"board hardware platform cpu memory disk temperature network"},{name:"cap",description:"Packet capture — start, stop, list, and export captures.",body:["**Sub-commands:** `start cap [sec]` · `end cap` · `list cap` · `export cap [id]`","","**`start cap [seconds]`** — Begin capture (default 120s, max 3600):","```","> start cap","Capturing... 118s remaining (4 captured)","","✓ Capture complete!"," Captured: 23 packets"," Duration: 120s"," Size: ~14.2 KB","```","","**`end cap`** — Stop capture early:","```","> end cap","✓ Capture stopped!"," Captured: 12 packets","```","","**`list cap`** — List saved captures:","```","> list cap","Capture Reports (2):"," 1. 23 pkts • 120s • ~14.2 KB (id: abc123)"," 2. 12 pkts • 34s • ~7.1 KB (id: def456)","```","","**`export cap [id]`** — Download by ID or index:","```","> export cap 1","✓ Downloading capture-abc123.json...","```"],searchText:"cap capture packet start end list export download diagnostic"},{name:"clear",description:"Clear the terminal screen.",body:["**Alias:** `cls`","```","> clear","```"],searchText:"clear cls screen"},{name:"clock",description:"Current system UTC time. Useful for NTP sync and packet timestamp correlation.",body:["```","> clock"," UTC Wed, 12 Feb 2026 00:01:34 GMT"," ISO 2026-02-12T00:01:34.000Z"," Unix 1770768094","```"],searchText:"clock time utc ntp unix iso timestamp"},{name:"convert",description:"Convert between hex and base64 encodings.",body:["**Usage:** `convert hex ` · `convert base64 `","```","> convert hex 48656C6C6F"," hex 48656C6C6F"," base64 SGVsbG8=","","> convert base64 SGVsbG8="," base64 SGVsbG8="," hex 48656C6C6F","```"],searchText:"convert hex base64 encoding decode"},{name:"get",description:"Read a configuration parameter.",body:[],interactive:"get",searchText:"get read config parameter name role lat lon radio freq tx bw sf cr txdelay mode duty flood advert"},{name:"help",description:"Show all commands, or detailed help for a specific command.",body:["**Alias:** `?` · `h`","```","> help Full command listing","> help ping Detailed help for ping","> ping help Same thing","```"],searchText:"help commands reference guide"},{name:"identities",description:"List all configured repeater and room server identities.",body:["**Alias:** `id` · `ids`","```","> identities","Identities (2)",""," 1. Local-Node repeater 0A1B2C3D"," 2. local-room room_server 0E5F6A7B","```"],searchText:"identities id ids repeater room server identity"},{name:"keys",description:"List configured transport encryption keys.",body:["```","> keys","Transport Keys (1)",""," main-transport flood: allow","```"],searchText:"keys transport encryption"},{name:"neighbors",description:"Direct RF neighbors with signal quality, RSSI, SNR, distance, and last-heard.",body:["**Alias:** `nb`","","**Sort qualifiers:** `sig` · `name` · `rssi` · `snr` · `dist` · `heard`","```","> neighbors","Direct Neighbors (4)","","+-------+-----------+-----------+--------+-------+--------+","| ▁▃▅▇█ | Node-1 | -87 dBm | 8.5 dB | 2.1km | 3m ago |","| ▁▃▅▇. | Relay-2 | -94 dBm | 5.2 dB | 4.8km | 1m ago |","| ▁▃▅.. | Node-3 | -108 dBm | 1.0 dB | 8.3km | 5m ago |","| ▁▃... | Node-4 | -118 dBm | -3 dB | 14km | 12m ago|","+-------+-----------+-----------+--------+-------+--------+","| SIG | NAME | RSSI | SNR | DIST | HEARD |","+-------+-----------+-----------+--------+-------+--------+","SF11/250kHz ant 3.5dBi nf -112dBm","```","","- **sig** — signal grade (weakest first)","- **name** — alphabetical","- **rssi** — RSSI (weakest first)","- **snr** — SNR (lowest first)","- **dist** — distance (closest first)","- **heard** — last seen (oldest first)"],searchText:"neighbors nb signal rssi snr distance sort direct rf"},{name:"packets",description:"Packet counters — received, transmitted, forwarded, dropped.",body:["```","> packets","Packet Stats 1321 total",""," Received 1284"," Transmitted 37"," Forwarded 891"," Dropped 14","```"],searchText:"packets received transmitted forwarded dropped counter"},{name:"ping",description:"Ping a neighbor by name or hex prefix. Shows RTT, signal quality, and path.",body:["**Usage:** `ping [timeout]`","```","> ping Node-1","▁▃▅▇█ Reply from Node-1",""," RTT 342ms"," RSSI -87 dBm"," SNR 8.5 dB"," Path direct"," Quality Excellent","```","","Custom timeout (default 30s):","```","> ping Node-4 60","```"],searchText:"ping rtt round trip time signal quality path neighbor"},{name:"restart",description:"Restart the pymc-repeater systemd service.",body:["**Alias:** `reboot`","```","> restart","Service is restarting (connection dropped).","Waiting for service... 8s","Service connected. (12s)","```","","The terminal polls automatically until the service comes back up."],searchText:"restart reboot service systemd"},{name:"rooms",description:"Room server statistics — message counts, active clients, sync status.",body:["```","> rooms","Rooms (1)",""," Local Room"," msgs 142 clients 3/5 sync running","```"],searchText:"rooms room server messages clients sync"},{name:"set",description:"Write a configuration parameter.",body:[],interactive:"set",searchText:"set write config parameter name lat lon freq tx bw sf cr txdelay mode duty log flood advert"},{name:"stats-core",description:"Engine vitals — uptime, duplicate cache, CPU, memory, temperature.",body:["```","> stats-core"," Core Stats",""," Uptime 2d 14h 32m"," Dup cache 128 entries TTL 900s",""," CPU 12.3% 4 cores"," Load 0.42 / 0.38 / 0.35"," Memory 412 MB / 664 MB 62%"," Temp 48.2°C","```"],searchText:"stats core engine vitals uptime cache cpu memory temperature"},{name:"stats-packets",description:"Firmware-compatible packet counters with rates and duplicate cache depth.",body:["```","> stats-packets"," Packet Counters",""," RX 1284 22.4/hr"," TX 37"," Forwarded 891 15.2/hr"," Dropped 14",""," Dup cache 128","```"],searchText:"stats packets firmware counter rate duplicate cache"},{name:"stats-radio",description:"Radio health — noise floor, airtime, duty cycle, and radio configuration.",body:["```","> stats-radio"," Radio Stats",""," Radio 906.875 MHz SF11 BW 250 kHz CR 4/5 22 dBm",""," Noise floor -112 dBm"," Airtime used 4.2s remaining: 55.8m"," Total airtime 1.2m"," Duty cycle 1.2%"," Utilization 0.8%","```"],searchText:"stats radio noise floor airtime duty cycle utilization"},{name:"status",description:"Quick summary of mode, neighbors, and uptime.",body:["**Alias:** `st`","```","> status","Local-Node repeater",""," Mode forward"," Neighbors 4 direct 12 total"," RX / TX 1284 / 37"," Uptime 2d 14h 32m","```"],searchText:"status st summary mode neighbors uptime"},{name:"top",description:"Live-updating system overview — CPU/memory gauges, mesh counters, processes.",body:["**Alias:** `htop`","","Refreshes every 3s. Press **Ctrl+C** to exit.","```","> top","Local-Node v1.0.0","──────────────────────────────────"," Sys 14d 3h 22m Svc 2d 14h 32m Load 0.42 0.38 0.35",""," CPU [████░░░░░░░░░░░░] 12.3% 4 cores"," Mem [██████████░░░░░░] 62.1% 412M/664M"," Dsk [███░░░░░░░░░░░░░] 18.4% 5.2G/28.7G"," cpu_thermal: 48.2°C",""," MESH"," Mode forward Nbrs 4/12 Noise -112dBm Air 1.2%"," RX 1284 TX 37 FWD 891 Drop 14"," RX/h 22 FWD/h 15",""," PROCS"," CPU MEM NAME"," 8.2 3.1 python3"," 2.1 1.4 cherrypy",""," 14:32:08 · Ctrl+C to exit","```","","Uses alternate screen buffer — scrollback is preserved."],searchText:"top htop live system overview cpu memory gauges mesh processes"},{name:"uptime",description:"How long the repeater service has been running.",body:["```","> uptime","Uptime 2d 14h 32m","```"],searchText:"uptime service running duration"},{name:"ver",description:"Version info for all three components.",body:["**Alias:** `version`","```","> ver"," pyMC_Repeater v1.0.0"," pyMC_Core v1.12.0"," pyMC_Console v1.0.0","```"],searchText:"ver version pymc repeater core console"}],ma=[{param:"name",category:"Identity",example:["> get name","name Local-Node"]},{param:"role",category:"Identity",example:["> get role","role repeater"]},{param:"lat",category:"Identity",example:["> get lat","lat 34.0522"],range:"-90 to 90"},{param:"lon",category:"Identity",example:["> get lon","lon -118.2437"],range:"-180 to 180"},{param:"public.key",category:"Identity",example:["> get public.key","public.key 0A1B2C3D4E5F..."]},{param:"radio",category:"Radio",example:["> get radio"," freq 906.875 MHz"," bw 250 kHz"," sf 11"," cr 4/5"," tx 22 dBm"]},{param:"freq",category:"Radio",example:["> get freq","freq 906.875 MHz"],range:"100–1000 MHz"},{param:"tx",category:"Radio",example:["> get tx","tx 22 dBm"],range:"2–22 dBm"},{param:"bw",category:"Radio",example:["> get bw","bw 250 kHz"],range:"7.8–500 kHz"},{param:"sf",category:"Radio",example:["> get sf","sf 11"],range:"5–12"},{param:"cr",category:"Radio",example:["> get cr","cr 4/5"],range:"5–8"},{param:"af",category:"Timing",example:["> get af","⚠ airtime_factor not yet exposed by pyMC_Repeater API."," Firmware range: 0-9. Tracked in CLI-Alignment.md."],range:"0–9 (pending)"},{param:"txdelay",category:"Timing",example:["> get txdelay","txdelay 1.0"],range:"0.0–5.0"},{param:"direct.txdelay",category:"Timing",example:["> get direct.txdelay","direct.txdelay 0.5"],range:"0.0–5.0"},{param:"rxdelay",category:"Timing",example:["> get rxdelay","rxdelay 0.0"],range:"≥ 0"},{param:"mode",category:"Repeater",example:["> get mode","mode forward"],range:"forward / monitor"},{param:"duty",category:"Repeater",example:["> get duty","duty on"],range:"on / off"},{param:"flood.max",category:"Repeater",example:["> get flood.max","flood.max 3"],range:"0–64"},{param:"advert.interval",category:"Repeater",example:["> get advert.interval","advert.interval 120m"],range:"0 (off) or 1–10080 min"},{param:"multi.acks",category:"Advanced",example:["> get multi.acks","multi.acks 0"],range:"0–255"},{param:"int.thresh",category:"Advanced",example:["> get int.thresh","int.thresh -120 dBm"],range:"-200 to 0 dBm"},{param:"agc.reset.interval",category:"Advanced",example:["> get agc.reset.interval","agc.reset.interval 0"],range:"≥ 0 (×4)"}],ha=[{param:"name",category:"Identity",example:["> set name Local-Node","OK - node_name set to Local-Node"],range:"text (no [ ] \\ / : , ? *)"},{param:"lat",category:"Identity",example:["> set lat 34.0522","OK - latitude set to 34.0522"],range:"-90 to 90"},{param:"lon",category:"Identity",example:["> set lon -118.2437","OK - longitude set to -118.2437"],range:"-180 to 180"},{param:"freq",category:"Radio",example:["> set freq 906.875","OK - frequency set to 906875000"],range:"100–1000 MHz"},{param:"tx",category:"Radio",example:["> set tx 22","OK - tx_power set to 22"],range:"2–22 dBm"},{param:"bw",category:"Radio",example:["> set bw 250","OK - bandwidth set to 250000"],range:"7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250, 500 kHz"},{param:"sf",category:"Radio",example:["> set sf 11","OK - spreading_factor set to 11"],range:"5–12"},{param:"cr",category:"Radio",example:["> set cr 5","OK - coding_rate set to 5"],range:"5–8"},{param:"af",category:"Timing",example:["> set af 2","⚠ airtime_factor not yet exposed by pyMC_Repeater API."," Firmware range: 0-9. Needs backend support."],range:"0–9 (pending)"},{param:"txdelay",category:"Timing",example:["> set txdelay 1.0","OK - tx_delay_factor set to 1"],range:"0.0–5.0"},{param:"direct.txdelay",category:"Timing",example:["> set direct.txdelay 0.5","OK - direct_tx_delay_factor set to 0.5"],range:"0.0–5.0"},{param:"rxdelay",category:"Timing",example:["> set rxdelay 0","OK - rx_delay_base set to 0"],range:"≥ 0"},{param:"mode",category:"Repeater",example:["> set mode forward","OK - Mode set to forward"],range:"forward / monitor"},{param:"flood.max",category:"Repeater",example:["> set flood.max 3","OK - max_flood_hops set to 3"],range:"0–64"},{param:"advert.interval",category:"Repeater",example:["> set advert.interval 120","OK - Local advert interval set to 120m"],range:"0 (off) or 1–10080 min"},{param:"duty",category:"Repeater",example:["> set duty on","OK - Duty cycle enabled"],range:"on / off"},{param:"log",category:"Repeater",example:["> set log info","OK - Log level set to INFO"],range:"debug, info, warning, error"},{param:"multi.acks",category:"Advanced",example:["> set multi.acks 0","OK - multi_acks set to 0"],range:"0–255"},{param:"int.thresh",category:"Advanced",example:["> set int.thresh -120","OK - interference_threshold set to -120"],range:"-200 to 0 dBm"},{param:"agc.reset.interval",category:"Advanced",example:["> set agc.reset.interval 8","OK - AGC reset interval set to 8"],range:"≥ 0 (rounded to ×4)"},{param:"prv.key",category:"Advanced",example:["> set prv.key <128-hex>","To set this key, run on the Pi:",""," sudo ./convert_firmware_key.sh ","","Then restart: sudo systemctl restart pymc-repeater"],range:"128-char hex (SSH only)"}];function ga({mode:e}){const t="get"===e?ma:ha,[s,n]=a.useState(0),o=t[s],i=a.useMemo(()=>{const e=new Map;for(const r of t){const t=e.get(r.category)||[];t.push(r),e.set(r.category,t)}return Array.from(e.entries())},[t]);return r.jsxs("div",{className:"flex flex-col gap-2",children:[r.jsx("div",{className:"flex flex-col gap-1.5",children:i.map(([e,a])=>r.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[r.jsx("span",{className:"text-xs text-fg-muted w-16 shrink-0 text-right pr-1",children:e}),a.map(e=>{const a=t.indexOf(e),o=a===s;return r.jsx("button",{onClick:()=>n(a),className:c("px-1.5 py-0.5 type-data-xs radius-badge transition-colors cursor-pointer",o?"bg-sys-blue text-fg-invert font-semibold":"bg-elevated text-fg-secondary hover:bg-elevated/80 hover:text-sys-blue"),children:e.param},e.param)})]},e))}),r.jsx("pre",{className:"px-3 py-2.5 radius-inner bg-body text-fg-secondary type-code overflow-x-auto border border-edge-subtle",children:o.example.map((e,t)=>r.jsx("div",{children:e||" "},t))}),o.range&&r.jsxs("p",{className:"text-xs text-fg-muted",children:[r.jsx("span",{className:"text-fg-secondary font-medium",children:o.param})," — ",o.range]})]})}function fa(e,t){const a=e.split(/(\*\*[^*]+\*\*)/g);return r.jsx("span",{children:a.map((e,t)=>e.startsWith("**")&&e.endsWith("**")?r.jsx("strong",{className:"text-fg-primary font-semibold",children:e.slice(2,-2)},t):e.split(/(`[^`]+`)/g).map((e,a)=>e.startsWith("`")&&e.endsWith("`")?r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue type-data-xs",children:e.slice(1,-1)},`${t}-${a}`):r.jsx("span",{children:e},`${t}-${a}`)))},t)}function ya({lines:e}){const t=[];let a=0;for(;ar.jsx("div",{children:e||" "},t))},t.length));continue}s.trim()?s.startsWith("- ")?(t.push(r.jsxs("div",{className:"flex gap-2 text-sm text-fg-secondary pl-2 py-0.5",children:[r.jsx("span",{className:"text-fg-muted shrink-0",children:"•"}),r.jsx("span",{children:fa(s.slice(2),0)})]},t.length)),a++):(t.push(r.jsx("p",{className:"text-sm text-fg-secondary py-0.5",children:fa(s,0)},t.length)),a++):(t.push(r.jsx("div",{className:"h-1.5"},t.length)),a++)}return r.jsx(r.Fragment,{children:t})}function xa({isOpen:e,onClose:t,onUseCommand:i}){const[l,d]=a.useState(""),u=a.useMemo(()=>{if(!l.trim())return pa;const e=l.toLowerCase();return pa.filter(t=>t.name.includes(e)||t.searchText.includes(e)||t.description.toLowerCase().includes(e))},[l]),p=l.trim().length>0;return r.jsxs(I,{open:e,onClose:t,size:"3xl",motionPlus:!0,className:"sm:min-w-[540px] md:min-w-[680px]",children:[r.jsx(F,{icon:r.jsx(de,{size:20}),title:"Terminal Command Guide",onClose:t}),r.jsxs(L,{className:"flex flex-col gap-0 !px-0 !py-0",children:[r.jsx("div",{className:"sticky top-0 z-10 px-5 py-3 border-b border-edge-subtle bg-surface/95 backdrop-blur-sm",children:r.jsxs("div",{className:"relative",children:[r.jsx(ue,{size:14,className:"absolute left-2.5 top-1/2 -translate-y-1/2 text-fg-muted"}),r.jsx("input",{type:"text",value:l,onChange:e=>d(e.target.value),placeholder:"Search commands...",className:"w-full pl-8 pr-3 py-1.5 text-sm bg-elevated border border-edge-subtle radius-inner text-fg-primary placeholder:text-fg-muted focus:outline-none focus:ring-1 focus:ring-sys-blue/50",autoFocus:!0})]})}),r.jsxs("div",{className:"overflow-y-auto px-5 py-3 h-[420px] sm:h-[520px] md:h-[600px]",children:[r.jsx(he,{mode:"popLayout",children:0===u.length?r.jsxs(ge.div,{initial:{opacity:0,scale:.96},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.96},transition:{duration:O.normal,ease:D.easeOut},className:"flex flex-col items-center gap-2 py-10 text-fg-muted",children:[r.jsx(ue,{className:"w-6 h-6 opacity-40"}),r.jsxs("p",{className:"text-sm",children:['No commands match "',l,'"']})]},"empty"):r.jsx(ge.div,{initial:!1,className:"flex flex-col gap-1",children:r.jsx(he,{initial:!1,children:u.map(e=>r.jsx(ge.div,{layout:"position",initial:{opacity:0,y:-4},animate:{opacity:1,y:0},exit:{opacity:0,y:-4},transition:P.fade,className:"min-w-0",children:r.jsx(s,{children:({open:t})=>r.jsxs("div",{className:c("radius-inner border transition-colors",t?"border-edge-subtle bg-elevated/50":"border-transparent hover:bg-elevated/30"),children:[r.jsxs("div",{className:"flex items-center w-full min-w-0",children:[r.jsxs(n,{className:"flex items-center gap-3 flex-1 min-w-0 px-3 py-2 text-left cursor-pointer",children:[r.jsx(pe,{size:14,className:c("shrink-0 text-fg-muted transition-transform duration-150",t&&"rotate-90")}),r.jsx("code",{className:"text-sm font-semibold text-sys-blue font-mono shrink-0",children:e.name}),r.jsx("span",{className:"text-xs text-fg-muted truncate min-w-0",children:e.description})]}),i&&r.jsx("button",{onClick:t=>{t.stopPropagation(),i(e.name)},className:"shrink-0 mr-2 px-2 py-0.5 text-xs font-semibold uppercase tracking-wider radius-badge bg-elevated text-fg-muted hover:text-sys-blue hover:bg-elevated/80 transition-colors cursor-pointer",title:`Use "${e.name}" in terminal`,children:"use"})]}),r.jsx(o,{className:"px-3 pb-3 pt-0 pl-9",children:e.interactive?r.jsx(ga,{mode:e.interactive}):r.jsx(ya,{lines:e.body})})]})})},e.name))})},"list")}),r.jsx(he,{children:!p&&r.jsxs(ge.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},exit:{opacity:0,y:6},transition:{duration:O.normal,ease:D.easeOut},className:"mt-4 px-3 py-3 radius-inner border border-edge-subtle bg-elevated/30",children:[r.jsx("p",{className:"text-xs font-semibold text-fg-muted mb-2",children:"Tips"}),r.jsxs("div",{className:"flex flex-col gap-1 text-xs text-fg-muted",children:[r.jsxs("p",{children:["Type ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:" help"})," in the terminal for detailed usage."]}),r.jsxs("p",{children:["Most commands have shorter aliases (e.g. ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"st"}),", ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"nb"}),", ",r.jsx("code",{className:"px-1 py-0.5 radius-badge bg-elevated text-sys-blue font-mono",children:"id"}),")."]}),r.jsxs("p",{children:["Signal bars ",r.jsx("span",{className:"font-mono",children:"▁▃▅▇█"})," are colored by link quality grade based on RSSI, SNR, and radio config."]}),r.jsx("p",{children:"Captures are stored in browser session only — export before closing the tab."})]})]})})]})]})]})}function va({onUseCommand:e}){const[t,s]=a.useState(!1),n=e?t=>{s(!1),e(t)}:void 0;return r.jsxs(r.Fragment,{children:[r.jsx(ne,{icon:r.jsx(de,{size:17,className:"translate-y-px"}),onClick:()=>s(!0),title:"CLI Command Guide"}),r.jsx(xa,{isOpen:t,onClose:()=>s(!1),onUseCommand:n})]})}const $a=function(){const e=new fe,t=new ft(e);return e.register(t,new yt,new vt,new Zr,new ea,new $t,new bt,new kt,new ta,new aa,new na,new qt,new er,new ur,new tr,new rr,new pr,new Cr,new Sr,new jr,new Nr,new Tr,new Rr,new zr,new Vr,new Qr,new ca),e}(),ba=$a.all().flatMap(e=>[{cmd:e.name,desc:e.description,params:e.params,required:!!e.params},...e.aliases.filter(e=>e.includes(" ")).map(t=>({cmd:t,desc:e.description,params:e.params,required:!!e.params}))]);ba.push({cmd:"start cap",desc:"Start packet capture",params:"[seconds]",required:!0},{cmd:"end cap",desc:"Stop capture"},{cmd:"list cap",desc:"List captures"},{cmd:"export cap",desc:"Download capture",params:"[id]",required:!0});const wa=["sig","name","rssi","snr","dist","heard"],_a={get:["name","role","lat","lon","radio","freq","tx","bw","sf","cr","af","txdelay","direct.txdelay","rxdelay","mode","repeat","flood.max","flood.advert.interval","advert.interval","duty","duty.max","multi.acks","int.thresh","agc.reset.interval","public.key","prv.key"],set:["name","lat","lon","freq","tx","bw","sf","cr","af","txdelay","direct.txdelay","rxdelay","mode","repeat","flood.max","flood.advert.interval","advert.interval","duty","log","multi.acks","int.thresh","agc.reset.interval","prv.key"],convert:["hex","base64"],neighbors:wa,nb:wa,"get neighbors":wa,"get neighbor":wa,"set mode":["forward","monitor"],"set duty":["on","off"],"set repeat":["on","off"],"set tx":["10","14","17","20","22"],"set sf":["7","8","9","10","11","12"],"set bw":["125","250","500"],"set cr":["5","6","7","8"],"set af":["0.5","1.0","1.5","2.0"],"set txdelay":["0.5","0.7","1.0","1.5"],"set direct.txdelay":["0.3","0.5","0.7"],"set log":["debug","info","warning","error"],"start cap":["30","60","120","300"]},ka=["@@@@@@@ @@@ @@@ @@@@@@@@@@ @@@@@@@ ","@@@@@@@@ @@@ @@@ @@@@@@@@@@@ @@@@@@@@ ","@@! @@@ @@! !@@ @@! @@! @@! !@@ ","!@! @!@ !@! @!! !@! !@! !@! !@! ","@!@@!@! !@!@! @!! !!@ @!@ !@! ","!!@!!! @!!! !@! ! !@! !!! ","!!: !!: !!: !!: :!! ",":!: :!: :!: :!: :!: "," :: :: ::: :: ::: ::: "," : : : : :: :: : "];function Ca(){return/Android|iPhone|iPad|iPod/i.test(navigator.userAgent)||window.innerWidth<640}function Sa(){const e=U(),{addCommand:t}=la(),s=a.useRef(null),n=a.useRef(null),o=a.useRef(null),i=a.useRef(null),p=a.useRef(""),m=a.useRef(-1),g=a.useRef(""),f=a.useRef(!1),y=a.useRef(null),x=a.useRef(!1),v=a.useRef(!1),$=a.useRef(!1),b=a.useRef([]),w=a.useRef(()=>{}),_=H(),[k,C]=a.useState("C0dE"),[S,j]=a.useState(!1),N=a.useRef(null),T="C0dE",R=a.useCallback(e=>{N.current&&(clearInterval(N.current),N.current=null);const t=T.padEnd(7),r=t+" "+e+" "+t;let a=0;const s=r.length-7;j(!0),C(r.slice(0,7)),N.current=setInterval(()=>{if(a++,a>s)return clearInterval(N.current),N.current=null,j(!1),void C(T);C(r.slice(a,a+7))},280)},[]);a.useEffect(()=>{const e=function(e){const t=t=>e(t.detail);return Wr.addEventListener(Gr,t),()=>Wr.removeEventListener(Gr,t)}(R),t=setInterval(()=>{Math.random()<.02&&R(Kr())},45e3);return()=>{e(),clearInterval(t),N.current&&clearInterval(N.current)}},[R]);const[M,E]=a.useState(!1),A=a.useRef(null);a.useEffect(()=>{const e=(t=()=>{A.current&&clearTimeout(A.current),E(!0),A.current=setTimeout(()=>E(!1),5e3)},Yr.addEventListener(Jr,t),()=>Yr.removeEventListener(Jr,t));var t;return()=>{e(),A.current&&clearTimeout(A.current)}},[]);const[I,F]=a.useState({show:!1,options:[],selectedIndex:0,input:""}),L=a.useRef([]),B=a.useRef(0);a.useEffect(()=>{(null==e?void 0:e.neighbors)&&(b.current=Object.values(e.neighbors).map(e=>e.node_name||e.name).filter(e=>!!e).sort())},[null==e?void 0:e.neighbors]);const D=a.useCallback(()=>{var e;null==(e=n.current)||e.write(`${z()||"user"}@pyMC${ve}: $${ve} `)},[]),O=a.useCallback(()=>{const e=n.current;e&&(e.write(Ke),D(),e.write(p.current))},[D]),P=a.useCallback(e=>{const t=function(e,t){const r=e.toLowerCase(),a=r.trim();if(!a)return[];const s=r.length>a.length&&r.endsWith(" ");if(!a.includes(" ")&&!s)return ba.filter(e=>e.cmd.toLowerCase().startsWith(a));const n=s?a:a.substring(0,a.lastIndexOf(" ")),o=s?"":a.substring(a.lastIndexOf(" ")+1);if("ping"===n&&t.length>0)return t.filter(e=>e.toLowerCase().startsWith(o)).slice(0,10).map(e=>({cmd:`ping ${e}`,desc:`→ ${e}`}));const i=_a[n];if(i){const e=i.filter(e=>e.toLowerCase().startsWith(o)).map(e=>({cmd:`${n} ${e}`,desc:`→ ${e}`}));if(!s&&o){const t=new Set(e.map(e=>e.cmd));for(const r of ba){const s=r.cmd.toLowerCase();s.startsWith(a)&&!t.has(s)&&(e.push(r),t.add(s))}}return e}return ba.filter(e=>e.cmd.toLowerCase().startsWith(a))}(e,b.current);L.current=t,B.current=0;const r=t.length>0&&e.trim().length>0;F({show:r,options:t,selectedIndex:0,input:e.trim()})},[]),K=a.useCallback(()=>{L.current=[],B.current=0,F({show:!1,options:[],selectedIndex:0,input:""})},[]),W=a.useCallback(e=>{var t;const r=L.current[e];r&&(p.current=r.required?r.cmd+" ":r.cmd,O(),r.required?P(p.current):K(),null==(t=n.current)||t.focus())},[O,P,K]),G=a.useCallback(async e=>{const r=n.current;if(!r)return;const a=e.trim();if(!a)return void D();f.current=!0;const s=new AbortController;y.current=s,t(a),m.current=-1;let o=0;const i={get cols(){return r.cols},get rows(){return r.rows},write(e,t="default"){const a=("default"===t?e:Me(e,t)).split("\n");for(const s of a)r.writeln(s);return o=Je(a,r.cols),String(o)},update(e,t,a){if($.current)r.write("");else if(o>0)for(let n=0;n{const t=n.current;if(!t)return;if(!v.current)return;if(f.current){for(let r=0;rrequestAnimationFrame(()=>{var t;return null==(t=document.querySelector(`[data-ac-index="${e}"]`))?void 0:t.scrollIntoView({block:"nearest"})});for(let s=0;s0){const e=L.current[B.current];e&&(p.current=e.cmd,O())}K();const e=p.current;p.current="",t.writeln(""),G(e);continue}if(127!==n&&8!==n)if(3!==n)if(12!==n)if(9!==n)if(27!==n)n>=32&&(p.current+=e[s],t.write(e[s]),m.current=-1,P(p.current));else{if(91===e.charCodeAt(s+1)){const t=e.charCodeAt(s+2);if(s+=2,65===t){if(L.current.length>0){const e=Math.max(B.current-1,0);B.current=e,F(t=>({...t,selectedIndex:e})),a(e)}else r.length>0&&(-1===m.current&&(g.current=p.current),m.current0){const e=Math.min(B.current+1,L.current.length-1);B.current=e,F(t=>({...t,selectedIndex:e})),a(e)}else m.current>0?(m.current--,p.current=r[r.length-1-m.current]||"",O()):0===m.current&&(m.current=-1,p.current=g.current,O());continue}if(67===t||68===t)continue;continue}L.current.length>0&&K()}else L.current.length>0&&W(B.current);else t.clear(),K(),O();else p.current="",K(),t.writeln("^C"),D();else p.current.length>0&&(p.current=p.current.slice(0,-1),t.write("\b \b"),P(p.current))}},[K,P,W,D,O,G]);a.useEffect(()=>{w.current=X},[X]);const V=a.useCallback(async()=>{const e=n.current;if(!e||x.current)return;x.current=!0;const t="",r="",a=ka.length,s=te-1;try{const t=Q(ka,0);for(const r of t)e.writeln(r);await new Promise(t=>{let r=0;const n=setInterval(()=>{if(r>=s)return clearInterval(n),void t();r++,e.write(`[${a}F`);const o=Q(ka,r);for(const t of o)e.write(`${t}\n`)},Z)})}finally{ee()}e.writeln(""),e.write(Fe("● Initializing terminal...")),await new Promise(e=>setTimeout(e,300)),e.write(Ke),e.writeln(`${t}✓ Initializing terminal...${r}`),e.write(Fe("● Connecting to repeater...")),await new Promise(e=>setTimeout(e,500)),e.write(Ke),"connected"===q.getState().health?e.writeln(`${t}✓ Connected to repeater${r}`):e.writeln(`${Ce}~ Connection status unknown${ve}`),e.writeln(Fe("Ready. Type 'help' for commands.")),e.writeln(""),D(),v.current=!0},[D]);a.useEffect(()=>{const e=s.current;if(!e)return;const t=Ca()?12:13,r=new l({theme:Ze(),fontFamily:'"JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',fontSize:t,lineHeight:Ca()?1.1:.65,cursorBlink:!1,cursorStyle:"underline",scrollback:1e4,convertEol:!0,allowTransparency:!0,rightClickSelectsWord:!1}),a=new d;r.loadAddon(a),r.loadAddon(new u),r.open(e),a.fit(),n.current=r,o.current=a;const i=r.onData(e=>w.current(e)),c=function(e){return h.subscribe(()=>{e.options.theme=Ze()})}(r),p=new ResizeObserver(()=>{requestAnimationFrame(()=>a.fit())});return p.observe(e),V(),Ca()||r.focus(),()=>{var e;null==(e=y.current)||e.abort(),$.current&&(r.write(Xe+Ge),$.current=!1),i.dispose(),c(),p.disconnect(),r.dispose(),n.current=null,o.current=null}},[]);const Y=a.useCallback(e=>{const t=e.target.value;t.length>0&&(X(t),e.target.value="")},[X]),J=a.useCallback(e=>{"Enter"===e.key?(e.preventDefault(),X("\r")):"Backspace"===e.key?(e.preventDefault(),X("")):"ArrowUp"===e.key?(e.preventDefault(),X("")):"ArrowDown"===e.key&&(e.preventDefault(),X(""))},[X]),ne=a.useCallback(()=>{var e,t;Ca()?null==(e=i.current)||e.focus():null==(t=n.current)||t.focus()},[]);a.useEffect(()=>{if(!Ca())return;const e=()=>{var e;const t=null==(e=s.current)?void 0:e.querySelector(".xterm-viewport");t&&(t.scrollTop=t.scrollHeight),requestAnimationFrame(()=>{var e;return null==(e=o.current)?void 0:e.fit()})},t=window.visualViewport;if(t){const r=()=>{t.height<.75*window.innerHeight&&e()};return t.addEventListener("resize",r),()=>t.removeEventListener("resize",r)}const r=i.current;if(r){const t=()=>setTimeout(e,300);return r.addEventListener("focus",t),()=>r.removeEventListener("focus",t)}},[]);const ie=a.useCallback(e=>{p.current=e+" ",O(),P(p.current),setTimeout(()=>{var e;null==(e=s.current)||e.click()},400)},[O,P]);return r.jsx(re,{children:r.jsx(ae,{children:r.jsxs("div",{className:"terminal-card flex flex-col gap-1 sm:gap-1.5",children:[r.jsxs("div",{className:"card-terminal-header flex-wrap",children:[r.jsx("span",{className:"seven-seg-panel",children:r.jsx(oe,{text:k,minChars:7,size:24,noCycle:S})}),r.jsx("div",{className:"header-well self-stretch flex-col sm:order-first",children:r.jsxs("div",{className:"indicator-key"+("connected"===_?" indicator-key--active":"degraded"===_?" indicator-key--sending":""),children:[r.jsx("span",{className:"indicator-key__label",children:"ONLINE"}),r.jsx("span",{className:"indicator-key__led"})]})}),r.jsx("div",{className:"card-terminal-ridge flex-1 min-w-4 sm:hidden"}),r.jsxs("div",{className:"header-well flex items-center gap-1 sm:order-last",children:[r.jsx(va,{onUseCommand:ie}),r.jsx(ua,{})]}),r.jsx("div",{className:"card-terminal-ridge flex-1 min-w-8 hidden sm:block"})]}),r.jsx(se,{noPadding:!0,className:"flex flex-col flex-1 min-h-0 overflow-hidden card-terminal",onClick:ne,children:r.jsxs("div",{className:"card-terminal-well flex-1 min-h-0 flex flex-col overflow-hidden",children:[r.jsxs("div",{className:"flex-1 min-h-0 terminal-gutter relative",children:[r.jsx("div",{ref:s,className:"h-full w-full"}),M&&r.jsxs("div",{className:"absolute inset-0 z-10 flex items-center justify-center",onClick:()=>E(!1),children:[r.jsx("div",{className:"absolute inset-0 animate-[partytime-bg_5s_ease-out_forwards]",style:{background:"rgba(0,0,0,0.82)"}}),r.jsxs("div",{className:"relative z-10 animate-[partytime-crt_5s_ease-out_forwards] partytime-glow",children:[r.jsx("img",{src:"/assets/partytime.gif",alt:"No way.",className:"max-h-[60vh] max-w-[70vw] object-contain rounded"}),r.jsx("div",{className:"absolute inset-0 pointer-events-none rounded partytime-scanlines"})]})]})]}),I.show&&I.options.length>0&&r.jsxs("div",{className:"flex-shrink-0 overflow-hidden terminal-completions",style:{borderTop:"1px solid var(--terminal-border)",background:"var(--terminal-bg-input)"},children:[r.jsx("div",{className:"overflow-y-auto",style:{maxHeight:"176px"},children:I.options.map((e,t)=>{const a=t===I.selectedIndex,s=I.input.length;return r.jsxs("div",{"data-ac-index":t,onClick:()=>W(t),className:c("terminal-ac-option",a?"text-sys-blue":"text-fg-primary"),style:{background:a?"var(--terminal-autocomplete-hover)":void 0},onMouseEnter:e=>{a||(e.currentTarget.style.background="var(--terminal-autocomplete-hover)")},onMouseLeave:e=>{a||(e.currentTarget.style.background="")},children:[r.jsx("span",{className:"terminal-ac-option__indicator",children:a?"▸":""}),r.jsxs("span",{className:"terminal-ac-option__cmd",children:[r.jsx("span",{className:"font-semibold text-sys-blue",children:e.cmd.substring(0,s)}),e.cmd.substring(s)]}),r.jsx("span",{className:"terminal-ac-option__desc",children:e.desc})]},e.cmd)})}),r.jsxs("div",{className:"terminal-ac-hints",children:[r.jsx("span",{className:"hidden sm:inline",children:"Tab · ↑↓ · Esc"}),r.jsx("span",{className:"sm:hidden",children:"Tap to select"}),r.jsxs("span",{children:[I.options.length," match",1!==I.options.length?"es":""]})]})]}),r.jsxs("div",{className:"terminal-mobile-input-bar sm:hidden",children:[r.jsx("input",{ref:i,type:"text",className:"terminal-mobile-input",onChange:Y,onKeyDown:J,autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",spellCheck:!1,enterKeyHint:"send","aria-label":"Terminal input",placeholder:"Type command..."}),r.jsx("button",{type:"button",className:"terminal-send-btn",onClick:()=>X("\r"),"aria-label":"Run command",children:r.jsx(me,{})})]}),r.jsxs("div",{className:"terminal-status-bar",children:[r.jsx("span",{className:"hidden sm:inline",children:"↑↓ History · Tab · Esc"}),r.jsx("span",{className:"sm:hidden",children:"Tap input to type"}),(null==e?void 0:e.version)&&r.jsxs("span",{children:["pyMC v",e.version]})]})]})})]})})})}export{Sa as default}; diff --git a/frontend/dist/assets/TimeRangeStepper-B5GfHny9.js b/frontend/dist/assets/TimeRangeStepper-CsLZzi5t.js similarity index 97% rename from frontend/dist/assets/TimeRangeStepper-B5GfHny9.js rename to frontend/dist/assets/TimeRangeStepper-CsLZzi5t.js index beea61a8..9ce0cba2 100644 --- a/frontend/dist/assets/TimeRangeStepper-B5GfHny9.js +++ b/frontend/dist/assets/TimeRangeStepper-CsLZzi5t.js @@ -1 +1 @@ -import{r as e,j as t,v as a,D as s,g as n}from"./vendor-react-alRNW2nb.js";import{b0 as r}from"./index-D7i6lQrq.js";import{c as i}from"./vendor-core-FtpmsTnh.js";import{af as o,D as l}from"./vendor-icons-TO0PZKGR.js";import{A as c,m as d}from"./vendor-motion-DNp0Qg4F.js";const m=e.memo(function({ranges:m,selectedIndex:u,onSelect:p,isPending:x,size:f="default"}){var h;const y=e.useRef(null),b=u>0,v=u{var a;const s="left"===e?6:-6;null==(a=y.current)||a.animate([{opacity:1,transform:"translateX(0)"},{opacity:0,transform:`translateX(${s}px)`}],{duration:80,easing:"ease-out"}),setTimeout(()=>{var e;t(),null==(e=y.current)||e.animate([{opacity:0,transform:`translateX(${-s}px)`},{opacity:1,transform:"translateX(0)"}],{duration:80,easing:"ease-out"})},80)},N=()=>b&&w("left",()=>p(u-1)),_=()=>v&&w("right",()=>p(u+1));return t.jsx(a,{className:"relative inline-flex",children:({open:e,close:a})=>t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:i("inline-flex items-center rounded-full bg-surface","shadow-[var(--neo-outer-sm)]",j?"gap-0.5 p-0.5":"gap-0.5 p-1",x&&"opacity-70"),children:[t.jsx("button",{type:"button",onClick:N,disabled:!b,"aria-label":"Previous",className:i("flex items-center justify-center rounded-full transition-all duration-100","text-fg-muted hover:text-fg-primary active:scale-90","disabled:opacity-25 disabled:pointer-events-none",j?"w-5 h-5":"w-6 h-6"),children:t.jsx(o,{className:j?"w-3 h-3":"w-3.5 h-3.5"})}),t.jsx(s,{className:i("rounded-full cursor-pointer transition-all","bg-surface shadow-[inset_0_0_0_1.5px_var(--sys-blue)]",j?"px-2.5 py-1":"px-3 py-1.5"),children:t.jsx("span",{ref:y,className:i("block font-semibold text-fg-primary tabular-nums select-none",j?"min-w-[1.5rem] text-[11px]":"min-w-[2rem] text-xs","text-center"),children:g})}),t.jsx("button",{type:"button",onClick:_,disabled:!v,"aria-label":"Next",className:i("flex items-center justify-center rounded-full transition-all duration-100","text-fg-muted hover:text-fg-primary active:scale-90","disabled:opacity-25 disabled:pointer-events-none",j?"w-5 h-5":"w-6 h-6"),children:t.jsx(l,{className:j?"w-3 h-3":"w-3.5 h-3.5"})})]}),t.jsx(c,{children:e&&t.jsx(n,{static:!0,anchor:"bottom",className:"z-50 mt-2",children:t.jsx(d.div,{initial:{opacity:0,y:-4,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.98},transition:r.dropdown,className:i("surface-elevated radius-inset p-1","shadow-[var(--neo-outer)]"),children:t.jsx("div",{className:"grid grid-cols-4 gap-0.5",children:m.map((e,s)=>t.jsx("button",{type:"button",onClick:()=>{s!==u&&p(s),a()},className:i("px-2.5 py-1.5 radius-control text-xs font-medium transition-colors",s===u?"shadow-[inset_0_0_0_1.5px_var(--sys-blue)] text-fg-primary":"text-fg-secondary hover:bg-overlay-soft"),children:e.label},e.label))})})})})]})})});export{m as T}; +import{r as e,j as t,v as a,D as s,g as n}from"./vendor-react-alRNW2nb.js";import{b0 as r}from"./index-CkRTgHHA.js";import{c as i}from"./vendor-core-FtpmsTnh.js";import{af as o,D as l}from"./vendor-icons-TO0PZKGR.js";import{A as c,m as d}from"./vendor-motion-DNp0Qg4F.js";const m=e.memo(function({ranges:m,selectedIndex:u,onSelect:p,isPending:x,size:f="default"}){var h;const y=e.useRef(null),b=u>0,v=u{var a;const s="left"===e?6:-6;null==(a=y.current)||a.animate([{opacity:1,transform:"translateX(0)"},{opacity:0,transform:`translateX(${s}px)`}],{duration:80,easing:"ease-out"}),setTimeout(()=>{var e;t(),null==(e=y.current)||e.animate([{opacity:0,transform:`translateX(${-s}px)`},{opacity:1,transform:"translateX(0)"}],{duration:80,easing:"ease-out"})},80)},N=()=>b&&w("left",()=>p(u-1)),_=()=>v&&w("right",()=>p(u+1));return t.jsx(a,{className:"relative inline-flex",children:({open:e,close:a})=>t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:i("inline-flex items-center rounded-full bg-surface","shadow-[var(--neo-outer-sm)]",j?"gap-0.5 p-0.5":"gap-0.5 p-1",x&&"opacity-70"),children:[t.jsx("button",{type:"button",onClick:N,disabled:!b,"aria-label":"Previous",className:i("flex items-center justify-center rounded-full transition-all duration-100","text-fg-muted hover:text-fg-primary active:scale-90","disabled:opacity-25 disabled:pointer-events-none",j?"w-5 h-5":"w-6 h-6"),children:t.jsx(o,{className:j?"w-3 h-3":"w-3.5 h-3.5"})}),t.jsx(s,{className:i("rounded-full cursor-pointer transition-all","bg-surface shadow-[inset_0_0_0_1.5px_var(--sys-blue)]",j?"px-2.5 py-1":"px-3 py-1.5"),children:t.jsx("span",{ref:y,className:i("block font-semibold text-fg-primary tabular-nums select-none",j?"min-w-[1.5rem] text-[11px]":"min-w-[2rem] text-xs","text-center"),children:g})}),t.jsx("button",{type:"button",onClick:_,disabled:!v,"aria-label":"Next",className:i("flex items-center justify-center rounded-full transition-all duration-100","text-fg-muted hover:text-fg-primary active:scale-90","disabled:opacity-25 disabled:pointer-events-none",j?"w-5 h-5":"w-6 h-6"),children:t.jsx(l,{className:j?"w-3 h-3":"w-3.5 h-3.5"})})]}),t.jsx(c,{children:e&&t.jsx(n,{static:!0,anchor:"bottom",className:"z-50 mt-2",children:t.jsx(d.div,{initial:{opacity:0,y:-4,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.98},transition:r.dropdown,className:i("surface-elevated radius-inset p-1","shadow-[var(--neo-outer)]"),children:t.jsx("div",{className:"grid grid-cols-4 gap-0.5",children:m.map((e,s)=>t.jsx("button",{type:"button",onClick:()=>{s!==u&&p(s),a()},className:i("px-2.5 py-1.5 radius-control text-xs font-medium transition-colors",s===u?"shadow-[inset_0_0_0_1.5px_var(--sys-blue)] text-fg-primary":"text-fg-secondary hover:bg-overlay-soft"),children:e.label},e.label))})})})})]})})});export{m as T}; diff --git a/frontend/dist/assets/chat-utils-DbM_TyxC.js b/frontend/dist/assets/chat-utils-mqGCinix.js similarity index 94% rename from frontend/dist/assets/chat-utils-DbM_TyxC.js rename to frontend/dist/assets/chat-utils-mqGCinix.js index fb1f79f6..c5b30be5 100644 --- a/frontend/dist/assets/chat-utils-DbM_TyxC.js +++ b/frontend/dist/assets/chat-utils-mqGCinix.js @@ -1 +1 @@ -import{r as e}from"./vendor-react-alRNW2nb.js";import{bb as n}from"./index-D7i6lQrq.js";const t=[n.green,n.blue,n.amber,n.pink,n.purple,n.cyan,n.orange,n.teal];function r(e){let n=0;for(let t=0;t0?{emoji:n[0],cleanName:e.replace(o,"").trim()||e}:{emoji:null,cleanName:e}}function i(e){const{cleanName:n}=a(e),t=n.split(/[\s-_]+/).filter(Boolean);return t.length>=2?((Array.from(t[0])[0]||"")+(Array.from(t[1])[0]||"")).toUpperCase():Array.from(n).slice(0,2).join("").toUpperCase()}function l(e){return new Date(1e3*e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})}function s(n){const t=/@\[([^\]]+)\]/g,r=[];let o,a=0;for(;null!==(o=t.exec(n));)o.index>a&&r.push(n.slice(a,o.index)),r.push(e.createElement("span",{key:o.index,className:"font-extrabold text-white"},o[1])),a=o.index+o[0].length;return a0?r:n}export{i as a,l as b,a as e,s as f,r as g}; +import{r as e}from"./vendor-react-alRNW2nb.js";import{bb as n}from"./index-CkRTgHHA.js";const t=[n.green,n.blue,n.amber,n.pink,n.purple,n.cyan,n.orange,n.teal];function r(e){let n=0;for(let t=0;t0?{emoji:n[0],cleanName:e.replace(o,"").trim()||e}:{emoji:null,cleanName:e}}function i(e){const{cleanName:n}=a(e),t=n.split(/[\s-_]+/).filter(Boolean);return t.length>=2?((Array.from(t[0])[0]||"")+(Array.from(t[1])[0]||"")).toUpperCase():Array.from(n).slice(0,2).join("").toUpperCase()}function l(e){return new Date(1e3*e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})}function s(n){const t=/@\[([^\]]+)\]/g,r=[];let o,a=0;for(;null!==(o=t.exec(n));)o.index>a&&r.push(n.slice(a,o.index)),r.push(e.createElement("span",{key:o.index,className:"font-extrabold text-white"},o[1])),a=o.index+o[0].length;return a0?r:n}export{i as a,l as b,a as e,s as f,r as g}; diff --git a/frontend/dist/assets/consumer-registry-KuOoZhsq.js b/frontend/dist/assets/consumer-registry-BUFl6buY.js similarity index 93% rename from frontend/dist/assets/consumer-registry-KuOoZhsq.js rename to frontend/dist/assets/consumer-registry-BUFl6buY.js index 6ff737f5..59c662f9 100644 --- a/frontend/dist/assets/consumer-registry-KuOoZhsq.js +++ b/frontend/dist/assets/consumer-registry-BUFl6buY.js @@ -1 +1 @@ -import{Q as t}from"./index-D7i6lQrq.js";import{r as a}from"./vendor-react-alRNW2nb.js";const e=a=>(a.type??a.payload_type)===t.ADVERT,n=a=>(a.type??a.payload_type)===t.TRACE,o=a=>(a.type??a.payload_type)===t.TXT_MSG,s=a=>(a.type??a.payload_type)===t.PATH,r=a=>(a.type??a.payload_type)===t.ACK,p=a=>{const e=a.type??a.payload_type;return e===t.GRP_TXT||e===t.GRP_DATA},y=t=>(t.path_length??(Array.isArray(t.original_path)?t.original_path.length:0))>0,f=t=>!!t.src_hash,c=t=>null!=t.airtime_ms,i=new Set,_=new Map;function l(t,a){return`${t}|${a}`}function d(t,a){const e=l(t,a);_.set(e,(_.get(e)??0)+1)}function u(t,a){const e=l(t,a),n=_.get(e)??0;n>1?_.set(e,n-1):_.delete(e)}function g(t){for(const a of t){const t=l(a.target,a.fn);i.has(t)||i.add(t)}}function h(t){a.useEffect(()=>{for(const a of t)d(a.target,a.fn);return()=>{for(const a of t)u(a.target,a.fn)}},[t])}export{y as a,f as b,o as c,r as d,e,n as f,s as g,c as h,p as i,g as r,h as u}; +import{Q as t}from"./index-CkRTgHHA.js";import{r as a}from"./vendor-react-alRNW2nb.js";const e=a=>(a.type??a.payload_type)===t.ADVERT,n=a=>(a.type??a.payload_type)===t.TRACE,o=a=>(a.type??a.payload_type)===t.TXT_MSG,s=a=>(a.type??a.payload_type)===t.PATH,r=a=>(a.type??a.payload_type)===t.ACK,p=a=>{const e=a.type??a.payload_type;return e===t.GRP_TXT||e===t.GRP_DATA},y=t=>(t.path_length??(Array.isArray(t.original_path)?t.original_path.length:0))>0,f=t=>!!t.src_hash,c=t=>null!=t.airtime_ms,i=new Set,_=new Map;function l(t,a){return`${t}|${a}`}function d(t,a){const e=l(t,a);_.set(e,(_.get(e)??0)+1)}function u(t,a){const e=l(t,a),n=_.get(e)??0;n>1?_.set(e,n-1):_.delete(e)}function g(t){for(const a of t){const t=l(a.target,a.fn);i.has(t)||i.add(t)}}function h(t){a.useEffect(()=>{for(const a of t)d(a.target,a.fn);return()=>{for(const a of t)u(a.target,a.fn)}},[t])}export{y as a,f as b,o as c,r as d,e,n as f,s as g,c as h,p as i,g as r,h as u}; diff --git a/frontend/dist/assets/index-B2A_8ldG.css b/frontend/dist/assets/index-BawBpZYt.css similarity index 90% rename from frontend/dist/assets/index-B2A_8ldG.css rename to frontend/dist/assets/index-BawBpZYt.css index 3900527d..9d8706f0 100644 --- a/frontend/dist/assets/index-B2A_8ldG.css +++ b/frontend/dist/assets/index-BawBpZYt.css @@ -1 +1 @@ -/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-divide-x-reverse:0}}}@layer theme{:root,:host{--color-amber-400:oklch(82.8% .189 84.429);--color-blue-500:oklch(62.3% .214 259.815);--color-violet-300:oklch(81.1% .111 293.571);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-5xl:3rem;--text-6xl:3.75rem;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-xs:4px;--radius-sm:6px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:20px;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-lg:16px;--blur-xl:24px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-display);--default-mono-font-family:var(--font-data);--color-body:var(--body);--color-surface:var(--surface);--color-elevated:var(--elevated);--color-subtle:var(--subtle);--color-edge-subtle:var(--edge-subtle);--color-edge-strong:var(--edge-strong);--color-fg-primary:var(--fg-primary);--color-fg-secondary:var(--fg-secondary);--color-fg-muted:var(--fg-muted);--color-fg-invert:var(--fg-invert);--font-title:var(--font-title);--duration-instant:75ms;--duration-fast:.15s;--duration-normal:.2s}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-x-3{inset-inline:calc(var(--spacing)*3)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.inset-y-2{inset-block:calc(var(--spacing)*2)}.-top-0\.5{top:calc(var(--spacing)*-.5)}.-top-1{top:calc(var(--spacing)*-1)}.-top-2{top:calc(var(--spacing)*-2)}.-top-\[3px\]{top:-3px}.top-0{top:calc(var(--spacing)*0)}.top-1{top:calc(var(--spacing)*1)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-3{top:calc(var(--spacing)*3)}.top-4{top:calc(var(--spacing)*4)}.top-12{top:calc(var(--spacing)*12)}.top-\[-4px\]{top:-4px}.top-\[40px\]{top:40px}.top-\[var\(--tip-y\,0\)\]{top:var(--tip-y,0)}.top-full{top:100%}.-right-0\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-2\.5{right:calc(var(--spacing)*2.5)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-\[-4px\]{right:-4px}.right-auto{right:auto}.right-full{right:100%}.-bottom-0\.5{bottom:calc(var(--spacing)*-.5)}.-bottom-1{bottom:calc(var(--spacing)*-1)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-3{bottom:calc(var(--spacing)*3)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-\[-4px\]{bottom:-4px}.bottom-\[-20px\]{bottom:-20px}.bottom-full{bottom:100%}.-left-3{left:calc(var(--spacing)*-3)}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-\[-4px\]{left:-4px}.left-\[19px\]{left:19px}.left-\[var\(--tip-x\,0\)\]{left:var(--tip-x,0)}.left-full{left:100%}.isolate{isolation:isolate}.-z-10{z-index:-10}.-z-20{z-index:-20}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[-1\]{z-index:-1}.z-\[1\]{z-index:1}.z-\[200\]{z-index:200}.z-\[600\]{z-index:600}.z-\[700\]{z-index:700}.z-\[9999\]{z-index:9999}.z-\[10001\]{z-index:10001}.z-\[10002\]{z-index:10002}.z-\[10003\]{z-index:10003}.z-\[10010\]{z-index:10010}.z-\[10020\]{z-index:10020}.col-auto{grid-column:auto}.col-span-2{grid-column:span 2/span 2}.col-span-full{grid-column:1/-1}.container{width:100%}@media(min-width:475px){.container{max-width:475px}}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-m-1{margin:calc(var(--spacing)*-1)}.-m-1\.5{margin:calc(var(--spacing)*-1.5)}.m-2{margin:calc(var(--spacing)*2)}.-mx-0{margin-inline:calc(var(--spacing)*0)}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.-mx-3{margin-inline:calc(var(--spacing)*-3)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-0{margin-inline:calc(var(--spacing)*0)}.mx-0\.5{margin-inline:calc(var(--spacing)*.5)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-1\.5{margin-inline:calc(var(--spacing)*1.5)}.mx-3{margin-inline:calc(var(--spacing)*3)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-4{margin-block:calc(var(--spacing)*4)}.my-6{margin-block:calc(var(--spacing)*6)}.-mt-0\.5{margin-top:calc(var(--spacing)*-.5)}.-mt-1{margin-top:calc(var(--spacing)*-1)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.-mt-5{margin-top:calc(var(--spacing)*-5)}.-mt-6{margin-top:calc(var(--spacing)*-6)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-2\.5{margin-top:calc(var(--spacing)*2.5)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-5{margin-top:calc(var(--spacing)*5)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-auto{margin-top:auto}.-mr-0\.5{margin-right:calc(var(--spacing)*-.5)}.-mr-1{margin-right:calc(var(--spacing)*-1)}.mr-0\.5{margin-right:calc(var(--spacing)*.5)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-auto{margin-right:auto}.-mb-0\.5{margin-bottom:calc(var(--spacing)*-.5)}.-mb-4{margin-bottom:calc(var(--spacing)*-4)}.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-4{margin-left:calc(var(--spacing)*-4)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-8{margin-left:calc(var(--spacing)*8)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-2\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-12{width:calc(var(--spacing)*12);height:calc(var(--spacing)*12)}.size-14{width:calc(var(--spacing)*14);height:calc(var(--spacing)*14)}.size-16{width:calc(var(--spacing)*16);height:calc(var(--spacing)*16)}.size-\[max\(100\%\,2\.75rem\)\]{width:max(100%,2.75rem);height:max(100%,2.75rem)}.size-full{width:100%;height:100%}.\!h-3{height:calc(var(--spacing)*3)!important}.\!h-5{height:calc(var(--spacing)*5)!important}.\!h-5\.5{height:calc(var(--spacing)*5.5)!important}.\!h-8{height:calc(var(--spacing)*8)!important}.\!h-\[calc\(100vh-11rem\)\]{height:calc(100vh - 11rem)!important}.\!h-auto{height:auto!important}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-64{height:calc(var(--spacing)*64)}.h-\[1\.5px\]{height:1.5px}.h-\[1px\]{height:1px}.h-\[2px\]{height:2px}.h-\[14px\]{height:14px}.h-\[15px\]{height:15px}.h-\[18px\]{height:18px}.h-\[30px\]{height:30px}.h-\[32px\]{height:32px}.h-\[36px\]{height:36px}.h-\[38px\]{height:38px}.h-\[60px\]{height:60px}.h-\[70vh\]{height:70vh}.h-\[75vh\]{height:75vh}.h-\[80vh\]{height:80vh}.h-\[120px\]{height:120px}.h-\[200px\]{height:200px}.h-\[420px\]{height:420px}.h-\[calc\(100dvh-56px\)\]{height:calc(100dvh - 56px)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-0{max-height:calc(var(--spacing)*0)}.max-h-24{max-height:calc(var(--spacing)*24)}.max-h-32{max-height:calc(var(--spacing)*32)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[45vh\]{max-height:45vh}.max-h-\[48px\]{max-height:48px}.max-h-\[60vh\]{max-height:60vh}.max-h-\[140px\]{max-height:140px}.max-h-\[200px\]{max-height:200px}.max-h-\[700px\]{max-height:700px}.max-h-\[calc\(100dvh-226px\)\]{max-height:calc(100dvh - 226px)}.max-h-\[calc\(100vh-80px\)\]{max-height:calc(100vh - 80px)}.max-h-\[calc\(100vh-200px\)\]{max-height:calc(100vh - 200px)}.\!min-h-\[400px\]{min-height:400px!important}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-9{min-height:calc(var(--spacing)*9)}.min-h-\[8px\]{min-height:8px}.min-h-\[28px\]{min-height:28px}.min-h-\[32px\]{min-height:32px}.min-h-\[38px\]{min-height:38px}.min-h-\[40px\]{min-height:40px}.min-h-\[44px\]{min-height:44px}.min-h-\[50vh\]{min-height:50vh}.min-h-\[120px\]{min-height:120px}.min-h-\[180px\]{min-height:180px}.min-h-\[300px\]{min-height:300px}.min-h-\[500px\]{min-height:500px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.min-h-svh{min-height:100svh}.\!w-3{width:calc(var(--spacing)*3)!important}.\!w-5{width:calc(var(--spacing)*5)!important}.\!w-5\.5{width:calc(var(--spacing)*5.5)!important}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/2{width:50%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-28{width:calc(var(--spacing)*28)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-80{width:calc(var(--spacing)*80)}.w-\[1\.75rem\]{width:1.75rem}.w-\[2\.4rem\]{width:2.4rem}.w-\[2\.25rem\]{width:2.25rem}.w-\[2px\]{width:2px}.w-\[3px\]{width:3px}.w-\[14px\]{width:14px}.w-\[28px\]{width:28px}.w-\[30px\]{width:30px}.w-\[32px\]{width:32px}.w-\[48px\]{width:48px}.w-\[52px\]{width:52px}.w-\[56px\]{width:56px}.w-\[60px\]{width:60px}.w-\[72px\]{width:72px}.w-\[240px\]{width:240px}.w-\[540px\]{width:540px}.w-\[var\(--button-width\)\]{width:var(--button-width)}.w-\[var\(--input-width\)\]{width:var(--input-width)}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[20rem\]{max-width:20rem}.max-w-\[50vw\]{max-width:50vw}.max-w-\[70px\]{max-width:70px}.max-w-\[70vw\]{max-width:70vw}.max-w-\[80px\]{max-width:80px}.max-w-\[85\%\]{max-width:85%}.max-w-\[85vw\]{max-width:85vw}.max-w-\[90px\]{max-width:90px}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[140px\]{max-width:140px}.max-w-\[220px\]{max-width:220px}.max-w-\[260px\]{max-width:260px}.max-w-\[960px\]{max-width:960px}.max-w-\[calc\(100vw-1\.5rem\)\]{max-width:calc(100vw - 1.5rem)}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-4{min-width:calc(var(--spacing)*4)}.min-w-8{min-width:calc(var(--spacing)*8)}.min-w-\[1\.5rem\]{min-width:1.5rem}.min-w-\[2\.25rem\]{min-width:2.25rem}.min-w-\[2rem\]{min-width:2rem}.min-w-\[10rem\]{min-width:10rem}.min-w-\[18px\]{min-width:18px}.min-w-\[44px\]{min-width:44px}.min-w-\[50px\]{min-width:50px}.min-w-\[60px\]{min-width:60px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[130px\]{min-width:130px}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.flex-\[17\]{flex:17}.flex-\[33\]{flex:33}.\!flex-shrink{flex-shrink:1!important}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.basis-0{flex-basis:calc(var(--spacing)*0)}.border-collapse{border-collapse:collapse}.origin-bottom{transform-origin:bottom}.origin-top{transform-origin:top}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-1\/4{--tw-translate-x: -25% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[4px\]{--tw-translate-x:4px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[18px\]{--tw-translate-x:18px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[22px\]{--tw-translate-x:22px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[30px\]{--tw-translate-x:30px;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-0{--tw-translate-y:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[0\.1em\]{--tw-translate-y:.1em;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-px{--tw-translate-y:1px;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-x-150{--tw-scale-x:150%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-0{rotate:none}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-\[partytime-bg_5s_ease-out_forwards\]{animation:5s ease-out forwards partytime-bg}.animate-\[partytime-crt_5s_ease-out_forwards\]{animation:5s ease-out forwards partytime-crt}.animate-\[shimmer-pulse_2s_ease-in-out_infinite\]{animation:2s ease-in-out infinite shimmer-pulse}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-copy{cursor:copy}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-ns-resize{cursor:ns-resize}.cursor-nwse-resize{cursor:nwse-resize}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.cursor-wait{cursor:wait}.touch-manipulation{touch-action:manipulation}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.resize-x{resize:horizontal}.resize-y{resize:vertical}.scroll-py-1{scroll-padding-block:calc(var(--spacing)*1)}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-\[2px\]{gap:2px}.gap-px{gap:1px}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-10>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*10)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*10)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px*var(--tw-space-y-reverse));margin-block-end:calc(1px*calc(1 - var(--tw-space-y-reverse)))}.gap-x-1\.5{column-gap:calc(var(--spacing)*1.5)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-y-0\.5{row-gap:calc(var(--spacing)*.5)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-1\.5{row-gap:calc(var(--spacing)*1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-edge-subtle>:not(:last-child)),:where(.divide-edge-subtle\/30>:not(:last-child)){border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){:where(.divide-edge-subtle\/30>:not(:last-child)){border-color:color-mix(in oklab,var(--edge-subtle)30%,transparent)}}.self-center{align-self:center}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.justify-self-start{justify-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\!overflow-hidden{overflow:hidden!important}.\!overflow-visible{overflow:visible!important}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.scroll-smooth{scroll-behavior:smooth}.\!rounded{border-radius:.25rem!important}.\!rounded-md{border-radius:8px!important}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:20px}.rounded-\[1\.125rem\]{border-radius:1.125rem}.rounded-\[1px\]{border-radius:1px}.rounded-card{border-radius:16px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:12px}.rounded-md{border-radius:8px}.rounded-none{border-radius:0}.rounded-pill{border-radius:9999px}.rounded-sm{border-radius:6px}.rounded-xl{border-radius:16px}.rounded-xs{border-radius:4px}.rounded-t-lg{border-top-left-radius:12px;border-top-right-radius:12px}.rounded-l-lg{border-top-left-radius:12px;border-bottom-left-radius:12px}.rounded-tl-md{border-top-left-radius:8px}.rounded-r-lg{border-top-right-radius:12px;border-bottom-right-radius:12px}.rounded-tr-md{border-top-right-radius:8px}.rounded-b-lg{border-bottom-right-radius:12px;border-bottom-left-radius:12px}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-0{border-right-style:var(--tw-border-style);border-right-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-\[var\(--route-direct\)\]\/30{border-color:var(--route-direct)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-direct\)\]\/30{border-color:color-mix(in oklab,var(--route-direct)30%,transparent)}}.border-\[var\(--route-flood\)\]\/30{border-color:var(--route-flood)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-flood\)\]\/30{border-color:color-mix(in oklab,var(--route-flood)30%,transparent)}}.border-\[var\(--route-transport\)\]\/30{border-color:var(--route-transport)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-transport\)\]\/30{border-color:color-mix(in oklab,var(--route-transport)30%,transparent)}}.border-current\/30{border-color:currentColor}@supports (color:color-mix(in lab,red,red)){.border-current\/30{border-color:color-mix(in oklab,currentcolor 30%,transparent)}}.border-edge-strong{border-color:var(--edge-strong)}.border-edge-subtle,.border-edge-subtle\/30{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/30{border-color:color-mix(in oklab,var(--edge-subtle)30%,transparent)}}.border-edge-subtle\/40{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/40{border-color:color-mix(in oklab,var(--edge-subtle)40%,transparent)}}.border-edge-subtle\/50{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/50{border-color:color-mix(in oklab,var(--edge-subtle)50%,transparent)}}.border-edge-subtle\/60{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/60{border-color:color-mix(in oklab,var(--edge-subtle)60%,transparent)}}.border-input-border{border-color:var(--input-border)}.border-signal-poor\/30{border-color:var(--signal-poor)}@supports (color:color-mix(in lab,red,red)){.border-signal-poor\/30{border-color:color-mix(in oklab,var(--signal-poor)30%,transparent)}}.border-sys-amber{border-color:var(--sys-amber)}.border-sys-blue,.border-sys-blue\/20{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/20{border-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.border-sys-blue\/25{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/25{border-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.border-sys-blue\/30{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/30{border-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.border-sys-blue\/40{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/40{border-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.border-sys-blue\/50{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/50{border-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.border-sys-cyan\/20{border-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.border-sys-cyan\/20{border-color:color-mix(in oklab,var(--sys-cyan)20%,transparent)}}.border-sys-cyan\/30{border-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.border-sys-cyan\/30{border-color:color-mix(in oklab,var(--sys-cyan)30%,transparent)}}.border-sys-green,.border-sys-green\/20{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/20{border-color:color-mix(in oklab,var(--sys-green)20%,transparent)}}.border-sys-green\/30{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/30{border-color:color-mix(in oklab,var(--sys-green)30%,transparent)}}.border-sys-green\/40{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/40{border-color:color-mix(in oklab,var(--sys-green)40%,transparent)}}.border-sys-green\/50{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/50{border-color:color-mix(in oklab,var(--sys-green)50%,transparent)}}.border-sys-indigo,.border-sys-indigo\/20{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/20{border-color:color-mix(in oklab,var(--sys-indigo)20%,transparent)}}.border-sys-indigo\/25{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/25{border-color:color-mix(in oklab,var(--sys-indigo)25%,transparent)}}.border-sys-indigo\/30{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/30{border-color:color-mix(in oklab,var(--sys-indigo)30%,transparent)}}.border-sys-orange\/50{border-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.border-sys-orange\/50{border-color:color-mix(in oklab,var(--sys-orange)50%,transparent)}}.border-sys-pink{border-color:var(--sys-pink)}.border-sys-purple{border-color:var(--sys-purple)}.border-sys-red,.border-sys-red\/20{border-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.border-sys-red\/20{border-color:color-mix(in oklab,var(--sys-red)20%,transparent)}}.border-sys-red\/50{border-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.border-sys-red\/50{border-color:color-mix(in oklab,var(--sys-red)50%,transparent)}}.border-toggle-on{border-color:var(--toggle-on)}.border-transparent{border-color:#0000}.border-violet-300{border-color:var(--color-violet-300)}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-zinc-500{border-color:var(--color-zinc-500)}.border-zinc-500\/40{border-color:#71717b66}@supports (color:color-mix(in lab,red,red)){.border-zinc-500\/40{border-color:color-mix(in oklab,var(--color-zinc-500)40%,transparent)}}.border-t-transparent{border-top-color:#0000}.border-l-sys-amber{border-left-color:var(--sys-amber)}.border-l-sys-blue{border-left-color:var(--sys-blue)}.border-l-sys-green{border-left-color:var(--sys-green)}.border-l-sys-indigo{border-left-color:var(--sys-indigo)}.border-l-sys-purple{border-left-color:var(--sys-purple)}.border-l-sys-red{border-left-color:var(--sys-red)}.border-l-sys-teal{border-left-color:var(--sys-teal)}.\!bg-transparent{background-color:#0000!important}.bg-\[\#007AFF\]{background-color:#007aff}.bg-\[\#34D399\]{background-color:#34d399}.bg-\[\#60A5FA\]{background-color:#60a5fa}.bg-\[\#0074BE\]{background-color:#0074be}.bg-\[\#18181b\]{background-color:#18181b}.bg-\[\#EFF0F1\]{background-color:#eff0f1}.bg-\[\#FF5F57\]{background-color:#ff5f57}.bg-\[var\(--map-ui-border\,var\(--edge-subtle\)\)\]{background-color:var(--map-ui-border,var(--edge-subtle))}.bg-\[var\(--route-direct\)\]\/20{background-color:var(--route-direct)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-direct\)\]\/20{background-color:color-mix(in oklab,var(--route-direct)20%,transparent)}}.bg-\[var\(--route-flood\)\]\/20{background-color:var(--route-flood)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-flood\)\]\/20{background-color:color-mix(in oklab,var(--route-flood)20%,transparent)}}.bg-\[var\(--route-transport\)\]\/20{background-color:var(--route-transport)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-transport\)\]\/20{background-color:color-mix(in oklab,var(--route-transport)20%,transparent)}}.bg-\[var\(--signal-critical\)\]{background-color:var(--signal-critical)}.bg-\[var\(--signal-excellent\)\]{background-color:var(--signal-excellent)}.bg-\[var\(--signal-fair\)\]{background-color:var(--signal-fair)}.bg-\[var\(--signal-good\)\]{background-color:var(--signal-good)}.bg-\[var\(--signal-poor\)\]{background-color:var(--signal-poor)}.bg-\[var\(--signal-unknown\)\]{background-color:var(--signal-unknown)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-black{background-color:var(--color-black)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-body,.bg-body\/50{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.bg-body\/50{background-color:color-mix(in oklab,var(--body)50%,transparent)}}.bg-chart-inner{background-color:var(--chart-inner)}.bg-edge-subtle{background-color:var(--edge-subtle)}.bg-elevated,.bg-elevated\/30{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/30{background-color:color-mix(in oklab,var(--elevated)30%,transparent)}}.bg-elevated\/50{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/50{background-color:color-mix(in oklab,var(--elevated)50%,transparent)}}.bg-elevated\/80{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/80{background-color:color-mix(in oklab,var(--elevated)80%,transparent)}}.bg-elevated\/90{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/90{background-color:color-mix(in oklab,var(--elevated)90%,transparent)}}.bg-fg-muted,.bg-fg-muted\/15{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/15{background-color:color-mix(in oklab,var(--fg-muted)15%,transparent)}}.bg-fg-muted\/20{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/20{background-color:color-mix(in oklab,var(--fg-muted)20%,transparent)}}.bg-fg-muted\/\[0\.03\]{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/\[0\.03\]{background-color:color-mix(in oklab,var(--fg-muted)3%,transparent)}}.bg-fg-primary\/30{background-color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.bg-fg-primary\/30{background-color:color-mix(in oklab,var(--fg-primary)30%,transparent)}}.bg-input-bg{background-color:var(--input-bg)}.bg-signal-excellent\/10{background-color:var(--signal-excellent)}@supports (color:color-mix(in lab,red,red)){.bg-signal-excellent\/10{background-color:color-mix(in oklab,var(--signal-excellent)10%,transparent)}}.bg-signal-fair\/10{background-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.bg-signal-fair\/10{background-color:color-mix(in oklab,var(--signal-fair)10%,transparent)}}.bg-signal-good\/10{background-color:var(--signal-good)}@supports (color:color-mix(in lab,red,red)){.bg-signal-good\/10{background-color:color-mix(in oklab,var(--signal-good)10%,transparent)}}.bg-signal-poor,.bg-signal-poor\/10{background-color:var(--signal-poor)}@supports (color:color-mix(in lab,red,red)){.bg-signal-poor\/10{background-color:color-mix(in oklab,var(--signal-poor)10%,transparent)}}.bg-status-danger,.bg-status-danger\/90{background-color:var(--status-danger)}@supports (color:color-mix(in lab,red,red)){.bg-status-danger\/90{background-color:color-mix(in oklab,var(--status-danger)90%,transparent)}}.bg-status-success{background-color:var(--status-success)}.bg-status-warning,.bg-status-warning\/15{background-color:var(--status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/15{background-color:color-mix(in oklab,var(--status-warning)15%,transparent)}}.bg-status-warning\/90{background-color:var(--status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/90{background-color:color-mix(in oklab,var(--status-warning)90%,transparent)}}.bg-subtle{background-color:var(--subtle)}.bg-subtle-fill{background-color:var(--subtle-fill)}.bg-subtle-fill-hover{background-color:var(--subtle-fill-hover)}.bg-subtle-fill-strong{background-color:var(--subtle-fill-strong)}.bg-subtle-fill\/30{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/30{background-color:color-mix(in oklab,var(--subtle-fill)30%,transparent)}}.bg-subtle-fill\/50{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/50{background-color:color-mix(in oklab,var(--subtle-fill)50%,transparent)}}.bg-subtle-fill\/80{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/80{background-color:color-mix(in oklab,var(--subtle-fill)80%,transparent)}}.bg-subtle\/30{background-color:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.bg-subtle\/30{background-color:color-mix(in oklab,var(--subtle)30%,transparent)}}.bg-subtle\/50{background-color:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.bg-subtle\/50{background-color:color-mix(in oklab,var(--subtle)50%,transparent)}}.bg-surface,.bg-surface\/30{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/30{background-color:color-mix(in oklab,var(--surface)30%,transparent)}}.bg-surface\/50{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/50{background-color:color-mix(in oklab,var(--surface)50%,transparent)}}.bg-surface\/75{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/75{background-color:color-mix(in oklab,var(--surface)75%,transparent)}}.bg-surface\/80{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/80{background-color:color-mix(in oklab,var(--surface)80%,transparent)}}.bg-surface\/85{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/85{background-color:color-mix(in oklab,var(--surface)85%,transparent)}}.bg-surface\/90{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/90{background-color:color-mix(in oklab,var(--surface)90%,transparent)}}.bg-surface\/95{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/95{background-color:color-mix(in oklab,var(--surface)95%,transparent)}}.bg-sys-amber,.bg-sys-amber\/5{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/5{background-color:color-mix(in oklab,var(--sys-amber)5%,transparent)}}.bg-sys-amber\/8{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/8{background-color:color-mix(in oklab,var(--sys-amber)8%,transparent)}}.bg-sys-amber\/10{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/10{background-color:color-mix(in oklab,var(--sys-amber)10%,transparent)}}.bg-sys-amber\/15{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/15{background-color:color-mix(in oklab,var(--sys-amber)15%,transparent)}}.bg-sys-amber\/20{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/20{background-color:color-mix(in oklab,var(--sys-amber)20%,transparent)}}.bg-sys-amber\/25{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/25{background-color:color-mix(in oklab,var(--sys-amber)25%,transparent)}}.bg-sys-amber\/50{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/50{background-color:color-mix(in oklab,var(--sys-amber)50%,transparent)}}.bg-sys-blue,.bg-sys-blue\/5{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/5{background-color:color-mix(in oklab,var(--sys-blue)5%,transparent)}}.bg-sys-blue\/8{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/8{background-color:color-mix(in oklab,var(--sys-blue)8%,transparent)}}.bg-sys-blue\/10{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/10{background-color:color-mix(in oklab,var(--sys-blue)10%,transparent)}}.bg-sys-blue\/12{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/12{background-color:color-mix(in oklab,var(--sys-blue)12%,transparent)}}.bg-sys-blue\/15{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/15{background-color:color-mix(in oklab,var(--sys-blue)15%,transparent)}}.bg-sys-blue\/20{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/20{background-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.bg-sys-blue\/25{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/25{background-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.bg-sys-blue\/30{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/30{background-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.bg-sys-blue\/40{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/40{background-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.bg-sys-blue\/50{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/50{background-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.bg-sys-cyan,.bg-sys-cyan\/5{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/5{background-color:color-mix(in oklab,var(--sys-cyan)5%,transparent)}}.bg-sys-cyan\/8{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/8{background-color:color-mix(in oklab,var(--sys-cyan)8%,transparent)}}.bg-sys-cyan\/10{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/10{background-color:color-mix(in oklab,var(--sys-cyan)10%,transparent)}}.bg-sys-cyan\/15{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/15{background-color:color-mix(in oklab,var(--sys-cyan)15%,transparent)}}.bg-sys-cyan\/20{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/20{background-color:color-mix(in oklab,var(--sys-cyan)20%,transparent)}}.bg-sys-cyan\/50{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/50{background-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.bg-sys-green,.bg-sys-green\/5{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/5{background-color:color-mix(in oklab,var(--sys-green)5%,transparent)}}.bg-sys-green\/8{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/8{background-color:color-mix(in oklab,var(--sys-green)8%,transparent)}}.bg-sys-green\/10{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/10{background-color:color-mix(in oklab,var(--sys-green)10%,transparent)}}.bg-sys-green\/15{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/15{background-color:color-mix(in oklab,var(--sys-green)15%,transparent)}}.bg-sys-green\/20{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/20{background-color:color-mix(in oklab,var(--sys-green)20%,transparent)}}.bg-sys-green\/25{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/25{background-color:color-mix(in oklab,var(--sys-green)25%,transparent)}}.bg-sys-green\/50{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/50{background-color:color-mix(in oklab,var(--sys-green)50%,transparent)}}.bg-sys-indigo,.bg-sys-indigo\/5{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/5{background-color:color-mix(in oklab,var(--sys-indigo)5%,transparent)}}.bg-sys-indigo\/10{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/10{background-color:color-mix(in oklab,var(--sys-indigo)10%,transparent)}}.bg-sys-indigo\/15{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/15{background-color:color-mix(in oklab,var(--sys-indigo)15%,transparent)}}.bg-sys-indigo\/20{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/20{background-color:color-mix(in oklab,var(--sys-indigo)20%,transparent)}}.bg-sys-indigo\/30{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/30{background-color:color-mix(in oklab,var(--sys-indigo)30%,transparent)}}.bg-sys-orange,.bg-sys-orange\/8{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/8{background-color:color-mix(in oklab,var(--sys-orange)8%,transparent)}}.bg-sys-orange\/15{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/15{background-color:color-mix(in oklab,var(--sys-orange)15%,transparent)}}.bg-sys-orange\/50{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/50{background-color:color-mix(in oklab,var(--sys-orange)50%,transparent)}}.bg-sys-pink,.bg-sys-pink\/8{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/8{background-color:color-mix(in oklab,var(--sys-pink)8%,transparent)}}.bg-sys-pink\/15{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/15{background-color:color-mix(in oklab,var(--sys-pink)15%,transparent)}}.bg-sys-pink\/25{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/25{background-color:color-mix(in oklab,var(--sys-pink)25%,transparent)}}.bg-sys-pink\/50{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/50{background-color:color-mix(in oklab,var(--sys-pink)50%,transparent)}}.bg-sys-purple,.bg-sys-purple\/8{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/8{background-color:color-mix(in oklab,var(--sys-purple)8%,transparent)}}.bg-sys-purple\/15{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/15{background-color:color-mix(in oklab,var(--sys-purple)15%,transparent)}}.bg-sys-purple\/50{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/50{background-color:color-mix(in oklab,var(--sys-purple)50%,transparent)}}.bg-sys-red,.bg-sys-red\/8{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/8{background-color:color-mix(in oklab,var(--sys-red)8%,transparent)}}.bg-sys-red\/10{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/10{background-color:color-mix(in oklab,var(--sys-red)10%,transparent)}}.bg-sys-red\/15{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/15{background-color:color-mix(in oklab,var(--sys-red)15%,transparent)}}.bg-sys-red\/20{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/20{background-color:color-mix(in oklab,var(--sys-red)20%,transparent)}}.bg-sys-red\/25{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/25{background-color:color-mix(in oklab,var(--sys-red)25%,transparent)}}.bg-sys-red\/50{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/50{background-color:color-mix(in oklab,var(--sys-red)50%,transparent)}}.bg-sys-teal,.bg-sys-teal\/8{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/8{background-color:color-mix(in oklab,var(--sys-teal)8%,transparent)}}.bg-sys-teal\/10{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/10{background-color:color-mix(in oklab,var(--sys-teal)10%,transparent)}}.bg-sys-teal\/15{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/15{background-color:color-mix(in oklab,var(--sys-teal)15%,transparent)}}.bg-sys-teal\/50{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/50{background-color:color-mix(in oklab,var(--sys-teal)50%,transparent)}}.bg-sys-yellow\/10{background-color:var(--sys-yellow)}@supports (color:color-mix(in lab,red,red)){.bg-sys-yellow\/10{background-color:color-mix(in oklab,var(--sys-yellow)10%,transparent)}}.bg-toggle-off{background-color:var(--toggle-off)}.bg-toggle-on{background-color:var(--toggle-on)}.bg-tooltip-bg,.bg-tooltip-bg\/80{background-color:var(--tooltip-bg)}@supports (color:color-mix(in lab,red,red)){.bg-tooltip-bg\/80{background-color:color-mix(in oklab,var(--tooltip-bg)80%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/\[0\.03\]{background-color:#ffffff08}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.03\]{background-color:color-mix(in oklab,var(--color-white)3%,transparent)}}.bg-white\/\[0\.04\]{background-color:#ffffff0a}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.04\]{background-color:color-mix(in oklab,var(--color-white)4%,transparent)}}.bg-white\/\[0\.06\]{background-color:#ffffff0f}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.06\]{background-color:color-mix(in oklab,var(--color-white)6%,transparent)}}.bg-zinc-400{background-color:var(--color-zinc-400)}.bg-zinc-500{background-color:var(--color-zinc-500)}.bg-zinc-500\/5{background-color:#71717b0d}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/5{background-color:color-mix(in oklab,var(--color-zinc-500)5%,transparent)}}.bg-zinc-500\/8{background-color:#71717b14}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/8{background-color:color-mix(in oklab,var(--color-zinc-500)8%,transparent)}}.bg-zinc-500\/10{background-color:#71717b1a}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/10{background-color:color-mix(in oklab,var(--color-zinc-500)10%,transparent)}}.bg-zinc-500\/15{background-color:#71717b26}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/15{background-color:color-mix(in oklab,var(--color-zinc-500)15%,transparent)}}.bg-zinc-500\/20{background-color:#71717b33}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/20{background-color:color-mix(in oklab,var(--color-zinc-500)20%,transparent)}}.bg-zinc-500\/40{background-color:#71717b66}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/40{background-color:color-mix(in oklab,var(--color-zinc-500)40%,transparent)}}.bg-zinc-500\/50{background-color:#71717b80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/50{background-color:color-mix(in oklab,var(--color-zinc-500)50%,transparent)}}.bg-zinc-600{background-color:var(--color-zinc-600)}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-900\/90{background-color:#18181be6}@supports (color:color-mix(in lab,red,red)){.bg-zinc-900\/90{background-color:color-mix(in oklab,var(--color-zinc-900)90%,transparent)}}.bg-cover{background-size:cover}.bg-center{background-position:50%}.bg-no-repeat{background-repeat:no-repeat}.fill-sys-green{fill:var(--sys-green)}.stroke-current{stroke:currentColor}.stroke-\[3\]{stroke-width:3px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.\!p-0{padding:calc(var(--spacing)*0)!important}.\!p-1\.5{padding:calc(var(--spacing)*1.5)!important}.\!p-2\.5{padding:calc(var(--spacing)*2.5)!important}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-0{padding-inline:calc(var(--spacing)*0)!important}.\!px-1{padding-inline:calc(var(--spacing)*1)!important}.\!px-1\.5{padding-inline:calc(var(--spacing)*1.5)!important}.px-0{padding-inline:calc(var(--spacing)*0)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.\!py-0{padding-block:calc(var(--spacing)*0)!important}.\!py-0\.5{padding-block:calc(var(--spacing)*.5)!important}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\.5{padding-block:calc(var(--spacing)*3.5)}.py-4{padding-block:calc(var(--spacing)*4)}.py-5{padding-block:calc(var(--spacing)*5)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-10{padding-block:calc(var(--spacing)*10)}.py-12{padding-block:calc(var(--spacing)*12)}.py-14{padding-block:calc(var(--spacing)*14)}.py-16{padding-block:calc(var(--spacing)*16)}.py-\[3px\]{padding-block:3px}.py-px{padding-block:1px}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-0\.5{padding-top:calc(var(--spacing)*.5)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-1\.5{padding-top:calc(var(--spacing)*1.5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-2\.5{padding-top:calc(var(--spacing)*2.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-5{padding-top:calc(var(--spacing)*5)}.pt-\[13px\]{padding-top:13px}.\!pr-0{padding-right:calc(var(--spacing)*0)!important}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pr-11{padding-right:calc(var(--spacing)*11)}.pr-\[env\(safe-area-inset-right\)\]{padding-right:env(safe-area-inset-right)}.pb-0{padding-bottom:calc(var(--spacing)*0)}.pb-0\.5{padding-bottom:calc(var(--spacing)*.5)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-2\.5{padding-left:calc(var(--spacing)*2.5)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-11{padding-left:calc(var(--spacing)*11)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-data)}.font-sans{font-family:var(--font-display)}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing)*6)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\!text-\[9px\]{font-size:9px!important}.\!text-\[10px\]{font-size:10px!important}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[20px\]{font-size:20px}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking:var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-inherit{color:inherit!important}.\!text-sys-green{color:var(--sys-green)!important}.\!text-sys-red{color:var(--sys-red)!important}.text-\[\#4A0000\]{color:#4a0000}.text-\[\#e8a517\]{color:#e8a517}.text-\[var\(--pkt-ack\)\]{color:var(--pkt-ack)}.text-\[var\(--pkt-advert\)\]{color:var(--pkt-advert)}.text-\[var\(--pkt-anon\)\]{color:var(--pkt-anon)}.text-\[var\(--pkt-control\)\]{color:var(--pkt-control)}.text-\[var\(--pkt-flood\)\]{color:var(--pkt-flood)}.text-\[var\(--pkt-grp-data\)\]{color:var(--pkt-grp-data)}.text-\[var\(--pkt-grp-txt\)\]{color:var(--pkt-grp-txt)}.text-\[var\(--pkt-path\)\]{color:var(--pkt-path)}.text-\[var\(--pkt-req\)\]{color:var(--pkt-req)}.text-\[var\(--pkt-response\)\]{color:var(--pkt-response)}.text-\[var\(--pkt-trace\)\]{color:var(--pkt-trace)}.text-\[var\(--pkt-txt-msg\)\]{color:var(--pkt-txt-msg)}.text-\[var\(--pkt-unknown\)\]{color:var(--pkt-unknown)}.text-\[var\(--route-direct\)\]{color:var(--route-direct)}.text-\[var\(--route-flood\)\]{color:var(--route-flood)}.text-\[var\(--route-transport\)\]{color:var(--route-transport)}.text-blue-500{color:var(--color-blue-500)}.text-body{color:var(--body)}.text-fg-invert,.text-fg-invert\/70{color:var(--fg-invert)}@supports (color:color-mix(in lab,red,red)){.text-fg-invert\/70{color:color-mix(in oklab,var(--fg-invert)70%,transparent)}}.text-fg-muted,.text-fg-muted\/20{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/20{color:color-mix(in oklab,var(--fg-muted)20%,transparent)}}.text-fg-muted\/30{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/30{color:color-mix(in oklab,var(--fg-muted)30%,transparent)}}.text-fg-muted\/40{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/40{color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.text-fg-muted\/50{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/50{color:color-mix(in oklab,var(--fg-muted)50%,transparent)}}.text-fg-muted\/60{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/60{color:color-mix(in oklab,var(--fg-muted)60%,transparent)}}.text-fg-muted\/70{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/70{color:color-mix(in oklab,var(--fg-muted)70%,transparent)}}.text-fg-muted\/80{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/80{color:color-mix(in oklab,var(--fg-muted)80%,transparent)}}.text-fg-primary,.text-fg-primary\/70{color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.text-fg-primary\/70{color:color-mix(in oklab,var(--fg-primary)70%,transparent)}}.text-fg-primary\/90{color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.text-fg-primary\/90{color:color-mix(in oklab,var(--fg-primary)90%,transparent)}}.text-fg-secondary,.text-fg-secondary\/60{color:var(--fg-secondary)}@supports (color:color-mix(in lab,red,red)){.text-fg-secondary\/60{color:color-mix(in oklab,var(--fg-secondary)60%,transparent)}}.text-icon-card-title{color:var(--icon-card-title)}.text-icon-page-title{color:var(--icon-page-title)}.text-icon-widget{color:var(--icon-widget)}.text-map-neighbor-color{color:var(--map-neighbor-color)}.text-signal-critical{color:var(--signal-critical)}.text-signal-excellent{color:var(--signal-excellent)}.text-signal-fair{color:var(--signal-fair)}.text-signal-good{color:var(--signal-good)}.text-signal-poor{color:var(--signal-poor)}.text-status-danger{color:var(--status-danger)}.text-status-success{color:var(--status-success)}.text-status-warning{color:var(--status-warning)}.text-sys-amber,.text-sys-amber\/60{color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.text-sys-amber\/60{color:color-mix(in oklab,var(--sys-amber)60%,transparent)}}.text-sys-amber\/70{color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.text-sys-amber\/70{color:color-mix(in oklab,var(--sys-amber)70%,transparent)}}.text-sys-blue{color:var(--sys-blue)}.text-sys-cyan{color:var(--sys-cyan)}.text-sys-green,.text-sys-green\/70{color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.text-sys-green\/70{color:color-mix(in oklab,var(--sys-green)70%,transparent)}}.text-sys-indigo,.text-sys-indigo\/70{color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.text-sys-indigo\/70{color:color-mix(in oklab,var(--sys-indigo)70%,transparent)}}.text-sys-orange{color:var(--sys-orange)}.text-sys-pink{color:var(--sys-pink)}.text-sys-purple{color:var(--sys-purple)}.text-sys-red,.text-sys-red\/70{color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.text-sys-red\/70{color:color-mix(in oklab,var(--sys-red)70%,transparent)}}.text-sys-teal{color:var(--sys-teal)}.text-sys-yellow{color:var(--sys-yellow)}.text-white{color:var(--color-white)}.text-white\/20{color:#fff3}@supports (color:color-mix(in lab,red,red)){.text-white\/20{color:color-mix(in oklab,var(--color-white)20%,transparent)}}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab,red,red)){.text-white\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-300{color:var(--color-zinc-300)}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-900{color:var(--color-zinc-900)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.accent-sys-blue{accent-color:var(--sys-blue)}.accent-sys-indigo{accent-color:var(--sys-indigo)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.opacity-100{opacity:1}.\!shadow-none{--tw-shadow:0 0 #0000!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow\!{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_4px_var\(--sys-blue\)\]{--tw-shadow:0 0 4px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_8px_var\(--sys-blue\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[inset_0_0_0_1\.5px_var\(--sys-blue\)\]{--tw-shadow:inset 0 0 0 1.5px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[var\(--neo-outer\)\]{--tw-shadow:var(--neo-outer);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[var\(--neo-outer-sm\)\]{--tw-shadow:var(--neo-outer-sm);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\!ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[1\.5px\]{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1.5px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[\#E0443E\]{--tw-ring-color:#e0443e}.ring-body{--tw-ring-color:var(--body)}.ring-edge-strong,.ring-edge-strong\/50{--tw-ring-color:var(--edge-strong)}@supports (color:color-mix(in lab,red,red)){.ring-edge-strong\/50{--tw-ring-color:color-mix(in oklab,var(--edge-strong)50%,transparent)}}.ring-edge-subtle{--tw-ring-color:var(--edge-subtle)}.ring-surface{--tw-ring-color:var(--surface)}.ring-sys-amber\/30{--tw-ring-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.ring-sys-amber\/30{--tw-ring-color:color-mix(in oklab,var(--sys-amber)30%,transparent)}}.ring-sys-amber\/50{--tw-ring-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.ring-sys-amber\/50{--tw-ring-color:color-mix(in oklab,var(--sys-amber)50%,transparent)}}.ring-sys-blue,.ring-sys-blue\/20{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/20{--tw-ring-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.ring-sys-blue\/30{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/30{--tw-ring-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.ring-sys-blue\/40{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/40{--tw-ring-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.ring-sys-blue\/50{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/50{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.ring-sys-cyan\/50{--tw-ring-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.ring-sys-cyan\/50{--tw-ring-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.ring-sys-green{--tw-ring-color:var(--sys-green)}.ring-sys-red,.ring-sys-red\/25{--tw-ring-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.ring-sys-red\/25{--tw-ring-color:color-mix(in oklab,var(--sys-red)25%,transparent)}}.ring-sys-teal\/25{--tw-ring-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.ring-sys-teal\/25{--tw-ring-color:color-mix(in oklab,var(--sys-teal)25%,transparent)}}.ring-zinc-600{--tw-ring-color:var(--color-zinc-600)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow{--tw-drop-shadow-size:drop-shadow(0 1px 2px var(--tw-drop-shadow-color,#0000001a))drop-shadow(0 1px 1px var(--tw-drop-shadow-color,#0000000f));--tw-drop-shadow:drop-shadow(0 1px 2px #0000001a)drop-shadow(0 1px 1px #0000000f);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.sepia{--tw-sepia:sepia(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-lg{--tw-backdrop-blur:blur(var(--blur-lg));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[opacity\,transform\]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,box-shadow\,background-color\]{transition-property:transform,box-shadow,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{--tw-ease:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.select-text{-webkit-user-select:text;user-select:text}.ring-inset{--tw-ring-inset:inset}:is(.\*\:w-full>*){width:100%}@media(hover:hover){.group-hover\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\:border-edge-strong:is(:where(.group):hover *){border-color:var(--edge-strong)}.group-hover\:bg-elevated:is(:where(.group):hover *){background-color:var(--elevated)}.group-hover\:bg-subtle-fill:is(:where(.group):hover *){background-color:var(--subtle-fill)}.group-hover\:text-fg-secondary:is(:where(.group):hover *){color:var(--fg-secondary)}.group-hover\:text-sys-indigo:is(:where(.group):hover *){color:var(--sys-indigo)}.group-hover\:text-white:is(:where(.group):hover *){color:var(--color-white)}.group-hover\:opacity-70:is(:where(.group):hover *){opacity:.7}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/band\:bg-sys-blue\/35:is(:where(.group\/band):hover *){background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.group-hover\/band\:bg-sys-blue\/35:is(:where(.group\/band):hover *){background-color:color-mix(in oklab,var(--sys-blue)35%,transparent)}}.group-hover\/tip\:visible:is(:where(.group\/tip):hover *){visibility:visible}.group-hover\/tip\:opacity-100:is(:where(.group\/tip):hover *){opacity:1}}.group-data-\[open\]\:rotate-180:is(:where(.group)[data-open] *){rotate:180deg}.placeholder\:text-fg-muted::placeholder,.placeholder\:text-fg-muted\/40::placeholder{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-fg-muted\/40::placeholder{color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.placeholder\:text-fg-muted\/50::placeholder{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-fg-muted\/50::placeholder{color:color-mix(in oklab,var(--fg-muted)50%,transparent)}}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:-inset-px:before{content:var(--tw-content);top:-1px;right:-1px;bottom:-1px;left:-1px}.before\:-inset-x-3:before{content:var(--tw-content);inset-inline:calc(var(--spacing)*-3)}.before\:-inset-y-1:before{content:var(--tw-content);inset-block:calc(var(--spacing)*-1)}.before\:rounded-lg:before{content:var(--tw-content);border-radius:12px}.before\:bg-subtle-fill:before{content:var(--tw-content);background-color:var(--subtle-fill)}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.odd\:bg-surface\/30:nth-child(odd){background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.odd\:bg-surface\/30:nth-child(odd){background-color:color-mix(in oklab,var(--surface)30%,transparent)}}.focus-within\:border-sys-blue:focus-within{border-color:var(--sys-blue)}@media(hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-x-150:hover{--tw-scale-x:150%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-\[1\.6\]:hover{scale:1.6}.hover\:border-edge-strong:hover{border-color:var(--edge-strong)}.hover\:border-fg-muted\/40:hover{border-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.hover\:border-fg-muted\/40:hover{border-color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.hover\:border-sys-amber:hover{border-color:var(--sys-amber)}.hover\:border-sys-blue:hover,.hover\:border-sys-blue\/30:hover{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:border-sys-blue\/30:hover{border-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:border-sys-green:hover{border-color:var(--sys-green)}.hover\:border-sys-indigo:hover{border-color:var(--sys-indigo)}.hover\:border-sys-pink:hover{border-color:var(--sys-pink)}.hover\:border-sys-purple:hover{border-color:var(--sys-purple)}.hover\:border-sys-red:hover{border-color:var(--sys-red)}.hover\:border-zinc-400:hover{border-color:var(--color-zinc-400)}.hover\:border-zinc-500:hover{border-color:var(--color-zinc-500)}.hover\:\!bg-transparent:hover{background-color:#0000!important}.hover\:bg-\[\#FF6961\]:hover{background-color:#ff6961}.hover\:bg-\[var\(--map-ui-hover\,var\(--elevated\)\)\]:hover{background-color:var(--map-ui-hover,var(--elevated))}.hover\:bg-black\/10:hover{background-color:#0000001a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/10:hover{background-color:color-mix(in oklab,var(--color-black)10%,transparent)}}.hover\:bg-elevated:hover,.hover\:bg-elevated\/30:hover{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-elevated\/30:hover{background-color:color-mix(in oklab,var(--elevated)30%,transparent)}}.hover\:bg-elevated\/80:hover{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-elevated\/80:hover{background-color:color-mix(in oklab,var(--elevated)80%,transparent)}}.hover\:bg-fg-muted:hover{background-color:var(--fg-muted)}.hover\:bg-signal-fair\/10:hover{background-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-signal-fair\/10:hover{background-color:color-mix(in oklab,var(--signal-fair)10%,transparent)}}.hover\:bg-subtle:hover{background-color:var(--subtle)}.hover\:bg-subtle-fill:hover{background-color:var(--subtle-fill)}.hover\:bg-subtle-fill-hover:hover{background-color:var(--subtle-fill-hover)}.hover\:bg-subtle-fill-strong:hover{background-color:var(--subtle-fill-strong)}.hover\:bg-surface:hover,.hover\:bg-surface\/60:hover{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-surface\/60:hover{background-color:color-mix(in oklab,var(--surface)60%,transparent)}}.hover\:bg-sys-amber:hover,.hover\:bg-sys-amber\/10:hover{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-amber\/10:hover{background-color:color-mix(in oklab,var(--sys-amber)10%,transparent)}}.hover\:bg-sys-amber\/80:hover{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-amber\/80:hover{background-color:color-mix(in oklab,var(--sys-amber)80%,transparent)}}.hover\:bg-sys-blue:hover,.hover\:bg-sys-blue\/5:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/5:hover{background-color:color-mix(in oklab,var(--sys-blue)5%,transparent)}}.hover\:bg-sys-blue\/10:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/10:hover{background-color:color-mix(in oklab,var(--sys-blue)10%,transparent)}}.hover\:bg-sys-blue\/20:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/20:hover{background-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.hover\:bg-sys-blue\/25:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/25:hover{background-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.hover\:bg-sys-blue\/30:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/30:hover{background-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:bg-sys-blue\/80:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/80:hover{background-color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.hover\:bg-sys-cyan\/10:hover{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-cyan\/10:hover{background-color:color-mix(in oklab,var(--sys-cyan)10%,transparent)}}.hover\:bg-sys-cyan\/25:hover{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-cyan\/25:hover{background-color:color-mix(in oklab,var(--sys-cyan)25%,transparent)}}.hover\:bg-sys-green:hover,.hover\:bg-sys-green\/10:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/10:hover{background-color:color-mix(in oklab,var(--sys-green)10%,transparent)}}.hover\:bg-sys-green\/15:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/15:hover{background-color:color-mix(in oklab,var(--sys-green)15%,transparent)}}.hover\:bg-sys-green\/80:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/80:hover{background-color:color-mix(in oklab,var(--sys-green)80%,transparent)}}.hover\:bg-sys-indigo:hover,.hover\:bg-sys-indigo\/5:hover{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-indigo\/5:hover{background-color:color-mix(in oklab,var(--sys-indigo)5%,transparent)}}.hover\:bg-sys-indigo\/25:hover{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-indigo\/25:hover{background-color:color-mix(in oklab,var(--sys-indigo)25%,transparent)}}.hover\:bg-sys-pink:hover{background-color:var(--sys-pink)}.hover\:bg-sys-purple:hover{background-color:var(--sys-purple)}.hover\:bg-sys-red:hover,.hover\:bg-sys-red\/8:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/8:hover{background-color:color-mix(in oklab,var(--sys-red)8%,transparent)}}.hover\:bg-sys-red\/10:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/10:hover{background-color:color-mix(in oklab,var(--sys-red)10%,transparent)}}.hover\:bg-sys-red\/15:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/15:hover{background-color:color-mix(in oklab,var(--sys-red)15%,transparent)}}.hover\:bg-tooltip-bg:hover{background-color:var(--tooltip-bg)}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\:bg-zinc-500:hover{background-color:var(--color-zinc-500)}.hover\:bg-zinc-500\/5:hover{background-color:#71717b0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/5:hover{background-color:color-mix(in oklab,var(--color-zinc-500)5%,transparent)}}.hover\:bg-zinc-500\/10:hover{background-color:#71717b1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/10:hover{background-color:color-mix(in oklab,var(--color-zinc-500)10%,transparent)}}.hover\:bg-zinc-500\/15:hover{background-color:#71717b26}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/15:hover{background-color:color-mix(in oklab,var(--color-zinc-500)15%,transparent)}}.hover\:bg-zinc-500\/20:hover{background-color:#71717b33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/20:hover{background-color:color-mix(in oklab,var(--color-zinc-500)20%,transparent)}}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-body:hover{color:var(--body)}.hover\:text-fg-invert:hover{color:var(--fg-invert)}.hover\:text-fg-muted:hover{color:var(--fg-muted)}.hover\:text-fg-primary:hover{color:var(--fg-primary)}.hover\:text-fg-secondary:hover{color:var(--fg-secondary)}.hover\:text-sys-blue:hover,.hover\:text-sys-blue\/80:hover{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:text-sys-blue\/80:hover{color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.hover\:text-sys-cyan:hover{color:var(--sys-cyan)}.hover\:text-sys-indigo:hover{color:var(--sys-indigo)}.hover\:text-sys-purple:hover{color:var(--sys-purple)}.hover\:text-sys-red:hover{color:var(--sys-red)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-zinc-300:hover{color:var(--color-zinc-300)}.hover\:text-zinc-400:hover{color:var(--color-zinc-400)}.hover\:text-zinc-900:hover{color:var(--color-zinc-900)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_8px_var\(--sys-blue\)\]:hover{--tw-shadow:0 0 8px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-none:hover{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-2:hover{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-sys-blue:hover,.hover\:ring-sys-blue\/30:hover{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:ring-sys-blue\/30:hover{--tw-ring-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:ring-sys-indigo:hover{--tw-ring-color:var(--sys-indigo)}}.focus\:border-sys-blue:focus,.focus\:border-sys-blue\/50:focus{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus\:border-sys-blue\/50:focus{border-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus\:border-zinc-500:focus{border-color:var(--color-zinc-500)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-edge-strong:focus{--tw-ring-color:var(--edge-strong)}.focus\:ring-signal-fair\/50:focus{--tw-ring-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-signal-fair\/50:focus{--tw-ring-color:color-mix(in oklab,var(--signal-fair)50%,transparent)}}.focus\:ring-sys-blue:focus,.focus\:ring-sys-blue\/50:focus{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-sys-blue\/50:focus{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus\:ring-sys-cyan\/50:focus{--tw-ring-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-sys-cyan\/50:focus{--tw-ring-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[\#FF5F57\]:focus-visible{--tw-ring-color:#ff5f57}.focus-visible\:ring-sys-blue\/50:focus-visible{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-sys-blue\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-90:active{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:cursor-grabbing:active{cursor:grabbing}.active\:bg-\[\#E04840\]:active{background-color:#e04840}.active\:bg-\[var\(--map-ui-active\,var\(--subtle\)\)\]:active{background-color:var(--map-ui-active,var(--subtle))}.active\:bg-elevated:active{background-color:var(--elevated)}.active\:bg-subtle-fill:active{background-color:var(--subtle-fill)}.active\:bg-subtle-fill-hover:active{background-color:var(--subtle-fill-hover)}.active\:bg-subtle-fill-strong:active{background-color:var(--subtle-fill-strong)}.active\:bg-sys-amber\/70:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/70:active{background-color:color-mix(in oklab,var(--sys-amber)70%,transparent)}}.active\:bg-sys-amber\/80:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/80:active{background-color:color-mix(in oklab,var(--sys-amber)80%,transparent)}}.active\:bg-sys-amber\/90:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/90:active{background-color:color-mix(in oklab,var(--sys-amber)90%,transparent)}}.active\:bg-sys-blue\/70:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/70:active{background-color:color-mix(in oklab,var(--sys-blue)70%,transparent)}}.active\:bg-sys-blue\/80:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/80:active{background-color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.active\:bg-sys-blue\/90:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/90:active{background-color:color-mix(in oklab,var(--sys-blue)90%,transparent)}}.active\:bg-sys-green\/70:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/70:active{background-color:color-mix(in oklab,var(--sys-green)70%,transparent)}}.active\:bg-sys-green\/80:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/80:active{background-color:color-mix(in oklab,var(--sys-green)80%,transparent)}}.active\:bg-sys-green\/90:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/90:active{background-color:color-mix(in oklab,var(--sys-green)90%,transparent)}}.active\:bg-sys-indigo\/80:active{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-indigo\/80:active{background-color:color-mix(in oklab,var(--sys-indigo)80%,transparent)}}.active\:bg-sys-indigo\/90:active{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-indigo\/90:active{background-color:color-mix(in oklab,var(--sys-indigo)90%,transparent)}}.active\:bg-sys-pink\/80:active{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-pink\/80:active{background-color:color-mix(in oklab,var(--sys-pink)80%,transparent)}}.active\:bg-sys-pink\/90:active{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-pink\/90:active{background-color:color-mix(in oklab,var(--sys-pink)90%,transparent)}}.active\:bg-sys-purple\/80:active{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-purple\/80:active{background-color:color-mix(in oklab,var(--sys-purple)80%,transparent)}}.active\:bg-sys-purple\/90:active{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-purple\/90:active{background-color:color-mix(in oklab,var(--sys-purple)90%,transparent)}}.active\:bg-sys-red\/80:active{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-red\/80:active{background-color:color-mix(in oklab,var(--sys-red)80%,transparent)}}.active\:bg-sys-red\/90:active{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-red\/90:active{background-color:color-mix(in oklab,var(--sys-red)90%,transparent)}}.active\:bg-tooltip-bg:active{background-color:var(--tooltip-bg)}.active\:bg-zinc-500\/80:active{background-color:#71717bcc}@supports (color:color-mix(in lab,red,red)){.active\:bg-zinc-500\/80:active{background-color:color-mix(in oklab,var(--color-zinc-500)80%,transparent)}}.active\:bg-zinc-500\/90:active{background-color:#71717be6}@supports (color:color-mix(in lab,red,red)){.active\:bg-zinc-500\/90:active{background-color:color-mix(in oklab,var(--color-zinc-500)90%,transparent)}}.active\:bg-zinc-700:active{background-color:var(--color-zinc-700)}.active\:text-sys-blue\/70:active{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:text-sys-blue\/70:active{color:color-mix(in oklab,var(--sys-blue)70%,transparent)}}.active\:text-sys-blue\/80:active{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:text-sys-blue\/80:active{color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.active\:text-white:active{color:var(--color-white)}.active\:text-zinc-900:active{color:var(--color-zinc-900)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-25:disabled{opacity:.25}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media(hover:hover){.disabled\:hover\:bg-transparent:disabled:hover{background-color:#0000}}.data-\[closed\]\:-translate-y-1[data-closed]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[closed\]\:scale-\[0\.98\][data-closed]{scale:.98}.data-\[closed\]\:opacity-0[data-closed]{opacity:0}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[enter\]\:duration-150[data-enter]{--tw-duration:.15s;transition-duration:.15s}.data-\[enter\]\:ease-out[data-enter]{--tw-ease:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.data-\[focus\]\:bg-sys-blue[data-focus]{background-color:var(--sys-blue)}.data-\[focus\]\:bg-sys-red[data-focus]{background-color:var(--sys-red)}.data-\[focus\]\:text-white[data-focus]{color:var(--color-white)}.data-\[leave\]\:duration-100[data-leave]{--tw-duration:.1s;transition-duration:.1s}.data-\[leave\]\:ease-in[data-leave]{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}@media(min-width:520px){.min-\[520px\]\:inline{display:inline}}@media(min-width:600px){.min-\[600px\]\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.min-\[600px\]\:gap-3{gap:calc(var(--spacing)*3)}.min-\[600px\]\:px-3{padding-inline:calc(var(--spacing)*3)}.min-\[600px\]\:py-2\.5{padding-block:calc(var(--spacing)*2.5)}}@media(min-width:900px){.min-\[900px\]\:block{display:block}.min-\[900px\]\:gap-2{gap:calc(var(--spacing)*2)}}@media(min-width:40rem){.sm\:top-4{top:calc(var(--spacing)*4)}.sm\:right-3{right:calc(var(--spacing)*3)}.sm\:right-4{right:calc(var(--spacing)*4)}.sm\:bottom-16{bottom:calc(var(--spacing)*16)}.sm\:left-auto{left:auto}.sm\:order-first{order:-9999}.sm\:order-last{order:9999}.sm\:col-span-1{grid-column:span 1/span 1}.sm\:-mx-6{margin-inline:calc(var(--spacing)*-6)}.sm\:mx-0{margin-inline:calc(var(--spacing)*0)}.sm\:mt-1{margin-top:calc(var(--spacing)*1)}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:mt-4{margin-top:calc(var(--spacing)*4)}.sm\:mr-0{margin-right:calc(var(--spacing)*0)}.sm\:-mb-6{margin-bottom:calc(var(--spacing)*-6)}.sm\:mb-1{margin-bottom:calc(var(--spacing)*1)}.sm\:mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.sm\:mb-2{margin-bottom:calc(var(--spacing)*2)}.sm\:mb-3{margin-bottom:calc(var(--spacing)*3)}.sm\:-ml-5{margin-left:calc(var(--spacing)*-5)}.sm\:-ml-px{margin-left:-1px}.sm\:ml-9{margin-left:calc(var(--spacing)*9)}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-3{height:calc(var(--spacing)*3)}.sm\:h-3\.5{height:calc(var(--spacing)*3.5)}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:h-6{height:calc(var(--spacing)*6)}.sm\:h-\[85vh\]{height:85vh}.sm\:h-\[500px\]{height:500px}.sm\:h-\[520px\]{height:520px}.sm\:max-h-96{max-height:calc(var(--spacing)*96)}.sm\:max-h-\[420px\]{max-height:420px}.sm\:max-h-\[600px\]{max-height:600px}.sm\:max-h-\[800px\]{max-height:800px}.sm\:max-h-\[calc\(100dvh-234px\)\]{max-height:calc(100dvh - 234px)}.sm\:max-h-\[calc\(100vh-180px\)\]{max-height:calc(100vh - 180px)}.sm\:min-h-0{min-height:calc(var(--spacing)*0)}.sm\:min-h-\[60px\]{min-height:60px}.sm\:w-3{width:calc(var(--spacing)*3)}.sm\:w-3\.5{width:calc(var(--spacing)*3.5)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-5{width:calc(var(--spacing)*5)}.sm\:w-6{width:calc(var(--spacing)*6)}.sm\:w-9{width:calc(var(--spacing)*9)}.sm\:w-12{width:calc(var(--spacing)*12)}.sm\:w-14{width:calc(var(--spacing)*14)}.sm\:w-16{width:calc(var(--spacing)*16)}.sm\:w-32{width:calc(var(--spacing)*32)}.sm\:w-40{width:calc(var(--spacing)*40)}.sm\:w-48{width:calc(var(--spacing)*48)}.sm\:w-64{width:calc(var(--spacing)*64)}.sm\:w-\[280px\]{width:280px}.sm\:w-auto{width:auto}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-3xl{max-width:var(--container-3xl)}.sm\:max-w-4xl{max-width:var(--container-4xl)}.sm\:max-w-5xl{max-width:var(--container-5xl)}.sm\:max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-none{max-width:none}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:min-w-0{min-width:calc(var(--spacing)*0)}.sm\:min-w-\[32px\]{min-width:32px}.sm\:min-w-\[180px\]{min-width:180px}.sm\:min-w-\[220px\]{min-width:220px}.sm\:min-w-\[540px\]{min-width:540px}.sm\:min-w-\[700px\]{min-width:700px}.sm\:flex-1{flex:1}.sm\:flex-initial{flex:0 auto}.sm\:flex-shrink-0{flex-shrink:0}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-\[280px_minmax\(400px\,1fr\)\]{grid-template-columns:280px minmax(400px,1fr)}.sm\:grid-cols-\[auto_minmax\(0\,1fr\)_auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr)}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-0\.5{gap:calc(var(--spacing)*.5)}.sm\:gap-1{gap:calc(var(--spacing)*1)}.sm\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.sm\:gap-2{gap:calc(var(--spacing)*2)}.sm\:gap-3{gap:calc(var(--spacing)*3)}.sm\:gap-4{gap:calc(var(--spacing)*4)}.sm\:gap-5{gap:calc(var(--spacing)*5)}.sm\:gap-6{gap:calc(var(--spacing)*6)}.sm\:gap-8{gap:calc(var(--spacing)*8)}:where(.sm\:space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}.sm\:gap-x-3{column-gap:calc(var(--spacing)*3)}.sm\:gap-x-4{column-gap:calc(var(--spacing)*4)}.sm\:gap-y-0\.5{row-gap:calc(var(--spacing)*.5)}.sm\:gap-y-2{row-gap:calc(var(--spacing)*2)}:where(.sm\:divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px*var(--tw-divide-x-reverse));border-inline-end-width:calc(1px*calc(1 - var(--tw-divide-x-reverse)))}:where(.sm\:divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px*var(--tw-divide-y-reverse));border-bottom-width:calc(0px*calc(1 - var(--tw-divide-y-reverse)))}.sm\:overflow-visible{overflow:visible}.sm\:\!p-0\.5{padding:calc(var(--spacing)*.5)!important}.sm\:\!p-1\.5{padding:calc(var(--spacing)*1.5)!important}.sm\:p-0\.5{padding:calc(var(--spacing)*.5)}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}.sm\:p-4{padding:calc(var(--spacing)*4)}.sm\:p-5{padding:calc(var(--spacing)*5)}.sm\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\:px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.sm\:px-4{padding-inline:calc(var(--spacing)*4)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:px-6{padding-inline:calc(var(--spacing)*6)}.sm\:py-1{padding-block:calc(var(--spacing)*1)}.sm\:py-1\.5{padding-block:calc(var(--spacing)*1.5)}.sm\:py-2{padding-block:calc(var(--spacing)*2)}.sm\:py-3{padding-block:calc(var(--spacing)*3)}.sm\:py-4{padding-block:calc(var(--spacing)*4)}.sm\:pt-2{padding-top:calc(var(--spacing)*2)}.sm\:pt-3{padding-top:calc(var(--spacing)*3)}.sm\:pt-4{padding-top:calc(var(--spacing)*4)}.sm\:pr-0{padding-right:calc(var(--spacing)*0)}.sm\:pr-6{padding-right:calc(var(--spacing)*6)}.sm\:pb-3{padding-bottom:calc(var(--spacing)*3)}.sm\:pb-4{padding-bottom:calc(var(--spacing)*4)}.sm\:pb-6{padding-bottom:calc(var(--spacing)*6)}.sm\:pl-2{padding-left:calc(var(--spacing)*2)}.sm\:pl-11{padding-left:calc(var(--spacing)*11)}.sm\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sm\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.sm\:text-\[11px\]{font-size:11px}.sm\:opacity-100{opacity:1}:is(.sm\:\*\:w-auto>*){width:auto}}@media(min-width:48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:h-\[80vh\]{height:80vh}.md\:h-\[600px\]{height:600px}.md\:max-h-\[900px\]{max-height:900px}.md\:w-72{width:calc(var(--spacing)*72)}.md\:min-w-\[680px\]{min-width:680px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media(min-width:64rem){.lg\:-mx-3{margin-inline:calc(var(--spacing)*-3)}.lg\:-mx-8{margin-inline:calc(var(--spacing)*-8)}.lg\:-mb-8{margin-bottom:calc(var(--spacing)*-8)}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:table-cell{display:table-cell}.lg\:h-dvh{height:100dvh}.lg\:max-h-\[calc\(100vh-194px\)\]{max-height:calc(100vh - 194px)}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.lg\:px-4{padding-inline:calc(var(--spacing)*4)}.lg\:px-8{padding-inline:calc(var(--spacing)*8)}.lg\:pt-0{padding-top:calc(var(--spacing)*0)}.lg\:pb-8{padding-bottom:calc(var(--spacing)*8)}}@media(min-width:80rem){.xl\:inline{display:inline}.xl\:w-44{width:calc(var(--spacing)*44)}}@media(prefers-color-scheme:dark){.dark\:bg-zinc-800{background-color:var(--color-zinc-800)}}.\[\&_button\]\:min-h-0 button{min-height:calc(var(--spacing)*0)}.\[\&_button\]\:px-2 button{padding-inline:calc(var(--spacing)*2)}.\[\&_button\]\:py-1 button{padding-block:calc(var(--spacing)*1)}.\[\&_button\]\:text-xs button{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_svg\]\:text-fg-muted svg{color:var(--fg-muted)}.\[\&_svg\]\:text-sys-blue svg{color:var(--sys-blue)}@media(hover:hover){.hover\:\[\&_svg\]\:text-fg-primary:hover svg{color:var(--fg-primary)}}.\[\&\:\:-moz-range-thumb\]\:h-4::-moz-range-thumb{height:calc(var(--spacing)*4)}.\[\&\:\:-moz-range-thumb\]\:w-4::-moz-range-thumb{width:calc(var(--spacing)*4)}.\[\&\:\:-moz-range-thumb\]\:cursor-pointer::-moz-range-thumb{cursor:pointer}.\[\&\:\:-moz-range-thumb\]\:appearance-none::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb{border-radius:3.40282e38px}.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-webkit-slider-thumb\]\:h-2\.5::-webkit-slider-thumb{height:calc(var(--spacing)*2.5)}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:h-3\.5::-webkit-slider-thumb{height:calc(var(--spacing)*3.5)}.\[\&\:\:-webkit-slider-thumb\]\:h-4::-webkit-slider-thumb{height:calc(var(--spacing)*4)}.\[\&\:\:-webkit-slider-thumb\]\:w-2\.5::-webkit-slider-thumb{width:calc(var(--spacing)*2.5)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3\.5::-webkit-slider-thumb{width:calc(var(--spacing)*3.5)}.\[\&\:\:-webkit-slider-thumb\]\:w-4::-webkit-slider-thumb{width:calc(var(--spacing)*4)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-sys-blue::-webkit-slider-thumb{background-color:var(--sys-blue)}.\[\&\:\:-webkit-slider-thumb\]\:bg-sys-indigo::-webkit-slider-thumb{background-color:var(--sys-indigo)}.\[\&\:\:-webkit-slider-thumb\]\:shadow-lg::-webkit-slider-thumb{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\[\&\:\:-webkit-slider-thumb\]\:shadow-md::-webkit-slider-thumb{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\[\&\:\:-webkit-slider-thumb\]\:transition-transform::-webkit-slider-thumb{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.\[\&\:\:-webkit-slider-thumb\]\:hover\:scale-110::-webkit-slider-thumb:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}}.\[\&\>\[data-slot\=icon\]\]\:h-4>[data-slot=icon]{height:calc(var(--spacing)*4)}.\[\&\>\[data-slot\=icon\]\]\:w-4>[data-slot=icon]{width:calc(var(--spacing)*4)}.\[\&\>\[data-slot\=icon\]\]\:shrink-0>[data-slot=icon]{flex-shrink:0}.\[\&\>\[data-slot\=section\]\+\[data-slot\=section\]\]\:mt-2\.5>[data-slot=section]+[data-slot=section]{margin-top:calc(var(--spacing)*2.5)}.\[\&\>\[data-slot\=section\]\+\[data-slot\=section\]\]\:mt-6>[data-slot=section]+[data-slot=section]{margin-top:calc(var(--spacing)*6)}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing)*3)}.\[\&\>svg\]\:h-4>svg{height:calc(var(--spacing)*4)}.\[\&\>svg\]\:h-\[1em\]>svg{height:1em}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing)*3)}.\[\&\>svg\]\:w-4>svg{width:calc(var(--spacing)*4)}.\[\&\>svg\]\:w-\[1em\]>svg{width:1em}.\[\&\>svg\]\:flex-shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:stroke-\[1\.5\]>svg{stroke-width:1.5px}@media(pointer:fine){.\[\@media\(pointer\:fine\)\]\:hidden{display:none}}}@supports (color:color(display-p3 1 1 1)){:root{--sys-red:color(display-p3 .898 .282 .302);--sys-orange:color(display-p3 .969 .42 .082);--sys-amber:color(display-p3 1 .698 .141);--sys-yellow:color(display-p3 .961 .851 .039);--sys-green:color(display-p3 .275 .655 .345);--sys-teal:color(display-p3 .071 .647 .58);--sys-cyan:color(display-p3 0 .635 .78);--sys-blue:color(display-p3 .231 .51 .965);--sys-indigo:color(display-p3 .357 .357 .839);--sys-purple:color(display-p3 .557 .306 .776);--sys-pink:color(display-p3 .839 .251 .624)}}a,button,[role=button],.interactive,.surface-base,[data-card-surface],.pill-tag,.pill-subtle,.toggle-group-item,.roster-row,.nav-item{transition:all .15s ease-out}a:hover,button:hover,[role=button]:hover,.interactive:hover,.surface-base:hover,[data-card-surface]:hover,.pill-tag:hover,.pill-subtle:hover,.toggle-group-item:hover,.roster-row:hover,.nav-item:hover{transition-duration:0s}a,button,[role=button],input,select,textarea{touch-action:manipulation;-webkit-tap-highlight-color:transparent}a,button{cursor:pointer}.truncate[title],.line-clamp-1[title],.line-clamp-2[title],.text-ellipsis[title]{cursor:help;position:relative}.truncate[title]:hover:after,.line-clamp-1[title]:hover:after,.line-clamp-2[title]:hover:after,.text-ellipsis[title]:hover:after{content:attr(title);z-index:9999;background:var(--tooltip-bg);border:1px solid var(--tooltip-border);width:max-content;max-width:300px;box-shadow:var(--tooltip-shadow);font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--tooltip-fg);white-space:normal;word-break:break-all;pointer-events:none;border-radius:6px;margin-top:4px;padding:6px 10px;line-height:1.4;animation:.15s ease-out tooltip-fade-in;position:absolute;top:100%;left:0}@keyframes tooltip-fade-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}.type-hero{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-5xl);font-weight:var(--font-semibold);letter-spacing:var(--tracking-tight);color:var(--fg-primary);line-height:1.05}.type-metric{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-4xl);font-weight:var(--font-semibold);letter-spacing:var(--tracking-tight);color:var(--fg-primary);line-height:1.1}.type-title{font-family:var(--font-title),system-ui,sans-serif;font-size:var(--text-2xl);font-weight:var(--font-semibold);line-height:var(--leading-snug);letter-spacing:var(--tracking-tight);color:var(--fg-primary)}.type-heading{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-lg);font-weight:var(--font-semibold);line-height:var(--leading-snug);color:var(--fg-primary)}.type-subheading{font-family:var(--font-card-title,var(--font-display)),system-ui,sans-serif;font-size:var(--text-card-title,var(--text-lg));font-weight:var(--font-card-title-weight,var(--font-semibold));line-height:var(--leading-snug);color:var(--fg-primary)}.type-body{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-base);font-weight:var(--font-normal);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-body-lg{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-md);font-weight:var(--font-normal);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-body-sm,.type-label{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-sm);font-weight:var(--font-medium);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-micro{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-normal);letter-spacing:.12em;text-transform:uppercase;color:var(--fg-secondary)}.type-data{font-family:var(--font-data);font-size:var(--text-base);font-weight:var(--font-normal);line-height:var(--leading-normal);letter-spacing:var(--tracking-wide);font-feature-settings:"zero","tnum"}.type-data-lg{font-family:var(--font-data);font-size:var(--text-lg);font-weight:var(--font-medium);line-height:var(--leading-snug);letter-spacing:var(--tracking-normal);font-feature-settings:"zero","tnum"}.type-data-xl{font-family:var(--font-data);font-size:var(--text-xl);font-weight:var(--font-semibold);line-height:var(--leading-snug);letter-spacing:-.01em;font-feature-settings:"zero","tnum"}.type-data-hero{font-family:var(--font-data);font-size:var(--text-2xl);font-weight:var(--font-semibold);letter-spacing:-.03em;font-feature-settings:"zero","tnum";line-height:1.1}@media(min-width:640px){.type-data-hero{font-size:var(--text-3xl)}}:root{--punc-margin-comma:-.15em;--punc-margin-period:-.12em;--punc-margin-colon:-.08em;--punc-margin-slash:-.06em;--punc-margin-mult:-.1em}.data-tight{display:inline}.data-tight .punc,.punc-tight{margin-right:var(--punc-margin-comma);margin-left:-.05em;display:inline-block}.data-tight .punc-period,.punc-period{margin-right:var(--punc-margin-period);margin-left:-.03em}.data-tight .punc-colon,.punc-colon{margin-right:var(--punc-margin-colon);margin-left:var(--punc-margin-colon)}.data-tight .punc-slash,.punc-slash{margin-right:var(--punc-margin-slash);margin-left:var(--punc-margin-slash)}.data-tight .punc-mult,.punc-mult{margin-right:var(--punc-margin-mult);margin-left:0;display:inline-block}.type-data-sm{font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);line-height:var(--leading-normal);letter-spacing:var(--tracking-wider);font-feature-settings:"zero","tnum"}.type-data-xs{font-family:var(--font-data);font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-normal);letter-spacing:var(--tracking-widest);font-feature-settings:"zero","tnum"}.type-data-2xs{font-family:var(--font-data);font-size:.5625rem;font-weight:var(--font-medium);letter-spacing:var(--tracking-wider);font-feature-settings:"zero","tnum";line-height:1.2}.type-code{font-family:var(--font-data);font-size:.875em;font-weight:var(--font-normal);line-height:var(--leading-relaxed);font-feature-settings:"zero","tnum"}.type-badge{font-family:var(--font-data);font-size:var(--text-xs);font-weight:var(--font-medium);letter-spacing:.08em;text-transform:uppercase;line-height:1}.type-tag{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-xs);font-weight:var(--font-medium);letter-spacing:.05em;line-height:1}.font-mono{font-feature-settings:"zero";font-family:var(--font-data)!important}.font-title{font-family:var(--font-title),system-ui,sans-serif!important}.font-display{font-family:var(--font-display),system-ui,sans-serif!important}.tabular-nums{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.lucide{stroke-width:1.75px}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0)}.pt-safe{padding-top:env(safe-area-inset-top,0)}.pl-safe{padding-left:env(safe-area-inset-left,0)}.pr-safe{padding-right:env(safe-area-inset-right,0)}.p-safe{padding-top:env(safe-area-inset-top,0);padding-right:env(safe-area-inset-right,0);padding-bottom:env(safe-area-inset-bottom,0);padding-left:env(safe-area-inset-left,0)}@keyframes shimmer{0%{opacity:.5;transform:translate(-100%)}50%{opacity:1}to{opacity:.5;transform:translate(100%)}}:root{--duration-instant:75ms;--duration-fast:.15s;--duration-normal:.2s;--duration-slow:.3s;--duration-slower:.5s;--ease-linear:linear;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--ease-bounce:cubic-bezier(.34,1.56,.64,1);--ease-spring:cubic-bezier(.175,.885,.32,1.275);--hover-scale-subtle:1.02;--hover-scale-pop:1.05;--hover-lift-y:-2px;--hover-lift-shadow:0 4px 12px #00000026;--active-scale:.98;--active-opacity:.9;--active-y:1px;--disabled-opacity:.4;--loading-opacity:.6}.interactive{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out);cursor:pointer}.interactive-fast{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-instant);transition-timing-function:var(--ease-out);cursor:pointer}.interactive-slow{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-normal);transition-timing-function:var(--ease-in-out);cursor:pointer}.hover-bg:hover{background-color:var(--subtle-fill-hover)}.hover-bg-strong:hover{background-color:var(--subtle-fill-strong)}.hover-lift:hover{transform:translateY(var(--hover-lift-y));box-shadow:var(--hover-lift-shadow)}.hover-scale:hover{transform:scale(var(--hover-scale-subtle))}.hover-pop:hover{transform:scale(var(--hover-scale-pop))}.hover-bright:hover{filter:brightness(1.1)}.hover-dim:hover{filter:brightness(.95)}.hover-opacity:hover{opacity:.8}.hover-stroke:hover{box-shadow:inset 0 0 0 1.5px var(--edge-subtle)}.hover-border:hover{border-color:var(--edge-strong)}.hover-text:hover{color:var(--fg-primary)}.row-hover{transition-property:background-color,border-color,color;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.row-hover:hover{background-color:var(--subtle-fill-hover)}.card-hover{transition-property:transform,box-shadow,border-color;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.card-hover:hover{transform:translateY(var(--hover-lift-y));box-shadow:var(--surface-shadow-md)}.btn-hover{transition-property:background-color,border-color,color,transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.btn-hover:hover{background-color:var(--subtle-fill-hover)}.icon-hover{transition-property:transform,filter,opacity;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.icon-hover:hover{transform:scale(var(--hover-scale-subtle));filter:brightness(1.15)}.active-press:active{transform:scale(var(--active-scale))}.active-depress:active{transform:translateY(var(--active-y))}.active-dim:active{opacity:var(--active-opacity)}.active-full:active{transform:scale(var(--active-scale));opacity:var(--active-opacity)}.state-disabled,.disabled{pointer-events:none;opacity:var(--disabled-opacity);cursor:not-allowed}.state-loading,.loading{pointer-events:none;opacity:var(--loading-opacity);cursor:wait}.loading-pulse{pointer-events:none;animation:pulse 1.5s var(--ease-in-out)infinite}@keyframes pulse{50%{opacity:.5}}.transition-base{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-colors{transition-property:background-color,border-color,color,fill,stroke;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-transform{transition-property:transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-in-out)}.transition-opacity{transition-property:opacity;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-shadow{transition-property:box-shadow;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}:root{--radius-xs:4px;--radius-sm:6px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:20px;--radius-3xl:24px;--surface-opacity-base:80%;--surface-opacity-elevated:85%;--surface-opacity-solid:95%;--surface-blur-sm:8px;--surface-blur-md:16px;--surface-blur-lg:24px;--surface-ring:inset 0 1px 0 0 #ffffff17,inset 1px 0 0 0 #ffffff12,inset 0 -1px 0 0 #0000008c,inset -1px 0 0 0 #00000073;--surface-ring-strong:inset 0 1px 0 0 #ffffff24,inset 1px 0 0 0 #ffffff1c,inset 0 -1px 0 0 #000000a6,inset -1px 0 0 0 #0000008c;--surface-shadow-sm:0 4px 6px -4px #0000001a;--surface-shadow-md:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--surface-shadow-lg:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--surface-shadow-xl:0 25px 50px -12px #00000040;--surface-tint-subtle:#ffffff08;--surface-tint-light:#ffffff0d;--surface-border-subtle:#ffffff0d;--stroke-none:0px;--stroke-thin:1px;--stroke-medium:1.5px;--stroke-thick:2px;--ring-width-default:2px;--ring-width-thick:3px;--ring-offset:2px;--ring-color:var(--sys-blue);--ring-color-error:var(--sys-red)}[data-mode=light]{--surface-ring:inset 0 1px 0 0 #ffffff8c,inset 1px 0 0 0 #ffffff73,inset 0 -1px 0 0 #0000001a,inset -1px 0 0 0 #00000014;--surface-ring-strong:inset 0 1px 0 0 #ffffffa6,inset 1px 0 0 0 #ffffff8c,inset 0 -1px 0 0 #00000024,inset -1px 0 0 0 #0000001c}.surface-base{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-base{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-base{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));box-shadow:var(--surface-ring)}.surface-elevated{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-elevated{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-elevated),transparent)}}.surface-elevated{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));box-shadow:var(--surface-ring),var(--surface-shadow-lg)}.surface-modal{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-modal{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-modal{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));box-shadow:var(--surface-ring),var(--surface-shadow-xl)}.surface-sidebar{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-sidebar{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-sidebar{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));border-right:1px solid var(--edge-subtle)}.surface-header{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.surface-header{background-color:color-mix(in srgb,var(--body)70%,transparent)}}.surface-header{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));border-bottom:1px solid var(--edge-subtle)}.surface-header[data-variant=dark]{-webkit-backdrop-filter:blur(var(--surface-blur-sm));backdrop-filter:blur(var(--surface-blur-sm));border-bottom-color:var(--edge-subtle);background-color:#000c}@supports (color:color-mix(in lab,red,red)){.surface-header[data-variant=dark]{border-bottom-color:color-mix(in srgb,var(--edge-subtle)50%,transparent)}}.surface-popover{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-popover{background-color:color-mix(in srgb,var(--surface)72%,transparent)}}.surface-popover{-webkit-backdrop-filter:blur(var(--surface-blur-lg))saturate(1.3);backdrop-filter:blur(var(--surface-blur-lg))saturate(1.3);box-shadow:var(--surface-ring-strong),var(--surface-shadow-xl)}.surface-inner{background-color:var(--surface-tint-subtle);border:1px solid var(--surface-border-subtle);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px #0000000d}.surface-badge{background-color:var(--surface-tint-light);box-shadow:var(--surface-ring)}.surface-control{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.surface-control{background-color:color-mix(in srgb,var(--elevated)92%,transparent)}}.surface-control{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));border:1px solid var(--edge-subtle);box-shadow:var(--surface-shadow-md)}.surface-input{background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);transition:border-color .15s,box-shadow .15s}.surface-input:focus{box-shadow:inset 0 0 0 2px var(--sys-blue)}.surface-checkbox{background-color:var(--surface-tint-light);border:1px solid var(--edge-subtle);transition:background-color .15s,border-color .15s}.surface-checkbox:checked{background-color:var(--sys-blue);border-color:var(--sys-blue)}.surface-reflex{box-shadow:var(--surface-ring),inset 1.5px 2.5px 0 -1.5px #ffffff40,inset -1.5px -1.5px 0 -1.5px #fff3,inset -2px -6px 1px -4px #ffffff26,inset 0 2px 3px -1.5px #0000001f,inset -.25px -1px 3px #00000014;position:relative;overflow:hidden}[data-mode=light] .surface-reflex{box-shadow:var(--surface-ring),inset 1.5px 2.5px 0 -1.5px #fff9,inset -1.5px -1.5px 0 -1.5px #fff6,inset -2px -6px 1px -4px #ffffff4d,inset 0 2px 3px -1.5px #0000000f,inset -.25px -1px 3px #0000000a}.surface-reflex:before{content:"";pointer-events:none;border-radius:inherit;background:linear-gradient(#ffffff0f,#0000 30px),linear-gradient(0deg,#0000000a,#0000 40px);position:absolute;top:0;right:0;bottom:0;left:0}[data-mode=light] .surface-reflex:before{background:linear-gradient(#fff6,#0000 30px),linear-gradient(0deg,#00000005,#0000 40px)}.surface-themed[data-theme=terminal]{background-color:var(--terminal-bg)}.surface-themed[data-theme=terminal-input]{background-color:var(--terminal-bg-input);border-top:1px solid var(--terminal-border)}.surface-themed[data-theme=terminal-status]{background-color:var(--terminal-bg-status);border-top:1px solid var(--terminal-border)}.surface-themed[data-theme=terminal-autocomplete]{background-color:var(--terminal-autocomplete-bg);-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));border:1px solid var(--terminal-autocomplete-border);box-shadow:var(--surface-shadow-xl),var(--surface-shadow-lg)}.surface-divider-bottom{border-bottom:1px solid var(--edge-subtle)}.surface-divider-top{border-top:1px solid var(--edge-subtle)}.surface-divider[data-theme=terminal]{border-color:var(--terminal-border)}:root{--depth-raised:-4px -4px 10px #ffffff03,4px 4px 10px #0000001a,-1px -1px 3px #ffffff02,1px 1px 3px #0001,inset -2px -2px 6px #00000026;--depth-raised-soft:-4px -4px 10px #ffffff02,4px 4px 10px #00000010,-1px -1px 3px #ffffff01,1px 1px 3px #0000000a,inset -2px -2px 6px #0000000a;--depth-inset:inset 3px 3px 6px #0009,inset -3px -3px 6px #ffffff0d,inset 0 1px 2px #0006,inset 0 -1px 1px #ffffff0a;--depth-inset-soft:inset 2px 2px 4px #00000059,inset -2px -2px 4px #ffffff08,1px 1px 2px #ffffff08,-1px -1px 2px #0000004d;--depth-stroke-tl:inset 0 1px 0 0 #ffffff17,inset 1px 0 0 0 #ffffff12;--depth-stroke-br:inset 0 -1px 0 0 #0000008c,inset -1px 0 0 0 #00000073;--neo-toggle-inset:inset 2px 2px 5px #0000004d,inset -1px -1px 3px #ffffff0a,inset 0 1px 2px #0003;--neo-toggle-raised:-2px -2px 5px #ffffff08,2px 2px 5px #00000040,-.5px -.5px 1px #ffffff05,.5px .5px 1px #00000026,inset 1px 1px 2px #ffffff0a,inset -1px -1px 2px #00000014}[data-mode=light]{--depth-raised:-3px -3px 6px #00000002,3px 3px 6px #00000006,-1px -1px 2px #0000,1px 1px 2px #00000001,inset -1px -1px 3px #0000001a;--depth-raised-soft:-3px -3px 6px #00000001,3px 3px 6px #00000005,-1px -1px 2px #00000001,1px 1px 2px #00000005,inset -1px -1px 3px #00000009;--depth-inset:inset 2px 2px 4px #0000001f,inset -2px -2px 4px #00000004,inset 0 1px 1px #00000014,inset 0 -1px 1px #00000003;--depth-inset-soft:inset 2px 2px 3px #00000012,inset -2px -2px 3px #00000003,1px 1px 2px #00000003,-1px -1px 2px #0000000f;--depth-stroke-tl:inset 0 1px 0 0 #fff,inset 1px 0 0 0 #fff;--depth-stroke-br:inset 0 -1px 0 0 #0000000d,inset -1px 0 0 0 #0000000a;--neo-toggle-inset:inset 2px 2px 4px #00000014,inset -1px -1px 2px #00000002,inset 0 1px 1px #0000000f;--neo-toggle-raised:-1.5px -1.5px 4px #00000002,1.5px 1.5px 4px #00000017,-.5px -.5px 1px #00000001,.5px .5px 1px #0001,inset 1px 1px 2px #00000002,inset -1px -1px 2px #00000009}.depth-raised{box-shadow:var(--depth-raised),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-raised-soft{box-shadow:var(--depth-raised-soft),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-inset{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-stroke,.depth-stroke-raised{box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-stroke-inset{box-shadow:inset 0 1px #0000008c,inset 1px 0 #00000073,inset 0 -1px #ffffff17,inset -1px 0 #ffffff12}[data-mode=light] .depth-stroke-inset{box-shadow:inset 0 1px #0000000d,inset 1px 0 #0000000a,inset 0 -1px #fff,inset -1px 0 #fff}.depth-inset-soft{box-shadow:var(--depth-inset-soft),var(--depth-stroke-tl),var(--depth-stroke-br);background:linear-gradient(#0000001f,#ffffff05)}[data-mode=light] .depth-inset-soft{background:linear-gradient(#00000006,#00000001)}.neomorphic-outer{box-shadow:var(--depth-raised),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-outer-soft,.neomorphic-outer-soft-stroke{box-shadow:var(--depth-raised-soft),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-inner{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-inner-subtle{box-shadow:var(--depth-inset-soft),var(--depth-stroke-tl),var(--depth-stroke-br);background:linear-gradient(#0000001f,#ffffff05)}[data-mode=light] .neomorphic-inner-subtle{background:linear-gradient(#00000006,#00000001)}.neomorphic-card{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}:root{--neo-outer:var(--depth-raised);--neo-outer-soft:var(--depth-raised-soft);--neo-outer-sm:-3px -3px 8px #ffffff03,3px 3px 8px #0000001a,-1px -1px 2px #ffffff02,1px 1px 2px #0001,inset -1px -1px 4px #00000026}[data-mode=light]{--neo-outer:var(--depth-raised);--neo-outer-soft:var(--depth-raised-soft);--neo-outer-sm:-2px -2px 5px #00000001,2px 2px 5px #00000007,-1px -1px 1px #00000001,1px 1px 1px #00000007,inset -1px -1px 2px #0000000d}.sidebar-neo-highlight{box-shadow:inset 0 0 0 2px var(--sys-blue);background:0 0}.sidebar-neo-indicator{box-shadow:none}:root{--neo-map-outer:-4px -4px 12px #ffffff04,4px 4px 12px #00000040,-1px -1px 3px #ffffff03,1px 1px 3px #00000026;--neo-map-inner:inset 0 0 30px #0000004d,inset 0 0 60px #00000026,inset 3px 3px 8px #ffffff0a,inset -3px -3px 8px #00000040}[data-mode=light]{--neo-map-outer:-4px -4px 12px #00000001,4px 4px 12px #0000000d,-1px -1px 3px #00000001,1px 1px 3px #00000008;--neo-map-inner:inset 0 0 30px #0000000f,inset 0 0 60px #00000008,inset 3px 3px 8px #ffffff26,inset -3px -3px 8px #0000000d}.neomorphic-map-frame{box-shadow:var(--neo-map-outer);position:relative;overflow:hidden}.neomorphic-map-frame:after{content:"";border-radius:inherit;box-shadow:var(--neo-map-inner);pointer-events:none;z-index:50;position:absolute;top:0;right:0;bottom:0;left:0}.card-terminal{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;background:var(--elevated)!important;-webkit-backdrop-filter:none!important;box-shadow:var(--neo-outer-sm)!important;--tw-ring-shadow:0 0 #0000!important;border:none!important;border-radius:12px!important;padding:2px!important}.card-terminal-well{border-radius:var(--radius-md);box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);--tui-accent:#ff8c00;--tui-accent-local:var(--sys-blue);--tui-muted:#666;--tui-body:#fff;--tui-system:#888;--tui-hover-bg:#1a1f2e;--tui-hover-bar:var(--sys-blue);--tui-danger:var(--sys-red);--tui-warn:#f59e0b;--tui-disabled:#333;--tui-placeholder:#666;background:linear-gradient(#050505,#0a0a0a,#0c0c0c)}:root{--tui-header-height:52px;--tui-header-padding:4px;--tui-header-gap:4px;--tui-header-radius:10px}@media(min-width:640px){:root{--tui-header-height:64px;--tui-header-padding:6px;--tui-header-gap:6px;--tui-header-radius:12px}}.card-terminal-header{align-items:flex-end;gap:var(--tui-header-gap);padding:var(--tui-header-padding);background:var(--elevated);border-radius:var(--tui-header-radius);box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);flex-wrap:wrap;flex-shrink:0;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem;display:flex}.card-terminal-ridge{margin:var(--tui-header-padding)calc(var(--tui-header-gap)*2);border-radius:var(--tui-header-radius);background:var(--elevated);box-shadow:var(--neo-outer-sm);align-self:stretch;min-width:0}.card-terminal-section{color:var(--tui-accent,#ff8c00);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem}.card-terminal input{caret-color:var(--tui-accent,#ff8c00);caret-shape:block}.tui-emoji{filter:grayscale()sepia()hue-rotate(350deg)saturate(5)brightness(.85);display:inline}.card-terminal input:focus,.card-terminal input:focus-visible{-webkit-appearance:none;outline-offset:0!important;box-shadow:none!important;outline:none!important}.card-terminal-divider{background:linear-gradient(#000,#1a1a1a);height:2px;box-shadow:0 1px #ffffff0a;border:none!important}[data-mode=light] .card-terminal-well{box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);--tui-accent:#1a1d20;--tui-accent-local:#2e4a68;--tui-muted:#858a90;--tui-body:#111314;--tui-system:#72777c;--tui-hover-bg:#0000000f;--tui-hover-bar:#2e4a68;--tui-danger:#a03028;--tui-warn:#6b5a20;--tui-disabled:#b8bcc0;--tui-placeholder:#95999e;background:#eff0f1}[data-mode=light] .card-terminal-section{color:#3a4550}[data-mode=light] .card-terminal input{caret-color:#2a2d30}[data-mode=light] .tui-emoji{filter:grayscale()brightness(.4)}.tui-input::placeholder{color:var(--tui-placeholder)}[data-mode=light] .card-terminal-divider{background:linear-gradient(#b0b4ba,#c2c6cc);box-shadow:0 1px #fff6}.radius-card{border-radius:var(--radius-xl)}.radius-inset{border-radius:var(--radius-lg)}.radius-inner{border-radius:var(--radius-md)}.radius-control{border-radius:var(--radius-sm)}.radius-badge{border-radius:var(--radius-xs)}.radius-hero{border-radius:var(--radius-2xl)}.radius-none{border-radius:0}.radius-pill{border-radius:9999px}.border-card,.border-control{border:var(--stroke-thin)solid var(--edge-subtle)}.border-emphasis{border:var(--stroke-medium)solid var(--edge-strong)}.ring-focus:focus-visible{outline:var(--ring-width-default)solid var(--ring-color);outline-offset:var(--ring-offset)}.ring-focus-inset:focus-visible{box-shadow:inset 0 0 0 var(--ring-width-default) var(--ring-color);outline:none}.ring-focus-error:focus-visible{outline:var(--ring-width-default)solid var(--ring-color-error);outline-offset:var(--ring-offset)}.divider-bottom{border-bottom:var(--stroke-thin)solid var(--edge-subtle)}.divider-top{border-top:var(--stroke-thin)solid var(--edge-subtle)}.divider-right{border-right:var(--stroke-thin)solid var(--edge-subtle)}.divider-left{border-left:var(--stroke-thin)solid var(--edge-subtle)}.surface-thumbnail{border-radius:var(--radius-sm);border:none;position:relative;overflow:hidden}.surface-thumbnail:after{content:"";z-index:10;pointer-events:none;border-radius:inherit;box-shadow:inset 0 0 0 .5px var(--default-light),inset .9px 1.5px 0 -1px var(--default-light),inset -1px -1px 0 -1px var(--default-light),inset -1.5px -4px .5px -3px var(--default-light),inset -.15px -.5px 2px 0 var(--default-dark),inset -.75px 1.25px 0 -1px var(--default-dark),inset 0 1.5px 2px -1px var(--default-dark);position:absolute;top:0;right:0;bottom:0;left:0}@supports (color:color-mix(in lab,red,red)){.surface-thumbnail:after{box-shadow:inset 0 0 0 .5px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*16%),transparent),inset .9px 1.5px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*140%),transparent),inset -1px -1px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*125%),transparent),inset -1.5px -4px .5px -3px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*94%),transparent),inset -.15px -.5px 2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*18%),transparent),inset -.75px 1.25px 0 -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent),inset 0 1.5px 2px -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent)}}.surface-thumbnail-selected:after{box-shadow:inset 0 0 0 1.5px var(--sys-blue),inset .9px 1.5px 0 -1px var(--default-light),inset -1px -1px 0 -1px var(--default-light),inset -1.5px -4px .5px -3px var(--default-light),inset -.15px -.5px 2px 0 var(--default-dark),inset -.75px 1.25px 0 -1px var(--default-dark),inset 0 1.5px 2px -1px var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.surface-thumbnail-selected:after{box-shadow:inset 0 0 0 1.5px var(--sys-blue),inset .9px 1.5px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*140%),transparent),inset -1px -1px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*125%),transparent),inset -1.5px -4px .5px -3px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*94%),transparent),inset -.15px -.5px 2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*18%),transparent),inset -.75px 1.25px 0 -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent),inset 0 1.5px 2px -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent)}}.surface-card-frame{z-index:1000;box-shadow:inset 0 0 0 1px var(--default-light),inset 1.8px 3px 0 -2px var(--default-light),inset -2px -2px 0 -2px var(--default-light),inset -3px -8px 1px -6px var(--default-light),inset -.3px -1px 4px 0 var(--default-dark),inset -1.5px 2.5px 0 -2px var(--default-dark),inset 0 3px 4px -2px var(--default-dark),inset 2px -6.5px 1px -4px var(--default-dark),0 1px 5px 0 var(--default-dark),0 6px 16px 0 var(--default-dark);border-radius:1.125rem;position:relative}@supports (color:color-mix(in lab,red,red)){.surface-card-frame{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*15%),transparent),inset 1.8px 3px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*90%),transparent),inset -2px -2px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*80%),transparent),inset -3px -8px 1px -6px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*60%),transparent),inset -.3px -1px 4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*15%),transparent),inset -1.5px 2.5px 0 -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*25%),transparent),inset 0 3px 4px -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*25%),transparent),inset 2px -6.5px 1px -4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent),0 1px 5px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*15%),transparent),0 6px 16px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent)}}.surface-card-frame:before{content:"";pointer-events:none;border-radius:inherit;z-index:1001;background:var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.separator-line{background:linear-gradient(to right,transparent,var(--default-light)20%,var(--default-light)80%,transparent);height:1px}@supports (color:color-mix(in lab,red,red)){.separator-line{background:linear-gradient(to right,transparent,color-mix(in srgb,var(--default-light)8%,transparent)20%,color-mix(in srgb,var(--default-light)8%,transparent)80%,transparent)}}.separator-line-vertical{background:linear-gradient(to bottom,transparent,var(--default-light)20%,var(--default-light)80%,transparent);width:1px}@supports (color:color-mix(in lab,red,red)){.separator-line-vertical{background:linear-gradient(to bottom,transparent,color-mix(in srgb,var(--default-light)8%,transparent)20%,color-mix(in srgb,var(--default-light)8%,transparent)80%,transparent)}}.rounded-pill{border-radius:9999px}.rounded-card{border-radius:var(--radius-xl)}.catalyst-mode .surface-card-frame{border-radius:var(--radius-xl)!important;box-shadow:inset 0 0 0 1px var(--edge-subtle)!important}.catalyst-mode .surface-card-frame:before{display:none!important}.catalyst-mode .map-control-surface,.catalyst-mode .map-controls-container,.catalyst-mode .maplibregl-ctrl-group{background-color:var(--map-ui-bg,var(--surface))!important;border-radius:var(--radius-md)!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--edge-subtle)),var(--map-ui-shadow,0 1px 3px 0 #0000001a)!important}.catalyst-mode .map-control-surface:after,.catalyst-mode .maplibregl-ctrl-group:after{display:none!important}.catalyst-mode .surface-thumbnail:after{box-shadow:inset 0 0 0 1px var(--edge-subtle)!important}.sidebar-panel{background-color:var(--default-tint);border:none;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.sidebar-panel{background-color:color-mix(in srgb,var(--default-tint)var(--default-bg-opacity),transparent)}}.sidebar-panel{-webkit-backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));box-shadow:inset 0 0 0 1px var(--default-light),inset -1px 0 0 0 var(--default-light),inset 1px 0 0 0 var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.sidebar-panel{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*10%),transparent),inset -1px 0 color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*8%),transparent),inset 1px 0 color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*10%),transparent)}}.sidebar-panel:before{content:"";pointer-events:none;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.catalyst-mode .sidebar-panel{background-color:var(--body)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;box-shadow:none!important;border:none!important}.catalyst-mode .sidebar-panel:before{display:none!important}.catalyst-mode [data-slot=section] a,.catalyst-mode [data-slot=section] button{border-radius:var(--radius-lg)!important}.catalyst-mode [data-slot=section] a:hover,.catalyst-mode [data-slot=section] button:hover{background-color:var(--surface)!important}.catalyst-mode [data-slot=section] a[data-current=true],.catalyst-mode [data-slot=section] button[data-current=true]{background-color:var(--surface)!important;color:var(--fg-primary)!important}.catalyst-mode [data-slot=section] a[data-current=true] svg,.catalyst-mode [data-slot=section] button[data-current=true] svg{color:var(--fg-primary)!important}.catalyst-mode [data-slot=section] .absolute.bg-sys-blue{display:none!important}.mobile-header{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.mobile-header{background-color:color-mix(in srgb,var(--body)70%,transparent)}}.mobile-header{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-bottom:1px solid var(--edge-subtle)}.catalyst-mode .mobile-header{background-color:var(--body)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}.main-content{overflow-x:clip}.catalyst-mode .main-content{background-color:var(--subtle);box-shadow:inset 0 0 0 1px var(--edge-subtle);border-radius:.75rem 0 0 .75rem;margin:.5rem 0}@media(max-width:1023px){.catalyst-mode .main-content{border-radius:0;margin:0}}.catalyst-mode [data-card-surface]{background-color:var(--surface)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;border-radius:var(--radius-xl)!important;--tw-ring-shadow:0 0 #0000!important;border:none!important}.catalyst-mode [data-card-surface]:before{display:none!important}.card-sm{min-height:7rem}.card-md{min-height:11rem}.card-lg{min-height:14rem}.card-hero{min-height:20rem}.card-auto{min-height:auto}@media(max-width:640px){.card-sm{min-height:6rem}.card-md{min-height:9rem}.card-lg{min-height:12rem}.card-hero{min-height:16rem}}.icon-sm{flex-shrink:0;width:1rem;height:1rem}.icon-md{flex-shrink:0;width:1.25rem;height:1.25rem}.icon-lg{flex-shrink:0;width:1.5rem;height:1.5rem}.icon-xl{flex-shrink:0;width:2rem;height:2rem}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--surface)}::-webkit-scrollbar-thumb{background-color:var(--edge-strong);border-radius:4px}::-webkit-scrollbar-thumb:hover{background-color:var(--fg-muted)}.sidebar-scroll{scrollbar-width:thin;scrollbar-color:transparent transparent}.sidebar-scroll:hover{scrollbar-color:var(--edge-subtle)transparent}.sidebar-scroll::-webkit-scrollbar{width:4px}.sidebar-scroll::-webkit-scrollbar-track{background:0 0}.sidebar-scroll::-webkit-scrollbar-thumb{background-color:#0000;border-radius:2px}.sidebar-scroll:hover::-webkit-scrollbar-thumb{background-color:var(--edge-subtle)}.layout-container{width:100%;max-width:80rem;margin-left:auto;margin-right:auto}.grid-12{grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;display:grid}@media(min-width:768px){.grid-12{gap:1.5rem}}.col-span-6{grid-column:span 6/span 6}.col-span-4{grid-column:span 4/span 4}.col-span-3{grid-column:span 3/span 3}@media(min-width:640px){.sm\:col-span-6{grid-column:span 6/span 6}.sm\:col-span-4{grid-column:span 4/span 4}.sm\:col-span-3{grid-column:span 3/span 3}}@media(min-width:768px){.md\:col-span-6{grid-column:span 6/span 6}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-3{grid-column:span 3/span 3}.md\:col-span-8{grid-column:span 8/span 8}.md\:col-span-12{grid-column:span 12/span 12}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-4{grid-column:span 4/span 4}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-8{grid-column:span 8/span 8}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:col-span-10{grid-column:span 10/span 10}.lg\:col-span-12{grid-column:span 12/span 12}}@media(min-width:1280px){.xl\:col-span-2{grid-column:span 2/span 2}.xl\:col-span-3{grid-column:span 3/span 3}.xl\:col-span-4{grid-column:span 4/span 4}.xl\:col-span-8{grid-column:span 8/span 8}}.gap-space-2{gap:.5rem}.gap-space-3{gap:.75rem}.gap-space-4{gap:1rem}.gap-space-6{gap:1.5rem}.gap-space-8{gap:2rem}.gap-y-space-4{row-gap:1rem}.gap-y-space-6{row-gap:1.5rem}.gap-y-space-8{row-gap:2rem}.gap-x-space-4{column-gap:1rem}.gap-x-space-6{column-gap:1.5rem}.gap-x-space-8{column-gap:2rem}.card-padding{padding:.75rem}@media(min-width:640px){.card-padding{padding:1rem}}.card-padding-sm{padding:.5rem}@media(min-width:640px){.card-padding-sm{padding:.75rem}}.card-padding-xs{padding:.5rem}@media(min-width:640px){.card-padding-xs{padding:.75rem}}.section-gap{flex-direction:column;gap:1rem;min-width:0;padding:.5rem .75rem .25rem;display:flex}@media(min-width:640px){.section-gap{gap:1.5rem}}@media(min-width:1024px){.section-gap{gap:2rem;padding:.5rem 1rem .25rem}}.bento-section{flex-direction:column;gap:1rem;min-width:0;display:flex}.stats-row-hero{grid-template-columns:repeat(2,1fr);gap:1rem;display:grid}@media(min-width:768px){.stats-row-hero{grid-template-columns:repeat(3,1fr);gap:1.5rem}}@media(min-width:1280px){.stats-row-hero{grid-template-columns:repeat(5,1fr)}}.stats-row-secondary{grid-template-columns:1fr;gap:1rem;display:grid}@media(min-width:640px){.stats-row-secondary{grid-template-columns:repeat(2,1fr)}}@media(min-width:1024px){.stats-row-secondary{grid-template-columns:repeat(4,1fr);gap:1.5rem}}.content-grid{grid-template-columns:1fr;gap:1rem;display:grid}@media(min-width:768px){.content-grid{gap:1.5rem}}@media(min-width:1280px){.content-grid{grid-template-columns:2fr 1fr}}.content-main,.content-sidebar{min-width:0}.bento-row{grid-template-columns:repeat(12,minmax(0,1fr));align-items:stretch;display:grid}.bento-row-hero{min-height:15rem}@media(min-width:768px){.bento-row-hero{min-height:17.5rem}}@media(min-width:1024px){.bento-row-hero{min-height:20rem}}.bento-row-hero-tall{height:20rem;min-height:20rem}@media(min-width:768px){.bento-row-hero-tall{height:23.3125rem;min-height:23.3125rem}}@media(min-width:1024px){.bento-row-hero-tall{height:26.625rem;min-height:26.625rem}}.bento-row-hero-auto{min-height:30rem}@media(min-width:768px){.bento-row-hero-auto{min-height:23.3125rem}}@media(min-width:1024px){.bento-row-hero-auto{min-height:26.625rem}}.bento-row-panel{grid-auto-rows:18.75rem}.bento-row-feature{grid-auto-rows:12.5rem}@media(min-width:768px){.bento-row-feature{grid-auto-rows:15rem}}@media(min-width:1024px){.bento-row-feature{grid-auto-rows:16.25rem}}.bento-row-standard{min-height:11.25rem}@media(min-width:768px){.bento-row-standard{min-height:12.5rem}}@media(min-width:1024px){.bento-row-standard{min-height:13.75rem}}.bento-row-compact{min-height:8.75rem}@media(min-width:768px){.bento-row-compact{min-height:10rem}}@media(min-width:1024px){.bento-row-compact{min-height:11.25rem}}.bento-row-widget{min-height:6.25rem}@media(min-width:768px){.bento-row-widget{min-height:6.875rem}}@media(min-width:1024px){.bento-row-widget{min-height:7.5rem}}.bento-row-auto{min-height:auto}.legend-item{cursor:pointer;border-radius:.25rem;align-items:center;gap:.25rem;padding:.25rem .375rem;font-size:.6875rem;line-height:1.2;transition:background-color .15s,opacity .15s;display:flex}.legend-item:hover{background-color:var(--hover-tint)}.legend-item-active{background-color:var(--subtle);opacity:1}.legend-item-dimmed{opacity:.35}.legend-item-chart-active{background-color:var(--hover-tint);opacity:1}.legend-label{color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;max-width:5.5rem;overflow:hidden}.legend-value{font-family:var(--font-data);font-variant-numeric:tabular-nums;color:var(--fg-secondary);flex-shrink:0;margin-left:auto;font-weight:600}.legend-value-live{color:var(--fg-primary)}.bento-gap{gap:1rem}.bento-gap-sm{gap:.5rem}@media(min-width:640px){.bento-gap-sm{gap:.75rem}}@media(min-width:768px){.bento-gap-sm{gap:1rem}}.bento-gap-lg{gap:1rem}@media(min-width:640px){.bento-gap-lg{gap:1.25rem}}@media(min-width:768px){.bento-gap-lg{gap:1.5rem}}@media(min-width:1024px){.bento-gap-lg{gap:2rem}}.bento-cell{flex-direction:column;min-width:0;min-height:0;display:flex}.bento-cell>*{flex:auto;min-height:0}.bento-cell[data-ratio]>:first-child{aspect-ratio:var(--cell-ratio);flex-shrink:1;max-height:100%}.bento-col-1{grid-column:span 1/span 1}.bento-col-2{grid-column:span 2/span 2}.bento-col-3{grid-column:span 3/span 3}.bento-col-4{grid-column:span 4/span 4}.bento-col-5{grid-column:span 5/span 5}.bento-col-6{grid-column:span 6/span 6}.bento-col-7{grid-column:span 7/span 7}.bento-col-8{grid-column:span 8/span 8}.bento-col-9{grid-column:span 9/span 9}.bento-col-10{grid-column:span 10/span 10}.bento-col-11{grid-column:span 11/span 11}.bento-col-12{grid-column:span 12/span 12}.col-span-full{grid-column:1/-1}.col-auto{grid-column:auto}.bento-col-1-5{grid-column:span 2/span 2}@media(min-width:640px){.sm\:bento-col-1{grid-column:span 1/span 1}.sm\:bento-col-2{grid-column:span 2/span 2}.sm\:bento-col-3{grid-column:span 3/span 3}.sm\:bento-col-4{grid-column:span 4/span 4}.sm\:bento-col-5{grid-column:span 5/span 5}.sm\:bento-col-6{grid-column:span 6/span 6}.sm\:bento-col-7{grid-column:span 7/span 7}.sm\:bento-col-8{grid-column:span 8/span 8}.sm\:bento-col-9{grid-column:span 9/span 9}.sm\:bento-col-10{grid-column:span 10/span 10}.sm\:bento-col-11{grid-column:span 11/span 11}.sm\:bento-col-12{grid-column:span 12/span 12}.sm\:col-span-full{grid-column:1/-1}.sm\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:768px){.md\:bento-col-1{grid-column:span 1/span 1}.md\:bento-col-2{grid-column:span 2/span 2}.md\:bento-col-3{grid-column:span 3/span 3}.md\:bento-col-4{grid-column:span 4/span 4}.md\:bento-col-5{grid-column:span 5/span 5}.md\:bento-col-6{grid-column:span 6/span 6}.md\:bento-col-7{grid-column:span 7/span 7}.md\:bento-col-8{grid-column:span 8/span 8}.md\:bento-col-9{grid-column:span 9/span 9}.md\:bento-col-10{grid-column:span 10/span 10}.md\:bento-col-11{grid-column:span 11/span 11}.md\:bento-col-12{grid-column:span 12/span 12}.md\:col-span-full{grid-column:1/-1}.md\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:1024px){.lg\:bento-col-1{grid-column:span 1/span 1}.lg\:bento-col-2{grid-column:span 2/span 2}.lg\:bento-col-3{grid-column:span 3/span 3}.lg\:bento-col-4{grid-column:span 4/span 4}.lg\:bento-col-5{grid-column:span 5/span 5}.lg\:bento-col-6{grid-column:span 6/span 6}.lg\:bento-col-7{grid-column:span 7/span 7}.lg\:bento-col-8{grid-column:span 8/span 8}.lg\:bento-col-9{grid-column:span 9/span 9}.lg\:bento-col-10{grid-column:span 10/span 10}.lg\:bento-col-11{grid-column:span 11/span 11}.lg\:bento-col-12{grid-column:span 12/span 12}.lg\:col-span-full{grid-column:1/-1}.lg\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:1280px){.xl\:bento-col-1{grid-column:span 1/span 1}.xl\:bento-col-2{grid-column:span 2/span 2}.xl\:bento-col-3{grid-column:span 3/span 3}.xl\:bento-col-4{grid-column:span 4/span 4}.xl\:bento-col-5{grid-column:span 5/span 5}.xl\:bento-col-6{grid-column:span 6/span 6}.xl\:bento-col-7{grid-column:span 7/span 7}.xl\:bento-col-8{grid-column:span 8/span 8}.xl\:bento-col-9{grid-column:span 9/span 9}.xl\:bento-col-10{grid-column:span 10/span 10}.xl\:bento-col-11{grid-column:span 11/span 11}.xl\:bento-col-12{grid-column:span 12/span 12}.xl\:col-span-full{grid-column:1/-1}.xl\:bento-col-1-5{grid-column:span 2/span 2}}.pill-filled{background:var(--sys-blue);color:var(--body);border-radius:9999px;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:opacity .15s;display:inline-flex}.pill-filled:hover{opacity:.9}.pill-subtle{background:var(--subtle);color:var(--fg-secondary);border:1px solid var(--edge-subtle);border-radius:9999px;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:all .15s;display:inline-flex}.pill-subtle:hover{background:var(--elevated);color:var(--fg-primary)}.pill-metric{text-transform:uppercase;letter-spacing:.05em;border-radius:9999px;align-items:center;gap:.25rem;padding:.25rem .5rem;font-size:.625rem;font-weight:600;line-height:1;display:inline-flex}.pill-metric-positive{background:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.pill-metric-positive{background:color-mix(in srgb,var(--sys-green)15%,transparent)}}.pill-metric-positive{color:var(--sys-green)}.pill-metric-negative{background:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.pill-metric-negative{background:color-mix(in srgb,var(--sys-red)15%,transparent)}}.pill-metric-negative{color:var(--sys-red)}.pill-metric-neutral{background:var(--overlay-soft);color:var(--fg-secondary)}.pill-tag{background:var(--sys-blue);border-radius:9999px;align-items:center;padding:.125rem .5rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.pill-tag{background:color-mix(in srgb,var(--sys-blue)10%,transparent)}}.pill-tag{color:var(--sys-blue);text-transform:uppercase;letter-spacing:.08em;font-size:.625rem;font-weight:600}[data-mode=light] [data-color=zinc]{background-color:var(--fg-muted)!important}@supports (color:color-mix(in lab,red,red)){[data-mode=light] [data-color=zinc]{background-color:color-mix(in srgb,var(--fg-muted)8%,transparent)!important}}[data-mode=light] [data-color=zinc]{color:var(--fg-muted)!important;font-weight:400!important}.toggle-group{background-color:var(--surface);box-shadow:var(--neo-outer-sm);border-radius:9999px;padding:3px;display:inline-flex;position:relative}.toggle-group:before{display:none}.toggle-group-item{border-radius:var(--radius-lg);color:var(--fg-muted);box-shadow:inset 0 0 0 1px var(--edge-subtle);padding:.375rem .75rem;font-size:.75rem;font-weight:500;transition:all .15s;position:relative}.toggle-group-item:hover:not(.active){color:var(--fg-secondary);box-shadow:inset 0 0 0 1.5px var(--edge-strong)}.toggle-group-item.active{color:var(--fg-primary);box-shadow:inset 0 0 0 1.5px var(--sys-blue)}.toggle-group-highlight{border-radius:inherit;box-shadow:inset 0 0 0 1.5px var(--sys-blue);background-color:#0000;position:absolute;top:0;right:0;bottom:0;left:0}.toggle-group-sm{padding:.1875rem}.toggle-group-sm .toggle-group-item{padding:.25rem .5rem;font-size:.6875rem}.toggle-group-micro{padding:.125rem}.toggle-group-micro .toggle-group-item{padding:.1875rem .375rem;font-size:.625rem}.chart-body{padding:1rem;position:relative}.chart-axis-label{color:var(--fg-muted);font-variant-numeric:tabular-nums;font-size:.6875rem}.chart-gridline{stroke:var(--chart-grid);stroke-dasharray:4 4}.chart-glow-primary{filter:drop-shadow(0 0 6px var(--sys-blue))}.chart-glow-secondary{filter:drop-shadow(0 0 6px var(--sys-indigo))}.chart-glow-tertiary{filter:drop-shadow(0 0 6px var(--sys-cyan))}.roster-list{flex-direction:column;display:flex}.roster-row{border-radius:var(--radius-lg);align-items:center;gap:.5rem;padding:.75rem .75rem .75rem .5rem;transition:background .15s;display:flex}@media(min-width:640px){.roster-row{gap:.75rem;padding:.75rem 1rem .75rem .75rem}}.roster-row:hover{background:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.roster-row:hover{background:color-mix(in srgb,var(--subtle)80%,transparent)}}.roster-row-interactive{cursor:pointer}.roster-row-interactive:active{background:var(--subtle)}.roster-row.selected{background:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.roster-row.selected{background:color-mix(in srgb,var(--sys-blue)8%,transparent)}}.roster-icon{border-radius:var(--radius-md);background-color:var(--default-tint);flex-shrink:0;justify-content:center;align-items:center;width:2.5rem;height:2.5rem;display:flex}@supports (color:color-mix(in lab,red,red)){.roster-icon{background-color:color-mix(in srgb,var(--default-tint)10%,transparent)}}.roster-icon{box-shadow:inset 0 0 0 1px var(--default-light),inset .5px 1px 0 0 var(--default-light)}@supports (color:color-mix(in lab,red,red)){.roster-icon{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*5%),transparent),inset .5px 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*30%),transparent)}}.roster-icon-sm{border-radius:var(--radius-md);width:2rem;height:2rem}.roster-content{flex-direction:column;flex:1;gap:.125rem;min-width:0;display:flex}.roster-title{color:var(--fg-primary);white-space:nowrap;text-overflow:ellipsis;font-size:.875rem;font-weight:500;overflow:hidden}.roster-subtitle{color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;font-size:.75rem;overflow:hidden}.roster-metrics{color:var(--fg-muted);align-items:center;gap:1rem;display:flex}.roster-metric{color:var(--fg-secondary);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:.8125rem;font-weight:600}@media(max-width:639px){.roster-row{flex-wrap:wrap;gap:.375rem;padding:.5rem .5rem .5rem .375rem}.roster-icon{border-radius:var(--radius-sm);width:1.75rem;height:1.75rem}.roster-content{flex:1 1 0;min-width:0;overflow:hidden}.roster-title{font-size:.75rem}.roster-metrics{flex-wrap:wrap;order:3;gap:.5rem;width:100%;margin-top:.25rem;padding-left:2.25rem}.roster-metric{flex-shrink:0;margin-left:auto;font-size:.6875rem}}@media(min-width:640px)and (max-width:767px){.roster-row{gap:.5rem}.roster-icon{border-radius:var(--radius-md);width:2rem;height:2rem}.roster-metrics{gap:.75rem}}@media(min-width:768px)and (max-width:1023px){.roster-metrics{gap:.875rem}}@media(min-width:1024px){.roster-row{gap:.875rem}.roster-metrics{gap:1rem}}.contacts-grid-header,.contacts-grid-row{grid-template-columns:1fr;grid-template-areas:"node";align-items:center;gap:.75rem;display:grid}.contacts-grid-row{contain:layout;padding:.625rem .75rem;transition:background-color .15s ease-out}.contacts-grid-row:hover{background-color:var(--subtle);transition-duration:0s}@media(max-width:639px){.contacts-grid-row{flex-wrap:nowrap;gap:.5rem;padding:.5rem .625rem;display:flex}.contacts-col-signal,.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity{display:none}.contacts-col-node{flex:1 1 0;min-width:0}.contacts-col-seen,.contacts-col-actions{flex-shrink:0;align-self:center}}@media(min-width:640px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(200px,1fr) 100px 60px 68px;grid-template-areas:"node signal seen actions"}.contacts-col-node{grid-area:node}.contacts-col-signal{grid-area:signal;display:flex}.contacts-col-seen{grid-area:seen}.contacts-col-actions{grid-area:actions}.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity{display:none}}@media(min-width:768px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(240px,1fr) 110px 80px 60px 68px;grid-template-areas:"node signal distance seen actions"}.contacts-col-distance{grid-area:distance;display:flex}}@media(min-width:1024px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(280px,1fr) 110px 80px 64px 64px 68px;grid-template-areas:"node signal distance centrality seen actions"}.contacts-col-centrality{grid-area:centrality;display:flex}}@media(min-width:1280px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(320px,1fr) 120px 80px 64px 64px 68px 68px;grid-template-areas:"node signal distance centrality activity seen actions"}.contacts-col-activity{grid-area:activity;display:flex}}.contacts-col-node{min-width:0}.contacts-col-signal,.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity,.contacts-col-seen,.contacts-col-actions{white-space:nowrap;flex-shrink:0;overflow:hidden}.roster-separator{background:linear-gradient(to right,transparent,var(--edge-subtle)20%,var(--edge-subtle)80%,transparent);height:1px;margin:0 1rem}.roster-empty{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:3rem 1.5rem;display:flex}.roster-empty-icon{width:3rem;height:3rem;color:var(--fg-muted);opacity:.5;margin-bottom:1rem}.roster-empty-title{color:var(--fg-secondary);margin-bottom:.25rem;font-size:.875rem;font-weight:500}.roster-empty-text{color:var(--fg-muted);font-size:.75rem}.btn-skeuo{border-radius:var(--radius-md);cursor:pointer;background:var(--ctrl-base);border:1.5px solid var(--ctrl-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-shadow-dark),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset);justify-content:center;align-items:center;gap:.5rem;padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;transition:all .12s ease-out;display:inline-flex;position:relative}.btn-skeuo:hover{background:var(--ctrl-base-hover);border-color:var(--ctrl-border-hover);box-shadow:0 4px 0 var(--ctrl-shadow-dark),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.btn-skeuo:active{background:var(--ctrl-base-active);box-shadow:0 0 0 var(--ctrl-shadow-dark),0 1px 3px var(--ctrl-shadow-mid),inset 0 3px 6px var(--ctrl-shadow-mid),inset 0 1px 0 var(--ctrl-shadow-dark);transform:translateY(3px)}.btn-skeuo:disabled{opacity:.4;cursor:not-allowed;transform:none}.btn-skeuo-primary{background:var(--ctrl-primary);border-color:var(--ctrl-primary-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-primary-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-primary-highlight),inset 0 -2px 0 var(--ctrl-primary-inset)}.btn-skeuo-primary:hover{background:var(--ctrl-primary-hover);border-color:var(--ctrl-primary-highlight);box-shadow:0 4px 0 var(--ctrl-primary-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-primary-highlight),inset 0 -2px 0 var(--ctrl-primary-inset)}.btn-skeuo-success{background:var(--ctrl-success);border-color:var(--ctrl-success-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-success-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-success-highlight),inset 0 -2px 0 var(--ctrl-success-inset)}.btn-skeuo-success:hover{background:var(--ctrl-success-hover);border-color:var(--ctrl-success-highlight);box-shadow:0 4px 0 var(--ctrl-success-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-success-highlight),inset 0 -2px 0 var(--ctrl-success-inset)}.btn-skeuo-warning{background:var(--ctrl-warning);border-color:var(--ctrl-warning-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-warning-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-warning-highlight),inset 0 -2px 0 var(--ctrl-warning-inset)}.btn-skeuo-warning:hover{background:var(--ctrl-warning-hover);border-color:var(--ctrl-warning-highlight);box-shadow:0 4px 0 var(--ctrl-warning-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-warning-highlight),inset 0 -2px 0 var(--ctrl-warning-inset)}.btn-skeuo-neutral{background:var(--ctrl-base);border-color:var(--ctrl-border);color:var(--fg-secondary);box-shadow:0 3px 0 var(--ctrl-shadow-dark),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.btn-skeuo-neutral:hover{background:var(--ctrl-base-hover);color:var(--fg-primary);box-shadow:0 4px 0 var(--ctrl-shadow-dark),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.control-card{border-radius:var(--radius-lg);background-color:var(--default-tint);padding:1rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.control-card{background-color:color-mix(in srgb,var(--default-tint)var(--default-bg-opacity),transparent)}}.control-card{-webkit-backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));box-shadow:inset 0 0 0 1px var(--default-light),inset 1.8px 3px 0 -2px var(--default-light),inset -2px -2px 0 -2px var(--default-light),inset -3px -8px 1px -6px var(--default-light),inset -.3px -1px 4px 0 var(--default-dark),inset 0 3px 4px -2px var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.control-card{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*10%),transparent),inset 1.8px 3px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*70%),transparent),inset -2px -2px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*50%),transparent),inset -3px -8px 1px -6px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*40%),transparent),inset -.3px -1px 4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*8%),transparent),inset 0 3px 4px -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent)}}.control-card:before{content:"";pointer-events:none;border-radius:inherit;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.control-card-header{justify-content:space-between;align-items:center;margin-bottom:.75rem;display:flex}.control-card-label{color:var(--fg-muted);font-size:.8125rem}.control-card-value{font-size:.8125rem;font-weight:600}.control-card-value-active{color:var(--sys-green)}.control-card-value-inactive{color:var(--fg-muted)}.btn-skeuo-icon{stroke-width:2.5px;width:1.125rem;height:1.125rem}.btn-terminal{width:100%;color:var(--tui-accent,#ff8c00);border:1px solid var(--tui-disabled,#333);cursor:pointer;background:0 0;border-radius:0;justify-content:center;align-items:center;gap:.5rem;padding:.5rem 1rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem;font-weight:500;line-height:1.25rem;transition:background-color .1s,border-color .1s;display:inline-flex}.btn-terminal:hover{background:var(--tui-hover-bg,#1a1f2e);border-color:var(--tui-accent,#ff8c00)}.btn-terminal:active{background:var(--tui-accent,#ff8c00);color:#0c0c0c}.btn-terminal:disabled{opacity:.3;cursor:not-allowed}.btn-terminal:disabled:hover{border-color:var(--tui-disabled,#333);background:0 0}.btn-terminal--danger{color:var(--sys-red)}.btn-terminal--danger:hover{border-color:var(--sys-red)}.btn-terminal--danger:active{background:var(--sys-red);color:#0c0c0c}.btn-terminal--muted{color:#666}.btn-terminal--muted:hover{color:#ccc;border-color:#666}.well-icon-btn{cursor:pointer;-webkit-tap-highlight-color:transparent;background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;border-radius:4px;outline:none;justify-content:center;align-items:center;padding:5px;transition:box-shadow 60ms;display:inline-flex;box-shadow:inset 0 3px 5px #000000e6,inset 0 1px 1px #000000b3,inset 0 -1px 2px #ffffff0a}.well-icon-btn:hover{box-shadow:inset 0 3px 5px #000000e6,inset 0 1px 1px #000000b3,inset 0 -1px 2px #ffffff0f}.well-icon-btn:active{box-shadow:inset 0 5px 8px #000000f2,inset 0 2px 3px #000c,inset 0 -1px 1px #ffffff05}.well-icon-btn svg{stroke-width:2px;width:14px;height:14px;transition:opacity 80ms}.well-icon-btn:hover svg{opacity:1}.well-icon-btn--amber svg{color:var(--tui-accent,#ff8c00);opacity:.7}.well-icon-btn--amber:hover svg{color:#ffa540}.well-icon-btn--amber:active svg{color:#ffd080}.well-icon-btn--danger svg{color:var(--sys-red);opacity:.7}.well-icon-btn--danger:hover svg{color:#ff6b6b}.well-icon-btn--danger:active svg{color:#ff9090}.keycap-group{align-items:stretch;gap:4px;width:100%;display:flex}.keycap-btn{--keycap-bevel-light:#82838d80;--keycap-bevel-dark:#2a243280;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;background:0 0;border:none;outline:none;flex-shrink:0;justify-content:center;align-items:center;margin:0;padding:0;display:flex}.keycap-btn--red-cap{--keycap-bevel-light:#a53a3a8c;--keycap-bevel-dark:#2d121280}.keycap-well{background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border-radius:6px;flex-shrink:0;padding:4px;display:inline-flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}.keycap-well--tight{padding:2px}.keycap-well--rounded{border-radius:var(--radius-lg)}.keycap-well--fill{flex:1;min-width:0}.header-well{align-items:center;gap:var(--tui-header-gap,4px);padding:var(--tui-header-padding,4px);border-radius:var(--tui-header-radius,12px);background:linear-gradient(#050505,#0a0a0a,#0c0c0c);flex-shrink:0;display:inline-flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}@media(min-width:640px){.header-well{height:var(--tui-header-height,64px)}}.keycap-wrap{transition:transform 40ms cubic-bezier(0,0,0,1);display:inline-flex;position:relative}.keycap-btn__img{height:calc(var(--tui-header-height,52px) - 8px);pointer-events:none;width:auto;transition:filter 40ms cubic-bezier(0,0,0,1);display:block}[data-mode=light] .keycap-btn{--keycap-bevel-light:#c8c8d2b3;--keycap-bevel-dark:#504e5a99}[data-mode=light] .keycap-btn--red-cap{--keycap-bevel-light:#dc8c8cb3;--keycap-bevel-dark:#64282899}[data-mode=light] .keycap-btn--red-cap .keycap-btn__img{filter:brightness(1.6)contrast(.7)saturate(1.15)drop-shadow(0 4px 6px #00000059)drop-shadow(0 2px 3px #0003)}[data-mode=light] .keycap-btn__img{filter:brightness(1.8)contrast(.7)saturate(.8)drop-shadow(0 4px 6px #00000059)drop-shadow(0 2px 3px #0003)}[data-mode=light] .keycap-btn:hover .keycap-btn__img{filter:brightness(1.95)contrast(.7)saturate(.8)drop-shadow(0 6px 10px #00000059)drop-shadow(0 3px 4px #0003)}[data-mode=light] .keycap-btn--pressed .keycap-btn__img{filter:brightness(1.5)contrast(.7)saturate(.8)drop-shadow(0 1px 2px #00000040)}.keycap-btn:hover .keycap-btn__img{filter:brightness(1.15)}.keycap-btn--pressed .keycap-wrap{transform:translateY(2px)scale(.97)}.keycap-btn--pressed .keycap-btn__img{filter:brightness(.75)}.keycap-btn--pressed .keycap-well{box-shadow:inset 0 5px 8px #000000f2,inset 0 2px 3px #000c,inset 0 -1px 1px #ffffff05}.keycap-btn--pressed:hover .keycap-btn__img{filter:brightness(.75)}.keycap-btn:disabled{cursor:not-allowed}.keycap-btn:disabled:hover .keycap-btn__img{filter:none}.keycap-icon-overlay{pointer-events:none;width:36%;height:42%;filter:drop-shadow(0 1.25px 0 var(--keycap-bevel-light))drop-shadow(0 -1px 0 var(--keycap-bevel-dark));justify-content:center;align-items:center;transition:color 60ms;display:flex;position:absolute;top:calc(44% - 2px);left:50%;transform:translate(-50%,-50%)}.keycap-icon-overlay svg{width:100%;height:100%}.keycap-btn:hover .keycap-icon-overlay{color:#ffdeb0}.keycap-wifi{pointer-events:none;width:36%;height:42%;filter:drop-shadow(0 1.5px 0 var(--keycap-bevel-light))drop-shadow(0 -.5px 0 var(--keycap-bevel-dark));position:absolute;top:calc(44% - 2px);left:50%;transform:translate(-50%,-50%)}.keycap-wifi--active{filter:drop-shadow(0 0 1.5px #ffdeb059)}@keyframes keycap-wifi-sweep{0%{stroke:#000}12%{stroke:#ffdeb0}28%{stroke:#ffdeb0}30%{stroke:#000}to{stroke:#000}}.keycap-wifi-arc{animation:1.8s step-end infinite keycap-wifi-sweep}.keycap-wifi-arc-1{animation-delay:0s}.keycap-wifi-arc-2{animation-delay:.45s}.keycap-wifi-arc-3{animation-delay:.9s}@keyframes keycap-wifi-blink-all{0%{stroke:#ffdeb0}70%{stroke:#ffdeb0}71%{stroke:#000}to{stroke:#000}}.keycap-wifi-blink-all{animation:.5s step-end forwards keycap-wifi-blink-all}.indicator-key-pair{flex:1;align-self:stretch;gap:4px;min-width:0;display:flex}.indicator-key{border-radius:calc(var(--tui-header-radius,12px) - 2px);background:#111;border:none;flex-direction:column;flex:1;justify-content:center;align-items:flex-start;gap:4px;min-width:0;padding:6px 10px 8px;display:flex}@media(min-width:640px){.indicator-key{gap:6px;padding:8px 12px 10px}}.indicator-key__label{letter-spacing:1.5px;color:#666;text-shadow:0 1px #ffffff0f;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.6875rem;font-weight:400}.indicator-key__led{width:22px;height:5px;box-shadow:none;background:#1a1a1a;border-radius:1px;display:block}[data-mode=light] .indicator-key{background:linear-gradient(135deg,#71717a,#a1a1aa);box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}[data-mode=light] .indicator-key__label{color:#d4d4d8;text-shadow:none;font-weight:600}[data-mode=light] .indicator-key__led{background:#333}.indicator-key--sending .indicator-key__led{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);animation:.6s step-end infinite led-blink;box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}@keyframes led-blink{0%{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}50%{box-shadow:none;background:#1a1a1a}}.indicator-key--sent .indicator-key__led{background:linear-gradient(#3d9a50,#52b862 40%,#46a758);animation:none;box-shadow:inset 0 1px 1px #82e69633,inset 0 -.5px .5px #143c194d}.indicator-key--active .indicator-key__led{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);animation:none;box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}[data-mode=light] .indicator-key--active .indicator-key__led,[data-mode=light] .indicator-key--sending .indicator-key__led{background:#ffb020;box-shadow:0 0 8px #ffb42880,0 0 3px #ffc83c66}[data-mode=light] .indicator-key--sent .indicator-key__led{background:#4ade60;box-shadow:0 0 8px #50dc6480,0 0 3px #64f07866}.mini-widget{gap:.25rem;padding:.75rem}.mini-widget-header{align-items:center;gap:.375rem;min-height:1.25rem;display:flex}.mini-widget-icon{width:1rem;height:1rem;color:var(--icon-widget);flex-shrink:0}.mini-widget-title{font-family:Poppins,sans-serif;font-size:var(--text-xs);color:var(--fg-muted);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;text-overflow:ellipsis;font-weight:500;line-height:1.2;overflow:hidden}.mini-widget-value{font-family:var(--font-data);font-size:var(--text-xl);color:var(--fg-primary);font-weight:600;line-height:1.1}.mini-widget-value-lg{font-size:var(--text-2xl)}.mini-widget-value-sm{font-size:var(--text-lg)}.mini-widget-unit{font-size:var(--text-xs);color:var(--fg-muted);margin-left:.125rem;font-weight:400}.mini-widget-subtitle{font-family:var(--font-data);font-size:var(--text-sm);color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;line-height:1.3;overflow:hidden}.mini-widget-status-dot{border-radius:50%;flex-shrink:0;width:.5rem;height:.5rem}.mini-widget-status-dot.excellent{background:var(--signal-excellent)}.mini-widget-status-dot.good{background:var(--signal-good)}.mini-widget-status-dot.fair{background:var(--signal-fair)}.mini-widget-status-dot.poor{background:var(--signal-poor)}.mini-widget-status-dot.critical{background:var(--signal-critical)}.mini-widget-status-dot.unknown{background:var(--signal-unknown)}.mini-widget-trend{font-size:var(--text-xs);align-items:center;gap:.125rem;font-weight:500;display:flex}.mini-widget-trend.up{color:var(--sys-red)}.mini-widget-trend.down{color:var(--sys-green)}.mini-widget-trend.stable{color:var(--fg-muted)}.mini-widget-sparkline{width:100%;min-width:1px;height:1.5rem;min-height:1px;margin-top:auto}.mini-widget-loading{justify-content:center;align-items:center;min-height:4rem;display:flex}.mini-widget-loading-spinner{border:2px solid var(--edge-subtle);border-top-color:var(--sys-blue);border-radius:50%;width:1rem;height:1rem;animation:.8s linear infinite spin}.mini-widget-error{min-height:4rem;color:var(--fg-muted);font-size:var(--text-sm);justify-content:center;align-items:center;display:flex}.mini-widget-progress{background:var(--subtle);border-radius:.125rem;height:.25rem;margin-top:auto;overflow:hidden}.mini-widget-progress-bar{border-radius:.125rem;height:100%;transition:width .3s}.mini-widget-progress-bar.excellent{background:var(--signal-excellent)}.mini-widget-progress-bar.good{background:var(--signal-good)}.mini-widget-progress-bar.fair{background:var(--signal-fair)}.mini-widget-progress-bar.poor{background:var(--signal-poor)}.mini-widget-progress-bar.critical{background:var(--signal-critical)}.mini-widget-toggle{align-items:center;gap:.5rem;display:flex}.mini-widget-toggle-track{background:var(--subtle);border:1px solid var(--edge-subtle);cursor:pointer;border-radius:.5rem;width:2rem;height:1rem;transition:all .2s;position:relative}.mini-widget-toggle-track.active{background:var(--sys-green);border-color:var(--sys-green)}.mini-widget-toggle-thumb{background:#fff;border-radius:50%;width:.75rem;height:.75rem;transition:left .2s;position:absolute;top:50%;left:.125rem;transform:translateY(-50%)}.mini-widget-toggle-track.active .mini-widget-toggle-thumb{left:calc(100% - .875rem)}.mesh-health-container{margin-bottom:1rem}@media(min-width:640px){.mesh-health-container{margin-bottom:1.5rem}}.mesh-health-header{align-items:center;gap:.375rem;margin-bottom:.5rem;display:flex}@media(min-width:640px){.mesh-health-header{gap:.5rem;margin-bottom:.75rem}}.widget-row{gap:.5rem;display:grid}@media(min-width:640px){.widget-row{gap:.75rem}}@media(min-width:768px){.widget-row{grid-template-columns:repeat(3,1fr)}.mini-widget{height:7.5rem}}@media(max-width:767px){.widget-row{grid-template-columns:repeat(2,1fr)}.mini-widget{min-height:5.5rem;padding:.5rem;overflow:hidden}.mini-widget-header{gap:.25rem;min-height:1rem}.mini-widget-icon{width:.75rem;height:.75rem}.mini-widget-title{font-size:.5625rem}.mini-widget-value{font-size:var(--text-base);line-height:1}.mini-widget-value-lg{font-size:var(--text-lg)}.mini-widget-value-sm{font-size:var(--text-base)}.mini-widget-unit{font-size:.625rem}.mini-widget-subtitle{font-size:.625rem;line-height:1.2}.mini-widget-sparkline{display:none}.mini-widget-progress{margin-top:.25rem}}.mini-widget-value.excellent{color:var(--signal-excellent)}.mini-widget-value.good{color:var(--signal-good)}.mini-widget-value.fair{color:var(--signal-fair)}.mini-widget-value.poor{color:var(--signal-poor)}.mini-widget-value.critical{color:var(--signal-critical)}.data-box{border-radius:var(--radius-sm);background:var(--data-box-bg);border:1px solid var(--data-box-border);font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);--data-box-color:var(--fg-primary);color:var(--data-box-color);letter-spacing:-.03em;font-variant-numeric:tabular-nums;font-feature-settings:"zero","tnum";white-space:nowrap;text-overflow:ellipsis;justify-content:center;align-items:center;min-width:0;padding:.25rem .5rem;line-height:1.2;display:inline-flex;overflow:hidden}.data-box-compact,.data-box-responsive{font-size:var(--text-xs);border-radius:var(--radius-xs);padding:.125rem .375rem}@media(min-width:640px){.data-box-responsive{font-size:var(--text-sm);border-radius:var(--radius-sm);padding:.25rem .5rem}}.data-box-hug{width:auto}.data-box-fill{width:100%;display:flex}.data-box-left{justify-content:flex-start}.data-box-center{justify-content:center}.data-box-right{justify-content:flex-end}.data-box-outlined{background:var(--data-box-accent)}@supports (color:color-mix(in lab,red,red)){.data-box-outlined{background:color-mix(in srgb,var(--data-box-accent)10%,transparent)}}.data-box-outlined{border:1.5px solid var(--data-box-accent);color:var(--data-box-accent);font-weight:650}.data-box-compact.data-box-outlined{border-width:1.5px}.data-box-label{font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--fg-muted);margin-bottom:.25rem;line-height:1.3}.input-base{border-radius:var(--radius-md);background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);width:100%;color:var(--fg-primary);transition:border-color var(--duration-fast)var(--ease-out),box-shadow var(--duration-fast)var(--ease-out);padding:.625rem .875rem;font-size:.875rem;line-height:1.5}.input-base::placeholder{color:var(--fg-muted)}.input-base:focus{border-color:var(--sys-blue);box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-base:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.input-base:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.input-compact{padding:.375rem .625rem;font-size:.8125rem}.input-error{border-color:var(--sys-red)}.input-error:focus{box-shadow:0 0 0 var(--ring-width-default) var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.input-error:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-red)25%,transparent)}}.input-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-md);background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);width:100%;color:var(--fg-primary);cursor:pointer;transition:border-color var(--duration-fast)var(--ease-out);padding:.625rem 2.5rem .625rem .875rem;font-size:.875rem}.input-select:focus{border-color:var(--sys-blue);box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-select:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.input-group{align-items:center;display:flex;position:relative}.input-group-icon{pointer-events:none;color:var(--fg-muted);width:1rem;height:1rem;position:absolute;left:.75rem}.input-group .input-base{padding-left:2.25rem}.input-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-xs);background-color:var(--surface-tint-light);border:var(--stroke-thin)solid var(--edge-subtle);cursor:pointer;width:1rem;height:1rem;transition:background-color var(--duration-fast)var(--ease-out),border-color var(--duration-fast)var(--ease-out)}.input-checkbox:checked{background-color:var(--sys-blue);border-color:var(--sys-blue)}.input-checkbox:focus-visible{box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-checkbox:focus-visible{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.toggle-switch-track{cursor:pointer;background-color:var(--bg-1);border-radius:9999px;align-items:center;transition:background-color .2s,box-shadow .2s;display:inline-flex;position:relative;box-shadow:inset 3px 3px 6px #0009,inset -3px -3px 6px #ffffff0d,inset 0 1px 2px #0006,inset 0 -1px 1px #ffffff0a}[data-mode=light] .toggle-switch-track{background-color:#ebedef;box-shadow:inset 3px 3px 6px #0000001f,inset -3px -3px 6px #00000003,inset 0 1px 2px #00000014,inset 0 -1px 1px #00000002}.toggle-switch-track:disabled{opacity:.5;cursor:not-allowed}.toggle-switch-thumb{background:linear-gradient(145deg,#f5f5f5,#e0e0e0);border-radius:9999px;justify-content:center;align-items:center;transition:transform .2s;display:inline-flex;position:relative;box-shadow:2px 2px 4px #0000004d,-1px -1px 3px #ffffff26}[data-mode=light] .toggle-switch-thumb{background:linear-gradient(145deg,#fff,#f7f7f7);box-shadow:3px 3px 6px #00000014,-2px -2px 5px #fffc}.toggle-switch-dot{background-color:#22c55e;border-radius:9999px;transition:opacity .2s,background-color .2s;box-shadow:inset 0 1px 2px #0000004d,inset 0 -.5px 1px #fff3}[data-mode=light] .toggle-switch-dot{background-color:#10b981}.toggle-switch-dot-danger{background-color:#ef4444}[data-mode=light] .toggle-switch-dot-danger{background-color:#dc2626}.toggle-switch-track[data-size=sm]{width:2.25rem;height:1.25rem}.toggle-switch-track[data-size=sm] .toggle-switch-thumb{width:.875rem;height:.875rem}.toggle-switch-track[data-size=sm] .toggle-switch-dot{width:.5rem;height:.5rem}.toggle-switch-track[data-size=md]{width:2.75rem;height:1.5rem}.toggle-switch-track[data-size=md] .toggle-switch-thumb{width:1rem;height:1rem}.toggle-switch-track[data-size=md] .toggle-switch-dot{width:.625rem;height:.625rem}.toggle-switch-track[data-size=lg]{width:3.5rem;height:1.75rem}.toggle-switch-track[data-size=lg] .toggle-switch-thumb{width:1.25rem;height:1.25rem}.toggle-switch-track[data-size=lg] .toggle-switch-dot{width:.75rem;height:.75rem}input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}input:focus-visible{box-shadow:0 0 0 2px var(--sys-blue);outline:none}select{background-image:none}.terminal-card{height:calc(100dvh - 132px);min-height:280px;max-height:calc(100vh - 100px);padding-bottom:env(safe-area-inset-bottom,0)}@media(min-width:640px){.terminal-card{height:calc(100dvh - 160px);min-height:400px}}@media(min-width:1024px){.terminal-card{height:calc(100vh - 120px);min-height:500px}}.terminal-ascii{letter-spacing:-.5px;font-size:8px}@media(min-width:375px){.terminal-ascii{letter-spacing:0;font-size:9px}}@media(min-width:414px){.terminal-ascii{font-size:10px}}@media(min-width:640px){.terminal-ascii{font-size:11px}}@media(min-width:768px){.terminal-ascii{font-size:12px}}@media(min-width:1024px){.terminal-ascii{font-size:13px}}@supports (-webkit-touch-callout:none){.terminal-card input{font-size:16px}}.terminal-card>div:first-child{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.terminal-gutter{padding:8px}@media(min-width:640px){.terminal-gutter{padding:16px}}.terminal-gutter .xterm{height:100%}.terminal-gutter .xterm-viewport{-webkit-overflow-scrolling:touch;overscroll-behavior:contain;overscroll-behavior-y:contain;overflow-y:auto!important}.terminal-gutter .xterm-screen{overflow:hidden}@media(max-width:639px){.terminal-gutter{touch-action:pan-y}.terminal-gutter .xterm-viewport{scroll-behavior:smooth}}[data-mode=light] .terminal-gutter{background:#eff0f1}[data-mode=light] .terminal-gutter .xterm-viewport{background:#eff0f1!important}.terminal-completions{font-family:JetBrains Mono,IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:13px;line-height:1.375}@media(max-width:639px){.terminal-completions{font-size:14px}.terminal-completions .overflow-y-auto{max-height:200px!important}}.terminal-ac-option{cursor:pointer;align-items:baseline;gap:.5rem;padding:.625rem .75rem;transition:background-color .1s;display:flex}@media(min-width:640px){.terminal-ac-option{padding:.25rem .75rem}}.terminal-ac-option__indicator{text-align:center;width:.75rem;color:var(--sys-blue);opacity:.8;flex-shrink:0}.terminal-ac-option__cmd{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.terminal-ac-option__desc{color:var(--fg-muted);flex-shrink:0;padding-left:.75rem;font-size:.6875rem}@media(max-width:359px){.terminal-ac-option__desc{display:none}}.terminal-ac-hints{color:var(--fg-muted);border-top:1px solid var(--terminal-border);justify-content:space-between;align-items:center;padding:.375rem .75rem;font-size:.6875rem;display:flex}@media(max-width:639px){.terminal-ac-hints{padding:.5rem .75rem;font-size:.75rem}}.terminal-mobile-input-bar{background:var(--terminal-bg-input,#0a0a0a);border-top:1px solid var(--terminal-border);align-items:center;gap:.5rem;padding:.5rem .75rem;display:flex}.terminal-mobile-input{min-width:0;color:var(--tui-body,#fff);border-radius:var(--radius-md);caret-color:var(--tui-accent,#ff8c00);background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;outline:none;flex:1;padding:.625rem .75rem;font-family:JetBrains Mono,IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:16px;line-height:1.25;box-shadow:inset 0 2px 4px #000000e6,inset 0 -1px #ffffff0a}.terminal-mobile-input::placeholder{color:var(--tui-placeholder,#666)}.terminal-mobile-input:focus{box-shadow:inset 0 2px 4px #000000e6,inset 0 -1px #ffffff0a,0 0 0 2px #3b82f64d}[data-mode=light] .terminal-mobile-input-bar{background:#dadde2}[data-mode=light] .terminal-mobile-input{color:var(--tui-body,#111);caret-color:#2a2d30;background:#eff0f1;box-shadow:inset 0 2px 4px #00000014,inset 0 -1px #ffffff80}[data-mode=light] .terminal-mobile-input::placeholder{color:#95999e}[data-mode=light] .terminal-mobile-input:focus{box-shadow:inset 0 2px 4px #00000014,inset 0 -1px #ffffff80,0 0 0 2px #3b82f640}.terminal-send-btn{border-radius:var(--radius-md);width:44px;height:44px;color:var(--tui-accent,#ff8c00);cursor:pointer;-webkit-tap-highlight-color:transparent;background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;transition:background-color .1s,transform 50ms;display:flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}.terminal-send-btn:active{transform:scale(.95);box-shadow:inset 0 3px 6px #000000e6,inset 0 -1px #ffffff05}.terminal-send-btn svg{stroke-width:2px;width:20px;height:20px}[data-mode=light] .terminal-send-btn{color:#fff;background:linear-gradient(135deg,#71717a,#a1a1aa);box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}.terminal-status-bar{color:var(--fg-muted);border-top:1px solid var(--terminal-border);justify-content:space-between;align-items:center;padding:.375rem .75rem;font-size:.6875rem;display:flex}@media(min-width:640px){.terminal-status-bar{padding:.25rem 1rem;font-size:.75rem}}.terminal-tap-hint{color:var(--fg-muted);opacity:.7;align-items:center;gap:.25rem;display:flex}.terminal-tap-hint svg{width:12px;height:12px}.seven-seg{vertical-align:middle;flex-shrink:1;align-items:center;gap:4px;min-width:0;line-height:1;display:inline-flex;transform:skew(-8deg)}.seven-seg__char{flex-shrink:0;display:block;overflow:visible}.seven-seg-panel{color:#ff8c00;height:var(--tui-header-height,52px);border-radius:var(--radius-md);background:#000;flex-shrink:1;align-items:center;min-width:0;padding:0 12px;display:inline-flex;overflow:hidden;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}@media(min-width:640px){.seven-seg-panel{padding:0 16px}}[data-mode=light] .seven-seg-panel{color:#18181b;border-radius:var(--radius-lg);background:linear-gradient(135deg,#52525b,#71717a);border:none;padding:8px 16px;position:relative;overflow:visible;box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}@media(min-width:640px){[data-mode=light] .seven-seg-panel{padding:12px 28px}}[data-mode=light] .seven-seg-panel:before{content:"";z-index:0;background:#d0d3d8;border-radius:0;position:absolute;top:8px;right:8px;bottom:8px;left:8px;box-shadow:inset 0 2px 4px #00000040,inset 0 1px 1px #00000026}@media(min-width:640px){[data-mode=light] .seven-seg-panel:before{top:12px;right:12px;bottom:12px;left:12px}}[data-mode=light] .seven-seg-panel .seven-seg{z-index:1;position:relative}[data-mode=light] .seven-seg-panel:after{content:"";pointer-events:none;z-index:2;background:linear-gradient(135deg,#ffffff59,#ffffff14 40%,#0000 60%);border-radius:0;position:absolute;top:8px;right:8px;bottom:8px;left:8px}@media(min-width:640px){[data-mode=light] .seven-seg-panel:after{top:12px;right:12px;bottom:12px;left:12px}}@keyframes flash-white-fade{0%{opacity:.2}to{opacity:0}}.flash-overlay{border-radius:inherit;pointer-events:none;z-index:50;background-color:#7c6ef6;animation:.6s ease-out forwards flash-white-fade;position:absolute;top:0;right:0;bottom:0;left:0}@keyframes flash-row-bg{0%{background-color:#7c6ef62e}to{background-color:#0000}}.flash-row{animation:.6s ease-out forwards flash-row-bg}@keyframes flash-icon-pulse{0%{color:#fff;filter:drop-shadow(0 0 6px #fffc)}to{color:var(--fg-muted);filter:none}}.flash-icon{animation:.6s ease-out forwards flash-icon-pulse}@keyframes pulse-slow{0%,to{opacity:1}50%{opacity:.4}}.animate-pulse-slow{animation:3s ease-in-out infinite pulse-slow}@keyframes partytime-bg{0%{opacity:0}3%{opacity:1}90%{opacity:1}to{opacity:0}}@keyframes partytime-crt{0%{opacity:1;filter:brightness(4)saturate(0);transform:scaleY(.005)scaleX(.6)}2.5%{opacity:1;filter:brightness(1.5)saturate(.6);transform:scaleY(1.02)scaleX(1)}4%{opacity:1;filter:brightness()saturate();transform:scaleY(1)scaleX(1)}5%{opacity:0}6%{opacity:1}7.5%{opacity:0}8.5%{opacity:1}90%{opacity:1;filter:brightness();transform:scaleY(1)scaleX(1)}94%{opacity:1;filter:brightness(3)saturate(0);transform:scaleY(.005)scaleX(1)}97%{opacity:.8;filter:brightness(5);transform:scaleY(.005)scaleX(.005)}to{opacity:0;transform:scaleY(0)scaleX(0)}}.partytime-scanlines{mix-blend-mode:multiply;background:repeating-linear-gradient(#0000 0,#0000 2px,#0000002e 2px,#0000002e 4px)}.partytime-glow{border-radius:6px;box-shadow:0 0 30px 6px #b4ffe61f,0 0 80px 20px #0009}@keyframes shimmer-border{0%{background-position:200% 0}to{background-position:-200% 0}}.shimmer-border{z-index:1;pointer-events:none;background:linear-gradient(90deg,transparent 0%,transparent 25%,var(--sys-blue)50%,transparent 75%,transparent 100%);border-radius:inherit;opacity:.8;background-size:200% 100%;padding:2px;animation:2s ease-in-out infinite shimmer-border;position:absolute;top:0;right:0;bottom:0;left:0;-webkit-mask-image:linear-gradient(#fff 0 0),linear-gradient(#fff 0 0);mask-image:linear-gradient(#fff 0,#fff 0),linear-gradient(#fff 0,#fff 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}@keyframes shimmer-pulse{0%,to{filter:var(--shimmer-shadow)brightness(1)}50%{filter:var(--shimmer-shadow)brightness(1.5)saturate(1.3)hue-rotate(-20deg)}}@keyframes shimmer-bar{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes sparkle-base{0%{background-position:0%}50%{background-position:100%}to{background-position:0%}}@keyframes sparkle-sweep{0%{transform:translate(-120%)}to{transform:translate(220%)}}.sparkle-bar-track{border-radius:inherit;box-shadow:inset 0 1px 2px #0006}.sparkle-bar-fill{background:linear-gradient(90deg,var(--sys-blue)0%,var(--sys-cyan)30%,var(--sys-indigo)60%,var(--sys-blue)100%);background-size:300% 100%;animation:4s ease-in-out infinite sparkle-base}.sparkle-bar-depth{border-radius:inherit;pointer-events:none;background:linear-gradient(#ffffff8c 0,#ffffff26 2px,#0000 40%,#0000 65%,#00000040);position:absolute;top:0;right:0;bottom:0;left:0}.sparkle-bar-sweep{border-radius:inherit;will-change:transform;pointer-events:none;background:linear-gradient(90deg,#0000,#0000 42%,#ffffff1f 45%,#ffffffa6 49%,#ffffffd9,#ffffffa6 51%,#ffffff1f 55%,#0000 58%,#0000);animation:2.2s cubic-bezier(.4,0,.2,1) infinite sparkle-sweep;position:absolute;top:0;right:0;bottom:0;left:0}@supports (color:color(display-p3 1 1 1)){.sparkle-bar-fill{background:linear-gradient(90deg,#0a84fe,#0089f4,#008ee9 7.5%,#0095d8 15%,#00a1bd 30%,#0093ca 37.5%,#0090ce,#058cd3,#1e87d4,#2b83d5 45%,#4970da,#5b5bde 60%,#4570ee 80%,#337af6 90%,#257ffa,#0a84fe) 0 0/300% 100%;background:linear-gradient(90deg,#0a84fe,color(xyz 0.256 0.245 0.923),color(xyz 0.248 0.252 0.875) 7.5%,color(xyz 0.234 0.266 0.782) 15%,color(xyz 0.209 0.295 0.612) 30%,color(xyz 0.211 0.253 0.637),#2b83d5,#4970da,#5b5bde 60%,#4570ee 80%,#337af6 90%,#257ffa,#0a84fe) 0 0/300% 100%}.sparkle-bar-depth{background:linear-gradient(#fff9,#ffffff2e 2px,#0000 40%,#0000 65%,#0000004d)}.sparkle-bar-sweep{background:linear-gradient(90deg,#0000,#0000 42%,#ffffff26 45%,#ffffffb3 49%,#ffffffe6,#ffffffb3 51%,#ffffff26 55%,#0000 58%,#0000)}}.shimmer-border-light{background:linear-gradient(90deg,#0000,#0000,#fff6,#0000,#0000)}.shimmer-indicator{background:var(--elevated);border-radius:2px;width:40px;height:4px;position:relative;overflow:hidden}.shimmer-indicator-inner{background:linear-gradient(90deg,transparent 0%,var(--sys-blue)50%,transparent 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite shimmer-border;position:absolute;top:0;right:0;bottom:0;left:0}.map-container-16-9{width:100%;height:80dvh;min-height:320px;max-height:900px;position:relative}@media(max-width:639px){.map-container-16-9{width:calc(100% + 2rem);height:70dvh;min-height:280px;max-height:600px;margin-left:-1rem;margin-right:-1rem}.map-container-16-9>div{border-radius:0!important}}@media(min-width:640px)and (max-width:1023px){.map-container-16-9{height:75dvh;max-height:700px}}@media(min-width:1920px){.map-container-16-9{max-height:1000px}}.map-container-fullscreen{width:100vw!important;height:calc(100dvh - 3.5rem)!important;aspect-ratio:unset!important;min-height:unset!important;max-height:unset!important;z-index:999!important;border-radius:0!important;padding-bottom:0!important;position:fixed!important;top:3.5rem!important;right:0!important;bottom:0!important;left:0!important}@media(min-width:1024px){.map-container-fullscreen{height:100dvh!important;top:0!important}}.map-blue-water{position:relative}.map-blue-water .leaflet-tile-pane{filter:sepia(.15)hue-rotate(180deg)saturate(.7)brightness(.95)}.map-blue-water:after{content:"";background:linear-gradient(180deg,var(--map-overlay-blue-dark)0%,var(--map-overlay-blue-light)100%);pointer-events:none;z-index:400;mix-blend-mode:multiply;position:absolute;top:0;right:0;bottom:0;left:0}.map-blue-water .leaflet-marker-pane,.map-blue-water .leaflet-popup-pane,.map-blue-water .leaflet-overlay-pane{filter:none!important}.leaflet-control-attribution{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.leaflet-control-attribution{background:color-mix(in srgb,var(--body)85%,transparent)!important}}.leaflet-control-attribution{color:var(--fg-muted)!important;border-radius:var(--radius-xs)0 0 0!important;padding:2px 6px!important;font-size:10px!important}.leaflet-control-attribution a{color:var(--fg-secondary)!important}.leaflet-control-zoom{overflow:hidden;border-radius:var(--radius-lg)!important;background:var(--body)!important;border:none!important;margin-top:1rem!important;margin-left:1rem!important}@supports (color:color-mix(in lab,red,red)){.leaflet-control-zoom{background:color-mix(in srgb,var(--body)85%,transparent)!important}}.leaflet-control-zoom{-webkit-backdrop-filter:blur(12px);border:1px solid var(--map-border-accent)!important}.leaflet-control-zoom a{color:var(--fg-secondary)!important;border:none!important;border-bottom:1px solid var(--map-border-accent-subtle)!important;background:0 0!important;width:32px!important;height:32px!important;font-size:16px!important;font-weight:500!important;line-height:32px!important}.leaflet-control-zoom a:last-child{border-bottom:none!important}.leaflet-control-zoom a:hover{background:var(--map-hover-tint)!important;color:var(--fg-primary)!important}.leaflet-control-zoom a.leaflet-disabled{opacity:.5;color:var(--fg-muted)!important}.map-dot-marker{background:0 0!important;border:none!important}.map-ring-marker,.map-filled-marker,.map-local-marker{cursor:pointer!important;z-index:500!important;pointer-events:auto!important;background:0 0!important;border:none!important}.leaflet-marker-pane{z-index:600!important;pointer-events:auto!important}.leaflet-marker-pane .leaflet-marker-icon{pointer-events:auto!important}.leaflet-popup-content-wrapper{border-radius:var(--radius-lg)!important;background-color:var(--map-popup-bg)!important;-webkit-backdrop-filter:blur(12px)brightness(.7)saturate(.9)!important;backdrop-filter:blur(12px)brightness(.7)saturate(.9)!important;box-shadow:inset 0 0 0 1px var(--map-hover-tint),var(--map-popup-shadow)!important;border:none!important;padding:0!important;position:relative!important;overflow:hidden!important}.leaflet-popup-content{color:var(--fg-primary)!important;margin:.75rem!important}.leaflet-popup-content strong{color:var(--fg-primary)!important}.leaflet-popup-content hr{border-color:var(--map-border-accent-subtle)!important;margin:.5rem 0!important}.leaflet-popup-tip-container{display:none!important}.leaflet-popup-close-button{color:var(--fg-muted)!important;width:24px!important;height:24px!important;padding:6px!important;font-size:18px!important;top:4px!important;right:4px!important}.leaflet-popup-close-button:hover{color:var(--fg-primary)!important;background:var(--map-hover-tint)!important;border-radius:var(--radius-xs)!important}.leaflet-tooltip{white-space:nowrap;border-radius:var(--radius-md)!important;background-color:var(--body)!important;box-shadow:inset 0 0 0 1px var(--default-border-glow),inset 1.5px 2px 0 -1px var(--default-highlight-tl),inset -1.5px -1.5px 0 -1px var(--default-highlight-br),inset 0 -1px 3px 0 var(--default-shadow-inner)!important;color:var(--fg-primary)!important;border:none!important;padding:.375rem .5rem!important;font-size:11px!important;position:relative!important;overflow:hidden!important}.leaflet-tooltip:after{content:""!important;pointer-events:none!important;border-radius:inherit!important;z-index:999!important;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important;position:absolute!important;top:0!important;right:0!important;bottom:0!important;left:0!important}.leaflet-tooltip:before{display:none!important}.leaflet-tooltip .text-fg-muted{color:var(--fg-muted)!important}.maplibregl-popup{font-family:var(--font-display),system-ui,-apple-system,sans-serif;font-size:var(--text-sm)}.maplibregl-popup-content{min-width:140px;border-radius:var(--radius-lg)!important;background-color:var(--body)!important;box-shadow:inset 0 0 0 1px var(--default-border-glow),inset 1.8px 3px 0 -2px var(--default-highlight-tl),inset -2px -2px 0 -2px var(--default-highlight-br),inset -3px -8px 1px -6px var(--default-highlight-edge),inset -.3px -1px 4px 0 var(--default-shadow-inner),inset 0 3px 4px -2px var(--default-shadow-top)!important;color:var(--fg-primary)!important;border:none!important;padding:.75rem!important;position:relative!important;overflow:hidden!important}.maplibregl-popup-content:after{content:""!important;pointer-events:none!important;border-radius:inherit!important;z-index:999!important;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important;position:absolute!important;top:0!important;right:0!important;bottom:0!important;left:0!important}.maplibregl-popup-close-button{border-radius:var(--radius-xs);transition:background .1s,color .1s;color:var(--fg-muted)!important;width:24px!important;height:24px!important;padding:6px!important;font-size:18px!important;top:4px!important;right:4px!important}.maplibregl-popup-close-button:hover{color:var(--fg-primary)!important;background:var(--map-hover-tint)!important}.maplibregl-popup-tip{display:none!important}.maplibregl-popup-anchor-bottom .maplibregl-popup-tip{border-top-color:var(--tooltip-bg)!important}.maplibregl-marker.local-node-marker{z-index:10!important}.maplibregl-marker:has(.z-50){z-index:20!important}.maplibregl-popup{z-index:100!important}.maplibregl-ctrl-attrib{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib{background:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib{color:var(--fg-muted)!important;padding:2px 6px!important;font-size:10px!important}.maplibregl-ctrl-attrib a{color:var(--fg-secondary)!important}.maplibregl-ctrl-attrib.maplibregl-compact{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib.maplibregl-compact{background:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib.maplibregl-compact{border-radius:var(--radius-xs)!important}.maplibregl-map,.leaflet-container{touch-action:pan-x pan-y;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.maplibregl-ctrl button:focus,.leaflet-control a:focus{outline:2px solid var(--sys-blue);outline-offset:2px}@media(prefers-contrast:high){.maplibregl-ctrl button,.leaflet-control a{border:2px solid!important}.map-legend,.map-controls{border:2px solid var(--fg-primary)!important}}@media(prefers-reduced-motion:reduce){.maplibregl-map,.leaflet-container{transition:none!important}.maplibregl-map *{transition:none!important;animation:none!important}}@-moz-document url-prefix(){.maplibregl-canvas{transform:translateZ(0)}}@supports (-webkit-touch-callout:none){.maplibregl-canvas{will-change:transform;transform:translateZ(0)}}@media(forced-colors:active){.maplibregl-ctrl button,.leaflet-control a{forced-color-adjust:none;color:buttontext!important;background:canvas!important;border:1px solid buttontext!important}.maplibregl-popup-content,.leaflet-popup-content-wrapper{color:canvastext!important;background:canvas!important;border:2px solid canvastext!important}}.maplibregl-ctrl-attrib-button{background-color:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib-button{background-color:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib-button{border-radius:var(--radius-xs)!important}.maplibregl-ctrl-group{border-radius:var(--radius-md)!important;background-color:var(--map-ui-bg,var(--surface))!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a)!important;border:none!important;position:relative!important;overflow:hidden!important}.maplibregl-ctrl-group:after{display:none!important}.maplibregl-ctrl-group button{border:none!important;border-bottom:1px solid var(--map-ui-border,var(--edge-subtle))!important;background:0 0!important;width:28px!important;height:28px!important}.maplibregl-ctrl-group button:last-child{border-bottom:none!important}.maplibregl-ctrl-group button:hover{background:var(--map-ui-hover,var(--elevated))!important}.maplibregl-ctrl-group button .maplibregl-ctrl-icon{filter:invert()brightness(.75)}.maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon{filter:invert()brightness()}[data-basemap=light] .maplibregl-ctrl-group button .maplibregl-ctrl-icon{filter:brightness(.3)}[data-basemap=light] .maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon{filter:brightness(.1)}.maplibregl-ctrl-scale{border:1px solid var(--map-local-color)!important;color:var(--map-local-color)!important;font-size:10px!important;font-family:var(--font-data)!important;background:0 0!important;border-top:none!important;border-radius:0!important;padding:2px 6px!important;line-height:1.2!important}.map-control-surface{border-radius:var(--radius-md);background-color:var(--map-ui-bg,var(--surface));color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);position:relative;overflow:hidden}.map-control-surface:after{display:none}.map-control-surface-active{border-radius:var(--radius-md);background-color:var(--map-ui-bg,var(--surface));color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border-strong,var(--edge-strong))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);position:relative;overflow:hidden}.map-control-surface-active:after{display:none}.map-control-surface .text-fg-secondary,.map-control-surface-active .text-fg-secondary,.map-legend-stack .text-fg-secondary{color:var(--map-ui-text-secondary,var(--fg-secondary))}.map-control-surface .text-fg-muted,.map-control-surface-active .text-fg-muted,.map-legend-stack .text-fg-muted{color:var(--map-ui-text-muted,var(--fg-muted))}.map-controls-container{background-color:var(--map-ui-bg,var(--surface));max-width:calc(100vw - 1.5rem);color:var(--map-ui-text,var(--fg-primary));border-radius:var(--radius-md);box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);flex-direction:column;align-items:stretch;gap:0;display:flex;overflow:hidden}.map-controls-row{flex-wrap:wrap;justify-content:flex-end;gap:.25rem;padding:.25rem;display:flex}.map-controls-row+.map-controls-row{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}.map-controls-secondary{flex-wrap:wrap}.map-control-btn{touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;padding:.375rem;transition:background-color .15s}.map-control-btn:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px;border-radius:var(--radius-sm)}@media(hover:hover)and (pointer:fine){.map-control-btn:hover{background-color:var(--map-ui-hover,var(--elevated))}}.map-control-btn:active{background-color:var(--map-ui-active,var(--subtle))}.map-tool-btn{touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}.map-tool-btn:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px}.map-tool-btn:active{filter:brightness(.85)}.map-control-surface button:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px}.map-control-icon{width:16px;height:16px}.map-nav-module{padding:.25rem}button[data-tint=warning]{--tint-color:var(--sys-amber)}button[data-tint=success]{--tint-color:var(--sys-green)}button[data-tint=primary]{--tint-color:var(--sys-blue)}.map-control-surface button[data-tint]{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]{background-color:color-mix(in srgb,var(--tint-color)12%,transparent)}}@media(hover:hover)and (pointer:fine){.map-control-surface button[data-tint]:hover{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]:hover{background-color:color-mix(in srgb,var(--tint-color)18%,transparent)}}}.map-control-surface button[data-tint]:active{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]:active{background-color:color-mix(in srgb,var(--tint-color)22%,transparent)}}@media(max-width:639px){.map-controls-container{border-radius:var(--radius-md);max-width:calc(100vw - 1rem)}.map-controls-row{gap:.125rem;padding:.1875rem}.map-control-btn{justify-content:center;align-items:center;min-width:44px;min-height:44px;padding:.625rem;display:flex}.map-control-icon{width:14px;height:14px}.map-control-label{display:none}.map-nav-module{padding:.1875rem}.maplibregl-ctrl-group{border-radius:var(--radius-md)!important}.maplibregl-ctrl-group button{width:28px!important;height:28px!important}.maplibregl-ctrl-group button .maplibregl-ctrl-icon{width:18px!important;height:18px!important}}@media(min-width:640px)and (max-width:1023px){.map-controls-row,.map-nav-module{padding:.25rem}}@media(min-width:1024px){.map-controls-row{gap:.375rem;padding:.375rem}.map-nav-module{padding:.375rem}}.map-legend-stack{z-index:600;background-color:var(--map-ui-bg,var(--surface));max-height:calc(100% - 1.5rem);color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);flex-direction:column;gap:0;display:flex;position:absolute;bottom:.75rem;left:.75rem;border-radius:var(--radius-md)!important;overflow:hidden!important}@media(max-width:639px){.map-legend-stack{width:auto;max-width:calc(100vw - 1.5rem)}}@media(min-width:640px){.map-legend-stack{max-width:160px;bottom:1rem;left:1rem}}.map-legend-stack>*,.map-legend-stack>.map-control-surface{box-shadow:none;background-color:#0000;border-radius:0}.map-legend-stack>*+*{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}.map-legend-stack .map-tool-btn{background-color:var(--map-ui-text,var(--fg-primary))}@supports (color:color-mix(in lab,red,red)){.map-legend-stack .map-tool-btn{background-color:color-mix(in srgb,var(--map-ui-text,var(--fg-primary))4%,transparent)}}.map-legend-stack>.map-tool-row+*{border-top:1.5px solid var(--map-ui-border-strong,var(--edge-strong))!important}.map-tool-row{flex-direction:column;display:flex;overflow:hidden}.map-tool-row>*+*{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}@media(max-width:639px){.map-tool-row{flex-direction:row}.map-tool-row>*+*{border-top:none;border-left:1px solid var(--map-ui-border,var(--edge-subtle))}.map-tool-row .map-tool-btn{justify-content:center;min-width:44px;min-height:44px;padding:.625rem;border-radius:0!important}.map-legend-stack>.map-tool-row>:first-child{border-top-left-radius:var(--radius-md)!important}.map-legend-stack>.map-tool-row>:last-child{border-top-right-radius:var(--radius-md)!important}.map-tool-row .map-tool-btn span:not(.sr-only){display:none}.map-tool-row .map-tool-btn svg{margin:0}}.map-edge-tooltip{z-index:1000;pointer-events:none;max-width:calc(100vw - 2rem);position:absolute;bottom:1rem;left:calc(50% + 85px);transform:translate(-50%)}.map-edge-tooltip-inner{pointer-events:auto;padding:.625rem 1rem}@media(max-width:639px){.map-edge-tooltip{bottom:.5rem;left:.5rem;right:.5rem;transform:none}.map-edge-tooltip-inner{border-radius:var(--radius-lg);background-color:var(--map-ui-bg,var(--body));padding:.75rem}.map-edge-tooltip .w-\[540px\]{width:100%;max-width:100%}}.map-container-fullscreen .map-edge-tooltip{bottom:1.5rem}[data-basemap=light]{--map-edge-rest:#0003;--map-edge-rest-bright:#0000004d;--map-edge-rest-dim:#0000001f;--map-ui-bg:#fff;--map-ui-bg-elevated:#fff;--map-ui-border:#0000001f;--map-ui-border-strong:#0003;--map-ui-text:#1a1a1a;--map-ui-text-secondary:#4a4a4a;--map-ui-text-muted:#737373;--map-ui-hover:#0000000f;--map-ui-active:#0000001a;--map-ui-stroke:#00000059;--map-ui-shadow:0 2px 8px #00000014,0 4px 16px #0000000a;--map-ui-stripe:#0000000a}[data-basemap=dark]{--map-ui-bg:var(--elevated);--map-ui-bg-elevated:var(--elevated);--map-ui-border:var(--edge-subtle);--map-ui-border-strong:var(--edge-strong);--map-ui-text:var(--fg-primary);--map-ui-text-secondary:var(--fg-secondary);--map-ui-text-muted:var(--fg-muted);--map-ui-hover:#ffffff1a;--map-ui-active:#ffffff24;--map-ui-stroke:#ffffff59;--map-ui-shadow:0 2px 10px #00000040,0 6px 20px #0003;--map-ui-stripe:#ffffff0a}[data-basemap] .map-control-surface,[data-basemap] .map-controls-container,[data-basemap] .map-legend-stack,[data-basemap] .map-legend-stack button,[data-basemap] .maplibregl-ctrl-group,[data-basemap] .maplibregl-ctrl-group button,[data-basemap] .maplibregl-popup-content,[data-basemap] .maplibregl-popup-close-button{transition:background-color .3s,color .3s,box-shadow .3s,border-color .3s!important}[data-basemap] .map-control-surface .text-fg-primary,[data-basemap] .map-control-surface .text-fg-secondary,[data-basemap] .map-control-surface .text-fg-muted,[data-basemap] .map-legend-stack .text-fg-primary,[data-basemap] .map-legend-stack .text-fg-secondary,[data-basemap] .map-legend-stack .text-fg-muted,[data-basemap] .maplibregl-popup-content .text-fg-primary,[data-basemap] .maplibregl-popup-content .text-fg-secondary,[data-basemap] .maplibregl-popup-content .text-fg-muted{transition:color .3s!important}[data-basemap] .map-control-surface .border-edge-subtle,[data-basemap] .map-legend-stack>*+*,[data-basemap] .map-controls-row+.map-controls-row{transition:border-color .3s!important}[data-basemap=light] .map-control-surface,[data-basemap=light] .map-controls-container,[data-basemap=light] .map-legend-stack{color:#1a1a1a!important;border-radius:var(--radius-md)!important;background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .maplibregl-ctrl-group{background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .maplibregl-ctrl-group button{border-bottom-color:#0000001f!important}[data-basemap=light] .maplibregl-ctrl-group button:hover{background-color:#0000000f!important}[data-basemap=light] .map-control-surface .text-fg-secondary,[data-basemap=light] .map-legend-stack .text-fg-secondary{color:#4a4a4a!important}[data-basemap=light] .map-control-surface .text-fg-muted,[data-basemap=light] .map-legend-stack .text-fg-muted{color:#737373!important}[data-basemap=light] .map-control-surface .text-fg-primary,[data-basemap=light] .map-legend-stack .text-fg-primary{color:#1a1a1a!important}[data-basemap=light] .map-control-surface button.text-fg-muted,[data-basemap=light] .map-control-surface [class*=text-fg-muted]{color:#737373!important}[data-basemap=light] .map-control-surface button:hover.text-fg-muted,[data-basemap=light] .map-control-surface button:hover .text-fg-muted{color:#1a1a1a!important}[data-basemap=dark] .map-control-surface button.text-fg-muted,[data-basemap=dark] .map-control-surface [class*=text-fg-muted]{color:var(--fg-secondary)!important}[data-basemap=dark] .map-control-surface button:hover.text-fg-muted,[data-basemap=dark] .map-control-surface button:hover [class*=text-fg-muted]{color:var(--fg-primary)!important}[data-basemap=light] .map-legend-stack>*+*,[data-basemap=light] .map-controls-row+.map-controls-row{border-top-color:#0000001f!important}[data-basemap=light] .map-control-surface .bg-border-subtle{background-color:#0000001f!important}[data-basemap=light] .map-control-surface .border-edge-subtle{border-color:#0000001f!important}[data-basemap=dark] .map-control-surface .border-edge-subtle{border-color:var(--edge-strong)!important}[data-basemap=light] .map-control-surface .surface-inner{box-shadow:inset 0 1px 2px #00000008;background-color:#00000008!important;border-color:#0000000f!important}[data-basemap=light] .map-control-surface .data-box{--data-box-bg:#00000008;--data-box-border:#00000014}[data-basemap=light] .map-control-btn:hover{background-color:#0000000f!important}[data-basemap=light] .map-control-btn:active{background-color:#0000001a!important}[data-basemap=light] .map-control-surface button:hover{color:var(--map-ui-text,#1a1a1a)!important;background-color:#00000014!important}[data-basemap=light] .map-control-surface button:active{color:var(--map-ui-text,#1a1a1a)!important;background-color:#0000001f!important}[data-basemap=dark] .map-control-surface [data-color]:hover{filter:brightness(1.4)}[data-basemap=light] .map-control-surface [data-color]:hover{filter:brightness(.92)}[data-basemap=light] .map-control-surface button[data-tint]{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]{background-color:color-mix(in srgb,var(--tint-color)14%,transparent)!important}}[data-basemap=light] .map-control-surface button[data-tint]:hover{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]:hover{background-color:color-mix(in srgb,var(--tint-color)22%,transparent)!important}}[data-basemap=light] .map-control-surface button[data-tint]:active{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]:active{background-color:color-mix(in srgb,var(--tint-color)28%,transparent)!important}}[data-basemap=dark] .maplibregl-popup-content{background-color:var(--body)!important;color:var(--fg-primary)!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,#ffffff8c),0 4px 16px #00000040!important}[data-basemap=dark] .maplibregl-popup-content:after{background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important}[data-basemap=dark] .maplibregl-popup-close-button{color:var(--fg-muted)!important}[data-basemap=dark] .maplibregl-popup-close-button:hover{color:var(--fg-primary)!important;background:#ffffff14!important}[data-basemap=light] .maplibregl-popup-content{color:#1a1a1a!important;background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .maplibregl-popup-content:after{display:none!important}[data-basemap=light] .maplibregl-popup-close-button{color:#737373!important}[data-basemap=light] .maplibregl-popup-close-button:hover{color:#1a1a1a!important;background:#0000000f!important}[data-basemap=light] .maplibregl-popup-content .text-fg-primary{color:#1a1a1a!important}[data-basemap=light] .maplibregl-popup-content .text-fg-secondary{color:#4a4a4a!important}[data-basemap=light] .maplibregl-popup-content .text-fg-muted{color:#737373!important}[data-basemap=light] .maplibregl-popup-content .data-box{--data-box-bg:#00000008;--data-box-border:#00000014}[data-basemap=light] .maplibregl-popup-content .surface-badge{background-color:#0000000d!important}[data-basemap=light] .maplibregl-popup-content .bg-subtle-fill-hover{background-color:#0000000a!important}[data-basemap=light] .maplibregl-popup-content button:hover{background-color:#0000000f!important}.border-map-ui-border{border-color:var(--map-ui-border)}@supports (color:color(display-p3 1 1 1)){.signal-bar-active{background-color:var(--p3-color,inherit)}}:root{--zinc-50:#fafafa;--zinc-75:#f7f7f8;--zinc-100:#f4f4f5;--zinc-200:#e4e4e7;--zinc-300:#d4d4d8;--zinc-400:#a1a1aa;--zinc-500:#71717a;--zinc-600:#52525b;--zinc-700:#3f3f46;--zinc-800:#27272a;--zinc-900:#18181b;--zinc-925:#111113;--zinc-950:#09090b;--sys-red:#e5484d;--sys-orange:#f76b15;--sys-amber:#ffb224;--sys-yellow:#f5d90a;--sys-brown:#ad7f58;--sys-green:#46a758;--sys-teal:#12a594;--sys-cyan:#00a2c7;--sys-blue:#3b82f6;--sys-indigo:#5b5bd6;--sys-purple:#8e4ec6;--sys-pink:#d6409f;--body:var(--zinc-950);--surface:var(--zinc-900);--elevated:var(--zinc-800);--subtle:var(--zinc-800);--edge-subtle:var(--zinc-800);--edge-strong:var(--zinc-600);--fg-primary:#fff;--fg-secondary:var(--zinc-400);--fg-muted:var(--zinc-500);--fg-invert:var(--zinc-950);--overlay-soft:#ffffff0a;--shadow-tint:#3b82f659;--sidebar-tint:#27272a80;--tooltip-bg:var(--zinc-800);--tooltip-fg:#fff;--tooltip-border:var(--zinc-800);--tooltip-shadow:0 4px 12px #0006;--hover-tint:#3b82f614;--default-tint:var(--zinc-900);--default-light:var(--zinc-700);--default-dark:var(--zinc-950);--default-reflex-light:0;--default-reflex-dark:0;--default-blur:0px;--default-blur-elevated:0px;--default-brightness:1;--default-surface-tint:linear-gradient(to bottom,#ffffff06,#ffffff04);--default-reflection-top:linear-gradient(to bottom,#ffffff05 0px,transparent 16px);--default-reflection-bottom:linear-gradient(to top,#ffffff05 0px,transparent 20px);--default-border-glow:#ffffff14;--default-highlight-tl:#ffffff1f;--default-highlight-br:#ffffff14;--default-highlight-edge:#ffffff0f;--default-shadow-inner:#00000026;--default-shadow-top:#0000001f;--default-bg-opacity:100%;--default-bg-opacity-elevated:100%;--signal-excellent:var(--sys-green);--signal-good:var(--sys-yellow);--signal-fair:var(--sys-amber);--signal-poor:var(--sys-orange);--signal-critical:var(--sys-red);--signal-unknown:var(--zinc-500);--sparkline-excellent:var(--signal-excellent);--sparkline-good:var(--signal-good);--sparkline-fair:var(--signal-fair);--sparkline-poor:var(--signal-poor);--sparkline-critical:var(--signal-critical);--sparkline-bg:#09090b80;--status-success:var(--sys-green);--status-warning:var(--sys-amber);--status-danger:var(--sys-red);--status-info:var(--sys-blue);--status-muted:var(--zinc-500);--pkt-advert:var(--sys-amber);--pkt-flood:var(--sys-cyan);--pkt-txt-msg:var(--sys-green);--pkt-ack:var(--zinc-500);--pkt-trace:var(--sys-amber);--pkt-req:var(--sys-teal);--pkt-response:var(--sys-pink);--pkt-grp-txt:var(--sys-pink);--pkt-grp-data:var(--sys-red);--pkt-path:var(--sys-amber);--pkt-anon:var(--sys-amber);--pkt-control:var(--sys-indigo);--pkt-unknown:var(--zinc-500);--pkt-science-req:#0090ff;--pkt-science-anon-req:#06c;--pkt-science-response:#6cf;--pkt-science-ack:#00e699;--pkt-science-advert:#fff200;--pkt-science-txt-msg:#ffb300;--pkt-science-grp-txt:#ff80c0;--pkt-science-grp-data:#f60;--pkt-science-multipart:#b3b3b3;--pkt-science-raw-custom:#e666cc;--pkt-science-path:#66b3ff;--pkt-science-trace:#33ffb3;--pkt-science-unknown:gray;--route-flood:var(--sys-blue);--route-direct:var(--sys-amber);--route-transport:var(--zinc-500);--chart-inner:var(--zinc-925);--chart-1:var(--sys-blue);--chart-2:var(--sys-teal);--chart-3:var(--sys-amber);--chart-4:var(--sys-orange);--chart-5:var(--sys-pink);--chart-6:var(--sys-indigo);--chart-7:var(--sys-cyan);--chart-8:var(--zinc-500);--chart-grid:#bfbfbf26;--chart-axis-tick:var(--fg-secondary);--chart-cursor:#fff3;--metric-received:var(--sys-blue);--metric-forwarded:var(--sys-teal);--metric-transmitted:var(--sys-orange);--metric-dropped:var(--sys-red);--metric-neutral:var(--zinc-400);--log-debug:var(--sys-brown);--log-info:var(--sys-cyan);--log-warning:var(--sys-amber);--log-error:var(--sys-red);--log-critical:var(--sys-pink);--icon-page-title:var(--sys-blue);--icon-card-title:var(--sys-blue);--icon-widget:var(--fg-secondary);--icon-action:var(--fg-secondary);--icon-nav:var(--fg-muted);--icon-nav-active:var(--sys-blue);--toggle-on:var(--sys-green);--toggle-off:var(--elevated);--data-box-bg:#ffffff08;--data-box-border:#ffffff0f;--map-node-fill:var(--sys-blue);--map-node-stroke:#ffffffe6;--map-hub-color:var(--sys-indigo);--map-hub-stroke:#ffffffe6;--map-gateway-color:var(--sys-indigo);--map-gateway-stroke:#ffffffd9;--map-local-color:var(--sys-amber);--map-neighbor-color:var(--sys-amber);--map-neighbor-stroke:#0006;--map-mobile-color:var(--sys-orange);--map-room-color:var(--sys-pink);--map-ghost-color:var(--sys-cyan);--map-popup-bg:var(--body)}@supports (color:color-mix(in lab,red,red)){:root{--map-popup-bg:color-mix(in srgb,var(--body)92%,transparent)}}:root{--map-popup-shadow:0 4px 16px #00000080;--map-overlay-blue-dark:#0d1e3226;--map-overlay-blue-light:#14284614;--map-border-accent:#8ca0c833;--map-border-accent-subtle:#8ca0c826;--map-hover-tint:#ffffff1a;--map-edge-rest:#ffffff40;--map-edge-rest-bright:#ffffff59;--map-edge-rest-dim:#ffffff26;--map-edge-hover-direct:var(--sys-cyan);--map-edge-hover-loop:var(--sys-indigo);--map-edge-hover-standard:var(--zinc-400);--map-edge-hover-neighbor:var(--sys-amber);--map-edge-highlight:gold;--link-strong:var(--sys-green);--link-medium:var(--sys-amber);--link-weak:var(--sys-red);--hop-0:var(--sys-cyan);--hop-1:var(--sys-green);--hop-2:var(--sys-teal);--hop-3:var(--sys-amber);--hop-distant:var(--zinc-500);--hop-hub:var(--sys-amber);--palette-bg-0:var(--zinc-950);--palette-bg-1:var(--zinc-900);--palette-bg-2:var(--zinc-800);--palette-bg-3:var(--zinc-700);--palette-bg-4:var(--zinc-600);--palette-bg-5:var(--zinc-500);--palette-bg-6:var(--zinc-400);--palette-bg-7:var(--zinc-300);--palette-fg-0:var(--zinc-500);--palette-fg-1:var(--zinc-400);--palette-fg-2:var(--zinc-300);--palette-fg-3:var(--zinc-200);--palette-fg-4:var(--zinc-50);--palette-red:var(--sys-red);--palette-red-bright:var(--sys-red);--palette-orange:var(--sys-orange);--palette-orange-bright:var(--sys-amber);--palette-yellow:var(--sys-yellow);--palette-yellow-bright:var(--sys-amber);--palette-green:var(--sys-green);--palette-green-bright:var(--sys-teal);--palette-aqua:var(--sys-cyan);--palette-aqua-bright:var(--sys-blue);--palette-blue:var(--sys-blue);--palette-blue-bright:var(--sys-indigo);--palette-purple:var(--sys-purple);--palette-purple-bright:var(--sys-pink);--ctrl-base:var(--palette-bg-4);--ctrl-base-hover:var(--palette-bg-5);--ctrl-base-active:var(--palette-bg-3);--ctrl-border:var(--palette-bg-5);--ctrl-border-hover:var(--palette-bg-6);--ctrl-shadow-dark:var(--palette-bg-1);--ctrl-shadow-mid:var(--palette-bg-0);--ctrl-highlight:var(--palette-bg-6);--ctrl-inset:var(--palette-bg-3);--ctrl-primary:#2563eb;--ctrl-primary-hover:#3b82f6;--ctrl-primary-border:#60a5fa;--ctrl-primary-shadow:#1d4ed8;--ctrl-primary-highlight:#93c5fd;--ctrl-primary-inset:#1e40af;--ctrl-success:#16a34a;--ctrl-success-hover:#22c55e;--ctrl-success-border:#4ade80;--ctrl-success-shadow:#15803d;--ctrl-success-highlight:#86efac;--ctrl-success-inset:#166534;--ctrl-warning:#d97706;--ctrl-warning-hover:#f59e0b;--ctrl-warning-border:#fbbf24;--ctrl-warning-shadow:#b45309;--ctrl-warning-highlight:#fde68a;--ctrl-warning-inset:#92400e;--ctrl-panel-top:var(--palette-bg-2);--ctrl-panel-mid:var(--palette-bg-1);--ctrl-panel-bottom:var(--palette-bg-0);--ctrl-panel-border:var(--palette-bg-4);--subtle-fill:#ffffff08;--subtle-fill-hover:#ffffff0f;--subtle-fill-strong:#ffffff14;--input-bg:#ffffff08;--input-border:#ffffff0f;--theme-transition:.4s ease;--text-xs:.64rem;--text-sm:.8rem;--text-base:1rem;--text-md:1.125rem;--text-lg:1.25rem;--text-xl:1.563rem;--text-2xl:1.953rem;--text-3xl:2.441rem;--text-4xl:3.052rem;--text-5xl:3.815rem;--text-6xl:4.768rem;--leading-tight:1.1;--leading-snug:1.25;--leading-normal:1.5;--leading-relaxed:1.625;--tracking-tight:-.025em;--tracking-normal:0;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--font-normal:400;--font-medium:500;--font-semibold:600;--font-bold:700;--font-extrabold:800}body{background:var(--body);color:var(--fg-secondary);font-family:var(--font-display),system-ui,-apple-system,sans-serif;font-weight:var(--font-normal);font-size:var(--text-base);line-height:var(--leading-normal);letter-spacing:var(--tracking-normal);font-feature-settings:"cv02","cv03","cv04";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;min-height:100vh}.bg-subtle-fill{background:var(--subtle-fill)}.bg-subtle-fill-hover{background:var(--subtle-fill-hover)}.bg-subtle-fill-strong{background:var(--subtle-fill-strong)}.hover\:bg-subtle-fill:hover{background:var(--subtle-fill)}.hover\:bg-subtle-fill-hover:hover{background:var(--subtle-fill-hover)}.hover\:bg-subtle-fill-strong:hover{background:var(--subtle-fill-strong)}.css-label--labels-container{pointer-events:none;z-index:10!important}.css-label--label{font-size:11px;font-family:var(--font-data),monospace;white-space:nowrap;border-radius:3px;padding:2px 6px;font-weight:500;box-shadow:0 1px 3px #0000004d;z-index:11!important;pointer-events:auto!important;text-shadow:none!important;color:#000!important;background:#fff!important}.meshgraph-label-cat-0{background:var(--meshgraph-label-0,#505050)!important;color:#fff!important}.meshgraph-label-cat-1{background:var(--meshgraph-label-1,#707070)!important;color:#fff!important}.meshgraph-label-cat-2{background:var(--meshgraph-label-2,#909090)!important;color:#000!important}.meshgraph-label-cat-3{background:var(--meshgraph-label-3,silver)!important;color:#000!important}.meshgraph-label-cat-4{background:var(--meshgraph-label-4,#fff)!important;color:#000!important}.meshgraph-label-cat-5{background:var(--meshgraph-label-5,#719cdf)!important;color:#fff!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}} +/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-divide-x-reverse:0}}}@layer theme{:root,:host{--color-amber-400:oklch(82.8% .189 84.429);--color-blue-500:oklch(62.3% .214 259.815);--color-violet-300:oklch(81.1% .111 293.571);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-5xl:3rem;--text-6xl:3.75rem;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-xs:4px;--radius-sm:6px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:20px;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--blur-lg:16px;--blur-xl:24px;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-display);--default-mono-font-family:var(--font-data);--color-body:var(--body);--color-surface:var(--surface);--color-elevated:var(--elevated);--color-subtle:var(--subtle);--color-edge-subtle:var(--edge-subtle);--color-edge-strong:var(--edge-strong);--color-fg-primary:var(--fg-primary);--color-fg-secondary:var(--fg-secondary);--color-fg-muted:var(--fg-muted);--color-fg-invert:var(--fg-invert);--font-title:var(--font-title);--duration-instant:75ms;--duration-fast:.15s;--duration-normal:.2s}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.inset-x-0{inset-inline:calc(var(--spacing)*0)}.inset-x-3{inset-inline:calc(var(--spacing)*3)}.inset-y-0{inset-block:calc(var(--spacing)*0)}.inset-y-2{inset-block:calc(var(--spacing)*2)}.-top-0\.5{top:calc(var(--spacing)*-.5)}.-top-1{top:calc(var(--spacing)*-1)}.-top-2{top:calc(var(--spacing)*-2)}.-top-\[3px\]{top:-3px}.top-0{top:calc(var(--spacing)*0)}.top-1{top:calc(var(--spacing)*1)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-3{top:calc(var(--spacing)*3)}.top-4{top:calc(var(--spacing)*4)}.top-12{top:calc(var(--spacing)*12)}.top-\[-4px\]{top:-4px}.top-\[40px\]{top:40px}.top-\[var\(--tip-y\,0\)\]{top:var(--tip-y,0)}.top-full{top:100%}.-right-0\.5{right:calc(var(--spacing)*-.5)}.-right-1{right:calc(var(--spacing)*-1)}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-2\.5{right:calc(var(--spacing)*2.5)}.right-3{right:calc(var(--spacing)*3)}.right-4{right:calc(var(--spacing)*4)}.right-\[-4px\]{right:-4px}.right-auto{right:auto}.right-full{right:100%}.-bottom-0\.5{bottom:calc(var(--spacing)*-.5)}.-bottom-1{bottom:calc(var(--spacing)*-1)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-1{bottom:calc(var(--spacing)*1)}.bottom-2{bottom:calc(var(--spacing)*2)}.bottom-3{bottom:calc(var(--spacing)*3)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-\[-4px\]{bottom:-4px}.bottom-\[-20px\]{bottom:-20px}.bottom-full{bottom:100%}.-left-3{left:calc(var(--spacing)*-3)}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-2\.5{left:calc(var(--spacing)*2.5)}.left-\[-4px\]{left:-4px}.left-\[19px\]{left:19px}.left-\[var\(--tip-x\,0\)\]{left:var(--tip-x,0)}.left-full{left:100%}.isolate{isolation:isolate}.-z-10{z-index:-10}.-z-20{z-index:-20}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[-1\]{z-index:-1}.z-\[1\]{z-index:1}.z-\[200\]{z-index:200}.z-\[600\]{z-index:600}.z-\[700\]{z-index:700}.z-\[9999\]{z-index:9999}.z-\[10001\]{z-index:10001}.z-\[10002\]{z-index:10002}.z-\[10003\]{z-index:10003}.z-\[10010\]{z-index:10010}.z-\[10020\]{z-index:10020}.col-auto{grid-column:auto}.col-span-2{grid-column:span 2/span 2}.col-span-full{grid-column:1/-1}.container{width:100%}@media(min-width:475px){.container{max-width:475px}}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.-m-1{margin:calc(var(--spacing)*-1)}.-m-1\.5{margin:calc(var(--spacing)*-1.5)}.m-2{margin:calc(var(--spacing)*2)}.-mx-0{margin-inline:calc(var(--spacing)*0)}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.-mx-3{margin-inline:calc(var(--spacing)*-3)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-0{margin-inline:calc(var(--spacing)*0)}.mx-0\.5{margin-inline:calc(var(--spacing)*.5)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-1\.5{margin-inline:calc(var(--spacing)*1.5)}.mx-3{margin-inline:calc(var(--spacing)*3)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-2{margin-block:calc(var(--spacing)*2)}.my-4{margin-block:calc(var(--spacing)*4)}.my-6{margin-block:calc(var(--spacing)*6)}.-mt-0\.5{margin-top:calc(var(--spacing)*-.5)}.-mt-1{margin-top:calc(var(--spacing)*-1)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.-mt-5{margin-top:calc(var(--spacing)*-5)}.-mt-6{margin-top:calc(var(--spacing)*-6)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-2\.5{margin-top:calc(var(--spacing)*2.5)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-5{margin-top:calc(var(--spacing)*5)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-auto{margin-top:auto}.-mr-0\.5{margin-right:calc(var(--spacing)*-.5)}.-mr-1{margin-right:calc(var(--spacing)*-1)}.mr-0\.5{margin-right:calc(var(--spacing)*.5)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-auto{margin-right:auto}.-mb-0\.5{margin-bottom:calc(var(--spacing)*-.5)}.-mb-4{margin-bottom:calc(var(--spacing)*-4)}.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.-ml-4{margin-left:calc(var(--spacing)*-4)}.ml-0\.5{margin-left:calc(var(--spacing)*.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-8{margin-left:calc(var(--spacing)*8)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-2\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-12{width:calc(var(--spacing)*12);height:calc(var(--spacing)*12)}.size-14{width:calc(var(--spacing)*14);height:calc(var(--spacing)*14)}.size-16{width:calc(var(--spacing)*16);height:calc(var(--spacing)*16)}.size-\[max\(100\%\,2\.75rem\)\]{width:max(100%,2.75rem);height:max(100%,2.75rem)}.size-full{width:100%;height:100%}.\!h-3{height:calc(var(--spacing)*3)!important}.\!h-5{height:calc(var(--spacing)*5)!important}.\!h-5\.5{height:calc(var(--spacing)*5.5)!important}.\!h-8{height:calc(var(--spacing)*8)!important}.\!h-\[calc\(100vh-11rem\)\]{height:calc(100vh - 11rem)!important}.\!h-auto{height:auto!important}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-4\.5{height:calc(var(--spacing)*4.5)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-12{height:calc(var(--spacing)*12)}.h-14{height:calc(var(--spacing)*14)}.h-16{height:calc(var(--spacing)*16)}.h-64{height:calc(var(--spacing)*64)}.h-\[1\.5px\]{height:1.5px}.h-\[1px\]{height:1px}.h-\[2px\]{height:2px}.h-\[14px\]{height:14px}.h-\[15px\]{height:15px}.h-\[18px\]{height:18px}.h-\[30px\]{height:30px}.h-\[32px\]{height:32px}.h-\[36px\]{height:36px}.h-\[38px\]{height:38px}.h-\[60px\]{height:60px}.h-\[70vh\]{height:70vh}.h-\[75vh\]{height:75vh}.h-\[80vh\]{height:80vh}.h-\[120px\]{height:120px}.h-\[200px\]{height:200px}.h-\[420px\]{height:420px}.h-\[calc\(100dvh-56px\)\]{height:calc(100dvh - 56px)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-0{max-height:calc(var(--spacing)*0)}.max-h-24{max-height:calc(var(--spacing)*24)}.max-h-32{max-height:calc(var(--spacing)*32)}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-60{max-height:calc(var(--spacing)*60)}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[45vh\]{max-height:45vh}.max-h-\[48px\]{max-height:48px}.max-h-\[60vh\]{max-height:60vh}.max-h-\[140px\]{max-height:140px}.max-h-\[200px\]{max-height:200px}.max-h-\[700px\]{max-height:700px}.max-h-\[calc\(100dvh-226px\)\]{max-height:calc(100dvh - 226px)}.max-h-\[calc\(100vh-80px\)\]{max-height:calc(100vh - 80px)}.max-h-\[calc\(100vh-200px\)\]{max-height:calc(100vh - 200px)}.\!min-h-\[400px\]{min-height:400px!important}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-9{min-height:calc(var(--spacing)*9)}.min-h-\[8px\]{min-height:8px}.min-h-\[28px\]{min-height:28px}.min-h-\[32px\]{min-height:32px}.min-h-\[38px\]{min-height:38px}.min-h-\[40px\]{min-height:40px}.min-h-\[44px\]{min-height:44px}.min-h-\[50vh\]{min-height:50vh}.min-h-\[120px\]{min-height:120px}.min-h-\[180px\]{min-height:180px}.min-h-\[300px\]{min-height:300px}.min-h-\[500px\]{min-height:500px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.min-h-svh{min-height:100svh}.\!w-3{width:calc(var(--spacing)*3)!important}.\!w-5{width:calc(var(--spacing)*5)!important}.\!w-5\.5{width:calc(var(--spacing)*5.5)!important}.w-0\.5{width:calc(var(--spacing)*.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-1\/2{width:50%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing)*4)}.w-4\.5{width:calc(var(--spacing)*4.5)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}.w-14{width:calc(var(--spacing)*14)}.w-16{width:calc(var(--spacing)*16)}.w-20{width:calc(var(--spacing)*20)}.w-24{width:calc(var(--spacing)*24)}.w-28{width:calc(var(--spacing)*28)}.w-32{width:calc(var(--spacing)*32)}.w-36{width:calc(var(--spacing)*36)}.w-40{width:calc(var(--spacing)*40)}.w-48{width:calc(var(--spacing)*48)}.w-64{width:calc(var(--spacing)*64)}.w-72{width:calc(var(--spacing)*72)}.w-80{width:calc(var(--spacing)*80)}.w-\[1\.75rem\]{width:1.75rem}.w-\[2\.4rem\]{width:2.4rem}.w-\[2\.25rem\]{width:2.25rem}.w-\[2px\]{width:2px}.w-\[3px\]{width:3px}.w-\[14px\]{width:14px}.w-\[28px\]{width:28px}.w-\[30px\]{width:30px}.w-\[32px\]{width:32px}.w-\[48px\]{width:48px}.w-\[52px\]{width:52px}.w-\[56px\]{width:56px}.w-\[60px\]{width:60px}.w-\[72px\]{width:72px}.w-\[240px\]{width:240px}.w-\[540px\]{width:540px}.w-\[var\(--button-width\)\]{width:var(--button-width)}.w-\[var\(--input-width\)\]{width:var(--input-width)}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[20rem\]{max-width:20rem}.max-w-\[50vw\]{max-width:50vw}.max-w-\[70px\]{max-width:70px}.max-w-\[70vw\]{max-width:70vw}.max-w-\[80px\]{max-width:80px}.max-w-\[85\%\]{max-width:85%}.max-w-\[85vw\]{max-width:85vw}.max-w-\[90px\]{max-width:90px}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[140px\]{max-width:140px}.max-w-\[220px\]{max-width:220px}.max-w-\[260px\]{max-width:260px}.max-w-\[960px\]{max-width:960px}.max-w-\[calc\(100vw-1\.5rem\)\]{max-width:calc(100vw - 1.5rem)}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-4{min-width:calc(var(--spacing)*4)}.min-w-8{min-width:calc(var(--spacing)*8)}.min-w-\[1\.5rem\]{min-width:1.5rem}.min-w-\[2\.25rem\]{min-width:2.25rem}.min-w-\[2rem\]{min-width:2rem}.min-w-\[10rem\]{min-width:10rem}.min-w-\[18px\]{min-width:18px}.min-w-\[44px\]{min-width:44px}.min-w-\[50px\]{min-width:50px}.min-w-\[60px\]{min-width:60px}.min-w-\[80px\]{min-width:80px}.min-w-\[100px\]{min-width:100px}.min-w-\[120px\]{min-width:120px}.min-w-\[130px\]{min-width:130px}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.flex-\[17\]{flex:17}.flex-\[33\]{flex:33}.\!flex-shrink{flex-shrink:1!important}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.basis-0{flex-basis:calc(var(--spacing)*0)}.border-collapse{border-collapse:collapse}.origin-bottom{transform-origin:bottom}.origin-top{transform-origin:top}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-1\/4{--tw-translate-x: -25% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing)*5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[4px\]{--tw-translate-x:4px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[18px\]{--tw-translate-x:18px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[22px\]{--tw-translate-x:22px;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[30px\]{--tw-translate-x:30px;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-0{--tw-translate-y:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[0\.1em\]{--tw-translate-y:.1em;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-px{--tw-translate-y:1px;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-110{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-x-150{--tw-scale-x:150%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-\[1\.02\]{scale:1.02}.-rotate-90{rotate:-90deg}.rotate-0{rotate:none}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-\[partytime-bg_5s_ease-out_forwards\]{animation:5s ease-out forwards partytime-bg}.animate-\[partytime-crt_5s_ease-out_forwards\]{animation:5s ease-out forwards partytime-crt}.animate-\[shimmer-pulse_2s_ease-in-out_infinite\]{animation:2s ease-in-out infinite shimmer-pulse}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-copy{cursor:copy}.cursor-default{cursor:default}.cursor-ew-resize{cursor:ew-resize}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-help{cursor:help}.cursor-not-allowed{cursor:not-allowed}.cursor-ns-resize{cursor:ns-resize}.cursor-nwse-resize{cursor:nwse-resize}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.cursor-wait{cursor:wait}.touch-manipulation{touch-action:manipulation}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.resize-x{resize:horizontal}.resize-y{resize:vertical}.scroll-py-1{scroll-padding-block:calc(var(--spacing)*1)}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-\[2px\]{gap:2px}.gap-px{gap:1px}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-10>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*10)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*10)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px*var(--tw-space-y-reverse));margin-block-end:calc(1px*calc(1 - var(--tw-space-y-reverse)))}.gap-x-1\.5{column-gap:calc(var(--spacing)*1.5)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-y-0\.5{row-gap:calc(var(--spacing)*.5)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-1\.5{row-gap:calc(var(--spacing)*1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-edge-subtle>:not(:last-child)),:where(.divide-edge-subtle\/30>:not(:last-child)){border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){:where(.divide-edge-subtle\/30>:not(:last-child)){border-color:color-mix(in oklab,var(--edge-subtle)30%,transparent)}}.self-center{align-self:center}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.justify-self-start{justify-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\!overflow-hidden{overflow:hidden!important}.\!overflow-visible{overflow:visible!important}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.scroll-smooth{scroll-behavior:smooth}.\!rounded{border-radius:.25rem!important}.\!rounded-md{border-radius:8px!important}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:20px}.rounded-\[1\.125rem\]{border-radius:1.125rem}.rounded-\[1px\]{border-radius:1px}.rounded-card{border-radius:16px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:12px}.rounded-md{border-radius:8px}.rounded-none{border-radius:0}.rounded-pill{border-radius:9999px}.rounded-sm{border-radius:6px}.rounded-xl{border-radius:16px}.rounded-xs{border-radius:4px}.rounded-t-lg{border-top-left-radius:12px;border-top-right-radius:12px}.rounded-l-lg{border-top-left-radius:12px;border-bottom-left-radius:12px}.rounded-tl-md{border-top-left-radius:8px}.rounded-r-lg{border-top-right-radius:12px;border-bottom-right-radius:12px}.rounded-tr-md{border-top-right-radius:8px}.rounded-b-lg{border-bottom-right-radius:12px;border-bottom-left-radius:12px}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-0{border-right-style:var(--tw-border-style);border-right-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-none{--tw-border-style:none;border-style:none}.border-\[var\(--route-direct\)\]\/30{border-color:var(--route-direct)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-direct\)\]\/30{border-color:color-mix(in oklab,var(--route-direct)30%,transparent)}}.border-\[var\(--route-flood\)\]\/30{border-color:var(--route-flood)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-flood\)\]\/30{border-color:color-mix(in oklab,var(--route-flood)30%,transparent)}}.border-\[var\(--route-transport\)\]\/30{border-color:var(--route-transport)}@supports (color:color-mix(in lab,red,red)){.border-\[var\(--route-transport\)\]\/30{border-color:color-mix(in oklab,var(--route-transport)30%,transparent)}}.border-current\/30{border-color:currentColor}@supports (color:color-mix(in lab,red,red)){.border-current\/30{border-color:color-mix(in oklab,currentcolor 30%,transparent)}}.border-edge-strong{border-color:var(--edge-strong)}.border-edge-subtle,.border-edge-subtle\/30{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/30{border-color:color-mix(in oklab,var(--edge-subtle)30%,transparent)}}.border-edge-subtle\/40{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/40{border-color:color-mix(in oklab,var(--edge-subtle)40%,transparent)}}.border-edge-subtle\/50{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/50{border-color:color-mix(in oklab,var(--edge-subtle)50%,transparent)}}.border-edge-subtle\/60{border-color:var(--edge-subtle)}@supports (color:color-mix(in lab,red,red)){.border-edge-subtle\/60{border-color:color-mix(in oklab,var(--edge-subtle)60%,transparent)}}.border-input-border{border-color:var(--input-border)}.border-signal-poor\/30{border-color:var(--signal-poor)}@supports (color:color-mix(in lab,red,red)){.border-signal-poor\/30{border-color:color-mix(in oklab,var(--signal-poor)30%,transparent)}}.border-sys-amber{border-color:var(--sys-amber)}.border-sys-blue,.border-sys-blue\/20{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/20{border-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.border-sys-blue\/25{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/25{border-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.border-sys-blue\/30{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/30{border-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.border-sys-blue\/40{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/40{border-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.border-sys-blue\/50{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.border-sys-blue\/50{border-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.border-sys-cyan\/20{border-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.border-sys-cyan\/20{border-color:color-mix(in oklab,var(--sys-cyan)20%,transparent)}}.border-sys-cyan\/30{border-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.border-sys-cyan\/30{border-color:color-mix(in oklab,var(--sys-cyan)30%,transparent)}}.border-sys-green,.border-sys-green\/20{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/20{border-color:color-mix(in oklab,var(--sys-green)20%,transparent)}}.border-sys-green\/30{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/30{border-color:color-mix(in oklab,var(--sys-green)30%,transparent)}}.border-sys-green\/40{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/40{border-color:color-mix(in oklab,var(--sys-green)40%,transparent)}}.border-sys-green\/50{border-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.border-sys-green\/50{border-color:color-mix(in oklab,var(--sys-green)50%,transparent)}}.border-sys-indigo,.border-sys-indigo\/20{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/20{border-color:color-mix(in oklab,var(--sys-indigo)20%,transparent)}}.border-sys-indigo\/25{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/25{border-color:color-mix(in oklab,var(--sys-indigo)25%,transparent)}}.border-sys-indigo\/30{border-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.border-sys-indigo\/30{border-color:color-mix(in oklab,var(--sys-indigo)30%,transparent)}}.border-sys-orange\/50{border-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.border-sys-orange\/50{border-color:color-mix(in oklab,var(--sys-orange)50%,transparent)}}.border-sys-pink{border-color:var(--sys-pink)}.border-sys-purple{border-color:var(--sys-purple)}.border-sys-red,.border-sys-red\/20{border-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.border-sys-red\/20{border-color:color-mix(in oklab,var(--sys-red)20%,transparent)}}.border-sys-red\/50{border-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.border-sys-red\/50{border-color:color-mix(in oklab,var(--sys-red)50%,transparent)}}.border-toggle-on{border-color:var(--toggle-on)}.border-transparent{border-color:#0000}.border-violet-300{border-color:var(--color-violet-300)}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.border-zinc-500{border-color:var(--color-zinc-500)}.border-zinc-500\/40{border-color:#71717b66}@supports (color:color-mix(in lab,red,red)){.border-zinc-500\/40{border-color:color-mix(in oklab,var(--color-zinc-500)40%,transparent)}}.border-t-transparent{border-top-color:#0000}.border-l-sys-amber{border-left-color:var(--sys-amber)}.border-l-sys-blue{border-left-color:var(--sys-blue)}.border-l-sys-green{border-left-color:var(--sys-green)}.border-l-sys-indigo{border-left-color:var(--sys-indigo)}.border-l-sys-purple{border-left-color:var(--sys-purple)}.border-l-sys-red{border-left-color:var(--sys-red)}.border-l-sys-teal{border-left-color:var(--sys-teal)}.\!bg-transparent{background-color:#0000!important}.bg-\[\#007AFF\]{background-color:#007aff}.bg-\[\#34D399\]{background-color:#34d399}.bg-\[\#60A5FA\]{background-color:#60a5fa}.bg-\[\#0074BE\]{background-color:#0074be}.bg-\[\#18181b\]{background-color:#18181b}.bg-\[\#EFF0F1\]{background-color:#eff0f1}.bg-\[\#FF5F57\]{background-color:#ff5f57}.bg-\[var\(--map-ui-border\,var\(--edge-subtle\)\)\]{background-color:var(--map-ui-border,var(--edge-subtle))}.bg-\[var\(--route-direct\)\]\/20{background-color:var(--route-direct)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-direct\)\]\/20{background-color:color-mix(in oklab,var(--route-direct)20%,transparent)}}.bg-\[var\(--route-flood\)\]\/20{background-color:var(--route-flood)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-flood\)\]\/20{background-color:color-mix(in oklab,var(--route-flood)20%,transparent)}}.bg-\[var\(--route-transport\)\]\/20{background-color:var(--route-transport)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--route-transport\)\]\/20{background-color:color-mix(in oklab,var(--route-transport)20%,transparent)}}.bg-\[var\(--signal-critical\)\]{background-color:var(--signal-critical)}.bg-\[var\(--signal-excellent\)\]{background-color:var(--signal-excellent)}.bg-\[var\(--signal-fair\)\]{background-color:var(--signal-fair)}.bg-\[var\(--signal-good\)\]{background-color:var(--signal-good)}.bg-\[var\(--signal-poor\)\]{background-color:var(--signal-poor)}.bg-\[var\(--signal-unknown\)\]{background-color:var(--signal-unknown)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-black{background-color:var(--color-black)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black)60%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-body,.bg-body\/50{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.bg-body\/50{background-color:color-mix(in oklab,var(--body)50%,transparent)}}.bg-chart-inner{background-color:var(--chart-inner)}.bg-edge-subtle{background-color:var(--edge-subtle)}.bg-elevated,.bg-elevated\/30{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/30{background-color:color-mix(in oklab,var(--elevated)30%,transparent)}}.bg-elevated\/50{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/50{background-color:color-mix(in oklab,var(--elevated)50%,transparent)}}.bg-elevated\/80{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/80{background-color:color-mix(in oklab,var(--elevated)80%,transparent)}}.bg-elevated\/90{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.bg-elevated\/90{background-color:color-mix(in oklab,var(--elevated)90%,transparent)}}.bg-fg-muted,.bg-fg-muted\/15{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/15{background-color:color-mix(in oklab,var(--fg-muted)15%,transparent)}}.bg-fg-muted\/20{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/20{background-color:color-mix(in oklab,var(--fg-muted)20%,transparent)}}.bg-fg-muted\/\[0\.03\]{background-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.bg-fg-muted\/\[0\.03\]{background-color:color-mix(in oklab,var(--fg-muted)3%,transparent)}}.bg-fg-primary\/30{background-color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.bg-fg-primary\/30{background-color:color-mix(in oklab,var(--fg-primary)30%,transparent)}}.bg-input-bg{background-color:var(--input-bg)}.bg-signal-excellent\/10{background-color:var(--signal-excellent)}@supports (color:color-mix(in lab,red,red)){.bg-signal-excellent\/10{background-color:color-mix(in oklab,var(--signal-excellent)10%,transparent)}}.bg-signal-fair\/10{background-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.bg-signal-fair\/10{background-color:color-mix(in oklab,var(--signal-fair)10%,transparent)}}.bg-signal-good\/10{background-color:var(--signal-good)}@supports (color:color-mix(in lab,red,red)){.bg-signal-good\/10{background-color:color-mix(in oklab,var(--signal-good)10%,transparent)}}.bg-signal-poor,.bg-signal-poor\/10{background-color:var(--signal-poor)}@supports (color:color-mix(in lab,red,red)){.bg-signal-poor\/10{background-color:color-mix(in oklab,var(--signal-poor)10%,transparent)}}.bg-status-danger,.bg-status-danger\/90{background-color:var(--status-danger)}@supports (color:color-mix(in lab,red,red)){.bg-status-danger\/90{background-color:color-mix(in oklab,var(--status-danger)90%,transparent)}}.bg-status-success{background-color:var(--status-success)}.bg-status-warning,.bg-status-warning\/15{background-color:var(--status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/15{background-color:color-mix(in oklab,var(--status-warning)15%,transparent)}}.bg-status-warning\/90{background-color:var(--status-warning)}@supports (color:color-mix(in lab,red,red)){.bg-status-warning\/90{background-color:color-mix(in oklab,var(--status-warning)90%,transparent)}}.bg-subtle{background-color:var(--subtle)}.bg-subtle-fill{background-color:var(--subtle-fill)}.bg-subtle-fill-hover{background-color:var(--subtle-fill-hover)}.bg-subtle-fill-strong{background-color:var(--subtle-fill-strong)}.bg-subtle-fill\/30{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/30{background-color:color-mix(in oklab,var(--subtle-fill)30%,transparent)}}.bg-subtle-fill\/50{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/50{background-color:color-mix(in oklab,var(--subtle-fill)50%,transparent)}}.bg-subtle-fill\/80{background-color:var(--subtle-fill)}@supports (color:color-mix(in lab,red,red)){.bg-subtle-fill\/80{background-color:color-mix(in oklab,var(--subtle-fill)80%,transparent)}}.bg-subtle\/30{background-color:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.bg-subtle\/30{background-color:color-mix(in oklab,var(--subtle)30%,transparent)}}.bg-subtle\/50{background-color:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.bg-subtle\/50{background-color:color-mix(in oklab,var(--subtle)50%,transparent)}}.bg-surface,.bg-surface\/30{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/30{background-color:color-mix(in oklab,var(--surface)30%,transparent)}}.bg-surface\/50{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/50{background-color:color-mix(in oklab,var(--surface)50%,transparent)}}.bg-surface\/75{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/75{background-color:color-mix(in oklab,var(--surface)75%,transparent)}}.bg-surface\/80{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/80{background-color:color-mix(in oklab,var(--surface)80%,transparent)}}.bg-surface\/85{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/85{background-color:color-mix(in oklab,var(--surface)85%,transparent)}}.bg-surface\/90{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/90{background-color:color-mix(in oklab,var(--surface)90%,transparent)}}.bg-surface\/95{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.bg-surface\/95{background-color:color-mix(in oklab,var(--surface)95%,transparent)}}.bg-sys-amber,.bg-sys-amber\/5{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/5{background-color:color-mix(in oklab,var(--sys-amber)5%,transparent)}}.bg-sys-amber\/8{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/8{background-color:color-mix(in oklab,var(--sys-amber)8%,transparent)}}.bg-sys-amber\/10{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/10{background-color:color-mix(in oklab,var(--sys-amber)10%,transparent)}}.bg-sys-amber\/15{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/15{background-color:color-mix(in oklab,var(--sys-amber)15%,transparent)}}.bg-sys-amber\/20{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/20{background-color:color-mix(in oklab,var(--sys-amber)20%,transparent)}}.bg-sys-amber\/25{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/25{background-color:color-mix(in oklab,var(--sys-amber)25%,transparent)}}.bg-sys-amber\/50{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.bg-sys-amber\/50{background-color:color-mix(in oklab,var(--sys-amber)50%,transparent)}}.bg-sys-blue,.bg-sys-blue\/5{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/5{background-color:color-mix(in oklab,var(--sys-blue)5%,transparent)}}.bg-sys-blue\/8{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/8{background-color:color-mix(in oklab,var(--sys-blue)8%,transparent)}}.bg-sys-blue\/10{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/10{background-color:color-mix(in oklab,var(--sys-blue)10%,transparent)}}.bg-sys-blue\/12{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/12{background-color:color-mix(in oklab,var(--sys-blue)12%,transparent)}}.bg-sys-blue\/15{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/15{background-color:color-mix(in oklab,var(--sys-blue)15%,transparent)}}.bg-sys-blue\/20{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/20{background-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.bg-sys-blue\/25{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/25{background-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.bg-sys-blue\/30{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/30{background-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.bg-sys-blue\/40{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/40{background-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.bg-sys-blue\/50{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.bg-sys-blue\/50{background-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.bg-sys-cyan,.bg-sys-cyan\/5{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/5{background-color:color-mix(in oklab,var(--sys-cyan)5%,transparent)}}.bg-sys-cyan\/8{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/8{background-color:color-mix(in oklab,var(--sys-cyan)8%,transparent)}}.bg-sys-cyan\/10{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/10{background-color:color-mix(in oklab,var(--sys-cyan)10%,transparent)}}.bg-sys-cyan\/15{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/15{background-color:color-mix(in oklab,var(--sys-cyan)15%,transparent)}}.bg-sys-cyan\/20{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/20{background-color:color-mix(in oklab,var(--sys-cyan)20%,transparent)}}.bg-sys-cyan\/50{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.bg-sys-cyan\/50{background-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.bg-sys-green,.bg-sys-green\/5{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/5{background-color:color-mix(in oklab,var(--sys-green)5%,transparent)}}.bg-sys-green\/8{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/8{background-color:color-mix(in oklab,var(--sys-green)8%,transparent)}}.bg-sys-green\/10{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/10{background-color:color-mix(in oklab,var(--sys-green)10%,transparent)}}.bg-sys-green\/15{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/15{background-color:color-mix(in oklab,var(--sys-green)15%,transparent)}}.bg-sys-green\/20{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/20{background-color:color-mix(in oklab,var(--sys-green)20%,transparent)}}.bg-sys-green\/25{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/25{background-color:color-mix(in oklab,var(--sys-green)25%,transparent)}}.bg-sys-green\/50{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.bg-sys-green\/50{background-color:color-mix(in oklab,var(--sys-green)50%,transparent)}}.bg-sys-indigo,.bg-sys-indigo\/5{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/5{background-color:color-mix(in oklab,var(--sys-indigo)5%,transparent)}}.bg-sys-indigo\/10{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/10{background-color:color-mix(in oklab,var(--sys-indigo)10%,transparent)}}.bg-sys-indigo\/15{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/15{background-color:color-mix(in oklab,var(--sys-indigo)15%,transparent)}}.bg-sys-indigo\/20{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/20{background-color:color-mix(in oklab,var(--sys-indigo)20%,transparent)}}.bg-sys-indigo\/30{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.bg-sys-indigo\/30{background-color:color-mix(in oklab,var(--sys-indigo)30%,transparent)}}.bg-sys-orange,.bg-sys-orange\/8{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/8{background-color:color-mix(in oklab,var(--sys-orange)8%,transparent)}}.bg-sys-orange\/15{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/15{background-color:color-mix(in oklab,var(--sys-orange)15%,transparent)}}.bg-sys-orange\/50{background-color:var(--sys-orange)}@supports (color:color-mix(in lab,red,red)){.bg-sys-orange\/50{background-color:color-mix(in oklab,var(--sys-orange)50%,transparent)}}.bg-sys-pink,.bg-sys-pink\/8{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/8{background-color:color-mix(in oklab,var(--sys-pink)8%,transparent)}}.bg-sys-pink\/15{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/15{background-color:color-mix(in oklab,var(--sys-pink)15%,transparent)}}.bg-sys-pink\/25{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/25{background-color:color-mix(in oklab,var(--sys-pink)25%,transparent)}}.bg-sys-pink\/50{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.bg-sys-pink\/50{background-color:color-mix(in oklab,var(--sys-pink)50%,transparent)}}.bg-sys-purple,.bg-sys-purple\/8{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/8{background-color:color-mix(in oklab,var(--sys-purple)8%,transparent)}}.bg-sys-purple\/15{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/15{background-color:color-mix(in oklab,var(--sys-purple)15%,transparent)}}.bg-sys-purple\/50{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.bg-sys-purple\/50{background-color:color-mix(in oklab,var(--sys-purple)50%,transparent)}}.bg-sys-red,.bg-sys-red\/8{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/8{background-color:color-mix(in oklab,var(--sys-red)8%,transparent)}}.bg-sys-red\/10{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/10{background-color:color-mix(in oklab,var(--sys-red)10%,transparent)}}.bg-sys-red\/15{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/15{background-color:color-mix(in oklab,var(--sys-red)15%,transparent)}}.bg-sys-red\/20{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/20{background-color:color-mix(in oklab,var(--sys-red)20%,transparent)}}.bg-sys-red\/25{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/25{background-color:color-mix(in oklab,var(--sys-red)25%,transparent)}}.bg-sys-red\/50{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.bg-sys-red\/50{background-color:color-mix(in oklab,var(--sys-red)50%,transparent)}}.bg-sys-teal,.bg-sys-teal\/8{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/8{background-color:color-mix(in oklab,var(--sys-teal)8%,transparent)}}.bg-sys-teal\/10{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/10{background-color:color-mix(in oklab,var(--sys-teal)10%,transparent)}}.bg-sys-teal\/15{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/15{background-color:color-mix(in oklab,var(--sys-teal)15%,transparent)}}.bg-sys-teal\/50{background-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.bg-sys-teal\/50{background-color:color-mix(in oklab,var(--sys-teal)50%,transparent)}}.bg-sys-yellow\/10{background-color:var(--sys-yellow)}@supports (color:color-mix(in lab,red,red)){.bg-sys-yellow\/10{background-color:color-mix(in oklab,var(--sys-yellow)10%,transparent)}}.bg-toggle-off{background-color:var(--toggle-off)}.bg-toggle-on{background-color:var(--toggle-on)}.bg-tooltip-bg,.bg-tooltip-bg\/80{background-color:var(--tooltip-bg)}@supports (color:color-mix(in lab,red,red)){.bg-tooltip-bg\/80{background-color:color-mix(in oklab,var(--tooltip-bg)80%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/\[0\.03\]{background-color:#ffffff08}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.03\]{background-color:color-mix(in oklab,var(--color-white)3%,transparent)}}.bg-white\/\[0\.04\]{background-color:#ffffff0a}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.04\]{background-color:color-mix(in oklab,var(--color-white)4%,transparent)}}.bg-white\/\[0\.06\]{background-color:#ffffff0f}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.06\]{background-color:color-mix(in oklab,var(--color-white)6%,transparent)}}.bg-zinc-400{background-color:var(--color-zinc-400)}.bg-zinc-500{background-color:var(--color-zinc-500)}.bg-zinc-500\/5{background-color:#71717b0d}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/5{background-color:color-mix(in oklab,var(--color-zinc-500)5%,transparent)}}.bg-zinc-500\/8{background-color:#71717b14}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/8{background-color:color-mix(in oklab,var(--color-zinc-500)8%,transparent)}}.bg-zinc-500\/10{background-color:#71717b1a}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/10{background-color:color-mix(in oklab,var(--color-zinc-500)10%,transparent)}}.bg-zinc-500\/15{background-color:#71717b26}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/15{background-color:color-mix(in oklab,var(--color-zinc-500)15%,transparent)}}.bg-zinc-500\/20{background-color:#71717b33}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/20{background-color:color-mix(in oklab,var(--color-zinc-500)20%,transparent)}}.bg-zinc-500\/40{background-color:#71717b66}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/40{background-color:color-mix(in oklab,var(--color-zinc-500)40%,transparent)}}.bg-zinc-500\/50{background-color:#71717b80}@supports (color:color-mix(in lab,red,red)){.bg-zinc-500\/50{background-color:color-mix(in oklab,var(--color-zinc-500)50%,transparent)}}.bg-zinc-600{background-color:var(--color-zinc-600)}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-900\/90{background-color:#18181be6}@supports (color:color-mix(in lab,red,red)){.bg-zinc-900\/90{background-color:color-mix(in oklab,var(--color-zinc-900)90%,transparent)}}.bg-cover{background-size:cover}.bg-center{background-position:50%}.bg-no-repeat{background-repeat:no-repeat}.fill-sys-green{fill:var(--sys-green)}.stroke-current{stroke:currentColor}.stroke-\[3\]{stroke-width:3px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.\!p-0{padding:calc(var(--spacing)*0)!important}.\!p-1\.5{padding:calc(var(--spacing)*1.5)!important}.\!p-2\.5{padding:calc(var(--spacing)*2.5)!important}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.p-12{padding:calc(var(--spacing)*12)}.\!px-0{padding-inline:calc(var(--spacing)*0)!important}.\!px-1{padding-inline:calc(var(--spacing)*1)!important}.\!px-1\.5{padding-inline:calc(var(--spacing)*1.5)!important}.px-0{padding-inline:calc(var(--spacing)*0)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.\!py-0{padding-block:calc(var(--spacing)*0)!important}.\!py-0\.5{padding-block:calc(var(--spacing)*.5)!important}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\.5{padding-block:calc(var(--spacing)*3.5)}.py-4{padding-block:calc(var(--spacing)*4)}.py-5{padding-block:calc(var(--spacing)*5)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.py-10{padding-block:calc(var(--spacing)*10)}.py-12{padding-block:calc(var(--spacing)*12)}.py-14{padding-block:calc(var(--spacing)*14)}.py-16{padding-block:calc(var(--spacing)*16)}.py-\[3px\]{padding-block:3px}.py-px{padding-block:1px}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-0\.5{padding-top:calc(var(--spacing)*.5)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-1\.5{padding-top:calc(var(--spacing)*1.5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-2\.5{padding-top:calc(var(--spacing)*2.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-5{padding-top:calc(var(--spacing)*5)}.pt-\[13px\]{padding-top:13px}.\!pr-0{padding-right:calc(var(--spacing)*0)!important}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pr-11{padding-right:calc(var(--spacing)*11)}.pr-\[env\(safe-area-inset-right\)\]{padding-right:env(safe-area-inset-right)}.pb-0{padding-bottom:calc(var(--spacing)*0)}.pb-0\.5{padding-bottom:calc(var(--spacing)*.5)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-2\.5{padding-left:calc(var(--spacing)*2.5)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-11{padding-left:calc(var(--spacing)*11)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-data)}.font-sans{font-family:var(--font-display)}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing)*6)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\!text-\[9px\]{font-size:9px!important}.\!text-\[10px\]{font-size:10px!important}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[17px\]{font-size:17px}.text-\[20px\]{font-size:20px}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking:var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.\!text-inherit{color:inherit!important}.\!text-sys-green{color:var(--sys-green)!important}.\!text-sys-red{color:var(--sys-red)!important}.text-\[\#4A0000\]{color:#4a0000}.text-\[\#e8a517\]{color:#e8a517}.text-\[var\(--pkt-ack\)\]{color:var(--pkt-ack)}.text-\[var\(--pkt-advert\)\]{color:var(--pkt-advert)}.text-\[var\(--pkt-anon\)\]{color:var(--pkt-anon)}.text-\[var\(--pkt-control\)\]{color:var(--pkt-control)}.text-\[var\(--pkt-flood\)\]{color:var(--pkt-flood)}.text-\[var\(--pkt-grp-data\)\]{color:var(--pkt-grp-data)}.text-\[var\(--pkt-grp-txt\)\]{color:var(--pkt-grp-txt)}.text-\[var\(--pkt-path\)\]{color:var(--pkt-path)}.text-\[var\(--pkt-req\)\]{color:var(--pkt-req)}.text-\[var\(--pkt-response\)\]{color:var(--pkt-response)}.text-\[var\(--pkt-trace\)\]{color:var(--pkt-trace)}.text-\[var\(--pkt-txt-msg\)\]{color:var(--pkt-txt-msg)}.text-\[var\(--pkt-unknown\)\]{color:var(--pkt-unknown)}.text-\[var\(--route-direct\)\]{color:var(--route-direct)}.text-\[var\(--route-flood\)\]{color:var(--route-flood)}.text-\[var\(--route-transport\)\]{color:var(--route-transport)}.text-blue-500{color:var(--color-blue-500)}.text-body{color:var(--body)}.text-fg-invert,.text-fg-invert\/70{color:var(--fg-invert)}@supports (color:color-mix(in lab,red,red)){.text-fg-invert\/70{color:color-mix(in oklab,var(--fg-invert)70%,transparent)}}.text-fg-muted,.text-fg-muted\/20{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/20{color:color-mix(in oklab,var(--fg-muted)20%,transparent)}}.text-fg-muted\/30{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/30{color:color-mix(in oklab,var(--fg-muted)30%,transparent)}}.text-fg-muted\/40{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/40{color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.text-fg-muted\/50{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/50{color:color-mix(in oklab,var(--fg-muted)50%,transparent)}}.text-fg-muted\/60{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/60{color:color-mix(in oklab,var(--fg-muted)60%,transparent)}}.text-fg-muted\/70{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/70{color:color-mix(in oklab,var(--fg-muted)70%,transparent)}}.text-fg-muted\/80{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.text-fg-muted\/80{color:color-mix(in oklab,var(--fg-muted)80%,transparent)}}.text-fg-primary,.text-fg-primary\/70{color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.text-fg-primary\/70{color:color-mix(in oklab,var(--fg-primary)70%,transparent)}}.text-fg-primary\/90{color:var(--fg-primary)}@supports (color:color-mix(in lab,red,red)){.text-fg-primary\/90{color:color-mix(in oklab,var(--fg-primary)90%,transparent)}}.text-fg-secondary,.text-fg-secondary\/60{color:var(--fg-secondary)}@supports (color:color-mix(in lab,red,red)){.text-fg-secondary\/60{color:color-mix(in oklab,var(--fg-secondary)60%,transparent)}}.text-icon-card-title{color:var(--icon-card-title)}.text-icon-page-title{color:var(--icon-page-title)}.text-icon-widget{color:var(--icon-widget)}.text-map-neighbor-color{color:var(--map-neighbor-color)}.text-signal-critical{color:var(--signal-critical)}.text-signal-excellent{color:var(--signal-excellent)}.text-signal-fair{color:var(--signal-fair)}.text-signal-good{color:var(--signal-good)}.text-signal-poor{color:var(--signal-poor)}.text-status-danger{color:var(--status-danger)}.text-status-success{color:var(--status-success)}.text-status-warning{color:var(--status-warning)}.text-sys-amber,.text-sys-amber\/60{color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.text-sys-amber\/60{color:color-mix(in oklab,var(--sys-amber)60%,transparent)}}.text-sys-amber\/70{color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.text-sys-amber\/70{color:color-mix(in oklab,var(--sys-amber)70%,transparent)}}.text-sys-blue{color:var(--sys-blue)}.text-sys-cyan{color:var(--sys-cyan)}.text-sys-green,.text-sys-green\/70{color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.text-sys-green\/70{color:color-mix(in oklab,var(--sys-green)70%,transparent)}}.text-sys-indigo,.text-sys-indigo\/70{color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.text-sys-indigo\/70{color:color-mix(in oklab,var(--sys-indigo)70%,transparent)}}.text-sys-orange{color:var(--sys-orange)}.text-sys-pink{color:var(--sys-pink)}.text-sys-purple{color:var(--sys-purple)}.text-sys-red,.text-sys-red\/70{color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.text-sys-red\/70{color:color-mix(in oklab,var(--sys-red)70%,transparent)}}.text-sys-teal{color:var(--sys-teal)}.text-sys-yellow{color:var(--sys-yellow)}.text-white{color:var(--color-white)}.text-white\/20{color:#fff3}@supports (color:color-mix(in lab,red,red)){.text-white\/20{color:color-mix(in oklab,var(--color-white)20%,transparent)}}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab,red,red)){.text-white\/40{color:color-mix(in oklab,var(--color-white)40%,transparent)}}.text-zinc-100{color:var(--color-zinc-100)}.text-zinc-300{color:var(--color-zinc-300)}.text-zinc-400{color:var(--color-zinc-400)}.text-zinc-900{color:var(--color-zinc-900)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.accent-sys-blue{accent-color:var(--sys-blue)}.accent-sys-indigo{accent-color:var(--sys-indigo)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.opacity-100{opacity:1}.\!shadow-none{--tw-shadow:0 0 #0000!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow\!{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_4px_var\(--sys-blue\)\]{--tw-shadow:0 0 4px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_0_8px_var\(--sys-blue\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[inset_0_0_0_1\.5px_var\(--sys-blue\)\]{--tw-shadow:inset 0 0 0 1.5px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[var\(--neo-outer\)\]{--tw-shadow:var(--neo-outer);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[var\(--neo-outer-sm\)\]{--tw-shadow:var(--neo-outer-sm);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\!ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor)!important;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)!important}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[1\.5px\]{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1.5px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[\#E0443E\]{--tw-ring-color:#e0443e}.ring-body{--tw-ring-color:var(--body)}.ring-edge-strong,.ring-edge-strong\/50{--tw-ring-color:var(--edge-strong)}@supports (color:color-mix(in lab,red,red)){.ring-edge-strong\/50{--tw-ring-color:color-mix(in oklab,var(--edge-strong)50%,transparent)}}.ring-edge-subtle{--tw-ring-color:var(--edge-subtle)}.ring-surface{--tw-ring-color:var(--surface)}.ring-sys-amber\/30{--tw-ring-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.ring-sys-amber\/30{--tw-ring-color:color-mix(in oklab,var(--sys-amber)30%,transparent)}}.ring-sys-amber\/50{--tw-ring-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.ring-sys-amber\/50{--tw-ring-color:color-mix(in oklab,var(--sys-amber)50%,transparent)}}.ring-sys-blue,.ring-sys-blue\/20{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/20{--tw-ring-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.ring-sys-blue\/30{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/30{--tw-ring-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.ring-sys-blue\/40{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/40{--tw-ring-color:color-mix(in oklab,var(--sys-blue)40%,transparent)}}.ring-sys-blue\/50{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.ring-sys-blue\/50{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.ring-sys-cyan\/50{--tw-ring-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.ring-sys-cyan\/50{--tw-ring-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.ring-sys-green{--tw-ring-color:var(--sys-green)}.ring-sys-red,.ring-sys-red\/25{--tw-ring-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.ring-sys-red\/25{--tw-ring-color:color-mix(in oklab,var(--sys-red)25%,transparent)}}.ring-sys-teal\/25{--tw-ring-color:var(--sys-teal)}@supports (color:color-mix(in lab,red,red)){.ring-sys-teal\/25{--tw-ring-color:color-mix(in oklab,var(--sys-teal)25%,transparent)}}.ring-zinc-600{--tw-ring-color:var(--color-zinc-600)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.drop-shadow{--tw-drop-shadow-size:drop-shadow(0 1px 2px var(--tw-drop-shadow-color,#0000001a))drop-shadow(0 1px 1px var(--tw-drop-shadow-color,#0000000f));--tw-drop-shadow:drop-shadow(0 1px 2px #0000001a)drop-shadow(0 1px 1px #0000000f);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.sepia{--tw-sepia:sepia(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-lg{--tw-backdrop-blur:blur(var(--blur-lg));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[opacity\,transform\]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,box-shadow\,background-color\]{transition-property:transform,box-shadow,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-75{--tw-duration:75ms;transition-duration:75ms}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.ease-in-out{--tw-ease:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{--tw-ease:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.select-text{-webkit-user-select:text;user-select:text}.ring-inset{--tw-ring-inset:inset}:is(.\*\:w-full>*){width:100%}@media(hover:hover){.group-hover\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\:border-edge-strong:is(:where(.group):hover *){border-color:var(--edge-strong)}.group-hover\:bg-elevated:is(:where(.group):hover *){background-color:var(--elevated)}.group-hover\:bg-subtle-fill:is(:where(.group):hover *){background-color:var(--subtle-fill)}.group-hover\:text-fg-secondary:is(:where(.group):hover *){color:var(--fg-secondary)}.group-hover\:text-sys-indigo:is(:where(.group):hover *){color:var(--sys-indigo)}.group-hover\:text-white:is(:where(.group):hover *){color:var(--color-white)}.group-hover\:opacity-70:is(:where(.group):hover *){opacity:.7}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/band\:bg-sys-blue\/35:is(:where(.group\/band):hover *){background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.group-hover\/band\:bg-sys-blue\/35:is(:where(.group\/band):hover *){background-color:color-mix(in oklab,var(--sys-blue)35%,transparent)}}.group-hover\/tip\:visible:is(:where(.group\/tip):hover *){visibility:visible}.group-hover\/tip\:opacity-100:is(:where(.group\/tip):hover *){opacity:1}}.group-data-\[open\]\:rotate-180:is(:where(.group)[data-open] *){rotate:180deg}.placeholder\:text-fg-muted::placeholder,.placeholder\:text-fg-muted\/40::placeholder{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-fg-muted\/40::placeholder{color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.placeholder\:text-fg-muted\/50::placeholder{color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.placeholder\:text-fg-muted\/50::placeholder{color:color-mix(in oklab,var(--fg-muted)50%,transparent)}}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:-inset-px:before{content:var(--tw-content);top:-1px;right:-1px;bottom:-1px;left:-1px}.before\:-inset-x-3:before{content:var(--tw-content);inset-inline:calc(var(--spacing)*-3)}.before\:-inset-y-1:before{content:var(--tw-content);inset-block:calc(var(--spacing)*-1)}.before\:rounded-lg:before{content:var(--tw-content);border-radius:12px}.before\:bg-subtle-fill:before{content:var(--tw-content);background-color:var(--subtle-fill)}.before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.odd\:bg-surface\/30:nth-child(odd){background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.odd\:bg-surface\/30:nth-child(odd){background-color:color-mix(in oklab,var(--surface)30%,transparent)}}.focus-within\:border-sys-blue:focus-within{border-color:var(--sys-blue)}@media(hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-x-150:hover{--tw-scale-x:150%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:scale-\[1\.6\]:hover{scale:1.6}.hover\:border-edge-strong:hover{border-color:var(--edge-strong)}.hover\:border-fg-muted\/40:hover{border-color:var(--fg-muted)}@supports (color:color-mix(in lab,red,red)){.hover\:border-fg-muted\/40:hover{border-color:color-mix(in oklab,var(--fg-muted)40%,transparent)}}.hover\:border-sys-amber:hover{border-color:var(--sys-amber)}.hover\:border-sys-blue:hover,.hover\:border-sys-blue\/30:hover{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:border-sys-blue\/30:hover{border-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:border-sys-green:hover{border-color:var(--sys-green)}.hover\:border-sys-indigo:hover{border-color:var(--sys-indigo)}.hover\:border-sys-pink:hover{border-color:var(--sys-pink)}.hover\:border-sys-purple:hover{border-color:var(--sys-purple)}.hover\:border-sys-red:hover{border-color:var(--sys-red)}.hover\:border-zinc-400:hover{border-color:var(--color-zinc-400)}.hover\:border-zinc-500:hover{border-color:var(--color-zinc-500)}.hover\:\!bg-transparent:hover{background-color:#0000!important}.hover\:bg-\[\#FF6961\]:hover{background-color:#ff6961}.hover\:bg-\[var\(--map-ui-hover\,var\(--elevated\)\)\]:hover{background-color:var(--map-ui-hover,var(--elevated))}.hover\:bg-black\/10:hover{background-color:#0000001a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-black\/10:hover{background-color:color-mix(in oklab,var(--color-black)10%,transparent)}}.hover\:bg-elevated:hover,.hover\:bg-elevated\/30:hover{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-elevated\/30:hover{background-color:color-mix(in oklab,var(--elevated)30%,transparent)}}.hover\:bg-elevated\/80:hover{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-elevated\/80:hover{background-color:color-mix(in oklab,var(--elevated)80%,transparent)}}.hover\:bg-fg-muted:hover{background-color:var(--fg-muted)}.hover\:bg-signal-fair\/10:hover{background-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-signal-fair\/10:hover{background-color:color-mix(in oklab,var(--signal-fair)10%,transparent)}}.hover\:bg-subtle:hover{background-color:var(--subtle)}.hover\:bg-subtle-fill:hover{background-color:var(--subtle-fill)}.hover\:bg-subtle-fill-hover:hover{background-color:var(--subtle-fill-hover)}.hover\:bg-subtle-fill-strong:hover{background-color:var(--subtle-fill-strong)}.hover\:bg-surface:hover,.hover\:bg-surface\/60:hover{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-surface\/60:hover{background-color:color-mix(in oklab,var(--surface)60%,transparent)}}.hover\:bg-sys-amber:hover,.hover\:bg-sys-amber\/10:hover{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-amber\/10:hover{background-color:color-mix(in oklab,var(--sys-amber)10%,transparent)}}.hover\:bg-sys-amber\/80:hover{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-amber\/80:hover{background-color:color-mix(in oklab,var(--sys-amber)80%,transparent)}}.hover\:bg-sys-blue:hover,.hover\:bg-sys-blue\/5:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/5:hover{background-color:color-mix(in oklab,var(--sys-blue)5%,transparent)}}.hover\:bg-sys-blue\/10:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/10:hover{background-color:color-mix(in oklab,var(--sys-blue)10%,transparent)}}.hover\:bg-sys-blue\/20:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/20:hover{background-color:color-mix(in oklab,var(--sys-blue)20%,transparent)}}.hover\:bg-sys-blue\/25:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/25:hover{background-color:color-mix(in oklab,var(--sys-blue)25%,transparent)}}.hover\:bg-sys-blue\/30:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/30:hover{background-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:bg-sys-blue\/80:hover{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-blue\/80:hover{background-color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.hover\:bg-sys-cyan\/10:hover{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-cyan\/10:hover{background-color:color-mix(in oklab,var(--sys-cyan)10%,transparent)}}.hover\:bg-sys-cyan\/25:hover{background-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-cyan\/25:hover{background-color:color-mix(in oklab,var(--sys-cyan)25%,transparent)}}.hover\:bg-sys-green:hover,.hover\:bg-sys-green\/10:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/10:hover{background-color:color-mix(in oklab,var(--sys-green)10%,transparent)}}.hover\:bg-sys-green\/15:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/15:hover{background-color:color-mix(in oklab,var(--sys-green)15%,transparent)}}.hover\:bg-sys-green\/80:hover{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-green\/80:hover{background-color:color-mix(in oklab,var(--sys-green)80%,transparent)}}.hover\:bg-sys-indigo:hover,.hover\:bg-sys-indigo\/5:hover{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-indigo\/5:hover{background-color:color-mix(in oklab,var(--sys-indigo)5%,transparent)}}.hover\:bg-sys-indigo\/25:hover{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-indigo\/25:hover{background-color:color-mix(in oklab,var(--sys-indigo)25%,transparent)}}.hover\:bg-sys-pink:hover{background-color:var(--sys-pink)}.hover\:bg-sys-purple:hover{background-color:var(--sys-purple)}.hover\:bg-sys-red:hover,.hover\:bg-sys-red\/8:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/8:hover{background-color:color-mix(in oklab,var(--sys-red)8%,transparent)}}.hover\:bg-sys-red\/10:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/10:hover{background-color:color-mix(in oklab,var(--sys-red)10%,transparent)}}.hover\:bg-sys-red\/15:hover{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-sys-red\/15:hover{background-color:color-mix(in oklab,var(--sys-red)15%,transparent)}}.hover\:bg-tooltip-bg:hover{background-color:var(--tooltip-bg)}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\:bg-zinc-500:hover{background-color:var(--color-zinc-500)}.hover\:bg-zinc-500\/5:hover{background-color:#71717b0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/5:hover{background-color:color-mix(in oklab,var(--color-zinc-500)5%,transparent)}}.hover\:bg-zinc-500\/10:hover{background-color:#71717b1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/10:hover{background-color:color-mix(in oklab,var(--color-zinc-500)10%,transparent)}}.hover\:bg-zinc-500\/15:hover{background-color:#71717b26}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/15:hover{background-color:color-mix(in oklab,var(--color-zinc-500)15%,transparent)}}.hover\:bg-zinc-500\/20:hover{background-color:#71717b33}@supports (color:color-mix(in lab,red,red)){.hover\:bg-zinc-500\/20:hover{background-color:color-mix(in oklab,var(--color-zinc-500)20%,transparent)}}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-body:hover{color:var(--body)}.hover\:text-fg-invert:hover{color:var(--fg-invert)}.hover\:text-fg-muted:hover{color:var(--fg-muted)}.hover\:text-fg-primary:hover{color:var(--fg-primary)}.hover\:text-fg-secondary:hover{color:var(--fg-secondary)}.hover\:text-sys-blue:hover,.hover\:text-sys-blue\/80:hover{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:text-sys-blue\/80:hover{color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.hover\:text-sys-cyan:hover{color:var(--sys-cyan)}.hover\:text-sys-indigo:hover{color:var(--sys-indigo)}.hover\:text-sys-purple:hover{color:var(--sys-purple)}.hover\:text-sys-red:hover{color:var(--sys-red)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-zinc-300:hover{color:var(--color-zinc-300)}.hover\:text-zinc-400:hover{color:var(--color-zinc-400)}.hover\:text-zinc-900:hover{color:var(--color-zinc-900)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_8px_var\(--sys-blue\)\]:hover{--tw-shadow:0 0 8px var(--tw-shadow-color,var(--sys-blue));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-none:hover{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-2:hover{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-sys-blue:hover,.hover\:ring-sys-blue\/30:hover{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.hover\:ring-sys-blue\/30:hover{--tw-ring-color:color-mix(in oklab,var(--sys-blue)30%,transparent)}}.hover\:ring-sys-indigo:hover{--tw-ring-color:var(--sys-indigo)}}.focus\:border-sys-blue:focus,.focus\:border-sys-blue\/50:focus{border-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus\:border-sys-blue\/50:focus{border-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus\:border-zinc-500:focus{border-color:var(--color-zinc-500)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-edge-strong:focus{--tw-ring-color:var(--edge-strong)}.focus\:ring-signal-fair\/50:focus{--tw-ring-color:var(--signal-fair)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-signal-fair\/50:focus{--tw-ring-color:color-mix(in oklab,var(--signal-fair)50%,transparent)}}.focus\:ring-sys-blue:focus,.focus\:ring-sys-blue\/50:focus{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-sys-blue\/50:focus{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus\:ring-sys-cyan\/50:focus{--tw-ring-color:var(--sys-cyan)}@supports (color:color-mix(in lab,red,red)){.focus\:ring-sys-cyan\/50:focus{--tw-ring-color:color-mix(in oklab,var(--sys-cyan)50%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[\#FF5F57\]:focus-visible{--tw-ring-color:#ff5f57}.focus-visible\:ring-sys-blue\/50:focus-visible{--tw-ring-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-sys-blue\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--sys-blue)50%,transparent)}}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-90:active{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.active\:cursor-grabbing:active{cursor:grabbing}.active\:bg-\[\#E04840\]:active{background-color:#e04840}.active\:bg-\[var\(--map-ui-active\,var\(--subtle\)\)\]:active{background-color:var(--map-ui-active,var(--subtle))}.active\:bg-elevated:active{background-color:var(--elevated)}.active\:bg-subtle-fill:active{background-color:var(--subtle-fill)}.active\:bg-subtle-fill-hover:active{background-color:var(--subtle-fill-hover)}.active\:bg-subtle-fill-strong:active{background-color:var(--subtle-fill-strong)}.active\:bg-sys-amber\/70:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/70:active{background-color:color-mix(in oklab,var(--sys-amber)70%,transparent)}}.active\:bg-sys-amber\/80:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/80:active{background-color:color-mix(in oklab,var(--sys-amber)80%,transparent)}}.active\:bg-sys-amber\/90:active{background-color:var(--sys-amber)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-amber\/90:active{background-color:color-mix(in oklab,var(--sys-amber)90%,transparent)}}.active\:bg-sys-blue\/70:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/70:active{background-color:color-mix(in oklab,var(--sys-blue)70%,transparent)}}.active\:bg-sys-blue\/80:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/80:active{background-color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.active\:bg-sys-blue\/90:active{background-color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-blue\/90:active{background-color:color-mix(in oklab,var(--sys-blue)90%,transparent)}}.active\:bg-sys-green\/70:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/70:active{background-color:color-mix(in oklab,var(--sys-green)70%,transparent)}}.active\:bg-sys-green\/80:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/80:active{background-color:color-mix(in oklab,var(--sys-green)80%,transparent)}}.active\:bg-sys-green\/90:active{background-color:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-green\/90:active{background-color:color-mix(in oklab,var(--sys-green)90%,transparent)}}.active\:bg-sys-indigo\/80:active{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-indigo\/80:active{background-color:color-mix(in oklab,var(--sys-indigo)80%,transparent)}}.active\:bg-sys-indigo\/90:active{background-color:var(--sys-indigo)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-indigo\/90:active{background-color:color-mix(in oklab,var(--sys-indigo)90%,transparent)}}.active\:bg-sys-pink\/80:active{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-pink\/80:active{background-color:color-mix(in oklab,var(--sys-pink)80%,transparent)}}.active\:bg-sys-pink\/90:active{background-color:var(--sys-pink)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-pink\/90:active{background-color:color-mix(in oklab,var(--sys-pink)90%,transparent)}}.active\:bg-sys-purple\/80:active{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-purple\/80:active{background-color:color-mix(in oklab,var(--sys-purple)80%,transparent)}}.active\:bg-sys-purple\/90:active{background-color:var(--sys-purple)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-purple\/90:active{background-color:color-mix(in oklab,var(--sys-purple)90%,transparent)}}.active\:bg-sys-red\/80:active{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-red\/80:active{background-color:color-mix(in oklab,var(--sys-red)80%,transparent)}}.active\:bg-sys-red\/90:active{background-color:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.active\:bg-sys-red\/90:active{background-color:color-mix(in oklab,var(--sys-red)90%,transparent)}}.active\:bg-tooltip-bg:active{background-color:var(--tooltip-bg)}.active\:bg-zinc-500\/80:active{background-color:#71717bcc}@supports (color:color-mix(in lab,red,red)){.active\:bg-zinc-500\/80:active{background-color:color-mix(in oklab,var(--color-zinc-500)80%,transparent)}}.active\:bg-zinc-500\/90:active{background-color:#71717be6}@supports (color:color-mix(in lab,red,red)){.active\:bg-zinc-500\/90:active{background-color:color-mix(in oklab,var(--color-zinc-500)90%,transparent)}}.active\:bg-zinc-700:active{background-color:var(--color-zinc-700)}.active\:text-sys-blue\/70:active{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:text-sys-blue\/70:active{color:color-mix(in oklab,var(--sys-blue)70%,transparent)}}.active\:text-sys-blue\/80:active{color:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.active\:text-sys-blue\/80:active{color:color-mix(in oklab,var(--sys-blue)80%,transparent)}}.active\:text-white:active{color:var(--color-white)}.active\:text-zinc-900:active{color:var(--color-zinc-900)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-25:disabled{opacity:.25}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media(hover:hover){.disabled\:hover\:bg-transparent:disabled:hover{background-color:#0000}}.data-\[closed\]\:-translate-y-1[data-closed]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[closed\]\:scale-\[0\.98\][data-closed]{scale:.98}.data-\[closed\]\:opacity-0[data-closed]{opacity:0}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[enter\]\:duration-150[data-enter]{--tw-duration:.15s;transition-duration:.15s}.data-\[enter\]\:ease-out[data-enter]{--tw-ease:cubic-bezier(0,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.data-\[focus\]\:bg-sys-blue[data-focus]{background-color:var(--sys-blue)}.data-\[focus\]\:bg-sys-red[data-focus]{background-color:var(--sys-red)}.data-\[focus\]\:text-white[data-focus]{color:var(--color-white)}.data-\[leave\]\:duration-100[data-leave]{--tw-duration:.1s;transition-duration:.1s}.data-\[leave\]\:ease-in[data-leave]{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}@media(min-width:520px){.min-\[520px\]\:inline{display:inline}}@media(min-width:600px){.min-\[600px\]\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.min-\[600px\]\:gap-3{gap:calc(var(--spacing)*3)}.min-\[600px\]\:px-3{padding-inline:calc(var(--spacing)*3)}.min-\[600px\]\:py-2\.5{padding-block:calc(var(--spacing)*2.5)}}@media(min-width:900px){.min-\[900px\]\:block{display:block}.min-\[900px\]\:gap-2{gap:calc(var(--spacing)*2)}}@media(min-width:40rem){.sm\:top-4{top:calc(var(--spacing)*4)}.sm\:right-3{right:calc(var(--spacing)*3)}.sm\:right-4{right:calc(var(--spacing)*4)}.sm\:bottom-16{bottom:calc(var(--spacing)*16)}.sm\:left-auto{left:auto}.sm\:order-first{order:-9999}.sm\:order-last{order:9999}.sm\:col-span-1{grid-column:span 1/span 1}.sm\:-mx-6{margin-inline:calc(var(--spacing)*-6)}.sm\:mx-0{margin-inline:calc(var(--spacing)*0)}.sm\:mt-1{margin-top:calc(var(--spacing)*1)}.sm\:mt-2{margin-top:calc(var(--spacing)*2)}.sm\:mt-4{margin-top:calc(var(--spacing)*4)}.sm\:mr-0{margin-right:calc(var(--spacing)*0)}.sm\:-mb-6{margin-bottom:calc(var(--spacing)*-6)}.sm\:mb-1{margin-bottom:calc(var(--spacing)*1)}.sm\:mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.sm\:mb-2{margin-bottom:calc(var(--spacing)*2)}.sm\:mb-3{margin-bottom:calc(var(--spacing)*3)}.sm\:-ml-5{margin-left:calc(var(--spacing)*-5)}.sm\:-ml-px{margin-left:-1px}.sm\:ml-9{margin-left:calc(var(--spacing)*9)}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:inline-flex{display:inline-flex}.sm\:h-3{height:calc(var(--spacing)*3)}.sm\:h-3\.5{height:calc(var(--spacing)*3.5)}.sm\:h-4{height:calc(var(--spacing)*4)}.sm\:h-6{height:calc(var(--spacing)*6)}.sm\:h-\[85vh\]{height:85vh}.sm\:h-\[500px\]{height:500px}.sm\:h-\[520px\]{height:520px}.sm\:max-h-96{max-height:calc(var(--spacing)*96)}.sm\:max-h-\[420px\]{max-height:420px}.sm\:max-h-\[600px\]{max-height:600px}.sm\:max-h-\[800px\]{max-height:800px}.sm\:max-h-\[calc\(100dvh-234px\)\]{max-height:calc(100dvh - 234px)}.sm\:max-h-\[calc\(100vh-180px\)\]{max-height:calc(100vh - 180px)}.sm\:min-h-0{min-height:calc(var(--spacing)*0)}.sm\:min-h-\[60px\]{min-height:60px}.sm\:w-3{width:calc(var(--spacing)*3)}.sm\:w-3\.5{width:calc(var(--spacing)*3.5)}.sm\:w-4{width:calc(var(--spacing)*4)}.sm\:w-5{width:calc(var(--spacing)*5)}.sm\:w-6{width:calc(var(--spacing)*6)}.sm\:w-9{width:calc(var(--spacing)*9)}.sm\:w-12{width:calc(var(--spacing)*12)}.sm\:w-14{width:calc(var(--spacing)*14)}.sm\:w-16{width:calc(var(--spacing)*16)}.sm\:w-32{width:calc(var(--spacing)*32)}.sm\:w-40{width:calc(var(--spacing)*40)}.sm\:w-48{width:calc(var(--spacing)*48)}.sm\:w-64{width:calc(var(--spacing)*64)}.sm\:w-\[280px\]{width:280px}.sm\:w-auto{width:auto}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-3xl{max-width:var(--container-3xl)}.sm\:max-w-4xl{max-width:var(--container-4xl)}.sm\:max-w-5xl{max-width:var(--container-5xl)}.sm\:max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-none{max-width:none}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:min-w-0{min-width:calc(var(--spacing)*0)}.sm\:min-w-\[32px\]{min-width:32px}.sm\:min-w-\[180px\]{min-width:180px}.sm\:min-w-\[220px\]{min-width:220px}.sm\:min-w-\[540px\]{min-width:540px}.sm\:min-w-\[700px\]{min-width:700px}.sm\:flex-1{flex:1}.sm\:flex-initial{flex:0 auto}.sm\:flex-shrink-0{flex-shrink:0}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-\[280px_minmax\(400px\,1fr\)\]{grid-template-columns:280px minmax(400px,1fr)}.sm\:grid-cols-\[auto_minmax\(0\,1fr\)_auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr)}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-0\.5{gap:calc(var(--spacing)*.5)}.sm\:gap-1{gap:calc(var(--spacing)*1)}.sm\:gap-1\.5{gap:calc(var(--spacing)*1.5)}.sm\:gap-2{gap:calc(var(--spacing)*2)}.sm\:gap-3{gap:calc(var(--spacing)*3)}.sm\:gap-4{gap:calc(var(--spacing)*4)}.sm\:gap-5{gap:calc(var(--spacing)*5)}.sm\:gap-6{gap:calc(var(--spacing)*6)}.sm\:gap-8{gap:calc(var(--spacing)*8)}:where(.sm\:space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}.sm\:gap-x-3{column-gap:calc(var(--spacing)*3)}.sm\:gap-x-4{column-gap:calc(var(--spacing)*4)}.sm\:gap-y-0\.5{row-gap:calc(var(--spacing)*.5)}.sm\:gap-y-2{row-gap:calc(var(--spacing)*2)}:where(.sm\:divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px*var(--tw-divide-x-reverse));border-inline-end-width:calc(1px*calc(1 - var(--tw-divide-x-reverse)))}:where(.sm\:divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px*var(--tw-divide-y-reverse));border-bottom-width:calc(0px*calc(1 - var(--tw-divide-y-reverse)))}.sm\:overflow-visible{overflow:visible}.sm\:\!p-0\.5{padding:calc(var(--spacing)*.5)!important}.sm\:\!p-1\.5{padding:calc(var(--spacing)*1.5)!important}.sm\:p-0\.5{padding:calc(var(--spacing)*.5)}.sm\:p-1\.5{padding:calc(var(--spacing)*1.5)}.sm\:p-4{padding:calc(var(--spacing)*4)}.sm\:p-5{padding:calc(var(--spacing)*5)}.sm\:px-2{padding-inline:calc(var(--spacing)*2)}.sm\:px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.sm\:px-4{padding-inline:calc(var(--spacing)*4)}.sm\:px-5{padding-inline:calc(var(--spacing)*5)}.sm\:px-6{padding-inline:calc(var(--spacing)*6)}.sm\:py-1{padding-block:calc(var(--spacing)*1)}.sm\:py-1\.5{padding-block:calc(var(--spacing)*1.5)}.sm\:py-2{padding-block:calc(var(--spacing)*2)}.sm\:py-3{padding-block:calc(var(--spacing)*3)}.sm\:py-4{padding-block:calc(var(--spacing)*4)}.sm\:pt-2{padding-top:calc(var(--spacing)*2)}.sm\:pt-3{padding-top:calc(var(--spacing)*3)}.sm\:pt-4{padding-top:calc(var(--spacing)*4)}.sm\:pr-0{padding-right:calc(var(--spacing)*0)}.sm\:pr-6{padding-right:calc(var(--spacing)*6)}.sm\:pb-3{padding-bottom:calc(var(--spacing)*3)}.sm\:pb-4{padding-bottom:calc(var(--spacing)*4)}.sm\:pb-6{padding-bottom:calc(var(--spacing)*6)}.sm\:pl-2{padding-left:calc(var(--spacing)*2)}.sm\:pl-11{padding-left:calc(var(--spacing)*11)}.sm\:text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.sm\:text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.sm\:text-\[11px\]{font-size:11px}.sm\:opacity-100{opacity:1}:is(.sm\:\*\:w-auto>*){width:auto}}@media(min-width:48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:grid{display:grid}.md\:hidden{display:none}.md\:h-\[80vh\]{height:80vh}.md\:h-\[600px\]{height:600px}.md\:max-h-\[900px\]{max-height:900px}.md\:w-72{width:calc(var(--spacing)*72)}.md\:min-w-\[680px\]{min-width:680px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media(min-width:64rem){.lg\:-mx-3{margin-inline:calc(var(--spacing)*-3)}.lg\:-mx-8{margin-inline:calc(var(--spacing)*-8)}.lg\:-mb-8{margin-bottom:calc(var(--spacing)*-8)}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:table-cell{display:table-cell}.lg\:h-dvh{height:100dvh}.lg\:max-h-\[calc\(100vh-194px\)\]{max-height:calc(100vh - 194px)}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.lg\:px-4{padding-inline:calc(var(--spacing)*4)}.lg\:px-8{padding-inline:calc(var(--spacing)*8)}.lg\:pt-0{padding-top:calc(var(--spacing)*0)}.lg\:pb-8{padding-bottom:calc(var(--spacing)*8)}}@media(min-width:80rem){.xl\:inline{display:inline}.xl\:w-44{width:calc(var(--spacing)*44)}}@media(prefers-color-scheme:dark){.dark\:bg-zinc-800{background-color:var(--color-zinc-800)}}.\[\&_button\]\:min-h-0 button{min-height:calc(var(--spacing)*0)}.\[\&_button\]\:px-2 button{padding-inline:calc(var(--spacing)*2)}.\[\&_button\]\:py-1 button{padding-block:calc(var(--spacing)*1)}.\[\&_button\]\:text-xs button{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_svg\]\:text-fg-muted svg{color:var(--fg-muted)}.\[\&_svg\]\:text-sys-blue svg{color:var(--sys-blue)}@media(hover:hover){.hover\:\[\&_svg\]\:text-fg-primary:hover svg{color:var(--fg-primary)}}.\[\&\:\:-moz-range-thumb\]\:h-4::-moz-range-thumb{height:calc(var(--spacing)*4)}.\[\&\:\:-moz-range-thumb\]\:w-4::-moz-range-thumb{width:calc(var(--spacing)*4)}.\[\&\:\:-moz-range-thumb\]\:cursor-pointer::-moz-range-thumb{cursor:pointer}.\[\&\:\:-moz-range-thumb\]\:appearance-none::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb{border-radius:3.40282e38px}.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-webkit-slider-thumb\]\:h-2\.5::-webkit-slider-thumb{height:calc(var(--spacing)*2.5)}.\[\&\:\:-webkit-slider-thumb\]\:h-3::-webkit-slider-thumb{height:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:h-3\.5::-webkit-slider-thumb{height:calc(var(--spacing)*3.5)}.\[\&\:\:-webkit-slider-thumb\]\:h-4::-webkit-slider-thumb{height:calc(var(--spacing)*4)}.\[\&\:\:-webkit-slider-thumb\]\:w-2\.5::-webkit-slider-thumb{width:calc(var(--spacing)*2.5)}.\[\&\:\:-webkit-slider-thumb\]\:w-3::-webkit-slider-thumb{width:calc(var(--spacing)*3)}.\[\&\:\:-webkit-slider-thumb\]\:w-3\.5::-webkit-slider-thumb{width:calc(var(--spacing)*3.5)}.\[\&\:\:-webkit-slider-thumb\]\:w-4::-webkit-slider-thumb{width:calc(var(--spacing)*4)}.\[\&\:\:-webkit-slider-thumb\]\:cursor-pointer::-webkit-slider-thumb{cursor:pointer}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-sys-blue::-webkit-slider-thumb{background-color:var(--sys-blue)}.\[\&\:\:-webkit-slider-thumb\]\:bg-sys-indigo::-webkit-slider-thumb{background-color:var(--sys-indigo)}.\[\&\:\:-webkit-slider-thumb\]\:shadow-lg::-webkit-slider-thumb{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\[\&\:\:-webkit-slider-thumb\]\:shadow-md::-webkit-slider-thumb{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.\[\&\:\:-webkit-slider-thumb\]\:transition-transform::-webkit-slider-thumb{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.\[\&\:\:-webkit-slider-thumb\]\:hover\:scale-110::-webkit-slider-thumb:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}}.\[\&\>\[data-slot\=icon\]\]\:h-4>[data-slot=icon]{height:calc(var(--spacing)*4)}.\[\&\>\[data-slot\=icon\]\]\:w-4>[data-slot=icon]{width:calc(var(--spacing)*4)}.\[\&\>\[data-slot\=icon\]\]\:shrink-0>[data-slot=icon]{flex-shrink:0}.\[\&\>\[data-slot\=section\]\+\[data-slot\=section\]\]\:mt-2\.5>[data-slot=section]+[data-slot=section]{margin-top:calc(var(--spacing)*2.5)}.\[\&\>\[data-slot\=section\]\+\[data-slot\=section\]\]\:mt-6>[data-slot=section]+[data-slot=section]{margin-top:calc(var(--spacing)*6)}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing)*3)}.\[\&\>svg\]\:h-4>svg{height:calc(var(--spacing)*4)}.\[\&\>svg\]\:h-\[1em\]>svg{height:1em}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing)*3)}.\[\&\>svg\]\:w-4>svg{width:calc(var(--spacing)*4)}.\[\&\>svg\]\:w-\[1em\]>svg{width:1em}.\[\&\>svg\]\:flex-shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:stroke-\[1\.5\]>svg{stroke-width:1.5px}@media(pointer:fine){.\[\@media\(pointer\:fine\)\]\:hidden{display:none}}}@supports (color:color(display-p3 1 1 1)){:root{--sys-red:color(display-p3 .898 .282 .302);--sys-orange:color(display-p3 .969 .42 .082);--sys-amber:color(display-p3 1 .698 .141);--sys-yellow:color(display-p3 .961 .851 .039);--sys-green:color(display-p3 .275 .655 .345);--sys-teal:color(display-p3 .071 .647 .58);--sys-cyan:color(display-p3 0 .635 .78);--sys-blue:color(display-p3 .231 .51 .965);--sys-indigo:color(display-p3 .357 .357 .839);--sys-purple:color(display-p3 .557 .306 .776);--sys-pink:color(display-p3 .839 .251 .624)}}a,button,[role=button],.interactive,.surface-base,[data-card-surface],.pill-tag,.pill-subtle,.toggle-group-item,.roster-row,.nav-item{transition:all .15s ease-out}a:hover,button:hover,[role=button]:hover,.interactive:hover,.surface-base:hover,[data-card-surface]:hover,.pill-tag:hover,.pill-subtle:hover,.toggle-group-item:hover,.roster-row:hover,.nav-item:hover{transition-duration:0s}a,button,[role=button],input,select,textarea{touch-action:manipulation;-webkit-tap-highlight-color:transparent}a,button{cursor:pointer}.truncate[title],.line-clamp-1[title],.line-clamp-2[title],.text-ellipsis[title]{cursor:help;position:relative}.truncate[title]:hover:after,.line-clamp-1[title]:hover:after,.line-clamp-2[title]:hover:after,.text-ellipsis[title]:hover:after{content:attr(title);z-index:9999;background:var(--tooltip-bg);border:1px solid var(--tooltip-border);width:max-content;max-width:300px;box-shadow:var(--tooltip-shadow);font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--tooltip-fg);white-space:normal;word-break:break-all;pointer-events:none;border-radius:6px;margin-top:4px;padding:6px 10px;line-height:1.4;animation:.15s ease-out tooltip-fade-in;position:absolute;top:100%;left:0}@keyframes tooltip-fade-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}.type-hero{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-5xl);font-weight:var(--font-semibold);letter-spacing:var(--tracking-tight);color:var(--fg-primary);line-height:1.05}.type-metric{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-4xl);font-weight:var(--font-semibold);letter-spacing:var(--tracking-tight);color:var(--fg-primary);line-height:1.1}.type-title{font-family:var(--font-title),system-ui,sans-serif;font-size:var(--text-2xl);font-weight:var(--font-semibold);line-height:var(--leading-snug);letter-spacing:var(--tracking-tight);color:var(--fg-primary)}.type-heading{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-lg);font-weight:var(--font-semibold);line-height:var(--leading-snug);color:var(--fg-primary)}.type-subheading{font-family:var(--font-card-title,var(--font-display)),system-ui,sans-serif;font-size:var(--text-card-title,var(--text-lg));font-weight:var(--font-card-title-weight,var(--font-semibold));line-height:var(--leading-snug);color:var(--fg-primary)}.type-body{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-base);font-weight:var(--font-normal);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-body-lg{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-md);font-weight:var(--font-normal);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-body-sm,.type-label{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-sm);font-weight:var(--font-medium);line-height:var(--leading-normal);color:var(--fg-secondary)}.type-micro{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-normal);letter-spacing:.12em;text-transform:uppercase;color:var(--fg-secondary)}.type-data{font-family:var(--font-data);font-size:var(--text-base);font-weight:var(--font-normal);line-height:var(--leading-normal);letter-spacing:var(--tracking-wide);font-feature-settings:"zero","tnum"}.type-data-lg{font-family:var(--font-data);font-size:var(--text-lg);font-weight:var(--font-medium);line-height:var(--leading-snug);letter-spacing:var(--tracking-normal);font-feature-settings:"zero","tnum"}.type-data-xl{font-family:var(--font-data);font-size:var(--text-xl);font-weight:var(--font-semibold);line-height:var(--leading-snug);letter-spacing:-.01em;font-feature-settings:"zero","tnum"}.type-data-hero{font-family:var(--font-data);font-size:var(--text-2xl);font-weight:var(--font-semibold);letter-spacing:-.03em;font-feature-settings:"zero","tnum";line-height:1.1}@media(min-width:640px){.type-data-hero{font-size:var(--text-3xl)}}:root{--punc-margin-comma:-.15em;--punc-margin-period:-.12em;--punc-margin-colon:-.08em;--punc-margin-slash:-.06em;--punc-margin-mult:-.1em}.data-tight{display:inline}.data-tight .punc,.punc-tight{margin-right:var(--punc-margin-comma);margin-left:-.05em;display:inline-block}.data-tight .punc-period,.punc-period{margin-right:var(--punc-margin-period);margin-left:-.03em}.data-tight .punc-colon,.punc-colon{margin-right:var(--punc-margin-colon);margin-left:var(--punc-margin-colon)}.data-tight .punc-slash,.punc-slash{margin-right:var(--punc-margin-slash);margin-left:var(--punc-margin-slash)}.data-tight .punc-mult,.punc-mult{margin-right:var(--punc-margin-mult);margin-left:0;display:inline-block}.type-data-sm{font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);line-height:var(--leading-normal);letter-spacing:var(--tracking-wider);font-feature-settings:"zero","tnum"}.type-data-xs{font-family:var(--font-data);font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-normal);letter-spacing:var(--tracking-widest);font-feature-settings:"zero","tnum"}.type-data-2xs{font-family:var(--font-data);font-size:.5625rem;font-weight:var(--font-medium);letter-spacing:var(--tracking-wider);font-feature-settings:"zero","tnum";line-height:1.2}.type-code{font-family:var(--font-data);font-size:.875em;font-weight:var(--font-normal);line-height:var(--leading-relaxed);font-feature-settings:"zero","tnum"}.type-badge{font-family:var(--font-data);font-size:var(--text-xs);font-weight:var(--font-medium);letter-spacing:.08em;text-transform:uppercase;line-height:1}.type-tag{font-family:var(--font-display),system-ui,sans-serif;font-size:var(--text-xs);font-weight:var(--font-medium);letter-spacing:.05em;line-height:1}.font-mono{font-feature-settings:"zero";font-family:var(--font-data)!important}.font-title{font-family:var(--font-title),system-ui,sans-serif!important}.font-display{font-family:var(--font-display),system-ui,sans-serif!important}.tabular-nums{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.lucide{stroke-width:1.75px}.pb-safe{padding-bottom:env(safe-area-inset-bottom,0)}.pt-safe{padding-top:env(safe-area-inset-top,0)}.pl-safe{padding-left:env(safe-area-inset-left,0)}.pr-safe{padding-right:env(safe-area-inset-right,0)}.p-safe{padding-top:env(safe-area-inset-top,0);padding-right:env(safe-area-inset-right,0);padding-bottom:env(safe-area-inset-bottom,0);padding-left:env(safe-area-inset-left,0)}@keyframes shimmer{0%{opacity:.5;transform:translate(-100%)}50%{opacity:1}to{opacity:.5;transform:translate(100%)}}:root{--duration-instant:75ms;--duration-fast:.15s;--duration-normal:.2s;--duration-slow:.3s;--duration-slower:.5s;--ease-linear:linear;--ease-in:cubic-bezier(.4,0,1,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--ease-bounce:cubic-bezier(.34,1.56,.64,1);--ease-spring:cubic-bezier(.175,.885,.32,1.275);--hover-scale-subtle:1.02;--hover-scale-pop:1.05;--hover-lift-y:-2px;--hover-lift-shadow:0 4px 12px #00000026;--active-scale:.98;--active-opacity:.9;--active-y:1px;--disabled-opacity:.4;--loading-opacity:.6}.interactive{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out);cursor:pointer}.interactive-fast{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-instant);transition-timing-function:var(--ease-out);cursor:pointer}.interactive-slow{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter;transition-duration:var(--duration-normal);transition-timing-function:var(--ease-in-out);cursor:pointer}.hover-bg:hover{background-color:var(--subtle-fill-hover)}.hover-bg-strong:hover{background-color:var(--subtle-fill-strong)}.hover-lift:hover{transform:translateY(var(--hover-lift-y));box-shadow:var(--hover-lift-shadow)}.hover-scale:hover{transform:scale(var(--hover-scale-subtle))}.hover-pop:hover{transform:scale(var(--hover-scale-pop))}.hover-bright:hover{filter:brightness(1.1)}.hover-dim:hover{filter:brightness(.95)}.hover-opacity:hover{opacity:.8}.hover-stroke:hover{box-shadow:inset 0 0 0 1.5px var(--edge-subtle)}.hover-border:hover{border-color:var(--edge-strong)}.hover-text:hover{color:var(--fg-primary)}.row-hover{transition-property:background-color,border-color,color;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.row-hover:hover{background-color:var(--subtle-fill-hover)}.card-hover{transition-property:transform,box-shadow,border-color;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.card-hover:hover{transform:translateY(var(--hover-lift-y));box-shadow:var(--surface-shadow-md)}.btn-hover{transition-property:background-color,border-color,color,transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.btn-hover:hover{background-color:var(--subtle-fill-hover)}.icon-hover{transition-property:transform,filter,opacity;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.icon-hover:hover{transform:scale(var(--hover-scale-subtle));filter:brightness(1.15)}.active-press:active{transform:scale(var(--active-scale))}.active-depress:active{transform:translateY(var(--active-y))}.active-dim:active{opacity:var(--active-opacity)}.active-full:active{transform:scale(var(--active-scale));opacity:var(--active-opacity)}.state-disabled,.disabled{pointer-events:none;opacity:var(--disabled-opacity);cursor:not-allowed}.state-loading,.loading{pointer-events:none;opacity:var(--loading-opacity);cursor:wait}.loading-pulse{pointer-events:none;animation:pulse 1.5s var(--ease-in-out)infinite}@keyframes pulse{50%{opacity:.5}}.transition-base{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-colors{transition-property:background-color,border-color,color,fill,stroke;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-transform{transition-property:transform;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-in-out)}.transition-opacity{transition-property:opacity;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}.transition-shadow{transition-property:box-shadow;transition-duration:var(--duration-fast);transition-timing-function:var(--ease-out)}:root{--radius-xs:4px;--radius-sm:6px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-2xl:20px;--radius-3xl:24px;--surface-opacity-base:80%;--surface-opacity-elevated:85%;--surface-opacity-solid:95%;--surface-blur-sm:8px;--surface-blur-md:16px;--surface-blur-lg:24px;--surface-ring:inset 0 1px 0 0 #ffffff17,inset 1px 0 0 0 #ffffff12,inset 0 -1px 0 0 #0000008c,inset -1px 0 0 0 #00000073;--surface-ring-strong:inset 0 1px 0 0 #ffffff24,inset 1px 0 0 0 #ffffff1c,inset 0 -1px 0 0 #000000a6,inset -1px 0 0 0 #0000008c;--surface-shadow-sm:0 4px 6px -4px #0000001a;--surface-shadow-md:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--surface-shadow-lg:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--surface-shadow-xl:0 25px 50px -12px #00000040;--surface-tint-subtle:#ffffff08;--surface-tint-light:#ffffff0d;--surface-border-subtle:#ffffff0d;--stroke-none:0px;--stroke-thin:1px;--stroke-medium:1.5px;--stroke-thick:2px;--ring-width-default:2px;--ring-width-thick:3px;--ring-offset:2px;--ring-color:var(--sys-blue);--ring-color-error:var(--sys-red)}[data-mode=light]{--surface-ring:inset 0 1px 0 0 #ffffff8c,inset 1px 0 0 0 #ffffff73,inset 0 -1px 0 0 #0000001a,inset -1px 0 0 0 #00000014;--surface-ring-strong:inset 0 1px 0 0 #ffffffa6,inset 1px 0 0 0 #ffffff8c,inset 0 -1px 0 0 #00000024,inset -1px 0 0 0 #0000001c}.surface-base{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-base{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-base{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));box-shadow:var(--surface-ring)}.surface-elevated{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-elevated{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-elevated),transparent)}}.surface-elevated{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));box-shadow:var(--surface-ring),var(--surface-shadow-lg)}.surface-modal{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-modal{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-modal{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));box-shadow:var(--surface-ring),var(--surface-shadow-xl)}.surface-sidebar{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-sidebar{background-color:color-mix(in srgb,var(--surface)var(--surface-opacity-base),transparent)}}.surface-sidebar{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));border-right:1px solid var(--edge-subtle)}.surface-header{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.surface-header{background-color:color-mix(in srgb,var(--body)70%,transparent)}}.surface-header{-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));border-bottom:1px solid var(--edge-subtle)}.surface-header[data-variant=dark]{-webkit-backdrop-filter:blur(var(--surface-blur-sm));backdrop-filter:blur(var(--surface-blur-sm));border-bottom-color:var(--edge-subtle);background-color:#000c}@supports (color:color-mix(in lab,red,red)){.surface-header[data-variant=dark]{border-bottom-color:color-mix(in srgb,var(--edge-subtle)50%,transparent)}}.surface-popover{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.surface-popover{background-color:color-mix(in srgb,var(--surface)72%,transparent)}}.surface-popover{-webkit-backdrop-filter:blur(var(--surface-blur-lg))saturate(1.3);backdrop-filter:blur(var(--surface-blur-lg))saturate(1.3);box-shadow:var(--surface-ring-strong),var(--surface-shadow-xl)}.surface-inner{background-color:var(--surface-tint-subtle);border:1px solid var(--surface-border-subtle);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px #0000000d}.surface-badge{background-color:var(--surface-tint-light);box-shadow:var(--surface-ring)}.surface-control{background-color:var(--elevated)}@supports (color:color-mix(in lab,red,red)){.surface-control{background-color:color-mix(in srgb,var(--elevated)92%,transparent)}}.surface-control{-webkit-backdrop-filter:blur(var(--surface-blur-md));backdrop-filter:blur(var(--surface-blur-md));border:1px solid var(--edge-subtle);box-shadow:var(--surface-shadow-md)}.surface-input{background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);transition:border-color .15s,box-shadow .15s}.surface-input:focus{box-shadow:inset 0 0 0 2px var(--sys-blue)}.surface-checkbox{background-color:var(--surface-tint-light);border:1px solid var(--edge-subtle);transition:background-color .15s,border-color .15s}.surface-checkbox:checked{background-color:var(--sys-blue);border-color:var(--sys-blue)}.surface-reflex{box-shadow:var(--surface-ring),inset 1.5px 2.5px 0 -1.5px #ffffff40,inset -1.5px -1.5px 0 -1.5px #fff3,inset -2px -6px 1px -4px #ffffff26,inset 0 2px 3px -1.5px #0000001f,inset -.25px -1px 3px #00000014;position:relative;overflow:hidden}[data-mode=light] .surface-reflex{box-shadow:var(--surface-ring),inset 1.5px 2.5px 0 -1.5px #fff9,inset -1.5px -1.5px 0 -1.5px #fff6,inset -2px -6px 1px -4px #ffffff4d,inset 0 2px 3px -1.5px #0000000f,inset -.25px -1px 3px #0000000a}.surface-reflex:before{content:"";pointer-events:none;border-radius:inherit;background:linear-gradient(#ffffff0f,#0000 30px),linear-gradient(0deg,#0000000a,#0000 40px);position:absolute;top:0;right:0;bottom:0;left:0}[data-mode=light] .surface-reflex:before{background:linear-gradient(#fff6,#0000 30px),linear-gradient(0deg,#00000005,#0000 40px)}.surface-themed[data-theme=terminal]{background-color:var(--terminal-bg)}.surface-themed[data-theme=terminal-input]{background-color:var(--terminal-bg-input);border-top:1px solid var(--terminal-border)}.surface-themed[data-theme=terminal-status]{background-color:var(--terminal-bg-status);border-top:1px solid var(--terminal-border)}.surface-themed[data-theme=terminal-autocomplete]{background-color:var(--terminal-autocomplete-bg);-webkit-backdrop-filter:blur(var(--surface-blur-lg));backdrop-filter:blur(var(--surface-blur-lg));border:1px solid var(--terminal-autocomplete-border);box-shadow:var(--surface-shadow-xl),var(--surface-shadow-lg)}.surface-divider-bottom{border-bottom:1px solid var(--edge-subtle)}.surface-divider-top{border-top:1px solid var(--edge-subtle)}.surface-divider[data-theme=terminal]{border-color:var(--terminal-border)}:root{--depth-raised:-4px -4px 10px #ffffff03,4px 4px 10px #0000001a,-1px -1px 3px #ffffff02,1px 1px 3px #0001,inset -2px -2px 6px #00000026;--depth-raised-soft:-4px -4px 10px #ffffff02,4px 4px 10px #00000010,-1px -1px 3px #ffffff01,1px 1px 3px #0000000a,inset -2px -2px 6px #0000000a;--depth-inset:inset 3px 3px 6px #0009,inset -3px -3px 6px #ffffff0d,inset 0 1px 2px #0006,inset 0 -1px 1px #ffffff0a;--depth-inset-soft:inset 2px 2px 4px #00000059,inset -2px -2px 4px #ffffff08,1px 1px 2px #ffffff08,-1px -1px 2px #0000004d;--depth-stroke-tl:inset 0 1px 0 0 #ffffff17,inset 1px 0 0 0 #ffffff12;--depth-stroke-br:inset 0 -1px 0 0 #0000008c,inset -1px 0 0 0 #00000073;--neo-toggle-inset:inset 2px 2px 5px #0000004d,inset -1px -1px 3px #ffffff0a,inset 0 1px 2px #0003;--neo-toggle-raised:-2px -2px 5px #ffffff08,2px 2px 5px #00000040,-.5px -.5px 1px #ffffff05,.5px .5px 1px #00000026,inset 1px 1px 2px #ffffff0a,inset -1px -1px 2px #00000014}[data-mode=light]{--depth-raised:-3px -3px 6px #00000002,3px 3px 6px #00000006,-1px -1px 2px #0000,1px 1px 2px #00000001,inset -1px -1px 3px #0000001a;--depth-raised-soft:-3px -3px 6px #00000001,3px 3px 6px #00000005,-1px -1px 2px #00000001,1px 1px 2px #00000005,inset -1px -1px 3px #00000009;--depth-inset:inset 2px 2px 4px #0000001f,inset -2px -2px 4px #00000004,inset 0 1px 1px #00000014,inset 0 -1px 1px #00000003;--depth-inset-soft:inset 2px 2px 3px #00000012,inset -2px -2px 3px #00000003,1px 1px 2px #00000003,-1px -1px 2px #0000000f;--depth-stroke-tl:inset 0 1px 0 0 #fff,inset 1px 0 0 0 #fff;--depth-stroke-br:inset 0 -1px 0 0 #0000000d,inset -1px 0 0 0 #0000000a;--neo-toggle-inset:inset 2px 2px 4px #00000014,inset -1px -1px 2px #00000002,inset 0 1px 1px #0000000f;--neo-toggle-raised:-1.5px -1.5px 4px #00000002,1.5px 1.5px 4px #00000017,-.5px -.5px 1px #00000001,.5px .5px 1px #0001,inset 1px 1px 2px #00000002,inset -1px -1px 2px #00000009}.depth-raised{box-shadow:var(--depth-raised),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-raised-soft{box-shadow:var(--depth-raised-soft),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-inset{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-stroke,.depth-stroke-raised{box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br)}.depth-stroke-inset{box-shadow:inset 0 1px #0000008c,inset 1px 0 #00000073,inset 0 -1px #ffffff17,inset -1px 0 #ffffff12}[data-mode=light] .depth-stroke-inset{box-shadow:inset 0 1px #0000000d,inset 1px 0 #0000000a,inset 0 -1px #fff,inset -1px 0 #fff}.depth-inset-soft{box-shadow:var(--depth-inset-soft),var(--depth-stroke-tl),var(--depth-stroke-br);background:linear-gradient(#0000001f,#ffffff05)}[data-mode=light] .depth-inset-soft{background:linear-gradient(#00000006,#00000001)}.neomorphic-outer{box-shadow:var(--depth-raised),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-outer-soft,.neomorphic-outer-soft-stroke{box-shadow:var(--depth-raised-soft),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-inner{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}.neomorphic-inner-subtle{box-shadow:var(--depth-inset-soft),var(--depth-stroke-tl),var(--depth-stroke-br);background:linear-gradient(#0000001f,#ffffff05)}[data-mode=light] .neomorphic-inner-subtle{background:linear-gradient(#00000006,#00000001)}.neomorphic-card{box-shadow:var(--depth-inset),var(--depth-stroke-tl),var(--depth-stroke-br)}:root{--neo-outer:var(--depth-raised);--neo-outer-soft:var(--depth-raised-soft);--neo-outer-sm:-3px -3px 8px #ffffff03,3px 3px 8px #0000001a,-1px -1px 2px #ffffff02,1px 1px 2px #0001,inset -1px -1px 4px #00000026}[data-mode=light]{--neo-outer:var(--depth-raised);--neo-outer-soft:var(--depth-raised-soft);--neo-outer-sm:-2px -2px 5px #00000001,2px 2px 5px #00000007,-1px -1px 1px #00000001,1px 1px 1px #00000007,inset -1px -1px 2px #0000000d}.sidebar-neo-highlight{box-shadow:inset 0 0 0 2px var(--sys-blue);background:0 0}.sidebar-neo-indicator{box-shadow:none}:root{--neo-map-outer:-4px -4px 12px #ffffff04,4px 4px 12px #00000040,-1px -1px 3px #ffffff03,1px 1px 3px #00000026;--neo-map-inner:inset 0 0 30px #0000004d,inset 0 0 60px #00000026,inset 3px 3px 8px #ffffff0a,inset -3px -3px 8px #00000040}[data-mode=light]{--neo-map-outer:-4px -4px 12px #00000001,4px 4px 12px #0000000d,-1px -1px 3px #00000001,1px 1px 3px #00000008;--neo-map-inner:inset 0 0 30px #0000000f,inset 0 0 60px #00000008,inset 3px 3px 8px #ffffff26,inset -3px -3px 8px #0000000d}.neomorphic-map-frame{box-shadow:var(--neo-map-outer);position:relative;overflow:hidden}.neomorphic-map-frame:after{content:"";border-radius:inherit;box-shadow:var(--neo-map-inner);pointer-events:none;z-index:50;position:absolute;top:0;right:0;bottom:0;left:0}.card-terminal{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;background:var(--elevated)!important;-webkit-backdrop-filter:none!important;box-shadow:var(--neo-outer-sm)!important;--tw-ring-shadow:0 0 #0000!important;border:none!important;border-radius:12px!important;padding:2px!important}.card-terminal-well{border-radius:var(--radius-md);box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);--tui-accent:#ff8c00;--tui-accent-local:var(--sys-blue);--tui-muted:#666;--tui-body:#fff;--tui-system:#888;--tui-hover-bg:#1a1f2e;--tui-hover-bar:var(--sys-blue);--tui-danger:var(--sys-red);--tui-warn:#f59e0b;--tui-disabled:#333;--tui-placeholder:#666;background:linear-gradient(#050505,#0a0a0a,#0c0c0c)}:root{--tui-header-height:52px;--tui-header-padding:4px;--tui-header-gap:4px;--tui-header-radius:10px}@media(min-width:640px){:root{--tui-header-height:64px;--tui-header-padding:6px;--tui-header-gap:6px;--tui-header-radius:12px}}.card-terminal-header{align-items:flex-end;gap:var(--tui-header-gap);padding:var(--tui-header-padding);background:var(--elevated);border-radius:var(--tui-header-radius);box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);flex-wrap:wrap;flex-shrink:0;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem;display:flex}.card-terminal-ridge{margin:var(--tui-header-padding)calc(var(--tui-header-gap)*2);border-radius:var(--tui-header-radius);background:var(--elevated);box-shadow:var(--neo-outer-sm);align-self:stretch;min-width:0}.card-terminal-section{color:var(--tui-accent,#ff8c00);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem}.card-terminal input{caret-color:var(--tui-accent,#ff8c00);caret-shape:block}.tui-emoji{filter:grayscale()sepia()hue-rotate(350deg)saturate(5)brightness(.85);display:inline}.card-terminal input:focus,.card-terminal input:focus-visible{-webkit-appearance:none;outline-offset:0!important;box-shadow:none!important;outline:none!important}.card-terminal-divider{background:linear-gradient(#000,#1a1a1a);height:2px;box-shadow:0 1px #ffffff0a;border:none!important}[data-mode=light] .card-terminal-well{box-shadow:var(--depth-stroke-tl),var(--depth-stroke-br);--tui-accent:#1a1d20;--tui-accent-local:#2e4a68;--tui-muted:#858a90;--tui-body:#111314;--tui-system:#72777c;--tui-hover-bg:#0000000f;--tui-hover-bar:#2e4a68;--tui-danger:#a03028;--tui-warn:#6b5a20;--tui-disabled:#b8bcc0;--tui-placeholder:#95999e;background:#eff0f1}[data-mode=light] .card-terminal-section{color:#3a4550}[data-mode=light] .card-terminal input{caret-color:#2a2d30}[data-mode=light] .tui-emoji{filter:grayscale()brightness(.4)}.tui-input::placeholder{color:var(--tui-placeholder)}[data-mode=light] .card-terminal-divider{background:linear-gradient(#b0b4ba,#c2c6cc);box-shadow:0 1px #fff6}.radius-card{border-radius:var(--radius-xl)}.radius-inset{border-radius:var(--radius-lg)}.radius-inner{border-radius:var(--radius-md)}.radius-control{border-radius:var(--radius-sm)}.radius-badge{border-radius:var(--radius-xs)}.radius-hero{border-radius:var(--radius-2xl)}.radius-none{border-radius:0}.radius-pill{border-radius:9999px}.border-card,.border-control{border:var(--stroke-thin)solid var(--edge-subtle)}.border-emphasis{border:var(--stroke-medium)solid var(--edge-strong)}.ring-focus:focus-visible{outline:var(--ring-width-default)solid var(--ring-color);outline-offset:var(--ring-offset)}.ring-focus-inset:focus-visible{box-shadow:inset 0 0 0 var(--ring-width-default) var(--ring-color);outline:none}.ring-focus-error:focus-visible{outline:var(--ring-width-default)solid var(--ring-color-error);outline-offset:var(--ring-offset)}.divider-bottom{border-bottom:var(--stroke-thin)solid var(--edge-subtle)}.divider-top{border-top:var(--stroke-thin)solid var(--edge-subtle)}.divider-right{border-right:var(--stroke-thin)solid var(--edge-subtle)}.divider-left{border-left:var(--stroke-thin)solid var(--edge-subtle)}.surface-thumbnail{border-radius:var(--radius-sm);border:none;position:relative;overflow:hidden}.surface-thumbnail:after{content:"";z-index:10;pointer-events:none;border-radius:inherit;box-shadow:inset 0 0 0 .5px var(--default-light),inset .9px 1.5px 0 -1px var(--default-light),inset -1px -1px 0 -1px var(--default-light),inset -1.5px -4px .5px -3px var(--default-light),inset -.15px -.5px 2px 0 var(--default-dark),inset -.75px 1.25px 0 -1px var(--default-dark),inset 0 1.5px 2px -1px var(--default-dark);position:absolute;top:0;right:0;bottom:0;left:0}@supports (color:color-mix(in lab,red,red)){.surface-thumbnail:after{box-shadow:inset 0 0 0 .5px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*16%),transparent),inset .9px 1.5px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*140%),transparent),inset -1px -1px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*125%),transparent),inset -1.5px -4px .5px -3px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*94%),transparent),inset -.15px -.5px 2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*18%),transparent),inset -.75px 1.25px 0 -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent),inset 0 1.5px 2px -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent)}}.surface-thumbnail-selected:after{box-shadow:inset 0 0 0 1.5px var(--sys-blue),inset .9px 1.5px 0 -1px var(--default-light),inset -1px -1px 0 -1px var(--default-light),inset -1.5px -4px .5px -3px var(--default-light),inset -.15px -.5px 2px 0 var(--default-dark),inset -.75px 1.25px 0 -1px var(--default-dark),inset 0 1.5px 2px -1px var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.surface-thumbnail-selected:after{box-shadow:inset 0 0 0 1.5px var(--sys-blue),inset .9px 1.5px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*140%),transparent),inset -1px -1px 0 -1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*125%),transparent),inset -1.5px -4px .5px -3px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*94%),transparent),inset -.15px -.5px 2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*18%),transparent),inset -.75px 1.25px 0 -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent),inset 0 1.5px 2px -1px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*31%),transparent)}}.surface-card-frame{z-index:1000;box-shadow:inset 0 0 0 1px var(--default-light),inset 1.8px 3px 0 -2px var(--default-light),inset -2px -2px 0 -2px var(--default-light),inset -3px -8px 1px -6px var(--default-light),inset -.3px -1px 4px 0 var(--default-dark),inset -1.5px 2.5px 0 -2px var(--default-dark),inset 0 3px 4px -2px var(--default-dark),inset 2px -6.5px 1px -4px var(--default-dark),0 1px 5px 0 var(--default-dark),0 6px 16px 0 var(--default-dark);border-radius:1.125rem;position:relative}@supports (color:color-mix(in lab,red,red)){.surface-card-frame{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*15%),transparent),inset 1.8px 3px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*90%),transparent),inset -2px -2px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*80%),transparent),inset -3px -8px 1px -6px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*60%),transparent),inset -.3px -1px 4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*15%),transparent),inset -1.5px 2.5px 0 -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*25%),transparent),inset 0 3px 4px -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*25%),transparent),inset 2px -6.5px 1px -4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent),0 1px 5px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*15%),transparent),0 6px 16px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent)}}.surface-card-frame:before{content:"";pointer-events:none;border-radius:inherit;z-index:1001;background:var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.separator-line{background:linear-gradient(to right,transparent,var(--default-light)20%,var(--default-light)80%,transparent);height:1px}@supports (color:color-mix(in lab,red,red)){.separator-line{background:linear-gradient(to right,transparent,color-mix(in srgb,var(--default-light)8%,transparent)20%,color-mix(in srgb,var(--default-light)8%,transparent)80%,transparent)}}.separator-line-vertical{background:linear-gradient(to bottom,transparent,var(--default-light)20%,var(--default-light)80%,transparent);width:1px}@supports (color:color-mix(in lab,red,red)){.separator-line-vertical{background:linear-gradient(to bottom,transparent,color-mix(in srgb,var(--default-light)8%,transparent)20%,color-mix(in srgb,var(--default-light)8%,transparent)80%,transparent)}}.rounded-pill{border-radius:9999px}.rounded-card{border-radius:var(--radius-xl)}.catalyst-mode .surface-card-frame{border-radius:var(--radius-xl)!important;box-shadow:inset 0 0 0 1px var(--edge-subtle)!important}.catalyst-mode .surface-card-frame:before{display:none!important}.catalyst-mode .map-control-surface,.catalyst-mode .map-controls-container,.catalyst-mode .maplibregl-ctrl-group{background-color:var(--map-ui-bg,var(--surface))!important;border-radius:var(--radius-md)!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--edge-subtle)),var(--map-ui-shadow,0 1px 3px 0 #0000001a)!important}.catalyst-mode .map-control-surface:after,.catalyst-mode .maplibregl-ctrl-group:after{display:none!important}.catalyst-mode .surface-thumbnail:after{box-shadow:inset 0 0 0 1px var(--edge-subtle)!important}.sidebar-panel{background-color:var(--default-tint);border:none;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.sidebar-panel{background-color:color-mix(in srgb,var(--default-tint)var(--default-bg-opacity),transparent)}}.sidebar-panel{-webkit-backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));box-shadow:inset 0 0 0 1px var(--default-light),inset -1px 0 0 0 var(--default-light),inset 1px 0 0 0 var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.sidebar-panel{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*10%),transparent),inset -1px 0 color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*8%),transparent),inset 1px 0 color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*10%),transparent)}}.sidebar-panel:before{content:"";pointer-events:none;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.catalyst-mode .sidebar-panel{background-color:var(--body)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;box-shadow:none!important;border:none!important}.catalyst-mode .sidebar-panel:before{display:none!important}.catalyst-mode [data-slot=section] a,.catalyst-mode [data-slot=section] button{border-radius:var(--radius-lg)!important}.catalyst-mode [data-slot=section] a:hover,.catalyst-mode [data-slot=section] button:hover{background-color:var(--surface)!important}.catalyst-mode [data-slot=section] a[data-current=true],.catalyst-mode [data-slot=section] button[data-current=true]{background-color:var(--surface)!important;color:var(--fg-primary)!important}.catalyst-mode [data-slot=section] a[data-current=true] svg,.catalyst-mode [data-slot=section] button[data-current=true] svg{color:var(--fg-primary)!important}.catalyst-mode [data-slot=section] .absolute.bg-sys-blue{display:none!important}.mobile-header{background-color:var(--body)}@supports (color:color-mix(in lab,red,red)){.mobile-header{background-color:color-mix(in srgb,var(--body)70%,transparent)}}.mobile-header{-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);border-bottom:1px solid var(--edge-subtle)}.catalyst-mode .mobile-header{background-color:var(--body)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}.main-content{overflow-x:clip}.catalyst-mode .main-content{background-color:var(--subtle);box-shadow:inset 0 0 0 1px var(--edge-subtle);border-radius:.75rem 0 0 .75rem;margin:.5rem 0}@media(max-width:1023px){.catalyst-mode .main-content{border-radius:0;margin:0}}.catalyst-mode [data-card-surface]{background-color:var(--surface)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;border-radius:var(--radius-xl)!important;--tw-ring-shadow:0 0 #0000!important;border:none!important}.catalyst-mode [data-card-surface]:before{display:none!important}.card-sm{min-height:7rem}.card-md{min-height:11rem}.card-lg{min-height:14rem}.card-hero{min-height:20rem}.card-auto{min-height:auto}@media(max-width:640px){.card-sm{min-height:6rem}.card-md{min-height:9rem}.card-lg{min-height:12rem}.card-hero{min-height:16rem}}.icon-sm{flex-shrink:0;width:1rem;height:1rem}.icon-md{flex-shrink:0;width:1.25rem;height:1.25rem}.icon-lg{flex-shrink:0;width:1.5rem;height:1.5rem}.icon-xl{flex-shrink:0;width:2rem;height:2rem}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--surface)}::-webkit-scrollbar-thumb{background-color:var(--edge-strong);border-radius:4px}::-webkit-scrollbar-thumb:hover{background-color:var(--fg-muted)}.sidebar-scroll{scrollbar-width:thin;scrollbar-color:transparent transparent}.sidebar-scroll:hover{scrollbar-color:var(--edge-subtle)transparent}.sidebar-scroll::-webkit-scrollbar{width:4px}.sidebar-scroll::-webkit-scrollbar-track{background:0 0}.sidebar-scroll::-webkit-scrollbar-thumb{background-color:#0000;border-radius:2px}.sidebar-scroll:hover::-webkit-scrollbar-thumb{background-color:var(--edge-subtle)}.layout-container{width:100%;max-width:80rem;margin-left:auto;margin-right:auto}.grid-12{grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;display:grid}@media(min-width:768px){.grid-12{gap:1.5rem}}.col-span-6{grid-column:span 6/span 6}.col-span-4{grid-column:span 4/span 4}.col-span-3{grid-column:span 3/span 3}@media(min-width:640px){.sm\:col-span-6{grid-column:span 6/span 6}.sm\:col-span-4{grid-column:span 4/span 4}.sm\:col-span-3{grid-column:span 3/span 3}}@media(min-width:768px){.md\:col-span-6{grid-column:span 6/span 6}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-3{grid-column:span 3/span 3}.md\:col-span-8{grid-column:span 8/span 8}.md\:col-span-12{grid-column:span 12/span 12}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-4{grid-column:span 4/span 4}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-8{grid-column:span 8/span 8}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:col-span-10{grid-column:span 10/span 10}.lg\:col-span-12{grid-column:span 12/span 12}}@media(min-width:1280px){.xl\:col-span-2{grid-column:span 2/span 2}.xl\:col-span-3{grid-column:span 3/span 3}.xl\:col-span-4{grid-column:span 4/span 4}.xl\:col-span-8{grid-column:span 8/span 8}}.gap-space-2{gap:.5rem}.gap-space-3{gap:.75rem}.gap-space-4{gap:1rem}.gap-space-6{gap:1.5rem}.gap-space-8{gap:2rem}.gap-y-space-4{row-gap:1rem}.gap-y-space-6{row-gap:1.5rem}.gap-y-space-8{row-gap:2rem}.gap-x-space-4{column-gap:1rem}.gap-x-space-6{column-gap:1.5rem}.gap-x-space-8{column-gap:2rem}.card-padding{padding:.75rem}@media(min-width:640px){.card-padding{padding:1rem}}.card-padding-sm{padding:.5rem}@media(min-width:640px){.card-padding-sm{padding:.75rem}}.card-padding-xs{padding:.5rem}@media(min-width:640px){.card-padding-xs{padding:.75rem}}.section-gap{flex-direction:column;gap:1rem;min-width:0;padding:.5rem .75rem .25rem;display:flex}@media(min-width:640px){.section-gap{gap:1.5rem}}@media(min-width:1024px){.section-gap{gap:2rem;padding:.5rem 1rem .25rem}}.bento-section{flex-direction:column;gap:1rem;min-width:0;display:flex}.stats-row-hero{grid-template-columns:repeat(2,1fr);gap:1rem;display:grid}@media(min-width:768px){.stats-row-hero{grid-template-columns:repeat(3,1fr);gap:1.5rem}}@media(min-width:1280px){.stats-row-hero{grid-template-columns:repeat(5,1fr)}}.stats-row-secondary{grid-template-columns:1fr;gap:1rem;display:grid}@media(min-width:640px){.stats-row-secondary{grid-template-columns:repeat(2,1fr)}}@media(min-width:1024px){.stats-row-secondary{grid-template-columns:repeat(4,1fr);gap:1.5rem}}.content-grid{grid-template-columns:1fr;gap:1rem;display:grid}@media(min-width:768px){.content-grid{gap:1.5rem}}@media(min-width:1280px){.content-grid{grid-template-columns:2fr 1fr}}.content-main,.content-sidebar{min-width:0}.bento-row{grid-template-columns:repeat(12,minmax(0,1fr));align-items:stretch;display:grid}.bento-row-hero{min-height:15rem}@media(min-width:768px){.bento-row-hero{min-height:17.5rem}}@media(min-width:1024px){.bento-row-hero{min-height:20rem}}.bento-row-hero-tall{height:20rem;min-height:20rem}@media(min-width:768px){.bento-row-hero-tall{height:23.3125rem;min-height:23.3125rem}}@media(min-width:1024px){.bento-row-hero-tall{height:26.625rem;min-height:26.625rem}}.bento-row-hero-auto{min-height:30rem}@media(min-width:768px){.bento-row-hero-auto{min-height:23.3125rem}}@media(min-width:1024px){.bento-row-hero-auto{min-height:26.625rem}}.bento-row-panel{grid-auto-rows:18.75rem}.bento-row-feature{grid-auto-rows:12.5rem}@media(min-width:768px){.bento-row-feature{grid-auto-rows:15rem}}@media(min-width:1024px){.bento-row-feature{grid-auto-rows:16.25rem}}.bento-row-standard{min-height:11.25rem}@media(min-width:768px){.bento-row-standard{min-height:12.5rem}}@media(min-width:1024px){.bento-row-standard{min-height:13.75rem}}.bento-row-compact{min-height:8.75rem}@media(min-width:768px){.bento-row-compact{min-height:10rem}}@media(min-width:1024px){.bento-row-compact{min-height:11.25rem}}.bento-row-widget{min-height:6.25rem}@media(min-width:768px){.bento-row-widget{min-height:6.875rem}}@media(min-width:1024px){.bento-row-widget{min-height:7.5rem}}.bento-row-auto{min-height:auto}.legend-item{cursor:pointer;border-radius:.25rem;align-items:center;gap:.25rem;padding:.25rem .375rem;font-size:.6875rem;line-height:1.2;transition:background-color .15s,opacity .15s;display:flex}.legend-item:hover{background-color:var(--hover-tint)}.legend-item-active{background-color:var(--subtle);opacity:1}.legend-item-dimmed{opacity:.35}.legend-item-chart-active{background-color:var(--hover-tint);opacity:1}.legend-label{color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;max-width:5.5rem;overflow:hidden}.legend-value{font-family:var(--font-data);font-variant-numeric:tabular-nums;color:var(--fg-secondary);flex-shrink:0;margin-left:auto;font-weight:600}.legend-value-live{color:var(--fg-primary)}.bento-gap{gap:1rem}.bento-gap-sm{gap:.5rem}@media(min-width:640px){.bento-gap-sm{gap:.75rem}}@media(min-width:768px){.bento-gap-sm{gap:1rem}}.bento-gap-lg{gap:1rem}@media(min-width:640px){.bento-gap-lg{gap:1.25rem}}@media(min-width:768px){.bento-gap-lg{gap:1.5rem}}@media(min-width:1024px){.bento-gap-lg{gap:2rem}}.bento-cell{flex-direction:column;min-width:0;min-height:0;display:flex}.bento-cell>*{flex:auto;min-height:0}.bento-cell[data-ratio]>:first-child{aspect-ratio:var(--cell-ratio);flex-shrink:1;max-height:100%}.bento-col-1{grid-column:span 1/span 1}.bento-col-2{grid-column:span 2/span 2}.bento-col-3{grid-column:span 3/span 3}.bento-col-4{grid-column:span 4/span 4}.bento-col-5{grid-column:span 5/span 5}.bento-col-6{grid-column:span 6/span 6}.bento-col-7{grid-column:span 7/span 7}.bento-col-8{grid-column:span 8/span 8}.bento-col-9{grid-column:span 9/span 9}.bento-col-10{grid-column:span 10/span 10}.bento-col-11{grid-column:span 11/span 11}.bento-col-12{grid-column:span 12/span 12}.col-span-full{grid-column:1/-1}.col-auto{grid-column:auto}.bento-col-1-5{grid-column:span 2/span 2}@media(min-width:640px){.sm\:bento-col-1{grid-column:span 1/span 1}.sm\:bento-col-2{grid-column:span 2/span 2}.sm\:bento-col-3{grid-column:span 3/span 3}.sm\:bento-col-4{grid-column:span 4/span 4}.sm\:bento-col-5{grid-column:span 5/span 5}.sm\:bento-col-6{grid-column:span 6/span 6}.sm\:bento-col-7{grid-column:span 7/span 7}.sm\:bento-col-8{grid-column:span 8/span 8}.sm\:bento-col-9{grid-column:span 9/span 9}.sm\:bento-col-10{grid-column:span 10/span 10}.sm\:bento-col-11{grid-column:span 11/span 11}.sm\:bento-col-12{grid-column:span 12/span 12}.sm\:col-span-full{grid-column:1/-1}.sm\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:768px){.md\:bento-col-1{grid-column:span 1/span 1}.md\:bento-col-2{grid-column:span 2/span 2}.md\:bento-col-3{grid-column:span 3/span 3}.md\:bento-col-4{grid-column:span 4/span 4}.md\:bento-col-5{grid-column:span 5/span 5}.md\:bento-col-6{grid-column:span 6/span 6}.md\:bento-col-7{grid-column:span 7/span 7}.md\:bento-col-8{grid-column:span 8/span 8}.md\:bento-col-9{grid-column:span 9/span 9}.md\:bento-col-10{grid-column:span 10/span 10}.md\:bento-col-11{grid-column:span 11/span 11}.md\:bento-col-12{grid-column:span 12/span 12}.md\:col-span-full{grid-column:1/-1}.md\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:1024px){.lg\:bento-col-1{grid-column:span 1/span 1}.lg\:bento-col-2{grid-column:span 2/span 2}.lg\:bento-col-3{grid-column:span 3/span 3}.lg\:bento-col-4{grid-column:span 4/span 4}.lg\:bento-col-5{grid-column:span 5/span 5}.lg\:bento-col-6{grid-column:span 6/span 6}.lg\:bento-col-7{grid-column:span 7/span 7}.lg\:bento-col-8{grid-column:span 8/span 8}.lg\:bento-col-9{grid-column:span 9/span 9}.lg\:bento-col-10{grid-column:span 10/span 10}.lg\:bento-col-11{grid-column:span 11/span 11}.lg\:bento-col-12{grid-column:span 12/span 12}.lg\:col-span-full{grid-column:1/-1}.lg\:bento-col-1-5{grid-column:span 2/span 2}}@media(min-width:1280px){.xl\:bento-col-1{grid-column:span 1/span 1}.xl\:bento-col-2{grid-column:span 2/span 2}.xl\:bento-col-3{grid-column:span 3/span 3}.xl\:bento-col-4{grid-column:span 4/span 4}.xl\:bento-col-5{grid-column:span 5/span 5}.xl\:bento-col-6{grid-column:span 6/span 6}.xl\:bento-col-7{grid-column:span 7/span 7}.xl\:bento-col-8{grid-column:span 8/span 8}.xl\:bento-col-9{grid-column:span 9/span 9}.xl\:bento-col-10{grid-column:span 10/span 10}.xl\:bento-col-11{grid-column:span 11/span 11}.xl\:bento-col-12{grid-column:span 12/span 12}.xl\:col-span-full{grid-column:1/-1}.xl\:bento-col-1-5{grid-column:span 2/span 2}}.pill-filled{background:var(--sys-blue);color:var(--body);border-radius:9999px;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:opacity .15s;display:inline-flex}.pill-filled:hover{opacity:.9}.pill-subtle{background:var(--subtle);color:var(--fg-secondary);border:1px solid var(--edge-subtle);border-radius:9999px;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:all .15s;display:inline-flex}.pill-subtle:hover{background:var(--elevated);color:var(--fg-primary)}.pill-metric{text-transform:uppercase;letter-spacing:.05em;border-radius:9999px;align-items:center;gap:.25rem;padding:.25rem .5rem;font-size:.625rem;font-weight:600;line-height:1;display:inline-flex}.pill-metric-positive{background:var(--sys-green)}@supports (color:color-mix(in lab,red,red)){.pill-metric-positive{background:color-mix(in srgb,var(--sys-green)15%,transparent)}}.pill-metric-positive{color:var(--sys-green)}.pill-metric-negative{background:var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.pill-metric-negative{background:color-mix(in srgb,var(--sys-red)15%,transparent)}}.pill-metric-negative{color:var(--sys-red)}.pill-metric-neutral{background:var(--overlay-soft);color:var(--fg-secondary)}.pill-tag{background:var(--sys-blue);border-radius:9999px;align-items:center;padding:.125rem .5rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.pill-tag{background:color-mix(in srgb,var(--sys-blue)10%,transparent)}}.pill-tag{color:var(--sys-blue);text-transform:uppercase;letter-spacing:.08em;font-size:.625rem;font-weight:600}[data-mode=light] [data-color=zinc]{background-color:var(--fg-muted)!important}@supports (color:color-mix(in lab,red,red)){[data-mode=light] [data-color=zinc]{background-color:color-mix(in srgb,var(--fg-muted)8%,transparent)!important}}[data-mode=light] [data-color=zinc]{color:var(--fg-muted)!important;font-weight:400!important}.toggle-group{background-color:var(--surface);box-shadow:var(--neo-outer-sm);border-radius:9999px;padding:3px;display:inline-flex;position:relative}.toggle-group:before{display:none}.toggle-group-item{border-radius:var(--radius-lg);color:var(--fg-muted);box-shadow:inset 0 0 0 1px var(--edge-subtle);padding:.375rem .75rem;font-size:.75rem;font-weight:500;transition:all .15s;position:relative}.toggle-group-item:hover:not(.active){color:var(--fg-secondary);box-shadow:inset 0 0 0 1.5px var(--edge-strong)}.toggle-group-item.active{color:var(--fg-primary);box-shadow:inset 0 0 0 1.5px var(--sys-blue)}.toggle-group-highlight{border-radius:inherit;box-shadow:inset 0 0 0 1.5px var(--sys-blue);background-color:#0000;position:absolute;top:0;right:0;bottom:0;left:0}.toggle-group-sm{padding:.1875rem}.toggle-group-sm .toggle-group-item{padding:.25rem .5rem;font-size:.6875rem}.toggle-group-micro{padding:.125rem}.toggle-group-micro .toggle-group-item{padding:.1875rem .375rem;font-size:.625rem}.chart-body{padding:1rem;position:relative}.chart-axis-label{color:var(--fg-muted);font-variant-numeric:tabular-nums;font-size:.6875rem}.chart-gridline{stroke:var(--chart-grid);stroke-dasharray:4 4}.chart-glow-primary{filter:drop-shadow(0 0 6px var(--sys-blue))}.chart-glow-secondary{filter:drop-shadow(0 0 6px var(--sys-indigo))}.chart-glow-tertiary{filter:drop-shadow(0 0 6px var(--sys-cyan))}.roster-list{flex-direction:column;display:flex}.roster-row{border-radius:var(--radius-lg);align-items:center;gap:.5rem;padding:.75rem .75rem .75rem .5rem;transition:background .15s;display:flex}@media(min-width:640px){.roster-row{gap:.75rem;padding:.75rem 1rem .75rem .75rem}}.roster-row:hover{background:var(--subtle)}@supports (color:color-mix(in lab,red,red)){.roster-row:hover{background:color-mix(in srgb,var(--subtle)80%,transparent)}}.roster-row-interactive{cursor:pointer}.roster-row-interactive:active{background:var(--subtle)}.roster-row.selected{background:var(--sys-blue)}@supports (color:color-mix(in lab,red,red)){.roster-row.selected{background:color-mix(in srgb,var(--sys-blue)8%,transparent)}}.roster-icon{border-radius:var(--radius-md);background-color:var(--default-tint);flex-shrink:0;justify-content:center;align-items:center;width:2.5rem;height:2.5rem;display:flex}@supports (color:color-mix(in lab,red,red)){.roster-icon{background-color:color-mix(in srgb,var(--default-tint)10%,transparent)}}.roster-icon{box-shadow:inset 0 0 0 1px var(--default-light),inset .5px 1px 0 0 var(--default-light)}@supports (color:color-mix(in lab,red,red)){.roster-icon{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*5%),transparent),inset .5px 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*30%),transparent)}}.roster-icon-sm{border-radius:var(--radius-md);width:2rem;height:2rem}.roster-content{flex-direction:column;flex:1;gap:.125rem;min-width:0;display:flex}.roster-title{color:var(--fg-primary);white-space:nowrap;text-overflow:ellipsis;font-size:.875rem;font-weight:500;overflow:hidden}.roster-subtitle{color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;font-size:.75rem;overflow:hidden}.roster-metrics{color:var(--fg-muted);align-items:center;gap:1rem;display:flex}.roster-metric{color:var(--fg-secondary);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:.8125rem;font-weight:600}@media(max-width:639px){.roster-row{flex-wrap:wrap;gap:.375rem;padding:.5rem .5rem .5rem .375rem}.roster-icon{border-radius:var(--radius-sm);width:1.75rem;height:1.75rem}.roster-content{flex:1 1 0;min-width:0;overflow:hidden}.roster-title{font-size:.75rem}.roster-metrics{flex-wrap:wrap;order:3;gap:.5rem;width:100%;margin-top:.25rem;padding-left:2.25rem}.roster-metric{flex-shrink:0;margin-left:auto;font-size:.6875rem}}@media(min-width:640px)and (max-width:767px){.roster-row{gap:.5rem}.roster-icon{border-radius:var(--radius-md);width:2rem;height:2rem}.roster-metrics{gap:.75rem}}@media(min-width:768px)and (max-width:1023px){.roster-metrics{gap:.875rem}}@media(min-width:1024px){.roster-row{gap:.875rem}.roster-metrics{gap:1rem}}.contacts-grid-header,.contacts-grid-row{grid-template-columns:1fr;grid-template-areas:"node";align-items:center;gap:.75rem;display:grid}.contacts-grid-row{contain:layout;padding:.625rem .75rem;transition:background-color .15s ease-out}.contacts-grid-row:hover{background-color:var(--subtle);transition-duration:0s}@media(max-width:639px){.contacts-grid-row{flex-wrap:nowrap;gap:.5rem;padding:.5rem .625rem;display:flex}.contacts-col-signal,.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity{display:none}.contacts-col-node{flex:1 1 0;min-width:0}.contacts-col-seen,.contacts-col-actions{flex-shrink:0;align-self:center}}@media(min-width:640px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(200px,1fr) 100px 60px 68px;grid-template-areas:"node signal seen actions"}.contacts-col-node{grid-area:node}.contacts-col-signal{grid-area:signal;display:flex}.contacts-col-seen{grid-area:seen}.contacts-col-actions{grid-area:actions}.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity{display:none}}@media(min-width:768px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(240px,1fr) 110px 80px 60px 68px;grid-template-areas:"node signal distance seen actions"}.contacts-col-distance{grid-area:distance;display:flex}}@media(min-width:1024px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(280px,1fr) 110px 80px 64px 64px 68px;grid-template-areas:"node signal distance centrality seen actions"}.contacts-col-centrality{grid-area:centrality;display:flex}}@media(min-width:1280px){.contacts-grid-header,.contacts-grid-row{grid-template-columns:minmax(320px,1fr) 120px 80px 64px 64px 68px 68px;grid-template-areas:"node signal distance centrality activity seen actions"}.contacts-col-activity{grid-area:activity;display:flex}}.contacts-col-node{min-width:0}.contacts-col-signal,.contacts-col-distance,.contacts-col-centrality,.contacts-col-activity,.contacts-col-seen,.contacts-col-actions{white-space:nowrap;flex-shrink:0;overflow:hidden}.roster-separator{background:linear-gradient(to right,transparent,var(--edge-subtle)20%,var(--edge-subtle)80%,transparent);height:1px;margin:0 1rem}.roster-empty{text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:3rem 1.5rem;display:flex}.roster-empty-icon{width:3rem;height:3rem;color:var(--fg-muted);opacity:.5;margin-bottom:1rem}.roster-empty-title{color:var(--fg-secondary);margin-bottom:.25rem;font-size:.875rem;font-weight:500}.roster-empty-text{color:var(--fg-muted);font-size:.75rem}.btn-skeuo{border-radius:var(--radius-md);cursor:pointer;background:var(--ctrl-base);border:1.5px solid var(--ctrl-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-shadow-dark),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset);justify-content:center;align-items:center;gap:.5rem;padding:.75rem 1.25rem;font-size:.875rem;font-weight:600;transition:all .12s ease-out;display:inline-flex;position:relative}.btn-skeuo:hover{background:var(--ctrl-base-hover);border-color:var(--ctrl-border-hover);box-shadow:0 4px 0 var(--ctrl-shadow-dark),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.btn-skeuo:active{background:var(--ctrl-base-active);box-shadow:0 0 0 var(--ctrl-shadow-dark),0 1px 3px var(--ctrl-shadow-mid),inset 0 3px 6px var(--ctrl-shadow-mid),inset 0 1px 0 var(--ctrl-shadow-dark);transform:translateY(3px)}.btn-skeuo:disabled{opacity:.4;cursor:not-allowed;transform:none}.btn-skeuo-primary{background:var(--ctrl-primary);border-color:var(--ctrl-primary-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-primary-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-primary-highlight),inset 0 -2px 0 var(--ctrl-primary-inset)}.btn-skeuo-primary:hover{background:var(--ctrl-primary-hover);border-color:var(--ctrl-primary-highlight);box-shadow:0 4px 0 var(--ctrl-primary-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-primary-highlight),inset 0 -2px 0 var(--ctrl-primary-inset)}.btn-skeuo-success{background:var(--ctrl-success);border-color:var(--ctrl-success-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-success-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-success-highlight),inset 0 -2px 0 var(--ctrl-success-inset)}.btn-skeuo-success:hover{background:var(--ctrl-success-hover);border-color:var(--ctrl-success-highlight);box-shadow:0 4px 0 var(--ctrl-success-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-success-highlight),inset 0 -2px 0 var(--ctrl-success-inset)}.btn-skeuo-warning{background:var(--ctrl-warning);border-color:var(--ctrl-warning-border);color:var(--fg-primary);box-shadow:0 3px 0 var(--ctrl-warning-shadow),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-warning-highlight),inset 0 -2px 0 var(--ctrl-warning-inset)}.btn-skeuo-warning:hover{background:var(--ctrl-warning-hover);border-color:var(--ctrl-warning-highlight);box-shadow:0 4px 0 var(--ctrl-warning-shadow),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-warning-highlight),inset 0 -2px 0 var(--ctrl-warning-inset)}.btn-skeuo-neutral{background:var(--ctrl-base);border-color:var(--ctrl-border);color:var(--fg-secondary);box-shadow:0 3px 0 var(--ctrl-shadow-dark),0 6px 16px var(--ctrl-shadow-mid),0 2px 6px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.btn-skeuo-neutral:hover{background:var(--ctrl-base-hover);color:var(--fg-primary);box-shadow:0 4px 0 var(--ctrl-shadow-dark),0 8px 20px var(--ctrl-shadow-mid),0 3px 8px var(--ctrl-shadow-dark),inset 0 1px 0 var(--ctrl-highlight),inset 0 -2px 0 var(--ctrl-inset)}.control-card{border-radius:var(--radius-lg);background-color:var(--default-tint);padding:1rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.control-card{background-color:color-mix(in srgb,var(--default-tint)var(--default-bg-opacity),transparent)}}.control-card{-webkit-backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));backdrop-filter:blur(var(--default-blur))brightness(var(--default-brightness));box-shadow:inset 0 0 0 1px var(--default-light),inset 1.8px 3px 0 -2px var(--default-light),inset -2px -2px 0 -2px var(--default-light),inset -3px -8px 1px -6px var(--default-light),inset -.3px -1px 4px 0 var(--default-dark),inset 0 3px 4px -2px var(--default-dark)}@supports (color:color-mix(in lab,red,red)){.control-card{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*10%),transparent),inset 1.8px 3px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*70%),transparent),inset -2px -2px 0 -2px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*50%),transparent),inset -3px -8px 1px -6px color-mix(in srgb,var(--default-light)calc(var(--default-reflex-light)*40%),transparent),inset -.3px -1px 4px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*8%),transparent),inset 0 3px 4px -2px color-mix(in srgb,var(--default-dark)calc(var(--default-reflex-dark)*12%),transparent)}}.control-card:before{content:"";pointer-events:none;border-radius:inherit;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom);position:absolute;top:0;right:0;bottom:0;left:0}.control-card-header{justify-content:space-between;align-items:center;margin-bottom:.75rem;display:flex}.control-card-label{color:var(--fg-muted);font-size:.8125rem}.control-card-value{font-size:.8125rem;font-weight:600}.control-card-value-active{color:var(--sys-green)}.control-card-value-inactive{color:var(--fg-muted)}.btn-skeuo-icon{stroke-width:2.5px;width:1.125rem;height:1.125rem}.btn-terminal{width:100%;color:var(--tui-accent,#ff8c00);border:1px solid var(--tui-disabled,#333);cursor:pointer;background:0 0;border-radius:0;justify-content:center;align-items:center;gap:.5rem;padding:.5rem 1rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875rem;font-weight:500;line-height:1.25rem;transition:background-color .1s,border-color .1s;display:inline-flex}.btn-terminal:hover{background:var(--tui-hover-bg,#1a1f2e);border-color:var(--tui-accent,#ff8c00)}.btn-terminal:active{background:var(--tui-accent,#ff8c00);color:#0c0c0c}.btn-terminal:disabled{opacity:.3;cursor:not-allowed}.btn-terminal:disabled:hover{border-color:var(--tui-disabled,#333);background:0 0}.btn-terminal--danger{color:var(--sys-red)}.btn-terminal--danger:hover{border-color:var(--sys-red)}.btn-terminal--danger:active{background:var(--sys-red);color:#0c0c0c}.btn-terminal--muted{color:#666}.btn-terminal--muted:hover{color:#ccc;border-color:#666}.well-icon-btn{cursor:pointer;-webkit-tap-highlight-color:transparent;background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;border-radius:4px;outline:none;justify-content:center;align-items:center;padding:5px;transition:box-shadow 60ms;display:inline-flex;box-shadow:inset 0 3px 5px #000000e6,inset 0 1px 1px #000000b3,inset 0 -1px 2px #ffffff0a}.well-icon-btn:hover{box-shadow:inset 0 3px 5px #000000e6,inset 0 1px 1px #000000b3,inset 0 -1px 2px #ffffff0f}.well-icon-btn:active{box-shadow:inset 0 5px 8px #000000f2,inset 0 2px 3px #000c,inset 0 -1px 1px #ffffff05}.well-icon-btn svg{stroke-width:2px;width:14px;height:14px;transition:opacity 80ms}.well-icon-btn:hover svg{opacity:1}.well-icon-btn--amber svg{color:var(--tui-accent,#ff8c00);opacity:.7}.well-icon-btn--amber:hover svg{color:#ffa540}.well-icon-btn--amber:active svg{color:#ffd080}.well-icon-btn--danger svg{color:var(--sys-red);opacity:.7}.well-icon-btn--danger:hover svg{color:#ff6b6b}.well-icon-btn--danger:active svg{color:#ff9090}.keycap-group{align-items:stretch;gap:4px;width:100%;display:flex}.keycap-btn{--keycap-bevel-light:#82838d80;--keycap-bevel-dark:#2a243280;cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;background:0 0;border:none;outline:none;flex-shrink:0;justify-content:center;align-items:center;margin:0;padding:0;display:flex}.keycap-btn--red-cap{--keycap-bevel-light:#a53a3a8c;--keycap-bevel-dark:#2d121280}.keycap-well{background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border-radius:6px;flex-shrink:0;padding:4px;display:inline-flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}.keycap-well--tight{padding:2px}.keycap-well--rounded{border-radius:var(--radius-lg)}.keycap-well--fill{flex:1;min-width:0}.header-well{align-items:center;gap:var(--tui-header-gap,4px);padding:var(--tui-header-padding,4px);border-radius:var(--tui-header-radius,12px);background:linear-gradient(#050505,#0a0a0a,#0c0c0c);flex-shrink:0;display:inline-flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}@media(min-width:640px){.header-well{height:var(--tui-header-height,64px)}}.keycap-wrap{transition:transform 40ms cubic-bezier(0,0,0,1);display:inline-flex;position:relative}.keycap-btn__img{height:calc(var(--tui-header-height,52px) - 8px);pointer-events:none;width:auto;transition:filter 40ms cubic-bezier(0,0,0,1);display:block}[data-mode=light] .keycap-btn{--keycap-bevel-light:#c8c8d2b3;--keycap-bevel-dark:#504e5a99}[data-mode=light] .keycap-btn--red-cap{--keycap-bevel-light:#dc8c8cb3;--keycap-bevel-dark:#64282899}[data-mode=light] .keycap-btn--red-cap .keycap-btn__img{filter:brightness(1.6)contrast(.7)saturate(1.15)drop-shadow(0 4px 6px #00000059)drop-shadow(0 2px 3px #0003)}[data-mode=light] .keycap-btn__img{filter:brightness(1.8)contrast(.7)saturate(.8)drop-shadow(0 4px 6px #00000059)drop-shadow(0 2px 3px #0003)}[data-mode=light] .keycap-btn:hover .keycap-btn__img{filter:brightness(1.95)contrast(.7)saturate(.8)drop-shadow(0 6px 10px #00000059)drop-shadow(0 3px 4px #0003)}[data-mode=light] .keycap-btn--pressed .keycap-btn__img{filter:brightness(1.5)contrast(.7)saturate(.8)drop-shadow(0 1px 2px #00000040)}.keycap-btn:hover .keycap-btn__img{filter:brightness(1.15)}.keycap-btn--pressed .keycap-wrap{transform:translateY(2px)scale(.97)}.keycap-btn--pressed .keycap-btn__img{filter:brightness(.75)}.keycap-btn--pressed .keycap-well{box-shadow:inset 0 5px 8px #000000f2,inset 0 2px 3px #000c,inset 0 -1px 1px #ffffff05}.keycap-btn--pressed:hover .keycap-btn__img{filter:brightness(.75)}.keycap-btn:disabled{cursor:not-allowed}.keycap-btn:disabled:hover .keycap-btn__img{filter:none}.keycap-icon-overlay{pointer-events:none;width:36%;height:42%;filter:drop-shadow(0 1.25px 0 var(--keycap-bevel-light))drop-shadow(0 -1px 0 var(--keycap-bevel-dark));justify-content:center;align-items:center;transition:color 60ms;display:flex;position:absolute;top:calc(44% - 2px);left:50%;transform:translate(-50%,-50%)}.keycap-icon-overlay svg{width:100%;height:100%}.keycap-btn:hover .keycap-icon-overlay{color:#ffdeb0}.keycap-wifi{pointer-events:none;width:36%;height:42%;filter:drop-shadow(0 1.5px 0 var(--keycap-bevel-light))drop-shadow(0 -.5px 0 var(--keycap-bevel-dark));position:absolute;top:calc(44% - 2px);left:50%;transform:translate(-50%,-50%)}.keycap-wifi--active{filter:drop-shadow(0 0 1.5px #ffdeb059)}@keyframes keycap-wifi-sweep{0%{stroke:#000}12%{stroke:#ffdeb0}28%{stroke:#ffdeb0}30%{stroke:#000}to{stroke:#000}}.keycap-wifi-arc{animation:1.8s step-end infinite keycap-wifi-sweep}.keycap-wifi-arc-1{animation-delay:0s}.keycap-wifi-arc-2{animation-delay:.45s}.keycap-wifi-arc-3{animation-delay:.9s}@keyframes keycap-wifi-blink-all{0%{stroke:#ffdeb0}70%{stroke:#ffdeb0}71%{stroke:#000}to{stroke:#000}}.keycap-wifi-blink-all{animation:.5s step-end forwards keycap-wifi-blink-all}.indicator-key-pair{flex:1;align-self:stretch;gap:4px;min-width:0;display:flex}.indicator-key{border-radius:calc(var(--tui-header-radius,12px) - 2px);background:#111;border:none;flex-direction:column;flex:1;justify-content:center;align-items:flex-start;gap:4px;min-width:0;padding:6px 10px 8px;display:flex}@media(min-width:640px){.indicator-key{gap:6px;padding:8px 12px 10px}}.indicator-key__label{letter-spacing:1.5px;color:#666;text-shadow:0 1px #ffffff0f;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.6875rem;font-weight:400}.indicator-key__led{width:22px;height:5px;box-shadow:none;background:#1a1a1a;border-radius:1px;display:block}[data-mode=light] .indicator-key{background:linear-gradient(135deg,#71717a,#a1a1aa);box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}[data-mode=light] .indicator-key__label{color:#d4d4d8;text-shadow:none;font-weight:600}[data-mode=light] .indicator-key__led{background:#333}.indicator-key--sending .indicator-key__led{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);animation:.6s step-end infinite led-blink;box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}@keyframes led-blink{0%{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}50%{box-shadow:none;background:#1a1a1a}}.indicator-key--sent .indicator-key__led{background:linear-gradient(#3d9a50,#52b862 40%,#46a758);animation:none;box-shadow:inset 0 1px 1px #82e69633,inset 0 -.5px .5px #143c194d}.indicator-key--active .indicator-key__led{background:linear-gradient(#e8a020,#ffb030 40%,#ff8c00);animation:none;box-shadow:inset 0 1px 1px #ffd26440,inset 0 -.5px .5px #783c004d}[data-mode=light] .indicator-key--active .indicator-key__led,[data-mode=light] .indicator-key--sending .indicator-key__led{background:#ffb020;box-shadow:0 0 8px #ffb42880,0 0 3px #ffc83c66}[data-mode=light] .indicator-key--sent .indicator-key__led{background:#4ade60;box-shadow:0 0 8px #50dc6480,0 0 3px #64f07866}.mini-widget{gap:.25rem;padding:.75rem}.mini-widget-header{align-items:center;gap:.375rem;min-height:1.25rem;display:flex}.mini-widget-icon{width:1rem;height:1rem;color:var(--icon-widget);flex-shrink:0}.mini-widget-title{font-family:Poppins,sans-serif;font-size:var(--text-xs);color:var(--fg-muted);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;text-overflow:ellipsis;font-weight:500;line-height:1.2;overflow:hidden}.mini-widget-value{font-family:var(--font-data);font-size:var(--text-xl);color:var(--fg-primary);font-weight:600;line-height:1.1}.mini-widget-value-lg{font-size:var(--text-2xl)}.mini-widget-value-sm{font-size:var(--text-lg)}.mini-widget-unit{font-size:var(--text-xs);color:var(--fg-muted);margin-left:.125rem;font-weight:400}.mini-widget-subtitle{font-family:var(--font-data);font-size:var(--text-sm);color:var(--fg-muted);white-space:nowrap;text-overflow:ellipsis;line-height:1.3;overflow:hidden}.mini-widget-status-dot{border-radius:50%;flex-shrink:0;width:.5rem;height:.5rem}.mini-widget-status-dot.excellent{background:var(--signal-excellent)}.mini-widget-status-dot.good{background:var(--signal-good)}.mini-widget-status-dot.fair{background:var(--signal-fair)}.mini-widget-status-dot.poor{background:var(--signal-poor)}.mini-widget-status-dot.critical{background:var(--signal-critical)}.mini-widget-status-dot.unknown{background:var(--signal-unknown)}.mini-widget-trend{font-size:var(--text-xs);align-items:center;gap:.125rem;font-weight:500;display:flex}.mini-widget-trend.up{color:var(--sys-red)}.mini-widget-trend.down{color:var(--sys-green)}.mini-widget-trend.stable{color:var(--fg-muted)}.mini-widget-sparkline{width:100%;min-width:1px;height:1.5rem;min-height:1px;margin-top:auto}.mini-widget-loading{justify-content:center;align-items:center;min-height:4rem;display:flex}.mini-widget-loading-spinner{border:2px solid var(--edge-subtle);border-top-color:var(--sys-blue);border-radius:50%;width:1rem;height:1rem;animation:.8s linear infinite spin}.mini-widget-error{min-height:4rem;color:var(--fg-muted);font-size:var(--text-sm);justify-content:center;align-items:center;display:flex}.mini-widget-progress{background:var(--subtle);border-radius:.125rem;height:.25rem;margin-top:auto;overflow:hidden}.mini-widget-progress-bar{border-radius:.125rem;height:100%;transition:width .3s}.mini-widget-progress-bar.excellent{background:var(--signal-excellent)}.mini-widget-progress-bar.good{background:var(--signal-good)}.mini-widget-progress-bar.fair{background:var(--signal-fair)}.mini-widget-progress-bar.poor{background:var(--signal-poor)}.mini-widget-progress-bar.critical{background:var(--signal-critical)}.mini-widget-toggle{align-items:center;gap:.5rem;display:flex}.mini-widget-toggle-track{background:var(--subtle);border:1px solid var(--edge-subtle);cursor:pointer;border-radius:.5rem;width:2rem;height:1rem;transition:all .2s;position:relative}.mini-widget-toggle-track.active{background:var(--sys-green);border-color:var(--sys-green)}.mini-widget-toggle-thumb{background:#fff;border-radius:50%;width:.75rem;height:.75rem;transition:left .2s;position:absolute;top:50%;left:.125rem;transform:translateY(-50%)}.mini-widget-toggle-track.active .mini-widget-toggle-thumb{left:calc(100% - .875rem)}.mesh-health-container{margin-bottom:1rem}@media(min-width:640px){.mesh-health-container{margin-bottom:1.5rem}}.mesh-health-header{align-items:center;gap:.375rem;margin-bottom:.5rem;display:flex}@media(min-width:640px){.mesh-health-header{gap:.5rem;margin-bottom:.75rem}}.widget-row{gap:.5rem;display:grid}@media(min-width:640px){.widget-row{gap:.75rem}}@media(min-width:768px){.widget-row{grid-template-columns:repeat(3,1fr)}.mini-widget{height:7.5rem}}@media(max-width:767px){.widget-row{grid-template-columns:repeat(2,1fr)}.mini-widget{min-height:5.5rem;padding:.5rem;overflow:hidden}.mini-widget-header{gap:.25rem;min-height:1rem}.mini-widget-icon{width:.75rem;height:.75rem}.mini-widget-title{font-size:.5625rem}.mini-widget-value{font-size:var(--text-base);line-height:1}.mini-widget-value-lg{font-size:var(--text-lg)}.mini-widget-value-sm{font-size:var(--text-base)}.mini-widget-unit{font-size:.625rem}.mini-widget-subtitle{font-size:.625rem;line-height:1.2}.mini-widget-sparkline{display:none}.mini-widget-progress{margin-top:.25rem}}.mini-widget-value.excellent{color:var(--signal-excellent)}.mini-widget-value.good{color:var(--signal-good)}.mini-widget-value.fair{color:var(--signal-fair)}.mini-widget-value.poor{color:var(--signal-poor)}.mini-widget-value.critical{color:var(--signal-critical)}.data-box{border-radius:var(--radius-sm);background:var(--data-box-bg);border:1px solid var(--data-box-border);font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);--data-box-color:var(--fg-primary);color:var(--data-box-color);letter-spacing:-.03em;font-variant-numeric:tabular-nums;font-feature-settings:"zero","tnum";white-space:nowrap;text-overflow:ellipsis;justify-content:center;align-items:center;min-width:0;padding:.25rem .5rem;line-height:1.2;display:inline-flex;overflow:hidden}.data-box-compact,.data-box-responsive{font-size:var(--text-xs);border-radius:var(--radius-xs);padding:.125rem .375rem}@media(min-width:640px){.data-box-responsive{font-size:var(--text-sm);border-radius:var(--radius-sm);padding:.25rem .5rem}}.data-box-hug{width:auto}.data-box-fill{width:100%;display:flex}.data-box-left{justify-content:flex-start}.data-box-center{justify-content:center}.data-box-right{justify-content:flex-end}.data-box-outlined{background:var(--data-box-accent)}@supports (color:color-mix(in lab,red,red)){.data-box-outlined{background:color-mix(in srgb,var(--data-box-accent)10%,transparent)}}.data-box-outlined{border:1.5px solid var(--data-box-accent);color:var(--data-box-accent);font-weight:650}.data-box-compact.data-box-outlined{border-width:1.5px}.data-box-label{font-family:var(--font-data);font-size:var(--text-sm);font-weight:var(--font-normal);color:var(--fg-muted);margin-bottom:.25rem;line-height:1.3}.input-base{border-radius:var(--radius-md);background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);width:100%;color:var(--fg-primary);transition:border-color var(--duration-fast)var(--ease-out),box-shadow var(--duration-fast)var(--ease-out);padding:.625rem .875rem;font-size:.875rem;line-height:1.5}.input-base::placeholder{color:var(--fg-muted)}.input-base:focus{border-color:var(--sys-blue);box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-base:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.input-base:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.input-compact{padding:.375rem .625rem;font-size:.8125rem}.input-error{border-color:var(--sys-red)}.input-error:focus{box-shadow:0 0 0 var(--ring-width-default) var(--sys-red)}@supports (color:color-mix(in lab,red,red)){.input-error:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-red)25%,transparent)}}.input-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-md);background-color:var(--input-bg);border:var(--stroke-thin)solid var(--input-border);width:100%;color:var(--fg-primary);cursor:pointer;transition:border-color var(--duration-fast)var(--ease-out);padding:.625rem 2.5rem .625rem .875rem;font-size:.875rem}.input-select:focus{border-color:var(--sys-blue);box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-select:focus{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.input-group{align-items:center;display:flex;position:relative}.input-group-icon{pointer-events:none;color:var(--fg-muted);width:1rem;height:1rem;position:absolute;left:.75rem}.input-group .input-base{padding-left:2.25rem}.input-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:var(--radius-xs);background-color:var(--surface-tint-light);border:var(--stroke-thin)solid var(--edge-subtle);cursor:pointer;width:1rem;height:1rem;transition:background-color var(--duration-fast)var(--ease-out),border-color var(--duration-fast)var(--ease-out)}.input-checkbox:checked{background-color:var(--sys-blue);border-color:var(--sys-blue)}.input-checkbox:focus-visible{box-shadow:0 0 0 var(--ring-width-default) var(--sys-blue);outline:none}@supports (color:color-mix(in lab,red,red)){.input-checkbox:focus-visible{box-shadow:0 0 0 var(--ring-width-default) color-mix(in srgb,var(--sys-blue)25%,transparent)}}.toggle-switch-track{cursor:pointer;background-color:var(--bg-1);border-radius:9999px;align-items:center;transition:background-color .2s,box-shadow .2s;display:inline-flex;position:relative;box-shadow:inset 3px 3px 6px #0009,inset -3px -3px 6px #ffffff0d,inset 0 1px 2px #0006,inset 0 -1px 1px #ffffff0a}[data-mode=light] .toggle-switch-track{background-color:#ebedef;box-shadow:inset 3px 3px 6px #0000001f,inset -3px -3px 6px #00000003,inset 0 1px 2px #00000014,inset 0 -1px 1px #00000002}.toggle-switch-track:disabled{opacity:.5;cursor:not-allowed}.toggle-switch-thumb{background:linear-gradient(145deg,#f5f5f5,#e0e0e0);border-radius:9999px;justify-content:center;align-items:center;transition:transform .2s;display:inline-flex;position:relative;box-shadow:2px 2px 4px #0000004d,-1px -1px 3px #ffffff26}[data-mode=light] .toggle-switch-thumb{background:linear-gradient(145deg,#fff,#f7f7f7);box-shadow:3px 3px 6px #00000014,-2px -2px 5px #fffc}.toggle-switch-dot{background-color:#22c55e;border-radius:9999px;transition:opacity .2s,background-color .2s;box-shadow:inset 0 1px 2px #0000004d,inset 0 -.5px 1px #fff3}[data-mode=light] .toggle-switch-dot{background-color:#10b981}.toggle-switch-dot-danger{background-color:#ef4444}[data-mode=light] .toggle-switch-dot-danger{background-color:#dc2626}.toggle-switch-track[data-size=sm]{width:2.25rem;height:1.25rem}.toggle-switch-track[data-size=sm] .toggle-switch-thumb{width:.875rem;height:.875rem}.toggle-switch-track[data-size=sm] .toggle-switch-dot{width:.5rem;height:.5rem}.toggle-switch-track[data-size=md]{width:2.75rem;height:1.5rem}.toggle-switch-track[data-size=md] .toggle-switch-thumb{width:1rem;height:1rem}.toggle-switch-track[data-size=md] .toggle-switch-dot{width:.625rem;height:.625rem}.toggle-switch-track[data-size=lg]{width:3.5rem;height:1.75rem}.toggle-switch-track[data-size=lg] .toggle-switch-thumb{width:1.25rem;height:1.25rem}.toggle-switch-track[data-size=lg] .toggle-switch-dot{width:.75rem;height:.75rem}input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}input:focus-visible{box-shadow:0 0 0 2px var(--sys-blue);outline:none}select{background-image:none}.terminal-card{height:calc(100dvh - 132px);min-height:280px;max-height:calc(100vh - 100px);padding-bottom:env(safe-area-inset-bottom,0)}@media(min-width:640px){.terminal-card{height:calc(100dvh - 160px);min-height:400px}}@media(min-width:1024px){.terminal-card{height:calc(100vh - 120px);min-height:500px}}.terminal-ascii{letter-spacing:-.5px;font-size:8px}@media(min-width:375px){.terminal-ascii{letter-spacing:0;font-size:9px}}@media(min-width:414px){.terminal-ascii{font-size:10px}}@media(min-width:640px){.terminal-ascii{font-size:11px}}@media(min-width:768px){.terminal-ascii{font-size:12px}}@media(min-width:1024px){.terminal-ascii{font-size:13px}}@supports (-webkit-touch-callout:none){.terminal-card input{font-size:16px}}.terminal-card>div:first-child{-webkit-overflow-scrolling:touch;overscroll-behavior:contain}.terminal-gutter{padding:8px}@media(min-width:640px){.terminal-gutter{padding:16px}}.terminal-gutter .xterm{height:100%}.terminal-gutter .xterm-viewport{-webkit-overflow-scrolling:touch;overscroll-behavior:contain;overscroll-behavior-y:contain;overflow-y:auto!important}.terminal-gutter .xterm-screen{overflow:hidden}@media(max-width:639px){.terminal-gutter{touch-action:pan-y}.terminal-gutter .xterm-viewport{scroll-behavior:smooth}}[data-mode=light] .terminal-gutter{background:#eff0f1}[data-mode=light] .terminal-gutter .xterm-viewport{background:#eff0f1!important}.terminal-completions{font-family:JetBrains Mono,IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:13px;line-height:1.375}@media(max-width:639px){.terminal-completions{font-size:14px}.terminal-completions .overflow-y-auto{max-height:200px!important}}.terminal-ac-option{cursor:pointer;align-items:baseline;gap:.5rem;padding:.625rem .75rem;transition:background-color .1s;display:flex}@media(min-width:640px){.terminal-ac-option{padding:.25rem .75rem}}.terminal-ac-option__indicator{text-align:center;width:.75rem;color:var(--sys-blue);opacity:.8;flex-shrink:0}.terminal-ac-option__cmd{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.terminal-ac-option__desc{color:var(--fg-muted);flex-shrink:0;padding-left:.75rem;font-size:.6875rem}@media(max-width:359px){.terminal-ac-option__desc{display:none}}.terminal-ac-hints{color:var(--fg-muted);border-top:1px solid var(--terminal-border);justify-content:space-between;align-items:center;padding:.375rem .75rem;font-size:.6875rem;display:flex}@media(max-width:639px){.terminal-ac-hints{padding:.5rem .75rem;font-size:.75rem}}.terminal-mobile-input-bar{background:var(--terminal-bg-input,#0a0a0a);border-top:1px solid var(--terminal-border);align-items:center;gap:.5rem;padding:.5rem .75rem;display:flex}.terminal-mobile-input{min-width:0;color:var(--tui-body,#fff);border-radius:var(--radius-md);caret-color:var(--tui-accent,#ff8c00);background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;outline:none;flex:1;padding:.625rem .75rem;font-family:JetBrains Mono,IBM Plex Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:16px;line-height:1.25;box-shadow:inset 0 2px 4px #000000e6,inset 0 -1px #ffffff0a}.terminal-mobile-input::placeholder{color:var(--tui-placeholder,#666)}.terminal-mobile-input:focus{box-shadow:inset 0 2px 4px #000000e6,inset 0 -1px #ffffff0a,0 0 0 2px #3b82f64d}[data-mode=light] .terminal-mobile-input-bar{background:#dadde2}[data-mode=light] .terminal-mobile-input{color:var(--tui-body,#111);caret-color:#2a2d30;background:#eff0f1;box-shadow:inset 0 2px 4px #00000014,inset 0 -1px #ffffff80}[data-mode=light] .terminal-mobile-input::placeholder{color:#95999e}[data-mode=light] .terminal-mobile-input:focus{box-shadow:inset 0 2px 4px #00000014,inset 0 -1px #ffffff80,0 0 0 2px #3b82f640}.terminal-send-btn{border-radius:var(--radius-md);width:44px;height:44px;color:var(--tui-accent,#ff8c00);cursor:pointer;-webkit-tap-highlight-color:transparent;background:linear-gradient(#050505,#0a0a0a,#0c0c0c);border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;transition:background-color .1s,transform 50ms;display:flex;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}.terminal-send-btn:active{transform:scale(.95);box-shadow:inset 0 3px 6px #000000e6,inset 0 -1px #ffffff05}.terminal-send-btn svg{stroke-width:2px;width:20px;height:20px}[data-mode=light] .terminal-send-btn{color:#fff;background:linear-gradient(135deg,#71717a,#a1a1aa);box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}.terminal-status-bar{color:var(--fg-muted);border-top:1px solid var(--terminal-border);justify-content:space-between;align-items:center;padding:.375rem .75rem;font-size:.6875rem;display:flex}@media(min-width:640px){.terminal-status-bar{padding:.25rem 1rem;font-size:.75rem}}.terminal-tap-hint{color:var(--fg-muted);opacity:.7;align-items:center;gap:.25rem;display:flex}.terminal-tap-hint svg{width:12px;height:12px}.seven-seg{vertical-align:middle;flex-shrink:1;align-items:center;gap:4px;min-width:0;line-height:1;display:inline-flex;transform:skew(-8deg)}.seven-seg__char{flex-shrink:0;display:block;overflow:visible}.seven-seg-panel{color:#ff8c00;height:var(--tui-header-height,52px);border-radius:var(--radius-md);background:#000;flex-shrink:1;align-items:center;min-width:0;padding:0 12px;display:inline-flex;overflow:hidden;box-shadow:inset 0 1px 3px #0009,inset 0 -1px 1px #ffffff08,0 1px #ffffff0d}@media(min-width:640px){.seven-seg-panel{padding:0 16px}}[data-mode=light] .seven-seg-panel{color:#18181b;border-radius:var(--radius-lg);background:linear-gradient(135deg,#52525b,#71717a);border:none;padding:8px 16px;position:relative;overflow:visible;box-shadow:inset 1px 1px #ffffff26,inset -1px -1px #0003}@media(min-width:640px){[data-mode=light] .seven-seg-panel{padding:12px 28px}}[data-mode=light] .seven-seg-panel:before{content:"";z-index:0;background:#d0d3d8;border-radius:0;position:absolute;top:8px;right:8px;bottom:8px;left:8px;box-shadow:inset 0 2px 4px #00000040,inset 0 1px 1px #00000026}@media(min-width:640px){[data-mode=light] .seven-seg-panel:before{top:12px;right:12px;bottom:12px;left:12px}}[data-mode=light] .seven-seg-panel .seven-seg{z-index:1;position:relative}[data-mode=light] .seven-seg-panel:after{content:"";pointer-events:none;z-index:2;background:linear-gradient(135deg,#ffffff59,#ffffff14 40%,#0000 60%);border-radius:0;position:absolute;top:8px;right:8px;bottom:8px;left:8px}@media(min-width:640px){[data-mode=light] .seven-seg-panel:after{top:12px;right:12px;bottom:12px;left:12px}}@keyframes flash-white-fade{0%{opacity:.2}to{opacity:0}}.flash-overlay{border-radius:inherit;pointer-events:none;z-index:50;background-color:#7c6ef6;animation:.6s ease-out forwards flash-white-fade;position:absolute;top:0;right:0;bottom:0;left:0}@keyframes flash-row-bg{0%{background-color:#7c6ef62e}to{background-color:#0000}}.flash-row{animation:.6s ease-out forwards flash-row-bg}@keyframes flash-icon-pulse{0%{color:#fff;filter:drop-shadow(0 0 6px #fffc)}to{color:var(--fg-muted);filter:none}}.flash-icon{animation:.6s ease-out forwards flash-icon-pulse}@keyframes pulse-slow{0%,to{opacity:1}50%{opacity:.4}}.animate-pulse-slow{animation:3s ease-in-out infinite pulse-slow}@keyframes partytime-bg{0%{opacity:0}3%{opacity:1}90%{opacity:1}to{opacity:0}}@keyframes partytime-crt{0%{opacity:1;filter:brightness(4)saturate(0);transform:scaleY(.005)scaleX(.6)}2.5%{opacity:1;filter:brightness(1.5)saturate(.6);transform:scaleY(1.02)scaleX(1)}4%{opacity:1;filter:brightness()saturate();transform:scaleY(1)scaleX(1)}5%{opacity:0}6%{opacity:1}7.5%{opacity:0}8.5%{opacity:1}90%{opacity:1;filter:brightness();transform:scaleY(1)scaleX(1)}94%{opacity:1;filter:brightness(3)saturate(0);transform:scaleY(.005)scaleX(1)}97%{opacity:.8;filter:brightness(5);transform:scaleY(.005)scaleX(.005)}to{opacity:0;transform:scaleY(0)scaleX(0)}}.partytime-scanlines{mix-blend-mode:multiply;background:repeating-linear-gradient(#0000 0,#0000 2px,#0000002e 2px,#0000002e 4px)}.partytime-glow{border-radius:6px;box-shadow:0 0 30px 6px #b4ffe61f,0 0 80px 20px #0009}@keyframes shimmer-border{0%{background-position:200% 0}to{background-position:-200% 0}}.shimmer-border{z-index:1;pointer-events:none;background:linear-gradient(90deg,transparent 0%,transparent 25%,var(--sys-blue)50%,transparent 75%,transparent 100%);border-radius:inherit;opacity:.8;background-size:200% 100%;padding:2px;animation:2s ease-in-out infinite shimmer-border;position:absolute;top:0;right:0;bottom:0;left:0;-webkit-mask-image:linear-gradient(#fff 0 0),linear-gradient(#fff 0 0);mask-image:linear-gradient(#fff 0,#fff 0),linear-gradient(#fff 0,#fff 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}@keyframes shimmer-pulse{0%,to{filter:var(--shimmer-shadow)brightness(1)}50%{filter:var(--shimmer-shadow)brightness(1.5)saturate(1.3)hue-rotate(-20deg)}}@keyframes shimmer-bar{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes sparkle-base{0%{background-position:0%}50%{background-position:100%}to{background-position:0%}}@keyframes sparkle-sweep{0%{transform:translate(-120%)}to{transform:translate(220%)}}.sparkle-bar-track{border-radius:inherit;box-shadow:inset 0 1px 2px #0006}.sparkle-bar-fill{background:linear-gradient(90deg,var(--sys-blue)0%,var(--sys-cyan)30%,var(--sys-indigo)60%,var(--sys-blue)100%);background-size:300% 100%;animation:4s ease-in-out infinite sparkle-base}.sparkle-bar-depth{border-radius:inherit;pointer-events:none;background:linear-gradient(#ffffff8c 0,#ffffff26 2px,#0000 40%,#0000 65%,#00000040);position:absolute;top:0;right:0;bottom:0;left:0}.sparkle-bar-sweep{border-radius:inherit;will-change:transform;pointer-events:none;background:linear-gradient(90deg,#0000,#0000 42%,#ffffff1f 45%,#ffffffa6 49%,#ffffffd9,#ffffffa6 51%,#ffffff1f 55%,#0000 58%,#0000);animation:2.2s cubic-bezier(.4,0,.2,1) infinite sparkle-sweep;position:absolute;top:0;right:0;bottom:0;left:0}@supports (color:color(display-p3 1 1 1)){.sparkle-bar-fill{background:linear-gradient(90deg,#0a84fe,#0089f4,#008ee9 7.5%,#0095d8 15%,#00a1bd 30%,#0093ca 37.5%,#0090ce,#058cd3,#1e87d4,#2b83d5 45%,#4970da,#5b5bde 60%,#4570ee 80%,#337af6 90%,#257ffa,#0a84fe) 0 0/300% 100%;background:linear-gradient(90deg,#0a84fe,color(xyz 0.256 0.245 0.923),color(xyz 0.248 0.252 0.875) 7.5%,color(xyz 0.234 0.266 0.782) 15%,color(xyz 0.209 0.295 0.612) 30%,color(xyz 0.211 0.253 0.637),#2b83d5,#4970da,#5b5bde 60%,#4570ee 80%,#337af6 90%,#257ffa,#0a84fe) 0 0/300% 100%}.sparkle-bar-depth{background:linear-gradient(#fff9,#ffffff2e 2px,#0000 40%,#0000 65%,#0000004d)}.sparkle-bar-sweep{background:linear-gradient(90deg,#0000,#0000 42%,#ffffff26 45%,#ffffffb3 49%,#ffffffe6,#ffffffb3 51%,#ffffff26 55%,#0000 58%,#0000)}}.shimmer-border-light{background:linear-gradient(90deg,#0000,#0000,#fff6,#0000,#0000)}.shimmer-indicator{background:var(--elevated);border-radius:2px;width:40px;height:4px;position:relative;overflow:hidden}.shimmer-indicator-inner{background:linear-gradient(90deg,transparent 0%,var(--sys-blue)50%,transparent 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite shimmer-border;position:absolute;top:0;right:0;bottom:0;left:0}.map-container-16-9{width:100%;height:80dvh;min-height:320px;max-height:900px;position:relative}@media(max-width:639px){.map-container-16-9{width:calc(100% + 2rem);height:70dvh;min-height:280px;max-height:600px;margin-left:-1rem;margin-right:-1rem}.map-container-16-9>div{border-radius:0!important}}@media(min-width:640px)and (max-width:1023px){.map-container-16-9{height:75dvh;max-height:700px}}@media(min-width:1920px){.map-container-16-9{max-height:1000px}}.map-container-fullscreen{width:100vw!important;height:calc(100dvh - 3.5rem)!important;aspect-ratio:unset!important;min-height:unset!important;max-height:unset!important;z-index:999!important;border-radius:0!important;padding-bottom:0!important;position:fixed!important;top:3.5rem!important;right:0!important;bottom:0!important;left:0!important}@media(min-width:1024px){.map-container-fullscreen{height:100dvh!important;top:0!important}}.map-blue-water{position:relative}.map-blue-water .leaflet-tile-pane{filter:sepia(.15)hue-rotate(180deg)saturate(.7)brightness(.95)}.map-blue-water:after{content:"";background:linear-gradient(180deg,var(--map-overlay-blue-dark)0%,var(--map-overlay-blue-light)100%);pointer-events:none;z-index:400;mix-blend-mode:multiply;position:absolute;top:0;right:0;bottom:0;left:0}.map-blue-water .leaflet-marker-pane,.map-blue-water .leaflet-popup-pane,.map-blue-water .leaflet-overlay-pane{filter:none!important}.leaflet-control-attribution{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.leaflet-control-attribution{background:color-mix(in srgb,var(--body)85%,transparent)!important}}.leaflet-control-attribution{color:var(--fg-muted)!important;border-radius:var(--radius-xs)0 0 0!important;padding:2px 6px!important;font-size:10px!important}.leaflet-control-attribution a{color:var(--fg-secondary)!important}.leaflet-control-zoom{overflow:hidden;border-radius:var(--radius-lg)!important;background:var(--body)!important;border:none!important;margin-top:1rem!important;margin-left:1rem!important}@supports (color:color-mix(in lab,red,red)){.leaflet-control-zoom{background:color-mix(in srgb,var(--body)85%,transparent)!important}}.leaflet-control-zoom{-webkit-backdrop-filter:blur(12px);border:1px solid var(--map-border-accent)!important}.leaflet-control-zoom a{color:var(--fg-secondary)!important;border:none!important;border-bottom:1px solid var(--map-border-accent-subtle)!important;background:0 0!important;width:32px!important;height:32px!important;font-size:16px!important;font-weight:500!important;line-height:32px!important}.leaflet-control-zoom a:last-child{border-bottom:none!important}.leaflet-control-zoom a:hover{background:var(--map-hover-tint)!important;color:var(--fg-primary)!important}.leaflet-control-zoom a.leaflet-disabled{opacity:.5;color:var(--fg-muted)!important}.map-dot-marker{background:0 0!important;border:none!important}.map-ring-marker,.map-filled-marker,.map-local-marker{cursor:pointer!important;z-index:500!important;pointer-events:auto!important;background:0 0!important;border:none!important}.leaflet-marker-pane{z-index:600!important;pointer-events:auto!important}.leaflet-marker-pane .leaflet-marker-icon{pointer-events:auto!important}.leaflet-popup-content-wrapper{border-radius:var(--radius-lg)!important;background-color:var(--map-popup-bg)!important;-webkit-backdrop-filter:blur(12px)brightness(.7)saturate(.9)!important;backdrop-filter:blur(12px)brightness(.7)saturate(.9)!important;box-shadow:inset 0 0 0 1px var(--map-hover-tint),var(--map-popup-shadow)!important;border:none!important;padding:0!important;position:relative!important;overflow:hidden!important}.leaflet-popup-content{color:var(--fg-primary)!important;margin:.75rem!important}.leaflet-popup-content strong{color:var(--fg-primary)!important}.leaflet-popup-content hr{border-color:var(--map-border-accent-subtle)!important;margin:.5rem 0!important}.leaflet-popup-tip-container{display:none!important}.leaflet-popup-close-button{color:var(--fg-muted)!important;width:24px!important;height:24px!important;padding:6px!important;font-size:18px!important;top:4px!important;right:4px!important}.leaflet-popup-close-button:hover{color:var(--fg-primary)!important;background:var(--map-hover-tint)!important;border-radius:var(--radius-xs)!important}.leaflet-tooltip{white-space:nowrap;border-radius:var(--radius-md)!important;background-color:var(--body)!important;box-shadow:inset 0 0 0 1px var(--default-border-glow),inset 1.5px 2px 0 -1px var(--default-highlight-tl),inset -1.5px -1.5px 0 -1px var(--default-highlight-br),inset 0 -1px 3px 0 var(--default-shadow-inner)!important;color:var(--fg-primary)!important;border:none!important;padding:.375rem .5rem!important;font-size:11px!important;position:relative!important;overflow:hidden!important}.leaflet-tooltip:after{content:""!important;pointer-events:none!important;border-radius:inherit!important;z-index:999!important;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important;position:absolute!important;top:0!important;right:0!important;bottom:0!important;left:0!important}.leaflet-tooltip:before{display:none!important}.leaflet-tooltip .text-fg-muted{color:var(--fg-muted)!important}.maplibregl-popup{font-family:var(--font-display),system-ui,-apple-system,sans-serif;font-size:var(--text-sm)}.maplibregl-popup-content{min-width:140px;border-radius:var(--radius-lg)!important;background-color:var(--body)!important;box-shadow:inset 0 0 0 1px var(--default-border-glow),inset 1.8px 3px 0 -2px var(--default-highlight-tl),inset -2px -2px 0 -2px var(--default-highlight-br),inset -3px -8px 1px -6px var(--default-highlight-edge),inset -.3px -1px 4px 0 var(--default-shadow-inner),inset 0 3px 4px -2px var(--default-shadow-top)!important;color:var(--fg-primary)!important;border:none!important;padding:.75rem!important;position:relative!important;overflow:hidden!important}.maplibregl-popup-content:after{content:""!important;pointer-events:none!important;border-radius:inherit!important;z-index:999!important;background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important;position:absolute!important;top:0!important;right:0!important;bottom:0!important;left:0!important}.maplibregl-popup-close-button{border-radius:var(--radius-xs);transition:background .1s,color .1s;color:var(--fg-muted)!important;width:24px!important;height:24px!important;padding:6px!important;font-size:18px!important;top:4px!important;right:4px!important}.maplibregl-popup-close-button:hover{color:var(--fg-primary)!important;background:var(--map-hover-tint)!important}.maplibregl-popup-tip{display:none!important}.maplibregl-popup-anchor-bottom .maplibregl-popup-tip{border-top-color:var(--tooltip-bg)!important}.maplibregl-marker.local-node-marker{z-index:10!important}.maplibregl-marker:has(.z-50){z-index:20!important}.maplibregl-popup{z-index:100!important}.maplibregl-ctrl-attrib{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib{background:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib{color:var(--fg-muted)!important;padding:2px 6px!important;font-size:10px!important}.maplibregl-ctrl-attrib a{color:var(--fg-secondary)!important}.maplibregl-ctrl-attrib.maplibregl-compact{background:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib.maplibregl-compact{background:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib.maplibregl-compact{border-radius:var(--radius-xs)!important}.maplibregl-map,.leaflet-container{touch-action:pan-x pan-y;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.maplibregl-ctrl button:focus,.leaflet-control a:focus{outline:2px solid var(--sys-blue);outline-offset:2px}@media(prefers-contrast:high){.maplibregl-ctrl button,.leaflet-control a{border:2px solid!important}.map-legend,.map-controls{border:2px solid var(--fg-primary)!important}}@media(prefers-reduced-motion:reduce){.maplibregl-map,.leaflet-container{transition:none!important}.maplibregl-map *{transition:none!important;animation:none!important}}@-moz-document url-prefix(){.maplibregl-canvas{transform:translateZ(0)}}@supports (-webkit-touch-callout:none){.maplibregl-canvas{will-change:transform;transform:translateZ(0)}}@media(forced-colors:active){.maplibregl-ctrl button,.leaflet-control a{forced-color-adjust:none;color:buttontext!important;background:canvas!important;border:1px solid buttontext!important}.maplibregl-popup-content,.leaflet-popup-content-wrapper{color:canvastext!important;background:canvas!important;border:2px solid canvastext!important}}.maplibregl-ctrl-attrib-button{background-color:var(--body)!important}@supports (color:color-mix(in lab,red,red)){.maplibregl-ctrl-attrib-button{background-color:color-mix(in srgb,var(--body)80%,transparent)!important}}.maplibregl-ctrl-attrib-button{border-radius:var(--radius-xs)!important}.maplibregl-ctrl-group{border-radius:var(--radius-md)!important;background-color:var(--map-ui-bg,var(--surface))!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a)!important;border:none!important;position:relative!important;overflow:hidden!important}.maplibregl-ctrl-group:after{display:none!important}.maplibregl-ctrl-group button{border:none!important;border-bottom:1px solid var(--map-ui-border,var(--edge-subtle))!important;background:0 0!important;width:28px!important;height:28px!important}.maplibregl-ctrl-group button:last-child{border-bottom:none!important}.maplibregl-ctrl-group button:hover{background:var(--map-ui-hover,var(--elevated))!important}.maplibregl-ctrl-group button .maplibregl-ctrl-icon{filter:invert()brightness(.75)}.maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon{filter:invert()brightness()}[data-basemap=light] .maplibregl-ctrl-group button .maplibregl-ctrl-icon{filter:brightness(.3)}[data-basemap=light] .maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon{filter:brightness(.1)}.maplibregl-ctrl-scale{border:1px solid var(--map-local-color)!important;color:var(--map-local-color)!important;font-size:10px!important;font-family:var(--font-data)!important;background:0 0!important;border-top:none!important;border-radius:0!important;padding:2px 6px!important;line-height:1.2!important}.map-control-surface{border-radius:var(--radius-md);background-color:var(--map-ui-bg,var(--surface));color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);position:relative;overflow:hidden}.map-control-surface:after{display:none}.map-control-surface-active{border-radius:var(--radius-md);background-color:var(--map-ui-bg,var(--surface));color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border-strong,var(--edge-strong))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);position:relative;overflow:hidden}.map-control-surface-active:after{display:none}.map-control-surface .text-fg-secondary,.map-control-surface-active .text-fg-secondary,.map-legend-stack .text-fg-secondary{color:var(--map-ui-text-secondary,var(--fg-secondary))}.map-control-surface .text-fg-muted,.map-control-surface-active .text-fg-muted,.map-legend-stack .text-fg-muted{color:var(--map-ui-text-muted,var(--fg-muted))}.map-controls-container{background-color:var(--map-ui-bg,var(--surface));max-width:calc(100vw - 1.5rem);color:var(--map-ui-text,var(--fg-primary));border-radius:var(--radius-md);box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);flex-direction:column;align-items:stretch;gap:0;display:flex;overflow:hidden}.map-controls-row{flex-wrap:wrap;justify-content:flex-end;gap:.25rem;padding:.25rem;display:flex}.map-controls-row+.map-controls-row{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}.map-controls-secondary{flex-wrap:wrap}.map-control-btn{touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;padding:.375rem;transition:background-color .15s}.map-control-btn:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px;border-radius:var(--radius-sm)}@media(hover:hover)and (pointer:fine){.map-control-btn:hover{background-color:var(--map-ui-hover,var(--elevated))}}.map-control-btn:active{background-color:var(--map-ui-active,var(--subtle))}.map-tool-btn{touch-action:manipulation;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}.map-tool-btn:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px}.map-tool-btn:active{filter:brightness(.85)}.map-control-surface button:focus-visible{outline:2px solid var(--sys-blue);outline-offset:-2px}.map-control-icon{width:16px;height:16px}.map-nav-module{padding:.25rem}button[data-tint=warning]{--tint-color:var(--sys-amber)}button[data-tint=success]{--tint-color:var(--sys-green)}button[data-tint=primary]{--tint-color:var(--sys-blue)}.map-control-surface button[data-tint]{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]{background-color:color-mix(in srgb,var(--tint-color)12%,transparent)}}@media(hover:hover)and (pointer:fine){.map-control-surface button[data-tint]:hover{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]:hover{background-color:color-mix(in srgb,var(--tint-color)18%,transparent)}}}.map-control-surface button[data-tint]:active{background-color:var(--tint-color)}@supports (color:color-mix(in lab,red,red)){.map-control-surface button[data-tint]:active{background-color:color-mix(in srgb,var(--tint-color)22%,transparent)}}@media(max-width:639px){.map-controls-container{border-radius:var(--radius-md);max-width:calc(100vw - 1rem)}.map-controls-row{gap:.125rem;padding:.1875rem}.map-control-btn{justify-content:center;align-items:center;min-width:44px;min-height:44px;padding:.625rem;display:flex}.map-control-icon{width:14px;height:14px}.map-control-label{display:none}.map-nav-module{padding:.1875rem}.maplibregl-ctrl-group{border-radius:var(--radius-md)!important}.maplibregl-ctrl-group button{width:28px!important;height:28px!important}.maplibregl-ctrl-group button .maplibregl-ctrl-icon{width:18px!important;height:18px!important}}@media(min-width:640px)and (max-width:1023px){.map-controls-row,.map-nav-module{padding:.25rem}}@media(min-width:1024px){.map-controls-row{gap:.375rem;padding:.375rem}.map-nav-module{padding:.375rem}}.map-legend-stack{z-index:600;background-color:var(--map-ui-bg,var(--surface));max-height:calc(100% - 1.5rem);color:var(--map-ui-text,var(--fg-primary));box-shadow:inset 0 0 0 1px var(--map-ui-stroke,var(--map-ui-border,var(--edge-subtle))),var(--map-ui-shadow,0 2px 8px #00000026,0 4px 16px #0000001a);flex-direction:column;gap:0;display:flex;position:absolute;bottom:.75rem;left:.75rem;border-radius:var(--radius-md)!important;overflow:hidden!important}@media(max-width:639px){.map-legend-stack{width:auto;max-width:calc(100vw - 1.5rem)}}@media(min-width:640px){.map-legend-stack{max-width:160px;bottom:1rem;left:1rem}}.map-legend-stack>*,.map-legend-stack>.map-control-surface{box-shadow:none!important;background-color:#0000!important;border-radius:0!important}.map-legend-stack>*+*{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}.map-legend-stack .map-tool-btn{background-color:var(--map-ui-text,var(--fg-primary))}@supports (color:color-mix(in lab,red,red)){.map-legend-stack .map-tool-btn{background-color:color-mix(in srgb,var(--map-ui-text,var(--fg-primary))4%,transparent)}}.map-legend-stack>.map-tool-row+*{border-top:1.5px solid var(--map-ui-border-strong,var(--edge-strong))!important}.map-tool-row{flex-direction:column;display:flex;overflow:hidden}.map-tool-row>*+*{border-top:1px solid var(--map-ui-border,var(--edge-subtle))}@media(max-width:639px){.map-tool-row{flex-direction:row}.map-tool-row>*+*{border-top:none;border-left:1px solid var(--map-ui-border,var(--edge-subtle))}.map-tool-row .map-tool-btn{justify-content:center;min-width:44px;min-height:44px;padding:.625rem;border-radius:0!important}.map-legend-stack>.map-tool-row>:first-child{border-top-left-radius:var(--radius-md)!important}.map-legend-stack>.map-tool-row>:last-child{border-top-right-radius:var(--radius-md)!important}.map-tool-row .map-tool-btn span:not(.sr-only){display:none}.map-tool-row .map-tool-btn svg{margin:0}}.map-edge-tooltip{z-index:1000;pointer-events:none;max-width:calc(100vw - 2rem);position:absolute;bottom:1rem;left:calc(50% + 85px);transform:translate(-50%)}.map-edge-tooltip-inner{pointer-events:auto;padding:.625rem 1rem}@media(max-width:639px){.map-edge-tooltip{bottom:.5rem;left:.5rem;right:.5rem;transform:none}.map-edge-tooltip-inner{border-radius:var(--radius-lg);background-color:var(--map-ui-bg,var(--body));padding:.75rem}.map-edge-tooltip .w-\[540px\]{width:100%;max-width:100%}}.map-container-fullscreen .map-edge-tooltip{bottom:1.5rem}[data-basemap=light]{--map-edge-rest:#0003;--map-edge-rest-bright:#0000004d;--map-edge-rest-dim:#0000001f;--map-ui-bg:#fff;--map-ui-bg-elevated:#fff;--map-ui-border:#0000001f;--map-ui-border-strong:#0003;--map-ui-text:#1a1a1a;--map-ui-text-secondary:#4a4a4a;--map-ui-text-muted:#737373;--map-ui-hover:#0000000f;--map-ui-active:#0000001a;--map-ui-stroke:#00000059;--map-ui-shadow:0 2px 8px #00000014,0 4px 16px #0000000a;--map-ui-stripe:#0000000a}[data-basemap=dark]{--map-ui-bg:var(--elevated);--map-ui-bg-elevated:var(--elevated);--map-ui-border:var(--edge-subtle);--map-ui-border-strong:var(--edge-strong);--map-ui-text:var(--fg-primary);--map-ui-text-secondary:var(--fg-secondary);--map-ui-text-muted:var(--fg-muted);--map-ui-hover:#ffffff1a;--map-ui-active:#ffffff24;--map-ui-stroke:#ffffff59;--map-ui-shadow:0 2px 10px #00000040,0 6px 20px #0003;--map-ui-stripe:#ffffff0a}[data-basemap] .map-control-surface,[data-basemap] .map-controls-container,[data-basemap] .map-legend-stack,[data-basemap] .map-legend-stack button,[data-basemap] .maplibregl-ctrl-group,[data-basemap] .maplibregl-ctrl-group button,[data-basemap] .maplibregl-popup-content,[data-basemap] .maplibregl-popup-close-button{transition:background-color .3s,color .3s,box-shadow .3s,border-color .3s!important}[data-basemap] .map-control-surface .text-fg-primary,[data-basemap] .map-control-surface .text-fg-secondary,[data-basemap] .map-control-surface .text-fg-muted,[data-basemap] .map-legend-stack .text-fg-primary,[data-basemap] .map-legend-stack .text-fg-secondary,[data-basemap] .map-legend-stack .text-fg-muted,[data-basemap] .maplibregl-popup-content .text-fg-primary,[data-basemap] .maplibregl-popup-content .text-fg-secondary,[data-basemap] .maplibregl-popup-content .text-fg-muted{transition:color .3s!important}[data-basemap] .map-control-surface .border-edge-subtle,[data-basemap] .map-legend-stack>*+*,[data-basemap] .map-controls-row+.map-controls-row{transition:border-color .3s!important}[data-basemap=light] .map-control-surface,[data-basemap=light] .map-controls-container,[data-basemap=light] .map-legend-stack{color:#1a1a1a!important;border-radius:var(--radius-md)!important;background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .map-legend-stack>.map-control-surface{box-shadow:none!important;background-color:#0000!important;border-radius:0!important}[data-basemap=light] .maplibregl-ctrl-group{background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .maplibregl-ctrl-group button{border-bottom-color:#0000001f!important}[data-basemap=light] .maplibregl-ctrl-group button:hover{background-color:#0000000f!important}[data-basemap=light] .map-control-surface .text-fg-secondary,[data-basemap=light] .map-legend-stack .text-fg-secondary{color:#4a4a4a!important}[data-basemap=light] .map-control-surface .text-fg-muted,[data-basemap=light] .map-legend-stack .text-fg-muted{color:#737373!important}[data-basemap=light] .map-control-surface .text-fg-primary,[data-basemap=light] .map-legend-stack .text-fg-primary{color:#1a1a1a!important}[data-basemap=light] .map-control-surface button.text-fg-muted,[data-basemap=light] .map-control-surface [class*=text-fg-muted]{color:#737373!important}[data-basemap=light] .map-control-surface button:hover.text-fg-muted,[data-basemap=light] .map-control-surface button:hover .text-fg-muted{color:#1a1a1a!important}[data-basemap=dark] .map-control-surface button.text-fg-muted,[data-basemap=dark] .map-control-surface [class*=text-fg-muted]{color:var(--fg-secondary)!important}[data-basemap=dark] .map-control-surface button:hover.text-fg-muted,[data-basemap=dark] .map-control-surface button:hover [class*=text-fg-muted]{color:var(--fg-primary)!important}[data-basemap=light] .map-legend-stack>*+*,[data-basemap=light] .map-controls-row+.map-controls-row{border-top-color:#0000001f!important}[data-basemap=light] .map-control-surface .bg-border-subtle{background-color:#0000001f!important}[data-basemap=light] .map-control-surface .border-edge-subtle{border-color:#0000001f!important}[data-basemap=dark] .map-control-surface .border-edge-subtle{border-color:var(--edge-strong)!important}[data-basemap=light] .map-control-surface .surface-inner{box-shadow:inset 0 1px 2px #00000008;background-color:#00000008!important;border-color:#0000000f!important}[data-basemap=light] .map-control-surface .data-box{--data-box-bg:#00000008;--data-box-border:#00000014}[data-basemap=light] .map-control-btn:hover{background-color:#0000000f!important}[data-basemap=light] .map-control-btn:active{background-color:#0000001a!important}[data-basemap=light] .map-control-surface button:hover{color:var(--map-ui-text,#1a1a1a)!important;background-color:#00000014!important}[data-basemap=light] .map-control-surface button:active{color:var(--map-ui-text,#1a1a1a)!important;background-color:#0000001f!important}[data-basemap=dark] .map-control-surface [data-color]:hover{filter:brightness(1.4)}[data-basemap=light] .map-control-surface [data-color]:hover{filter:brightness(.92)}[data-basemap=light] .map-control-surface button[data-tint]{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]{background-color:color-mix(in srgb,var(--tint-color)14%,transparent)!important}}[data-basemap=light] .map-control-surface button[data-tint]:hover{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]:hover{background-color:color-mix(in srgb,var(--tint-color)22%,transparent)!important}}[data-basemap=light] .map-control-surface button[data-tint]:active{background-color:var(--tint-color)!important}@supports (color:color-mix(in lab,red,red)){[data-basemap=light] .map-control-surface button[data-tint]:active{background-color:color-mix(in srgb,var(--tint-color)28%,transparent)!important}}[data-basemap=dark] .maplibregl-popup-content{background-color:var(--body)!important;color:var(--fg-primary)!important;box-shadow:inset 0 0 0 1px var(--map-ui-stroke,#ffffff8c),0 4px 16px #00000040!important}[data-basemap=dark] .maplibregl-popup-content:after{background:var(--default-surface-tint),var(--default-reflection-top),var(--default-reflection-bottom)!important}[data-basemap=dark] .maplibregl-popup-close-button{color:var(--fg-muted)!important}[data-basemap=dark] .maplibregl-popup-close-button:hover{color:var(--fg-primary)!important;background:#ffffff14!important}[data-basemap=light] .maplibregl-popup-content{color:#1a1a1a!important;background-color:#fff!important;box-shadow:inset 0 0 0 1px #00000059,0 2px 8px #00000014,0 4px 16px #0000000a!important}[data-basemap=light] .maplibregl-popup-content:after{display:none!important}[data-basemap=light] .maplibregl-popup-close-button{color:#737373!important}[data-basemap=light] .maplibregl-popup-close-button:hover{color:#1a1a1a!important;background:#0000000f!important}[data-basemap=light] .maplibregl-popup-content .text-fg-primary{color:#1a1a1a!important}[data-basemap=light] .maplibregl-popup-content .text-fg-secondary{color:#4a4a4a!important}[data-basemap=light] .maplibregl-popup-content .text-fg-muted{color:#737373!important}[data-basemap=light] .maplibregl-popup-content .data-box{--data-box-bg:#00000008;--data-box-border:#00000014}[data-basemap=light] .maplibregl-popup-content .surface-badge{background-color:#0000000d!important}[data-basemap=light] .maplibregl-popup-content .bg-subtle-fill-hover{background-color:#0000000a!important}[data-basemap=light] .maplibregl-popup-content button:hover{background-color:#0000000f!important}.border-map-ui-border{border-color:var(--map-ui-border)}@supports (color:color(display-p3 1 1 1)){.signal-bar-active{background-color:var(--p3-color,inherit)}}:root{--zinc-50:#fafafa;--zinc-75:#f7f7f8;--zinc-100:#f4f4f5;--zinc-200:#e4e4e7;--zinc-300:#d4d4d8;--zinc-400:#a1a1aa;--zinc-500:#71717a;--zinc-600:#52525b;--zinc-700:#3f3f46;--zinc-800:#27272a;--zinc-900:#18181b;--zinc-925:#111113;--zinc-950:#09090b;--sys-red:#e5484d;--sys-orange:#f76b15;--sys-amber:#ffb224;--sys-yellow:#f5d90a;--sys-brown:#ad7f58;--sys-green:#46a758;--sys-teal:#12a594;--sys-cyan:#00a2c7;--sys-blue:#3b82f6;--sys-indigo:#5b5bd6;--sys-purple:#8e4ec6;--sys-pink:#d6409f;--body:var(--zinc-950);--surface:var(--zinc-900);--elevated:var(--zinc-800);--subtle:var(--zinc-800);--edge-subtle:var(--zinc-800);--edge-strong:var(--zinc-600);--fg-primary:#fff;--fg-secondary:var(--zinc-400);--fg-muted:var(--zinc-500);--fg-invert:var(--zinc-950);--overlay-soft:#ffffff0a;--shadow-tint:#3b82f659;--sidebar-tint:#27272a80;--tooltip-bg:var(--zinc-800);--tooltip-fg:#fff;--tooltip-border:var(--zinc-800);--tooltip-shadow:0 4px 12px #0006;--hover-tint:#3b82f614;--default-tint:var(--zinc-900);--default-light:var(--zinc-700);--default-dark:var(--zinc-950);--default-reflex-light:0;--default-reflex-dark:0;--default-blur:0px;--default-blur-elevated:0px;--default-brightness:1;--default-surface-tint:linear-gradient(to bottom,#ffffff06,#ffffff04);--default-reflection-top:linear-gradient(to bottom,#ffffff05 0px,transparent 16px);--default-reflection-bottom:linear-gradient(to top,#ffffff05 0px,transparent 20px);--default-border-glow:#ffffff14;--default-highlight-tl:#ffffff1f;--default-highlight-br:#ffffff14;--default-highlight-edge:#ffffff0f;--default-shadow-inner:#00000026;--default-shadow-top:#0000001f;--default-bg-opacity:100%;--default-bg-opacity-elevated:100%;--signal-excellent:var(--sys-green);--signal-good:var(--sys-yellow);--signal-fair:var(--sys-amber);--signal-poor:var(--sys-orange);--signal-critical:var(--sys-red);--signal-unknown:var(--zinc-500);--sparkline-excellent:var(--signal-excellent);--sparkline-good:var(--signal-good);--sparkline-fair:var(--signal-fair);--sparkline-poor:var(--signal-poor);--sparkline-critical:var(--signal-critical);--sparkline-bg:#09090b80;--status-success:var(--sys-green);--status-warning:var(--sys-amber);--status-danger:var(--sys-red);--status-info:var(--sys-blue);--status-muted:var(--zinc-500);--pkt-advert:var(--sys-amber);--pkt-flood:var(--sys-cyan);--pkt-txt-msg:var(--sys-green);--pkt-ack:var(--zinc-500);--pkt-trace:var(--sys-amber);--pkt-req:var(--sys-teal);--pkt-response:var(--sys-pink);--pkt-grp-txt:var(--sys-pink);--pkt-grp-data:var(--sys-red);--pkt-path:var(--sys-amber);--pkt-anon:var(--sys-amber);--pkt-control:var(--sys-indigo);--pkt-unknown:var(--zinc-500);--pkt-science-req:#0090ff;--pkt-science-anon-req:#06c;--pkt-science-response:#6cf;--pkt-science-ack:#00e699;--pkt-science-advert:#fff200;--pkt-science-txt-msg:#ffb300;--pkt-science-grp-txt:#ff80c0;--pkt-science-grp-data:#f60;--pkt-science-multipart:#b3b3b3;--pkt-science-raw-custom:#e666cc;--pkt-science-path:#66b3ff;--pkt-science-trace:#33ffb3;--pkt-science-unknown:gray;--route-flood:var(--sys-blue);--route-direct:var(--sys-amber);--route-transport:var(--zinc-500);--chart-inner:var(--zinc-925);--chart-1:var(--sys-blue);--chart-2:var(--sys-teal);--chart-3:var(--sys-amber);--chart-4:var(--sys-orange);--chart-5:var(--sys-pink);--chart-6:var(--sys-indigo);--chart-7:var(--sys-cyan);--chart-8:var(--zinc-500);--chart-grid:#bfbfbf26;--chart-axis-tick:var(--fg-secondary);--chart-cursor:#fff3;--metric-received:var(--sys-blue);--metric-forwarded:var(--sys-teal);--metric-transmitted:var(--sys-orange);--metric-dropped:var(--sys-red);--metric-neutral:var(--zinc-400);--log-debug:var(--sys-brown);--log-info:var(--sys-cyan);--log-warning:var(--sys-amber);--log-error:var(--sys-red);--log-critical:var(--sys-pink);--icon-page-title:var(--sys-blue);--icon-card-title:var(--sys-blue);--icon-widget:var(--fg-secondary);--icon-action:var(--fg-secondary);--icon-nav:var(--fg-muted);--icon-nav-active:var(--sys-blue);--toggle-on:var(--sys-green);--toggle-off:var(--elevated);--data-box-bg:#ffffff08;--data-box-border:#ffffff0f;--map-node-fill:var(--sys-blue);--map-node-stroke:#ffffffe6;--map-hub-color:var(--sys-indigo);--map-hub-stroke:#ffffffe6;--map-gateway-color:var(--sys-indigo);--map-gateway-stroke:#ffffffd9;--map-local-color:var(--sys-amber);--map-neighbor-color:var(--sys-amber);--map-neighbor-stroke:#0006;--map-mobile-color:var(--sys-orange);--map-room-color:var(--sys-pink);--map-ghost-color:var(--sys-cyan);--map-popup-bg:var(--body)}@supports (color:color-mix(in lab,red,red)){:root{--map-popup-bg:color-mix(in srgb,var(--body)92%,transparent)}}:root{--map-popup-shadow:0 4px 16px #00000080;--map-overlay-blue-dark:#0d1e3226;--map-overlay-blue-light:#14284614;--map-border-accent:#8ca0c833;--map-border-accent-subtle:#8ca0c826;--map-hover-tint:#ffffff1a;--map-edge-rest:#ffffff40;--map-edge-rest-bright:#ffffff59;--map-edge-rest-dim:#ffffff26;--map-edge-hover-direct:var(--sys-cyan);--map-edge-hover-loop:var(--sys-indigo);--map-edge-hover-standard:var(--zinc-400);--map-edge-hover-neighbor:var(--sys-amber);--map-edge-highlight:gold;--link-strong:var(--sys-green);--link-medium:var(--sys-amber);--link-weak:var(--sys-red);--hop-0:var(--sys-cyan);--hop-1:var(--sys-green);--hop-2:var(--sys-teal);--hop-3:var(--sys-amber);--hop-distant:var(--zinc-500);--hop-hub:var(--sys-amber);--palette-bg-0:var(--zinc-950);--palette-bg-1:var(--zinc-900);--palette-bg-2:var(--zinc-800);--palette-bg-3:var(--zinc-700);--palette-bg-4:var(--zinc-600);--palette-bg-5:var(--zinc-500);--palette-bg-6:var(--zinc-400);--palette-bg-7:var(--zinc-300);--palette-fg-0:var(--zinc-500);--palette-fg-1:var(--zinc-400);--palette-fg-2:var(--zinc-300);--palette-fg-3:var(--zinc-200);--palette-fg-4:var(--zinc-50);--palette-red:var(--sys-red);--palette-red-bright:var(--sys-red);--palette-orange:var(--sys-orange);--palette-orange-bright:var(--sys-amber);--palette-yellow:var(--sys-yellow);--palette-yellow-bright:var(--sys-amber);--palette-green:var(--sys-green);--palette-green-bright:var(--sys-teal);--palette-aqua:var(--sys-cyan);--palette-aqua-bright:var(--sys-blue);--palette-blue:var(--sys-blue);--palette-blue-bright:var(--sys-indigo);--palette-purple:var(--sys-purple);--palette-purple-bright:var(--sys-pink);--ctrl-base:var(--palette-bg-4);--ctrl-base-hover:var(--palette-bg-5);--ctrl-base-active:var(--palette-bg-3);--ctrl-border:var(--palette-bg-5);--ctrl-border-hover:var(--palette-bg-6);--ctrl-shadow-dark:var(--palette-bg-1);--ctrl-shadow-mid:var(--palette-bg-0);--ctrl-highlight:var(--palette-bg-6);--ctrl-inset:var(--palette-bg-3);--ctrl-primary:#2563eb;--ctrl-primary-hover:#3b82f6;--ctrl-primary-border:#60a5fa;--ctrl-primary-shadow:#1d4ed8;--ctrl-primary-highlight:#93c5fd;--ctrl-primary-inset:#1e40af;--ctrl-success:#16a34a;--ctrl-success-hover:#22c55e;--ctrl-success-border:#4ade80;--ctrl-success-shadow:#15803d;--ctrl-success-highlight:#86efac;--ctrl-success-inset:#166534;--ctrl-warning:#d97706;--ctrl-warning-hover:#f59e0b;--ctrl-warning-border:#fbbf24;--ctrl-warning-shadow:#b45309;--ctrl-warning-highlight:#fde68a;--ctrl-warning-inset:#92400e;--ctrl-panel-top:var(--palette-bg-2);--ctrl-panel-mid:var(--palette-bg-1);--ctrl-panel-bottom:var(--palette-bg-0);--ctrl-panel-border:var(--palette-bg-4);--subtle-fill:#ffffff08;--subtle-fill-hover:#ffffff0f;--subtle-fill-strong:#ffffff14;--input-bg:#ffffff08;--input-border:#ffffff0f;--theme-transition:.4s ease;--text-xs:.64rem;--text-sm:.8rem;--text-base:1rem;--text-md:1.125rem;--text-lg:1.25rem;--text-xl:1.563rem;--text-2xl:1.953rem;--text-3xl:2.441rem;--text-4xl:3.052rem;--text-5xl:3.815rem;--text-6xl:4.768rem;--leading-tight:1.1;--leading-snug:1.25;--leading-normal:1.5;--leading-relaxed:1.625;--tracking-tight:-.025em;--tracking-normal:0;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--font-normal:400;--font-medium:500;--font-semibold:600;--font-bold:700;--font-extrabold:800}body{background:var(--body);color:var(--fg-secondary);font-family:var(--font-display),system-ui,-apple-system,sans-serif;font-weight:var(--font-normal);font-size:var(--text-base);line-height:var(--leading-normal);letter-spacing:var(--tracking-normal);font-feature-settings:"cv02","cv03","cv04";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;min-height:100vh}.bg-subtle-fill{background:var(--subtle-fill)}.bg-subtle-fill-hover{background:var(--subtle-fill-hover)}.bg-subtle-fill-strong{background:var(--subtle-fill-strong)}.hover\:bg-subtle-fill:hover{background:var(--subtle-fill)}.hover\:bg-subtle-fill-hover:hover{background:var(--subtle-fill-hover)}.hover\:bg-subtle-fill-strong:hover{background:var(--subtle-fill-strong)}.css-label--labels-container{pointer-events:none;z-index:10!important}.css-label--label{font-size:11px;font-family:var(--font-data),monospace;white-space:nowrap;border-radius:3px;padding:2px 6px;font-weight:500;box-shadow:0 1px 3px #0000004d;z-index:11!important;pointer-events:auto!important;text-shadow:none!important;color:#000!important;background:#fff!important}.meshgraph-label-cat-0{background:var(--meshgraph-label-0,#505050)!important;color:#fff!important}.meshgraph-label-cat-1{background:var(--meshgraph-label-1,#707070)!important;color:#fff!important}.meshgraph-label-cat-2{background:var(--meshgraph-label-2,#909090)!important;color:#000!important}.meshgraph-label-cat-3{background:var(--meshgraph-label-3,silver)!important;color:#000!important}.meshgraph-label-cat-4{background:var(--meshgraph-label-4,#fff)!important;color:#000!important}.meshgraph-label-cat-5{background:var(--meshgraph-label-5,#719cdf)!important;color:#fff!important}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}} diff --git a/frontend/dist/assets/index-D7i6lQrq.js b/frontend/dist/assets/index-CkRTgHHA.js similarity index 77% rename from frontend/dist/assets/index-D7i6lQrq.js rename to frontend/dist/assets/index-CkRTgHHA.js index b8eb4c25..8932cbf8 100644 --- a/frontend/dist/assets/index-D7i6lQrq.js +++ b/frontend/dist/assets/index-CkRTgHHA.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-AaBhF2Vi.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-core-FtpmsTnh.js","assets/ascii-burst-CXC_pYgi.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-charts-C916_-gs.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/Dashboard-CyVZY-Lj.js","assets/PageLayout-QhCLxU34.js","assets/consumer-registry-KuOoZhsq.js","assets/AnimatedNumber-Dx2y1t97.js","assets/node-types-CiI69Tya.js","assets/meshcore-tx-constants-BDLT5LMb.js","assets/PacketList-BfWkNwPj.js","assets/primitives-YN2ynYwE.js","assets/payload-decoders-DjZO58V7.js","assets/badge-colors-BxLppqaF.js","assets/chat-utils-DbM_TyxC.js","assets/SignalIndicator-fAt1Aewy.js","assets/usePipelineStore-D3dOwDkO.js","assets/geo-utils-DJn8DnxF.js","assets/DataBox-DpDXI-WX.js","assets/useMapViewStore-1yyjXCM8.js","assets/TimeRangeStepper-B5GfHny9.js","assets/LightSparkline-BAD3v4m9.js","assets/link-scoring-oriFkjrN.js","assets/NodeInformationCard-68hFKJ-B.js","assets/ChatBubble-BkCCRzh5.js","assets/Grid-m53vqd2Y.js","assets/Packets-BgwWZIr7.js","assets/AnalyzerFilterPanel-DfkXd7UH.js","assets/Contacts-Dlk8XXyy.js","assets/ping-5xLx9WS1.js","assets/listbox-BG13Q7Di.js","assets/CollisionExplorerModal-B2vZL8RO.js","assets/BasemapLayer-CSqjQAiA.js","assets/ConfirmModal-XwU3yUZY.js","assets/maplibre-gl-B1CfjdFi.css","assets/Statistics-CvVaUNEa.js","assets/easing-GXZYrvDD.js","assets/MeshGraph-DIhPFkau.js","assets/DeepAnalysisModal-Ca6cBH6E.js","assets/System-ClKsjWUq.js","assets/Logs-0I5VPDkH.js","assets/Terminal-Bhtd_bQn.js","assets/xterm-WPd9ZkSt.js","assets/system-Circh3O5.js","assets/KeycapButton-B1_-eSeA.js","assets/keycap-sfx-Bpx9zhkt.js","assets/xterm-6GBZ9nXN.css","assets/Configuration-BqjgQq_Y.js","assets/RoomServer-COraO77j.js","assets/PacketObservatory-ChFmVrLE.js","assets/Sessions-C8xhZKXf.js"])))=>i.map(i=>d[i]); -var e,t,a,n=Object.defineProperty,r=(e,t,a)=>((e,t,a)=>t in e?n(e,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[t]=a)(e,"symbol"!=typeof t?t+"":t,a);import{r as s,j as o,c as i,L as l,h as c,z as d,Q as u,y as h,x as m,X as g,d as p,a as f,W as b,t as y,Z as w,M as C,K as k,e as v}from"./vendor-react-alRNW2nb.js";import{u as D}from"./vendor-charts-C916_-gs.js";import{_ as A}from"./cosmograph-DqYT4sUA.js";import{L as x,c as E,a as F,u as B,b as j,R as S,d as M,N,B as L}from"./vendor-core-FtpmsTnh.js";import{A as T,m as _,L as R}from"./vendor-motion-DNp0Qg4F.js";import{M as z,X as P,C as I,I as $,L as q,a as O,b as H,T as W,E as U,S as V,c as G,d as J,e as K,f as X,g as Y,h as Q,i as Z,j as ee,W as te,G as ae,F as ne,k as re,l as se,P as oe,m as ie,n as le,U as ce,R as de,o as ue,p as he}from"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";import"./vendor-virt-BytWoLhu.js";!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const a of e)if("childList"===a.type)for(const e of a.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const me={red:"#E5484D",orange:"#F76B15",amber:"#FFB224",yellow:"#F5D90A",brown:"#AD7F58",green:"#46A758",teal:"#12A594",cyan:"#00A2C7",blue:"#3B82F6",indigo:"#5B5BD6",purple:"#8E4EC6",pink:"#D6409F"},ge={50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"};function pe(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const fe={surfaces:{defaults:{tint:"#252525",light:"#ffffff",dark:"#000000",reflexLight:.15,reflexDark:.8,blur:6,blurElevated:8,brightness:1,opacity:8,opacityElevated:12},card:{radius:"1.125rem",padding:"1.25rem",paddingCompact:"0.75rem"},sidebar:{tint:"rgba(113, 156, 223, 0.06)",width:"16rem",drawerWidth:"85vw"},modal:{radius:"1.125rem",backdropBlur:"8px",backdropColor:"rgba(0, 0, 0, 0.6)"}},colors:{bg:{body:ge[950],surface:ge[900],elevated:ge[800],subtle:ge[800]},border:{subtle:ge[800],strong:ge[600]},text:{primary:"#ffffff",secondary:ge[400],muted:ge[500],inverse:ge[950]},accent:{primary:me.blue,secondary:me.purple,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[500]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[500]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[500],grid:"rgba(191, 191, 191, 0.15)",axis:ge[400],cursor:"rgba(255, 255, 255, 0.2)"},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[700],edgeHover:me.cyan}},typography:{font:{title:"'Inter', system-ui, sans-serif",display:"'Inter', system-ui, sans-serif",mono:"'JetBrains Mono', 'SF Mono', Monaco, monospace"},size:{xs:"0.64rem",sm:"0.8rem",base:"1rem",md:"1.125rem",lg:"1.25rem",xl:"1.563rem",xxl:"1.953rem",hero:"3.052rem"},weight:{normal:400,medium:500,semibold:600,bold:700},leading:{tight:1.1,snug:1.25,normal:1.5},tracking:{tight:"-0.02em",normal:"0",wide:"0.05em"}},spacing:{space:{gap:"1.5rem",gapMobile:"0.75rem",page:"1.5rem",pageMobile:"1rem",section:"2rem"},radius:{sm:"0.5rem",md:"0.875rem",lg:"1.125rem",xl:"1.5rem",pill:"9999px"}},motion:{fast:"0.1s",normal:"0.15s",slow:"0.4s",easing:"ease-out"}};function be(e){const t=e.replace("#","");if(6!==t.length&&3!==t.length)return e;let a,n,r;return 3===t.length?(a=parseInt(t[0]+t[0],16)/255,n=parseInt(t[1]+t[1],16)/255,r=parseInt(t[2]+t[2],16)/255):(a=parseInt(t.slice(0,2),16)/255,n=parseInt(t.slice(2,4),16)/255,r=parseInt(t.slice(4,6),16)/255),`color(display-p3 ${a.toFixed(3)} ${n.toFixed(3)} ${r.toFixed(3)})`}function ye(){return"undefined"!=typeof window&&CSS.supports("color","color(display-p3 1 1 1)")}function we(e,t){const a={...e};for(const n of Object.keys(t)){const r=t[n],s=e[n];void 0!==r&&("object"!=typeof r||null===r||Array.isArray(r)||"object"!=typeof s||null===s||Array.isArray(s)?a[n]=r:a[n]=we(s,r))}return a}function Ce(e){return{meta:e.meta,display:e.display,surfaces:e.surfaces?we(fe.surfaces,e.surfaces):fe.surfaces,colors:e.colors?we(fe.colors,e.colors):fe.colors,typography:e.typography?we(fe.typography,e.typography):fe.typography,spacing:e.spacing?we(fe.spacing,e.spacing):fe.spacing,motion:e.motion?we(fe.motion,e.motion):fe.motion}}function ke(e){const t=e.replace("#","");return 6===t.length?`${parseInt(t.slice(0,2),16)}, ${parseInt(t.slice(2,4),16)}, ${parseInt(t.slice(4,6),16)}`:"255, 255, 255"}const ve={"Breeze Dark":Ce({meta:{id:"",name:"",dataTheme:"",previewColor:me.blue,backgroundImage:"",backgroundBrightness:100,isDark:!0},display:{font:"Inter, sans-serif",color:ge[400],size:1,palette:[[me.blue,me.green,me.amber,me.orange,me.red],[ge[950],ge[900],ge[800],ge[700],ge[50]]]},typography:{font:{title:"Inter, sans-serif",display:"Inter, sans-serif",mono:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'},weight:{normal:400,medium:500,semibold:600,bold:700,badge:700},tracking:{tight:"-0.02em",normal:"0",wide:"0.025em"},badge:{textTransform:"capitalize"}},surfaces:{defaults:{tint:ge[900],light:ge[700],dark:ge[950],reflexLight:0,reflexDark:0,blur:0,blurElevated:0,brightness:1,opacity:100,opacityElevated:100,catalystMode:!0},sidebar:{tint:`${ge[800]}80`},card:{radius:"0.5rem"},modal:{radius:"0.75rem"}},colors:{bg:{body:ge[950],surface:ge[900],elevated:ge[800],subtle:ge[900]},border:{subtle:ge[800],strong:ge[600]},text:{primary:"#fff",secondary:ge[400],muted:ge[500],inverse:ge[950]},accent:{primary:me.blue,secondary:me.amber,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[500]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[500]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[500],grid:`${ge[50]}0d`,axis:`${ge[50]}33`,cursor:`${me.blue}33`},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:`${ge[50]}e6`,hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[700],edgeHover:me.blue}}}),"Breeze Light":Ce({meta:{id:"",name:"",dataTheme:"",previewColor:me.blue,backgroundImage:"",backgroundColor:ge[200],backgroundBrightness:100,isDark:!1},display:{font:"Inter, sans-serif",color:ge[600],size:1,palette:[[me.blue,me.green,me.amber,me.orange,me.red],[ge[200],ge[50],ge[100],ge[500],ge[900]]]},typography:{font:{title:"Inter, sans-serif",display:"Inter, sans-serif",mono:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'},weight:{normal:400,medium:500,semibold:600,bold:700,badge:700},tracking:{tight:"-0.02em",normal:"0",wide:"0.025em"},badge:{textTransform:"capitalize"}},surfaces:{defaults:{tint:ge[50],light:ge[200],dark:ge[400],reflexLight:0,reflexDark:0,blur:0,blurElevated:0,brightness:1,opacity:100,opacityElevated:100,catalystMode:!0},sidebar:{tint:"rgba(0, 0, 0, 0.02)"},card:{radius:"0.5rem"},modal:{radius:"0.75rem"}},colors:{bg:{body:ge[200],surface:ge[50],elevated:"#FFFFFF",subtle:ge[100]},border:{subtle:"#DEE0E2",strong:"#BFC2C5"},text:{primary:ge[900],secondary:ge[600],muted:ge[500],inverse:"#FFFFFF"},accent:{primary:me.blue,secondary:me.amber,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[400]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[400]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[400],grid:`${ge[900]}0d`,axis:`${ge[900]}80`,cursor:`${me.blue}1a`},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[400],edgeHover:me.blue},sidebar:{bg:"rgba(0, 0, 0, 0.02)",navHoverBg:"rgba(0, 0, 0, 0.04)",navActiveBg:"rgba(59, 130, 246, 0.10)",navActiveText:me.blue}}})};function De(e,t){const a=e.toLowerCase();return{...t,meta:{...t.meta,id:a,name:e,dataTheme:a}}}const Ae=Object.fromEntries(Object.entries(ve).map(([e,t])=>[e,De(e,t)])),xe=Object.values(Ae);function Ee(e){return xe.find(t=>t.meta.id===e)}function Fe(e){return"string"==typeof e&&xe.some(t=>t.meta.id===e)}new Map(Object.entries(Ae));const Be=Ae["Breeze Dark"],je=Be.meta.id;Be.meta.backgroundImage;const Se={themeId:je,brightness:Be.meta.backgroundBrightness},Me="pymc-theme-id",Ne="pymc-bg-brightness",Le="pymc-color-scheme",Te="pymc-background";const _e={50:.97,100:.92,200:.84,300:.73,400:.62,500:.5,600:.4,700:.32,800:.24,900:.16},Re=[50,100,200,300,400,500,600,700,800,900],ze=["red","orange","yellow","green","aqua","blue","purple"];function Pe(e,t,a){const n=e=>Math.round(Math.max(0,Math.min(255,e))).toString(16).padStart(2,"0");return`#${n(e)}${n(t)}${n(a)}`}function Ie(e){const t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function $e(e){const t=e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055;return Math.round(255*t)}function qe(e,t,a){const n=a*(Math.PI/180),r=t*Math.cos(n),s=t*Math.sin(n),o=e+.3963377774*r+.2158037573*s,i=e-.1055613458*r-.0638541728*s,l=e-.0894841775*r-1.291485548*s,c=o*o*o,d=i*i*i,u=l*l*l,h=-1.2684380046*c+2.6097574011*d-.3413193965*u,m=-.0041960863*c-.7034186147*d+1.707614701*u;return[$e(4.0767416621*c-3.3077115913*d+.2309699292*u),$e(h),$e(m)]}function Oe(e){const[t,a,n]=function(e){const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}(e),[,r,s]=function(e,t,a){const n=Ie(e),r=Ie(t),s=Ie(a),o=.4122214708*n+.5363325363*r+.0514459929*s,i=.2119034982*n+.6806995451*r+.1073969566*s,l=.0883024619*n+.2817188376*r+.6299787005*s,c=Math.cbrt(o),d=Math.cbrt(i),u=Math.cbrt(l),h=.2104542553*c+.793617785*d-.0040720468*u,m=1.9779984951*c-2.428592205*d+.4505937099*u,g=.0259040371*c+.7827717662*d-.808675766*u,p=Math.sqrt(m*m+g*g);let f=Math.atan2(g,m)*(180/Math.PI);return f<0&&(f+=360),[h,p,f]}(t,a,n),o={};for(const i of Re){const e=_e[i],t=r*(1-.3*Math.abs(e-.5)),[a,n,l]=qe(e,t,s);o[i]=Pe(a,n,l)}return o}function He(e){return"undefined"==typeof window?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()}function We(e,t){"undefined"!=typeof document&&document.documentElement.style.setProperty(e,t)}const Ue=new Map;function Ve(e){var t;if(!e.startsWith("var("))return e;const a=Ue.get(e);if(a)return a;const n=e.match(/var\(([^,)]+)(?:,\s*([^)]+))?\)/);if(!n)return e;const r=n[1].trim(),s=(null==(t=n[2])?void 0:t.trim())||"#888888",o=getComputedStyle(document.documentElement).getPropertyValue(r).trim()||s;return Ue.set(e,o),o}function Ge(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(t)return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)];const a=/^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);return a?[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]:[0,0,0]}let Je=null,Ke=0;const Xe=s.memo(function({timestamps:e,series:t,onHover:a,onSeriesHover:n,highlightedKey:r=null,cursorColor:i,overlayLine:l=null,startTs:c,endTs:d,externalAxes:u=!1}){const h=s.useRef(null),m=s.useRef(null),g=s.useRef(t),p=s.useRef(r),f=s.useRef(l),b=s.useRef(a),y=s.useRef(n),w=s.useRef(null),C=s.useRef(c),k=s.useRef(d),v=s.useRef(u),A=s.useRef(e.length);s.useLayoutEffect(()=>{g.current=t,p.current=r,f.current=l,b.current=a,y.current=n,C.current=c,k.current=d,v.current=u});const x=s.useMemo(()=>{const t=new Array(e.length).fill(1);return[e,t]},[e]),E=s.useMemo(()=>({hooks:{draw:e=>{(function(e,t,a,n,r,s){if(0===t.length)return;const o=e.ctx,i=e.bbox,l=i.left,c=i.top,d=i.width,u=i.height;if(d<=0||u<=0)return;const h=8*(window.devicePixelRatio||1);o.save(),o.beginPath(),o.roundRect(l,c,d,u,h),o.clip();const m=e.data[0],g=m.length;if(0===g)return;const p=r??m[0],f=(s??m[g-1])-p||1,b=g>1?m[1]-m[0]:f/g,y=e=>l+(e-p)/f*d,w=e=>c+u*(1-e);for(let C=0;C=0;t--){const e=m[t],a=w(r[t]),n=y(t0&&o.lineTo(s,w(r[t-1]))}o.closePath(),o.fill(),o.restore()}n&&n.values.length>0&&function(e,t,a,n){const r=e.ctx,s=e.bbox,o=s.left,i=s.top,l=s.width,c=s.height;if(l<=0||c<=0)return;const d=e.data[0],u=d.length,h=t.values;if(0===u||0===h.length)return;const m=window.devicePixelRatio||1,g=a??d[0],p=(n??d[u-1])-g||1,f=e=>o+(e-g)/p*l,b=e=>i+c*(1-e),y=Ve(t.color),w=(t.lineWidth??2)*m;r.save(),r.strokeStyle=y,r.lineWidth=w,r.lineCap="round",r.lineJoin="round",r.beginPath();let C=0;for(;C=u)return void r.restore();const k=f(d[C]),v=b(h[C]);r.moveTo(k,v);for(let A=C+1;A({width:400,height:200,padding:u?[0,0,0,0]:[8,0,0,32],cursor:{show:!0,x:!0,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0,range:(e,t,a)=>[C.current??t,k.current??a]},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],hooks:{setCursor:[e=>{var t,a,n,r;const s=e.cursor.idx;if(null!=s&&s>=0){const n=e.data[0][s];null==(t=b.current)||t.call(b,s,n);const r=e.cursor.left,o=e.cursor.top;if(void 0!==r&&void 0!==o&&null!==r&&null!==o){const t=window.devicePixelRatio||1,n=e.ctx,s=Math.round((e.bbox.left/t+r)*t),i=Math.round((e.bbox.top/t+o)*t),l=n.getImageData(s,i,1,1).data,c=l[0],d=l[1],u=l[2];let h=null;if(l[3]>10){const e=g.current;for(const t of e){const e=Ve(t.color),[a,n,r]=Ge(e),s=30;if(Math.abs(c-a)<=s&&Math.abs(d-n)<=s&&Math.abs(u-r)<=s){h=t.key;break}}}h!==w.current&&(w.current=h,null==(a=y.current)||a.call(y,h))}}else null==(n=b.current)||n.call(b,null,null),null!==w.current&&(w.current=null,null==(r=y.current)||r.call(y,null))}]},plugins:[E]}),[E]);s.useEffect(()=>{const t=h.current;if(!t||0===e.length)return;const a=A.current,n=e.length,r=Math.abs(n-a);if(!(!m.current||r>100||a>0&&r/a>.1)&&m.current)return m.current.setData(x),void(A.current=n);m.current&&m.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...F,width:o,height:i},x,t);return m.current=l,A.current=n,()=>{l.destroy(),m.current=null}},[F,x,e.length]),s.useEffect(()=>{const e=h.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!m.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&m.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{m.current&&m.current.redraw()},[r,t,l]);const B=s.useCallback(()=>{null==a||a(null,null),null==n||n(null),w.current=null},[a,n]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:h,className:"w-full h-full overflow-hidden",onMouseLeave:B})}),Ye=s.createContext(null),Qe={blksand:"breeze dark",magma:"breeze dark",waves:"breeze dark",stars:"breeze dark",folds:"breeze dark","kde breeze":"breeze dark",ribbon:"breeze light"};function Ze(e){const t=Ee(e);t&&function(e){if("undefined"==typeof document)return;const t=function(e){var t;const a={},n=e.surfaces.defaults;a["--default-tint"]=n.tint,a["--default-light"]=n.light,a["--default-dark"]=n.dark,a["--default-reflex-light"]=String(n.reflexLight),a["--default-reflex-dark"]=String(n.reflexDark),a["--default-blur"]=`${n.blur}px`,a["--default-blur-elevated"]=`${n.blurElevated}px`,a["--default-brightness"]=String(n.brightness),a["--default-bg-opacity"]=`${n.opacity}%`,a["--default-bg-opacity-elevated"]=`${n.opacityElevated}%`,a["--default-stroke-only"]=n.strokeOnly?"1":"0",a["--default-stroke-width"]=n.strokeWidth?`${n.strokeWidth}px`:"0px",a["--default-stroke-color"]=n.strokeColor||"transparent",a["--sidebar-tint"]=e.surfaces.sidebar.tint;const r=e.meta.isDark;a["--tooltip-bg"]=r?e.colors.bg.elevated:"#FFFFFF",a["--tooltip-fg"]=r?"#FFFFFF":e.colors.text.primary,a["--tooltip-border"]=r?e.colors.border.subtle:"rgba(0, 0, 0, 0.12)",a["--tooltip-shadow"]=r?"0 4px 12px rgba(0, 0, 0, 0.4)":"0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.08)",a["--hover-tint"]=`rgba(${ke(e.colors.accent.primary)}, 0.08)`,a["--shadow-tint"]=`rgba(${ke(e.colors.accent.primary)}, 0.35)`,a["--body"]=e.colors.bg.body,a["--surface"]=e.colors.bg.surface,a["--elevated"]=e.colors.bg.elevated,a["--subtle"]=e.colors.bg.subtle,a["--edge-subtle"]=e.colors.border.subtle,a["--edge-strong"]=e.colors.border.strong,a["--fg-primary"]=e.colors.text.primary,a["--fg-secondary"]=e.colors.text.secondary,a["--fg-muted"]=e.colors.text.muted,a["--fg-invert"]=e.colors.text.inverse,a["--signal-excellent"]=e.colors.signal.excellent,a["--signal-good"]=e.colors.signal.good,a["--signal-fair"]=e.colors.signal.fair,a["--signal-poor"]=e.colors.signal.poor,a["--signal-critical"]=e.colors.signal.critical,a["--signal-unknown"]=e.colors.signal.unknown,a["--sparkline-excellent"]=e.colors.signal.excellent,a["--sparkline-good"]=e.colors.signal.good,a["--sparkline-fair"]=e.colors.signal.fair,a["--sparkline-poor"]=e.colors.signal.poor,a["--sparkline-critical"]=e.colors.signal.critical,a["--sparkline-bg"]=e.meta.isDark?"rgba(9, 9, 11, 0.5)":"transparent",a["--status-success"]=e.colors.status.success,a["--status-warning"]=e.colors.status.warning,a["--status-danger"]=e.colors.status.danger,a["--status-info"]=e.colors.status.info,a["--status-muted"]=e.colors.status.muted;const s=e.colors.chart;a["--pkt-advert"]=s.c3,a["--pkt-flood"]=s.c7,a["--pkt-txt-msg"]=e.colors.signal.excellent,a["--pkt-ack"]=s.c8,a["--pkt-trace"]=s.c3,a["--pkt-req"]=s.c2,a["--pkt-response"]=s.c5,a["--pkt-grp-txt"]=e.colors.map.room,a["--pkt-grp-data"]=e.colors.status.danger,a["--pkt-path"]=s.c3,a["--pkt-anon"]=s.c3,a["--pkt-control"]=s.c6,a["--pkt-unknown"]=e.colors.status.muted,a["--route-flood"]=s.c1,a["--route-direct"]=s.c3,a["--route-transport"]=s.c8,a["--chart-1"]=s.c1,a["--chart-2"]=s.c2,a["--chart-3"]=s.c3,a["--chart-4"]=s.c4,a["--chart-5"]=s.c5,a["--chart-6"]=s.c6,a["--chart-7"]=s.c7,a["--chart-8"]=s.c8,a["--chart-grid"]=s.grid,a["--chart-axis-tick"]=s.axis,a["--chart-cursor"]=s.cursor,a["--metric-received"]=e.colors.metric.received,a["--metric-forwarded"]=e.colors.metric.forwarded,a["--metric-transmitted"]=e.colors.metric.transmitted,a["--metric-dropped"]=e.colors.metric.dropped,a["--metric-neutral"]=e.colors.text.secondary,a["--log-debug"]=e.colors.status.muted,a["--log-info"]=e.colors.status.info,a["--log-warning"]=e.colors.status.warning,a["--log-error"]=e.colors.status.danger,a["--log-critical"]=e.colors.status.danger;const o=e.colors.map;a["--map-node-fill"]=me.blue,a["--map-node-stroke"]="rgba(255,255,255,0.9)",a["--map-hub-color"]=me.purple,a["--map-hub-stroke"]="rgba(255,255,255,0.9)",a["--map-gateway-color"]=me.indigo,a["--map-gateway-stroke"]="rgba(255,255,255,0.85)",a["--map-local-color"]=me.amber,a["--map-neighbor-color"]=me.amber,a["--map-neighbor-stroke"]="rgba(0,0,0,0.4)",a["--map-mobile-color"]=me.orange,a["--map-room-color"]=me.pink,a["--map-ghost-color"]=me.cyan,a["--map-edge-rest"]=o.edge,a["--map-edge-rest-bright"]=e.colors.border.strong,a["--map-edge-rest-dim"]=e.colors.bg.subtle,a["--map-edge-hover-direct"]=o.edgeHover,a["--map-edge-hover-loop"]=me.purple,a["--map-edge-hover-standard"]=e.colors.text.muted,a["--map-edge-hover-neighbor"]=me.amber,a["--link-strong"]=e.colors.signal.excellent,a["--link-medium"]=s.c3,a["--link-weak"]=e.colors.status.danger,a["--hop-0"]=s.c7,a["--hop-1"]=e.colors.signal.excellent,a["--hop-2"]=s.c2,a["--hop-3"]=s.c3,a["--hop-distant"]=e.colors.text.muted,a["--hop-hub"]=o.local;const i=e.colors.icon;a["--icon-page-title"]=(null==i?void 0:i.pageTitle)??s.c1,a["--icon-card-title"]=(null==i?void 0:i.cardTitle)??s.c1,a["--icon-widget"]=(null==i?void 0:i.widget)??e.colors.text.secondary,a["--icon-action"]=(null==i?void 0:i.action)??e.colors.text.secondary,a["--icon-nav"]=(null==i?void 0:i.nav)??e.colors.text.muted,a["--icon-nav-active"]=(null==i?void 0:i.navActive)??s.c1,a["--toggle-on"]=e.colors.signal.excellent,a["--toggle-off"]=e.colors.bg.elevated;const l=e.meta.isDark,c=e.colors.sidebar;a["--sidebar-bg"]=(null==c?void 0:c.bg)??"transparent",a["--sidebar-nav-hover-bg"]=(null==c?void 0:c.navHoverBg)??(l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.04)"),a["--sidebar-nav-active-bg"]=(null==c?void 0:c.navActiveBg)??`color-mix(in srgb, ${s.c1} 15%, transparent)`,a["--sidebar-nav-active-text"]=(null==c?void 0:c.navActiveText)??s.c1,a["--data-box-bg"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--data-box-border"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--subtle-fill"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--subtle-fill-hover"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.05)",a["--subtle-fill-strong"]=l?"rgba(255, 255, 255, 0.08)":"rgba(0, 0, 0, 0.06)",a["--color-pill-bg"]=l?"rgba(0, 0, 0, 0.3)":"rgba(255, 255, 255, 0.3)",a["--terminal-bg"]=l?"rgba(0, 0, 0, 0.4)":"rgba(0, 0, 0, 0.03)",a["--terminal-bg-input"]=l?"rgba(0, 0, 0, 0.5)":"rgba(0, 0, 0, 0.05)",a["--terminal-bg-status"]=l?"rgba(0, 0, 0, 0.3)":"rgba(0, 0, 0, 0.04)",a["--terminal-border"]=l?"rgba(255, 255, 255, 0.1)":"rgba(0, 0, 0, 0.1)",a["--terminal-autocomplete-bg"]=l?"rgba(0, 0, 0, 0.8)":"rgba(255, 255, 255, 0.95)",a["--terminal-autocomplete-border"]=l?"rgba(255, 255, 255, 0.2)":"rgba(0, 0, 0, 0.15)",a["--terminal-autocomplete-hover"]=l?"rgba(255, 255, 255, 0.1)":"rgba(0, 0, 0, 0.05)",a["--livedot-idle"]=l?"#666677":"#999999",a["--ctrl-panel-top"]=l?"rgba(30, 30, 30, 0.95)":"rgba(240, 240, 240, 0.95)",a["--ctrl-panel-mid"]=l?"rgba(25, 25, 25, 0.95)":"rgba(235, 235, 235, 0.95)",a["--ctrl-panel-bottom"]=l?"rgba(20, 20, 20, 0.95)":"rgba(230, 230, 230, 0.95)",a["--ctrl-panel-border"]=l?"rgba(60, 60, 60, 1)":"rgba(200, 200, 200, 1)",a["--chart-grid-line"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--chart-inner"]=l?"#111113":"#f7f7f8",a["--surface-ring"]=l?"inset 0 0 0 1px rgba(255, 255, 255, 0.1)":"inset 0 0 0 1px rgba(0, 0, 0, 0.08)",a["--surface-ring-strong"]=l?"inset 0 0 0 1px rgba(255, 255, 255, 0.15)":"inset 0 0 0 1px rgba(0, 0, 0, 0.12)",a["--surface-tint-subtle"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.02)",a["--surface-tint-light"]=l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.03)",a["--surface-border-subtle"]=l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.06)",a["--map-control-active-amber"]=l?"rgba(251, 191, 36, 0.15)":"rgba(217, 119, 6, 0.12)",a["--map-control-active-sky"]=l?"rgba(56, 189, 248, 0.15)":"rgba(14, 165, 233, 0.12)",a["--map-control-active-teal"]=l?"rgba(45, 212, 191, 0.15)":"rgba(20, 184, 166, 0.12)",a["--sidebar-action-active-green"]=l?"rgba(10, 26, 10, 1)":"rgba(220, 252, 231, 1)",a["--sidebar-action-active-teal"]=l?"rgba(10, 36, 32, 1)":"rgba(204, 251, 241, 1)",a["--sidebar-action-active-amber"]=l?"rgba(26, 20, 8, 1)":"rgba(254, 243, 199, 1)",a["--thumbnail-brightness"]=l?"1.5":"1.8",a["--input-bg"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--input-border"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--font-title"]=e.typography.font.title,a["--font-display"]=e.typography.font.display,a["--font-data"]=e.typography.font.mono,a["--font-card-title"]=e.typography.font.cardTitle??e.typography.font.display,a["--font-badge"]=e.typography.font.badge??e.typography.font.display,a["--font-normal"]=String(e.typography.weight.normal),a["--font-medium"]=String(e.typography.weight.medium),a["--font-semibold"]=String(e.typography.weight.semibold),a["--font-bold"]=String(e.typography.weight.bold),a["--font-card-title-weight"]=String(e.typography.weight.cardTitle??e.typography.weight.semibold),a["--font-badge-weight"]=String(e.typography.weight.badge??e.typography.weight.medium),a["--badge-text-transform"]=(null==(t=e.typography.badge)?void 0:t.textTransform)??"none";const d=e.typography.size;d.xxl&&(a["--text-2xl"]=d.xxl),d.xl&&(a["--text-xl"]=d.xl),d.lg&&(a["--text-lg"]=d.lg),d.md&&(a["--text-md"]=d.md),d.base&&(a["--text-base"]=d.base),d.sm&&(a["--text-sm"]=d.sm),d.xs&&(a["--text-xs"]=d.xs),d.hero&&(a["--text-5xl"]=d.hero),d.cardTitle&&(a["--text-card-title"]=d.cardTitle);const u=e.typography.tracking;return u&&(a["--tracking-tight"]=u.tight,a["--tracking-normal"]=u.normal,a["--tracking-wide"]=u.wide),a["--theme-transition"]=`${e.motion.slow} ${e.motion.easing}`,function(e){if(!ye())return e;const t={},a=/^#[0-9A-Fa-f]{3,6}$/;for(const[n,r]of Object.entries(e))t[n]=a.test(r)?be(r):r;return t}(a)}(e),a=document.documentElement;for(const[n,r]of Object.entries(t))a.style.setProperty(n,r);e.surfaces.defaults.strokeOnly?a.classList.add("stroke-only"):a.classList.remove("stroke-only"),e.surfaces.defaults.catalystMode?a.classList.add("catalyst-mode"):a.classList.remove("catalyst-mode"),a.dataset.mode=e.meta.isDark?"dark":"light"}(t),document.documentElement.dataset.themeId=e}function et({children:e}){const[t,a]=s.useState(()=>function(){if("undefined"==typeof window)return Se;try{let e=localStorage.getItem(Me);const t=localStorage.getItem(Ne);if(!e){const t=localStorage.getItem(Le),a=localStorage.getItem(Te);t?e=t:a&&(e=a),e&&(localStorage.setItem(Me,e),localStorage.removeItem(Le),localStorage.removeItem("pymc-background-image"),localStorage.removeItem(Te))}e&&e in Qe&&(e=Qe[e],localStorage.setItem(Me,e));const a=e&&Fe(e)?e:Se.themeId;let n=Se.brightness;if(t){const e=parseInt(t,10);!isNaN(e)&&e>=0&&e<=100&&(n=e)}return{themeId:a,brightness:n}}catch{return Se}}()),n=s.useRef(!1),r=s.useRef(null),[i,l]=s.useState(null);s.useEffect(()=>{r.current&&(clearTimeout(r.current),r.current=null),n.current&&(l("#808080"),r.current=setTimeout(()=>{l(null),r.current=null},1800)),n.current=!0,Ze(t.themeId),Ue.clear(),requestAnimationFrame(()=>{!function(){if("undefined"==typeof window)return;for(const t of ze){const e=He(`--palette-${t}-bright`),a=He(`--palette-${t}`),n=e||a;if(!n)continue;const r=Oe(n);for(const s of Re)We(`--palette-${t}-${s}`,r[s])}const e=He("--palette-bg-4");if(e){const t=Oe(e);for(const e of Re)We(`--palette-neutral-${e}`,t[e])}}()})},[t.themeId]),s.useEffect(()=>{!function(e){if("undefined"!=typeof window)try{localStorage.setItem(Me,e.themeId),localStorage.setItem(Ne,String(e.brightness))}catch{}}(t)},[t]),s.useEffect(()=>{xe.forEach(e=>{var t;e.meta.backgroundImage&&(t=e.meta.backgroundImage)&&((new Image).src=t)})},[]);const c=s.useCallback(e=>{if(!Fe(e))return;const t=Ee(e);t&&a(a=>({...a,themeId:e,brightness:t.meta.backgroundBrightness}))},[]),d=s.useCallback(e=>{const t=Math.max(0,Math.min(100,Math.round(e)));a(e=>({...e,brightness:t}))},[]),u=s.useMemo(()=>({theme:t,setTheme:c,setBrightness:d}),[t,c,d]);return o.jsxs(Ye.Provider,{value:u,children:[e,i&&o.jsx("div",{className:"fixed inset-0 pointer-events-none z-[9999]",style:{backgroundColor:i,animation:"theme-crossfade 1.8s ease-out forwards"}},t.themeId),o.jsx("style",{children:"\n @keyframes theme-crossfade {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n "})]})}function tt(){const e=s.useContext(Ye);if(!e)throw new Error("useTheme must be used within a ThemeProvider. Wrap your app with in App.tsx.");return e}const at=s.forwardRef(function(e,t){const{href:a,...n}=e;return a.startsWith("http://")||a.startsWith("https://")||a.startsWith("//")?o.jsx(i,{children:o.jsx("a",{...n,href:a,ref:t})}):o.jsx(i,{children:o.jsx(x,{...n,to:a,ref:t})})}),nt={0:"REQ",1:"RESPONSE",2:"TXT_MSG",3:"ACK",4:"ADVERT",5:"GRP_TXT",6:"GRP_DATA",7:"ANON_REQ",8:"PATH",9:"TRACE",10:"MULTIPART",11:"CONTROL",15:"RAW_CUSTOM"},rt={0:"T_FLOOD",1:"FLOOD",2:"DIRECT",3:"T_DIRECT"},st={REQ:0,RESPONSE:1,TXT_MSG:2,ACK:3,ADVERT:4,GRP_TXT:5,GRP_DATA:6,ANON_REQ:7,PATH:8,TRACE:9,MULTIPART:10,RAW_CUSTOM:15};function ot(e){return 1===e||0===e}function it(e){return 2===e||3===e}const lt={acton:{discrete:["#260D40","#2B1345","#2F194B","#342152","#382657","#3C2C5C","#403261","#443766","#483E6C","#4C4371","#504876","#544D7B","#57527F","#5D5884","#625C88","#685F8A","#6E618C","#74628D","#7B638D","#81638E","#88648E","#8E648E","#95658F","#9D658F","#A4668F","#AB6690","#B26790","#BB6992","#C26B94","#C86F97","#CD749B","#D07AA0","#D382A7","#D688AC","#D88FB2","#D995B8","#DB9CBD","#DEA4C4","#DFABC9","#E1B1CE","#E3B7D3","#E5BED8","#E6C5DE","#E8CBE2","#E9D0E6","#EBD6EA","#ECDBEE","#EDE1F3","#EFE6F6","#F0EAFA"],categorical:["#260D40","#F0EAFA","#A76690","#DDA1C2","#585380","#7D638E","#E8CAE1","#CF789E","#403261","#4C4371","#ECDBEE","#69608B","#E3B6D2","#D78CB0","#91648F","#BE6A92","#342152","#EAD3E8","#524B79","#73628D","#463A69","#605B86","#E5C0DA","#D382A7","#C86F97","#86648E","#EEE3F4","#DA97B9","#9B658F","#B26790","#2D1749","#E0ACCA","#3A2959","#8B648E","#311C4D","#EBD7EB","#EDDFF1","#AC6790","#A1668F","#6E618C","#E6C5DE","#78628D","#433665","#DEA7C6","#81638E","#554F7C","#B86891","#3D2D5D","#4F4775","#EFE7F7","#E9CEE4","#D27DA3","#2A1244","#655D89","#C36C94","#E1B1CE","#493F6D","#5C5783","#CC739A","#DB9CBD","#D892B4","#D587AB","#96658F","#E4BBD6","#362455","#4E4573","#7F638E","#D37FA5","#E1AECC","#382657","#EBD9ED","#DFA9C8","#A4668F","#8E648E","#99658F","#675F8A","#B56891","#BB6992","#E5BED8","#E2B4D0","#D07AA0","#71618C","#E6C2DC","#AA6690","#625C88","#EDE1F3","#E8CCE3","#AF6790","#CA7199","#C16B93","#453867","#57517E","#84638E","#4B416F","#E7C7DF","#423463","#514977","#3E2F5F","#544D7B","#93658F"]},bam:{discrete:["#65024B","#701057","#7B1B61","#88276E","#923078","#9B3881","#A4418A","#AC4993","#B5549C","#BC5CA3","#C266AB","#C970B2","#CF7AB9","#D587C1","#DA93C8","#DF9ECE","#E3AAD4","#E7B5DA","#EBC2E0","#EECCE5","#F1D5E9","#F3DDED","#F5E4F0","#F6EBF1","#F6EFF1","#F5F2F0","#F3F3ED","#EFF3E6","#EBF1DF","#E5EFD5","#DDEBCA","#D4E6BD","#C8DEAB","#BCD79B","#B0CE8C","#A3C67D","#97BC6F","#88B161","#7CA856","#72A04D","#679845","#5E903D","#538735","#4B7F2E","#427827","#397021","#306819","#245D10","#195507","#0D4C00"],categorical:["#65024B","#701057","#7B1B61","#88276E","#923078","#9B3881","#A4418A","#AC4993","#B5549C","#BC5CA3","#C266AB","#C970B2","#CF7AB9","#D587C1","#DA93C8","#DF9ECE","#E3AAD4","#E7B5DA","#EBC2E0","#EECCE5","#F1D5E9","#F3DDED","#F5E4F0","#F6EBF1","#F6EFF1","#F5F2F0","#F3F3ED","#EFF3E6","#EBF1DF","#E5EFD5","#DDEBCA","#D4E6BD","#C8DEAB","#BCD79B","#B0CE8C","#A3C67D","#97BC6F","#88B161","#7CA856","#72A04D","#679845","#5E903D","#538735","#4B7F2E","#427827","#397021","#306819","#245D10","#195507","#0D4C00"]},bamako:{discrete:["#003B47","#023C46","#053E45","#083F43","#0A4141","#0D4340","#0F443E","#12463C","#16483A","#194A38","#1C4D36","#204F34","#235132","#28542F","#2C572C","#305A2A","#355C27","#395F24","#3F6321","#44661E","#49691A","#4E6D17","#537014","#5A7410","#5F780D","#657C09","#6A7F05","#718302","#788501","#7F8700","#858800","#8C8A00","#948C01","#9B8E04","#A1920B","#A89713","#AE9C1B","#B7A225","#BEA82E","#C5AD37","#CBB341","#D2B84D","#D9BF5B","#DEC567","#E4CA73","#E9D07E","#EFD58A","#F5DB97","#FAE0A3","#FFE5AD"],categorical:["#003B47","#FFE5AD","#61790B","#B4A022","#245231","#406420","#898900","#DDC464","#0F443E","#EFD58A","#CAB23F","#194A38","#748401","#506E16","#9E9108","#315A29","#083F43","#A99815","#948C01","#6A7F05","#BFA930","#7F8700","#14473B","#1E4E35","#F7DD9C","#2A562D","#043D45","#597411","#E6CC77","#385F25","#48691B","#D4BB51","#0B4241","#8F8A00","#44661E","#1B4C37","#547113","#6F8203","#12463D","#998E03","#27542F","#4C6B18","#A4940E","#2E582B","#355C27","#B9A529","#215033","#EAD181","#FBE1A5","#C5AD37","#3C6122","#848800","#063E44","#E2C86E","#D9BF5B","#CFB648","#16493A","#798600","#023C46","#667C08","#5D770E","#0D433F","#AE9C1B","#F3D993","#094042","#A69611","#8C8A00","#053E45","#0C4240","#365E26","#6D8004","#9C8F05","#4A6A1A","#D6BD56","#B19E1F","#F9DFA0","#647B0A","#2F592A","#10453D","#818800","#C7AF3B","#46681C","#0E443F","#265330","#174A39","#335B28","#5B750F","#778501","#5F780D","#E8CF7C","#718302","#F1D78E","#978D02","#F5DB97","#204F34","#AC9A18","#29552E","#A1920B","#B7A225","#033C46"]},bamo:{discrete:["#4F3043","#56304B","#603354","#6D3961","#793F6B","#834675","#8D4E7E","#965587","#A05E91","#A86698","#B06EA0","#B877A7","#BF81AF","#C78DB8","#CD98BE","#D2A3C4","#D6ADC8","#D9B5CB","#DABECC","#DAC3CC","#D9C7CA","#D8CAC8","#D6CBC6","#D4CDC2","#D1CDBE","#CCCDB9","#C6CBB1","#BCC5A4","#B2BE97","#A7B58A","#9CAB7E","#92A174","#889669","#808D62","#79855C","#737D56","#6D7552","#666C4C","#616548","#5C5D45","#575642","#54503F","#50493D","#4D453C","#4B403B","#4A3C3A","#49393A","#49343B","#4A313E","#4E3042"],categorical:["#4F3043","#56304B","#603354","#6D3961","#793F6B","#834675","#8D4E7E","#965587","#A05E91","#A86698","#B06EA0","#B877A7","#BF81AF","#C78DB8","#CD98BE","#D2A3C4","#D6ADC8","#D9B5CB","#DABECC","#DAC3CC","#D9C7CA","#D8CAC8","#D6CBC6","#D4CDC2","#D1CDBE","#CCCDB9","#C6CBB1","#BCC5A4","#B2BE97","#A7B58A","#9CAB7E","#92A174","#889669","#808D62","#79855C","#737D56","#6D7552","#666C4C","#616548","#5C5D45","#575642","#54503F","#50493D","#4D453C","#4B403B","#4A3C3A","#49393A","#49343B","#4A313E","#4E3042"]},batlow:{discrete:["#011959","#06215B","#0A285C","#0D315D","#0E375E","#103D5F","#114260","#124761","#144D62","#165162","#195662","#1C5A62","#205E61","#26635F","#2C665D","#33695A","#3A6C57","#416F53","#4A724E","#52744A","#5A7745","#627941","#6A7B3D","#747E38","#7D8134","#868330","#8F862D","#9B892B","#A58B2C","#AF8D2E","#B98F32","#C29037","#CD923F","#D69446","#DE964F","#E69858","#ED9A62","#F39E70","#F8A17B","#FAA587","#FCA993","#FDAC9E","#FDB1AB","#FDB4B6","#FDB8C0","#FDBCCB","#FCBFD6","#FCC4E3","#FBC8EF","#FACCFA"],categorical:["#011959","#FACCFA","#828231","#226061","#F29D6D","#4D734D","#114360","#C09036","#FDB4B4","#DD954D","#356A59","#FCBFD6","#175262","#677B3E","#A18A2B","#0D315D","#FCA890","#FBC6E8","#2B655E","#B18D2F","#5A7745","#FDAEA2","#CF9340","#0F3B5F","#E9995C","#FDBAC4","#416F53","#91862D","#1B5962","#08255B","#747E38","#134B61","#F9A380","#8A842F","#0E365E","#124761","#154F62","#E39754","#7B8034","#1E5D62","#99882C","#195662","#0B2B5C","#FDB7BC","#C8913B","#FCC3DF","#EE9B64","#A98C2C","#FDB1AB","#FDBCCD","#FBC9F1","#051F5A","#F6A077","#607942","#FDAB9A","#477150","#3B6D56","#B98F32","#26635F","#537549","#D69446","#6D7C3B","#30685C","#103F60","#FBA689","#BD8F34","#CB923E","#EB9A60","#FDB8C0","#FBC7EC","#F09C69","#8E852E","#FDBBC9","#7F8133","#031C5A","#114160","#FDAC9E","#5D7844","#FCA995","#185462","#787F36","#A58B2C","#0A285C","#9D892B","#33695A","#0D335E","#637A40","#165062","#124561","#205E61","#144D62","#1D5B62","#0C2E5D","#D9954A","#3E6E55","#AD8C2D","#F49F72","#868330","#B58E30","#577647"]},batlowk:{discrete:["#04050A","#0A0D15","#0F141E","#121B29","#152233","#18293D","#1C3146","#21384F","#274156","#2C485B","#314E5E","#36535F","#3B575F","#405C5E","#445F5D","#49625B","#4D6558","#526756","#586B52","#5E6E4F","#63724B","#6A7548","#717845","#797D41","#81813E","#8A853B","#938839","#9F8D38","#A99139","#B3943B","#BE973E","#C89A43","#D39D4C","#DB9F54","#E2A15D","#E8A366","#EEA570","#F3A77C","#F6A986","#F8AC91","#FAAE9A","#FCB1A4","#FDB4B0","#FDB7B9","#FDBAC3","#FDBDCD","#FDC1D8","#FCC5E4","#FBC8EF","#FACCFA"],categorical:["#04050A","#FDC0D6","#787C41","#38555F","#E5A160","#536855","#AF933A","#FAAE9A","#1A2E43","#FDB6B7","#294458","#455F5C","#63724B","#CD9B47","#91883A","#F3A77E","#111A27","#F7AB8D","#FDBBC5","#FCB2AA","#D99E52","#A18E38","#4C6459","#21384F","#3F5B5E","#152335","#0C1019","#EEA570","#5B6D50","#6C7647","#314E5E","#85823D","#BE973E","#7E7F3F","#FBB0A2","#49625B","#576A53","#0F151F","#2D495B","#DFA059","#727944","#FDBDCD","#253E54","#EAA368","#C69942","#3C585F","#998B38","#677449","#F1A678","#F9AC92","#141F2F","#1D3248","#506657","#090C13","#A99139","#5F6F4E","#35525F","#435D5D","#FDB8BD","#F5A984","#B5953B","#FDB5B2","#17273B","#D39D4C","#8C853B","#9D8C38","#415C5E","#1F354B","#33505E","#FCB1A6","#101723","#3E595F","#121C2B","#757B43","#06080F","#FCB3AE","#3A565F","#274156","#61704D","#88843C","#2B475A","#FDBED1","#6A7548","#596C51","#192B3F","#6F7845","#233B51","#C99A45","#F0A574","#DC9F55","#2F4B5D","#47615C","#F6AA88","#FDB9C1","#C29840","#4A635A","#FAAD96","#81813E","#7B7E40","#E7A264"]},batloww:{discrete:["#011959","#06215B","#0A285C","#0D315D","#0E375E","#103D5F","#114260","#124761","#144C62","#165062","#185562","#1B5962","#1F5D62","#246261","#2A665F","#30695D","#366C5A","#3D7056","#467352","#4E764E","#56794A","#5E7C46","#667F42","#70823D","#798539","#828936","#8C8C33","#989032","#A29433","#AD9738","#B79B3F","#C19E48","#CBA154","#D3A45E","#D9A669","#DFA872","#E4AA7C","#E9AC88","#EEAF91","#F2B39C","#F6B9A8","#F9C0B5","#FCCAC4","#FED3CF","#FFDBDA","#FFE3E2","#FFEAEA","#FFF2F2","#FFF8F8","#FFFEFE"],categorical:["#FFFEFE","#011959","#7E8737","#205F61","#E7AB84","#497451","#114360","#FED1CD","#BF9D46","#637E44","#9E9233","#FFEAEA","#0D315D","#326B5C","#F5B7A6","#165162","#D7A564","#0F3B5F","#1A5862","#3D7056","#FFF5F5","#FFDFDD","#FAC3BA","#134A61","#08255B","#70823D","#EEB094","#56794A","#E0A874","#8E8D33","#28655F","#AF9839","#CBA154","#EBAD8B","#1D5C62","#051F5A","#124761","#FFE5E4","#B79B3F","#A79535","#386D59","#5C7B47","#185562","#DBA76D","#F8BDAF","#FFF0F0","#246261","#F2B39C","#868A35","#4F774D","#E4AA7C","#2D685E","#77853A","#FED8D6","#103F60","#FFFAF9","#968F32","#D1A35C","#144E62","#FCCAC4","#437254","#698040","#0E365E","#0B2B5C","#C59F4C","#30695D","#1C5A62","#A29433","#407155","#FFDBDA","#0C2E5D","#F7BAAA","#E5AB80","#175362","#828936","#1F5D62","#BB9C42","#E9AC88","#FFF7F7","#3A6E58","#9A9132","#8A8B34","#4C754F","#FFEDED","#D9A669","#144C62","#266460","#FDCDC9","#FCC6BF","#FFE2E1","#FFFCFC","#7B8639","#2B675E","#155062","#5F7C45","#F9C0B5","#356C5A","#F3B5A1","#EDAF8F","#FED5D2"]},berlin:{discrete:["#9EB0FF","#93AFFA","#87ADF4","#79ABED","#6CA9E6","#60A5DF","#54A0D5","#489ACA","#3E90BC","#3787AF","#327EA3","#2D7597","#296B8B","#25607C","#225771","#1E4E65","#1B465A","#183D4F","#153342","#122C38","#11242E","#101D25","#11181C","#121214","#160E0D","#1B0B07","#210B03","#270D01","#2D0E00","#340F00","#3B1100","#421301","#4B1602","#541905","#5D1E09","#68240F","#732B16","#803620","#8A3F2A","#944834","#9E513F","#A85A4A","#B46658","#BE6F63","#C8796F","#D2837A","#DD8D86","#EA9995","#F4A3A1","#FFADAD"],categorical:["#9EB0FF","#93AFFA","#87ADF4","#79ABED","#6CA9E6","#60A5DF","#54A0D5","#489ACA","#3E90BC","#3787AF","#327EA3","#2D7597","#296B8B","#25607C","#225771","#1E4E65","#1B465A","#183D4F","#153342","#122C38","#11242E","#101D25","#11181C","#121214","#160E0D","#1B0B07","#210B03","#270D01","#2D0E00","#340F00","#3B1100","#421301","#4B1602","#541905","#5D1E09","#68240F","#732B16","#803620","#8A3F2A","#944834","#9E513F","#A85A4A","#B46658","#BE6F63","#C8796F","#D2837A","#DD8D86","#EA9995","#F4A3A1","#FFADAD"]},bilbao:{discrete:["#4C0001","#54070B","#5B0E13","#64161A","#6B1D20","#712227","#77282D","#7D2E34","#84343B","#8A3A41","#8F4047","#94464B","#984C4F","#9B5253","#9D5754","#9E5C56","#A06057","#A16458","#A26959","#A36D5A","#A4715B","#A5745B","#A6785C","#A77C5D","#A8805E","#A9845F","#AA875F","#AC8C60","#AD9061","#AE9463","#AF9864","#B19D68","#B3A36E","#B6A975","#B8AD7E","#BBB287","#BDB590","#C0B99A","#C2BCA3","#C4BFAA","#C6C2B2","#C8C5B9","#CBCAC1","#CFCEC9","#D5D4D1","#DBDBDA","#E3E3E2","#EDEDED","#F6F6F6","#FFFFFF"],categorical:["#4C0001","#F8F8F8","#A9815E","#984D50","#BEB794","#AF9965","#CCCAC3","#78292F","#A26A59","#9F5D56","#64161A","#B6AA77","#C4C0AC","#A6765C","#8A3A41","#AC8C60","#DDDDDB","#A16358","#C7C5B7","#B3A16B","#A4705A","#6E2024","#EAEAE9","#92434A","#BAB185","#9C5554","#AD9262","#580B10","#813137","#C1BCA1","#AA865F","#D2D2CE","#A77C5D","#D7D7D4","#BCB48D","#B4A571","#C0B99A","#9E5955","#AB8960","#A6795C","#A36D5A","#8E3F46","#85353C","#A16758","#732529","#CAC7BD","#F1F1F0","#520509","#AC8F61","#5E1115","#C6C2B2","#E3E3E2","#691B1F","#B8AD7E","#95484D","#AE9663","#B19D68","#A5735B","#A06057","#9A5152","#A87E5D","#7D2E34","#A9835E","#C3BEA6","#CFCEC9","#A46E5A","#F4F4F4","#DADAD8","#B29F69","#EDEDED","#BBB289","#9D5754","#AF9764","#904148","#994F51","#B3A36E","#A87F5E","#A26859","#AC8D61","#BDB590","#AA875F","#A77A5D","#AB8A60","#A4715B","#611418","#BFB897","#E6E6E6","#9B5353","#D5D4D1","#974A4F","#C8C6BA","#A16558","#9F5E56","#76272C","#67191D","#8C3C43","#B9AF82","#C3BFA9","#B5A874","#4F0205"]},broc:{discrete:["#2C1A4C","#2B2154","#2B295B","#2A3164","#29396C","#284174","#29497C","#2A5183","#305C8C","#376593","#416D9A","#4B76A0","#567FA6","#6489AD","#6F92B3","#7B9BBA","#86A3C0","#92ACC6","#A0B7CD","#ACC0D3","#B8C9DA","#C4D2E0","#D0DBE6","#DEE5EC","#E7ECED","#EDEFE9","#EDEEE1","#E9E9D4","#E4E4C8","#DEDEBD","#D8D8B1","#D2D2A5","#C9C996","#C1C18A","#B8B87E","#AEAE73","#A3A369","#97975E","#8D8D56","#83834D","#797945","#70703D","#646434","#5B5B2C","#525224","#49491D","#404016","#36360F","#2E2E08","#262600"],categorical:["#2C1A4C","#2B2154","#2B295B","#2A3164","#29396C","#284174","#29497C","#2A5183","#305C8C","#376593","#416D9A","#4B76A0","#567FA6","#6489AD","#6F92B3","#7B9BBA","#86A3C0","#92ACC6","#A0B7CD","#ACC0D3","#B8C9DA","#C4D2E0","#D0DBE6","#DEE5EC","#E7ECED","#EDEFE9","#EDEEE1","#E9E9D4","#E4E4C8","#DEDEBD","#D8D8B1","#D2D2A5","#C9C996","#C1C18A","#B8B87E","#AEAE73","#A3A369","#97975E","#8D8D56","#83834D","#797945","#70703D","#646434","#5B5B2C","#525224","#49491D","#404016","#36360F","#2E2E08","#262600"]},broco:{discrete:["#372F38","#36303D","#363144","#36354E","#363957","#373F60","#39456A","#3C4D75","#415780","#47608A","#4D6992","#55729A","#5D7BA2","#6886AA","#728FB1","#7C97B7","#86A0BD","#91A8C2","#9DB2C8","#A7BACC","#B1C1CE","#BAC8D0","#C2CDD0","#CAD1CD","#CED3C8","#CFD3C2","#CFD1B9","#CBCCAD","#C6C6A2","#BFBF96","#B8B78B","#AFAF7F","#A4A472","#9B9A68","#91915E","#888755","#7E7E4C","#737243","#6B693D","#626137","#5B5932","#54512E","#4C482B","#474229","#423D29","#3F3829","#3C352B","#39322E","#383032","#372F37"],categorical:["#372F38","#36303D","#363144","#36354E","#363957","#373F60","#39456A","#3C4D75","#415780","#47608A","#4D6992","#55729A","#5D7BA2","#6886AA","#728FB1","#7C97B7","#86A0BD","#91A8C2","#9DB2C8","#A7BACC","#B1C1CE","#BAC8D0","#C2CDD0","#CAD1CD","#CED3C8","#CFD3C2","#CFD1B9","#CBCCAD","#C6C6A2","#BFBF96","#B8B78B","#AFAF7F","#A4A472","#9B9A68","#91915E","#888755","#7E7E4C","#737243","#6B693D","#626137","#5B5932","#54512E","#4C482B","#474229","#423D29","#3F3829","#3C352B","#39322E","#383032","#372F37"]},buda:{discrete:["#B301B3","#B30BAE","#B314AA","#B31CA6","#B323A2","#B3289F","#B32E9D","#B4339A","#B53998","#B63E96","#B84394","#B94892","#BB4C91","#BD528F","#BE568D","#C05B8C","#C15F8A","#C36389","#C46987","#C66D86","#C77184","#C97583","#CA7982","#CB7E80","#CD837F","#CE877E","#CF8B7D","#D0917B","#D1957A","#D29979","#D49E78","#D5A277","#D6A776","#D7AC75","#D8B073","#D9B572","#DAB971","#DCBF70","#DDC36F","#DEC86E","#DFCC6C","#E0D16B","#E2D76A","#E4DC69","#E6E168","#E9E667","#EDEC67","#F3F366","#F9F966","#FFFF66"],categorical:["#B301B3","#FFFF66","#CD857E","#BC4E90","#DBBD70","#C56A87","#B32F9C","#E3DB69","#D4A177","#EDEC67","#D1937B","#B73F95","#C05C8B","#DFCB6D","#C97882","#B31CA6","#D8AE74","#E7E368","#DAB572","#B311AC","#D39A79","#C36389","#C77184","#B53798","#E1D36B","#BE558E","#B94793","#CB7E80","#CF8C7C","#DDC46E","#B326A0","#F6F566","#D6A875","#DAB971","#C66E86","#E2D76A","#B32B9E","#B317A9","#B4339A","#BA4B91","#C46788","#C2608A","#B309AF","#D49E78","#B63B97","#BD528F","#DCC06F","#EAE767","#FAFA66","#D2977A","#F1F066","#D0907C","#CE897D","#C87483","#CC827F","#D5A576","#B321A3","#E5DF68","#B84394","#D9B273","#E0CF6C","#CA7B81","#DEC86E","#BF598C","#D7AB75","#E6E168","#D1957A","#CC8080","#D39C78","#E0CD6C","#CD847F","#B63D96","#C87384","#C66C86","#F8F866","#D49F78","#D9B473","#DAB772","#BF578D","#CB7D81","#CF8A7D","#B32D9D","#D08E7C","#DBBB71","#C2628A","#E2D56A","#DCBF70","#BC508F","#C46987","#C05B8C","#DFCA6D","#DDC26F","#C15E8B","#D7AD74","#F3F366","#DEC66E","#D5A377","#B31AA7","#BA4992","#CE877E"]},bukavu:{discrete:["#1A3333","#1B373D","#1C3C47","#1E4255","#1F4762","#214E71","#235582","#255E92","#2969A1","#2C73AD","#2F7CB8","#3485C2","#3B8EC7","#4799C8","#50A1C9","#59AAC9","#62B2CA","#6BBACB","#76C3CB","#81CCCD","#92D5D1","#A4DED5","#B6E7DA","#CCF2DF","#DDFBE3","#034224","#08491F","#115119","#1C5914","#2B6212","#3D6915","#4E6E1B","#617224","#6F742B","#7B7631","#867836","#917B3C","#9E7E45","#AA844F","#B48D5D","#BC976C","#C3A27C","#CAB08F","#CFBBA0","#D5C6B0","#DACFC1","#DFD7D0","#E4DFE0","#E9E6ED","#EDEDFC"],categorical:["#1A3333","#1B373D","#1C3C47","#1E4255","#1F4762","#214E71","#235582","#255E92","#2969A1","#2C73AD","#2F7CB8","#3485C2","#3B8EC7","#4799C8","#50A1C9","#59AAC9","#62B2CA","#6BBACB","#76C3CB","#81CCCD","#92D5D1","#A4DED5","#B6E7DA","#CCF2DF","#DDFBE3","#034224","#08491F","#115119","#1C5914","#2B6212","#3D6915","#4E6E1B","#617224","#6F742B","#7B7631","#867836","#917B3C","#9E7E45","#AA844F","#B48D5D","#BC976C","#C3A27C","#CAB08F","#CFBBA0","#D5C6B0","#DACFC1","#DFD7D0","#E4DFE0","#E9E6ED","#EDEDFC"]},cork:{discrete:["#2C194C","#2B2254","#2B295C","#2A3265","#293A6D","#284275","#284A7C","#2A5284","#2F5C8D","#366493","#3F6C99","#49749F","#527CA4","#5E85AA","#688DB0","#7395B6","#7E9DBB","#8AA6C2","#99B1C9","#A5BBD0","#B2C5D7","#C0CFDE","#CDD9E5","#DCE5EB","#E5ECED","#E6EEEA","#E0EAE1","#D4E2D4","#C8DBC8","#BCD3BC","#B0CAB0","#A4C2A3","#95B895","#89B088","#7DA87D","#71A071","#669966","#599059","#4F894E","#458244","#3B7B3A","#317430","#266A25","#1F611D","#1A5816","#174E12","#14450E","#123A0A","#103107","#0F2903"],categorical:["#2C194C","#2B2254","#2B295C","#2A3265","#293A6D","#284275","#284A7C","#2A5284","#2F5C8D","#366493","#3F6C99","#49749F","#527CA4","#5E85AA","#688DB0","#7395B6","#7E9DBB","#8AA6C2","#99B1C9","#A5BBD0","#B2C5D7","#C0CFDE","#CDD9E5","#DCE5EB","#E5ECED","#E6EEEA","#E0EAE1","#D4E2D4","#C8DBC8","#BCD3BC","#B0CAB0","#A4C2A3","#95B895","#89B088","#7DA87D","#71A071","#669966","#599059","#4F894E","#458244","#3B7B3A","#317430","#266A25","#1F611D","#1A5816","#174E12","#14450E","#123A0A","#103107","#0F2903"]},corko:{discrete:["#3F3E3A","#3E3D3F","#3E3D44","#3E3D4B","#3E3F52","#3E425A","#3F4762","#414C6C","#445578","#485D82","#4E658B","#546E94","#5C779C","#6581A5","#6E8AAC","#7792B2","#809BB8","#89A3BD","#94ACC2","#9CB3C5","#A3BAC7","#A9C0C8","#AEC5C7","#B0C9C4","#B0CABF","#ADCAB9","#A9C9B2","#A2C5A8","#9BC19F","#93BC95","#8BB68B","#82B081","#78A775","#709F6A","#689760","#608E56","#5A864C","#537B42","#4F733B","#4B6B35","#486431","#465D2E","#44562C","#43512C","#424D2D","#42492E","#414630","#404333","#404036","#3F3E3A"],categorical:["#3F3E3A","#3E3D3F","#3E3D44","#3E3D4B","#3E3F52","#3E425A","#3F4762","#414C6C","#445578","#485D82","#4E658B","#546E94","#5C779C","#6581A5","#6E8AAC","#7792B2","#809BB8","#89A3BD","#94ACC2","#9CB3C5","#A3BAC7","#A9C0C8","#AEC5C7","#B0C9C4","#B0CABF","#ADCAB9","#A9C9B2","#A2C5A8","#9BC19F","#93BC95","#8BB68B","#82B081","#78A775","#709F6A","#689760","#608E56","#5A864C","#537B42","#4F733B","#4B6B35","#486431","#465D2E","#44562C","#43512C","#424D2D","#42492E","#414630","#404333","#404036","#3F3E3A"]},davos:{discrete:["#00054A","#010E51","#041459","#081C61","#0C2368","#102A6F","#133075","#17377C","#1C3F83","#204588","#244C8D","#295291","#2D5895","#335F98","#38649A","#3C699C","#416E9D","#46729D","#4C779D","#517B9C","#567F9B","#5A829A","#5F8598","#658996","#698C94","#6E8F92","#739290","#78968D","#7D998C","#829D8A","#88A089","#8DA488","#95AA87","#9BAF88","#A3B489","#ABBB8C","#B4C190","#BFCA96","#C9D29E","#D2D9A6","#DBE0AF","#E3E7B8","#EBEDC4","#F0F1CD","#F4F4D6","#F7F7DE","#FAF9E6","#FCFCF0","#FDFDF7","#FEFEFE"],categorical:["#00054A","#FDFDF4","#688B94","#2D5895","#B2C08F","#E8EBC0","#87A089","#133075","#4B769D","#5A829A","#204588","#76958E","#D0D8A4","#99AD88","#F6F6DB","#3C699C","#081C61","#031256","#1A3B7F","#537C9C","#A4B68A","#C1CC98","#7E9A8B","#FAFAE8","#356199","#0E266B","#DEE3B3","#274F90","#6F9091","#618697","#8FA588","#F0F1CD","#43709D","#1D4084","#47739D","#F3F4D4","#658996","#567F9B","#17367A","#FCFBEE","#4F799D","#C9D29E","#93A987","#39659B","#D8DEAB","#ABBB8C","#739290","#B9C693","#F8F8E1","#234A8C","#112B70","#7A978D","#9EB188","#315C97","#829D8A","#05175B","#010C50","#3F6C9D","#0B2065","#5D8499","#2A5392","#8BA388","#6B8D93","#EDEFC7","#E3E7B8","#22488A","#638897","#122E73","#00094D","#AEBD8D","#4D789D","#CDD5A1","#5F8598","#58819A","#071A5E","#0C2368","#18387D","#91A787","#37639A","#EBEDC4","#F2F2D0","#FBFBEB","#74938F","#2F5A96","#335F98","#809B8B","#BDC995","#49759D","#719191","#9BAF88","#F7F7DE","#1B3E82","#A8B88B","#849E89","#557E9B","#E6E9BC","#45719D","#1E4386","#96AB87","#89A188"]},devon:{discrete:["#2C1A4C","#2B1E51","#2B2356","#2A295B","#2A2D60","#293265","#29376A","#283B6E","#274174","#27467A","#274C7F","#275186","#28568C","#2A5C95","#2D609C","#3064A3","#3468AA","#396BB1","#3F70B9","#4774C0","#4F79C6","#597DCC","#6382D1","#6F88D7","#798CDB","#8290DF","#8C95E2","#969AE6","#9E9EE9","#A6A3EB","#ACA7ED","#B1ACEF","#B7B1F0","#BBB5F1","#BFB9F2","#C3BEF3","#C7C2F4","#CCC7F4","#D0CCF5","#D4D0F6","#D8D4F7","#DCD9F8","#E1DEF9","#E5E3FA","#E9E7FB","#EDECFB","#F2F0FC","#F7F6FD","#FBFAFE","#FFFFFF"],categorical:["#2C1A4C","#F8F8FE","#758AD9","#C6C0F3","#28568C","#29376A","#AAA5ED","#DEDCF8","#3D6EB7","#EBE9FB","#9197E4","#3063A2","#274579","#577CCB","#D2CEF6","#2A285A","#BAB3F1","#B2ADEF","#F2F0FC","#274E82","#2A2F62","#CCC7F4","#9E9EE9","#4875C1","#C0BAF2","#2B5D98","#3669AD","#2B2154","#E4E2FA","#8290DF","#D8D4F7","#6784D3","#283E71","#C9C4F4","#BDB7F1","#DBD8F8","#283A6D","#4F79C6","#A4A2EB","#EEEDFC","#CFCBF5","#E8E5FA","#5F80CF","#4272BC","#B6B0F0","#2B1D50","#AEA9EE","#275287","#2A2B5E","#989BE7","#293366","#27497D","#8A94E1","#295A92","#3266A7","#F5F4FD","#7B8DDC","#274174","#2D609C","#2B2558","#6F88D7","#E1DEF9","#3A6CB2","#D5D1F6","#C3BEF3","#2E629F","#3165A4","#8D95E3","#3468AA","#DAD6F7","#D1CDF5","#9B9CE8","#275084","#B8B2F0","#27477B","#6382D1","#4573BF","#A2A0EA","#F7F6FD","#C7C2F4","#F3F2FD","#274376","#8692E0","#2B1F52","#CAC6F4","#ACA7ED","#E3E0F9","#F0EEFC","#E6E4FA","#386AB0","#2C1C4E","#6B86D5","#28396B","#283C6F","#2A5C95","#2A2D60","#BEB9F2","#C2BCF2","#7E8FDD","#3F70B9"]},fes:{discrete:["#0D0D0D","#181818","#212121","#2B2B2B","#343434","#3C3C3C","#454545","#4D4D4D","#565656","#5E5E5E","#656565","#6D6D6D","#747474","#7C7C7C","#848484","#8B8B8B","#939393","#9C9C9C","#A7A7A7","#B1B1B1","#BBBBBB","#C5C5C5","#D1D1D1","#DFDFDF","#ECECEC","#094225","#184822","#2B4F20","#3A5420","#485822","#555B24","#615E26","#6F6229","#7A652B","#86682E","#926B30","#9F7035","#AD7940","#B6834D","#BD8E5C","#C2996C","#C6A47C","#CCB18F","#D1BCA0","#D5C6B0","#DACFC1","#DFD7CF","#E4DFE0","#E8E6ED","#EDEDFC"],categorical:["#0D0D0D","#181818","#212121","#2B2B2B","#343434","#3C3C3C","#454545","#4D4D4D","#565656","#5E5E5E","#656565","#6D6D6D","#747474","#7C7C7C","#848484","#8B8B8B","#939393","#9C9C9C","#A7A7A7","#B1B1B1","#BBBBBB","#C5C5C5","#D1D1D1","#DFDFDF","#ECECEC","#094225","#184822","#2B4F20","#3A5420","#485822","#555B24","#615E26","#6F6229","#7A652B","#86682E","#926B30","#9F7035","#AD7940","#B6834D","#BD8E5C","#C2996C","#C6A47C","#CCB18F","#D1BCA0","#D5C6B0","#DACFC1","#DFD7CF","#E4DFE0","#E8E6ED","#EDEDFC"]},glasgow:{discrete:["#361338","#3B1434","#401530","#45172C","#491828","#4D1924","#511B21","#561C1D","#5B1E18","#602014","#662210","#6B260B","#6F2B07","#723203","#743802","#743E01","#754300","#744900","#744F01","#745402","#735905","#725F0B","#716413","#70691E","#6E6E27","#6C7231","#6B763A","#697B46","#677F4F","#658359","#648763","#628B6C","#618F78","#609381","#60978A","#619B94","#659F9D","#6CA5A8","#74A9B0","#7DADB8","#86B1BF","#8EB4C6","#99B9CE","#A1BCD5","#AABFDB","#B2C3E1","#BBC6E7","#C6CBF0","#D0CFF7","#DBD3FF"],categorical:["#361338","#DBD3FF","#6D702B","#69A3A5","#702D06","#A0BBD3","#638968","#521B20","#745101","#84B0BE","#754001","#5F9587","#BBC6E7","#612013","#45172C","#687D4A","#726210","#618F78","#4B1926","#3E1532","#629C96","#658359","#CACCF3","#76AAB2","#6B763A","#744900","#6A250C","#ADC1DD","#735905","#92B6C9","#591D1A","#743702","#70681C","#4F1A23","#754400","#6D2909","#60998E","#41162F","#744D00","#745503","#B4C3E2","#697A42","#7DADB8","#628C70","#8BB3C3","#561C1D","#D2D0F9","#99B9CE","#3A1435","#6F6C23","#743B01","#60927F","#662210","#648661","#659F9D","#678051","#725E0A","#481829","#6FA6AB","#6C7332","#5D1E17","#A6BED8","#C2C9ED","#723203","#716617","#68240E","#6F6A20","#C6CBF0","#79ABB5","#72600D","#754200","#43162D","#67A1A1","#6B7536","#5F1F15","#735B07","#571C1B","#72A8AF","#744F01","#BEC8EA","#381337","#8EB4C6","#628B6C","#677E4D","#60917B","#639E9A","#4A1827","#A3BDD6","#3C1433","#743901","#632112","#B7C5E5","#4D1924","#65845D","#618E74","#609483","#9CBAD1","#46172A","#87B1C1","#6D712F"]},grayc:{discrete:["#000000","#090909","#111111","#171717","#1C1C1C","#212121","#252525","#2A2A2A","#303030","#343434","#393939","#3D3D3D","#424242","#474747","#4B4B4B","#505050","#545454","#585858","#5D5D5D","#616161","#656565","#696969","#6D6D6D","#717171","#757575","#797979","#7D7D7D","#818181","#858585","#898989","#8E8E8E","#929292","#979797","#9C9C9C","#A1A1A1","#A6A6A6","#ABABAB","#B1B1B1","#B6B6B6","#BCBCBC","#C1C1C1","#C7C7C7","#CECECE","#D5D5D5","#DBDBDB","#E2E2E2","#E8E8E8","#F1F1F1","#F8F8F8","#FFFFFF"],categorical:["#070707","#F9F9F9","#777777","#454545","#AEAEAE","#909090","#292929","#5F5F5F","#D1D1D1","#9E9E9E","#525252","#E4E4E4","#6C6C6C","#BFBFBF","#1A1A1A","#373737","#848484","#595959","#222222","#B6B6B6","#A6A6A6","#3E3E3E","#7D7D7D","#666666","#969696","#8A8A8A","#4B4B4B","#DADADA","#C8C8C8","#313131","#717171","#131313","#EFEFEF","#C4C4C4","#A2A2A2","#424242","#878787","#252525","#2D2D2D","#4F4F4F","#3B3B3B","#808080","#1E1E1E","#BBBBBB","#AAAAAA","#EAEAEA","#696969","#7A7A7A","#DFDFDF","#636363","#565656","#B2B2B2","#0E0E0E","#9A9A9A","#5C5C5C","#747474","#F3F3F3","#333333","#6E6E6E","#D5D5D5","#8D8D8D","#939393","#494949","#CCCCCC","#171717","#BDBDBD","#575757","#C1C1C1","#404040","#828282","#E2E2E2","#151515","#1C1C1C","#0B0B0B","#9C9C9C","#858585","#2F2F2F","#B4B4B4","#888888","#242424","#272727","#3C3C3C","#B0B0B0","#353535","#545454","#5B5B5B","#393939","#D7D7D7","#A4A4A4","#A8A8A8","#959595","#767676","#646464","#989898","#444444","#474747","#111111","#F6F6F6","#ECECEC","#4D4D4D"]},hawaii:{discrete:["#8C0273","#8E0D6E","#8F1569","#901D63","#91235F","#91285A","#922D56","#933252","#94384D","#943D4A","#954246","#964742","#964C3F","#97523B","#985638","#985C34","#996131","#9A662E","#9B6C2A","#9B7226","#9C7823","#9C7E20","#9D841E","#9D8C1C","#9C921C","#9B991D","#9AA021","#97A828","#94AE30","#91B439","#8CB942","#88BE4C","#82C359","#7EC663","#79CA6E","#74CE79","#70D183","#6AD591","#66D89C","#62DCA7","#60DFB2","#5FE2BD","#61E6CA","#67E9D5","#6FEBDE","#7AEEE7","#87EFEE","#98F1F5","#A6F1F9","#B3F2FD"],categorical:["#8C0273","#B3F2FD","#9C951C","#6CD48C","#964D3E","#8ABC48","#9B6D29","#66E8D3","#922E55","#9C801F","#87EFEE","#995D34","#7BC969","#901D63","#60DEB0","#96AA2B","#943D4A","#975439","#82C359","#5FE4C2","#9AA021","#73CE7B","#65D99E","#954544","#9D8A1C","#8E126B","#91B439","#9DF1F7","#73ECE2","#91265C","#9C7724","#9A652E","#93364F","#922A59","#996131","#9D851D","#9D901C","#9A692C","#68D695","#902160","#9B9A1E","#985836","#9B7226","#933252","#77CC72","#9C7B21","#954147","#8D0A6F","#93AF32","#62DCA7","#92F0F3","#8F1867","#7DEEE8","#97513C","#6CEBDB","#61E6CA","#A8F2FA","#964941","#7FC661","#86BF50","#98A526","#70D183","#5FE1B9","#8DB840","#94394D","#9C7923","#8F1569","#985A35","#60E0B4","#9A6B2A","#91245E","#97A828","#9B7425","#6AD591","#95AD2E","#5FE2BD","#60E5C6","#953F48","#933054","#63E7CF","#84C154","#8D0671","#82EFEB","#9B9D1F","#99A323","#88BE4C","#6ED288","#6FEBDE","#9A672D","#91285A","#75CD76","#995F32","#68E9D7","#9B7028","#61DDAB","#943B4B","#933450","#8DF0F0","#8F1A65","#81C45D"]},imola:{discrete:["#1A33B3","#1C37B1","#1E3AAF","#203EAD","#2242AB","#2345AA","#2548A8","#274CA6","#2950A4","#2A53A3","#2C56A1","#2E599F","#2F5D9E","#32609B","#346499","#366797","#386A95","#3B6C92","#3E708F","#41738C","#44768A","#467987","#4A7C85","#4E8082","#518480","#56887E","#5A8C7D","#5F927B","#64967A","#689B79","#6DA078","#72A576","#78AB75","#7DB074","#82B572","#87BA71","#8CBF70","#93C66E","#98CB6D","#9ED06C","#A4D66A","#ACDB69","#B5E268","#BFE767","#C8EB67","#D3F066","#DDF466","#EAF866","#F5FB66","#FFFF66"],categorical:["#1A33B3","#FFFF66","#54867F","#305E9D","#91C36F","#3F718E","#2549A8","#BDE667","#70A377","#2B53A2","#376896","#80B373","#A3D56B","#DDF466","#203EAD","#487B86","#62947A","#2D59A0","#88BB71","#5B8D7D","#CDED66","#4E8082","#EEF966","#33639A","#284EA5","#44768A","#2344AA","#AFDE69","#3B6C92","#78AB75","#1D39B0","#99CC6D","#699C79","#3D6F90","#2C56A1","#2F5B9E","#5E917B","#4B7D84","#9ED06C","#1F3CAE","#C4EA67","#84B772","#274CA6","#D5F066","#2951A4","#74A776","#578A7E","#2446A9","#1C36B1","#A9D96A","#95C86E","#467888","#2141AC","#7CAF74","#356598","#B5E268","#66987A","#396A94","#F7FC66","#8CBF70","#E6F666","#32609B","#518380","#41738C","#6DA078","#6B9E78","#B9E468","#7AAD74","#528580","#32629B","#86B971","#3C6E91","#5C8F7C","#C8EB67","#ACDB69","#D1EF66","#E2F566","#97CA6D","#1B35B2","#1C37B0","#2345AA","#2F5D9E","#1F3DAE","#457789","#3A6B93","#598B7D","#D9F266","#346499","#386995","#A6D76A","#366797","#274DA6","#56887E","#A1D36B","#42748B","#7EB173","#72A576","#477987","#4C7F83","#F2FB66"]},lajolla:{discrete:["#191900","#1E1B02","#221C05","#271E08","#2C200B","#31220E","#362411","#3C2614","#442817","#4B2B1B","#532D1F","#5B3023","#633328","#6E362D","#783932","#813C37","#8B3F3B","#96423F","#A24543","#AD4746","#B74A48","#C04D49","#C9514B","#D1564C","#D75C4D","#DB634E","#DD694F","#E0714F","#E17750","#E37D50","#E48351","#E58951","#E79052","#E89652","#E99C52","#EAA253","#EBA853","#EDAF54","#EEB555","#F0BC57","#F1C25A","#F3CA5F","#F5D369","#F7DA74","#F9E282","#FBE890","#FCEF9F","#FDF5B0","#FEFABE","#FFFECB"],categorical:["#191900","#FFFECB","#D85F4D","#ECAC54","#653329","#F7D971","#A44544","#E58751","#362411","#E1744F","#C44E4A","#E99A52","#4B2B1B","#833D38","#F1C159","#FCEF9F","#271E08","#FEF7B6","#402716","#D0554C","#FAE587","#E79052","#EFB655","#B54947","#201C04","#E37D50","#743830","#DD694F","#EBA353","#94413E","#572F21","#F4CD61","#2E210C","#FDF3AB","#32220F","#241D06","#F5D369","#7B3B34","#1D1B02","#F0BC57","#5E3125","#F8DF7C","#512D1E","#CA514B","#E48251","#E68C51","#EA9E53","#E89552","#BC4C49","#6C362C","#EDB154","#9C4341","#E27950","#FBEA93","#3B2513","#FEFBC0","#452918","#EBA853","#F2C75C","#8B3F3B","#DB644E","#AD4746","#DF6E4F","#D55A4D","#2B200A","#783932","#E79352","#D75C4D","#FEF9BB","#EDAF54","#E0714F","#7F3C36","#613227","#F7DC77","#C7504B","#F1C45A","#30210D","#F4D065","#1E1B03","#FAE78D","#F9E282","#DA614E","#392412","#4E2C1D","#E99C52","#EFB956","#221C05","#EBA553","#FDF5B0","#984240","#E38050","#8F403D","#542E20","#ECAA54","#E68E51","#70372E","#DE6C4F","#B94A48","#291F09","#1B1A01"]},lapaz:{discrete:["#1A0C64","#1C1368","#1E196D","#202071","#212675","#222B79","#23317D","#253681","#263C85","#274189","#29478C","#2A4C8F","#2C5192","#2E5795","#305C98","#32609A","#35659C","#386A9E","#3C70A0","#3F74A1","#4379A2","#487DA3","#4D81A3","#5386A4","#588AA3","#5E8EA3","#6591A2","#6C95A1","#7398A0","#7A9A9E","#809D9D","#879F9B","#90A199","#97A397","#9EA596","#A5A795","#ADAA95","#B7AD96","#BFB199","#C8B69C","#D2BBA2","#DAC1A8","#E4C9B2","#EBCFBB","#F1D5C4","#F5DBCD","#F9E1D6","#FBE8E1","#FDEDEA","#FEF2F3"],categorical:["#1A0C64","#FEF2F3","#5B8BA3","#B3AC96","#2C5292","#3C70A0","#EACEB9","#859E9C","#24327E","#6F96A1","#33619A","#202071","#D0BAA0","#9BA496","#F9E1D6","#4A7FA3","#284289","#90A199","#FCEAE5","#1D176B","#37699D","#F3D8C8","#A7A895","#5285A4","#7A9A9E","#2F5A97","#4278A2","#263A84","#6591A2","#C1B299","#DEC3AB","#222978","#2A4B8E","#5688A4","#D7BEA6","#FDEEEC","#608EA3","#EFD3C0","#A1A696","#6A94A1","#FBE6DD","#ADAA95","#F6DDCF","#4E82A3","#2E5695","#3A6D9F","#C8B69C","#1C1268","#232D7B","#3F74A1","#467BA3","#1E1C6E","#7F9C9D","#BAAF97","#253681","#315E99","#29478C","#E4C9B2","#74989F","#273E87","#212575","#95A398","#8AA09A","#35659C","#2B4F91","#23307C","#E7CBB5","#F1D5C4","#2B4D90","#202373","#588AA3","#D3BCA3","#5487A4","#447AA2","#6792A2","#24347F","#253882","#ECD0BD","#879F9B","#305C98","#E1C6AF","#1E196D","#5D8DA3","#AAA995","#386B9E","#487DA3","#77999F","#F7DFD3","#BEB098","#1F1E70","#325F99","#4176A2","#F4DACB","#4C80A3","#2D5494","#8DA099","#6C95A1","#FAE3DA","#FDECE8","#B7AD96"]},lipari:{discrete:["#031326","#05192F","#062038","#092844","#0C2E4D","#103557","#163C5F","#1E4368","#294B70","#345075","#3E5578","#47587A","#4F5B7B","#575C7A","#5D5D79","#635E78","#695E76","#6E5F75","#765F73","#7C6071","#826070","#89606E","#90616C","#98616A","#A06268","#A86266","#B06364","#BA6462","#C36660","#CB685F","#D46B5E","#DB705F","#E27760","#E77E63","#E98567","#EA8D6B","#EA946F","#E89C75","#E7A279","#E6A87E","#E5AF84","#E5B58A","#E6BD92","#E7C49A","#EACCA3","#EDD3AD","#F0DBB7","#F5E5C4","#F9EDCF","#FDF5DA"],categorical:["#031326","#FDF5DA","#A56267","#525B7A","#E99B74","#785F72","#DA6F5E","#183E61","#E7C398","#8D616D","#365176","#092844","#655E77","#E98466","#BF6561","#F0DBB7","#E5AD82","#B26364","#EBCFA7","#5C5D79","#061D35","#25486D","#0E3353","#EA906D","#98616A","#E37861","#E5B88C","#826070","#CD685F","#6E5F75","#45587A","#F6E8C9","#E7A37A","#615E78","#E77E63","#D46B5E","#9F6268","#E99570","#93616B","#87606E","#7D6071","#F3E1C0","#575C7A","#0B2D4B","#2D4D72","#E6A87E","#E9C99F","#FAEED1","#1E4368","#EA8A69","#B86462","#6A5E76","#AB6365","#735F74","#DF735F","#E5B287","#13385A","#05182D","#E6BD92","#3E5578","#EDD5AF","#07223C","#C6665F","#4C5A7A","#E8A077","#B56363","#FBF1D6","#A26267","#E6C095","#0A2A48","#F8EBCD","#EACCA3","#AE6364","#7A5F72","#635E78","#E98768","#041629","#715F74","#ECD2AB","#A86266","#8A606E","#96616B","#545C7A","#EFD8B3","#F5E5C4","#9B6169","#F2DEBB","#765F73","#6C5F75","#294B70","#22466B","#E89D76","#E88165","#BC6461","#E6A67C","#85606F","#C36660","#1B4064","#D06A5E","#103557"]},lisbon:{discrete:["#E6E5FF","#D8DCF7","#CBD2EF","#BBC6E5","#ADBCDE","#A0B3D6","#93A9CE","#86A0C6","#7794BD","#6A8BB5","#5E81AC","#5177A4","#456E9B","#38628F","#2F5984","#274F78","#20476D","#1B3F61","#173653","#142E48","#12283E","#112233","#111D2A","#121921","#15181B","#181A18","#1E1D17","#252419","#2D2B1C","#353220","#3E3A25","#46422A","#514C31","#5A5536","#645E3C","#6D6741","#777047","#837B4F","#8D8556","#988F5E","#A29A67","#ADA470","#B9B17D","#C3BC89","#CDC795","#D7D2A2","#E0DCAF","#ECE9BE","#F5F4CB","#FFFFD9"],categorical:["#E6E5FF","#D8DCF7","#CBD2EF","#BBC6E5","#ADBCDE","#A0B3D6","#93A9CE","#86A0C6","#7794BD","#6A8BB5","#5E81AC","#5177A4","#456E9B","#38628F","#2F5984","#274F78","#20476D","#1B3F61","#173653","#142E48","#12283E","#112233","#111D2A","#121921","#15181B","#181A18","#1E1D17","#252419","#2D2B1C","#353220","#3E3A25","#46422A","#514C31","#5A5536","#645E3C","#6D6741","#777047","#837B4F","#8D8556","#988F5E","#A29A67","#ADA470","#B9B17D","#C3BC89","#CDC795","#D7D2A2","#E0DCAF","#ECE9BE","#F5F4CB","#FFFFD9"]},managua:{discrete:["#FFCF67","#F9C564","#F3BB60","#EBB05D","#E5A659","#DF9D56","#D99554","#D38C51","#CC824D","#C67B4B","#C07348","#B96C46","#B36444","#AB5C41","#A4553F","#9D4F3D","#95483C","#8E423A","#843B39","#7C3639","#743139","#6D2D3A","#662A3D","#5F2941","#5A2846","#552A4C","#522C53","#4F315D","#4D3566","#4C3B6F","#4C4179","#4C4883","#4D518E","#4F5897","#51609F","#5367A7","#556FAE","#5878B6","#5B80BC","#5E88C2","#6190C8","#6498CE","#68A3D5","#6BACDB","#6FB5E1","#72BEE6","#76C7EC","#7AD3F3","#7DDDF9","#81E7FF"],categorical:["#FFCF67","#F9C564","#F3BB60","#EBB05D","#E5A659","#DF9D56","#D99554","#D38C51","#CC824D","#C67B4B","#C07348","#B96C46","#B36444","#AB5C41","#A4553F","#9D4F3D","#95483C","#8E423A","#843B39","#7C3639","#743139","#6D2D3A","#662A3D","#5F2941","#5A2846","#552A4C","#522C53","#4F315D","#4D3566","#4C3B6F","#4C4179","#4C4883","#4D518E","#4F5897","#51609F","#5367A7","#556FAE","#5878B6","#5B80BC","#5E88C2","#6190C8","#6498CE","#68A3D5","#6BACDB","#6FB5E1","#72BEE6","#76C7EC","#7AD3F3","#7DDDF9","#81E7FF"]},navia:{discrete:["#031327","#041930","#051E3A","#052546","#062B50","#06315A","#073764","#083E6D","#0B4578","#0E4C80","#115286","#15588B","#195E8E","#1E6491","#216991","#246D91","#27718F","#2A748E","#2D788C","#307A8A","#337D89","#368087","#398385","#3C8683","#3F8981","#428C7F","#468F7D","#4A937A","#4E9678","#529A76","#579E73","#5BA271","#62A86E","#67AD6B","#6EB269","#76B768","#7FBD68","#8CC56A","#98CB6F","#A4D176","#B1D67F","#BCDB89","#C9E096","#D3E3A1","#DCE7AC","#E3EAB6","#EAEDBF","#F1F0CA","#F7F2D2","#FCF4D9"],categorical:["#031327","#FCF4D9","#408A80","#87C269","#1B608F","#59A072","#073966","#D1E39F","#2F798B","#EAEDBF","#052546","#266F90","#6BB06A","#0E4D81","#AED57D","#4C947A","#378186","#DFE8B0","#337D89","#2A748E","#14578A","#051C36","#9ACC70","#0A4374","#468F7D","#529A76","#F4F1CD","#062F56","#C1DC8D","#206891","#78B968","#62A86E","#3C8583","#569D74","#236C91","#F8F3D3","#D8E5A8","#0C487B","#04182E","#71B469","#B8D985","#07345E","#05213E","#4F9778","#5DA470","#3E8882","#062A4E","#7FBD68","#EFEFC6","#C9E096","#115286","#2C768D","#1E6491","#49917B","#66AC6C","#28718F","#A4D176","#90C76C","#438C7F","#175C8D","#083E6D","#E5EAB8","#317B8A","#357F87","#398385","#B3D781","#0D4A7E","#1C6290","#052342","#579F73","#9FCE73","#448D7E","#051A32","#FAF3D6","#428B7F","#29738F","#104F84","#5FA66F","#509877","#8CC56A","#094071","#2D788C","#083B6A","#D5E4A3","#2B758D","#226A91","#04162B","#BCDB89","#47907C","#4D9579","#E2E9B4","#7BBB68","#6EB269","#135488","#4A937A","#F1F0CA","#5BA271","#C5DE92","#F6F2D0","#CDE19B"]},naviaw:{discrete:["#041427","#051A31","#05203B","#062747","#072D52","#08345C","#0A3A66","#0C416F","#0F4979","#135080","#175686","#1B5D8A","#1F628D","#23698F","#276D8F","#2A728F","#2D758E","#30798D","#347D8B","#378089","#3A8388","#3D8686","#408984","#448C82","#489080","#4B937E","#50977C","#559C79","#5AA077","#5FA575","#65AA73","#6CAF71","#76B671","#7FBD71","#89C474","#95CB78","#A2D27F","#B1D98A","#BEDF95","#C9E5A1","#D3E9AD","#DBEDB9","#E4F1C6","#E9F4D0","#EEF6D9","#F2F8E1","#F6FAE9","#F9FCF1","#FCFDF7","#FEFEFD"],categorical:["#041427","#FBFDF6","#478F80","#9FD07D","#1F628D","#64A973","#E3F0C4","#0A3A66","#337C8B","#C7E49E","#7DBC71","#549B7A","#2A718F","#135080","#F2F8E1","#3C8586","#062747","#D7EBB2","#418A83","#B4DB8C","#2E778D","#6FB271","#EBF5D4","#0E4574","#051D37","#4D957D","#256B8F","#195A88","#388189","#F7FAEC","#5CA276","#8CC574","#073056","#31798C","#367E8A","#69AD72","#E7F3CC","#104A7A","#95CB78","#EFF6DB","#0B406D","#2C748E","#4A927F","#DDEEBB","#50987C","#165584","#589E78","#76B671","#3F8785","#05192F","#BEDF95","#448C82","#22678E","#06223F","#A9D684","#08355E","#CFE8A8","#F9FCF1","#286E8F","#85C172","#072C50","#F5F9E7","#1C5F8B","#3A8387","#60A675","#F3F9E4","#0C4271","#266D8F","#81BE72","#0A3D6A","#4B937E","#9ACD7B","#EDF5D7","#90C876","#A4D381","#378089","#1B5D8A","#489080","#145282","#DAECB6","#67AB73","#CBE6A3","#B9DD90","#3D8686","#23698F","#6CAF71","#FAFCF3","#79B971","#D3E9AD","#5AA077","#458E81","#72B471","#327B8C","#E5F1C8","#051B33","#F8FBEE","#062443","#398288","#2B728F","#06294C"]},nuuk:{discrete:["#05598C","#0E5B8B","#155C89","#1C5E87","#226085","#276184","#2C6383","#326682","#386982","#3E6C82","#446F82","#4A7283","#517584","#587A86","#5F7D88","#66818A","#6C858C","#73898E","#7B8E91","#819192","#879594","#8D9996","#939C97","#99A097","#9EA498","#A2A798","#A6AA97","#ABAD96","#AEAF95","#B1B194","#B3B492","#B6B690","#B8B88E","#BABA8C","#BDBC8A","#BFBE88","#C1C187","#C4C385","#C7C684","#CAC983","#CDCD83","#D2D184","#D7D787","#DDDD8B","#E3E290","#E8E895","#EEEE9C","#F4F4A4","#F9F9AB","#FEFEB2"],categorical:["#05598C","#FEFEB2","#A1A698","#537785","#C3C385","#B5B591","#7D8F91","#2D6483","#DDDD8B","#919B96","#BCBC8B","#3F6C82","#CDCD83","#1C5E87","#ADAE95","#68838B","#EEEE9C","#A7AA97","#879594","#C8C783","#F6F6A7","#135C89","#B9B98E","#497183","#73898E","#366882","#C0BF88","#D4D486","#99A097","#B1B293","#5E7D88","#256185","#E6E693","#829293","#788C90","#9DA398","#AAAC96","#E1E18F","#3B6A82","#638089","#B3B492","#A4A897","#446F82","#BABA8C","#D8D888","#185D88","#8C9895","#215F86","#BEBD89","#B7B78F","#CACA83","#4E7484","#C1C186","#959E97","#F2F2A1","#AFB094","#326682","#587A86","#296284","#FAFAAD","#6E868C","#C5C584","#D1D084","#0D5B8B","#E9E997","#DFDF8D","#66818A","#B0B194","#5B7B87","#2B6383","#859493","#CCCB83","#F8F8AA","#D2D285","#1F5F86","#70878D","#4B7383","#768B8F","#FCFCAF","#A9AB97","#BFBE88","#C9C983","#346782","#DBDA89","#236085","#BDBD8A","#BAB98D","#B8B88E","#2F6583","#939C97","#9FA498","#A2A798","#CFCF84","#B4B591","#C4C485","#979F97","#F0F09E","#155C89","#9BA298","#517584"]},oleron:{discrete:["#1A2659","#212E61","#293568","#323F72","#3A477A","#424F82","#4A578A","#535F92","#5D699C","#6572A5","#6E7BAE","#7784B7","#808DC0","#8B97CA","#94A1D3","#9DAADC","#A6B3E5","#AFBCEC","#B9C6F2","#C0CDF5","#C7D4F7","#CEDAF9","#D4E1FB","#DCE9FD","#E3F0FE","#1F4E00","#2C5100","#3A5600","#445900","#4F5C02","#5A6005","#65660C","#736D18","#7E7423","#8A7B2E","#94823A","#9F8945","#AC9253","#B79A5E","#C3A36A","#CEAC75","#D9B581","#E5C090","#EDC99D","#F2D2A9","#F6DAB5","#F8E2C0","#FAECCE","#FBF4DA","#FDFDE6"],categorical:["#1A2659","#212E61","#293568","#323F72","#3A477A","#424F82","#4A578A","#535F92","#5D699C","#6572A5","#6E7BAE","#7784B7","#808DC0","#8B97CA","#94A1D3","#9DAADC","#A6B3E5","#AFBCEC","#B9C6F2","#C0CDF5","#C7D4F7","#CEDAF9","#D4E1FB","#DCE9FD","#E3F0FE","#1F4E00","#2C5100","#3A5600","#445900","#4F5C02","#5A6005","#65660C","#736D18","#7E7423","#8A7B2E","#94823A","#9F8945","#AC9253","#B79A5E","#C3A36A","#CEAC75","#D9B581","#E5C090","#EDC99D","#F2D2A9","#F6DAB5","#F8E2C0","#FAECCE","#FBF4DA","#FDFDE6"]},oslo:{discrete:["#010101","#04070B","#060C13","#0A121B","#0C1620","#0D1927","#0E1D2D","#0F2133","#10263C","#112A43","#122E4A","#133251","#153758","#173C61","#194169","#1B4670","#1E4A78","#214F80","#255589","#295A91","#2E5F99","#3364A1","#3A6AA9","#4371B2","#4B77B9","#537DBE","#5B83C3","#6489C6","#6B8EC8","#7292C9","#7896C9","#7E9ACA","#859ECA","#8BA2C9","#91A6C9","#97A9C9","#9DADC9","#A4B2CA","#AAB6CA","#B1BBCB","#B8BFCD","#BFC5CF","#C7CCD3","#CFD2D8","#D7D9DD","#DEE0E2","#E6E7E9","#EFF0F1","#F7F7F8","#FFFFFF"],categorical:["#030609","#F9F9F9","#507BBC","#163B5E","#A0AFC9","#7B98CA","#27588E","#0E2032","#CACED5","#122D48","#3767A6","#1D4875","#8DA3C9","#E2E3E5","#678BC7","#B4BDCC","#0C151F","#BFC5CF","#97A9C9","#4371B2","#10263D","#080E16","#7292C9","#215081","#2E5F99","#AAB6CA","#ECEDEE","#0D1A28","#143454","#D5D8DC","#5B83C3","#19426A","#859ECA","#13314E","#0E1D2D","#3D6CAC","#6C8FC8","#7795C9","#F3F3F4","#4976B8","#245488","#DBDDE0","#112A43","#92A6C9","#C5C9D2","#809BCA","#0F2337","#3263A0","#050A10","#B9C1CD","#1F4C7B","#183E64","#A5B3CA","#0A121B","#9CACC9","#6187C5","#0D1824","#8AA1CA","#2A5B93","#547EBF","#D1D3D9","#E6E7E9","#1B456F","#B0BACB","#153758","#7494C9","#D8DADE","#6A8DC8","#90A5C9","#99ABC9","#235285","#133251","#060C13","#406EAF","#7E9ACA","#173C61","#4C78BA","#122F4B","#1C4772","#87A0CA","#CED1D7","#C2C7D1","#0F253A","#2C5D96","#C7CCD3","#112B45","#EFF0F1","#6F90C9","#0E1E2F","#ADB8CB","#7997CA","#4673B5","#15395B","#091018","#194067","#30619C","#94A8C9","#F6F6F6","#0F2135","#A3B1CA"]},roma:{discrete:["#7E1700","#832504","#883008","#8F3C0C","#934610","#984E14","#9C5717","#A05F1B","#A5681F","#A97023","#AD7826","#B0802B","#B58930","#BA9437","#BE9D3E","#C2A647","#C7B051","#CBBA5D","#CFC66D","#D1CF7B","#D2D78A","#D2DE98","#D0E4A6","#CBE8B4","#C4EABE","#BDEAC6","#B3E9CD","#A6E6D2","#9BE2D5","#8EDDD7","#81D7D7","#74CFD6","#64C6D5","#59BDD2","#4FB5D0","#46ACCC","#3EA4C9","#379AC5","#3292C2","#2E8ABF","#2B82BB","#287AB8","#2471B4","#2269B0","#1F60AD","#1C58A9","#194FA5","#1344A0","#0C3B9C","#033198"],categorical:["#7E1700","#832504","#883008","#8F3C0C","#934610","#984E14","#9C5717","#A05F1B","#A5681F","#A97023","#AD7826","#B0802B","#B58930","#BA9437","#BE9D3E","#C2A647","#C7B051","#CBBA5D","#CFC66D","#D1CF7B","#D2D78A","#D2DE98","#D0E4A6","#CBE8B4","#C4EABE","#BDEAC6","#B3E9CD","#A6E6D2","#9BE2D5","#8EDDD7","#81D7D7","#74CFD6","#64C6D5","#59BDD2","#4FB5D0","#46ACCC","#3EA4C9","#379AC5","#3292C2","#2E8ABF","#2B82BB","#287AB8","#2471B4","#2269B0","#1F60AD","#1C58A9","#194FA5","#1344A0","#0C3B9C","#033198"]},romao:{discrete:["#733957","#773850","#7A3849","#7E3942","#823C3D","#863F38","#8A4334","#8E4831","#94502E","#98572C","#9D5F2B","#A3672C","#A8712E","#AF7D32","#B58837","#BB933F","#C19F47","#C6AA52","#CDB761","#D1C26E","#D4CB7B","#D6D388","#D5D995","#D3DEA3","#CEE0AD","#C8E1B6","#C1E1BE","#B6DEC5","#ABDBC9","#A0D6CC","#94D0CE","#88C9CF","#7BC0CE","#70B8CD","#67AFCA","#5FA6C7","#589CC4","#5291BE","#4F88B9","#4E7EB3","#4F75AC","#516BA4","#55609A","#595891","#5D5087","#62497D","#664474","#6B3F69","#6F3B60","#723959"],categorical:["#733957","#773850","#7A3849","#7E3942","#823C3D","#863F38","#8A4334","#8E4831","#94502E","#98572C","#9D5F2B","#A3672C","#A8712E","#AF7D32","#B58837","#BB933F","#C19F47","#C6AA52","#CDB761","#D1C26E","#D4CB7B","#D6D388","#D5D995","#D3DEA3","#CEE0AD","#C8E1B6","#C1E1BE","#B6DEC5","#ABDBC9","#A0D6CC","#94D0CE","#88C9CF","#7BC0CE","#70B8CD","#67AFCA","#5FA6C7","#589CC4","#5291BE","#4F88B9","#4E7EB3","#4F75AC","#516BA4","#55609A","#595891","#5D5087","#62497D","#664474","#6B3F69","#6F3B60","#723959"]},tofino:{discrete:["#DED9FF","#D0CFF9","#C3C6F3","#B3BBEC","#A6B1E6","#98A8E1","#8B9FDB","#7E95D4","#6E89CB","#617FC3","#5575B8","#4A6BAC","#4262A0","#395790","#334F83","#2E4776","#293F6A","#24385D","#1F304F","#1B2943","#172338","#141D2E","#111824","#0F151B","#0D1516","#0D1712","#0F1B12","#112113","#142716","#162F19","#1A361C","#1D3E20","#224825","#26512A","#2A5A2E","#2E6233","#336C38","#39773E","#3F8144","#488B4A","#529551","#5FA059","#70AB63","#7FB46B","#8EBD73","#9DC57B","#ACCD83","#BDD68C","#CCDE94","#DBE69B"],categorical:["#DED9FF","#D0CFF9","#C3C6F3","#B3BBEC","#A6B1E6","#98A8E1","#8B9FDB","#7E95D4","#6E89CB","#617FC3","#5575B8","#4A6BAC","#4262A0","#395790","#334F83","#2E4776","#293F6A","#24385D","#1F304F","#1B2943","#172338","#141D2E","#111824","#0F151B","#0D1516","#0D1712","#0F1B12","#112113","#142716","#162F19","#1A361C","#1D3E20","#224825","#26512A","#2A5A2E","#2E6233","#336C38","#39773E","#3F8144","#488B4A","#529551","#5FA059","#70AB63","#7FB46B","#8EBD73","#9DC57B","#ACCD83","#BDD68C","#CCDE94","#DBE69B"]},tokyo:{discrete:["#1C0E34","#241036","#2D1339","#37163D","#3F1A40","#481E43","#4F2345","#562948","#5D304A","#62354C","#663B4D","#69404E","#6B454F","#6D4B50","#6E4F50","#6F5251","#6F5651","#705951","#715C52","#715F52","#716252","#726452","#726753","#736B53","#736E53","#747153","#757554","#757A54","#767E55","#778355","#788856","#798E57","#7B9558","#7C9B5A","#7EA25C","#81A95E","#84B062","#88B968","#8DC16E","#93CA76","#9BD27F","#A4DA8A","#AFE398","#BAEAA4","#C5EFB0","#CFF4BB","#D8F7C5","#E2F9CF","#E9FBD7","#EFFCDD"],categorical:["#1C0E34","#EFFCDD","#747053","#6C4750","#87B666","#B8E8A1","#512446","#715D52","#798B56","#7D9F5B","#37163D","#726653","#99D07D","#63374C","#6F5451","#D8F7C5","#767C54","#705951","#5B2D49","#7B9558","#441D41","#291238","#E5FAD2","#C9F1B4","#716252","#81AA5F","#683F4E","#736B53","#6E4E50","#757654","#8EC370","#A7DD8E","#778455","#747354","#84B062","#231036","#93CA76","#DFF9CC","#30143A","#A0D785","#7FA45D","#EAFBD8","#6A434F","#C1EDAB","#736D53","#562948","#6D4B50","#7A9057","#7C9A59","#4B2044","#715F52","#663B4D","#D1F4BD","#705651","#8ABD6A","#6E5151","#AFE398","#5F324B","#757954","#3E193F","#726853","#726452","#778055","#705B52","#788756","#61344C","#746E53","#ABE093","#532747","#85B364","#7EA25C","#261137","#736C53","#E8FBD5","#4E2245","#88B968","#798E57","#767E55","#726753","#757754","#715E52","#3A183E","#6E4F51","#778255","#7B9759","#DCF8C9","#EDFCDA","#411B40","#7D9C5A","#767B54","#726352","#6F5551","#726552","#82AD60","#D5F6C1","#34153C","#9CD481","#747454","#C5EFB0","#481E43"]},turku:{discrete:["#000000","#090908","#111110","#181816","#1D1D1A","#22221F","#272723","#2C2C27","#33322B","#38382F","#3D3D32","#424235","#474738","#4E4D3C","#53523E","#585841","#5D5D43","#626246","#686848","#6E6D4B","#73724D","#797750","#7F7D52","#878356","#8E8859","#968E5C","#9D9360","#A79864","#AF9C68","#B69F6C","#BEA270","#C4A474","#CCA579","#D1A67D","#D7A781","#DBA886","#E0A98B","#E6AB92","#EAAD98","#EFB09F","#F2B4A7","#F6B9AE","#F9BFB7","#FBC4BF","#FDC9C6","#FECFCC","#FED4D3","#FFDBDA","#FFE0E0","#FFE6E6"],categorical:["#070707","#FFE6E6","#948D5B","#E5AA90","#4D4C3B","#2C2C27","#C3A374","#6D6C4A","#FBC4BF","#D6A780","#F2B4A7","#1C1C19","#3D3D32","#AC9A67","#7E7C52","#FED6D4","#5D5D43","#35342D","#DDA888","#141312","#55543F","#242420","#FDCDCA","#F7BCB3","#898456","#B8A06D","#ECAE9B","#CDA57A","#FFDEDD","#646447","#454537","#9F9461","#76744E","#71704C","#30302A","#414135","#181816","#FCC8C4","#EFB1A1","#838054","#F5B8AD","#E1A98C","#C8A477","#686848","#595941","#20201D","#8E8859","#D1A67D","#B29D6A","#E9AC95","#BEA270","#FED1CF","#0E0E0D","#A59764","#DAA784","#282823","#F9C0B9","#51503D","#393930","#FFDAD9","#49493A","#606045","#FFE2E1","#9A915E","#797750","#F4B6AA","#F6BAB0","#CBA578","#FFD8D6","#FECFCC","#262622","#C0A272","#868255","#1A1A18","#FAC2BC","#8B8658","#E3AA8E","#161614","#4F4E3C","#C6A475","#2E2E28","#BBA16F","#6B6A49","#E7AB93","#CFA67C","#626246","#53523E","#5B5B42","#FED3D1","#7C7A51","#817E53","#73724D","#FFDCDB","#37372E","#F8BEB6","#0B0B0A","#575740","#DFA98A","#474738","#B59F6C"]},vanimo:{discrete:["#FFCDFD","#F7BEF2","#F0B0E8","#E6A0DC","#DE93D2","#D786C8","#CF7ABF","#C76FB5","#BD63AA","#B45AA1","#AB5198","#A1498E","#964184","#883977","#7C326B","#6E2C60","#612654","#542148","#451C3B","#391931","#2F1728","#281521","#22141C","#1D1417","#1A1414","#191612","#191811","#1B1D11","#1D2212","#212913","#253014","#2B3916","#324419","#384D1B","#3F561E","#456021","#4C6924","#547427","#5A7C2A","#60852E","#678E32","#6E9737","#77A33F","#7FAE47","#88BA51","#92C65D","#9CD26B","#A9E27F","#B3EF92","#BEFDA5"],categorical:["#FFCDFD","#F7BEF2","#F0B0E8","#E6A0DC","#DE93D2","#D786C8","#CF7ABF","#C76FB5","#BD63AA","#B45AA1","#AB5198","#A1498E","#964184","#883977","#7C326B","#6E2C60","#612654","#542148","#451C3B","#391931","#2F1728","#281521","#22141C","#1D1417","#1A1414","#191612","#191811","#1B1D11","#1D2212","#212913","#253014","#2B3916","#324419","#384D1B","#3F561E","#456021","#4C6924","#547427","#5A7C2A","#60852E","#678E32","#6E9737","#77A33F","#7FAE47","#88BA51","#92C65D","#9CD26B","#A9E27F","#B3EF92","#BEFDA5"]},vik:{discrete:["#001261","#011A66","#02226B","#022B71","#023376","#023A7B","#034280","#034A85","#06548B","#0B5D91","#136697","#1E6F9D","#2B79A4","#3C85AC","#4B90B3","#5A9ABA","#6AA4C1","#7AAEC8","#8DBAD0","#9DC4D6","#ADCDDD","#BDD6E3","#CCDFE8","#DEE6E9","#E8E7E5","#EEE3DC","#EEDBD0","#EBD0C0","#E7C6B2","#E3BCA5","#DFB298","#DBA88B","#D69D7C","#D29470","#CE8B64","#CA8258","#C6794C","#C26E3F","#BE6533","#B85C28","#B2511D","#A94512","#9C3709","#912D06","#872406","#7E1D06","#741506","#6A0D07","#620607","#590008"],categorical:["#001261","#011A66","#02226B","#022B71","#023376","#023A7B","#034280","#034A85","#06548B","#0B5D91","#136697","#1E6F9D","#2B79A4","#3C85AC","#4B90B3","#5A9ABA","#6AA4C1","#7AAEC8","#8DBAD0","#9DC4D6","#ADCDDD","#BDD6E3","#CCDFE8","#DEE6E9","#E8E7E5","#EEE3DC","#EEDBD0","#EBD0C0","#E7C6B2","#E3BCA5","#DFB298","#DBA88B","#D69D7C","#D29470","#CE8B64","#CA8258","#C6794C","#C26E3F","#BE6533","#B85C28","#B2511D","#A94512","#9C3709","#912D06","#872406","#7E1D06","#741506","#6A0D07","#620607","#590008"]},viko:{discrete:["#4F1A3D","#4B1D43","#48214A","#432653","#3F2C5B","#3C3263","#38396C","#354174","#334B7F","#345487","#365E8F","#3B6797","#42719E","#4D7DA6","#5787AD","#6391B4","#709ABA","#7DA4BF","#8EAEC4","#9BB5C7","#A9BBC8","#B5C0C8","#C0C2C5","#CBC2BF","#D2C0B8","#D6BDAF","#D9B7A6","#D9AF99","#D8A88D","#D6A082","#D39776","#CF8D6B","#C8825D","#C27752","#BB6D47","#B3623D","#AA5633","#9F492A","#953E25","#8C3521","#822C1F","#7A251E","#721F1F","#6B1A21","#661824","#611627","#5C152B","#571631","#531736","#50193C"],categorical:["#4F1A3D","#4B1D43","#48214A","#432653","#3F2C5B","#3C3263","#38396C","#354174","#334B7F","#345487","#365E8F","#3B6797","#42719E","#4D7DA6","#5787AD","#6391B4","#709ABA","#7DA4BF","#8EAEC4","#9BB5C7","#A9BBC8","#B5C0C8","#C0C2C5","#CBC2BF","#D2C0B8","#D6BDAF","#D9B7A6","#D9AF99","#D8A88D","#D6A082","#D39776","#CF8D6B","#C8825D","#C27752","#BB6D47","#B3623D","#AA5633","#9F492A","#953E25","#8C3521","#822C1F","#7A251E","#721F1F","#6B1A21","#661824","#611627","#5C152B","#571631","#531736","#50193C"]}};function ct(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const dt={waves:"batlow",blksand:"tokyo",breeze:"imola",magma:"batlow",ribbon:"hawaii",stars:"batlow",folds:"imola"},ut={[st.ADVERT]:1,[st.TXT_MSG]:4,[st.GRP_TXT]:2,[st.RESPONSE]:8,[st.REQ]:13,[st.ANON_REQ]:7,[st.ACK]:11,[st.PATH]:24,[st.TRACE]:16,[st.GRP_DATA]:34,[st.MULTIPART]:52,[st.RAW_CUSTOM]:14};function ht(){let e="breeze dark",t=!0;if("undefined"!=typeof window){e=localStorage.getItem("pymc-theme-id")||"breeze dark";const a=Ee(e);t=(null==a?void 0:a.meta.isDark)??!0}const a=dt[e]??"batlow",n=lt[a],r=n.discrete.length,s=Math.floor(r/2);return{colormap:n,colormapName:a,isDark:t,baseIndex:t?s:0,halfSize:s}}let mt=null;function gt(e){const{colormap:t,isDark:a}=ht();if("number"!=typeof e)return a?"#A5A5A5":"#666666";const n=ut[e];if(void 0===n)return a?"#A5A5A5":"#666666";const r=t.categorical;return r[Math.min(n,r.length-1)]}function pt(e){const t=gt(e);return null===mt&&(mt=ye()),mt?function(e){return ye()?be(e):e}(t):t}function ft(e){return ct(gt(e))}function bt(e,t){return(Math.max(e,t)+.05)/(Math.min(e,t)+.05)}function yt(e){const t=function(e){const t=e.replace("#",""),a=parseInt(t.slice(0,2),16)/255,n=parseInt(t.slice(2,4),16)/255,r=parseInt(t.slice(4,6),16)/255,s=e=>e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*s(a)+.7152*s(n)+.0722*s(r)}(e);return bt(t,1)>bt(t,0)?"light":"dark"}function wt(e){return 1===e||!0===e}function Ct(e){return void 0===e?"bg-[var(--signal-unknown)]":e>=5?"bg-[var(--signal-excellent)]":e>=0?"bg-[var(--signal-good)]":e>=-5?"bg-[var(--signal-fair)]":e>=-10?"bg-[var(--signal-poor)]":"bg-[var(--signal-critical)]"}const kt=E("inline-flex items-center gap-1","radius-badge px-1.5 py-0.5","text-xs"),vt={fontFamily:"var(--font-badge)",fontWeight:"var(--font-badge-weight)",textTransform:"var(--badge-text-transform, none)"},Dt={red:"var(--sys-red)",orange:"var(--sys-orange)",amber:"var(--sys-amber)",yellow:"var(--sys-yellow)",lime:"var(--sys-green)",green:"var(--sys-green)",emerald:"var(--sys-green)",teal:"var(--sys-teal)",cyan:"var(--sys-cyan)",sky:"var(--sys-cyan)",blue:"var(--sys-blue)",indigo:"var(--sys-indigo)",violet:"var(--sys-indigo)",purple:"var(--sys-purple)",fuchsia:"var(--sys-pink)",pink:"var(--sys-pink)",rose:"var(--sys-red)",brown:"var(--sys-brown)",zinc:"var(--fg-muted)"};function At(e){if(!e.startsWith("var("))return e;if("undefined"!=typeof window){const t=e.match(/var\((--[^,)]+)/);if(t){const e=getComputedStyle(document.documentElement).getPropertyValue(t[1]).trim();if(e&&e.startsWith("#"))return e}}return"#666666"}function xt({color:e="zinc",customColor:t,filled:a=!1,compact:n=!1,className:r,title:i,children:l}){const c=s.useMemo(()=>{const n=t??Dt[e];if(a){if(t){const e=yt(At(t));return{backgroundColor:t,color:"light"===e?"rgba(255,255,255,0.95)":"rgba(0,0,0,0.85)"}}return{backgroundColor:n,color:["amber","yellow","lime"].includes(e)?"rgba(0,0,0,0.85)":"rgba(255,255,255,0.95)"}}return{backgroundColor:`color-mix(in srgb, ${n} 15%, transparent)`,color:n}},[e,t,a]);return o.jsx("span",{className:E(kt,n&&"!px-1 !py-0 !text-[10px]",r),style:{...vt,...c},"data-color":e,title:i,children:l})}const Et=s.forwardRef(function({color:e="zinc",customColor:t,filled:a=!1,compact:n=!1,className:r,children:i,...c},d){const u=s.useMemo(()=>{const n=t??Dt[e];if(a){if(t){const e=yt(At(t));return{backgroundColor:t,color:"light"===e?"rgba(255,255,255,0.95)":"rgba(0,0,0,0.85)"}}return{backgroundColor:n,color:["amber","yellow","lime"].includes(e)?"rgba(0,0,0,0.85)":"rgba(255,255,255,0.95)"}}return{backgroundColor:`color-mix(in srgb, ${n} 15%, transparent)`,color:n}},[e,t,a]),h=E(kt,n&&"!px-1 !py-0 !text-[10px]","interactive hover-opacity",r);return"href"in c&&void 0!==c.href?o.jsx(at,{...c,ref:d,className:h,style:{...vt,...u},children:i}):o.jsx(l,{...c,ref:d,className:h,style:{...vt,...u},children:i})}),Ft=E("relative inline-flex items-center justify-center gap-2","text-sm font-medium whitespace-nowrap","radius-inner px-3 py-1.5","ring-focus","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-base","[&>[data-slot=icon]]:w-4 [&>[data-slot=icon]]:h-4 [&>[data-slot=icon]]:shrink-0"),Bt={primary:E("bg-sys-blue text-white","hover:bg-sys-blue","active:bg-sys-blue/80","border-[1.5px] border-sys-blue"),success:E("bg-sys-green text-white","hover:bg-sys-green","active:bg-sys-green/80","border-[1.5px] border-sys-green"),danger:E("bg-sys-red text-white","hover:bg-sys-red","active:bg-sys-red/80","border-[1.5px] border-sys-red"),warning:E("bg-sys-indigo text-bg-body","hover:bg-sys-indigo","active:bg-sys-indigo/80","border-[1.5px] border-sys-indigo"),muted:E("bg-elevated text-fg-primary","hover:bg-subtle","active:bg-elevated","border-[1.5px] border-edge-subtle"),pink:E("bg-sys-pink text-white","hover:bg-sys-pink","active:bg-sys-pink/80","border-[1.5px] border-sys-pink"),amber:E("bg-sys-amber text-zinc-900","hover:bg-sys-amber","active:bg-sys-amber/80","border-[1.5px] border-sys-amber"),indigo:E("bg-sys-indigo text-white","hover:bg-sys-indigo","active:bg-sys-indigo/80","border-[1.5px] border-sys-indigo"),purple:E("bg-sys-purple text-white","hover:bg-sys-purple","active:bg-sys-purple/80","border-[1.5px] border-sys-purple"),zinc:E("bg-zinc-500 text-white","hover:bg-zinc-500","active:bg-zinc-500/80","border-[1.5px] border-zinc-500")},jt={primary:E("bg-transparent text-sys-blue","border-[1.5px] border-sys-blue","hover:bg-sys-blue hover:text-white hover:border-sys-blue","active:bg-sys-blue/90 active:text-white"),success:E("bg-transparent text-sys-green","border-[1.5px] border-sys-green","hover:bg-sys-green hover:text-white hover:border-sys-green","active:bg-sys-green/90 active:text-white"),danger:E("bg-transparent text-sys-red","border-[1.5px] border-sys-red","hover:bg-sys-red hover:text-white hover:border-sys-red","active:bg-sys-red/90 active:text-white"),warning:E("bg-transparent text-sys-indigo","border-[1.5px] border-sys-indigo","hover:bg-sys-indigo hover:text-bg-body hover:border-sys-indigo","active:bg-sys-indigo/90 active:text-bg-body"),muted:E("bg-transparent text-fg-muted","border-[1.5px] border-edge-subtle","hover:bg-subtle hover:text-fg-primary hover:border-edge-strong","active:bg-elevated"),pink:E("bg-transparent text-sys-pink","border-[1.5px] border-sys-pink","hover:bg-sys-pink hover:text-white hover:border-sys-pink","active:bg-sys-pink/90 active:text-white"),amber:E("bg-transparent text-sys-amber","border-[1.5px] border-sys-amber","hover:bg-sys-amber hover:text-zinc-900 hover:border-sys-amber","active:bg-sys-amber/90 active:text-zinc-900"),indigo:E("bg-transparent text-sys-indigo","border-[1.5px] border-sys-indigo","hover:bg-sys-indigo hover:text-white hover:border-sys-indigo","active:bg-sys-indigo/90 active:text-white"),purple:E("bg-transparent text-sys-purple","border-[1.5px] border-sys-purple","hover:bg-sys-purple hover:text-white hover:border-sys-purple","active:bg-sys-purple/90 active:text-white"),zinc:E("bg-transparent text-fg-muted","border-[1.5px] border-edge-subtle","hover:bg-zinc-500 hover:text-white hover:border-zinc-500","active:bg-zinc-500/90 active:text-white")},St={primary:E("bg-transparent text-sys-blue border-transparent","hover:bg-sys-blue hover:text-white","active:bg-sys-blue/90 active:text-white"),success:E("bg-transparent text-sys-green border-transparent","hover:bg-sys-green hover:text-white","active:bg-sys-green/90 active:text-white"),danger:E("bg-transparent text-sys-red border-transparent","hover:bg-sys-red hover:text-white","active:bg-sys-red/90 active:text-white"),warning:E("bg-transparent text-sys-indigo border-transparent","hover:bg-sys-indigo hover:text-bg-body","active:bg-sys-indigo/90 active:text-bg-body"),muted:E("bg-transparent text-fg-muted border-transparent","hover:bg-subtle hover:text-fg-primary","active:bg-elevated"),pink:E("bg-transparent text-sys-pink border-transparent","hover:bg-sys-pink hover:text-white","active:bg-sys-pink/90 active:text-white"),amber:E("bg-transparent text-sys-amber border-transparent","hover:bg-sys-amber hover:text-zinc-900","active:bg-sys-amber/90 active:text-zinc-900"),indigo:E("bg-transparent text-sys-indigo border-transparent","hover:bg-sys-indigo hover:text-white","active:bg-sys-indigo/90 active:text-white"),purple:E("bg-transparent text-sys-purple border-transparent","hover:bg-sys-purple hover:text-white","active:bg-sys-purple/90 active:text-white"),zinc:E("bg-transparent text-zinc-400 border-transparent","hover:bg-zinc-500 hover:text-white","active:bg-zinc-500/90 active:text-white")},Mt=s.forwardRef(function({color:e="muted",outline:t=!1,plain:a=!1,className:n,children:r,...s},i){const c=E(Ft,a?St[e]:t?jt[e]:Bt[e],n);return"href"in s&&void 0!==s.href?o.jsx(at,{...s,ref:i,className:c,children:r}):o.jsx(l,{...s,ref:i,className:c,children:r})}),Nt={duration:.15,ease:[.4,0,.2,1]},Lt={type:"tween",duration:.25,ease:[.4,0,.2,1]},Tt={type:"tween",duration:.3,ease:[.4,0,.2,1]},_t=s.createContext(!1);function Rt(){return s.useContext(_t)}const zt=s.createContext(void 0);function Pt(){return s.useContext(zt)}const It="#1A1A1A",$t="#737373",qt={xs:"sm:max-w-xs",sm:"sm:max-w-sm",md:"sm:max-w-md",lg:"sm:max-w-lg",xl:"sm:max-w-xl","2xl":"sm:max-w-2xl","3xl":"sm:max-w-3xl","4xl":"sm:max-w-4xl","5xl":"sm:max-w-5xl",full:"sm:max-w-[calc(100vw-2rem)]"};function Ot({open:e,onClose:t,size:a="md",className:n,children:r,bottomSheet:i=!0,motionPlus:l=!1,basemapMode:u,solid:h=!1}){const m="light"===u,[g,p]=s.useState(!1),f=s.useRef(null);s.useEffect(()=>(f.current&&(clearTimeout(f.current),f.current=null),e?f.current=setTimeout(()=>{p(!0)},350):queueMicrotask(()=>p(!1)),()=>{f.current&&(clearTimeout(f.current),f.current=null)}),[e]);const b=s.useCallback((e,a)=>{(a.offset.y>100||a.velocity.y>500)&&t()},[t]),y=l?Tt:Lt,w=l?.98:.99,C=i?8:4;return o.jsx(T,{mode:"wait",children:e&&o.jsxs(c,{static:!0,open:e,onClose:t,className:"relative z-[10010]",children:[o.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:Nt,className:"fixed inset-0 bg-black/50 backdrop-blur-sm","aria-hidden":"true"}),o.jsx("div",{className:"fixed inset-0 overflow-y-auto",children:o.jsx("div",{className:E("flex min-h-full justify-center",i?"items-end sm:items-center sm:p-4":"items-center p-4"),children:o.jsx(_.div,{drag:!!i&&"y",dragConstraints:{top:0,bottom:0},dragElastic:{top:0,bottom:.4},onDragEnd:b,initial:{opacity:0,scale:w,y:C},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.99,y:i?40:4},transition:y,style:{willChange:"transform, opacity"},className:E(i&&"w-full sm:w-auto"),children:o.jsx(d,{className:E("relative w-full shadow-2xl flex flex-col",!u&&!h&&"bg-surface/80 backdrop-blur-xl",!u&&h&&"bg-surface",!u&&"ring-1 ring-inset ring-edge-subtle",qt[a],i?"radius-card overflow-hidden pb-safe":"radius-card overflow-hidden",n),style:u?{backgroundColor:m?"#F8F8F8":"var(--surface)",boxShadow:"inset 0 0 0 1px "+(m?"rgba(0, 0, 0, 0.08)":"rgba(255, 255, 255, 0.1)")}:void 0,children:o.jsx(zt.Provider,{value:u,children:o.jsx(_t.Provider,{value:g,children:r})})})})})})]})})}function Ht({className:e,...t}){const a=Pt(),n="light"===a;return o.jsx(u,{...t,className:E("text-base font-semibold sm:text-lg",!a&&"text-fg-primary",e),style:a?{color:n?It:"var(--fg-primary)"}:void 0})}function Wt({icon:e,title:t,onClose:a,className:n}){const r=Pt(),s="light"===r;return o.jsxs("div",{className:E("flex items-center justify-between px-4 sm:px-6 py-3 sm:py-4 border-b",!r&&"border-edge-subtle",n),style:r?{borderColor:s?"rgba(0, 0, 0, 0.12)":"var(--edge-subtle)"}:void 0,children:[o.jsxs("div",{className:"flex items-center gap-3",children:[e&&o.jsx("div",{className:E(!r&&"text-icon-card-title"),style:r?{color:s?"#4A4A4A":"var(--icon-card-title)"}:void 0,children:e}),o.jsx(Ht,{children:t})]}),a&&o.jsxs(o.Fragment,{children:[o.jsx("button",{onClick:a,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),o.jsx("button",{onClick:a,className:E("hidden sm:flex items-center justify-center p-2 radius-inner transition-colors",!r&&"text-fg-muted hover:text-fg-primary hover:bg-subtle"),style:r?{color:s?$t:"var(--fg-muted)"}:void 0,onMouseEnter:e=>{r&&(e.currentTarget.style.color=s?It:"var(--fg-primary)",e.currentTarget.style.backgroundColor=s?"rgba(0, 0, 0, 0.06)":"var(--subtle)")},onMouseLeave:e=>{r&&(e.currentTarget.style.color=s?$t:"var(--fg-muted)",e.currentTarget.style.backgroundColor="transparent")},"aria-label":"Close",children:o.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}function Ut({className:e,...t}){return o.jsx("div",{...t,className:E("px-6 py-5",e)})}function Vt({className:e,...t}){return o.jsx("div",{...t,className:E("flex flex-col-reverse gap-3 px-6 pb-6 pt-0","sm:flex-row sm:justify-end","*:w-full sm:*:w-auto",e)})}const Gt={snappy:{type:"spring",stiffness:500,damping:30},smooth:{type:"spring",stiffness:300,damping:30},gentle:{type:"spring",stiffness:200,damping:25}},Jt={fast:.15,normal:.2,medium:.3},Kt={easeOut:[0,0,.2,1],easeIn:[.4,0,1,1]},Xt={dropdown:{type:"spring",stiffness:500,damping:30},fade:{duration:Jt.fast,ease:Kt.easeOut},numberTicker:{type:"spring",visualDuration:.4,bounce:.15,opacity:{duration:.15,ease:"linear"}},numberReveal:{type:"spring",visualDuration:.6,bounce:.25,opacity:{duration:.2,ease:"linear"}}},Yt={normal:.05};function Qt({className:e,...t}){return o.jsx("nav",{...t,className:E(e,"flex h-full min-h-0 flex-col")})}function Zt({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex flex-col border-b border-edge-subtle p-4","[&>[data-slot=section]+[data-slot=section]]:mt-2.5")})}function ea({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex flex-1 flex-col p-3","overflow-y-auto sidebar-scroll","[&>[data-slot=section]+[data-slot=section]]:mt-6")})}function ta({className:e,...t}){return o.jsx("div",{...t,className:E(e,"mt-auto flex flex-col","[&>[data-slot=section]+[data-slot=section]]:mt-2.5")})}function aa({className:e,...t}){const a=s.useId();return o.jsx(R,{id:a,children:o.jsx("div",{...t,"data-slot":"section",className:E(e,"flex flex-col gap-0.5")})})}const na=s.forwardRef(function(e,t){const{current:a,className:n,children:r,accentColor:s,...i}=e,c=!!s,d=E("relative isolate flex w-full items-center gap-3 radius-inner px-3 py-2 text-left","min-h-[38px]","text-sm font-medium","[&>svg]:w-4 [&>svg]:h-4 [&>svg]:flex-shrink-0",a?c?"text-white":"text-white [&_svg]:text-sys-blue":"text-fg-muted hover:text-fg-primary hover:bg-elevated [&_svg]:text-fg-muted hover:[&_svg]:text-fg-primary","transition-all duration-150"),u=c?{willChange:"transform",backgroundColor:s,boxShadow:[`0 0 10px 2px color-mix(in oklch, ${s} 50%, transparent)`,`0 0 4px 0 color-mix(in oklch, ${s} 70%, transparent)`].join(", ")}:{willChange:"transform"},h=c?{willChange:"transform",background:"transparent",boxShadow:[`inset 0 0 0 1.5px ${s}`,`inset 0 0 3px 0.5px color-mix(in oklch, ${s} 30%, transparent)`,`inset 0 0 6px 1px color-mix(in oklch, ${s} 14%, transparent)`,`inset 0 0 10px 2px color-mix(in oklch, ${s} 5%, transparent)`,`0 0 20px -4px color-mix(in oklch, ${s} 22%, transparent)`,`0 0 8px -2px color-mix(in oklch, ${s} 14%, transparent)`].join(", ")}:{willChange:"transform"};return o.jsxs("span",{className:E(n,"relative"),children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-indicator",className:E("absolute inset-y-2 -left-3 w-0.5 rounded-full",!c&&"bg-sys-blue sidebar-neo-indicator"),style:u,transition:Gt.snappy}),"string"==typeof i.href?o.jsxs(x,{to:i.href,onClick:i.onClick,onMouseEnter:i.onMouseEnter,onMouseLeave:i.onMouseLeave,className:d,"data-current":a?"true":void 0,ref:t,children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-highlight",className:E("absolute inset-0 radius-inner z-[-1]",!c&&"sidebar-neo-highlight"),style:h,transition:Gt.snappy}),r]}):o.jsxs(l,{...i,className:E("cursor-default",d),"data-current":a?"true":void 0,ref:t,children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-highlight",className:E("absolute inset-0 radius-inner z-[-1]",!c&&"sidebar-neo-highlight"),style:h,transition:Gt.snappy}),r]})]})});function ra({className:e,...t}){return o.jsx("span",{...t,className:E(e,"truncate")})}function sa({className:e,variant:t="default",...a}){return o.jsx("span",{...a,className:E("ml-auto flex items-center gap-1 px-1.5 py-0.5 rounded-full","text-xs font-medium",{default:"bg-subtle text-fg-muted",accent:"bg-sys-blue/20 text-sys-blue",success:"bg-sys-green/20 text-sys-green",warning:"bg-sys-indigo/20 text-sys-indigo",danger:"bg-sys-red/20 text-sys-red"}[t],e)})}const oa=s.createContext(null),ia={type:"spring",visualDuration:.35,bounce:.15};function la({open:e,onClose:t,children:a}){return o.jsx(T,{children:e&&o.jsxs(c,{static:!0,open:e,onClose:t,className:"lg:hidden relative z-[10002]",children:[o.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.25,ease:"easeOut"},className:"fixed inset-0 bg-black/60 backdrop-blur-sm","aria-hidden":"true"}),o.jsx(_.div,{initial:{x:"-100%"},animate:{x:0},exit:{x:"-100%"},transition:ia,className:"fixed inset-y-0 left-0 w-72 max-w-[85vw] z-[10003]",children:o.jsx(d,{className:"h-full",children:o.jsxs("div",{className:"flex h-full flex-col sidebar-panel",children:[o.jsx("div",{className:"absolute top-4 right-4 z-10",children:o.jsx(h,{className:"p-2 rounded-lg text-fg-muted hover:text-fg-primary hover:bg-subtle-fill transition-colors","aria-label":"Close navigation",children:o.jsx(P,{className:"w-5 h-5"})})}),a]})})})]})})}function ca({sidebar:e,navbar:t,children:a,className:n}){const[r,i]=s.useState(!1),l=()=>i(!0),c=()=>i(!1),d={isOpen:r,open:l,close:c,toggle:()=>i(e=>!e)};return o.jsx(oa.Provider,{value:d,children:o.jsxs("div",{className:"flex h-screen overflow-hidden bg-body",children:[o.jsx("aside",{className:"hidden lg:flex flex-col w-64 flex-shrink-0 h-full relative sidebar-panel",children:e}),o.jsx(la,{open:r,onClose:c,children:e}),o.jsxs("div",{className:"flex-1 flex flex-col min-w-0",children:[o.jsx("header",{className:"lg:hidden sticky top-0 z-[10001] h-14 mobile-header",children:o.jsxs("div",{className:"flex items-center h-full px-4",children:[o.jsx("button",{onClick:l,className:"w-10 h-10 flex items-center justify-center rounded-lg hover:bg-subtle-fill active:bg-subtle-fill transition-colors mr-2","aria-label":"Open navigation",children:o.jsx(z,{className:"w-5 h-5 text-fg-primary"})}),o.jsx("div",{className:"flex-1 min-w-0",children:t})]})}),o.jsx("main",{className:E("flex-1 overflow-y-auto main-content",n),children:a})]})]})})}function da({className:e,...t}){return o.jsx("nav",{...t,className:E(e,"flex flex-1 items-center gap-3")})}function ua({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex items-center gap-3")})}function ha({className:e,...t}){return o.jsx("div",{"aria-hidden":"true",...t,className:E(e,"flex-1")})}const ma=[45,72,33,58,80,42,65,28,55,75,38,62];function ga({className:e,style:t}){return o.jsx("div",{className:E("animate-pulse bg-subtle-fill radius-badge",e),style:t})}function pa(){return o.jsx("div",{className:"p-3 radius-inner border-card bg-subtle",children:o.jsxs("div",{className:"flex items-start gap-3",children:[o.jsx(ga,{className:"w-14 h-6 rounded shrink-0"}),o.jsxs("div",{className:"flex-1 min-w-0 space-y-2",children:[o.jsx(ga,{className:"h-4 w-full"}),o.jsx(ga,{className:"h-4 w-3/4"}),o.jsx(ga,{className:"h-3 w-32 mt-1"})]})]})})}function fa({count:e=8}){return o.jsx("div",{className:"space-y-2",children:Array.from({length:e}).map((e,t)=>o.jsx(pa,{},t))})}function ba(){return o.jsxs("div",{className:"flex flex-col gap-3 h-full","aria-hidden":"true",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]}),o.jsx(ga,{className:"h-8 w-20"}),o.jsxs("div",{className:"flex-1 flex flex-col justify-end gap-2",children:[o.jsx(ga,{className:"h-3 w-full"}),o.jsx(ga,{className:"h-3 w-3/4"})]})]})}function ya(){return o.jsxs("div",{className:"flex flex-col gap-3 h-full","aria-hidden":"true",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]}),o.jsx("div",{className:"flex-1 flex items-end gap-1",children:ma.slice(0,8).map((e,t)=>o.jsx(ga,{className:"flex-1",style:{height:`${e}%`}},t))})]})}function wa({rows:e=5}){return o.jsxs("div",{className:"flex flex-col h-full","aria-hidden":"true",children:[o.jsx("div",{className:"pb-3 border-b border-edge-subtle",children:o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]})}),o.jsx("div",{className:"flex-1 pt-3 flex flex-col gap-3",children:Array.from({length:e}).map((e,t)=>o.jsx(ga,{className:"h-6 w-full"},t))})]})}const Ca={sm:"radius-inner",md:"radius-inset",lg:"radius-card",xl:"radius-hero",full:"radius-pill",none:"radius-none"},ka=s.forwardRef(function({children:e,elevated:t,compact:a,noPadding:n,radius:r="lg",glass:s=!0,stroke:i=!0,shadow:l,reflex:c=!1,glow:d=!1,neomorphic:u=!0,onClick:h,className:m,style:g,isLoaded:p=!0,skeletonType:f="card",...b},y){const w={...g,...c?{"--surface-reflex":"1"}:{}},C=E(Ca[r],s&&(t?"bg-surface/85 backdrop-blur-xl":"bg-surface/80 backdrop-blur-lg"),!s&&"bg-surface",u&&"depth-raised",i&&!u&&!d&&"ring-1 ring-inset ring-edge-subtle",d&&"ring-1 ring-inset ring-sys-blue/40",(l??t??!1)&&(t?"shadow-xl":"shadow-lg"),c&&"surface-reflex","h-full flex flex-col relative",!n&&(a?"p-3 sm:p-4":"p-4 sm:p-5"),h&&"cursor-pointer",m);return p?o.jsx("div",{ref:y,"data-card-surface":!0,className:C,style:w,onClick:h,...b,children:e}):o.jsx("div",{ref:y,"data-card-surface":!0,className:C,style:w,...b,children:(()=>{switch(f){case"chart":return o.jsx(ya,{});case"list":return o.jsx(wa,{});default:return o.jsx(ba,{})}})()})});function va({title:e,icon:t,badge:a,badgeColor:n="teal",subtitle:r,actions:s,iconColor:i="text-icon-card-title",listHeader:l=!1,stackActionsOnMobile:c=!1,stackBreakpoint:d="sm",titleExtra:u,onClick:h,className:m}){const g="px-5 py-4 border-b border-edge-subtle",p=o.jsxs(o.Fragment,{children:[t&&o.jsx("span",{className:E("icon-md flex items-center justify-center",i),children:t}),o.jsx("span",{className:"type-micro",children:e}),a&&o.jsx(xt,{color:n,children:a}),u]}),f=h?"button":"div",b=h?{onClick:h,type:"button"}:{};return c&&s?o.jsxs(f,{...b,className:E("flex flex-col gap-1 flex-shrink-0",l?g:"mb-3",h&&"w-full text-left cursor-pointer",m),children:[o.jsxs("div",{className:{sm:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 min-h-[32px]",md:"flex flex-col md:flex-row md:items-center md:justify-between gap-2 min-h-[32px]",lg:"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-2 min-h-[32px]"}[d],children:[o.jsx("div",{className:"flex items-center gap-3",children:p}),o.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:s})]}),r&&o.jsx("p",{className:"type-label text-fg-muted ml-8",children:r})]}):o.jsxs(f,{...b,className:E("flex flex-col gap-1 flex-shrink-0",l?g:"mb-3",h&&"w-full text-left cursor-pointer",m),children:[o.jsxs("div",{className:"flex items-center justify-between gap-2 min-h-[32px]",children:[o.jsx("div",{className:"flex items-center gap-3",children:p}),s&&o.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:s})]}),r&&o.jsx("p",{className:"type-label text-fg-muted ml-8",children:r})]})}s.forwardRef(function({children:e,icon:t,className:a,...n},r){return o.jsxs("h3",{ref:r,className:E("flex items-center gap-2","text-base font-semibold text-fg-primary",a),...n,children:[t&&o.jsx("span",{className:"text-icon-card-title w-5 h-5 flex-shrink-0",children:t}),e]})}),s.forwardRef(function({children:e,className:t,...a},n){return o.jsx("p",{ref:n,className:E("text-sm text-fg-muted",t),...a,children:e})});const Da=s.forwardRef(function({children:e,centered:t,className:a,...n},r){return o.jsx("div",{ref:r,className:E("flex-1 min-h-0",t&&"flex items-center justify-center",a),...n,children:e})});function Aa({defaultOpen:e=!1,className:t,children:a}){return o.jsx(g,{defaultOpen:e,children:o.jsx("div",{className:E("flex flex-col",t),children:a})})}s.forwardRef(function({children:e,className:t,...a},n){return o.jsx("div",{ref:n,className:E("flex items-center justify-end gap-3","pt-4 mt-4","border-t border-edge-subtle",t),...a,children:e})}),s.forwardRef(function({children:e,border:t,className:a,...n},r){return o.jsx("div",{ref:r,className:E(t&&"pt-4 mt-4 border-t border-edge-subtle",a),...n,children:e})});const xa=s.forwardRef(function({className:e,icon:t,children:a,...n},r){return o.jsx(m,{ref:r,className:E("flex w-full items-center justify-between gap-3","px-3 py-2 radius-inner","text-sm font-medium text-fg-muted","row-hover hover:text-fg-primary","ring-focus",e),...n,children:({open:e})=>o.jsxs(o.Fragment,{children:[a,o.jsx("span",{className:E("transition-transform duration-200",e?"rotate-180":"rotate-0"),children:t||o.jsx(I,{className:"w-4 h-4"})})]})})});function Ea({direction:e="down",className:t,children:a}){const n={hidden:{height:0,opacity:0,y:"up"===e?8:-8},visible:{height:"auto",opacity:1,y:0}};return o.jsx(p,{static:!0,children:({open:r})=>o.jsx(T,{initial:!1,children:r&&o.jsx(_.div,{initial:"hidden",animate:"visible",exit:"hidden",variants:n,transition:{height:{duration:.2,ease:[.4,0,.2,1]},opacity:{duration:.15},y:{duration:.15}},className:E("overflow-hidden",t),children:o.jsx("div",{className:E("up"===e?"pb-2":"pt-2"),children:a})})})})}function Fa({label:e,icon:t,defaultOpen:a=!0,direction:n="down",className:r,dataId:s,children:i}){const l=s?{[`data-${s}-disclosure`]:!0}:{},c=o.jsxs("span",{className:"flex items-center gap-3",children:[t&&o.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:t}),o.jsx("span",{className:"type-micro",children:e})]});return"up"===n?o.jsx(g,{defaultOpen:a,children:({open:a})=>o.jsxs("div",{className:E("relative",r),children:[o.jsx(p,{static:!0,className:"relative z-50",children:o.jsx(T,{initial:!1,mode:"wait",children:a&&o.jsxs(_.div,{initial:{y:12,scale:.97,opacity:0},animate:{y:0,scale:1,opacity:1},exit:{y:6,scale:.98,opacity:0},transition:{type:"spring",stiffness:400,damping:32,mass:.8,opacity:{duration:.15,ease:[.4,0,.2,1]}},className:"absolute bottom-full left-0 right-0 z-50 mb-1 origin-bottom radius-inset shadow-lg border-card bg-surface/75 backdrop-blur-sm",children:[o.jsxs("div",{className:"flex items-center justify-between px-3 py-2",children:[o.jsxs("span",{className:"flex items-center gap-3",children:[t&&o.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:t}),o.jsx("span",{className:"type-micro",children:e})]}),o.jsx(m,{className:"p-1 rounded hover:bg-subtle-fill-strong transition-colors",children:o.jsx(_.span,{initial:{rotate:0},animate:{rotate:180},exit:{rotate:0},transition:{type:"spring",stiffness:400,damping:25},children:o.jsx(I,{className:"w-4 h-4"})})})]}),o.jsx("div",{className:"px-3 pb-3",children:i})]})})}),o.jsx(_.div,{animate:{opacity:a?.4:1,scale:a?.98:1},transition:{type:"spring",stiffness:500,damping:35},children:o.jsxs(m,{...l,className:E("flex w-full items-center justify-between gap-3","px-3 py-3.5 rounded-none rounded-t-lg","bg-surface depth-stroke-raised","text-sm font-medium text-fg-muted","hover:bg-elevated hover:text-fg-primary transition-colors","ring-focus"),children:[c,o.jsx(_.span,{animate:{rotate:a?180:0},transition:{type:"spring",stiffness:400,damping:25},children:o.jsx(I,{className:"w-4 h-4"})})]})})]})}):o.jsxs(Aa,{defaultOpen:a,className:r,children:[o.jsx(xa,{...l,children:c}),o.jsx(Ea,{direction:"down",children:o.jsx("div",{className:"bg-subtle-fill radius-inset mx-1 mt-1",children:i})})]})}function Ba({placement:e}){const t=E("absolute w-2 h-2 rotate-45","top"===e&&"bottom-[-4px] left-1/2 -translate-x-1/2","bottom"===e&&"top-[-4px] left-1/2 -translate-x-1/2","left"===e&&"right-[-4px] top-1/2 -translate-y-1/2","right"===e&&"left-[-4px] top-1/2 -translate-y-1/2");return o.jsx("span",{className:t,style:{backgroundColor:"var(--tooltip-bg)"}})}function ja({content:e,children:t,placement:a="top",delay:n=200,arrow:r=!0,disabled:i=!1,className:l}){const[c,d]=s.useState(!1),[u,h]=s.useState({top:0,left:0}),[m,g]=s.useState(!1),p=s.useRef(null),b=s.useRef(null),y=s.useRef();s.useEffect(()=>{g(!0)},[]),s.useEffect(()=>{if(!c||!p.current||!b.current)return;const e=p.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),n=function(e,t,a){const n=window.scrollY,r=window.scrollX;switch(a){case"top":return{top:e.top+n-t.height-8,left:e.left+r+(e.width-t.width)/2};case"bottom":return{top:e.bottom+n+8,left:e.left+r+(e.width-t.width)/2};case"left":return{top:e.top+n+(e.height-t.height)/2,left:e.left+r-t.width-8};case"right":return{top:e.top+n+(e.height-t.height)/2,left:e.right+r+8}}}(e,t,a),r=window.innerWidth-t.width-8,s=window.innerHeight+window.scrollY-t.height-8;h({top:Math.max(8,Math.min(n.top,s)),left:Math.max(8,Math.min(n.left,r))})},[c,a]);const w=s.useCallback(()=>{i||(y.current=setTimeout(()=>{d(!0)},n))},[n,i]),C=s.useCallback(()=>{y.current&&clearTimeout(y.current),d(!1)},[]);if(s.useEffect(()=>()=>{y.current&&clearTimeout(y.current)},[]),!s.isValidElement(t))return t;const k=s.cloneElement(t,{ref:p,onMouseEnter:e=>{var a,n;w(),null==(n=(a=t.props).onMouseEnter)||n.call(a,e)},onMouseLeave:e=>{var a,n;C(),null==(n=(a=t.props).onMouseLeave)||n.call(a,e)},onFocus:e=>{var a,n;w(),null==(n=(a=t.props).onFocus)||n.call(a,e)},onBlur:e=>{var a,n;C(),null==(n=(a=t.props).onBlur)||n.call(a,e)}}),v=(e=>({hidden:{opacity:0,scale:.96,...{top:{y:4},bottom:{y:-4},left:{x:4},right:{x:-4}}[e]},visible:{opacity:1,scale:1,x:0,y:0}}))(a),D=o.jsx(T,{children:c&&o.jsxs(_.div,{ref:b,initial:"hidden",animate:"visible",exit:"hidden",variants:v,transition:{duration:.15,ease:"easeOut"},className:E("fixed z-[10020] px-2.5 py-1.5 text-xs font-medium","rounded-lg","pointer-events-none",l),style:{top:u.top,left:u.left,backgroundColor:"var(--tooltip-bg)",color:"var(--tooltip-fg)",border:"1px solid var(--tooltip-border)",boxShadow:"var(--tooltip-shadow)"},role:"tooltip",children:[e,r&&o.jsx(Ba,{placement:a})]})});return o.jsxs(o.Fragment,{children:[k,m&&f.createPortal(D,document.body)]})}const Sa={sm:{track:"h-5 w-9",thumb:"h-3.5 w-3.5",translate:"translate-x-[18px]",icon:"w-3 h-3",dot:"w-2 h-2"},md:{track:"h-6 w-11",thumb:"h-4 w-4",translate:"translate-x-[22px]",icon:"w-4 h-4",dot:"w-2.5 h-2.5"},lg:{track:"h-7 w-14",thumb:"h-5 w-5",translate:"translate-x-[30px]",icon:"w-4 h-4",dot:"w-3 h-3"}},Ma=s.forwardRef(function({enabled:e,onChange:t,label:a,description:n,tooltip:r,size:s="md",color:i="muted",dangerOff:l=!1,disabled:c=!1,status:d="idle",name:u,className:h},m){const g=Sa[s],p="loading"===d,f="muted"===i;return o.jsxs(b,{disabled:c||p,className:E("flex items-center gap-3",h),children:[o.jsx(y,{ref:m,checked:e,onChange:t,name:u,className:E(f?"toggle-switch-track":"group relative inline-flex shrink-0 items-center rounded-full border-2",g.track,!f&&(e?"bg-toggle-on border-toggle-on":"bg-toggle-off border-edge-subtle"),"disabled:opacity-50 disabled:cursor-not-allowed","ring-focus","transition-all duration-200"),"data-size":s,children:o.jsx("span",{className:E(f?"toggle-switch-thumb":"relative inline-flex items-center justify-center bg-white shadow-lg","transform rounded-full transition-transform duration-200",g.thumb,e?g.translate:"translate-x-[4px]"),children:f&&o.jsx("span",{className:E("toggle-switch-dot",g.dot,l?E("opacity-100",!e&&"toggle-switch-dot-danger"):e?"opacity-100":"opacity-0")})})}),(a||n||r)&&o.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[a&&o.jsx(w,{className:E("text-sm font-medium cursor-pointer select-none",c?"text-fg-muted":"text-fg-primary"),children:a}),r&&o.jsx(ja,{content:r,placement:"top",children:o.jsx("span",{className:"text-fg-muted hover:text-fg-secondary cursor-help transition-colors",children:o.jsx($,{className:"w-3.5 h-3.5"})})}),n&&!r&&o.jsx(C,{className:"text-xs text-fg-muted",children:n})]}),"idle"!==d&&o.jsxs("div",{className:"flex items-center shrink-0",children:["loading"===d&&o.jsx(q,{className:E(g.icon,"text-fg-muted animate-spin")}),"success"===d&&o.jsx(O,{className:E(g.icon,"text-sys-green")}),"error"===d&&o.jsx(P,{className:E(g.icon,"text-sys-red")})]})]})}),Na=s.forwardRef(function({enabled:e,onChange:t,size:a="md",disabled:n=!1,"aria-label":r,className:s},i){const l=Sa[a];return o.jsx(y,{ref:i,checked:e,onChange:t,disabled:n,"aria-label":r,className:E("toggle-switch-track",l.track,"disabled:opacity-50 disabled:cursor-not-allowed","ring-focus","transition-all duration-200",s),"data-size":a,children:o.jsx("span",{className:E("toggle-switch-thumb","transform rounded-full transition-transform duration-200",l.thumb,e?l.translate:"translate-x-[4px]"),children:o.jsx("span",{className:E("toggle-switch-dot",l.dot,e?"opacity-100":"opacity-0")})})})}),La={sm:{input:"h-8 text-sm px-3",icon:"w-4 h-4",iconPadding:"pl-8",trailingIconPadding:"pr-8"},md:{input:"h-[38px] text-sm px-4",icon:"w-4 h-4",iconPadding:"pl-10",trailingIconPadding:"pr-10"},lg:{input:"h-11 text-base px-4",icon:"w-5 h-5",iconPadding:"pl-11",trailingIconPadding:"pr-11"}},Ta=s.forwardRef(function({type:e="text",size:t="md",invalid:a=!1,leadingIcon:n,trailingIcon:r,leadingAddon:s,trailingAddon:i,className:l,disabled:c,...d},u){const h=La[t],m=n||s,g=r||i;return s||i?o.jsxs("div",{className:E("flex",l),children:[s&&o.jsx("span",{className:E("inline-flex items-center px-3 rounded-l-lg border border-r-0","bg-input-bg text-fg-muted text-sm",a?"border-sys-red":"border-input-border"),children:s}),o.jsx("input",{ref:u,type:e,disabled:c,className:E("flex-1 min-w-0 font-mono",h.input,"bg-input-bg",a?"border border-sys-red":"border border-input-border","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!c&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors",s&&!i&&"rounded-r-lg",i&&!s&&"rounded-l-lg",!s&&!i&&"radius-inner"),...d}),i&&o.jsx("span",{className:E("inline-flex items-center px-3 rounded-r-lg border border-l-0","bg-input-bg text-fg-muted text-sm",a?"border-sys-red":"border-input-border"),children:i})]}):o.jsxs("div",{className:E("relative",l),children:[n&&o.jsx("div",{className:E("absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none","text-fg-muted"),children:o.jsx("span",{className:h.icon,children:n})}),o.jsx("input",{ref:u,type:e,disabled:c,className:E("w-full radius-inner font-mono",h.input,m&&h.iconPadding,g&&h.trailingIconPadding,"bg-input-bg",a?"border border-sys-red":"border border-input-border","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!c&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors"),...d}),r&&o.jsx("div",{className:E("absolute inset-y-0 right-0 flex items-center pr-3","text-fg-muted"),children:o.jsx("span",{className:h.icon,children:r})})]})}),_a=s.forwardRef(function({label:e,description:t,errorMessage:a,required:n,invalid:r,className:s,...i},l){const c=r&&a;return o.jsxs(b,{className:E("flex flex-col gap-1.5",s),children:[e&&o.jsxs(w,{className:"text-sm font-medium text-fg-primary",children:[e,n&&o.jsx("span",{className:"text-sys-red ml-0.5",children:"*"})]}),t&&!c&&o.jsx(C,{className:"text-xs text-fg-muted -mt-0.5",children:t}),o.jsx(Ta,{ref:l,invalid:r,...i}),c&&o.jsx("p",{className:"text-xs text-sys-red",children:a})]})});s.forwardRef(function({value:e,onChange:t,min:a,max:n,step:r=1,precision:s,...i},l){const c=void 0!==s&&"number"==typeof e?e.toFixed(s):e;return o.jsx(Ta,{ref:l,type:"number",value:c,onChange:e=>{const r=e.target.value;if(""===r||"-"===r)return void t(0);const s=parseFloat(r);if(!isNaN(s)){const e=void 0!==a&&void 0!==n?Math.min(Math.max(s,a),n):void 0!==a?Math.max(s,a):void 0!==n?Math.min(s,n):s;t(e)}},min:a,max:n,step:r,...i})});const Ra={none:"resize-none",vertical:"resize-y",horizontal:"resize-x",both:"resize"},za=s.forwardRef(function({rows:e=3,resize:t="vertical",invalid:a=!1,disabled:n,className:r,...s},i){return o.jsx("textarea",{ref:i,rows:e,disabled:n,className:E("w-full radius-inner px-4 py-3 text-sm",Ra[t],"bg-subtle",a?"border border-sys-red":"border-control","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!n&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors",r),...s})});s.forwardRef(function({label:e,description:t,errorMessage:a,required:n,invalid:r,showCount:s,maxLength:i,value:l,className:c,...d},u){const h=r&&a,m="string"==typeof l?l.length:0;return o.jsxs(b,{className:E("flex flex-col gap-1.5",c),children:[e&&o.jsxs(w,{className:"text-sm font-medium text-fg-primary",children:[e,n&&o.jsx("span",{className:"text-sys-red ml-0.5",children:"*"})]}),t&&!h&&o.jsx(C,{className:"text-xs text-fg-muted -mt-0.5",children:t}),o.jsx(za,{ref:u,invalid:r,maxLength:i,value:l,...d}),o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[h?o.jsx("p",{className:"text-xs text-sys-red flex-1",children:a}):o.jsx("span",{}),s&&i&&o.jsxs("span",{className:E("text-xs",m>i?"text-sys-red":"text-fg-muted"),children:[m,"/",i]})]})]})});const Pa={sm:{box:"h-4 w-4",icon:"h-3 w-3",radius:"rounded"},md:{box:"h-5 w-5",icon:"h-3.5 w-3.5",radius:"rounded-md"},lg:{box:"h-6 w-6",icon:"h-4 w-4",radius:"rounded-md"}},Ia=s.forwardRef(function({checked:e,onChange:t,indeterminate:a=!1,label:n,description:r,size:s="md",disabled:i=!1,name:l,value:c,className:d},u){const h=Pa[s];return o.jsxs(b,{disabled:i,className:E("flex items-start gap-3",d),children:[o.jsxs(k,{ref:u,checked:e,onChange:t,name:l,value:c,className:E("group relative flex shrink-0 items-center justify-center",h.box,h.radius,"border-2 transition-all duration-150",!e&&!a&&"border-edge-subtle bg-subtle",(e||a)&&"border-sys-blue bg-sys-blue",!e&&!a&&!i&&"hover:border-edge-strong","ring-focus","disabled:opacity-50 disabled:cursor-not-allowed"),children:[e&&!a&&o.jsx(O,{className:E(h.icon,"text-white stroke-[3]")}),a&&o.jsx(H,{className:E(h.icon,"text-white stroke-[3]")})]}),(n||r)&&o.jsxs("div",{className:"flex-1 min-w-0 select-none",children:[n&&o.jsx(w,{className:E("text-sm font-medium cursor-pointer",i?"text-fg-muted":"text-fg-primary"),children:n}),r&&o.jsx(C,{className:"text-xs text-fg-muted mt-0.5",children:r})]})]})});s.createContext({variant:"default",divider:"subtle",grid:!0});const $a="0.9.285",qa="'JetBrains Mono', monospace",Oa=s.memo(function({height:e=16,responsive:t=!1,className:a=""}){const n="var(--sys-blue)",r="var(--fg-primary)";if(t){const e=145,t=24;return o.jsxs("svg",{className:a,viewBox:`0 0 ${e} ${t}`,preserveAspectRatio:"xMidYMid meet",role:"img","aria-label":"pyMC:Console",style:{display:"block",width:"80%",height:"auto"},children:[o.jsx("style",{children:`\n .logo-text {\n font-family: ${qa};\n }\n .logo-accent {\n fill: var(--sys-blue, #719CDF);\n }\n .logo-main {\n fill: var(--fg-primary, #FFFFFF);\n }\n `}),o.jsxs("text",{x:"0",y:"18",className:"logo-text",fontSize:"20",fontWeight:"400",letterSpacing:"-0.02em",children:[o.jsx("tspan",{className:"logo-accent",children:"py"}),o.jsx("tspan",{className:"logo-main",children:"MC"}),o.jsx("tspan",{className:"logo-accent",children:":"}),o.jsx("tspan",{className:"logo-main",children:"Console"})]})]})}const s="string"==typeof e?parseFloat(e):e,i={fontFamily:qa,fontSize:.8*s+"px",fontWeight:400,lineHeight:1,letterSpacing:"-0.02em",whiteSpace:"nowrap"};return o.jsxs("span",{className:a,style:i,role:"img","aria-label":"pyMC:Console",children:[o.jsx("span",{style:{color:n},children:"py"}),o.jsx("span",{style:{color:r},children:"MC"}),o.jsx("span",{style:{color:n},children:":"}),o.jsx("span",{style:{color:r},children:"Console"})]})});let Ha=null;function Wa(e){if(e)try{sessionStorage.setItem("auth_redirect_reason",e)}catch{}Ha?Ha("/login",{replace:!0}):window.location.replace("/login")}const Ua="pymc_jwt_token",Va="pymc_client_id",Ga="pymc_remember_me",Ja=new Set;function Ka(e){for(const a of Ja)try{a(e)}catch(t){console.error("[Auth] Token change callback error:",t)}}function Xa(){let e=localStorage.getItem(Va);return e||(e=`${Date.now()}-${Math.random().toString(36).substring(2,15)}`,localStorage.setItem(Va,e)),e}function Ya(){return"true"===localStorage.getItem(Ga)}function Qa(e){e?localStorage.setItem(Ga,"true"):localStorage.removeItem(Ga)}function Za(){return Ya()?localStorage:sessionStorage}function en(){return Za().getItem(Ua)||localStorage.getItem(Ua)||sessionStorage.getItem(Ua)}function tn(e){Za().setItem(Ua,e),Ya()?sessionStorage.removeItem(Ua):localStorage.removeItem(Ua),Ka(e)}function an(){localStorage.removeItem(Ua),sessionStorage.removeItem(Ua),Ka(null)}function nn(){return!(!en()||sn()&&(an(),1))}function rn(e){try{const t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),a=decodeURIComponent(atob(t).split("").map(e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(a)}catch{return null}}function sn(){const e=en();if(!e)return!0;const t=rn(e);return!t||!t.exp||Date.now()>=1e3*t.exp-6e4}function on(){const e=en();if(!e)return 0;const t=rn(e);return t&&t.exp?Math.max(0,Math.floor((1e3*t.exp-Date.now())/1e3)):0}function ln(){const e=en();if(!e)return!1;const t=rn(e);if(!t||!t.exp)return!1;const a=1e3*t.exp-Date.now();return a>0&&a<3e5}function cn(){const e=en();if(!e)return null;const t=rn(e);return t&&t.sub?t.sub:null}async function dn(e,t,a=!1){Qa(a);try{const a=await fetch("/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t,client_id:Xa()})}),n=a.headers.get("content-type");if(!n||!n.includes("application/json"))return console.error("Login response not JSON:",a.status),{success:!1,error:`Server error: ${a.status}`};const r=await a.json();return r.success&&r.token?(tn(r.token),{success:!0}):{success:!1,error:r.error||"Login failed"}}catch(n){return console.error("Login error:",n),{success:!1,error:"Connection error. Please try again."}}}async function un(){const e=en();if(!e)return console.warn("[Auth] refreshToken: No token to refresh"),!1;const t=rn(e);(null==t?void 0:t.exp)&&Math.floor((1e3*t.exp-Date.now())/1e3);try{const t=await fetch("/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({client_id:Xa()})});if(!t.ok){let e="";try{const a=await t.json();e=a.error||JSON.stringify(a)}catch{e=t.statusText}return console.warn(`[Auth] Token refresh failed: ${t.status} - ${e}`),!1}const a=await t.json();if(a.success&&a.token){tn(a.token);const e=rn(a.token);return(null==e?void 0:e.exp)&&Math.floor((1e3*e.exp-Date.now())/1e3),!0}return console.warn("[Auth] Token refresh response invalid:",a),!1}catch(a){return console.error("[Auth] Token refresh error:",a),!1}}let hn=null;async function mn(){const e=en();if(!e)return!1;const t=rn(e);return(null==t?void 0:t.exp)&&Math.floor((1e3*t.exp-Date.now())/1e3),!ln()||hn||(hn=un().finally(()=>{hn=null}),hn)}let gn=!1;const pn=new class{constructor(){r(this,"listeners",new Set)}get active(){return this.listeners.size>0}emit(e,t){if(0===this.listeners.size)return;const a={type:e,ts:performance.now(),data:t};for(const n of this.listeners)n(a)}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}clear(){this.listeners.clear()}},fn=new class{constructor(){r(this,"ws",null),r(this,"connectionState","disconnected"),r(this,"reconnectAttempts",0),r(this,"pingIntervalId",null),r(this,"lastPongTime",Date.now()),r(this,"reconnectTimeoutId",null),r(this,"packetListeners",new Set),r(this,"statsListeners",new Set),r(this,"systemStatsListeners",new Set),r(this,"packetStatsListeners",new Set),r(this,"connectionListeners",new Set),r(this,"unsubscribeTokenChange",null),r(this,"wsSupported",!0)}buildWsUrl(){const e=en(),t=Xa(),a=new URLSearchParams;e&&a.set("token",e),t&&a.set("client_id",t);const n=a.toString()?`?${a.toString()}`:"";return`${"https:"===window.location.protocol?"wss:":"ws:"}//${window.location.host}/ws/packets${n}`}connect(){var e,t;if((null==(e=this.ws)?void 0:e.readyState)!==WebSocket.OPEN&&(null==(t=this.ws)?void 0:t.readyState)!==WebSocket.CONNECTING&&this.wsSupported){this.setConnectionState("connecting");try{const e=this.buildWsUrl();this.ws=new WebSocket(e),this.ws.onopen=this.handleOpen.bind(this),this.ws.onmessage=this.handleMessage.bind(this),this.ws.onerror=this.handleError.bind(this),this.ws.onclose=this.handleClose.bind(this),this.unsubscribeTokenChange||(this.unsubscribeTokenChange=(a=e=>{e&&"connected"===this.connectionState&&(this.disconnect(),this.connect())},Ja.add(a),()=>Ja.delete(a)))}catch(n){console.error("[WS] Failed to create WebSocket:",n),this.wsSupported=!1,this.setConnectionState("disconnected")}var a}}disconnect(){this.clearPingInterval(),this.clearReconnectTimeout(),this.ws&&(this.ws.onopen=null,this.ws.onmessage=null,this.ws.onerror=null,this.ws.onclose=null,this.ws.readyState!==WebSocket.OPEN&&this.ws.readyState!==WebSocket.CONNECTING||this.ws.close(1e3,"Client disconnect"),this.ws=null),this.setConnectionState("disconnected"),this.reconnectAttempts=0}isConnected(){var e;return(null==(e=this.ws)?void 0:e.readyState)===WebSocket.OPEN}getConnectionState(){return this.connectionState}isSupported(){return this.wsSupported}resetSupported(){this.wsSupported||(this.wsSupported=!0,this.reconnectAttempts=0)}send(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)return console.warn("[WS] Cannot send: not connected"),!1;try{return this.ws.send(JSON.stringify(e)),!0}catch(t){return console.error("[WS] Send failed:",t),!1}}onPacket(e){return this.packetListeners.add(e),()=>this.packetListeners.delete(e)}onStats(e){return this.statsListeners.add(e),()=>this.statsListeners.delete(e)}onSystemStats(e){return this.systemStatsListeners.add(e),()=>this.systemStatsListeners.delete(e)}onPacketStats(e){return this.packetStatsListeners.add(e),()=>this.packetStatsListeners.delete(e)}onConnectionChange(e){return this.connectionListeners.add(e),e(this.connectionState,this.reconnectAttempts),()=>this.connectionListeners.delete(e)}handleOpen(){this.setConnectionState("connected"),this.reconnectAttempts=0,pn.active&&pn.emit("transport:ws:state",{state:"connected"}),this.lastPongTime=Date.now();const e=en();e&&this.ws&&this.ws.send(JSON.stringify({type:"auth",token:e})),this.startPingInterval()}handleMessage(e){var t;try{const a=JSON.parse(e.data);switch(a.type){case"packet":pn.active&&pn.emit("transport:ws:packet",{hash:null==(t=a.data)?void 0:t.packet_hash}),this.notifyPacketListeners(a.data);break;case"stats":{pn.active&&pn.emit("transport:ws:stats");const e=a.data;e&&"noise_floor_dbm"in e&&this.notifyStatsListeners(e),(null==e?void 0:e.packet_stats)&&this.notifyPacketStatsListeners(e.packet_stats),(null==e?void 0:e.system_stats)&&this.notifySystemStatsListeners(e.system_stats);break}case"packet_stats":{const e=a.data;this.notifyPacketStatsListeners(e);break}case"system_stats":this.notifySystemStatsListeners(a.data);break;case"ping":this.lastPongTime=Date.now(),this.send({type:"pong"});break;case"pong":this.lastPongTime=Date.now();break;default:a.type}}catch(a){console.error("[WS] Failed to parse message:",a)}}handleError(e){console.error("[WS] Error:",e)}handleClose(e){e.code,e.reason,pn.active&&pn.emit("transport:ws:state",{state:"disconnected",code:e.code}),this.clearPingInterval(),1e3!==e.code?(1006===e.code&&this.reconnectAttempts,this.scheduleReconnect()):this.setConnectionState("disconnected")}setConnectionState(e){if(this.connectionState!==e){this.connectionState=e;for(const a of this.connectionListeners)try{a(e,this.reconnectAttempts)}catch(t){console.error("[WS] Connection listener error:",t)}}}notifyPacketListeners(e){for(const a of this.packetListeners)try{a(e)}catch(t){console.error("[WS] Packet listener error:",t)}}notifyStatsListeners(e){for(const a of this.statsListeners)try{a(e)}catch(t){console.error("[WS] Stats listener error:",t)}}notifySystemStatsListeners(e){for(const a of this.systemStatsListeners)try{a(e)}catch(t){console.error("[WS] System stats listener error:",t)}}notifyPacketStatsListeners(e){for(const a of this.packetStatsListeners)try{a(e)}catch(t){console.error("[WS] Packet stats listener error:",t)}}startPingInterval(){this.clearPingInterval(),this.pingIntervalId=setInterval(()=>{var e;if((null==(e=this.ws)?void 0:e.readyState)===WebSocket.OPEN){this.send({type:"ping"});const e=Date.now()-this.lastPongTime;e>6e4&&(console.warn(`[WS] No pong in ${Math.round(e/1e3)}s, reconnecting...`),this.disconnect(),this.connect())}},3e4)}async verifyConnection(e=5e3){return!(!this.ws||this.ws.readyState!==WebSocket.OPEN)&&new Promise(t=>{const a=Date.now(),n=this.lastPongTime;this.send({type:"ping"});const r=setInterval(()=>{this.lastPongTime>n?(clearInterval(r),t(!0)):Date.now()-a>e&&(clearInterval(r),console.warn("[WS] Connection verification failed - no pong received"),t(!1))},100)})}clearPingInterval(){this.pingIntervalId&&(clearInterval(this.pingIntervalId),this.pingIntervalId=null)}scheduleReconnect(){if(this.reconnectAttempts>=20)return console.error("[WS] Max reconnection attempts (20) reached"),this.wsSupported=!1,void this.setConnectionState("disconnected");this.setConnectionState("reconnecting");const e=Math.min(1e3*Math.pow(2,Math.min(this.reconnectAttempts,5)),3e4);this.reconnectAttempts,this.reconnectAttempts++,this.reconnectTimeoutId=setTimeout(()=>{this.reconnectTimeoutId=null,this.connect()},e)}clearReconnectTimeout(){this.reconnectTimeoutId&&(clearTimeout(this.reconnectTimeoutId),this.reconnectTimeoutId=null)}terminate(){this.disconnect(),this.unsubscribeTokenChange&&(this.unsubscribeTokenChange(),this.unsubscribeTokenChange=null),this.packetListeners.clear(),this.statsListeners.clear(),this.systemStatsListeners.clear(),this.packetStatsListeners.clear(),this.connectionListeners.clear()}};function bn(e){return{paths:e.paths,byEndpoints:new Map(e.byEndpointsEntries),canonicalPaths:new Map(e.canonicalPathsEntries),totalObservations:e.totalObservations,uniquePathCount:e.uniquePathCount}}function yn(){return{paths:[],byEndpoints:new Map,canonicalPaths:new Map,totalObservations:0,uniquePathCount:0}}async function wn(e,t,a,n,r=!1){const s=`/api/bulk_packets?${new URLSearchParams({limit:String(a),start_timestamp:String(e),end_timestamp:String(t)})}`,o={Accept:"application/json"},i=en();i&&(o.Authorization=`Bearer ${i}`);const l=new AbortController,c=setTimeout(()=>l.abort(),6e4);try{const i=await fetch(s,{headers:o,signal:l.signal});if(401===i.status&&!r&&await un())return wn(e,t,a,n,!0);if(!i.ok)throw new Error(`API ${i.status}`);const c=await i.json();return c.success&&c.data?c.data:[]}finally{clearTimeout(c)}}async function Cn(e,t,a,n,r,s){try{const o=await async function(e,t,a,n,r,s){const o=3600*(s??6),i=[];for(let d=r??Math.floor(Date.now()/1e3);d>e;d-=o)i.push({start:Math.max(e,d-o),end:d});i.length;let l=0,c=0;null==t||t({loaded:0,phase:"fetching",chunk:0});for(let d=0;d0&&await new Promise(e=>setTimeout(e,100));const e=i.slice(d,d+2);c++;const r=await Promise.all(e.map(e=>kn(e.start,e.end,n,a)));for(const t of r)l+=t;null==t||t({loaded:l,phase:"fetching",chunk:c})}return null==t||t({loaded:l,phase:"complete",chunk:c}),l}(e,t,a,n,r,s);if(o>0)return o}catch{}return async function(e,t,a,n,r){let s=0,o=0,i=r??Math.floor(Date.now()/1e3);for(new Date(1e3*e).toISOString(),new Date(1e3*i).toISOString(),null==t||t({loaded:0,phase:"fetching",chunk:0});i>e&&o<100;){o++;try{const r=await wn(e,i,1e4,n);if(0===r.length)break;s+=r.length;let l=i;for(let e=0;e=i){console.warn(`[bulk] Cursor stuck at ${i}`);break}if(i=c,null==a||a(r),null==t||t({loaded:s,phase:"fetching",chunk:o}),r.length<1e4)break}catch(l){if(l instanceof Error&&"AbortError"===l.name)break;console.error(`[bulk] Chunk ${o} failed:`,l);break}}return null==t||t({loaded:s,phase:"complete",chunk:o}),s}(e,t,a,n,r)}async function kn(e,t,a,n){let r=t,s=0,o=0;for(;r>e&&o<100;){o++;const t=await wn(e,r,5e3,a);if(0===t.length)break;s+=t.length,null==n||n(t);let i=r;for(let e=0;e=r)break;if(r=l,t.length<5e3)break}return s}"undefined"!=typeof window&&(window.diagnoseBulkFetch=async()=>{var e;Date.now();const t=en();try{const a=`/api/bulk_packets?limit=100&start_timestamp=0&end_timestamp=${Math.floor(Date.now()/1e3)}`,n={Accept:"application/json"};t&&(n.Authorization=`Bearer ${t}`);const r=await fetch(a,{headers:n});r.status,Object.fromEntries(r.headers.entries());const s=await r.text();s.length,Date.now();try{const t=JSON.parse(s);null==(e=t.data)||e.length,t.success||t.error}catch{s.slice(0,500)}}catch(a){console.error("[diag] Fetch failed:",a)}});const vn=3,Dn=2,An=15,xn=6,En=3,Fn=0,Bn=1,jn=2,Sn=3,Mn={[Fn]:"T_FLOOD",[Bn]:"FLOOD",[jn]:"DIRECT",[Sn]:"T_DIRECT"},Nn=0,Ln=1,Tn=2,_n=3,Rn=4,zn=5,Pn=6,In=7,$n=8,qn=9,On=10,Hn=11,Wn=15,Un={REQ:0,RESPONSE:1,TXT_MSG:2,ACK:3,ADVERT:4,GRP_TXT:5,GRP_DATA:6,ANON_REQ:7,PATH:8,TRACE:9},Vn={[Nn]:"REQ",[Ln]:"RESPONSE",[Tn]:"TXT_MSG",[_n]:"ACK",[Rn]:"ADVERT",[zn]:"GRP_TXT",[Pn]:"GRP_DATA",[In]:"ANON_REQ",[$n]:"PATH",[qn]:"TRACE",[On]:"MULTIPART",[Hn]:"CONTROL",[Wn]:"RAW_CUSTOM"},Gn=1,Jn=32,Kn=64,Xn=2,Yn=64,Qn=4,Zn=1,er=2,tr=3,ar=4,nr=16,rr=32,sr=64,or=128,ir=15;function lr(e){return 1===e||0===e}function cr(e){return 2===e||3===e}function dr(e){return 0===e||3===e}function ur(e){const t=[];switch(15&e){case 1:t.push("is companion");break;case 2:t.push("is repeater");break;case 3:t.push("is room server");break;case 4:t.push("is sensor")}return 16&e&&t.push("has location"),32&e&&t.push("has feature 1"),64&e&&t.push("has feature 2"),128&e&&t.push("has name"),t.join(", ")||"none"}function hr(e){return null==e?"UNKNOWN":Mn[e]??`UNKNOWN(${e})`}function mr(e){return null==e?"UNKNOWN":Vn[e]??`UNKNOWN(${e})`}const gr=Object.freeze({advertSender:null,advertNodeType:null,advertFlags:null,advertHasLocation:null,advertHasName:null,advertName:null,advertLatitude:null,advertLongitude:null});function pr(e,t){if(4!==t||!e||e.length<6)return gr;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return gr;const n=3&a;let r=2;if(0!==n&&3!==n||(r+=8),r+2>e.length)return gr;const s=parseInt(e.slice(r,r+2),16);if(isNaN(s))return gr;if(r+=2+2*s,r+64>e.length)return gr;const o=e.slice(r,r+64).toLowerCase(),i=r+200;if(i+2>e.length)return{...gr,advertSender:o};const l=parseInt(e.slice(i,i+2),16);if(isNaN(l))return{...gr,advertSender:o};const c=!!(16&l),d=!!(128&l);let u=null,h=null;if(c){const t=i+2;if(t+16<=e.length){const a=[0,1,2,3].map(a=>parseInt(e.slice(t+2*a,t+2*a+2),16)),n=[0,1,2,3].map(a=>parseInt(e.slice(t+8+2*a,t+8+2*a+2),16));a.every(e=>!isNaN(e))&&n.every(e=>!isNaN(e))&&(u=(a[0]|a[1]<<8|a[2]<<16|a[3]<<24)/1e6,h=(n[0]|n[1]<<8|n[2]<<16|n[3]<<24)/1e6)}}let m=null;if(d){let t=i+2;if(c&&(t+=16),32&l&&(t+=4),64&l&&(t+=4),t0){const e=new TextDecoder("utf-8",{fatal:!1}).decode(new Uint8Array(a)).replace(/\uFFFD/g,"").replace(/[\x00-\x1F\x7F]/g,"").trim();e.length>0&&(m=e)}}}return{advertSender:o,advertNodeType:15&l,advertFlags:l,advertHasLocation:c,advertHasName:d,advertName:m,advertLatitude:u,advertLongitude:h}}function fr(e,t){if(5!==t&&6!==t||!e||e.length<6)return null;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return null;const n=3&a;let r=2;if(0!==n&&3!==n||(r=10),r+2>e.length)return null;const s=parseInt(e.slice(r,r+2),16);return isNaN(s)?null:(r+=2+2*s,r+2>e.length?null:e.slice(r,r+2).toUpperCase())}function br(e){const t=Array.isArray(e.original_path)?e.original_path:[],a=e.route??e.route_type;let n;return n=0===a||1===a?Math.max(0,t.length-1):2===a||3===a?t.length:e.path_length??t.length,{hopCount:n,isZeroHop:0===n}}function yr(e,t){if(e&&/^[0-9a-fA-F]+$/.test(e)&&e.length%2==0)return e.length/2;const a=t.length??t.payload_length;if(a&&a>0){let e=2;const n=t.route??t.route_type;return 0!==n&&3!==n||(e+=4),null!=t.path_length?e+=t.path_length:Array.isArray(t.original_path)&&(e+=t.original_path.length),a+e}}function wr(e,t){if(9!==t||!e||e.length<6)return null;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return null;const n=3&a;let r=2;if(0!==n&&3!==n||(r+=8),r+2>e.length)return null;const s=parseInt(e.slice(r,r+2),16);if(isNaN(s)||0===s)return null;r+=2;const o=r+2*s;if(o>e.length)return null;const i=[];for(let l=r;lthis.listeners.delete(e)}getState(){return{isLoading:this.isLoading,isBackgroundLoading:this.isBackgroundLoading,isTopologyLoading:this.isTopologyLoading,backgroundLoadComplete:this.meta.backgroundLoadComplete,topologyLoadComplete:this.meta.topologyLoadComplete,packetCount:this.packets.size,statusMessage:this.statusMessage,loadProgress:this.loadProgress,dataTier:this.meta.dataTier,threeDayLoadComplete:this.meta.threeDayLoadComplete,sevenDayLoadComplete:this.meta.sevenDayLoadComplete,fourteenDayLoadComplete:this.meta.fourteenDayLoadComplete,twentyOneDayLoadComplete:this.meta.twentyOneDayLoadComplete,thirtyDayLoadComplete:this.meta.thirtyDayLoadComplete,ninetyDayLoadComplete:this.meta.ninetyDayLoadComplete,maxRetentionDays:this.getMaxRetentionDays()}}getDataTier(){return this.meta.dataTier}getMaxRetentionDays(){if(!(this.meta.threeDayLoadComplete||this.meta.sevenDayLoadComplete||this.meta.fourteenDayLoadComplete||this.meta.twentyOneDayLoadComplete||this.meta.thirtyDayLoadComplete||this.meta.ninetyDayLoadComplete))return;const e=this.meta.oldestTimestamp;if(!e||e===1/0)return;const t=(Date.now()/1e3-e)/86400;return Math.ceil(t)+1}getPackets(){return this.sortedDirty&&(this.sortedPackets=Array.from(this.packets.values()).sort((e,t)=>(e.timestamp??0)-(t.timestamp??0)),this.sortedDirty=!1),this.sortedPackets}getPacketCount(){return this.packets.size}getPacketsUnsorted(){return Array.from(this.packets.values())}getNewestTimestamp(){return this.meta.newestTimestamp}getOldestTimestamp(){return this.meta.oldestTimestamp}isStale(){return 0===this.packets.size||Date.now()-this.meta.lastUpdated>vr}isHeavyLoadInProgress(){return this.isBackgroundLoading||this.isTopologyLoading}async initialLoad(e){if(this.meta.backgroundLoadComplete&&this.packets.size>0)return this.getPackets();0===this.packets.size&&(this.meta.oldestTimestamp=1/0,this.meta.newestTimestamp=0),this.sortedDirty=!0,this.isLoading=!0,this.loadProgress={loaded:this.packets.size,target:3e4,percent:0},this.notifyListeners();const t=Math.floor((Date.now()-864e5)/1e3);try{await Cn(t,e=>{this.loadProgress={loaded:e.loaded,target:Math.max(3e4,e.loaded),percent:"complete"===e.phase?100:Math.min(95,10*e.chunk)},e.chunk%2==0&&this.notifyListeners()},t=>{this.bulkInsert(t),null==e||e()}),this.meta.packetCount=this.packets.size,this.meta.backgroundLoadComplete=!0,this.meta.dataTier="24h",this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100},this.packets.size,this.saveToStorage(),this.scheduleInternHotTier()}catch(a){console.error("[PacketCache] Load failed:",a)}finally{this.isLoading=!1,this.loadProgress=null,this.notifyListeners()}return this.getPackets()}bulkInsert(e){let t=this.meta.oldestTimestamp;t!==1/0&&0!==t||(t=Number.MAX_SAFE_INTEGER);let a=this.meta.newestTimestamp;for(let n=0;na&&(a=o),this.extractAdvertData(r)}t0&&o<1/0?o:r;if(i<=s){const t={"3d":["threeDayLoadComplete"],"7d":["threeDayLoadComplete","sevenDayLoadComplete"],"14d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete"],"21d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete"],"30d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete","thirtyDayLoadComplete"],"90d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete","thirtyDayLoadComplete","ninetyDayLoadComplete"]};for(const a of t[e]??[])this.meta[a]=!0;return this.meta.dataTier=e,this.isBackgroundLoading=!1,void this.notifyListeners()}const l={"3d":2,"7d":6,"14d":13,"21d":20,"30d":29,"90d":89},c={"3d":6,"7d":6,"14d":6,"21d":12,"30d":12,"90d":24},d=3e4*(l[e]??13),u=this.packets.size,h=u+d;this.loadProgress={loaded:u,target:h,percent:0},this.statusMessage=`Loading ${e} history...`,this.notifyListeners();let m=0;try{await Cn(s,e=>{this.loadProgress={loaded:u+e.loaded,target:Math.max(h,u+e.loaded),percent:Math.min(99,Math.round((u+e.loaded)/h*100))},e.chunk%2==0&&this.notifyListeners()},e=>{const t=this.packets.size;this.bulkInsert(e),m+=this.packets.size-t,null==a||a()},void 0,i,c[e]);const t=Date.now()-1e3*this.meta.oldestTimestamp;"3d"===e?(this.meta.threeDayLoadComplete=t>=Dr,this.meta.threeDayLoadComplete&&(this.meta.dataTier="3d")):"7d"===e?(this.meta.sevenDayLoadComplete=t>=Ar,this.meta.sevenDayLoadComplete&&(this.meta.dataTier="7d")):"14d"===e?(this.meta.fourteenDayLoadComplete=t>=xr,this.meta.fourteenDayLoadComplete&&(this.meta.dataTier="14d")):"21d"===e?(this.meta.twentyOneDayLoadComplete=t>=Er,this.meta.twentyOneDayLoadComplete&&(this.meta.dataTier="21d")):"30d"===e?(this.meta.thirtyDayLoadComplete=t>=Fr,this.meta.thirtyDayLoadComplete&&(this.meta.dataTier="30d")):"90d"===e&&(this.meta.ninetyDayLoadComplete=t>=Br,this.meta.ninetyDayLoadComplete&&(this.meta.dataTier="90d")),this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100};const n=(t/864e5).toFixed(1);Number(n),this.packets.size.toLocaleString(),m.toLocaleString(),this.notifyListeners(),this.saveToStorage()}catch(g){console.error(`[PacketCache] ${e} load failed:`,g),this.statusMessage=`${e} load failed`}finally{this.isBackgroundLoading=!1,this.statusMessage="",this.loadProgress=null,this.notifyListeners()}}isDataTierAvailable(e){switch(e){case"24h":return this.meta.backgroundLoadComplete;case"3d":return this.meta.threeDayLoadComplete;case"7d":return this.meta.sevenDayLoadComplete;case"14d":return this.meta.fourteenDayLoadComplete;case"21d":return this.meta.twentyOneDayLoadComplete;case"30d":return this.meta.thirtyDayLoadComplete;case"90d":return this.meta.ninetyDayLoadComplete;default:return!1}}async topologyLoad(){if(!this.meta.topologyLoadComplete&&!this.isTopologyLoading)return this.doTopologyLoad()}async forceTopologyLoad(){if(!this.isTopologyLoading)return this.meta.topologyLoadComplete=!1,this.doTopologyLoad()}async forceDeepLoad(){return this.forceTopologyLoad()}async doTopologyLoad(){this.isTopologyLoading=!0;const e=Date.now(),t=Math.floor(e/1e3),a=Math.floor((e-xr)/1e3),n=this.meta.oldestTimestamp,r=n>0&&n<1/0?n:t;if(r<=a)return this.meta.topologyLoadComplete=!0,void(this.isTopologyLoading=!1);const s=this.packets.size,o=s+42e4;this.statusMessage="Loading topology data...",this.loadProgress={loaded:s,target:o,percent:0},this.notifyListeners();let i=0;try{await Cn(a,e=>{this.loadProgress={loaded:s+e.loaded,target:Math.max(o,s+e.loaded),percent:Math.min(99,Math.round((s+e.loaded)/o*100))},e.chunk%2==0&&this.notifyListeners()},e=>{const t=this.packets.size;this.bulkInsert(e),i+=this.packets.size-t},void 0,r),this.statusMessage=`Processing ${this.packets.size.toLocaleString()} packets...`,this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100},this.notifyListeners(),this.meta.topologyLoadComplete=!0,this.meta.threeDayLoadComplete=!0,this.meta.sevenDayLoadComplete=!0,this.meta.fourteenDayLoadComplete=!0,this.meta.dataTier="14d",this.saveToStorage(),this.packets.size}catch(l){console.error("[PacketCache] Topology load failed:",l),this.statusMessage="Load failed"}finally{this.isTopologyLoading=!1,this.statusMessage="",this.loadProgress=null,this.notifyListeners()}}async poll(){try{const e=await this.fetchRecentPackets(100);if(e.success&&e.data){const t=this.packets.size;this.mergePackets(e.data);const a=this.packets.size-t;return a>0&&(this.saveToStorage(),this.notifyListeners()),a}}catch(e){console.error("[PacketCache] Poll failed:",e)}return 0}clear(){this.packets.clear(),this.sortedPackets=[],this.sortedDirty=!0,this.stringPool.clear(),this.stripScheduled=!1,this.meta={oldestTimestamp:0,newestTimestamp:0,lastUpdated:0,packetCount:0,backgroundLoadComplete:!1,topologyLoadComplete:!1,dataTier:"24h",threeDayLoadComplete:!1,sevenDayLoadComplete:!1,fourteenDayLoadComplete:!1,twentyOneDayLoadComplete:!1,thirtyDayLoadComplete:!1,ninetyDayLoadComplete:!1},this.clearStorage(),this.notifyListeners()}mergePacketsDirectly(e){const t=this.packets.size;this.mergePackets(e);const a=this.packets.size-t;return a>0&&(this.saveToStorage(),this.notifyListeners()),a}mergePackets(e){let t=!1;for(const a of e){const e=a.packet_hash;if(!e)continue;const n=a.timestamp??0,r=`${e}:${n}`;this.packets.has(r)||(this.packets.set(r,a),t=!0),(0===this.meta.oldestTimestamp||nthis.meta.newestTimestamp&&(this.meta.newestTimestamp=n)}if(t){this.sortedDirty=!0;for(const t of e)this.internPacketStrings(t),this.extractAdvertData(t),this.extractChannelHash(t),this.extractByteLength(t),this.extractHopData(t);this.scheduleStrip()}this.meta.lastUpdated=Date.now(),this.meta.packetCount=this.packets.size}notifyListeners(){const e=this.getState();for(const t of this.listeners)t(e)}scheduleStrip(){this.stripScheduled||this.packets.size<=Sr||"undefined"!=typeof window&&(this.stripScheduled=!0,"requestIdleCallback"in window?requestIdleCallback(()=>this.stripWarmPackets(),{timeout:5e3}):setTimeout(()=>this.stripWarmPackets(),500))}stripWarmPackets(){this.stripScheduled=!1;const e=this.packets.size;if(e<=Sr)return;const t=Array.from(this.packets.values());t.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0));const a=e-Sr;let n=0;for(let r=0;r=5e3&&rt.length)return null;const s=parseInt(t.slice(r,r+2),16);if(isNaN(s))return null;if(r+=2+2*s,r>=t.length)return null;const o=t.slice(r);return o.length>=38?o.slice(0,38):o}extractTraceTag(e){if(!e||e.length<8)return null;const t=parseInt(e.slice(0,2),16),a=parseInt(e.slice(2,4),16),n=parseInt(e.slice(4,6),16),r=parseInt(e.slice(6,8),16);return isNaN(t)||isNaN(a)||isNaN(n)||isNaN(r)?null:((t|a<<8|n<<16|r<<24)>>>0).toString(16).toUpperCase().padStart(8,"0")}extractTracePathHashes(e){if(!e||e.length<20)return null;const t=e.slice(18);if(0===t.length)return null;const a=[];for(let n=0;n0?a:null}internPacketStrings(e){if(e.src_hash&&(e.src_hash=this.intern(e.src_hash)),e.dst_hash&&(e.dst_hash=this.intern(e.dst_hash)),e.path_hash&&(e.path_hash=this.intern(e.path_hash)),e.original_path&&"string"==typeof e.original_path)try{e.original_path=JSON.parse(e.original_path)}catch{e.original_path=void 0}if(e.forwarded_path&&"string"==typeof e.forwarded_path)try{e.forwarded_path=JSON.parse(e.forwarded_path)}catch{e.forwarded_path=void 0}if(Array.isArray(e.original_path))for(let t=0;t5e4&&this.stringPool.clear();const t=this.stringPool.get(e);return void 0!==t?t:(this.stringPool.set(e,e),e)}scheduleInternHotTier(){if("undefined"==typeof window)return;const e=()=>{for(const e of this.packets.values())e._stripped||(this.internPacketStrings(e),this.extractAdvertData(e))};"requestIdleCallback"in window?requestIdleCallback(()=>e(),{timeout:1e4}):setTimeout(e,1e3)}loadFromStorage(){if("undefined"!=typeof window)try{const e=localStorage.getItem(kr);e&&(this.meta=JSON.parse(e));const t=localStorage.getItem(Cr);if(t){const e=JSON.parse(t);let a=1/0,n=0;for(const t of e)if(t.packet_hash){const e=t.timestamp??0,r=`${t.packet_hash}:${e}`;this.packets.set(r,t),this.extractAdvertData(t),e>0&&en&&(n=e)}this.packets.size>0&&a!==1/0&&(this.meta.oldestTimestamp=a,this.meta.newestTimestamp=n)}if(this.meta.lastUpdated>0&&Date.now()-this.meta.lastUpdated>vr)return void this.clear();this.meta.backgroundLoadComplete=!1,this.meta.threeDayLoadComplete=!1,this.meta.sevenDayLoadComplete=!1,this.meta.fourteenDayLoadComplete=!1,this.meta.twentyOneDayLoadComplete=!1,this.meta.thirtyDayLoadComplete=!1,this.meta.ninetyDayLoadComplete=!1,this.meta.dataTier="24h";const a=37500;this.meta.topologyLoadComplete&&this.packets.size{this.saveTimer=null,this.flushToStorage()},e.SAVE_DEBOUNCE_MS)))}flushToStorage(){try{let e;if(localStorage.setItem(kr,JSON.stringify(this.meta)),this.packets.size<=3e3)e=Array.from(this.packets.values());else if(this.sortedDirty){const t=Array.from(this.packets.values()),a=new Float64Array(t.length);for(let e=0;e(e.timestamp??0)>=n),e.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0))}else e=this.sortedPackets.slice(-3e3);localStorage.setItem(Cr,JSON.stringify(e))}catch(e){if(e instanceof DOMException&&"QuotaExceededError"===e.name){console.warn("[PacketCache] Storage quota exceeded, clearing packet data to save meta");try{localStorage.removeItem(Cr),localStorage.setItem(kr,JSON.stringify(this.meta))}catch{console.warn("[PacketCache] Unable to save even meta data")}}else console.warn("[PacketCache] Failed to save to storage:",e)}}clearStorage(){if("undefined"!=typeof window)try{localStorage.removeItem(Cr),localStorage.removeItem(kr)}catch(e){console.warn("[PacketCache] Failed to clear storage:",e)}}async fetchRecentPackets(e=1e3,t=!1){const a=`/api/recent_packets?limit=${e}`,n=en(),r={Accept:"application/json"};n&&(r.Authorization=`Bearer ${n}`);const s=await fetch(a,{headers:r});if(401===s.status&&!t&&await un())return this.fetchRecentPackets(e,!0);if(!s.ok)throw new Error(`API error: ${s.status}`);return s.json()}};r(Mr,"SAVE_DEBOUNCE_MS",1e4);const Nr=new Mr,Lr=3e5,Tr=class e{constructor(){r(this,"worker",null),r(this,"listeners",new Set),r(this,"currentTopology",{edges:[],validatedEdges:[],weakEdges:[],certainEdges:[],uncertainEdges:[],edgeMap:new Map,maxPacketCount:0,maxCertainCount:0,neighborAffinity:new Map,fullAffinity:new Map,localPrefix:null,centrality:new Map,hubNodes:[],gatewayNodes:[],loops:[],loopEdgeKeys:new Set,txDelayRecommendations:new Map,pathRegistry:yn(),edgeBetweenness:new Map,backboneEdges:[],nodeMobility:new Map,mobileNodes:[],pathHealth:[],lastHopNeighbors:[],disambiguationStats:{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:[],viterbiStats:{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map,communityCount:0,backboneNodes:[],traceLinks:new Map,traceLinkSummary:{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:{confirmedResolutions:new Map,confirmedLinks:[]}}),r(this,"isComputing",!1),r(this,"pendingRequest",null),r(this,"debounceTimer",null),r(this,"restartCount",0),r(this,"lastInputFingerprint",""),r(this,"lastComputeTime",0),r(this,"lastComputePacketCount",0),r(this,"lastComputeNeighborCount",0),r(this,"lastComputeNewestTs",0),r(this,"lastComputeWindowHours",null),r(this,"knownPrefixPairs",new Set),r(this,"pendingFingerprint",""),r(this,"pendingPacketCount",0),r(this,"pendingNeighborCount",0),r(this,"pendingNewestTs",0),r(this,"pendingWindowHours",null)}getDebounceMs(e=!1){return e?100:Nr.isHeavyLoadInProgress()?5e3:Nr.getPacketCount()>1e5?500:100}buildFingerprint(e,t,a,n){return`${e}:${t}:${a??""}:${n??""}`}captureKnownPrefixPairs(){const e=new Set;for(const t of this.currentTopology.edgeMap.keys()){const a=t.split("→");2===a.length&&e.add(`${a[0].slice(0,2)}→${a[1].slice(0,2)}`)}this.knownPrefixPairs=e}hasNewPrefixPairs(e){var t;if(0===e.length||0===this.knownPrefixPairs.size)return!0;const a=e.length-this.lastComputePacketCount;if(a<=0)return!1;if(a>500)return!0;const n=this.lastComputeNewestTs;for(let r=e.length-1;r>=0;r--){const a=e[r];if((a.timestamp??0)<=n)break;const s=a.original_path??a.forwarded_path,o=null==(t=a.src_hash)?void 0:t.slice(0,2);if(o&&s&&s.length>0){const e=String(s[0]).slice(0,2);if(!this.knownPrefixPairs.has(`${o}→${e}`))return!0}if(s&&s.length>=2)for(let e=0;e{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[TopologyService] Worker error:",e),this.isComputing=!1;for(const t of this.listeners)try{t(this.currentTopology,0)}catch{}this.restartWorker()}}catch(e){console.error("[TopologyService] Failed to initialize worker:",e)}return this.worker}restartWorker(){this.restartCount>=e.MAX_RESTARTS?console.warn("[TopologyService] Max restarts reached, not restarting"):(this.restartCount++,console.warn(`[TopologyService] Restarting worker (attempt ${this.restartCount})`),this.worker&&(this.worker.terminate(),this.worker=null))}handleWorkerMessage(e){if(this.isComputing=!1,"error"!==e.type){var t;this.currentTopology={edges:(t=e.payload).edges??[],validatedEdges:t.validatedEdges??[],weakEdges:t.weakEdges??[],certainEdges:t.certainEdges??[],uncertainEdges:t.uncertainEdges??[],maxPacketCount:t.maxPacketCount??0,maxCertainCount:t.maxCertainCount??0,localPrefix:t.localPrefix??null,hubNodes:t.hubNodes??[],gatewayNodes:t.gatewayNodes??[],edgeMap:new Map(t.edgeMapEntries??[]),neighborAffinity:new Map(t.neighborAffinityEntries??[]),fullAffinity:new Map(t.fullAffinityEntries??[]),centrality:new Map(t.centralityEntries??[]),loops:t.loops??[],loopEdgeKeys:new Set(t.loopEdgeKeyEntries??[]),txDelayRecommendations:new Map(t.txDelayRecommendationEntries??[]),pathRegistry:t.pathRegistry?bn(t.pathRegistry):yn(),edgeBetweenness:new Map(t.edgeBetweennessEntries??[]),backboneEdges:t.backboneEdges??[],nodeMobility:new Map(t.nodeMobilityEntries??[]),mobileNodes:t.mobileNodes??[],pathHealth:t.pathHealth??[],lastHopNeighbors:t.lastHopNeighbors??[],disambiguationStats:t.disambiguationStats??{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:t.discoveredNodes??[],viterbiStats:t.viterbiStats??{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map(t.nodeMetricsEntries??[]),communityCount:t.communityCount??0,backboneNodes:t.backboneNodes??[],traceLinks:new Map(t.traceLinkEntries??[]),traceLinkSummary:t.traceLinkSummary??{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:t.traceDisambiguationFeedbackEntries?{confirmedResolutions:new Map(t.traceDisambiguationFeedbackEntries.confirmedResolutions??[]),confirmedLinks:t.traceDisambiguationFeedbackEntries.confirmedLinks??[]}:{confirmedResolutions:new Map,confirmedLinks:[]}},this.lastInputFingerprint=this.pendingFingerprint,this.lastComputeTime=Date.now(),this.lastComputePacketCount=this.pendingPacketCount,this.lastComputeNeighborCount=this.pendingNeighborCount,this.lastComputeNewestTs=this.pendingNewestTs,this.lastComputeWindowHours=this.pendingWindowHours,this.captureKnownPrefixPairs(),pn.active&&pn.emit("worker:topology:done",{ms:e.computeTimeMs,edges:this.currentTopology.edges.length});for(const t of this.listeners)try{t(this.currentTopology,e.computeTimeMs)}catch(a){console.error("[TopologyService] Listener error:",a)}if(this.pendingRequest){const e=this.pendingRequest;this.pendingRequest=null,this.computeInternal(e)}}else console.error("[TopologyService] Worker computation error:",e.error)}computeInternal(e){const t=this.ensureWorker();if(!t)return void console.warn("[TopologyService] Worker not available");this.isComputing=!0,pn.active&&pn.emit("worker:topology:start",{packets:e.packets.length});const a={type:"compute",payload:e};t.postMessage(a)}compute(e,t,a,n,r,s,o,i,l,c,d){const u=Object.keys(t).length,h=this.buildFingerprint(e.length,u,a,c),m=Date.now()-this.lastComputeTime;if(h===this.lastInputFingerprint&&m0&&mthis.lastComputePacketCount&&!this.hasNewPrefixPairs(e))return;const g=c!==this.lastComputeWindowHours;this.pendingFingerprint=h,this.pendingPacketCount=e.length,this.pendingNeighborCount=u,this.pendingWindowHours=c??null,this.pendingNewestTs=e.length>0?e[e.length-1].timestamp??0:0;const p=this.currentTopology.traceDisambiguationFeedback,f=p.confirmedResolutions.size>0||p.confirmedLinks.length>0?{confirmedResolutions:Array.from(p.confirmedResolutions.entries()),confirmedLinks:p.confirmedLinks}:void 0,b={packets:e,neighbors:t,localHash:a,localLat:n,localLon:r,airtimeMs:s,zeroHopNeighbors:o,terrainGrid:i,enableTerrainAware:void 0!==i,srcHashResolverEntries:l?Array.from(l.entries()):void 0,windowHours:c,spreadingFactor:d,previousTraceEvidenceSerialized:f};this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.isComputing?this.pendingRequest=b:this.computeInternal(b)},this.getDebounceMs(g))}subscribe(e){return this.listeners.add(e),this.currentTopology.edges.length>0&&e(this.currentTopology,0),()=>{this.listeners.delete(e)}}getTopology(){return this.currentTopology}isWorking(){return this.isComputing}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}};r(Tr,"MAX_RESTARTS",1);const _r=new Tr,Rr=F(e=>({topology:{edges:[],validatedEdges:[],weakEdges:[],certainEdges:[],uncertainEdges:[],edgeMap:new Map,maxPacketCount:0,maxCertainCount:0,neighborAffinity:new Map,fullAffinity:new Map,localPrefix:null,centrality:new Map,hubNodes:[],gatewayNodes:[],loops:[],loopEdgeKeys:new Set,txDelayRecommendations:new Map,pathRegistry:yn(),edgeBetweenness:new Map,backboneEdges:[],nodeMobility:new Map,mobileNodes:[],pathHealth:[],lastHopNeighbors:[],disambiguationStats:{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:[],viterbiStats:{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map,communityCount:0,backboneNodes:[],traceLinks:new Map,traceLinkSummary:{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:{confirmedResolutions:new Map,confirmedLinks:[]}},isComputing:!1,lastComputeTimeMs:0,lastUpdated:0,setTopology:(t,a)=>e({topology:t,lastComputeTimeMs:a,lastUpdated:Date.now(),isComputing:!1}),setComputing:t=>e({isComputing:t})}));"undefined"!=typeof window&&_r.subscribe((e,t)=>{Rr.getState().setTopology(e,t)});const zr=Rr,Pr=()=>Rr(e=>e.topology),Ir=()=>Rr(e=>e.topology.hubNodes),$r=()=>Rr(e=>e.topology.centrality),qr=()=>Rr(e=>e.topology.fullAffinity),Or=()=>Rr(e=>e.isComputing),Hr=()=>Rr(e=>e.lastUpdated);let Wr=null,Ur=null,Vr=null,Gr=null,Jr=null,Kr=null;const Xr=()=>Rr(e=>(e.topology.hubNodes!==Ur&&(Ur=e.topology.hubNodes,Wr=new Set(e.topology.hubNodes)),Wr)),Yr=()=>Rr(e=>e.topology.txDelayRecommendations),Qr=()=>Rr(e=>e.topology.pathRegistry.canonicalPaths),Zr=()=>Rr(e=>(e.topology.mobileNodes!==Gr&&(Gr=e.topology.mobileNodes,Vr=new Set(e.topology.mobileNodes)),Vr)),es=()=>Rr(e=>e.topology.pathHealth),ts=()=>Rr(e=>e.topology.lastHopNeighbors),as=()=>Rr(e=>e.topology.disambiguationStats),ns=()=>Rr(e=>e.topology.disambiguationStats.highCollisionPrefixes),rs=()=>Rr(e=>e.topology.disambiguationStats.totalPrefixes>0),ss=()=>Rr(e=>e.topology.discoveredNodes),os=()=>Rr(e=>e.topology.viterbiStats),is=()=>Rr(e=>(e.topology.discoveredNodes!==Kr&&(Kr=e.topology.discoveredNodes,Jr=e.topology.discoveredNodes.filter(e=>e.isLikelyReal)),Jr)),ls=()=>Rr(e=>e.topology.nodeMetrics),cs=()=>Rr(e=>e.topology.communityCount);let ds=null,us=null;const hs=()=>Rr(e=>{if(e.topology.nodeMetrics!==us){us=e.topology.nodeMetrics,ds={local:0,hub:0,gateway:0,backbone:0,neighbor:0,mobile:0,ghost:0,standard:0};for(const t of e.topology.nodeMetrics.values())ds[t.nodeClass]++}return ds}),ms=()=>Rr(e=>e.topology.traceLinks),gs=()=>Rr(e=>e.topology.traceLinkSummary),ps=()=>Rr(e=>e.topology.traceLinks.size>0),fs=()=>Rr(e=>e.topology.traceDisambiguationFeedback);let bs=null,ys=null;const ws=()=>Rr(e=>{const t=e.topology.traceLinks;if(t!==ys){ys=t;const e=new Map,a=new Map,n=new Set;for(const o of t.values()){const t=o.fromHash0?(i.mean*i.count+l.mean*l.count)/e:0,median:e>0?(i.median*i.count+l.median*l.count)/e:0,min:Math.min(i.min,l.min),max:Math.max(i.max,l.max),stdDev:Math.max(i.stdDev,l.stdDev),count:e}}else i?c=i:l&&(c=l);const d=i&&l?Math.abs(i.mean-l.mean):null,u=i&&l?Math.min(i.mean,l.mean):(null==i?void 0:i.mean)??(null==l?void 0:l.mean)??0,h=u>=10?"excellent":u>=5?"good":u>=0?"fair":u>=-5?"poor":"critical",m=Math.max((null==n?void 0:n.confidence)??0,(null==o?void 0:o.confidence)??0),[g,p]=t.split("|");r.push({nodeA:{hash:g,name:null,prefix:(null==n?void 0:n.fromPrefix)??(null==o?void 0:o.toPrefix)??g.slice(0,2)},nodeB:{hash:p,name:null,prefix:(null==n?void 0:n.toPrefix)??(null==o?void 0:o.fromPrefix)??p.slice(0,2)},aToB:i,bToA:l,composite:c,asymmetryDb:d,quality:h,confidence:m})}r.sort((e,t)=>t.composite.mean-e.composite.mean),bs=r}return bs});function Cs(e,t,a,n){return!t&&n>=3?"offline":a?"connected"!==e&&t||n>0&&n<3?"degraded":"connected":"offline"}const ks=F((e,t)=>({wsState:"disconnected",wsReconnectAttempt:0,restHealthy:!0,lastSuccessfulFetch:null,consecutiveFailures:0,authValid:!0,authExpiresIn:null,meshContext:{edgeCount:0,hubCount:0,lastTopologyUpdate:0,hasTopologyData:!1},health:"connected",bannerDismissed:!1,isInitializing:!0,initialize:()=>{const a=fn.onConnectionChange((a,n)=>{const{restHealthy:r,authValid:s,consecutiveFailures:o,health:i,isInitializing:l}=t(),c=l&&"connected"===a,d=Cs(a,r,s,o);e({wsState:a,wsReconnectAttempt:n??0,health:d,isInitializing:!c&&l,bannerDismissed:(d===i||"connected"!==d)&&t().bannerDismissed})});t().updateAuthState();const n=zr.subscribe(a=>{const{topology:n,lastUpdated:r}=a,s={edgeCount:n.edges.length,hubCount:n.hubNodes.length,lastTopologyUpdate:r,hasTopologyData:n.edges.length>0},o=t().meshContext;o.edgeCount===s.edgeCount&&o.hubCount===s.hubCount&&o.lastTopologyUpdate===s.lastTopologyUpdate||e({meshContext:s})}),r=setTimeout(()=>{t().isInitializing&&e({isInitializing:!1})},1e4),s=setInterval(()=>{t().updateAuthState()},3e4);return()=>{a(),n(),clearTimeout(r),clearInterval(s)}},updateRestHealth:a=>{const{wsState:n,authValid:r,consecutiveFailures:s,health:o}=t(),i=a?0:s+1,l=a||i<3,c=a?Date.now():t().lastSuccessfulFetch,d=Cs(n,l,r,i);e({restHealthy:l,lastSuccessfulFetch:c,consecutiveFailures:i,health:d,bannerDismissed:"connected"!==d&&d===o&&t().bannerDismissed})},updateAuthState:()=>{const a=nn()&&!sn(),n=on(),{wsState:r,restHealthy:s,consecutiveFailures:o,health:i}=t(),l=Cs(r,s,a,o);e({authValid:a,authExpiresIn:n>0?n:null,health:l,bannerDismissed:l===i&&t().bannerDismissed})},dismissBanner:()=>{e({bannerDismissed:!0})}})),vs=()=>ks(e=>e.health),Ds="";class As extends Error{constructor(e,t){super(`Request timed out after ${t}ms: ${e}`),this.endpoint=e,this.timeoutMs=t,this.name="TimeoutError"}}const xs=new Map;let Es=!1;async function Fs(e,t,a=!1){const n=function(e,t){return(null==t?void 0:t.method)&&"GET"!==t.method?"":e}(e,t);if(n){const e=xs.get(n);if(e)return e}const r=`${e}`;!a&&ln()&&(await un()||console.warn("[API] Proactive token refresh failed, continuing with existing token"));const s=en();if(!s&&!e.includes("/auth/"))throw console.warn("[API] No auth token available for protected endpoint:",e),Wa("no_token"),new Error("Not authenticated");const o={Accept:"application/json",...s?{Authorization:`Bearer ${s}`}:{}};if(null==t?void 0:t.headers){const e=t.headers;e instanceof Headers?e.forEach((e,t)=>{o[t]=e}):Array.isArray(e)?e.forEach(([e,t])=>{o[e]=t}):Object.assign(o,e)}(null==t?void 0:t.body)&&(o["Content-Type"]="application/json");const i=!(null==t?void 0:t.method)||"GET"===t.method,l=(null==t?void 0:t.timeout)??(i?15e3:3e4),c=new AbortController,d=setTimeout(()=>c.abort(),l);(null==t?void 0:t.signal)&&(t.signal.aborted?(clearTimeout(d),c.abort()):t.signal.addEventListener("abort",()=>c.abort(),{once:!0}));const u=(async()=>{try{const n=await fetch(r,{...t,headers:o,signal:c.signal});if(clearTimeout(d),401===n.status){if(!a&&!Es){if(await un())return Fs(e,t,!0);console.warn("[API] Token refresh failed")}throw Es||(Es=!0,an(),Wa("session_expired")),new Error("Session expired. Please log in again.")}if(!n.ok)throw new Error(`API error: ${n.status} ${n.statusText} (${e})`);return n.json()}catch(n){if(clearTimeout(d),n instanceof DOMException&&"AbortError"===n.name)throw ks.getState().updateRestHealth(!1),new As(e,l);throw n}})();return n&&(xs.set(n,u),u.finally(()=>{xs.delete(n)})),u}const Bs={spreadingFactor:7,bandwidthHz:125e3,codingRate:5,preambleLength:8,crcEnabled:!0,explicitHeader:!0};function js(e){let t=2;const a=e.route??e.route_type;return 0!==a&&3!==a||(t+=4),null!=e.path_length?t+=e.path_length:Array.isArray(e.original_path)&&(t+=e.original_path.length),t}function Ss(e){if(void 0!==e._byteLength)return e._byteLength;if(e.raw_packet){const t=e.raw_packet;if(/^[0-9a-fA-F]+$/.test(t)&&t.length%2==0)return t.length/2;if(/^[A-Za-z0-9+/=]+$/.test(t)){const e=(t.match(/=+$/)||[""])[0].length;return Math.floor(3*t.length/4)-e}return t.length}if(e.length&&e.length>0)return e.length+js(e);if(e.payload_length&&e.payload_length>0)return e.payload_length+js(e);if(e.payload){const t=e.payload;return/^[0-9a-fA-F]+$/.test(t)&&t.length%2==0?t.length/2:t.length}return 32}function Ms(e,t={}){return void 0!==e.airtime_ms&&e.airtime_ms>0?e.airtime_ms:function(e,t={}){const a=t.spreadingFactor??Bs.spreadingFactor,n=t.bandwidthHz??Bs.bandwidthHz,r=t.codingRate??Bs.codingRate,s=t.preambleLength??Bs.preambleLength??8,o=t.crcEnabled??Bs.crcEnabled?1:0,i=t.explicitHeader??Bs.explicitHeader?0:1,l=a>=11&&n<=125e3?1:0,c=n/1e3,d=Math.pow(2,a)/c,u=(s+4.25)*d,h=Math.max(8*e-4*a+28+16*o-20*i,0),m=4*(a-2*l);return u+(8+Math.ceil(h/m)*r)*d}(Ss(e),t)}function Ns(e){return e&&"chat node"===e.toLowerCase()?"Companion":e}async function Ls(){return function(e){if(e.neighbors)for(const t of Object.values(e.neighbors))t.contact_type=Ns(t.contact_type);return e}(await Fs("/api/stats"))}async function Ts(){return Fs("/api/logs")}async function _s(e){return Fs(`/api/packet_by_hash?packet_hash=${e}`)}async function Rs(e=24){return Fs(`/api/noise_floor_history?hours=${e}`)}const zs=new Map;function Ps(e=!1){if(e)zs.clear();else for(const[t]of zs)parseInt(t.split("-")[0],10)<=60&&zs.delete(t)}function Is(e,t,a,n){const r=60*e/t,s=Math.floor(Date.now()/1e3),o=Math.floor(s/r)*r,i=o-60*e,l=a.filter(e=>e.timestamp>=i&&e.timestamp<=o),c=n?function(e){var t;const a=null==(t=null==e?void 0:e.config)?void 0:t.radio;return{spreadingFactor:(null==a?void 0:a.spreading_factor)??Bs.spreadingFactor,bandwidthHz:(null==a?void 0:a.bandwidth)??Bs.bandwidthHz,codingRate:(null==a?void 0:a.coding_rate)??Bs.codingRate,preambleLength:(null==a?void 0:a.preamble_length)??Bs.preambleLength,crcEnabled:!0,explicitHeader:!0}}(n):Bs,d=function(e,t,a,n,r){const s=new Array(t),o=new Array(t),i=new Array(t),l=new Array(t),c=new Array(t),d=new Array(t),u=new Array(t);for(let m=0;m=t)continue;const p=Ms(h,r),f=h.packet_origin;if("tx_local"===f?(i[g].count++,i[g].airtime_ms+=p):"tx_forward"===f||h.transmitted?(l[g].count++,l[g].airtime_ms+=p):h.drop_reason&&(c[g].count++,c[g].airtime_ms+=p),"tx_local"!==f){s[g].count++,s[g].airtime_ms+=p,d[g].snr+=h.snr||0,d[g].rssi+=h.rssi||0,d[g].count++;const e=h.packet_hash;e&&!u[g].has(e)&&(u[g].add(e),o[g].count++,o[g].airtime_ms+=p)}}for(let m=0;m0&&(s[m].avg_snr=d[m].snr/d[m].count,s[m].avg_rssi=d[m].rssi/d[m].count);return{received:s,unique_received:o,transmitted:i,forwarded:l,dropped:c}}(l,t,i,r,c);return{time_range_minutes:e,bucket_count:t,bucket_duration_seconds:r,start_time:i,end_time:o,...d}}async function $s(e=24){try{return await Fs(`/api/crc_count?hours=${e}`)}catch{return{success:!1,error:"Not available"}}}let qs=1;async function Os(){var e,t;const a=await Fs("/api/hardware_stats");return a.success&&(null==(t=null==(e=a.data)?void 0:e.cpu)?void 0:t.count)&&(qs=a.data.cpu.count),a}async function Hs(){var e;const t=await Fs("/api/hardware_processes");if(t.success&&(null==(e=t.data)?void 0:e.processes)&&qs>1)for(const a of t.data.processes)a.cpu_percent=a.cpu_percent/qs;return t}async function Ws(e){const t={...e};return null!=e.frequency_mhz&&(t.frequency=Math.round(1e6*e.frequency_mhz),delete t.frequency_mhz),null!=e.bandwidth_khz&&(t.bandwidth=Math.round(1e3*e.bandwidth_khz),delete t.bandwidth_khz),Fs("/api/update_radio_config",{method:"POST",body:JSON.stringify(t)})}async function Us(){return Fs("/api/send_advert",{method:"POST",body:"{}"})}async function Vs(e){return Fs("/api/set_mode",{method:"POST",body:JSON.stringify({mode:e})})}async function Gs(e){return Fs("/api/set_duty_cycle",{method:"POST",body:JSON.stringify({enabled:e})})}async function Js(e){try{return await Fs("/api/log_level",{method:"POST",body:JSON.stringify({level:e})})}catch(t){return{success:!1,error:t instanceof Error?t.message:"Unknown error"}}}async function Ks(){return Fs("/api/identities")}async function Xs(){return Fs("/api/acl_info")}async function Ys(e){const t=(new URLSearchParams).toString();return Fs("/api/acl_clients"+(t?"?"+t:""))}async function Qs(e){return Fs("/api/acl_remove_client",{method:"POST",body:JSON.stringify(e)})}async function Zs(){return Fs("/api/acl_stats")}async function eo(e){const t=(new URLSearchParams).toString();return Fs("/api/room_stats"+(t?"?"+t:""))}const to=new class{constructor(){r(this,"worker",null),r(this,"listeners",new Set),r(this,"sparklines",new Map),r(this,"isComputing",!1),r(this,"lastComputeTimeMs",0),r(this,"pendingRequest",null),r(this,"debounceTimer",null),r(this,"debounceMs",150)}ensureWorker(){if(this.worker)return!0;if("undefined"==typeof window)return!1;try{return this.worker=new Worker(new URL("/assets/sparkline.worker-CmKhBAy5.js",import.meta.url),{type:"module"}),this.worker.onmessage=e=>{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[SparklineService] Worker error:",e),this.isComputing=!1,this.notifyListeners()},!0}catch(e){return console.error("[SparklineService] Failed to initialize worker:",e),!1}}handleWorkerMessage(e){if(this.isComputing=!1,"error"===e.type)return console.error("[SparklineService] Worker computation error:",e.error),void this.notifyListeners();if(this.sparklines=new Map(e.payload.sparklineEntries),this.lastComputeTimeMs=e.computeTimeMs,pn.active&&pn.emit("worker:sparkline:done",{ms:e.computeTimeMs,nodes:this.sparklines.size}),this.notifyListeners(),this.pendingRequest){const e=this.pendingRequest;this.pendingRequest=null,this.computeInternal(e.packets,e.nodeHashes)}}computeInternal(e,t){if(!this.ensureWorker())return void console.warn("[SparklineService] Worker not available");if(0===t.length)return this.isComputing=!1,void this.notifyListeners();this.isComputing=!0,pn.active&&pn.emit("worker:sparkline:start",{nodes:t.length,packets:e.length}),this.notifyListeners();const a={type:"compute",payload:{packets:e,nodeHashes:t}};this.worker.postMessage(a)}notifyListeners(){for(const t of this.listeners)try{t(this.sparklines,this.isComputing)}catch(e){console.error("[SparklineService] Listener error:",e)}}compute(e,t){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.isComputing?this.pendingRequest={packets:e,nodeHashes:t}:this.computeInternal(e,t)},this.debounceMs)}getSparkline(e){return this.sparklines.get(e)??[]}getAllSparklines(){return this.sparklines}hasSparkline(e){return this.sparklines.has(e)}isWorking(){return this.isComputing}getLastComputeTime(){return this.lastComputeTimeMs}subscribe(e){return this.listeners.add(e),e(this.sparklines,this.isComputing),()=>{this.listeners.delete(e)}}clear(){this.sparklines.clear(),this.notifyListeners()}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}},ao=F(e=>({connectionState:"disconnected",isSupported:!0,reconnectAttempt:0,lastConnected:null,initialize:()=>{fn.onConnectionChange((t,a)=>{e(e=>({connectionState:t,reconnectAttempt:a??0,isSupported:fn.isSupported(),lastConnected:"connected"===t?Date.now():e.lastConnected}))}),fn.connect()}})),no=.05,ro=1e3,so="terrarium";function oo(e,t,a){try{return e.queryTerrainElevation({lng:t,lat:a})??0}catch{return 0}}const io=F((e,t)=>({terrainGrid:null,isLoading:!1,error:null,lastLoadedAt:null,cachedBounds:null,terrainDisambiguationEnabled:!0,loadTerrain:async(a,n)=>{const r=t();if(!(r.isLoading||(s=r.cachedBounds,o=a,s&&s.minLat<=o.minLat&&s.maxLat>=o.maxLat&&s.minLng<=o.minLng&&s.maxLng>=o.maxLng))){var s,o;e({isLoading:!0,error:null});try{n.getTerrain()||(n.getSource(so)||(n.addSource(so,{type:"raster-dem",tiles:["https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"],encoding:"terrarium",tileSize:256}),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("Terrain source load timeout")),1e4),r=t=>{t.sourceId===so&&t.isSourceLoaded&&(clearTimeout(a),n.off("sourcedata",r),e())};n.on("sourcedata",r)})),n.setTerrain({source:so}),await new Promise(e=>setTimeout(e,500)));const t=await async function(e,t){const{minLat:a,maxLat:n,minLng:r,maxLng:s}=t;let o=Math.ceil((s-r)/.001),i=Math.ceil((n-a)/.001);o>ro&&(o=ro),i>ro&&(i=ro);const l=(s-r)/o,c=(n-a)/i,d=Math.max(l,c),u=new Float32Array(o*i);let h=0;for(let m=0;msetTimeout(e,0))}}return{origin:[a,r],cellSize:d,width:o,height:i,elevations:u}}(n,a);e({terrainGrid:t,isLoading:!1,lastLoadedAt:Date.now(),cachedBounds:a})}catch(i){const t=i instanceof Error?i.message:"Unknown error loading terrain";console.error("[TerrainStore] Load error:",t),e({isLoading:!1,error:t})}}},preloadFromNodes:async(e,a)=>{const n=function(e){const t=e.filter(e=>void 0!==e.latitude&&void 0!==e.longitude&&(0!==e.latitude||0!==e.longitude));if(0===t.length)return null;let a=1/0,n=-1/0,r=1/0,s=-1/0;for(const o of t)a=Math.min(a,o.latitude),n=Math.max(n,o.latitude),r=Math.min(r,o.longitude),s=Math.max(s,o.longitude);return{minLat:a-no,maxLat:n+no,minLng:r-no,maxLng:s+no}}(e);n&&await t().loadTerrain(n,a)},clearTerrain:()=>{e({terrainGrid:null,cachedBounds:null,lastLoadedAt:null,error:null})},setTerrainDisambiguationEnabled:t=>{e({terrainDisambiguationEnabled:t})},getTerrainGridForDisambiguation:()=>{const e=t();return e.terrainDisambiguationEnabled?e.terrainGrid:null}})),lo="pymc-stealth-location";function co(e){if("undefined"!=typeof window)try{localStorage.setItem(lo,JSON.stringify(e))}catch{}}function uo(e){return!isNaN(e)&&e>=-90&&e<=90}function ho(e){return!isNaN(e)&&e>=-180&&e<=180}const mo=function(){if("undefined"==typeof window)return{};try{const e=localStorage.getItem(lo);if(!e)return{};const t=JSON.parse(e);if("number"==typeof t.latitude&&"number"==typeof t.longitude&&"boolean"==typeof t.enabled&&uo(t.latitude)&&ho(t.longitude))return t}catch{}return{}}(),go=F((e,t)=>({latitude:mo.latitude??null,longitude:mo.longitude??null,enabled:mo.enabled??!1,setLocation:(a,n)=>{uo(a)&&ho(n)?(e({latitude:a,longitude:n}),co({latitude:a,longitude:n,enabled:t().enabled})):console.warn("[StealthStore] Invalid coordinates:",a,n)},enable:()=>{const{latitude:a,longitude:n}=t();null!==a&&null!==n?(e({enabled:!0}),co({latitude:a,longitude:n,enabled:!0})):console.warn("[StealthStore] Cannot enable without coordinates")},disable:()=>{e({enabled:!1});const{latitude:a,longitude:n}=t();null!==a&&null!==n&&co({latitude:a,longitude:n,enabled:!1})},clear:()=>{e({latitude:null,longitude:null,enabled:!1}),function(){if("undefined"!=typeof window)try{localStorage.removeItem(lo)}catch{}}()},getEffectiveLocation:()=>{const{latitude:e,longitude:a,enabled:n}=t();return n&&null!==e&&null!==a?{latitude:e,longitude:a}:null},isActive:()=>{const{latitude:e,longitude:a,enabled:n}=t();return n&&null!==e&&null!==a}})),po=class e{constructor(){r(this,"worker",null),r(this,"isReady",!1),r(this,"restartCount",0),r(this,"pendingRequests",[]),r(this,"currentRequest",null),this.initWorker()}initWorker(){if("undefined"!=typeof window)try{this.worker=new Worker(new URL("/assets/decryption.worker-CsyRC9O1.js",import.meta.url),{type:"module"}),this.worker.onmessage=this.handleMessage.bind(this),this.worker.onerror=e=>{console.error("[DecryptionService] Worker error:",e),this.currentRequest&&(this.currentRequest.onBatchComplete(0,0,0),this.currentRequest=null),this.restartWorker()}}catch(e){console.error("[DecryptionService] Failed to initialize worker:",e)}}restartWorker(){this.restartCount>=e.MAX_RESTARTS?console.warn("[DecryptionService] Max restarts reached, not restarting"):(this.restartCount++,console.warn(`[DecryptionService] Restarting worker (attempt ${this.restartCount})`),this.worker&&(this.worker.terminate(),this.worker=null),this.isReady=!1,this.initWorker())}handleMessage(e){var t,a,n,r;const s=e.data;switch(s.type){case"ready":this.isReady=!0,this.processNextRequest();break;case"progress":(null==(t=this.currentRequest)?void 0:t.onProgress)&&this.currentRequest.onProgress(s.processed,s.total);break;case"result":(null==(a=this.currentRequest)?void 0:a.onResult)&&this.currentRequest.onResult(s.result);break;case"results":if(null==(n=this.currentRequest)?void 0:n.onResults)this.currentRequest.onResults(s.results);else if(null==(r=this.currentRequest)?void 0:r.onResult)for(const e of s.results)this.currentRequest.onResult(e);break;case"batchComplete":pn.active&&pn.emit("worker:decryption:batch",{success:s.successCount,total:s.totalCount,ms:s.computeTimeMs}),this.currentRequest&&(this.currentRequest.onBatchComplete(s.successCount,s.totalCount,s.computeTimeMs),this.currentRequest=null),this.processNextRequest();break;case"error":console.error("[DecryptionService] Worker error:",s.error),this.currentRequest&&(this.currentRequest.onBatchComplete(0,0,0),this.currentRequest=null),this.processNextRequest()}}processNextRequest(){if(!this.isReady||!this.worker||this.currentRequest)return;const e=this.pendingRequests.shift();if(!e)return;this.currentRequest={onProgress:e.onProgress,onResult:e.onResult,onResults:e.onResults,onBatchComplete:e.onBatchComplete};const t={type:"decrypt",packets:e.packets,knownKey:e.knownKey};this.worker.postMessage(t)}decrypt(e,t){return new Promise(a=>{const n=e.map(e=>({packet_hash:e.packet_hash,raw_packet:e.raw_packet||"",timestamp:e.timestamp??0,rssi:e.rssi,snr:e.snr,type:e.type,payload_type:e.payload_type}));this.pendingRequests.push({packets:n,knownKey:null==t?void 0:t.knownKey,onProgress:null==t?void 0:t.onProgress,onResults:null==t?void 0:t.onResults,onResult:null==t?void 0:t.onResult,onBatchComplete:(e,t,n)=>{a({successCount:e,totalCount:t,computeTimeMs:n})}}),this.processNextRequest()})}isServiceReady(){return this.isReady}isProcessing(){return null!==this.currentRequest}getPendingCount(){return this.pendingRequests.length}pause(){if(this.worker){const e={type:"pause"};this.worker.postMessage(e)}}resume(){if(this.worker){const e={type:"resume"};this.worker.postMessage(e)}}terminate(){if(this.worker){const e={type:"stop"};this.worker.postMessage(e),this.worker.terminate(),this.worker=null}this.isReady=!1,this.pendingRequests=[],this.currentRequest=null}};r(po,"MAX_RESTARTS",1);const fo=new po;function bo(e){const t=e.replace(/^0x/i,"").replace(/\s/g,"");if(t.length%2!=0)throw new Error("Invalid hex string: odd number of characters");const a=new Uint8Array(t.length/2);for(let n=0;ne.toString(16).padStart(2,"0")).join("");return t&&(n=n.toUpperCase()),a&&(n="0x"+n),n}function wo(e,t=!0){const a=(255&e).toString(16).padStart(2,"0");return t?a.toUpperCase():a}function Co(e,t,a,n){if(e+t>a)throw new Error(n)}function ko(e){if(e>256)throw new Error(`payload too large: ${e} > 256`)}function vo(){return"undefined"!=typeof crypto&&void 0!==crypto.subtle&&"function"==typeof crypto.subtle.digest}const Do=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Ao=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);function xo(e,t){return(e>>>t|e<<32-t)>>>0}function Eo(e,t){let a=e[0],n=e[1],r=e[2],s=e[3],o=e[4],i=e[5],l=e[6],c=e[7];for(let d=0;d<64;d++){if(d>=16){const e=xo(t[d-15&15],7)^xo(t[d-15&15],18)^t[d-15&15]>>>3,a=xo(t[d-2&15],17)^xo(t[d-2&15],19)^t[d-2&15]>>>10;t[15&d]=t[15&d]+e+t[d-7&15]+a>>>0}const e=c+(xo(o,6)^xo(o,11)^xo(o,25))+(o&i^~o&l)+Do[d]+t[15&d]>>>0,u=a&n^a&r^n&r;c=l,l=i,i=o,o=s+e>>>0,s=r,r=n,n=a,a=e+((xo(a,2)^xo(a,13)^xo(a,22))+u>>>0)>>>0}e[0]=e[0]+a>>>0,e[1]=e[1]+n>>>0,e[2]=e[2]+r>>>0,e[3]=e[3]+s>>>0,e[4]=e[4]+o>>>0,e[5]=e[5]+i>>>0,e[6]=e[6]+l>>>0,e[7]=e[7]+c>>>0}function Fo(e){const t=new Uint32Array(Ao),a=new Uint32Array(16),n=8*e.length,r=e.length+9+63&-64,s=new Uint8Array(r);s.set(e),s[e.length]=128;const o=new DataView(s.buffer);o.setUint32(r-4,n,!1);for(let c=0;c>=1}return a}function Lo(e){let t=e[13];e[13]=e[9],e[9]=e[5],e[5]=e[1],e[1]=t,t=e[2],e[2]=e[10],e[10]=t,t=e[6],e[6]=e[14],e[14]=t,t=e[3],e[3]=e[7],e[7]=e[11],e[11]=e[15],e[15]=t}function To(e){for(let t=0;t<16;t++)e[t]=So[e[t]]}function _o(e,t){for(let a=0;a<16;a++)e[a]^=t[a]}function Ro(e){for(let t=0;t<4;t++){const a=4*t,n=e[a],r=e[a+1],s=e[a+2],o=e[a+3];e[a]=No(14,n)^No(11,r)^No(13,s)^No(9,o),e[a+1]=No(9,n)^No(14,r)^No(11,s)^No(13,o),e[a+2]=No(13,n)^No(9,r)^No(14,s)^No(11,o),e[a+3]=No(11,n)^No(13,r)^No(9,s)^No(14,o)}}function zo(e,t){const a=new Uint8Array(e);_o(a,t[10]);for(let n=9;n>=1;n--)Lo(a),To(a),_o(a,t[n]),Ro(a);return Lo(a),To(a),_o(a,t[0]),a}function Po(e,t){const a=function(e){const t=[],a=new Uint8Array(176);a.set(e.slice(0,16));for(let n=16;n<176;n+=4){let e=a[n-4],t=a[n-3],r=a[n-2],s=a[n-1];if(n%16==0){const a=e;e=jo[t]^Mo[n/16-1],t=jo[r],r=jo[s],s=jo[a]}a[n]=a[n-16]^e,a[n+1]=a[n-15]^t,a[n+2]=a[n-14]^r,a[n+3]=a[n-13]^s}for(let n=0;n<11;n++)t.push(a.slice(16*n,16*(n+1)));return t}(e),n=new Uint8Array(t.length);for(let r=0;r>>0}function Oo(e,t){return e[t]|e[t+1]<<8}function Ho(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0}function Wo(e,t,a){t[a]=255&e,t[a+1]=e>>8&255}function Uo(e){return(e instanceof Uint8Array?Array.from(e):e).map(e=>wo(e,!0)).join("->")}const Vo={name:"Public",secret:"8b3387e9c5cdea6ac9e5edbaa115cd72"},Go=["southbay","south-bay","bot","ventura","weather","wardrive","test","icewatch","sbcountymesh","sb-county-mesh","sbcounty","sb-county","meshbud","mesh-bud","ai-bot","aibot","hdmesh","hd-mesh","hdme","hdme7","hdme7yard","hdmeyard","hdmeshtayrd","hdmestayrd","hdmestyard","hdmetayrd","hdmeshtnyard","mustard","socalmesh","socal-mesh","meshla","mesh-la","lamesh","la-mesh","westcoast","west-coast","wcmesh","wc-mesh","eastcoast","east-coast","midwest","southwest","northwest","northeast","southeast","california","cali","santaclarita","santa-clarita","scv","newhall","valencia","saugus","castaic","palmdale","lancaster","antelopevalley","antelope-valley","avmesh","av-mesh","highdesert","high-desert","mojave","victorville","hesperia","barstow","pomona","claremont","glendora","azusa","covina","westcovina","west-covina","walnut","diamondbar","diamond-bar","whittier","brea","yorbalinda","yorba-linda","montebello","montereypark","monterey-park","alhambra","arcadia","monrovia","duarte","hermosabeach","hermosa-beach","manhattanbeach","manhattan-beach","redondobeach","redondo-beach","palosverdes","palos-verdes","sanpedro","san-pedro","ojai","fillmore","santapaula","santa-paula","porthueneme","port-hueneme","general","public","main","default","chat","local","mesh","network","emergency","sos","help","news","info","status","alerts","announce","random","offtopic","off-topic","lobby","lounge","hangout","testing","dev","development","beta","alpha","experimental","personaltest","personal-test","mytest","my-test","testchannel","test-channel","meshcore","mesh-core","meshtastic","lora","lo-ra","lorawan","lora-wan","radio","ham","amateur","hamradio","ham-radio","amateurradio","repeater","repeaters","gateway","node","nodes","rf","rfmesh","offgrid","off-grid","prepper","preppers","emcomm","ares","races","socal","so-cal","southerncalifornia","southern-california","losangeles","los-angeles","la","laarea","la-area","greaterla","sfv","sfvalley","sf-valley","sanfernandovalley","san-fernando-valley","sanfernando","san-fernando","valley","thevalley","the-valley","westla","west-la","eastla","east-la","southla","south-la","dtla","downtown","downtownla","downtown-la","hollywood","beverlyhills","beverly-hills","santamonica","santa-monica","culvercity","culver-city","marinadelrey","marina-del-rey","longbeach","long-beach","torrance","carson","compton","inglewood","pasadena","glendale","burbank","noho","northhollywood","north-hollywood","encino","tarzana","woodland","woodlandhills","woodland-hills","calabasas","malibu","topanga","agoura","agourahills","agoura-hills","thousandoaks","thousand-oaks","simivalley","simi-valley","simi","venturacounty","ventura-county","oxnard","camarillo","moorpark","santabarbara","santa-barbara","sb","goleta","carpinteria","orangecounty","orange-county","oc","irvine","anaheim","fullerton","costamesa","costa-mesa","newportbeach","newport-beach","huntingtonbeach","inlandempire","inland-empire","ie","riverside","sanbernardino","san-bernardino","ontario","rancho","ranchocucamonga","rancho-cucamonga","fontana","corona","palmsprings","palm-springs","palmdesert","palm-desert","coachella","temecula","murrieta","hemet","perris","menifee","sandiego","san-diego","sd","sdmesh","sd-mesh","norcal","nor-cal","northerncalifornia","northern-california","bayarea","bay-area","sfbay","sf-bay","sfbayarea","sf-bay-area","sanfrancisco","san-francisco","sf","sfmesh","sf-mesh","oakland","berkeley","eastbay","east-bay","alameda","sanjose","san-jose","sj","southbay","south-bay","siliconvalley","silicon-valley","santaclara","santa-clara","sunnyvale","mountainview","mountain-view","paloalto","palo-alto","menlopark","menlo-park","redwoodcity","redwood-city","fremont","hayward","unioncity","union-city","newark","milpitas","santacruz","santa-cruz","watsonville","monterey","montereybay","monterey-bay","salinas","carmel","pacificgrove","pacific-grove","sacramento","sac","sactown","westsac","west-sac","roseville","folsom","fresno","bakersfield","stockton","modesto","visalia","seattle","seattlemesh","seattle-mesh","pnw","pacificnorthwest","pacific-northwest","portland","pdx","portlandmesh","portland-mesh","oregon","denver","denvermesh","denver-mesh","colorado","boulder","fortcollins","austin","austinmesh","austin-mesh","atx","texas","sanantonio","san-antonio","dallas","dfw","dallasmesh","dallas-mesh","fortworth","fort-worth","houston","houstonmesh","houston-mesh","htx","phoenix","phoenixmesh","phoenix-mesh","arizona","az","tucson","mesa","tempe","lasvegas","las-vegas","vegas","vegasmesh","vegas-mesh","nevada","henderson","saltlake","salt-lake","slc","saltlakecity","salt-lake-city","utah","chicago","chicagomesh","chicago-mesh","chitown","illinois","detroit","detroitmesh","detroit-mesh","michigan","annarbor","ann-arbor","minneapolis","twincities","twin-cities","minnesota","stpaul","st-paul","atlanta","atlantamesh","atlanta-mesh","atl","georgia","miami","miamimesh","miami-mesh","florida","tampa","orlando","jacksonville","boston","bostonmesh","boston-mesh","massachusetts","cambridge","newyork","new-york","nyc","nycmesh","nyc-mesh","brooklyn","manhattan","queens","newjersey","new-jersey","nj","jersey","philly","philadelphia","philadelphiamesh","philadelphia-mesh","pennsylvania","dc","washingtondc","washington-dc","dmv","nova","maryland","virginia","raleigh","durham","rdu","triangle","northcarolina","north-carolina","charlotte","clt","southcarolina","south-carolina","nashville","tennessee","memphis","knoxville","neworleans","new-orleans","nola","louisiana","hawaii","oahu","honolulu","maui","bigisland","big-island","alaska","anchorage","fairbanks","canada","toronto","vancouver","montreal","calgary","edmonton","ottawa","uk","london","manchester","birmingham","edinburgh","glasgow","bristol","germany","berlin","munich","hamburg","frankfurt","cologne","france","paris","lyon","marseille","spain","madrid","barcelona","italy","rome","milan","netherlands","amsterdam","rotterdam","brabant","flevoland","gelderland","noordbrabant","noordholland","zuid-holland","zuidholland","zeeland","twente","alkmaar","almere","amstelland","capelleaandenijssel","denhaag","dordrecht","drechtsteden","eindhoven","haarlem","hellevoetsluis","hilversum","katwijk","lelystad","maassluis","middelburg","rijnmond","tilburg","utrecht","vlissingen","voorburg","voorne-putten","walcheren","west-friesland","zaandam","zaanstreek-waterland","024-bot","afrithonbot","ai","amradio","analyser","angrynerds","bemesh","buch","burgernet","chatgpt","dares","dekroeg","dtis","english","evenvroegopstaan","fosdem","gezellig","gmr","gmrbot","goedemorgen","gyverbot","haagscourant","hackerspacenijmegen","hamradionederland","hetweerinjegemeente","hsnl","jokes","kanalen","koffie","linux","nerd","nl-alert","nl-prio","noodkanaal","nsagov","pi4hm","pi4utr","pingbot","sensemakers","sports","survival","uitdagingen","valleibot","valleirug","vleesboek","wardrive","weer","australia","sydney","melbourne","brisbane","perth","adelaide","newzealand","new-zealand","auckland","wellington","japan","tokyo","osaka","kyoto","southkorea","south-korea","korea","seoul","taiwan","taipei","singapore","hongkong","hong-kong","india","mumbai","delhi","bangalore","brazil","saopaulo","sao-paulo","rio","mexico","mexicocity","mexico-city","guadalajara","tijuana","gps","location","tracking","tracker","position","coordinates","sensor","sensors","telemetry","data","iot","aprs","beacon","beacons","ping","pings","debug","admin","ops","operations","monitor","monitoring","security","secure","private","encrypted","hiking","camping","outdoors","outdoor","backcountry","trails","offroad","off-road","overlanding","jeep","offroading","sailing","boating","marine","maritime","aviation","flying","pilots","drone","drones","weather","wx","storm","storms","skywarn","traffic","commute","transit","community","group","team","club","family","friends","neighbors","neighborhood","block","street","local","town","city","county","region","north","south","east","west","central","downtown","uptown","midtown","home","house","cabin","ranch","farm","test1","test2","test3","test4","test5","channel1","channel2","channel3","mesh1","mesh2","mesh3","group1","group2","group3","team1","team2","team3","net1","net2","net3","relay","relays","link","links","hub","hubs","core","backbone","qso","ragchew","net","nets","roundtable","simplex","duplex","vhf","uhf","hf","2m","70cm","33cm","23cm","900mhz","915mhz","ism","ism-band","ism915","ism868","license-free","event","events","exercise","drill","training","practice","race","marathon","cycling","running","triathlon","ironman","festival","concert","gathering","meetup","meet-up","convention","hamfest","ham-fest","field-day","fieldday","winter-field-day","sota","pota","summits","parks","parks-on-the-air","2024","2025","2026","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec","winter","spring","summer","fall","autumn","mountain","mountains","hills","peak","summit","ridge","canyon","beach","coast","coastal","shore","bay","lake","river","creek","park","forest","woods","desert","island","peninsula","urban","suburban","rural","metro","area","zone","sector","base","mobile","portable","handheld","fixed","station","primary","secondary","backup","alternate","spare","alpha","bravo","charlie","delta","echo","foxtrot","red","blue","green","yellow","orange","purple","black","white","trace","traces","log","logs","metrics","stats","statistics","raw","stream","feed","live","realtime","real-time","sync","replication","mirror","copy","archive","open","closed","free","premium","pro","plus","lite","basic","new","old","legacy","current","next","future","one","two","three","four","five","six","seven","eight","nine","ten","hamradio","ham-radio","amateurradio","amateur-radio","arrl","dxcc","dxing","morsecode","morse-code","fldigi","js8call","winlink","vara","pactor","packet","ax25","aprsmesh","qrp","qro","qrz","qsl","qth","ragchew","rag-chew","elmer","elmers","technician","amateur","microwave","satellite","ariss","amsat","cubesat","sdr","rtlsdr","rtl-sdr","hackrf","portapack","yaesu","icom","kenwood","elecraft","flexradio","alinco","baofeng","quansheng","antennas","dipole","vertical","yagi","efhw","endfed","wwff","iota","contesting","cwops","auxcomm","satern","maker","makers","makerspace","maker-space","hackerspace","hacker-space","fablab","fab-lab","doityourself","homebrew","home-brew","fromscratch","arduino","esp32","esp8266","stm32","teensy","pico","rp2040","attiny","raspberrypi","raspberry-pi","rpi","beaglebone","beagle-bone","orangepi","orange-pi","kicad","eagle","altium","oshpark","jlcpcb","pcbway","soldering","throughhole","oscilloscope","multimeter","logicanalyzer","logic-analyzer","testbench","3dprinting","3d-printing","3dprint","printer","prusa","ender","creality","bambu","voron","lasercutter","laser-cutter","woodworking","metalworking","welding","resin","fdm","sla","fusion360","fusion-360","freecad","openscad","solidworks","programming","coding","software","developer","developers","devops","sysadmin","linux","unix","bsd","freebsd","openbsd","netbsd","macos","windows","android","ios","python","javascript","typescript","rust","golang","java","kotlin","swift","ruby","perl","csharp","dotnet","haskell","lisp","clojure","elixir","erlang","react","angular","svelte","nodejs","deno","nextjs","nuxt","docker","kubernetes","terraform","ansible","puppet","vagrant","github","gitlab","bitbucket","opensource","open-source","foss","floss","homelab","home-lab","selfhost","self-host","selfhosted","self-hosted","homelabbers","homeassistant","home-assistant","hass","openhab","domoticz","nodered","node-red","mqtt","zigbee","zwave","thread","wifi","bluetooth","rfid","infosec","cybersec","cybersecurity","cyber-security","netsec","opsec","hacking","hacker","hackers","pentest","pentesting","redteam","red-team","blueteam","blue-team","capture-the-flag","bugbounty","bug-bounty","vuln","exploit","malware","reverse","defcon","blackhat","bsides","shmoocon","derbycon","toorcon","hacktheplanet","lockpicking","locksport","toool","deviant","socialeng","social-eng","osint","privacy","anonymity","encryption","crypto","signal","hiking","hiker","hikers","backpacking","backpacker","thru-hike","thruhike","camper","campers","glamping","dispersed","primitive","wilderness","climbing","climber","climbers","rockclimbing","rock-climbing","bouldering","trad","sport","mountaineering","alpine","peaks","fourteeners","14ers","highpoints","skiing","skier","snowboard","snowboarder","backcountry-ski","touring","splitboard","kayak","kayaking","kayaker","canoe","canoeing","paddle","paddling","paddleboard","surfing","surfer","surfers","bodyboard","longboard","shortboard","waves","scuba","freedive","freediving","snorkel","underwater","spearfishing","fishing","angler","anglers","flyfishing","fly-fishing","trout","hunting","hunter","hunters","archery","bowhunting","bow-hunting","rifle","shotgun","cyclist","biking","bicycle","bicycling","roadbike","road-bike","mountainbike","mountain-bike","mountainbiking","mountain-biking","trailriding","ebike","e-bike","ebikes","electric-bike","peloton","strava","zwift","gravel","gravelbike","gravel-bike","bikepacking","bike-packing","randonneur","fixie","fixedgear","fixed-gear","singlespeed","single-speed","commuter","offroading","off-roading","fourwheeling","4wd","awd","jeeping","wrangler","gladiator","tacoma","runner","4runner","overland","overlander","rooftoptent","rooftop-tent","expedition","utv","sxs","sidebyside","side-by-side","rzr","canam","polaris","dirtbike","dirt-bike","motocross","enduro","dualsport","dual-sport","motorcycle","moto","harley","sportbike","cruiser","rving","motorhome","campervan","camper-van","vanlife","van-life","skoolie","trucker","trucking","diesel","semi","bigrig","big-rig","pilot","pilots","flying","flight","airplane","aircraft","planes","cessna","piper","cirrus","beechcraft","mooney","bonanza","skyhawk","helicopter","heli","rotor","rotorcraft","chopper","robinson","glider","gliding","soaring","sailplane","paraglider","paragliding","hangglider","drones","uav","uas","fpv","quadcopter","multirotor","mavic","phantom","rocketry","rockets","hpr","nar","tripoli","model-rocket","amateur-rocket","spacex","nasa","esa","starlink","starship","falcon","artemis","boat","boats","boater","boaters","yachting","yacht","sail","sailor","powerboat","speedboat","fishing-boat","pontoon","jetski","jet-ski","pwc","waverunner","marina","harbor","harbour","dock","pier","anchorage","mooring","liveaboard","cruising","bluewater","blue-water","inshore","intracoastal","marine-radio","marineradio","ais","chartplotter","navionics","opencpn","prepper","preppers","prepping","survival","survivalist","shtf","teotwawki","bol","bugout","bug-out","bugin","bug-in","edc","everyday-carry","loadout","firstaid","first-aid","trauma","tccc","stopthebleed","aed","waterpurification","water-purification","berkey","sawyer","lifestraw","foodstorage","food-storage","canning","dehydrating","freezedried","freeze-dried","battery","generator","inverter","offgrid","off-grid","griddown","grid-down","communications","gmrs","frs","murs","citizens-band","shortwave","homestead","homesteading","homesteader","farming","farmer","farmers","ranching","garden","gardening","gardener","permaculture","organic","regenerative","sustainable","chickens","poultry","goats","sheep","cattle","pigs","livestock","beekeeping","bees","apiary","greenhouse","hydroponics","aquaponics","vertical-farm","indoor-garden","growroom","grow-room","meteorology","stormchasing","storm-chasing","tornado","hurricane","earthquake","quake","seismic","tsunami","volcano","volcanic","geology","geologist","astronomy","stargazing","telescope","astrophotography","astrophoto","deepsky","deep-sky","citizen-science","citizenscience","research","science","stem","education","learning","gaming","gamer","gamers","videogames","video-games","pcgaming","pc-gaming","console","esports","e-sports","competitive","tournament","lan-party","retrogaming","minecraft","terraria","valheim","rust-game","dayz","tarkov","pubg","fortnite","apex","virtualreality","virtual-reality","augmentedreality","augmented-reality","oculus","tabletop","boardgames","board-games","dungeons-dragons","ttrpg","pathfinder","musician","musicians","bands","livemusic","live-music","concerts","guitar","guitarist","bassist","drums","drummer","keyboard","synth","synthesizer","production","producer","producers","beatmaking","beat-making","ableton","flstudio","audiophile","hifi","hi-fi","vinyl","records","turntable","headphones","speakers","podcast","podcasting","podcaster","streaming","streamer","twitch","youtube","content","photography","photographer","photographers","photog","cameras","dslr","mirrorless","canon","nikon","fuji","fujifilm","panasonic","olympus","leica","hasselblad","portrait","wildlife","macro","nightsky","night-sky","timelapse","videography","videographer","filmmaker","filmmaking","cinematography","editing","premiere","davinci","finalcut","final-cut","aftereffects","after-effects","vfx","artist","artists","artwork","creative","creatives","designer","designers","illustration","illustrator","drawing","sketch","sketching","digital-art","digitalart","graphicdesign","graphic-design","uiux","ui-ux","webdesign","web-design","animation","animator","motion","motiongraphics","motion-graphics","3dart","3d-art","blender","foodie","foodies","cooking","cooks","chef","chefs","culinary","kitchen","barbecue","grilling","smoking","smoker","brisket","ribs","pulled-pork","lownslow","baking","baker","sourdough","pastry","dessert","cakes","cookies","brewing","craft-beer","craftbeer","ipa","lager","stout","espresso","barista","roasting","whiskey","bourbon","cocktails","fitness","workout","lifting","weightlifting","powerlifting","bodybuilding","crossfit","hiit","cardio","runners","ultramarathon","triathlete","swimming","swimmer","openwater","open-water","yoga","pilates","meditation","mindfulness","wellness","nutrition","basketball","football","soccer","baseball","hockey","tennis","volleyball","dogs","puppy","puppies","canine","dogtraining","dog-training","cats","kitten","kittens","feline","meow","pets","animals","birding","birdwatching","bird-watching","aquarium","reeftank","reef-tank","saltwater","freshwater","planted-tank","reptiles","reptile","snakes","lizard","gecko","bearded-dragon","neighborhood","nextdoor","meet-up","volunteer","volunteering","nonprofit","non-profit","charity","mutual-aid","mutualaid","parents","parenting","families","children","youth","teens","seniors","lgbtq","pride","queer","nonbinary","ally","allies","inclusive","diversity","burningman","burning-man","playa","blackrock","coachella","sxsw","defcon","hope","layerone","layer-one","supercon","makerfaire","maker-faire","bamboozle","lightning","ragbrai","burnitdown","burning","regional","decomp","toorcamp","chaos","congress","hackathon","ctf-event","capture","wardriving","foxhunt","fox-hunt","brc","ttitd","center-camp","centercamp","esplanade","deep-playa","effigy","temple","soundcamp","sound-camp","mutant-vehicle","art-car","ranger","rangers","lamplighters","dgs","leave-no-trace","moop","gifting","radical-self","immediacy","participation","decommodification","overlandexpo","overland-expo","overlandtrail","overland-trail","overlandbound","overlandjournal","adventurebike","adventure-bike","dirtevery","rubicontrail","rubicon-trail","moab","deathvalley","death-valley","joshua-tree","joshuatree","bigbear","big-bear","mammoth","tahoe","yosemite","sequoia","kingscyn","kings-canyon","meshcore","mesh-core","meshcore-test","meshcore-dev","meshcore-beta","mctest","mc-test","mcdev","mc-dev","mcmain","mc-main","mcpublic","meshcorebot","meshcore-bot","mcbot","mc-bot","meshchat","mesh-chat","meshnet","mesh-net","meshnetwork","mesh-network","meshlink","mesh-link","meshhub","mesh-hub","meshnode","mesh-node","meshrelay","mesh-relay","meshgateway","mesh-gateway","meshbridge","mesh-bridge","meshrouter","meshtalk","mesh-talk","meshvoice","mesh-voice","meshdata","mesh-data","meshsensor","mesh-sensor","meshtrack","mesh-track","meshgps","mesh-gps","meshmap","mesh-map","meshstatus","mesh-status","meshping","mesh-ping","meshtest","mesh-test","meshtesting","mesh-testing","meshdev","mesh-dev","meshops","mesh-ops","meshadmin","mesh-admin","meshmon","mesh-mon","meshlog","mesh-log","meshdebug","mesh-debug","meshdiag","mesh-diag","meshcore-alpha","meshcore-stable","meshcore-main","meshcore-local","mc-alpha","mc-beta","mc-stable","mc-local","mc-ops","mc-admin","meshcoretest","meshcoredev","meshcorebeta","meshcorealpha","meshcoremain","meshcorelocal","meshcoreops","meshcoreadmin","meshcoremon","meshcorelog","meshcorechat","meshcorenet","meshcorelink","meshcorehub","meshcorenode","meshcorerelay","meshcoregateway","meshcorebridge","meshcorerouter","meshcoresensor","meshcoretrack","meshcoregps","meshcoremap","meshcoreping","mcnetwork","mc-network","mcchat","mc-chat","mclink","mc-link","mchub","mc-hub","mcnode","mc-node","mcrelay","mc-relay","mcgateway","mc-gateway","mcbridge","mc-bridge","mcrouter","mc-router","mcsensor","mc-sensor","mctrack","mc-track","mcgps","mc-gps","mcmap","mc-map","mcstatus","mc-status","mcping","mc-ping","mcmon","mc-mon","mclog","mc-log","mcdebug","mc-debug","mcdiag","mc-diag","meshroom","mesh-room","meshrooms","mesh-rooms","meshserver","mesh-server","meshclient","mesh-client","meshcompanion","mesh-companion","meshrepeater","mesh-repeater","meshbase","mesh-base","meshportal","mesh-portal","meshtastic","mesh-tastic","meshtastictest","meshtastic-test","meshtasticdev","meshtastic-dev","meshtasticlocal","meshtastic-local","mttest","mt-test","mtdev","mt-dev","mtlocal","mt-local","longfast","long-fast","longmod","long-mod","longslow","long-slow","shortfast","short-fast","shortslow","short-slow","medfast","med-fast","medslow","med-slow","verylongslow","very-long-slow","meshtastic-alpha","meshtastic-beta","meshtastic-main","meshtastic-stable","meshtasticbeta","meshtasticalpha","meshtasticmain","meshtasticstable","mtbeta","mt-beta","mtalpha","mt-alpha","mtmain","mt-main","mtstable","mt-stable","mtops","mt-ops","mtadmin","mt-admin","mtchat","mt-chat","mtnet","mt-net","mtlink","mt-link","mthub","mt-hub","mtnode","mt-node","mtrelay","mt-relay","longrange","long-range","shortrange","short-range","medrange","med-range","ultralong","ultra-long","ultrafast","ultra-fast","ultraslow","ultra-slow","mediumfast","medium-fast","mediumslow","medium-slow","mediummod","medium-mod","turbofast","turbo-fast","turboslow","turbo-slow","lora","lo-ra","lorawan","lora-wan","loratest","lora-test","loradev","lora-dev","loranet","lora-net","loramesh","lora-mesh","loralink","lora-link","lorahub","lora-hub","loranode","lora-node","lora915","lora-915","lora868","lora-868","lora433","lora-433","sx1262","sx1276","sx1278","semtech","chirp","chirpstack","lorabeta","lora-beta","loraalpha","lora-alpha","loramain","lora-main","lorastable","lora-stable","loraops","lora-ops","loraadmin","lora-admin","lorachat","lora-chat","lorarelay","lora-relay","loragateway","lora-gateway","lorabridge","lora-bridge","lorarouter","lora-router","loraserver","lora-server","lorasensor","lora-sensor","loratrack","lora-track","loragps","lora-gps","loramap","lora-map","lorastatus","lora-status","loraping","lora-ping","loramon","lora-mon","loralog","lora-log","loradebug","lora-debug","lora923","lora-923","lora865","lora-865","lora470","lora-470","sx1261","sx1280","sx1268","sx126x","sx127x","sx128x","llcc68","lr1110","lr1120","lr1121","stm32wl","ra01","ra02","heltec","heltec-lora","ttgo","ttgo-lora","lilygo","lilygo-lora","rak","rak-lora","rak4631","rak3172","rak811","wisblock","test","testing","test1","test2","test3","test123","testchannel","test-channel","testnet","test-net","testmesh","test-mesh","dev","devel","develop","development","devtest","dev-test","sandbox","playground","scratch","temp","temporary","tmp","debug","debugging","diag","diagnostic","diagnostics","alpha","beta","gamma","canary","nightly","unstable","stable","experiment","experimental","trial","pilot","prototype","poc","test4","test5","test6","test7","test8","test9","test10","test01","test02","test03","test-1","test-2","test-3","testA","testB","testC","test-a","test-b","test-c","testing1","testing2","testing3","testing-1","testing-2","testing-3","devnet","dev-net","devmesh","dev-mesh","devchannel","dev-channel","stagenet","stage-net","staging","stage","stagetest","stage-test","qanet","qa-net","qa","qatest","qa-test","qachannel","qa-channel","labnet","lab-net","lab","labtest","lab-test","testlab","test-lab","benchnet","bench-net","benchmark","bench","perftest","perf-test","loadtest","load-test","stresstest","stress-test","smoketest","smoke-test","unittest","unit-test","integtest","integ-test","e2etest","e2e-test","mocknet","mock-net","mock","faker","dummy","sample","example","demonet","demo-net","demo","showcase","preview","prerelease","pre-release","release","rc","release-candidate","releasecandidate","final","production","emergency","emergencies","emer","emerg","911","999","112","sos","mayday","help","rescue","distress","urgent","priority","alert","alerts","warning","warnings","alarm","alarms","safety","safe","danger","hazard","caution","critical","evacuation","evac","evacuate","shelter","shelterinplace","shelter-in-place","lockdown","allclear","all-clear","fire","fires","wildfire","wildfires","brushfire","forestfire","flood","floods","flooding","flashflood","flash-flood","quake","earthquake","aftershock","tsunami","tremor","tornado","hurricane","cyclone","typhoon","storm","severe","missing","missingperson","missing-person","amber","silveralert","medical","medic","ems","ambulance","paramedic","firstaid","first-aid","police","sheriff","lawenforcement","law-enforcement","cert","cert-team","certteam","voad","redcross","red-cross","emergencynet","emergency-net","emergencychannel","emergency-channel","emeralert","emer-alert","sosnet","sos-net","soschannel","sos-channel","maydaynet","mayday-net","maydaychannel","mayday-channel","helpnet","help-net","helpchannel","help-channel","helpline","help-line","rescuenet","rescue-net","rescuechannel","rescue-channel","rescueteam","rescue-team","disaster","disasters","disasternet","disaster-net","disasterrelief","disaster-relief","crisis","crisisnet","crisis-net","crisischannel","crisis-channel","incident","incidentnet","incident-net","incidentchannel","incident-channel","alertnet","alert-net","alertchannel","alert-channel","alertsystem","alert-system","warningnet","warning-net","warningchannel","warning-channel","safetynet","safety-net","safetychannel","safety-channel","safetycheck","safety-check","hazardnet","hazard-net","hazardchannel","hazard-channel","hazmat","haz-mat","firenet","fire-net","firechannel","fire-channel","firefighter","fire-fighter","firedept","fire-dept","firehouse","fire-house","firestation","fire-station","wildfirenet","wildfire-net","wildfirechannel","wildfire-channel","campfire","camp-fire","structurefire","structure-fire","grassfire","grass-fire","floodnet","flood-net","floodchannel","flood-channel","floodwatch","flood-watch","floodwarning","flood-warning","highwater","high-water","risingwater","rising-water","earthquakenet","earthquake-net","earthquakechannel","earthquake-channel","tornadonet","tornado-net","tornadochannel","tornado-channel","hurricanenet","hurricane-net","hurricanechannel","hurricane-channel","stormnet","storm-net","stormchannel","storm-channel","severeweather","severe-weather","medicalnet","medical-net","medicalchannel","medical-channel","traumanet","trauma-net","traumachannel","trauma-channel","traumacenter","trauma-center","hospital","hospitals","clinic","clinics","urgent-care","urgentcare","poisoncontrol","poison-control","cpr-net","cprnet","lifesaver","life-saver","searchandrescue","search-and-rescue","sar","sarnet","sar-net","sarteam","sar-team","coastguard","coast-guard","uscg","lifeguard","life-guard","beachpatrol","beach-patrol","mountainrescue","mountain-rescue","caverescue","cave-rescue","swiftwater","swift-water","k9unit","k9-unit","searchdog","search-dog","rescuedog","rescue-dog","civildefense","civil-defense","fema","dhs","oem","eoc","eocnet","eoc-net","weather","wx","wxalert","wx-alert","wxwatch","wx-watch","wxwarning","wx-warning","wxreport","wx-report","wxupdate","wx-update","forecast","conditions","climate","temperature","temp","temps","rain","rainfall","precipitation","precip","snow","snowfall","wind","winds","windy","gust","gusts","breeze","humidity","humid","dewpoint","dew-point","barometer","pressure","sunny","cloudy","overcast","fog","foggy","mist","haze","smog","heat","heatwave","heat-wave","cold","coldsnap","cold-snap","freeze","lightning","thunder","thunderstorm","tstorm","t-storm","hail","sleet","ice","icy","blackice","black-ice","frost","noaa","nws","skywarn","spotter","spotters","stormspotter","weathernet","weather-net","weatherchannel","weather-channel","wxnet","wx-net","wxchannel","wx-channel","wxstation","wx-station","forecastnet","forecast-net","forecastchannel","forecast-channel","localwx","local-wx","localweather","local-weather","dailywx","daily-wx","hourlywx","hourly-wx","weeklyforecast","weekly-forecast","rainnet","rain-net","rainchannel","rain-channel","rainalert","rain-alert","rainwatch","rain-watch","rainwarning","rain-warning","heavyrain","heavy-rain","snownet","snow-net","snowchannel","snow-channel","snowalert","snow-alert","snowwatch","snow-watch","snowwarning","snow-warning","heavysnow","heavy-snow","blizzard","blizzardwatch","blizzard-watch","blizzardwarning","blizzard-warning","windnet","wind-net","windchannel","wind-channel","windalert","wind-alert","windwatch","wind-watch","windwarning","wind-warning","highwind","high-wind","tempnet","temp-net","tempchannel","temp-channel","tempalert","temp-alert","heatnet","heat-net","heatchannel","heat-channel","heatalert","heat-alert","heatwatch","heat-watch","heatwarning","heat-warning","extremeheat","extreme-heat","coldnet","cold-net","coldchannel","cold-channel","coldalert","cold-alert","coldwatch","cold-watch","coldwarning","cold-warning","extremecold","extreme-cold","winterstorm","winter-storm","icestorm","ice-storm","freezingrain","freezing-rain","thunderstormnet","thunderstorm-net","thunderstormwatch","thunderstorm-watch","thunderstormwarning","thunderstorm-warning","severethunderstorm","severe-thunderstorm","lightningnet","lightning-net","lightningchannel","lightning-channel","lightningalert","lightning-alert","lightningwatch","lightning-watch","tornadowatch","tornado-watch","tornadowarning","tornado-warning","hurricanewatch","hurricane-watch","hurricanewarning","hurricane-warning","tropicalstorm","tropical-storm","tropicaldepression","tropical-depression","stormwatch","storm-watch","stormwarning","storm-warning","stormalert","storm-alert","skywarnnet","skywarn-net","skywarnchannel","skywarn-channel","spotternetwork","spotter-network","stormchase","storm-chase","stormchaser","storm-chaser","amateurwx","amateur-wx","citizenwx","citizen-wx","pwswx","pws-wx","weatherstation","weather-station","wxstation","wx-station","metar","taf","status","stat","stats","statistics","metrics","health","healthcheck","monitor","monitoring","mon","watch","watcher","watchdog","uptime","downtime","outage","outages","incident","incidents","report","reports","reporting","update","updates","bulletin","announce","announcement","announcements","broadcast","broadcasts","notify","notification","notifications","ping","pong","heartbeat","check","checkin","check-in","checkout","check-out","rollcall","roll-call","statusnet","status-net","statuschannel","status-channel","statusupdate","status-update","statusreport","status-report","statuscheck","status-check","statusboard","status-board","monitornet","monitor-net","monitorchannel","monitor-channel","monitoringnet","monitoring-net","monitoringchannel","monitoring-channel","watchnet","watch-net","watchchannel","watch-channel","watchlist","watch-list","healthnet","health-net","healthchannel","health-channel","healthstatus","health-status","uptimenet","uptime-net","uptimechannel","uptime-channel","uptimemonitor","uptime-monitor","outagenet","outage-net","outagechannel","outage-channel","outagereport","outage-report","incidentnet","incident-net","incidentchannel","incident-channel","incidentreport","incident-report","incidentresponse","incident-response","alertsnet","alerts-net","alertschannel","alerts-channel","updatenet","update-net","updatechannel","update-channel","updatefeed","update-feed","bulletinnet","bulletin-net","bulletinchannel","bulletin-channel","bulletinboard","bulletin-board","noticeboard","notice-board","announcenet","announce-net","announcechannel","announce-channel","broadcastnet","broadcast-net","broadcastchannel","broadcast-channel","notifynet","notify-net","notifychannel","notify-channel","pingnet","ping-net","pingchannel","ping-channel","pingtest","ping-test","heartbeatnet","heartbeat-net","heartbeatchannel","heartbeat-channel","rollcallnet","rollcall-net","rollcallchannel","rollcall-channel","checkinnet","checkin-net","checkinchannel","checkin-channel","headcount","head-count","accountability","welfare","wellbeing","well-being","ops","operations","opsnet","ops-net","opschannel","ops-channel","admin","admins","administrator","root","superuser","sudo","control","command","cmd","hq","headquarters","base","basecamp","dispatch","dispatcher","coord","coordinate","coordination","tactical","tac","tacnet","tac-net","tacchannel","tac-channel","logistics","logi","supply","supplies","resource","resources","comms","comm","communications","radio","radionet","radio-net","opsteam","ops-team","opsgroup","ops-group","opscenter","ops-center","opsroom","ops-room","opsdesk","ops-desk","opslead","ops-lead","adminnet","admin-net","adminchannel","admin-channel","adminteam","admin-team","adminops","admin-ops","admingroup","admin-group","admindesk","admin-desk","controlnet","control-net","controlchannel","control-channel","controlroom","control-room","controlcenter","control-center","commandnet","command-net","commandchannel","command-channel","commandpost","command-post","commandcenter","command-center","hqnet","hq-net","hqchannel","hq-channel","hqops","hq-ops","dispatchnet","dispatch-net","dispatchchannel","dispatch-channel","dispatchcenter","dispatch-center","dispatchdesk","dispatch-desk","coordnet","coord-net","coordchannel","coord-channel","coordteam","coord-team","coordcenter","coord-center","coordinationcenter","coordination-center","tacops","tac-ops","tacteam","tac-team","tacgroup","tac-group","taccom","tac-com","taccomms","tac-comms","tacradio","tac-radio","logisticsnet","logistics-net","logisticschannel","logistics-channel","logisticsteam","logistics-team","logisticsops","logistics-ops","supplynet","supply-net","supplychannel","supply-channel","supplychain","supply-chain","resourcenet","resource-net","resourcechannel","resource-channel","commsnet","comms-net","commschannel","comms-channel","commsteam","comms-team","commsops","comms-ops","commscheck","comms-check","commstest","comms-test","radioops","radio-ops","radioteam","radio-team","radiocheck","radio-check","netcontrol","net-control","netops","net-ops","noc","nocnet","noc-net","info","information","infochannel","info-channel","fyi","news","newsfeed","news-feed","headlines","breaking","latest","traffic","trafficreport","traffic-report","roadconditions","road-conditions","transit","bus","train","subway","metro","commute","commuter","events","calendar","schedule","agenda","upcoming","whats-on","infonet","info-net","infohub","info-hub","infodesk","info-desk","infoboard","info-board","infopoint","info-point","infoline","info-line","newsnet","news-net","newschannel","news-channel","newshub","news-hub","newsdesk","news-desk","newsroom","news-room","newsflash","news-flash","breakingnews","breaking-news","latestnews","latest-news","topnews","top-news","localnews","local-news","regionalnews","regional-news","worldnews","world-news","trafficnet","traffic-net","trafficchannel","traffic-channel","trafficupdate","traffic-update","trafficalert","traffic-alert","roadnet","road-net","roadchannel","road-channel","roadupdate","road-update","transitnet","transit-net","transitchannel","transit-channel","transitupdate","transit-update","transitalert","transit-alert","busnet","bus-net","buschannel","bus-channel","busupdate","bus-update","trainnet","train-net","trainchannel","train-channel","trainupdate","train-update","subwaynet","subway-net","subwaychannel","subway-channel","metronet","metro-net","metrochannel","metro-channel","metroupdate","metro-update","commuternet","commuter-net","commuterchannel","commuter-channel","eventsnet","events-net","eventschannel","events-channel","eventshub","events-hub","eventcalendar","event-calendar","localevents","local-events","calendarnet","calendar-net","calendarchannel","calendar-channel","schedulenet","schedule-net","schedulechannel","schedule-channel","agendanet","agenda-net","agendachannel","agenda-channel","upcomingnet","upcoming-net","upcomingchannel","upcoming-channel","location","locations","gps","position","positions","coordinates","track","tracker","tracking","trace","tracer","tracing","beacon","beacons","waypoint","waypoints","checkpoint","checkpoints","geofence","geolocation","geo","mapping","maps","navigate","navigation","locationnet","location-net","locationchannel","location-channel","locationtrack","location-track","locationshare","location-share","gpsnet","gps-net","gpschannel","gps-channel","gpstrack","gps-track","gpsshare","gps-share","gpslog","gps-log","gpsdata","gps-data","positionnet","position-net","positionchannel","position-channel","positiontrack","position-track","positionshare","position-share","coordnet","coord-net","coordchannel","coord-channel","coordshare","coord-share","tracknet","track-net","trackchannel","track-channel","trackshare","track-share","trackingnet","tracking-net","trackingchannel","tracking-channel","tracernet","tracer-net","tracerchannel","tracer-channel","beaconnet","beacon-net","beaconchannel","beacon-channel","beacontrack","beacon-track","beaconshare","beacon-share","waypointnet","waypoint-net","waypointchannel","waypoint-channel","waypointshare","waypoint-share","waypointlog","waypoint-log","checkpointnet","checkpoint-net","checkpointchannel","checkpoint-channel","geofencenet","geofence-net","geofencechannel","geofence-channel","geofencealert","geofence-alert","geozonenet","geozone-net","geonet","geo-net","geochannel","geo-channel","geotrack","geo-track","mappingnet","mapping-net","mappingchannel","mapping-channel","mapnet","map-net","mapchannel","map-channel","mapshare","map-share","navnet","nav-net","navchannel","nav-channel","navtrack","nav-track","navigationnet","navigation-net","navigationchannel","navigation-channel","fleettrack","fleet-track","fleetnet","fleet-net","assettrack","asset-track","whereis","where-is","findme","find-me","locateme","locate-me","nocap","no-cap","frfr","fr-fr","bussin","sheesh","slay","slaps","goated","goat","goats","based","cringe","mid","lowkey","highkey","vibe","vibes","vibing","vibecheck","vibe-check","goodvibes","good-vibes","sus","sussy","sussy-baka","imposter","amongus","among-us","bet","bets","yeet","yeeted","yoink","skibidi","rizz","ohio","bruh","bruv","fam","bestie","besties","squad","squadgoals","squad-goals","slayyy","periodt","purr","queen","king","icon","iconic","legend","main-character","maincharacter","npc","npcs","side-quest","sidequest","understood-the-assignment","ate","served","mother","mothering","rent-free","rentfree","living-rent-free","touch-grass","touchgrass","copium","hopium","doom","doomer","bloomer","zoomer","zoomers","ratio","ratiod","caught-in-4k","receipts","tea","spillthetea","spill-the-tea","simp","simping","stan","stanning","oomf","moots","mutuals","tiktok","fyp","foryou","for-you","foryoupage","trending","viral","cheugy","basic","pick-me","pickme","girlboss","girl-boss","iykyk","iyky","ifykyk","valid","hits-different","hitsdifferent","unhinged","chaotic","feral","unalive","delulu","delusion","bereal","be-real","dump","photodump","photo-dump","core","coded","aesthetic","cottagecore","darkacademia","dark-academia","goblinmode","goblin-mode","softlaunch","soft-launch","hardlaunch","hard-launch","ngl","tbh","ong","on-god","ongod","deadass","dead-ass","fr","real","cap","capping","no-cap-fr","nocapfr","respectfully","allegedly","understood","assignment","ate-that","atethat","devoured","cleared","snatched","slayed","bodied","ended","finished","done","over","deceased","screaming","crying","sobbing","im-weak","imweak","sending-me","sendingme","its-giving","itsgiving","giving","serve","serving","ate-left-no-crumbs","main","protagonist","background-character","backgroundcharacter","side-character","sidecharacter","villain-era","villainera","redemption-arc","character-development","characterdevelopment","plot-twist","plottwist","lore","lore-drop","loredrop","deep-lore","deeplore","canon","fanon","ick","icks","red-flag","redflag","green-flag","greenflag","beige-flag","situationship","talking-stage","talkingstage","roster","rotation","era","eras","villain-arc","healing-era","flop-era","flopping","ate-and-left","understood-assignment","no-thoughts","nothoughts","brain-rot","brainrot","rotted","chronically-online","chronicallyonline","parasocial","hyperfixation","hyperfixating","special-interest","infodump","info-dump","infodumping","yapping","yap","yapper","glazing","glaze","glazer","meat-riding","meatriding","dickriding","aura","aura-points","aurapoints","negative-aura","positiveaura","sigma","sigma-grindset","sigmagrindset","alpha","beta","omega","mewing","mew","looksmax","looksmaxxing","mogging","mog","mogger","gyat","gyatt","bussin-bussin","respectfully-disrespectfully","real-ones","realones","day-ones","dayones","ride-or-die","rideordie","caught-lacking","caughtlacking","down-bad","downbad","down-tremendous","downhorrendous","down-horrendous","astronomically-down","abysmal","its-joever","joever","its-so-over","we-are-so-back","weareback","lock-in","lockin","locked-in","lockedin","locked-tf-in","cooked","cooking","cookin","chef","michelin","gourmet","fr-ong","frong","no-diddy","nodiddy","pause","unpause","resume","edging","edged","gooning","gooned","fanum-tax","fanumtax","hawk-tuah","hawktuah","kai-cenat","speed","ishowspeed","prime","adulting","adult","grown","grownup","grown-up","oldmillennial","avocadotoast","avocado-toast","brunch","brunching","mimosas","doggo","doggie","pupper","puppers","floof","chonk","chonky","birb","smol","smoll","smolbean","smol-bean","boop","snoot","blep","mlem","feels","allthefeels","all-the-feels","rightinthefeels","right-in-the-feels","mood","bigmood","big-mood","sadboi","sad-boi","sadgirl","sad-girl","aesthetic","vsco","vsco-girl","vscogirl","sksksk","andioop","and-i-oop","netflix","netflixandchill","netflix-and-chill","binge","bingewatch","throwback","tbt","throwbackthursday","throwback-thursday","flashback","nostalgia","nostalgic","90skid","90s-kid","80skid","80s-kid","pokemon","pikachu","nintendo","zelda","mario","sonic","sega","harrypotter","harry-potter","hogwarts","hufflepuff","gryffindor","slytherin","ravenclaw","muggle","potterhead","potter-head","starwars","star-wars","jedi","sith","mandalorian","mando","yoda","marvel","mcu","avengers","thanos","ironman","iron-man","spiderman","lotr","lordoftherings","lord-of-the-rings","hobbit","gandalf","frodo","gameofthrones","game-of-thrones","got","thrones","winteriscoming","nailed-it","nailedit","winning","fail","fails","epic","epicfail","fml","yolo","swag","swagger","legit","literally","literally-cant","cant-even","canteven","dying","dead","imdead","im-dead","deceased","goals","lifegoals","life-goals","relationshipgoals","relationship-goals","bae","babe","babes","hubby","wifey","fiance","soulmate","soul-mate","foodporn","food-porn","foodie","nomnom","nom-nom","yummy","delish","wanderlust","travelbug","travel-bug","jetset","jet-set","jetsetter","selfie","selfies","selfietime","selfie-time","groupie","photobomb","blessed","grateful","thankful","humbled","mindblown","mind-blown","extra","salty","shook","triggered","woke","cancelled","cancel","ghosting","ghosted","ghost","friendzone","friend-zone","friendzoned","shade","throwing-shade","tea","spill","spilltea","spill-tea","savage","clap-back","clapback","drag","dragged","read","receipts","tfw","mfw","mrw","dae","eli5","tldr","tl-dr","ama","iama","reddit","redditor","upvote","downvote","karma","cakeday","cake-day","meme","memes","dank","dankmemes","dank-memes","memelord","meme-lord","oldmillenial","xennial","geriatricmillennial","geriatric-millennial","youngmillennial","young-millennial","eldermillennial","elder-millennial","millennialproblems","millennial-problems","millenniallife","millennial-life","firstworldproblems","first-world-problems","struggle","struggles","thestruggle","broke","brokemillennial","broke-millennial","studentloans","student-loans","sidehustle","side-hustle","hustleculture","hustle-culture","grind","grinding","worklifebalance","work-life-balance","burnout","burn-out","selfcare","self-care","treatyoself","treat-yo-self","treatyourself","indulgence","splurge","athleisure","leggings","yoga","yogapants","yoga-pants","pilates","kale","quinoa","acai","matcha","oatmilk","oat-milk","plantbased","plant-based","glutenfree","gluten-free","organic","nongmo","non-gmo","farmtotable","farm-to-table","craftbeer","craft-beer","craftcocktails","craft-cocktails","speakeasy","rooftopbar","rooftop-bar","happyhour","happy-hour","winenight","wine-night","tacotuesday","taco-tuesday","pizzanight","pizza-night","takeout","take-out","doordash","ubereats","uber-eats","grubhub","postmates","instacart","plantmom","plant-mom","plantdad","plant-dad","plantparent","plant-parent","crazycatlady","crazy-cat-lady","dogmom","dog-mom","dogdad","dog-dad","furbaby","fur-baby","furbabies","rescuedog","rescue-dog","adoptdontshop","engagement","engaged","shesaidyes","she-said-yes","weddingplanning","wedding-planning","bridesquad","bride-squad","groomsmen","bachelorette","bachelor","honeymoon","firsthome","first-home","homeowner","home-owner","housegoals","house-goals","diy","diyer","fixer-upper","fixerupper","hgtv","pinterestfail","pinterest-fail","netflix-queue","netflixqueue","bingeing","binge-watching","streamingwars","truecrimeobsessed","true-crime-obsessed","truecrime","true-crime","murderino","podcastaddict","podcast-addict","serialpodcast","serial-podcast","officelife","office-life","corporatelife","corporate-life","cubicle","openoffice","slack","slackchannel","slack-channel","zoomlife","zoom-life","zoommeetings","wfh","workfromhome","work-from-home","remotework","remote-work","hybridwork","quietquitting","quiet-quitting","thegreatresignation","thegreatreshuffling","sundayscaries","sunday-scaries","mondaymotivation","monday-motivation","humpday","hump-day","tgif","fridayfeeling","friday-feeling","fridayvibes","itstheweekend","weekendvibes","weekend-vibes","weekendmode","weekend-mode","lol","lmao","lmfao","rofl","roflmao","omg","wtf","ftw","smh","tbh","icymi","fomo","jomo","fwiw","imho","imo","brb","gtg","ttyl","nbd","idk","idgaf","stfu","nsfw","tmi","btw","afaik","iirc","ymmv","ianal","whatever","whatev","whatevs","meh","blah","ugh","duh","psych","noway","no-way","asif","as-if","getreal","get-real","talktotheh","talk-to-the-hand","nottt","not","sike","syke","psyche","gnarly","rad","radical","tubular","bodacious","righteous","excellent","bogus","heinous","grody","gag-me","gagme","barf","barfbag","gross","dude","dudes","dudette","bro","bros","broski","homie","homies","homes","peeps","posse","crew","gang","clique","tribe","chill","chillax","chillaxin","chilling","chillin","kickin","kickback","kick-back","hangout","hang-out","hangtime","hang-time","couch","couchpotato","couch-potato","vegging","veggingout","vegging-out","slacker","slackers","slack","slacking","procrastinate","procrastinating","grunge","grungy","alternative","alt","indie","underground","mtv","vh1","headbangers","headbanging","moshing","moshpit","mosh-pit","nirvana","cobain","soundgarden","pearljam","pearl-jam","aliceinchains","beavis","butthead","beavisandbutthead","daria","simpsons","bartman","waynesworld","waynes-world","partyon","party-on","schwing","excellent","billted","bill-ted","bogusjourney","bogus-journey","stationn","ferris","ferrisbueller","ferris-bueller","dayoff","day-off","buellerr","breakfast-club","breakfastclub","sixteen-candles","sixteencandles","pretty-in-pink","prettyinpink","mollyringwald","molly-ringwald","johnhughes","john-hughes","hughes","brat-pack","bratpack","pager","beeper","pagenme","page-me","callme","call-me","hitmeup","snailmail","snail-mail","aol","aim","icq","uh-oh","a-s-l","asl","netscape","geocities","angelfire","tripod","webcrawler","askjeeves","gen-x","genx","genxer","gen-xer","xer","xers","forgottengeneration","latchkeykid","latchkey-kid","latchkey","unsupervised","freerange","free-range","mtv-generation","mtvgeneration","mtvkids","mtv-kids","videokilled","video-killed","reagan-era","reaganera","coldwar","cold-war","coldwarkids","cold-war-kids","afterschoolspecial","after-school-special","justdontdoit","saynotodrugs","dareprogram","dare-program","scared-straight","scaredstraight","whatcha-talkin-bout","diffrentstrokes","factsoflife","facts-of-life","familyties","family-ties","growinpains","growin-pains","cosby","cheers","thirtysomething","thirty-something","madaboutyou","mad-about-you","seinfeld","seinfeldian","kramers","masterofyourdomain","yada-yada-yada","friends","centralpark","central-perk","rachel","ross","chandler","monica","melrose","melroseplace","melrose-place","90210","beverlyhills90210","myso-called-life","mysocalledlife","angela","jordan-catalano","jordancatalano","freaksandgeeks","freaks-and-geeks","lindsay","undeclared","realworld","real-world","truestory","true-story","roadrules","road-rules","unplugged","mtv-unplugged","mtvunplugged","acoustic","coffehouse","grunge-era","grungeera","seattlesound","seattle-sound","subpop","sub-pop","smellsliketeenspirit","smells-like-teen-spirit","nevermind","bleach","ten","superunknown","dirt","facelift","jaroffies","jar-of-flies","greenday","green-day","dookie","basketcase","basket-case","wheniseptember","blink182","blink-182","enema","whats-my-age-again","allthesmallthings","sublime","santeria","wrongway","wrong-way","40oz","forty-oz","rage","ratm","rageagainstthemachine","killinginthename","bulls-on-parade","tool","lateralus","aenima","undertow","opiate","spiralout","spiral-out","nineinchnails","nine-inch-nails","nin","closer","headlikeahole","smashingpumpkins","smashing-pumpkins","siamesedream","mellon-collie","radiohead","okcomputer","ok-computer","creep","karma-police","paranoidandroid","beck","loser","odelay","whereitsat","where-its-at","twoturnstables","pulpfiction","pulp-fiction","royalewithcheese","saywhatagain","ezekiel","clerks","viewaskew","view-askew","jayandsilentbob","snootchie","officespace","office-space","tpsreports","tps-reports","piecesofflair","thematrix","the-matrix","redpill","bluepill","neo","morpheus","followthewhiterabbit","fightclub","fight-club","firstrandbeof","projectmayhem","tylerdurden","xfiles","x-files","mulderandscully","thetruthisoutthere","iwanttobelieve","buffy","buffythevampireslayer","buffy-tvs","scoobygang","sunnydale","groovy","far-out","farout","outtasite","outta-sight","righteous","cool","coolio","coolcat","cool-cat","coolbeans","cool-beans","neato","solid","solidgold","solid-gold","golden","goldies","oldies","classics","keen","swell","peachy","peachykeen","peachy-keen","hunky-dory","hunkydory","hip","hipster","hipcat","hip-cat","hep","hepcat","hep-cat","jazzy","square","squares","squaresville","uptight","uncool","unhip","bread","dough","moolah","bucks","clams","greenbacks","benjamins","pad","crib","digs","joint","spot","place","casa","hacienda","wheels","ride","whip","jalopy","hooptie","beater","clunker","oldtimer","old-timer","oldschool","old-school","vintage","retro","classic","backyard","frontporch","front-porch","patio","deck","garage","workshop","hamshack","ham-shack","radioshack","radio-shack","basement","attic","lodge","elks","moose","eagles","vfw","legion","american-legion","rotary","kiwanis","lions","shriners","masons","masonic","fraternal","church","chapel","parish","congregation","fellowship","ministry","sunday","sabbath","potluck","pot-luck","social","supper","supperclub","bridge","bridgeclub","bridge-club","cards","cardgame","card-game","bingo","bunco","poker","pokernight","poker-night","gamenight","game-night","bowling","bowlingalley","bowling-alley","bowlingleague","bowling-league","golf","golfclub","golf-club","teeoff","tee-off","links","fairway","fishing","fishinghole","fishing-hole","fishingbuddy","fishing-buddy","hunting","huntingcamp","hunting-camp","deercamp","deer-camp","cabin","rv","rvclub","rv-club","camper","campground","koa","goodsam","good-sam","snowbird","snowbirds","sunbird","sunbirds","winter-texan","wintertexan","retired","retirement","goldenage","golden-age","goldenyears","golden-years","aarp","seniors","seniormoments","senior-moments","grandkids","grandchildren","boomer","boomers","babyboomer","baby-boomer","babyboomers","baby-boomers","woodstock","woodstocknation","woodstock-nation","hippie","hippies","hippy","peacelove","peace-love","peacesign","peace-sign","makelovenotowar","flowerpower","flower-power","flowerchild","flower-child","summerofove","counterculture","counter-culture","freebird","free-bird","freespirit","tune-in-turn-on","dropmeout","trippingout","tripping-out","psychedelic","grateful-dead","gratefuldead","deadhead","dead-head","deadheads","beatles","beatlemania","fab-four","fabfour","johnpaugeorgeringo","rollingstones","rolling-stones","stones","jagger","keithrichards","thewho","the-who","mygeneration","my-generation","tommyboy","ledzeppelin","led-zeppelin","zeppelin","stairway","stairwaytoheaven","pinkfloyd","pink-floyd","thewall","the-wall","darkside","darksidemoon","doors","thedoors","jimmorrison","jim-morrison","lightmyfire","riders","hendrix","jimi","jimihendrix","purplehaze","purple-haze","voodoo-child","janis","janisjoplin","janis-joplin","mercedesbenz","piecemyheart","ccr","creedence","creedence-clearwater","fortunateson","badmoonrising","eagles","hotelcalifornia","hotel-california","desperado","takiteasy","fleetwood","fleetwoodmac","fleetwood-mac","rumours","dreams","thchain","carlysimon","carly-simon","youresovain","anticipation","simongarfunkel","simon-garfunkel","soundofsilence","bridgeovertroubledwater","caroleking","carole-king","tapestry","youvegotafriend","naturalwoman","crosbystillsnash","crosby-stills-nash","csny","suite-judy-blue-eyes","vietnam","vietnamera","vietnam-era","vietnamvet","vietnam-vet","napalm","civilrights","civil-rights","mlk","martin-luther-king","ihaveadream","moonlanding","moon-landing","apollo","apollo11","onesmallstep","jfk","kennedy","camelot","asknotwhat","cubanmissilecrisis","coldwars","watergate","nixon","rosemarywoods","18minutes","deepthroat","mash","allinthefamily","all-in-the-family","archie","archiebunker","happydays","happy-days","fonzie","thfonz","aaayyyy","jumptheshark","laverne-shirley","laverneshirley","schlemiel","schlimazel","marytylermore","mary-tyler-moore","rhoda","lou-grant","lourant","bobnehart","bob-newhart","newhart","hiimbob","thisislarrybrother","sanford-son","sanfordandson","bigdummy","elizabethimcoming","jeffersons","thejeffersons","movingonup","moving-on-up","deluxe","goodtimes","good-times","dynomite","dy-no-mite","jj","chico-man","chicoman","chicoandtheman","lookingfordwardo","kolchak","nightstalker","night-stalker","barnaby","barnabyjones","columbo","onmorething","one-more-thing","justonemorething","magnum","magnumpi","magnum-pi","selleck","tomelleck","ferrari308","rockfordfiles","rockford-files","jimrockford","answeringmachine","dallastv","dallas-tv","whoshotjr","who-shot-jr","ewingsouthfork","dynasty","alexis","crystalcarrington","catfight","shoulderpads","sixmilliondollarman","bionicwoman","bionic-woman","wecanrebuildhim","the","be","to","of","and","a","in","that","have","i","it","for","not","on","with","he","as","you","do","at","this","but","his","by","from","they","we","say","her","she","or","an","will","my","one","all","would","there","their","what","so","up","out","if","about","who","get","which","go","me","when","make","can","like","time","no","just","him","know","take","people","into","year","your","good","some","could","them","see","other","than","then","now","look","only","come","its","over","think","also","back","after","use","two","how","our","work","first","well","way","even","new","want","because","any","these","give","day","most","us","is","are","was","were","been","good","bad","great","best","worst","first","last","next","only","own","free","open","close","closed","new","old","young","big","small","little","long","short","high","low","fast","slow","quick","hot","cold","warm","cool","hard","soft","easy","difficult","simple","complex","clear","dark","light","bright","deep","shallow","wide","narrow","thick","thin","heavy","full","empty","clean","dirty","wet","dry","loud","quiet","silent","strong","weak","rich","poor","cheap","expensive","safe","dangerous","healthy","sick","happy","sad","angry","calm","busy","lazy","crazy","smart","stupid","clever","wise","dumb","funny","serious","strange","normal","weird","perfect","broken","whole","complete","partial","ready","active","passive","alive","dead","awake","asleep","aware","blind","bold","brave","calm","careful","certain","chief","common","curious","current","direct","double","early","entire","exact","extra","fair","false","famous","final","fine","firm","flat","former","forward","fresh","front","frozen","general","giant","global","golden","grand","green","gross","guilty","hidden","hollow","honest","huge","human","humble","hungry","ideal","ill","inner","instant","intense","internal","joint","just","keen","key","kind","known","large","late","latter","leading","legal","likely","limited","linear","liquid","live","living","local","logical","lonely","loose","lost","lovely","lower","lucky","mad","magic","main","major","male","female","manual","married","massive","master","maximum","mean","medium","mental","middle","military","minimum","minor","missing","mixed","mobile","modern","monthly","moral","mutual","naked","narrow","nasty","native","natural","nearby","neat","negative","nervous","neutral","next","nice","noble","noisy","normal","northern","novel","obvious","odd","official","ok","okay","olympic","only","open","opening","opposite","optional","orange","ordinary","organic","original","other","outdoor","outer","outside","overall","overseas","owing","own","pale","parallel","partial","particular","past","patient","peaceful","peculiar","permanent","personal","petty","physical","pink","plain","pleasant","plenty","plus","pointed","polite","political","popular","positive","possible","potential","powerful","practical","precious","precise","pregnant","present","presidential","pretty","previous","primary","prime","principal","prior","private","probable","productive","professional","profound","progressive","prominent","proper","prospective","protective","proud","provincial","psychological","public","pure","purple","qualified","quick","quiet","radical","random","rapid","rare","raw","ready","real","realistic","reasonable","recent","red","redundant","regional","regular","relative","relevant","reliable","religious","reluctant","remaining","remarkable","remote","representative","resident","resistant","respective","responsible","resulting","revolutionary","rich","ridiculous","right","rigid","rising","risky","rival","romantic","rough","round","royal","ruling","running","rural","sacred","sad","safe","salty","same","sample","go","come","get","give","take","make","do","say","see","look","find","use","tell","ask","work","seem","feel","try","leave","call","keep","let","begin","start","show","hear","play","run","move","live","believe","hold","bring","happen","write","provide","sit","stand","lose","pay","meet","include","continue","set","learn","change","lead","understand","watch","follow","stop","create","speak","read","allow","add","spend","grow","open","walk","win","offer","remember","love","consider","appear","buy","wait","serve","die","send","expect","build","stay","fall","cut","reach","kill","remain","suggest","raise","pass","sell","require","report","decide","pull","break","push","throw","catch","jump","kick","hit","fly","swim","drive","ride","climb","dance","sing","cook","eat","drink","sleep","wake","wash","dress","fight","help","save","teach","study","test","check","join","connect","link","share","post","send","receive","accept","reject","approve","deny","confirm","cancel","reset","restart","refresh","reload","update","upgrade","install","uninstall","download","upload","sync","backup","restore","recover","repair","fix","solve","resolve","complete","finish","time","year","people","way","day","man","woman","child","world","life","hand","part","place","case","week","company","system","program","question","work","government","number","night","point","home","water","room","mother","area","money","story","fact","month","lot","right","study","book","eye","job","word","business","issue","side","kind","head","house","service","friend","father","power","hour","game","line","end","member","law","car","city","community","name","president","team","minute","idea","kid","body","information","back","parent","face","others","level","office","door","health","person","art","war","history","party","result","change","morning","reason","research","girl","guy","moment","air","teacher","force","education","hello","hi","hey","hola","bonjour","ciao","aloha","howdy","greetings","welcome","goodbye","bye","farewell","later","peace","cheers","thanks","thankyou","thank-you","please","sorry","excuse","pardon","congrats","congratulations","bravo","wow","amazing","awesome","cool","nice","great","excellent","perfect","wonderful","fantastic","incredible","unbelievable","omg","wtf","lol","lmao","rofl","haha","hehe","xoxo","hugs","kisses","python","javascript","typescript","java","csharp","cpp","cplusplus","golang","go-lang","rust","rustlang","rust-lang","ruby","php","perl","swift","kotlin","scala","haskell","lisp","clojure","erlang","elixir","fsharp","ocaml","lua","r-lang","rlang","julia","dart","fortran","cobol","assembly","asm","wasm","webassembly","sql","nosql","graphql","mongodb","postgres","postgresql","mysql","mariadb","sqlite","redis","memcached","cassandra","dynamodb","firebase","supabase","prisma","sequelize","typeorm","react","reactjs","react-native","reactnative","angular","angularjs","vue","vuejs","svelte","sveltekit","nextjs","next-js","nuxt","nuxtjs","gatsby","remix","astro","solid","solidjs","preact","qwik","htmx","alpine","tailwind","tailwindcss","bootstrap","bulma","foundation","materialui","chakra","antd","ant-design","shadcn","radix","headlessui","daisyui","nodejs","node-js","deno","bun","express","fastify","koa","nestjs","django","flask","fastapi","rails","rubyonrails","laravel","symfony","spring","springboot","spring-boot","dotnet","aspnet","blazor","maui","electron","tauri","flutter","ionic","capacitor","cordova","xamarin","unity","unreal","godot","pygame","phaser","threejs","three-js","babylon","webpack","vite","rollup","parcel","esbuild","swc","babel","eslint","prettier","jest","vitest","mocha","jasmine","cypress","playwright","selenium","puppeteer","storybook","chromatic","ladle","histoire","docker","kubernetes","k8s","k3s","minikube","helm","istio","envoy","podman","containerd","crio","rancher","openshift","nomad","consul","terraform","pulumi","crossplane","ansible","puppet","chef","saltstack","vagrant","packer","vault","boundary","waypoint","atlantis","argocd","argo-cd","fluxcd","flux-cd","jenkins","circleci","travisci","travis-ci","github-actions","githubactions","gitlab-ci","gitlabci","bitbucket-pipelines","azure-devops","azuredevops","teamcity","bamboo","drone","tekton","spinnaker","aws","amazon","azure","gcp","google-cloud","googlecloud","digitalocean","linode","vultr","hetzner","ovh","scaleway","upcloud","heroku","vercel","netlify","cloudflare","fastly","akamai","cloudfront","railway","render","fly-io","flyio","deno-deploy","workers","cloudflare-workers","lambda","serverless","faas","paas","iaas","saas","baas","kaas","daas","nginx","apache","caddy","traefik","haproxy","envoy","kong","apisix","grafana","prometheus","loki","tempo","jaeger","zipkin","datadog","newrelic","splunk","elastic","elasticsearch","kibana","logstash","elk","fluentd","fluentbit","vector","telegraf","influxdb","timescaledb","questdb","pagerduty","opsgenie","victorops","statuspage","incident-io","rootly","ai","artificial-intelligence","ml","machine-learning","machinelearning","deep-learning","deeplearning","neural","neuralnet","neural-network","tensorflow","pytorch","keras","jax","flax","scikit","sklearn","scipy","numpy","pandas","matplotlib","seaborn","plotly","bokeh","altair","huggingface","hugging-face","transformers","diffusers","datasets","openai","gpt","gpt4","gpt-4","chatgpt","chat-gpt","claude","anthropic","gemini","bard","palm","llama","llama2","llama-2","mistral","mixtral","falcon","mpt","dolly","alpaca","vicuna","orca","phi","zephyr","yi","qwen","deepseek","codellama","code-llama","starcoder","codegen","copilot","cursor","tabnine","codeium","replit","sourcegraph","cody","continue","langchain","llamaindex","llama-index","autogpt","auto-gpt","babyagi","agentgpt","superagi","crewai","autogen","semantic-kernel","guidance","ollama","lmstudio","lm-studio","localai","local-ai","gpt4all","koboldai","oobabooga","text-generation-webui","vllm","tgi","triton","tensorrt","stable-diffusion","stablediffusion","midjourney","dalle","dall-e","imagen","sdxl","controlnet","lora","dreambooth","textual-inversion","automatic1111","comfyui","invokeai","fooocus","kohya","runpod","replicate","banana","modal","anyscale","ray","mlflow","weights-biases","wandb","comet","neptune","clearml","dvc","lakefs","pachyderm","kubeflow","mlrun","seldon","bentoml","mlserver","torchserve","triton-inference","sagemaker","vertex","azure-ml","databricks","snowflake","dbt","airbyte","fivetran","security","cybersec","infosec","netsec","appsec","devsecops","secops","hacking","hacker","hackers","pentest","pentesting","redteam","red-team","blueteam","blue-team","purpleteam","purple-team","bugbounty","bug-bounty","ctf","capture-the-flag","wargames","hackthebox","tryhackme","picoctf","overthewire","vulnhub","exploit","exploits","exploit-db","cve","nvd","mitre","attck","att-ck","owasp","sans","nist","iso27001","soc2","gdpr","hipaa","pci","pci-dss","compliance","audit","forensics","malware","ransomware","trojan","virus","worm","rootkit","botnet","phishing","spearphishing","whaling","vishing","smishing","social-eng","osint","recon","reconnaissance","footprinting","scanning","enumeration","privilege-escalation","privesc","lateral-movement","persistence","exfil","firewall","ids","ips","waf","siem","soar","edr","xdr","mdr","ndr","vpn","proxy","tor","onion","i2p","freenet","darknet","darkweb","encryption","decryption","cipher","hash","hashing","sha","md5","bcrypt","argon2","scrypt","aes","rsa","ecc","ecdsa","ed25519","curve25519","ssl","tls","https","certificates","pki","x509","acme","letsencrypt","oauth","oauth2","oidc","saml","jwt","tokens","sessions","cookies","mfa","2fa","totp","hotp","fido","fido2","webauthn","passkeys","biometrics","password","passwords","passphrase","keychain","vault","secrets","keys","nmap","masscan","zmap","shodan","censys","greynoise","binaryedge","burp","burpsuite","zap","owasp-zap","nikto","sqlmap","metasploit","cobalt-strike","cobaltstrike","empire","covenant","sliver","mythic","mimikatz","bloodhound","responder","impacket","crackmapexec","evil-winrm","hashcat","john","johntheripper","hydra","medusa","aircrack","aircrack-ng","wireshark","tcpdump","tshark","scapy","ettercap","bettercap","mitmproxy","ghidra","ida","radare2","r2","binary-ninja","hopper","cutter","x64dbg","immunity","ollydbg","gdb","lldb","windbg","frida","objection","cycript","blockchain","crypto","cryptocurrency","defi","de-fi","cefi","ce-fi","bitcoin","btc","ethereum","eth","solana","sol","cardano","ada","polkadot","dot","avalanche","avax","polygon","matic","arbitrum","arb","optimism","op","base","zksync","zk-sync","starknet","scroll","linea","cosmos","atom","osmosis","osmo","celestia","tia","injective","inj","near","nearprotocol","aptos","apt","sui","mina","algorand","algo","tezos","xtz","hedera","hbar","fantom","ftm","harmony","one","elrond","egld","flow","icp","internet-computer","filecoin","fil","arweave","ar","storj","sia","akash","akt","render","rndr","chainlink","link","thegraph","grt","api3","band","uma","tellor","uniswap","uni","sushiswap","sushi","pancakeswap","cake","curve","crv","aave","compound","comp","makerdao","maker","mkr","dai","synthetix","lido","steth","rocketpool","reth","frax","convex","cvx","yearn","yfi","dydx","gmx","perpetual","perp","vertex","hyperliquid","drift","opensea","blur","looksrare","x2y2","sudoswap","nftx","rarible","foundation","nft","nfts","pfp","generative","ordinals","inscriptions","brc20","brc-20","wallet","wallets","metamask","phantom","rainbow","rabby","frame","zerion","ledger","trezor","coldcard","bitbox","keystone","hardware-wallet","seed","seedphrase","seed-phrase","mnemonic","private-key","privatekey","mining","miner","miners","hashrate","hash-rate","pow","pos","dpos","staking","stake","validator","validators","delegation","slashing","gas","gwei","eip","eip1559","erc20","erc721","erc1155","erc4626","dao","daos","governance","proposal","voting","snapshot","tally","multisig","multi-sig","gnosis","safe","timelock","vesting","airdrop","hardware","electronics","circuits","pcb","breadboard","soldering","arduino","esp32","esp8266","stm32","teensy","pico","rp2040","attiny","raspberrypi","raspberry-pi","rpi","rpi4","rpi5","rpi-zero","rpizero","beaglebone","beagle-bone","orangepi","orange-pi","bananapi","banana-pi","jetson","nvidia-jetson","nano","xavier","orin","coral","edge-tpu","fpga","verilog","vhdl","systemverilog","chisel","myhdl","amaranth","xilinx","altera","intel-fpga","lattice","gowin","efinix","anlogic","asic","risc","risc-v","riscv","arm","arm64","aarch64","x86","x64","mips","powerpc","sparc","xtensa","avr","pic","msp430","8051","microcontroller","mcu","soc","cpu","gpu","npu","tpu","dpu","ipu","memory","ram","dram","sram","flash","eeprom","rom","nvram","mram","ssd","nvme","hdd","storage","raid","nas","san","das","iscsi","usb","usb-c","thunderbolt","pcie","sata","nvlink","hdmi","displayport","ethernet","wifi","bluetooth","ble","zigbee","zwave","thread","matter","lora","lorawan","sigfox","nbiot","nb-iot","lte-m","catm1","5g","4g","antenna","antennas","rf","sdr","rtl-sdr","hackrf","limesdr","pluto","oscilloscope","logic-analyzer","multimeter","power-supply","signal-gen","3dprinter","3d-printer","3dprinting","fdm","sla","resin","filament","cnc","laser","lasercutter","laser-cutter","plasma","waterjet","edm","physics","quantum","quantum-physics","quantumphysics","quantummechanics","relativity","einstein","newton","particle","particles","hadron","cern","fermion","boson","higgs","quark","lepton","neutrino","photon","electron","proton","neutron","atom","atoms","atomic","nuclear","fission","fusion","plasma","magnetism","electromagnetism","gravity","gravitation","spacetime","blackhole","black-hole","singularity","wormhole","darkmatter","dark-matter","darkenergy","dark-energy","cosmology","bigbang","big-bang","inflation","astronomy","astrophysics","cosmos","universe","multiverse","galaxy","galaxies","milkyway","milky-way","andromeda","nebula","nebulae","pulsar","quasar","magnetar","supernova","nova","dwarf","whitedwarf","reddwarf","star","stars","stellar","solar","sun","sunspot","corona","flare","planet","planets","planetary","exoplanet","mercury","venus","earth","mars","jupiter","saturn","uranus","neptune","pluto","ceres","eris","moon","moons","lunar","asteroid","asteroids","comet","comets","meteor","telescope","telescopes","hubble","webb","jwst","james-webb","chandra","spitzer","kepler","tess","gaia","vlt","elt","keck","alma","ska","nasa","esa","jaxa","isro","roscosmos","cnsa","spacex","blueorigin","virgin-galactic","rocketlab","relativity-space","firefly","astra","chemistry","chem","chemical","chemicals","molecule","molecules","molecular","organic","inorganic","polymer","polymers","catalyst","reaction","synthesis","element","elements","periodic","periodic-table","hydrogen","helium","lithium","carbon","nitrogen","oxygen","sulfur","phosphorus","potassium","calcium","iron","copper","zinc","silver","gold","platinum","uranium","plutonium","biology","bio","biological","bioscience","lifescience","life-science","cell","cells","cellular","dna","rna","mrna","gene","genes","genetic","genetics","genomics","genome","chromosome","protein","proteins","enzyme","bacteria","bacterial","virus","viral","microbe","microbes","microbiology","fungus","fungi","yeast","algae","plankton","protozoa","amoeba","evolution","darwin","natural-selection","species","taxonomy","phylogeny","ecology","ecosystem","biodiversity","conservation","endangered","extinction","botany","botanical","plant","plants","flora","flower","flowers","tree","trees","forest","forests","rainforest","jungle","grassland","savanna","zoology","animal","animals","fauna","mammal","mammals","reptile","reptiles","amphibian","amphibians","bird","birds","avian","fish","fishes","marine","insect","insects","arthropod","arachnid","spider","spiders","butterfly","earth","earthscience","earth-science","geology","geological","geologist","rock","rocks","mineral","minerals","crystal","crystals","gem","gems","volcano","volcanoes","volcanic","lava","magma","eruption","tectonic","earthquake","earthquakes","seismic","seismology","fault","faults","mountain","mountains","peak","peaks","summit","ridge","range","alps","himalayas","rockies","andes","everest","kilimanjaro","fuji","denali","ocean","oceans","oceanic","atlantic","pacific","indian","arctic","antarctic","sea","seas","mediterranean","caribbean","baltic","adriatic","aegean","river","rivers","stream","streams","creek","creeks","delta","estuary","lake","lakes","pond","ponds","reservoir","wetland","wetlands","swamp","island","islands","peninsula","cape","bay","gulf","strait","channel","continent","continents","africa","asia","europe","northamerica","southamerica","australia","oceania","antarctica","arctic","polar","tropical","equator","climate","weather","meteorology","atmosphere","stratosphere","troposphere","temperature","precipitation","humidity","pressure","wind","winds","storm","storms","hurricane","typhoon","cyclone","tornado","tornadoes","lightning","thunder","thunderstorm","monsoon","blizzard","drought","environment","environmental","eco","ecology","green","sustainable","sustainability","renewable","renewables","solar","solar-power","solarpower","wind-power","windpower","hydro","hydroelectric","geothermal","biomass","nuclear-power","nuclearpower","fusion-power","fusionpower","clean-energy","carbon","carbon-neutral","carbonneutral","netzero","net-zero","emissions","greenhouse","co2","methane","ozone","pollution","pollutants","smog","recycle","recycling","compost","composting","waste","zerowaste","zero-waste","plastic","plastics","microplastic","biodegradable","reusable","disposable","organic","natural","vegan","vegetarian","plantbased","plant-based","climate-change","climatechange","global-warming","globalwarming","ipcc","paris-agreement","cop","cop28","unfccc","epa","wwf","greenpeace","sports","sport","athletics","athletic","athlete","athletes","fitness","workout","workouts","exercise","exercises","training","trainer","gym","football","nfl","soccer","fifa","worldcup","world-cup","premier-league","champions-league","laliga","la-liga","bundesliga","seriea","serie-a","basketball","nba","wnba","ncaa","march-madness","hoops","dunk","slam","baseball","mlb","homerun","home-run","worldseries","world-series","hockey","nhl","ice-hockey","icehockey","puck","slap-shot","goalie","tennis","atp","wta","wimbledon","usopen","us-open","roland-garros","golf","pga","lpga","masters","ryder-cup","birdie","eagle","hole-in-one","boxing","mma","ufc","bellator","wrestling","wwe","aew","judo","karate","taekwondo","jiu-jitsu","jiujitsu","bjj","muay-thai","kickboxing","kung-fu","olympics","olympic","paralympics","paralympic","commonwealthgames","running","runner","runners","marathon","marathons","half-marathon","5k","10k","ultra","ultramarathon","trail-running","trailrunning","cross-country","cycling","cyclist","cycling","tour-de-france","tourdefrance","giro","vuelta","time-trial","peloton","velodrome","bmx","mountainbike","mtb","swimming","swimmer","swimmers","pool","freestyle","backstroke","butterfly","triathlon","triathlete","ironman","sprint-tri","olympic-tri","duathlon","weightlifting","powerlifting","crossfit","bodybuilding","strongman","yoga","pilates","aerobics","zumba","hiit","cardio","stretching","mobility","surfing","surf","surfer","surfers","waves","barrel","pipeline","wsl","skateboarding","skate","skater","skaters","sk8","halfpipe","vert","street","snowboarding","snowboard","snowboarder","skiing","ski","skier","slopes","climbing","climber","climbers","bouldering","trad","sport-climbing","parkour","freerunning","free-running","traceur","movement","calisthenics","music","musician","musicians","musical","song","songs","album","albums","artist","artists","band","bands","singer","singers","vocalist","voice","rock","rock-music","rockmusic","rocknroll","rock-n-roll","classic-rock","pop","pop-music","popmusic","kpop","k-pop","jpop","j-pop","cpop","c-pop","hiphop","hip-hop","rap","rapper","rappers","trap","drill","grime","rnb","r-n-b","soul","funk","disco","motown","reggae","dancehall","ska","jazz","jazz-music","jazzmusic","bebop","swing","bigband","big-band","blues","blues-music","bluesmusic","delta-blues","chicago-blues","electric","country","country-music","countrymusic","bluegrass","americana","folk","electronic","edm","techno","house","trance","dubstep","drum-and-bass","dnb","drumnbass","ambient","chillout","chill-out","lofi","lo-fi","beats","classical","classical-music","classicalmusic","orchestra","symphony","opera","choir","choral","chamber","baroque","romantic","contemporary","metal","heavy-metal","heavymetal","death-metal","black-metal","thrash","punk","punk-rock","punkrock","hardcore","emo","screamo","post-punk","indie","indie-rock","indierock","indie-pop","indiepop","alternative","grunge","shoegaze","dream-pop","dreampop","noise","experimental","world-music","worldmusic","latin","salsa","merengue","bachata","cumbia","afrobeat","afro-beat","afropop","afro-pop","highlife","juju","mbalax","guitar","guitarist","bass","bassist","drums","drummer","percussion","keyboard","keyboardist","piano","pianist","synth","synthesizer","keys","violin","violinist","cello","cellist","viola","bass","doublebass","saxophone","sax","trumpet","trombone","clarinet","flute","oboe","horn","dj","deejay","turntable","turntables","mixing","mixer","scratching","producer","producers","production","beatmaker","beat-maker","beats","recording","studio","studios","mastering","mixing","mixing-board","spotify","apple-music","applemusic","tidal","deezer","soundcloud","bandcamp","youtube-music","youtubemusic","amazon-music","amazonmusic","vinyl","records","record","lp","ep","single","singles","discography","concert","concerts","gig","gigs","tour","touring","festival","festivals","coachella","glastonbury","lollapalooza","bonnaroo","burning-man","sxsw","grammy","grammys","brit-awards","vma","ama","billboard","rolling-stone","movies","movie","film","films","cinema","cinematic","theater","theatre","hollywood","bollywood","nollywood","tollywood","anime","animation","documentary","documentaries","doc","docs","docuseries","docu-series","tv","television","series","show","shows","episode","episodes","season","drama","dramas","comedy","comedies","romcom","rom-com","sitcom","sitcoms","action","adventure","thriller","thrillers","horror","scary","slasher","scifi","sci-fi","science-fiction","sciencefiction","fantasy","dystopia","superhero","superheroes","marvel","mcu","dc","dceu","batman","superman","spiderman","spider-man","avengers","xmen","x-men","fantastic-four","starwars","star-wars","startrek","star-trek","trekkie","trekkies","lotr","lord-of-the-rings","lordoftherings","hobbit","tolkien","middle-earth","harrypotter","harry-potter","hogwarts","wizarding","potterhead","gameofthrones","game-of-thrones","got","westeros","houseofdragon","stranger-things","strangerthings","breaking-bad","breakingbad","bettercallsaul","netflix","hulu","disney-plus","disneyplus","hbo","hbomax","max","amazon-prime","amazonprime","primevideo","prime-video","appletv","paramount-plus","paramountplus","peacock","criterion","mubi","shudder","director","directors","filmmaker","filmmakers","cinematographer","dop","actor","actors","actress","actresses","cast","casting","audition","screenwriter","screenwriting","script","scripts","screenplay","storyboard","oscar","oscars","academy-awards","academyawards","emmy","emmys","golden-globe","goldenglobes","bafta","cannes","sundance","tribeca","toronto","tiff","venice","berlinale","sxsw-film","telluride","gaming","gamer","gamers","games","game","videogames","video-games","pc-gaming","pcgaming","console","consoles","handheld","mobile-gaming","playstation","ps5","ps4","ps3","psn","xbox","xboxone","xbox-series","nintendo","switch","switch-2","wii","wiiu","gamecube","n64","snes","nes","steam","steamdeck","steam-deck","epic","epicgames","epic-games","gog","rpg","jrpg","mmorpg","mmo","fps","tps","rts","moba","battle-royale","sandbox","survival","roguelike","roguelite","metroidvania","souls-like","platformer","puzzle","adventure","simulation","sim","sims","strategy","minecraft","fortnite","valorant","csgo","cs2","counterstrike","counter-strike","league","leagueoflegends","league-of-legends","lol","dota","dota2","overwatch","ow2","apex","apexlegends","apex-legends","warzone","callofduty","gta","grandtheftauto","grand-theft-auto","gta6","gta5","rockstar","eldenring","elden-ring","darksouls","dark-souls","bloodborne","sekiro","zelda","totk","botw","tears-of-the-kingdom","breath-of-the-wild","link","mario","supermario","super-mario","mariokart","mario-kart","smashbros","pokemon","pokemongo","pokemon-go","pikachu","scarlet","violet","finalfantasy","final-fantasy","ff16","ff14","ffxiv","squareenix","destiny","destiny2","bungie","halo","haloinfinite","343industries","diablo","diablo4","worldofwarcraft","world-of-warcraft","wow","blizzard","starcraft","hearthstone","overwatch","battlenet","battle-net","assassinscreed","assassins-creed","farcry","far-cry","watchdogs","ubisoft","cyberpunk","cyberpunk2077","witcher","witcher3","cdprojekt","cdpr","baldursgate","baldurs-gate","bg3","larian","divinity","dos2","esports","e-sports","competitive","tournament","tournaments","lan","twitch","streamer","streamers","streaming","youtube-gaming","kick","speedrun","speedrunner","speedrunning","gdq","agdq","sgdq","food","foods","foodie","foodies","cooking","cook","cooks","chef","chefs","recipe","recipes","kitchen","kitchens","culinary","gastronomy","gourmet","restaurant","restaurants","dining","dine","eat","eating","meal","meals","breakfast","brunch","lunch","dinner","supper","snack","snacks","dessert","appetizer","appetizers","entree","entrees","side","sides","course","pizza","pizzas","burger","burgers","sandwich","sandwiches","wrap","wraps","taco","tacos","burrito","burritos","quesadilla","nachos","enchilada","sushi","sashimi","ramen","udon","soba","tempura","teriyaki","bento","pasta","spaghetti","lasagna","ravioli","gnocchi","risotto","italian","steak","steaks","bbq","barbeque","barbecue","grill","grilling","smoker","chicken","beef","pork","lamb","fish","seafood","shrimp","lobster","crab","vegetarian","vegan","plantbased","plant-based","meatless","tofu","tempeh","salad","salads","soup","soups","stew","stews","chili","curry","curries","bread","breads","baking","baker","bakery","pastry","pastries","cake","cookies","brownies","pie","pies","tart","tarts","donut","donuts","coffee","espresso","latte","cappuccino","mocha","americano","coldbrew","tea","teas","greentea","green-tea","blacktea","black-tea","herbal","chai","beer","beers","craft-beer","craftbeer","ipa","lager","stout","ale","brew","wine","wines","redwine","red-wine","whitewine","white-wine","rose","sparkling","cocktail","cocktails","mixology","bartender","bartending","spirits","whiskey","whisky","bourbon","scotch","vodka","gin","rum","tequila","fashion","style","styling","stylist","stylish","trendy","trend","trends","clothing","clothes","outfit","outfits","ootd","lookbook","wardrobe","dress","dresses","shirt","shirts","pants","jeans","shorts","skirt","jacket","jackets","coat","coats","sweater","hoodie","hoodies","blazer","shoes","sneakers","boots","heels","sandals","loafers","footwear","accessories","accessory","jewelry","jewellery","watch","watches","bag","bags","handbag","purse","wallet","sunglasses","hat","hats","scarf","designer","designers","luxury","luxe","haute-couture","hautecouture","runway","catwalk","model","models","modeling","modelling","supermodel","vogue","elle","harpers-bazaar","gq","esquire","cosmopolitan","instyle","beauty","beautiful","gorgeous","stunning","glam","glamour","glamorous","makeup","make-up","cosmetics","lipstick","mascara","eyeliner","eyeshadow","foundation","concealer","blush","bronzer","highlighter","contour","skincare","skin-care","skincareroutine","cleanser","moisturizer","serum","sunscreen","spf","anti-aging","antiaging","wrinkles","acne","pores","hair","haircare","hair-care","hairstyle","hairstyles","haircut","haircolor","blonde","brunette","redhead","highlights","balayage","ombre","extensions","nails","manicure","pedicure","nailart","nail-art","gelnails","acrylics","fragrance","perfume","cologne","scent","scents","aromatherapy","essentials","travel","traveling","travelling","traveler","traveller","travelers","trip","trips","vacation","vacations","holiday","holidays","getaway","adventure","adventures","explore","exploring","explorer","wanderlust","backpacking","backpacker","backpackers","hostel","hostels","hotel","hotels","airbnb","vrbo","booking","expedia","tripadvisor","kayak","skyscanner","flight","flights","airline","airlines","airport","airports","terminal","cruise","cruises","cruising","sailing","yacht","charter","island-hopping","roadtrip","road-trip","roadtrips","driving","scenic","route","routes","hiking","hike","hikes","trail","trails","trek","trekking","camping","beach","beaches","coastal","seaside","oceanfront","beachfront","shore","mountain","mountains","alpine","summit","peak","valley","canyon","gorge","city","cities","urban","metropolitan","downtown","cityscape","skyline","village","villages","town","towns","countryside","rural","scenic","landmark","landmarks","monument","monuments","heritage","unesco","historic","paris","london","newyork","new-york","tokyo","rome","barcelona","amsterdam","berlin","vienna","prague","budapest","lisbon","madrid","athens","istanbul","dubai","singapore","hongkong","hong-kong","bangkok","seoul","taipei","sydney","melbourne","auckland","capetown","cape-town","cairo","marrakech","nairobi","rio","buenosaires","buenos-aires","mexicocity","mexico-city","lima","bogota","sanfrancisco","san-francisco","losangeles","los-angeles","chicago","miami","lasvegas","las-vegas","seattle","boston","austin","denver","portland","vancouver","toronto","montreal","calgary","ottawa","quebec","edmonton","family","families","familytime","family-time","familyfirst","famfam","parents","parenting","parent","parenthood","parentlife","parent-life","mom","moms","momlife","mom-life","mommy","mother","mothers","motherhood","dad","dads","dadlife","dad-life","daddy","father","fathers","fatherhood","kids","kid","children","child","childhood","kidlife","kid-life","toddler","baby","babies","newborn","infant","pregnancy","pregnant","expecting","grandparents","grandma","grandpa","grandmother","grandfather","nana","papa","siblings","sibling","brother","brothers","sister","sisters","twins","friends","friend","friendship","friendships","bestfriend","best-friend","bff","besties","bestie","squad","squadgoals","squad-goals","crew","gang","dating","date","dates","relationship","relationships","couple","couples","boyfriend","girlfriend","partner","partners","significant-other","so","engaged","engagement","fiance","fiancee","wedding","weddings","bride","groom","married","marriage","spouse","husband","wife","newlyweds","anniversary","anniversaries","love","loving","romance","romantic","single","singles","singlelife","single-life","bachelor","bachelorette","divorce","divorced","separated","coparenting","co-parenting","stepparent","blended","blendedfamily","blended-family","adoption","adopted","foster","lgbtq","lgbt","lgbtqia","queer","pride","pridemonth","pride-month","gay","gays","lesbian","lesbians","bisexual","bi","pansexual","pan","transgender","trans","nonbinary","non-binary","nb","genderfluid","genderqueer","asexual","ace","aromantic","aro","demisexual","demi","intersex","ally","coming-out","comingout","outandproud","out-and-proud","loveislove","love-is-love","feminist","feminism","feminists","womensrights","womens-rights","equality","civilrights","civil-rights","humanrights","human-rights","socialjustice","blm","blacklivesmatter","black-lives-matter","antiracism","anti-racism","indigenous","native","firstnations","first-nations","aboriginal","tribal","disability","disabled","accessibility","a11y","inclusion","inclusive","neurodivergent","adhd","autism","autistic","dyslexia","dyslexic","mental-health","mentalhealth","anxiety","depression","bipolar","ptsd","ocd","therapy","selfcare","self-care","wellness","wellbeing","well-being","mindfulness","meditation","meditate","mindful","zen","calm","peace","peaceful","serenity","recovery","sober","sobriety","clean","aa","na","12steps","12-steps","support","supportgroup","support-group","community","communities","tribe","religion","religious","faith","faithful","belief","believe","believer","spiritual","spirituality","spirit","spirits","soul","souls","divine","christian","christianity","christians","church","churches","jesus","christ","catholic","catholicism","catholics","protestant","evangelical","baptist","methodist","lutheran","presbyterian","orthodox","episcopal","anglican","mormon","lds","latterday","latter-day","jehovah","adventist","pentecostal","jewish","judaism","jews","hebrew","israel","israeli","kosher","sabbath","torah","talmud","synagogue","temple","rabbi","hanukkah","passover","yom-kippur","muslim","islam","islamic","muslims","quran","koran","allah","muhammad","mosque","masjid","imam","halal","ramadan","eid","hajj","mecca","medina","hindu","hinduism","hindus","vedic","yoga","karma","dharma","mantra","temple","temples","krishna","shiva","vishnu","ganesh","diwali","holi","buddhist","buddhism","buddhists","buddha","zen","tibetan","dalai-lama","meditation","enlightenment","nirvana","sangha","dharma","sutra","sikh","sikhism","sikhs","guru","gurus","gurdwara","punjabi","pagan","paganism","wicca","wiccan","witchcraft","witch","witches","atheist","atheism","agnostic","agnosticism","secular","humanist","humanism","prayer","prayers","praying","worship","worshipping","praise","praising","blessing","blessings","blessed","miracle","miracles","grace","salvation","heaven","hell","afterlife","eternal","eternity","resurrection","redemption","work","working","worker","workers","workplace","worklife","work-life","job","jobs","career","careers","profession","professional","professionals","office","offices","corporate","corporation","company","companies","business","startup","startups","entrepreneur","entrepreneurs","entrepreneurship","founder","ceo","cto","cfo","coo","cmo","ciso","vp","director","manager","lead","employee","employees","employer","employers","hr","humanresources","human-resources","hiring","hire","recruit","recruiting","recruitment","talent","headhunter","interview","interviews","interviewing","resume","cv","linkedin","networking","salary","salaries","compensation","benefits","perks","bonus","bonuses","promotion","promoted","raise","negotiation","negotiate","contract","contracts","remote","remotework","remote-work","wfh","workfromhome","work-from-home","hybrid","flexible","flexibility","freelance","freelancer","freelancing","gig","gigeconomy","gig-economy","sideproject","side-project","sidehustle","meeting","meetings","presentation","presentations","conference","conferences","project","projects","deadline","deadlines","milestone","milestones","deliverable","team","teams","teamwork","collaboration","collaborate","agile","scrum","kanban","leadership","leader","leaders","management","manage","managing","productivity","efficiency","efficient","effective","performance","kpi","okr","metrics","burnout","stress","stressed","workload","overtime","quit","quitting","resign","retirement","retired","retiring","pension","401k","ira","savings","invest","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","42","50","60","69","70","80","88","90","99","100","101","111","123","200","222","247","300","333","365","400","404","420","444","500","555","666","700","777","800","888","900","911","999","1000","1111","1234","2000","2020","2021","2022","2023","2024","2025","2026","2027","2028","2029","2030","2050","3000","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch10","ch11","ch12","ch13","ch14","ch15","ch16","ch17","ch18","ch19","ch20","channel1","channel2","channel3","channel4","channel5","channel6","channel7","channel8","channel9","channel10","channel11","channel12","channel13","room1","room2","room3","room4","room5","room6","room7","room8","room9","room10","group1","group2","group3","group4","group5","group6","group7","group8","group9","group10","team1","team2","team3","team4","team5","team6","team7","team8","team9","team10","zone1","zone2","zone3","zone4","zone5","zone6","zone7","zone8","zone9","zone10","area1","area2","area3","area4","area5","area6","area7","area8","area9","area10","sector1","sector2","sector3","sector4","sector5","sector6","sector7","sector8","net1","net2","net3","net4","net5","net6","net7","net8","net9","net10","link1","link2","link3","link4","link5","link6","link7","link8","link9","link10","node1","node2","node3","node4","node5","node6","node7","node8","node9","node10","hub1","hub2","hub3","hub4","hub5","hub6","hub7","hub8","hub9","hub10","mesh1","mesh2","mesh3","mesh4","mesh5","mesh6","mesh7","mesh8","mesh9","mesh10","radio1","radio2","radio3","radio4","radio5","radio6","radio7","radio8","radio9","relay1","relay2","relay3","relay4","relay5","relay6","relay7","relay8","relay9","base1","base2","base3","base4","base5","base6","base7","base8","base9","base10","unit1","unit2","unit3","unit4","unit5","unit6","unit7","unit8","unit9","unit10","server1","server2","server3","server4","server5","server6","server7","server8","dev1","dev2","dev3","dev4","dev5","prod1","prod2","prod3","stage1","stage2","test1","test2","test3","test4","test5","test6","test7","test8","test9","test10","user1","user2","user3","user4","user5","admin1","admin2","admin3","ops1","ops2","alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel","india","juliet","kilo","lima","mike","november","oscar","papa","quebec","romeo","sierra","tango","uniform","victor","whiskey","xray","x-ray","yankee","zulu","alpha1","bravo1","charlie1","delta1","echo1","foxtrot1","alpha-team","bravo-team","charlie-team","delta-team","echo-team","team-alpha","team-bravo","team-charlie","team-delta","team-echo","red","blue","green","yellow","orange","purple","pink","black","white","gray","grey","brown","gold","silver","bronze","copper","platinum","cyan","magenta","teal","navy","maroon","olive","lime","aqua","coral","crimson","indigo","violet","turquoise","beige","ivory","tan","khaki","red-team","blue-team","green-team","yellow-team","orange-team","purple-team","team-red","team-blue","team-green","team-yellow","team-orange","team-purple","rednet","bluenet","greennet","blacknet","whitenet","darknet","clearnet","monday","tuesday","wednesday","thursday","friday","saturday","sunday","mon","tue","wed","thu","fri","sat","sun","weekday","weekend","january","february","march","april","may","june","july","august","september","october","november","december","jan","feb","mar","apr","jun","jul","aug","sep","oct","nov","dec","spring","summer","fall","autumn","winter","season","seasons","seasonal","morning","afternoon","evening","night","midnight","noon","dawn","dusk","daily","weekly","monthly","yearly","annual","quarterly","hourly","today","tomorrow","yesterday","now","later","soon","always","never","24-7","247","round-the-clock","nonstop","non-stop","always-on","alwayson","north","south","east","west","northeast","northwest","southeast","southwest","northern","southern","eastern","western","central","middle","center","up","down","left","right","top","bottom","front","back","side","upper","lower","inner","outer","inside","outside","above","below","near","far","close","distant","local","remote","nearby","faraway","here","there","everywhere","anywhere","somewhere","nowhere","wherever","mini","micro","nano","tiny","small","little","medium","large","big","huge","giant","massive","mega","giga","tera","peta","exa","ultra","super","hyper","extreme","max","maximum","min","minimum","plus","extra","lite","light","heavy","full","empty","half","partial","complete","total","all-chat","allchat","main-chat","mainchat","public-chat","publicchat","general-chat","generalchat","global-chat","globalchat","world-chat","worldchat","local-chat","localchat","open-chat","openchat","free-chat","freechat","random-chat","randomchat","voice-chat","voicechat","text-chat","textchat","all-net","allnet","main-net","mainnet","test-net","testnet","dev-net","devnet","local-net","localnet","global-net","globalnet","public-net","publicnet","mesh-net","meshnet","radio-net","radionet","ham-net","hamnet","emerg-net","emergnet","all-hands","allhands","town-hall","townhall","standby","stand-by","on-call","oncall","help-desk","helpdesk","support","tech-support","techsupport","customer-support","feedback","suggestions","ideas","feature-requests","featurerequests","bug-reports","watercooler","water-cooler","coffee-break","coffeebreak","break-room","breakroom","off-topic","offtopic","random","misc","miscellaneous","other","everything-else","introductions","intro","intros","welcome","new-members","newmembers","onboarding","announcements","announce","news","updates","changelog","releases","roadmap","rules","guidelines","faq","faqs","help","how-to","howto","tutorial","tutorials","resources","links","useful-links","usefullinks","bookmarks","reference","docs","showcase","show-and-tell","showandtell","gallery","portfolio","projects","builds","jobs","hiring","careers","opportunities","gigs","freelance","classifieds","buy-sell","buysell","marketplace","trade","trading","swap","swaps","deals","events","meetups","meetup","gatherings","conferences","workshops","webinars","study-group","studygroup","book-club","bookclub","movie-night","movienight","game-night","gamenight","trivia","quiz","contests","challenges","competitions","reddit","twitter","x","facebook","fb","instagram","ig","insta","tiktok","youtube","yt","pinterest","snapchat","snap","linkedin","tumblr","threads","mastodon","fediverse","bluesky","bsky","discord","slack","telegram","signal","whatsapp","messenger","wechat","line","kakao","viber","matrix","element","clubhouse","spaces","periscope","vine","myspace","digg","stumbleupon","quora","medium","substack","patreon","onlyfans","fanhouse","gumroad","behance","dribbble","deviantart","artstation","pixiv","flickr","500px","meme","memes","dank","dankmemes","dank-memes","cursed","blessed","blursed","cringe","based","redpill","redpilled","blackpill","copium","hopium","cope","poggers","pog","pogchamp","pepe","wojak","gigachad","chad","virgin","simp","simping","stan","stanning","parasocial","irl","afk","brb","ttyl","fomo","yolo","goat","goated","lit","fire","slay","slaying","periodt","sus","sussy","imposter","amogus","amongus","among-us","crewmate","ratio","ratiod","L","W","big-L","big-W","touch-grass","touchgrass","npc","npcs","normie","normies","sheeple","boomer","zoomer","doomer","coomer","consoomer","wagie","neet","incel","volcel","blackpilled","glowie","janny","jannie","based-and-redpilled","keyed","kino","sovl","tfw","mfw","mrw","imo","imho","afaik","eli5","tldr","tl-dr","reddit-moment","leddit","hivemind","groupthink","echo-chamber","circlejerk","wholesome","wholesome100","chungus","big-chungus","keanu","reeves","stonks","not-stonks","diamond-hands","diamondhands","paper-hands","hodl","to-the-moon","tothemoon","moon","mooning","ape","apes","ape-together","tendies","gme","gamestop","wallstreetbets","wsb","yeet","yeeted","yoink","noob","newb","newbie","scrub","pwned","owned","rekt","wrecked","gg","ggwp","ggez","ez","ezpz","no-cap","nocap","cap","capping","fr","frfr","bussin","valid","bet","no-shot","sheesh","sheeesh","ong","ongggg","mid","L-take","W-take","hot-take","cold-take","spicy","spicy-take","rent-free","rentfree","living-rent-free","unhinged","brainrot","brain-rot","vtuber","vtubers","vtubing","hololive","nijisanji","vshoujo","idol","content","content-creator","contentcreator","creator","creators","influencer","influencers","viral","viralvideo","viral-video","trending","fyp","foryou","for-you","foryoupage","algorithm","algo","engagement","analytics","metrics","subscriber","subscribers","subs","sub","follower","followers","following","like","likes","share","shares","repost","reposts","retweet","rt","quote","comment","comments","reply","replies","dm","dms","direct-message","inbox","notification","notifications","notif","notifs","ping","pings","mention","highlight","highlights","clip","clips","vod","vods","archive","archives","premiere","premieres","watchparty","watch-party","reaction","reactions","react","reacting","review","reviews","tier-list","tierlist","ranking","collab","collabs","collaboration","crossover","feature","featured","guest","host","hosting","cohost","co-host","panel","panels","podcast","podcasts","episode","ep","eps","season","seasons","series","miniseries","mini-series","subreddit","subreddits","sub","subs","thread","threads","post","posts","forum","forums","board","boards","chan","chans","4chan","8chan","8kun","imageboard","textboard","bbs","bulletin-board","usenet","newsgroup","irc","ircnet","efnet","freenode","libera","oftc","rizon","undernet","xmpp","jabber","mumble","teamspeak","ts3","ventrilo","vent","raidcall","wiki","wikipedia","wikia","fandom","tvtropes","knowyourmeme","kym","encyclopediadramatica","ed","urban-dictionary","urbandictionary","ud","google","alphabet","apple","microsoft","msft","amazon","meta","facebook","nvidia","nvda","amd","intel","qualcomm","broadcom","samsung","tsmc","oracle","sap","salesforce","adobe","autodesk","vmware","dell","hp","hpe","ibm","cisco","juniper","arista","palo-alto","fortinet","crowdstrike","palantir","snowflake","databricks","mongodb","elastic","splunk","datadog","zoom","webex","teams","meet","slack","atlassian","jira","confluence","notion","airtable","coda","asana","monday","clickup","trello","basecamp","figma","sketch","invision","zeplin","framer","webflow","squarespace","wix","shopify","bigcommerce","magento","woocommerce","stripe","paypal","square","plaid","brex","ramp","affirm","klarna","afterpay","coinbase","binance","robinhood","fidelity","vanguard","schwab","etrade","interactive-brokers","uber","lyft","doordash","grubhub","instacart","postmates","deliveroo","airbnb","vrbo","booking","expedia","kayak","tripadvisor","yelp","spotify","apple-music","pandora","soundcloud","bandcamp","tidal","deezer","dropbox","box","onedrive","gdrive","google-drive","icloud","mega","nintendo","sony","playstation","xbox","microsoft-gaming","activision","blizzard","activision-blizzard","ea","electronic-arts","ubisoft","epic","valve","steam","rockstar","take-two","2k","bethesda","zenimax","id-software","bioware","dice","respawn","bungie","343","naughtydog","insomniac","santa-monica","guerrilla","sucker-punch","bend","bluepoint","housemarque","fromsoftware","from-software","bandainamco","bandai-namco","capcom","konami","sega","atlus","squareenix","square-enix","enix","square","level5","gamefreak","game-freak","creatures","pokemon-company","mihoyo","hoyoverse","riot","riot-games","tencent","netease","nexon","ncsoft","krafton","pubg","supercell","king","rovio","zynga","playtika","scopely","jam-city","paradox","firaxis","amplitude","creative-assembly","relic","obsidian","larian","cd-projekt","cdpr","techland","4a-games","remedy","io-interactive","disney","pixar","marvel","lucasfilm","warner","warnerbros","warner-bros","universal","paramount","sony-pictures","lionsgate","mgm","dreamworks","illumination","laika","ghibli","studio-ghibli","toei","sunrise","bones","madhouse","mappa","wit","trigger","kyoani","kyoto-animation","ufotable","a1-pictures","cloverworks","shaft","gainax","khara","production-ig","ig","netflix","hulu","hbo","max","disney-plus","prime-video","peacock","paramount-plus","apple-tv","crunchyroll","funimation","hidive","vrv","cbs","nbc","abc","fox","cw","amc","fx","showtime","starz","epix","bbc","itv","channel4","sky","britbox","hayu","acorn","curiositystream","discovery","discovery-plus","history","natgeo","nat-geo","animal-planet","tesla","rivian","lucid","nio","xpeng","byd","polestar","fisker","ford","gm","general-motors","chevy","chevrolet","dodge","ram","jeep","chrysler","toyota","honda","nissan","mazda","subaru","mitsubishi","hyundai","kia","genesis","volkswagen","vw","audi","bmw","mercedes","porsche","lamborghini","ferrari","maserati","alfa-romeo","fiat","volvo","land-rover","range-rover","jaguar","bentley","rolls-royce","aston-martin","mclaren","bugatti","koenigsegg","pagani","rimac","lotus","alpine","medical","medicine","healthcare","health-care","hospital","hospitals","doctor","doctors","dr","physician","physicians","surgeon","surgeons","nurse","nurses","nursing","rn","lpn","cna","np","pa","physician-assistant","pharmacy","pharmacist","pharmacists","pharma","pharmaceutical","rx","dentist","dentists","dental","dentistry","orthodontist","orthodontics","optometrist","ophthalmologist","optometry","vision","eye-care","eyecare","therapist","therapists","therapy","counselor","counseling","psychologist","psychiatrist","psychiatry","psychology","mental-health","mentalhealth","physical-therapy","pt","occupational-therapy","ot","speech-therapy","slp","chiropractor","chiropractic","acupuncture","acupuncturist","naturopath","emt","paramedic","paramedics","ems","emergency","er","icu","nicu","radiology","radiologist","xray","mri","ct","ultrasound","imaging","pathology","pathologist","lab","laboratory","diagnostics","testing","oncology","oncologist","cancer","tumor","chemotherapy","radiation","cardiology","cardiologist","heart","cardiac","cardiovascular","cv","neurology","neurologist","neuro","brain","spine","neurosurgery","pediatrics","pediatrician","peds","children","child-health","childhealth","geriatrics","geriatrician","elderly","senior-care","seniorcare","aging","dermatology","dermatologist","derm","skin","skincare","skin-care","orthopedics","orthopedic","ortho","bone","joint","sports-medicine","gastroenterology","gastro","gi","digestive","gut","intestinal","endocrinology","endocrine","diabetes","thyroid","hormone","hormones","pulmonology","pulmonologist","respiratory","lung","lungs","breathing","nephrology","nephrologist","kidney","kidneys","renal","dialysis","urology","urologist","bladder","prostate","urinary","reproductive","obgyn","ob-gyn","obstetrics","gynecology","obstetrician","gynecologist","fertility","ivf","reproductive-health","reproductivehealth","prenatal","legal","lawyer","lawyers","attorney","attorneys","law","laws","lawfirm","paralegal","paralegals","legal-assistant","legalassistant","clerk","clerks","judge","judges","court","courts","courthouse","trial","trials","jury","litigation","litigator","litigators","lawsuit","lawsuits","case","cases","criminal","criminal-law","defense","defender","prosecution","prosecutor","civil","civil-law","tort","torts","injury","personal-injury","malpractice","corporate-law","corporatelaw","business-law","commercial","contracts","intellectual-property","ip","patent","patents","trademark","copyright","family-law","familylaw","divorce","custody","child-support","alimony","immigration","immigration-law","visa","visas","citizenship","naturalization","real-estate-law","property-law","estate","estates","probate","trusts","tax-law","taxlaw","irs","tax-attorney","taxattorney","audit","audits","employment-law","labor-law","hr-law","discrimination","harassment","constitutional","constitutional-law","civil-rights","human-rights","environmental-law","epa","regulation","regulations","compliance","bankruptcy","restructuring","insolvency","creditor","debtor","debt","education","educator","educators","teach","teaching","teacher","teachers","professor","professors","prof","profs","faculty","academic","academics","student","students","pupil","pupils","learner","learners","learning","school","schools","elementary","primary","middle-school","middleschool","high-school","highschool","secondary","k12","k-12","grade","grades","college","colleges","university","universities","uni","campus","campuses","undergraduate","undergrad","graduate","grad","postgrad","phd","doctorate","masters","bachelors","associates","degree","degrees","diploma","diplomas","curriculum","syllabus","course","courses","class","classes","lecture","seminar","seminars","workshop","workshops","lab","labs","laboratory","tutor","tutors","tutoring","mentor","mentors","mentoring","mentorship","homeschool","homeschooling","unschool","unschooling","montessori","waldorf","stem","steam","science","math","mathematics","calculus","algebra","english","literature","writing","grammar","composition","rhetoric","history","geography","social-studies","socialstudies","civics","economics","art","arts","music","drama","theater","theatre","dance","visual-arts","physical-education","pe","gym","athletics","sports","health","wellness","construction","contractor","contractors","builder","builders","building","carpenter","carpenters","carpentry","woodwork","woodworking","woodworker","electrician","electricians","electrical","electric","wiring","power","plumber","plumbers","plumbing","pipes","piping","drainage","sewage","hvac","heating","cooling","ac","air-conditioning","ventilation","duct","roofer","roofers","roofing","roof","roofs","shingles","gutters","mason","masons","masonry","brick","bricks","stone","concrete","cement","painter","painters","painting","paint","wallpaper","drywall","finishing","welder","welders","welding","fabrication","fabricator","metalwork","machinist","machinists","machining","lathe","mill","milling","turning","mechanic","mechanics","mechanical","automotive","auto","car-repair","landscaper","landscapers","landscaping","lawn","garden","gardening","surveyor","surveyors","surveying","survey","land","property","boundary","architect","architects","architecture","architectural","design","drafting","engineer","engineers","engineering","structural","civil-engineering","inspector","inspectors","inspection","code","codes","permit","permits","firefighter","firefighters","fire","fire-department","firedepartment","fd","police","police-officer","policeofficer","cop","cops","officer","officers","sheriff","sheriffs","deputy","deputies","detective","detectives","state-trooper","trooper","troopers","highway-patrol","patrol","patrolling","swat","tactical","k9","k-9","canine","bomb-squad","bombsquad","hostage","emt","emts","paramedic","paramedics","ambulance","ems","first-responder","dispatcher","dispatchers","dispatch","911","emergency","emergencies","search-rescue","sar","rescue","rescuer","rescuers","coast-guard","lifeguard","hazmat","hazardous","decon","decontamination","chemical","biological","military","armed-forces","armedforces","defense","defence","dod","mod","army","soldier","soldiers","infantry","armor","artillery","cavalry","navy","sailor","sailors","naval","fleet","submarine","surface","carrier","airforce","air-force","pilot","pilots","aviator","aviation","fighter","marines","marine","marinecorps","marine-corps","leatherneck","oorah","coastguard","coast-guard","uscg","maritime","port","harbor","border","spaceforce","space-force","ussf","space","satellite","orbital","launch","national-guard","nationalguard","guard","reserve","reserves","reservist","veteran","veterans","vet","vets","retired","retiree","retirees","officer","officers","enlisted","nco","warrant","general","admiral","special-ops","specialops","specops","sof","delta","seals","rangers","green-berets","greenberets","airborne","paratrooper","paratroopers","outdoor","outdoors","outside","nature","wilderness","wild","backcountry","hiking","hiker","hikers","backpacking","backpacker","thru-hike","thruhike","camping","camper","campers","campsite","tent","tenting","glamping","rv","rving","campervan","vanlife","van-life","overlanding","overland","fishing","fisher","fishers","angler","anglers","angling","fly-fishing","hunting","hunter","hunters","hunt","game","wildlife","deer","elk","duck","birding","birdwatching","bird-watching","birder","birders","ornithology","foraging","forager","foragers","mushroom","mushrooms","fungi","mycology","kayaking","kayak","kayaker","kayakers","canoeing","canoe","paddling","rafting","raft","rafts","whitewater","white-water","rapids","river","scuba","diving","diver","divers","snorkeling","snorkel","freediving","sailing","sailor","sailors","sail","sailboat","yacht","yachting","rock-climbing","rockclimbing","bouldering","climber","climbers","crag","mountaineering","mountaineer","alpinism","alpine","summit","peak-bagging","caving","caver","cavers","spelunking","spelunker","cave","caves","offroad","off-road","atv","utv","sxs","dirtbike","dirt-bike","quad","photography","photographer","photographers","photo","photos","camera","videography","videographer","video","videos","filming","filmmaking","painting","painter","painters","canvas","acrylic","oil","watercolor","drawing","drawer","drawers","sketch","sketching","pencil","charcoal","sculpting","sculptor","sculptors","sculpture","clay","pottery","ceramics","knitting","knitter","knitters","knit","yarn","wool","needles","pattern","crocheting","crochet","crocheter","hook","hooks","amigurumi","blanket","sewing","sewer","sewers","seamstress","tailor","fabric","quilting","embroidery","embroiderer","cross-stitch","crossstitch","needlepoint","woodworking","woodworker","woodworkers","carpentry","furniture","lathe","metalworking","metalworker","blacksmith","blacksmithing","forge","forging","leatherworking","leatherwork","leather","leathercraft","tanning","tooling","jewelry-making","jewelrymaking","jeweler","beading","beads","wirework","origami","paper-craft","papercraft","scrapbooking","scrapbook","cardmaking","calligraphy","calligrapher","lettering","hand-lettering","handlettering","candle-making","candlemaking","soap-making","soapmaking","bath-bombs","collecting","collector","collectors","collection","collections","collectible","stamps","stamp","philately","philatelist","postage","postal","letters","coins","coin","numismatics","numismatist","currency","bullion","precious","cards","card","trading-cards","tradingcards","tcg","ccg","mtg","pokemon-tcg","comics","comic","comic-books","comicbooks","graphic-novels","graphicnovels","manga","manhwa","manhua","webtoon","webtoons","light-novel","lightnovel","figurines","figure","figures","statue","statues","action-figures","toys","funko","funko-pop","funkopop","pop","pops","nendoroid","figma","sh-figuarts","model-kits","modelkits","gunpla","gundam","plamo","scale-models","miniatures","lego","legos","bricks","moc","mocs","afol","tfol","kfol","megabloks","antiques","antique","vintage","retro","thrift","thrifting","estate-sale","vinyl","records","record","lp","lps","turntable","audiophile","hifi","watches","watch","horology","horologist","timepiece","wristwatch","pocket","boardgame","boardgames","board-games","board-game","tabletop","table-top","cardgame","cardgames","card-games","card-game","deckbuilder","deck-builder","rpg","rpgs","tabletop-rpg","ttrpg","pen-and-paper","roleplay","roleplaying","dnd","d-and-d","dungeons-and-dragons","dungeonsanddragons","dungeon","dragon","pathfinder","starfinder","call-of-cthulhu","coc","shadowrun","cyberpunk-red","warhammer","warhammer40k","40k","age-of-sigmar","aos","sigmar","gw","warmachine","hordes","infinity","malifaux","necromunda","kill-team","killteam","miniature","miniatures","minis","mini","wargaming","wargames","wargamer","painting-minis","paintingminis","mini-painting","minipainting","terrain","chess","checkers","go","baduk","weiqi","shogi","mahjong","mah-jong","poker","blackjack","bridge","canasta","rummy","hearts","spades","solitaire","catan","settlers","ticket-to-ride","tickettoride","pandemic","wingspan","gloomhaven","spirit-island","spiritisland","terraforming-mars","scythe","pets","pet","petcare","pet-care","petowner","pet-owner","petparents","dogs","dog","puppy","puppies","pupper","doggo","doggos","canine","k9","cats","cat","kitten","kittens","kitty","kitties","feline","meow","birds","bird","parrot","parrots","parakeet","budgie","cockatiel","finch","fish","aquarium","aquariums","fishtank","fish-tank","freshwater","saltwater","reef","reeftank","reef-tank","coral","corals","marine","aquascape","reptiles","reptile","snake","snakes","lizard","lizards","gecko","bearded","turtle","turtles","tortoise","tortoises","terrapin","amphibian","frog","rabbit","rabbits","bunny","bunnies","hare","lagomorph","binky","binkies","hamster","hamsters","gerbil","gerbils","mouse","mice","rat","rats","guinea-pig","guineapig","guinea","cavy","cavies","chinchilla","ferret","horse","horses","equine","equestrian","pony","ponies","riding","stable","farm","farming","farmlife","farm-life","livestock","chicken","chickens","goat","goats","sheep","lamb","lambs","pig","pigs","cow","cows","cattle","english","spanish","espanol","french","francais","german","deutsch","italian","italiano","portuguese","portugues","russian","russkiy","japanese","nihongo","chinese","mandarin","cantonese","zhongwen","korean","hangul","hangugeo","arabic","hindi","urdu","bengali","turkish","turkce","persian","farsi","dutch","nederlands","polish","swedish","svenska","norwegian","norsk","danish","dansk","finnish","greek","ellinika","hebrew","ivrit","vietnamese","tiengviet","thai","indonesian","bahasa","malay","tagalog","filipino","swahili","kiswahili","czech","cestina","hungarian","magyar","romanian","romana","ukrainian","usa","united-states","unitedstates","america","american","americans","canada","canadian","canadians","mexico","mexican","mexicans","brasil","brazil","brazilian","argentina","argentine","chile","chilean","peru","colombia","colombian","venezuela","venezuelan","ecuador","uruguay","uk","united-kingdom","unitedkingdom","britain","british","england","scotland","scottish","wales","welsh","ireland","irish","northern-ireland","france","french","germany","german","germans","italy","italian","italians","spain","spanish","portugal","portuguese","netherlands","dutch","belgium","switzerland","swiss","austria","austrian","poland","polish","czech","russia","russian","russians","ukraine","ukrainian","ukrainians","belarus","china","chinese","taiwan","taiwanese","hongkong","hong-kong","macau","japan","japanese","korea","korean","koreans","north-korea","south-korea","india","indian","indians","pakistan","pakistani","bangladesh","bangladeshi","australia","australian","australians","aussie","aussies","nz","newzealand","new-zealand","kiwi","kiwis","fiji","fijian","samoa","samoan","tonga","philippines","filipino","filipinos","pinoy","pinay","vietnam","vietnamese","thailand","thai","thais","indonesia","indonesian","malaysia","malaysian","singapore","singaporean","brunei","myanmar","burmese","cambodia","cambodian","laos","laotian","nepal","nepali","srilanka","sri-lanka","srilankan","egypt","egyptian","egyptians","morocco","moroccan","algeria","algerian","tunisia","tunisian","libya","libyan","sudan","sudanese","ethiopia","kenya","kenyan","kenyans","tanzania","tanzanian","uganda","ugandan","nigeria","nigerian","nigerians","ghana","ghanaian","senegal","senegalese","southafrica","south-africa","southafrican","south-african","namibia","botswana","zimbabwe","zambia","mozambique","angola","congo","congolese","israel","israeli","israelis","palestine","palestinian","palestinians","jordan","jordanian","lebanon","lebanese","syria","syrian","iraq","iraqi","iran","iranian","iranians","persian","persians","saudi","saudi-arabia","uae","emirates","emirati","dubai","abudhabi","abu-dhabi","qatar","qatari","kuwait","kuwaiti","bahrain","bahraini","oman","omani","yemen","yemeni","turkey","turkish","turks","greece","greek","greeks","cyprus","cypriot","scandinavia","scandinavian","nordic","norway","norwegian","sweden","swedish","denmark","danish","finland","finnish","finns","iceland","icelandic","baltics","baltic","estonia","estonian","latvia","latvian","lithuania","balkans","balkan","serbia","serbian","croatia","croatian","bosnia","slovenia","slovenian","macedonia","macedonian","albania","albanian","romania","romanian","bulgaria","bulgarian","hungary","hungarian","slovakia","slovak","slovakian","moldova","moldovan","georgia","georgian","armenia","armenian","azerbaijan","azerbaijani","kazakhstan","kazakh","uzbekistan","uzbek","turkmenistan","kyrgyzstan","tajikistan","mongolia","caribbean","jamaica","jamaican","bahamas","bahamian","barbados","trinidad","cuba","cuban","haiti","haitian","dominican","puerto-rico","puertorico","latin","latino","latina","latinx","hispanic","latinoamerica","latam","california","cali","ca","socal","norcal","bayarea","bay-area","la","texas","tx","houston","dallas","austin","sanantonio","san-antonio","florida","fl","miami","orlando","tampa","jacksonville","fortlauderdale","newyork","new-york","ny","nyc","brooklyn","manhattan","queens","bronx","pennsylvania","pa","philly","philadelphia","pittsburgh","harrisburg","illinois","il","chicago","chi","chiraq","chitown","springfield","ohio","oh","cleveland","columbus","cincinnati","toledo","akron","georgia","ga","atlanta","atl","savannah","augusta","macon","northcarolina","north-carolina","nc","charlotte","raleigh","durham","southcarolina","south-carolina","sc","charleston","columbia","greenville","michigan","mi","detroit","annarbor","ann-arbor","grandrapids","lansing","newjersey","new-jersey","nj","jersey","newark","trenton","atlantic-city","virginia","va","richmond","norfolk","vb","virginia-beach","alexandria","washington","wa","seattle","tacoma","spokane","olympia","bellevue","arizona","az","phoenix","phx","tucson","scottsdale","mesa","tempe","massachusetts","ma","boston","cambridge","worcester","springfield","tennessee","tn","nashville","memphis","knoxville","chattanooga","indiana","in","indianapolis","indy","fortwayne","fort-wayne","southbend","missouri","mo","stlouis","st-louis","kansascity","kansas-city","springfield","maryland","md","baltimore","bmore","annapolis","bethesda","rockville","wisconsin","wi","milwaukee","madison","greenbay","green-bay","kenosha","colorado","co","denver","boulder","coloradosprings","colorado-springs","minnesota","mn","minneapolis","stpaul","st-paul","twincities","twin-cities","alabama","al","birmingham","montgomery","mobile","huntsville","tuscaloosa","louisiana","la","neworleans","new-orleans","nola","batonrouge","baton-rouge","kentucky","ky","louisville","lexington","bowling-green","frankfort","oregon","or","portland","pdx","eugene","salem","bend","medford","oklahoma","ok","okc","oklahomacity","oklahoma-city","tulsa","norman","connecticut","ct","hartford","newhaven","new-haven","stamford","bridgeport","utah","ut","saltlakecity","salt-lake-city","slc","provo","ogden","iowa","ia","desmoines","des-moines","cedarrapids","cedar-rapids","davenport","nevada","nv","lasvegas","las-vegas","vegas","reno","henderson","sparks","arkansas","ar","littlerock","little-rock","fayetteville","fortsmith","mississippi","ms","jackson","gulfport","biloxi","hattiesburg","southaven","kansas","ks","wichita","overlandpark","overland-park","kansascity","topeka","newmexico","new-mexico","nm","albuquerque","santafe","santa-fe","lascruces","nebraska","ne","omaha","lincoln","bellevue","grandisland","grand-island","idaho","id","boise","meridian","nampa","idahofalls","idaho-falls","pocatello","westvirginia","west-virginia","wv","charleston","huntington","morgantown","hawaii","hi","honolulu","maui","oahu","kauai","bigisland","big-island","newhampshire","new-hampshire","nh","manchester","nashua","concord","portsmouth","maine","me","portland","lewiston","bangor","auburn","augusta","rhodeisland","rhode-island","ri","providence","warwick","cranston","newport","montana","mt","billings","missoula","greatfalls","great-falls","bozeman","delaware","de","wilmington","dover","newark","middletown","smyrna","southdakota","south-dakota","sd","siouxfalls","sioux-falls","rapidcity","northdakota","north-dakota","nd","fargo","bismarck","grandforks","grand-forks","alaska","ak","anchorage","fairbanks","juneau","sitka","ketchikan","vermont","vt","burlington","essex","rutland","colchester","bennington","wyoming","wy","cheyenne","casper","laramie","gillette","rocksprings","dc","washingtondc","washington-dc","dmv","nova","northern-virginia","puertorico","puerto-rico","pr","sanjuan","san-juan","bayamon","carolina","midwest","midwestern","northeast","northeastern","southeast","southeastern","southwest","southwestern","northwest","northwestern","pacificnorthwest","pnw","newengland","new-england","deepouth","deep-south","sunbelt","sun-belt","rustbelt","rust-belt","biblebelt","bible-belt","cornbelt","corn-belt"];async function Jo(e){const t=function(e){let t=e.startsWith("#")?e.slice(1):e;return t=t.toLowerCase().replace(/[^a-z0-9-]/g,""),t=t.replace(/-+/g,"-"),t=t.replace(/^-+|-+$/g,""),t}(e);if(!t)throw new Error(`Invalid channel name: "${e}" filters to empty string`);const a=`#${t}`,n=(new TextEncoder).encode(a),r=(await Bo(n)).slice(0,16),s=(await Bo(r))[0],o=new Uint8Array(32);return o.set(r),{name:`#${t}`,channelHash:s,aesKey:r,hmacKey:o,autoDiscovered:!0}}let Ko=null,Xo=null;const Yo=new Map;let Qo=null;const Zo="pymc_discovered_channels";function ei(e){Yo.set(e.channelHash,e),e.autoDiscovered&&function(){try{const e=[];for(const t of Yo.values())t.autoDiscovered&&e.push({name:t.name,hash:t.channelHash});localStorage.setItem(Zo,JSON.stringify(e))}catch(e){console.warn("[ChannelKeys] Failed to save stored channels:",e)}}()}async function ti(){Ko||(Xo||(Xo=(async()=>{await async function(){try{const e=localStorage.getItem(Zo);if(!e)return;const t=JSON.parse(e);for(const{name:a}of t)try{const e=await Jo(a);Yo.set(e.channelHash,e)}catch{}t.length>0&&t.length}catch(e){console.warn("[ChannelKeys] Failed to load stored channels:",e)}}();const e=await async function(){const{default:e}=await A(async()=>{const{default:e}=await import("./generated-geo-channels-CkSMgZLG.js");return{default:e}},[]);return[...Go,...e]}(),t=new Map;for(const a of e)try{const e=await Jo(a),n=t.get(e.channelHash)||[];n.push(e),t.set(e.channelHash,n)}catch{}Ko=t,e.length,t.size})()),await Xo)}async function ai(e,t,a){const n=await async function(e,t){if(vo())try{const a=new ArrayBuffer(e.length);new Uint8Array(a).set(e);const n=new ArrayBuffer(t.length);new Uint8Array(n).set(t);const r=await crypto.subtle.importKey("raw",a,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),s=await crypto.subtle.sign("HMAC",r,n);return new Uint8Array(s)}catch{}return async function(e,t){const a=64;let n;e.length>a?(n=new Uint8Array(a),n.set(Fo(e))):(n=new Uint8Array(a),n.set(e));const r=new Uint8Array(a),s=new Uint8Array(a);for(let c=0;c=2024&&a<=2030;if(!n)return{valid:!1,confidence:"low"};const r=e.slice(5);if(0===r.length)return{valid:!1,confidence:"low"};let s=0,o=!1;for(let l=0;l=32&&e<=126||0===e||10===e||13===e||9===e)&&s++,58===e&&(o=!0)}const i=s/r.length;return i>=.85&&o&&n?{valid:!0,confidence:"high"}:i>=.7&&n?{valid:!0,confidence:"medium"}:{valid:!1,confidence:"low"}}async function ri(e,t,a){await ti();const n=await async function(){return Qo||(Qo=await async function(e,t=!1){const a=bo(e.secret),n=(await Bo(a))[0],r=new Uint8Array(32);return r.set(a.slice(0,32)),{name:e.name,channelHash:n,aesKey:r.slice(0,16),hmacKey:r,autoDiscovered:t}}(Vo)),Qo}();if(n.channelHash===e&&await ai(n.hmacKey,t,a))return{channelName:"Public",plaintext:Po(n.aesKey,a),keys:n};const r=Yo.get(e);if(r&&await ai(r.hmacKey,t,a)){const e=Po(r.aesKey,a);return{channelName:r.name,plaintext:e,keys:r}}const s=(null==Ko?void 0:Ko.get(e))||[],o=[];for(const l of s){if(await ai(l.hmacKey,t,a)){ei(l);const e=Po(l.aesKey,a);return{channelName:l.name,plaintext:e,keys:l}}o.push(l)}let i=null;for(const l of o)try{const e=Po(l.aesKey,a),t=ni(e);if(t.valid){if("high"===t.confidence)return{channelName:l.name,plaintext:e,keys:l,macCorrupted:!0};"medium"!==t.confidence||i||(i={keys:l,plaintext:e,confidence:"medium"})}}catch{}return i?{channelName:i.keys.name,plaintext:i.plaintext,keys:i.keys,macCorrupted:!0}:null}async function si(e){return await ti(),((null==Ko?void 0:Ko.get(e))||[]).map(e=>e.name)}async function oi(e,t,a,n){try{const r=await Jo(e);if(r.channelHash!==t)return{success:!1,error:`Hash mismatch: "${e}" has hash 0x${r.channelHash.toString(16).toUpperCase().padStart(2,"0")}, packet has 0x${t.toString(16).toUpperCase().padStart(2,"0")}`};if(!(await ai(r.hmacKey,a,n)))return{success:!1,error:"MAC verification failed - wrong channel name or corrupted data"};const s=Po(r.aesKey,n);return ei(r),{success:!0,result:{channelName:r.name,plaintext:s,keys:r}}}catch(r){return{success:!1,error:`Error: ${r instanceof Error?r.message:String(r)}`}}}let ii=null,li=[];function ci(e){return{decoded:e.success?{type:"grp_txt",channelHash:e.channelHash,channelName:e.channelName,text:e.text??"",decrypted:!0,senderName:e.senderName,timestamp:e.timestamp,flags:e.flags,macCorrupted:e.macCorrupted,isPublicHashChannel:!0}:null,timestamp:e.packetTimestamp,rssi:e.rssi,snr:e.snr}}const di=F((e,t)=>{let a=!1;return{messages:new Map,stableMessages:new Map,lastSnapshotUpdate:0,processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1},initialDecodeComplete:!1,_successCount:0,queueDecryption:async(n,r)=>{const{messages:s,processing:o}=t(),i=(null==r?void 0:r.quickMode)??!1;let l=n.filter(e=>(e.type??e.payload_type)===Un.GRP_TXT&&e.raw_packet&&!s.has(e.packet_hash)&&!o.has(e.packet_hash));if(0===l.length)return;if(i&&l.length>100&&(l=l.sort((e,t)=>(t.timestamp??0)-(e.timestamp??0)).slice(0,100)),a){const e=new Set(li.map(e=>e.packet_hash)),t=l.filter(t=>!e.has(t.packet_hash));return void(t.length>0&&(li.push(...t),t.length))}a=!0;const c=new Set(l.map(e=>e.packet_hash));e(e=>({processing:new Set([...e.processing,...c]),progress:{total:l.length,processed:0,percent:0,isDecoding:!0}}));try{const{totalCount:a}=await fo.decrypt(l,{onProgress:(t,a)=>{e({progress:{total:a,processed:t,percent:Math.round(t/a*100),isDecoding:!0}})},onResults:a=>{const{messages:n}=t();let r=0;for(const e of a)n.set(e.packetHash,ci(e)),e.success&&!e.macCorrupted&&r++;e(e=>({messages:n,_successCount:e._successCount+r})),ii&&clearTimeout(ii),ii=setTimeout(()=>{e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now()})},500)}});ii&&(clearTimeout(ii),ii=null);const n=t().messages;if(n.size>5e4){const e=Array.from(n.entries()).sort((e,t)=>e[1].timestamp-t[1].timestamp).slice(0,n.size-5e4);for(const[t]of e)n.delete(t)}if(e({messages:n,stableMessages:new Map(n),lastSnapshotUpdate:Date.now(),processing:new Set,initialDecodeComplete:!0,progress:{total:a,processed:a,percent:100,isDecoding:!1}}),li.length>0){const e=li;li=[],e.length,setTimeout(()=>{t().queueDecryption(e)},50)}}catch(d){console.error("[DecodedMessages] Worker decryption failed:",d),e({processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1}})}finally{a=!1}},queueChannelDecryption:async(n,r)=>{const{messages:s,processing:o}=t(),i=await async function(e){const t=await async function(e){return Jo(e.startsWith("#")?e.slice(1):e)}(e);return{name:t.name,channelHash:t.channelHash,aesKeyHex:yo(t.aesKey),hmacKeyHex:yo(t.hmacKey)}}(r),l=n.filter(e=>{if((e.type??e.payload_type)!==Un.GRP_TXT||!e.raw_packet)return!1;if(s.has(e.packet_hash)||o.has(e.packet_hash))return!1;const t=e.raw_packet;if(t.length<4)return!1;const a=3&parseInt(t.slice(0,2),16);let n=2;return 0!==a&&3!==a||(n=10),n+=2+2*parseInt(t.slice(n,n+2),16),parseInt(t.slice(n,n+2),16)===i.channelHash});if(0===l.length)return;if(a)return;a=!0;const c=new Set(l.map(e=>e.packet_hash));e(e=>({processing:new Set([...e.processing,...c]),progress:{total:l.length,processed:0,percent:0,isDecoding:!0}}));try{l.length;const{totalCount:a}=await fo.decrypt(l,{knownKey:i,onProgress:(t,a)=>{e({progress:{total:a,processed:t,percent:Math.round(t/a*100),isDecoding:!0}})},onResults:a=>{const{messages:n}=t();let r=0;for(const e of a)n.set(e.packetHash,ci(e)),e.success&&!e.macCorrupted&&r++;e(e=>({messages:n,_successCount:e._successCount+r})),ii&&clearTimeout(ii),ii=setTimeout(()=>{e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now()})},500)}});ii&&(clearTimeout(ii),ii=null),e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now(),processing:new Set,progress:{total:a,processed:a,percent:100,isDecoding:!1}})}catch(d){console.error("[DecodedMessages] Fast-path decryption failed:",d),e({processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1}})}finally{a=!1}},getMessage:e=>t().messages.get(e),getSuccessfulMessages:()=>{var e;const{messages:a}=t(),n=[];for(const t of a.values())(null==(e=t.decoded)?void 0:e.decrypted)&&!t.decoded.macCorrupted&&n.push(t);return n.sort((e,t)=>e.timestamp-t.timestamp)},clear:()=>{ii&&(clearTimeout(ii),ii=null),e({messages:new Map,stableMessages:new Map,lastSnapshotUpdate:0,processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1},initialDecodeComplete:!1,_successCount:0})}}});function ui(e){return di(t=>t.messages.get(e))}function hi(){return di(e=>e.progress)}function mi(){return di(e=>e.initialDecodeComplete)}function gi(){return di(e=>e.stableMessages)}function pi(){return di(e=>e.stableMessages)}const fi=Object.freeze(Object.defineProperty({__proto__:null,hasAttemptedPacket:function(e){return di.getState().messages.has(e)},useAttemptedPackets:pi,useDecodedMessage:ui,useDecodedMessageCount:function(){return di(e=>e._successCount)},useDecodedMessagesStore:di,useDecryptionProgress:hi,useInitialDecodeComplete:mi,useStableMessages:gi},Symbol.toStringTag,{value:"Module"})),bi=[{label:"20m",minutes:20,buckets:80},{label:"1h",minutes:60,buckets:80},{label:"3h",minutes:180,buckets:80},{label:"12h",minutes:720,buckets:80},{label:"24h",minutes:1440,buckets:80},{label:"3d",minutes:4320,buckets:80},{label:"7d",minutes:10080,buckets:80},{label:"14d",minutes:20160,buckets:80},{label:"21d",minutes:30240,buckets:80},{label:"30d",minutes:43200,buckets:80},{label:"90d",minutes:129600,buckets:80}],yi=[{label:"1h",hours:1},{label:"3h",hours:3},{label:"12h",hours:12},{label:"24h",hours:24},{label:"3d",hours:72},{label:"7d",hours:168},{label:"14d",hours:336},{label:"21d",hours:504},{label:"30d",hours:720},{label:"90d",hours:2160}];function wi(e,t=12){return Math.max(t,Math.round(e/15))}const Ci={hero:wi(1200),statsCard:wi(380)};function ki(e){switch(e){case 1:return 3600;case 3:case 12:return 5400;case 24:return 8640;case 72:case 168:case 336:case 504:case 720:case 2160:return 720;default:{const t=3600*e,a=Math.round(t/10);return Math.min(Math.max(360,a),720)}}}const vi="'JetBrains Mono', 'SF Mono', Monaco, monospace",Di={stats:3e3,logs:2e3,system:3e3},Ai={DEBUG:"text-sys-orange",INFO:"text-sys-cyan",WARNING:"text-sys-amber",ERROR:"text-sys-red",CRITICAL:"text-sys-pink"};function xi(e){return Ai[e]??"text-fg-muted border-edge-subtle"}function Ei(e){return e?(e.startsWith("0x")?e.slice(2):e).slice(0,2).toUpperCase():""}function Fi(e,t){if(!e)return"expired";const a=t/1e3-e;return a<=10800?"active":a<=86400?"stale":"expired"}function Bi(e,t,a=Date.now()){if(!e)return[];const n=Object.keys(e);if(0===n.length)return[];const r=[];for(let s=0;st.count!==e.count?t.count-e.count:t.lastSeen-e.lastSeen),r}const ji={critical:0,high:150,medium:300,low:450};let Si=!1;const Mi=[],Ni=new Set;function Li(e,t="medium"){if(Si){const a=setTimeout(()=>{e(),Ni.delete(a)},ji[t]);return Ni.add(a),()=>{clearTimeout(a),Ni.delete(a)}}{const a={callback:e,priority:t};return Mi.push(a),()=>{const e=Mi.indexOf(a);-1!==e&&Mi.splice(e,1)}}}let Ti;function _i(e){Ti=e}const Ri=F((e,t)=>({hardwareStats:null,hardwareStatsLoading:!1,hardwareStatsError:null,resourceHistory:[],lastResourceFetch:0,fetchHardwareStats:async()=>{try{const a=await Os();if(a.success&&a.data){const n=a.data;e({hardwareStats:n,hardwareStatsLoading:!1,hardwareStatsError:null});const r=80;t().addResourceDataPoint(n.cpu.usage_percent,n.memory.usage_percent,r)}else e({hardwareStatsError:a.error??"Failed to fetch hardware stats",hardwareStatsLoading:!1})}catch(a){e({hardwareStatsError:a instanceof Error?a.message:"Failed to fetch hardware stats",hardwareStatsLoading:!1})}},addResourceDataPoint:(a,n,r)=>{const s=Date.now(),{lastResourceFetch:o,resourceHistory:i}=t();if(s-o<1e3)return;const l={timestamp:s,time:new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),cpu:a,memory:n};let c;i.length>=r?(c=i.slice(1),c.push(l)):c=[...i,l],e({resourceHistory:c,lastResourceFetch:s})},initialize:()=>{t().fetchHardwareStats();const e=setInterval(()=>{"undefined"!=typeof document&&document.hidden||t().fetchHardwareStats()},Di.system);return()=>{clearInterval(e)}}})),zi=Ri,Pi=()=>Ri(e=>e.hardwareStats),Ii=()=>Ri(e=>e.hardwareStatsLoading),$i=()=>Ri(e=>e.hardwareStatsError),qi=()=>Ri(e=>e.resourceHistory),Oi=()=>Ri(e=>e.fetchHardwareStats);function Hi(e){return e.startsWith("0x")||e.startsWith("0X")?e.slice(2,4).toUpperCase():e.slice(0,2).toUpperCase()}function Wi(e,t){let a=e.forwarded_path??e.original_path;if("string"==typeof a)try{a=JSON.parse(a)}catch{return null}if(!a||!Array.isArray(a)||0===a.length)return null;const n=a.map(e=>String(e).toUpperCase()),r=t?Hi(t):null,s=n[n.length-1],o=null!==r&&s===r,i=o?n.slice(0,-1):[...n];return{effective:i,original:n,hadLocal:o,effectiveLength:i.length}}function Ui(e,t){let a=e;if("string"==typeof a)try{a=JSON.parse(a)}catch{return null}if(!a||!Array.isArray(a)||0===a.length)return null;const n=a.map(e=>String(e).toUpperCase()),r=t?Hi(t):null,s=n[n.length-1],o=null!==r&&s===r,i=o?n.slice(0,-1):[...n];return{effective:i,original:n,hadLocal:o,effectiveLength:i.length}}function Vi(e,t){return t-e}function Gi(e,t){const a=e.toUpperCase();return t.startsWith("0x")||t.startsWith("0X")?t.slice(2).toUpperCase().startsWith(a):t.toUpperCase().startsWith(a)}function Ji(e){return 4===(e.type??e.payload_type)&&!0!==e.transmitted&&function(e){if(null!=e._isZeroHop)return e._isZeroHop;const t=function(e){if(Array.isArray(e))return e;if("string"==typeof e&&e.startsWith("["))try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}return[]}(e.original_path),a=e.route??e.route_type;return it(a)?0===t.length:ot(a)?t.length<=1:0===t.length}(e)}function Ki(e,t,a,n){if(!e)return null;let r=e;if(e.length<=4){const n=e.replace(/^0x/i,"").toUpperCase();if(n===t)return null;const s=a.get(n);if(!s)return null;r=s}return n.has(r)?Hi(r)===t?null:r:null}function Xi(e,t){e.count++,void 0!==t.rssi&&null!==t.rssi&&(e.rssiSum+=t.rssi,e.rssiCount++),void 0!==t.snr&&null!==t.snr&&(e.snrSum+=t.snr,e.snrCount++);const a=t.timestamp??0;a>e.lastSeen&&(e.lastSeen=a)}function Yi(e){return{hash:e,count:0,rssiSum:0,rssiCount:0,snrSum:0,snrCount:0,lastSeen:0}}function Qi(e,t){const a=function(e,t){const a=t-1e3*e;return a<=6048e5?"active":a<=12096e5?"stale":"expired"}(e.lastSeen,t);return"expired"===a?null:{hash:e.hash,prefix:Hi(e.hash),count:e.count,avgRssi:e.rssiCount>0?e.rssiSum/e.rssiCount:null,avgSnr:e.snrCount>0?e.snrSum/e.snrCount:null,lastSeen:e.lastSeen,status:a}}const Zi="pymc-hidden-contacts",el="pymc-quick-neighbors",tl="pymc-local-hash",al="pymc-global-time-range";let nl=null;function rl(){if("undefined"==typeof window)return[];try{const e=localStorage.getItem(el);if(e)return JSON.parse(e)}catch{}return[]}function sl(e){"undefined"!=typeof window&&(nl&&clearTimeout(nl),nl=setTimeout(()=>{try{localStorage.setItem(el,JSON.stringify(e))}catch{}nl=null},1e3))}function ol(){if("undefined"!=typeof window)try{const e=localStorage.getItem(tl);if(e)return e}catch{}}function il(e){if("undefined"!=typeof window)try{localStorage.setItem(tl,e)}catch{}}function ll(){if("undefined"==typeof window)return new Set;try{const e=localStorage.getItem(Zi);if(e)return new Set(JSON.parse(e))}catch{}return new Set}function cl(){if("undefined"==typeof window)return 4;try{const e=localStorage.getItem(al);if(e){const t=parseInt(e,10);if(!isNaN(t)&&t>=0&&t<=10)return t>4?4:t}}catch{}return 4}function dl(e,t){"undefined"!=typeof window&&"requestIdleCallback"in window?requestIdleCallback(()=>e(),{timeout:t}):setTimeout(e,100)}function ul(e,t=200,a=1500){let n=0,r=0;return()=>{const s=Date.now();s-n>=t&&(n=s,e({lastPacketTimestamp:Nr.getNewestTimestamp()})),s-r>=a&&(r=s,e({packets:Nr.getPackets()}))}}function hl(e,t,a={}){const{idleTimeout:n=2e3,decryptMode:r="full",includeAnimationReady:s=!1}=a;0!==t.length&&(pn.active&&pn.emit("cascade:hydrate",{packetCount:t.length,decryptMode:r}),dl(()=>e().triggerTopologyCompute(),n),dl(()=>e().triggerSparklineCompute(),Math.max(n-1e3,500)),s&&setTimeout(()=>function(){if(!Si){Si=!0;for(const e of Mi){const t=ji[e.priority],a=setTimeout(()=>{e.callback(),Ni.delete(a)},t);Ni.add(a)}Mi.length=0}}(),16),"quick"===r?setTimeout(()=>{di.getState().queueDecryption(t)},500):"full"===r&&dl(()=>{di.getState().queueDecryption(t)},n),Ps())}const ml={"3d":{load:e=>Nr.loadTier("3d",e),idleTimeout:2e3},"7d":{load:e=>Nr.loadTier("7d",e),idleTimeout:2e3},"14d":{load:e=>Nr.loadTier("14d",e),idleTimeout:5e3},"21d":{load:e=>Nr.loadTier("21d",e),idleTimeout:5e3},"30d":{load:e=>Nr.loadTier("30d",e),idleTimeout:8e3},"90d":{load:e=>Nr.loadTier("90d",e),idleTimeout:1e4}},gl={5:"3d",6:"7d",7:"14d",8:"21d",9:"30d",10:"90d"},pl=F((e,t)=>({stats:null,statsLoading:!1,statsError:null,packets:Nr.getPackets(),packetsLoading:!1,packetsError:null,lastPacketTimestamp:Nr.getNewestTimestamp(),logs:[],logsLoading:!1,liveMode:!0,flashReceived:0,flashAdvert:0,pendingAdvertLocalHash:null,pendingAdvertTimestamp:null,hiddenContacts:ll(),quickNeighbors:rl(),cachedLocalHash:ol(),initialized:!1,packetCacheState:Nr.getState(),mutationsInFlight:new Set,globalTimeRangeIndex:cl(),initializeApp:async()=>{const{initialized:a}=t();if(a)return;e({initialized:!0,statsLoading:!0,packetsLoading:!0}),Nr.subscribe(t=>{e({packetCacheState:t})});const{hiddenContacts:n}=t(),r=ul(e,50,1500);Ls().then(t=>{const a=Bi(t.neighbors,n),r=t.local_hash;e({stats:t,statsLoading:!1,quickNeighbors:a,cachedLocalHash:r}),sl(a),r&&il(r)}).catch(t=>{e({statsError:t instanceof Error?t.message:"Failed to fetch stats",statsLoading:!1})}),Nr.initialLoad(r).then(a=>{if(a.length>0){const n=Nr.getNewestTimestamp();e({packets:a,packetsLoading:!1,lastPacketTimestamp:n}),hl(t,a,{idleTimeout:2e3,decryptMode:"quick",includeAnimationReady:!0})}else e({packetsLoading:!1})}).catch(t=>{e({packetsError:t instanceof Error?t.message:"Failed to load packets",packetsLoading:!1})}),ao.getState().initialize();let s=null,o=Nr.getPacketCount();fn.onPacket(a=>{const{lastPacketTimestamp:n,mutationsInFlight:r}=t();if(r.size>0)return;Nr.mergePacketsDirectly([a]),pn.active&&pn.emit("store:packets:ws-merge",{hash:a.packet_hash});const i=a.timestamp??0;i>n&&(e({lastPacketTimestamp:i}),s||(s=setTimeout(()=>{if(s=null,!Nr.isHeavyLoadInProgress()){const a=Nr.getPacketCount();if(a!==o){o=a;const n=Nr.getPackets();e({packets:n,flashReceived:t().flashReceived+1}),Ps()}}},500))),di.getState().queueDecryption([a])}),fn.onStats(a=>{const{mutationsInFlight:n,hiddenContacts:r}=t();if(n.size>0)return;const s=Bi(a.neighbors,r),o=a.local_hash,i=t().quickNeighbors;s.length!==i.length||s.some((e,t)=>{var a;return e.hash!==(null==(a=i[t])?void 0:a.hash)})?(e({stats:a,statsLoading:!1,statsError:null,quickNeighbors:s,cachedLocalHash:o}),sl(s)):e({stats:a,statsLoading:!1,statsError:null,cachedLocalHash:o}),o&&il(o)}),fn.onPacketStats(a=>{const{stats:n,mutationsInFlight:r}=t();if(!n||r.size>0)return;const s={...n,rx_count:a.rx_count??n.rx_count,tx_count:a.tx_count??n.tx_count,forwarded_count:a.forwarded_count??n.forwarded_count,dropped_count:a.dropped_count??n.dropped_count};e({stats:s})});const i=function(e){const t=setInterval(()=>{Nr.isHeavyLoadInProgress()||e().mutationsInFlight.size>0||e().fetchStats().then(()=>{ks.getState().updateRestHealth(!0)}).catch(()=>{ks.getState().updateRestHealth(!1)})},Di.stats);let a,n=!0;if(function t(){if(!n)return;const a=fn.isConnected()?15e3:3e3;setTimeout(async()=>{n&&(e().liveMode&&!Nr.isHeavyLoadInProgress()&&await e().fetchPackets(),t())},a)}(),"undefined"!=typeof document){let t=Date.now();const n=3e5,r=async()=>{if(document.hidden)t=Date.now();else{const a=Date.now()-t,r=a>n;Math.round(a/1e3),r&&(fn.resetSupported(),fn.isConnected()?await fn.verifyConnection(3e3)||(console.warn("[useStore] WS stale after wake, reconnecting..."),fn.disconnect(),fn.connect()):fn.isSupported()&&fn.connect()),e().fetchStats({force:!0}),e().fetchPackets()}};document.addEventListener("visibilitychange",r),a=()=>document.removeEventListener("visibilitychange",r)}return()=>{clearInterval(t),n=!1,null==a||a()}}(t),l=zi.getState().initialize();Ol=()=>{i(),l()}},prefetchForRoute:e=>{switch(e){case"/logs":Ts().catch(()=>{});break;case"/system":Os().catch(()=>{});break;case"/statistics":(async function(e=24){return Fs(`/api/packet_type_graph_data?hours=${e}`)})(3).catch(()=>{}),Rs(3).catch(()=>{});break;case"/settings":(async function(){return Fs("/api/radio_presets")})().catch(()=>{})}},fetchStats:async a=>{const{stats:n,mutationsInFlight:r,hiddenContacts:s}=t();if(r.size>0&&!(null==a?void 0:a.force))return;n||e({statsLoading:!0}),e({statsError:null});const o=performance.now();try{const a=await Ls();pn.active&&pn.emit("transport:rest:stats",{durationMs:performance.now()-o,ok:!0});const n=Bi(a.neighbors,s),r=a.local_hash,i=t().quickNeighbors;n.length!==i.length||n.some((e,t)=>{var a;return e.hash!==(null==(a=i[t])?void 0:a.hash)})?(e({stats:a,statsLoading:!1,quickNeighbors:n,cachedLocalHash:r}),sl(n)):e({stats:a,statsLoading:!1,cachedLocalHash:r}),r&&il(r)}catch(i){pn.active&&pn.emit("transport:rest:stats",{durationMs:performance.now()-o,ok:!1}),e({statsError:i instanceof Error?i.message:"Failed to fetch stats",statsLoading:!1})}},fetchPackets:async()=>{const{packets:a,lastPacketTimestamp:n}=t();0===a.length&&e({packetsLoading:!0}),e({packetsError:null});const r=performance.now();try{const a=await Nr.poll();if(pn.active&&pn.emit("transport:rest:packets",{durationMs:performance.now()-r,count:a}),a>0){const r=Nr.getPackets(),s=Nr.getNewestTimestamp();s>n&&n>0&&(e({flashReceived:t().flashReceived+1}),Ps()),e({packets:r,packetsLoading:!1,lastPacketTimestamp:s||n}),di.getState().queueDecryption(r),a>50&&n>0&&hl(t,r,{idleTimeout:500,decryptMode:"skip"})}else e({packetsLoading:!1})}catch(s){e({packetsError:s instanceof Error?s.message:"Failed to fetch packets",packetsLoading:!1})}},fetchLogs:async()=>{const{logs:a}=t();0===a.length&&e({logsLoading:!0});try{const t=await Ts();e({logs:t.logs,logsLoading:!1})}catch{e({logsLoading:!1})}},setLiveMode:t=>{e({liveMode:t})},setMode:async a=>{const n="setMode",{mutationsInFlight:r}=t(),s=new Set(r);s.add(n),e({mutationsInFlight:s});try{if(!(await Vs(a)).success)throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}catch(o){const{mutationsInFlight:a}=t(),r=new Set(a);throw r.delete(n),e({mutationsInFlight:r}),o}},clearModeMutation:()=>{const{mutationsInFlight:a}=t(),n=new Set(a);n.delete("setMode"),e({mutationsInFlight:n})},setDutyCycle:async a=>{const n="setDutyCycle",{mutationsInFlight:r}=t(),s=new Set(r);s.add(n),e({mutationsInFlight:s});try{if(!(await Gs(a)).success)throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}finally{const{mutationsInFlight:a}=t(),r=new Set(a);r.delete(n),e({mutationsInFlight:r})}},setDutyCycleConfig:async a=>{var n;const r="setDutyCycleConfig",{mutationsInFlight:s}=t(),o=new Set(s);o.add(r),e({mutationsInFlight:o});try{const e=await async function(e){return Fs("/api/update_duty_cycle_config",{method:"POST",body:JSON.stringify(e)})}(a);if(!e.success&&!(null==(n=e.data)?void 0:n.persisted))throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}catch(i){const{mutationsInFlight:a}=t(),n=new Set(a);throw n.delete(r),e({mutationsInFlight:n}),i}},clearDutyCycleMutation:()=>{const{mutationsInFlight:a}=t(),n=new Set(a);n.delete("setDutyCycleConfig"),e({mutationsInFlight:n})},startMutation:a=>{const{mutationsInFlight:n}=t(),r=new Set(n);r.add(a),e({mutationsInFlight:r})},clearMutation:a=>{const{mutationsInFlight:n}=t(),r=new Set(n);r.delete(a),e({mutationsInFlight:r})},sendAdvert:async()=>{try{const a=await Us();return a.success?(e({flashAdvert:t().flashAdvert+1}),{success:!0}):{success:!1,error:a.error||"Failed to send advert"}}catch(a){const e=a instanceof Error?a.message:"Unknown error";return console.error("Failed to send advert:",e),{success:!1,error:e}}},triggerFlashReceived:()=>{e({flashReceived:t().flashReceived+1})},triggerFlashAdvert:()=>{e({flashAdvert:t().flashAdvert+1})},hideContact:a=>{const{hiddenContacts:n}=t(),r=new Set(n);r.add(a),e({hiddenContacts:r}),function(e){if("undefined"!=typeof window)try{localStorage.setItem(Zi,JSON.stringify([...e]))}catch{}}(r)},clearPacketCache:()=>{Nr.clear(),e({packets:[],lastPacketTimestamp:0}),Nr.initialLoad().then(a=>{a.length>0&&(e({packets:a,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(t,a,{idleTimeout:2e3,decryptMode:"full"}))})},triggerTopologyCompute:()=>{var e,a,n,r,s,o,i;const{stats:l,hiddenContacts:c}=t(),d=Nr.getPacketsUnsorted();if(0===d.length||!l)return;const u=l.neighbors??{},h=Object.fromEntries(Object.entries(u).filter(([e])=>!c.has(e))),m=l.local_hash;let g=null==(a=null==(e=l.config)?void 0:e.repeater)?void 0:a.latitude,p=null==(r=null==(n=l.config)?void 0:n.repeater)?void 0:r.longitude;if(!g||!p||0===g&&0===p){const e=go.getState().getEffectiveLocation();e&&(g=e.latitude,p=e.longitude)}const f=[];for(const[t,D]of Object.entries(h))D.zero_hop&&f.push({hash:t,advertCount:D.advert_count??1,avgRssi:D.rssi??null,avgSnr:D.snr??null,lastSeen:D.last_seen??0,latitude:D.latitude,longitude:D.longitude});const b=io.getState().getTerrainGridForDisambiguation(),y=Ti,w=y&&y.size>0?y:void 0,{globalTimeRangeIndex:C}=t(),k=(null==(s=bi[C])?void 0:s.minutes)?bi[C].minutes/60:null,v=null==(i=null==(o=l.config)?void 0:o.radio)?void 0:i.spreading_factor;_r.compute(d,h,m,g,p,void 0,f,b??void 0,w,k,v)},triggerDeepAnalysis:async()=>{await Nr.forceDeepLoad();const a=Nr.getPackets();a.length>0&&(e({packets:a,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(t,a,{idleTimeout:3e3,decryptMode:"full"}))},updateQuickNeighbors:()=>{const{packets:a,stats:n,hiddenContacts:r}=t();if(0===a.length||!n)return;const s=n.neighbors??{},o=function(e,t,a){if(!a||0===e.length||0===Object.keys(t).length)return[];const n=Date.now(),r=Hi(a),s=new Set(Object.keys(t)),o=function(e){var t,a;const n=new Map;for(const r of Object.keys(e)){const s=Hi(r),o=n.get(s);if(o){const i=null==(t=e[o])?void 0:t.zero_hop;(null==(a=e[r])?void 0:a.zero_hop)&&!i&&n.set(s,r)}else n.set(s,r)}return n}(t),i=new Map;for(const c of e){if(!Ji(c))continue;const e=Ki(c.src_hash,r,o,s);if(!e)continue;let t=i.get(e);t||(t=Yi(e),i.set(e,t)),Xi(t,c)}for(const[c,d]of Object.entries(t))Hi(c)!==r&&d.zero_hop&&!i.has(c)&&i.set(c,{hash:c,count:d.advert_count??0,rssiSum:d.rssi??0,rssiCount:void 0!==d.rssi?1:0,snrSum:d.snr??0,snrCount:void 0!==d.snr?1:0,lastSeen:d.last_seen??0});const l=[];for(const c of i.values()){const e=Qi(c,n);e&&l.push(e)}return l.sort((e,t)=>t.count!==e.count?t.count-e.count:t.lastSeen-e.lastSeen),l}(a,Object.fromEntries(Object.entries(s).filter(([e])=>!r.has(e))),n.local_hash),i=t().quickNeighbors;(o.length!==i.length||o.some((e,t)=>{var a,n;return e.hash!==(null==(a=i[t])?void 0:a.hash)||e.count!==(null==(n=i[t])?void 0:n.count)}))&&(e({quickNeighbors:o}),sl(o))},triggerSparklineCompute:()=>{const{stats:e,hiddenContacts:a}=t();if(!e)return;const n=Nr.getPacketsUnsorted();if(0===n.length)return;const r=e.neighbors??{},s=Object.keys(r).filter(e=>!a.has(e));0!==s.length&&to.compute(n,s)},requestTierData:async a=>{const n=ml[a];await async function(e,t,a,n){const r=ul(a);await e(r);const s=Nr.getPackets();a({packets:s,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(n,s,{idleTimeout:t,decryptMode:"full"})}(n.load,n.idleTimeout,e,t)},setGlobalTimeRange:a=>{e({globalTimeRangeIndex:a}),function(e){if("undefined"!=typeof window)try{localStorage.setItem(al,e.toString())}catch{}}(a);const{packetCacheState:n}=t(),r=gl[a];!r||function(e,t){return{"3d":e.threeDayLoadComplete,"7d":e.sevenDayLoadComplete,"14d":e.fourteenDayLoadComplete,"21d":e.twentyOneDayLoadComplete,"30d":e.thirtyDayLoadComplete,"90d":e.ninetyDayLoadComplete}[t]}(n,r)||n.isBackgroundLoading?(Ps(),dl(()=>t().triggerTopologyCompute(),1e3)):t().requestTierData(r)}})),fl=pl,bl=()=>pl(e=>e.stats),yl=()=>pl(e=>e.statsError),wl=()=>pl(e=>e.packets),Cl=()=>pl(e=>e.packetsLoading),kl=()=>pl(e=>e.logs),vl=()=>pl(e=>e.logsLoading),Dl=()=>pl(e=>e.liveMode),Al=()=>pl(e=>e.flashReceived),xl=()=>pl(e=>e.flashAdvert),El=()=>pl(e=>e.initializeApp),Fl=()=>pl(e=>e.prefetchForRoute),Bl=()=>pl(e=>e.fetchLogs),jl=()=>pl(e=>e.setLiveMode),Sl=()=>pl(e=>e.hiddenContacts),Ml=()=>pl(e=>e.hideContact),Nl=()=>pl(e=>e.packetCacheState),Ll=()=>pl(e=>e.quickNeighbors),Tl=()=>pl(e=>e.cachedLocalHash),_l=()=>pl(e=>e.lastPacketTimestamp),Rl=()=>pl(e=>e.globalTimeRangeIndex),zl=()=>pl(e=>e.setGlobalTimeRange),Pl=()=>pl(e=>e.packetCacheState.dataTier),Il=()=>pl(e=>null!==e.stats&&e.packetCacheState.backgroundLoadComplete),$l=()=>pl(e=>e.packets.length>0),ql=()=>pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.radio)?void 0:n.spreading_factor});let Ol=null;function Hl(){null==Ol||Ol(),Ol=null}function Wl(){const e=pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.repeater)?void 0:n.latitude}),t=pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.repeater)?void 0:n.longitude}),a=pl(e=>{var t,a,n;return(null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.node_name)||(null==(n=e.stats)?void 0:n.node_name)||"Local Node"}),n=go(e=>e.latitude),r=go(e=>e.longitude),s=go(e=>e.enabled);return e&&t&&(0!==e||0!==t)?{latitude:e,longitude:t,name:a,isStealth:!1}:s&&null!==n&&null!==r?{latitude:n,longitude:r,name:a,isStealth:!0}:null}const Ul=Object.freeze(Object.defineProperty({__proto__:null,teardownPolling:Hl,useAddResourceDataPoint:()=>Ri(e=>e.addResourceDataPoint),useCachedLocalHash:Tl,useClearMutation:()=>pl(e=>e.clearMutation),useClearPacketCache:()=>pl(e=>e.clearPacketCache),useDataTier:Pl,useEffectiveLocalLocation:Wl,useFetchHardwareStats:Oi,useFetchLogs:Bl,useFetchPackets:()=>pl(e=>e.fetchPackets),useFetchStats:()=>pl(e=>e.fetchStats),useFlashAdvert:xl,useFlashReceived:Al,useGlobalTimeRangeIndex:Rl,useHardwareStats:Pi,useHardwareStatsError:$i,useHardwareStatsLoading:Ii,useHasPackets:$l,useHiddenContacts:Sl,useHideContact:Ml,useInitializeApp:El,useIsFourteenDayDataAvailable:()=>pl(e=>e.packetCacheState.fourteenDayLoadComplete),useIsLoaded:Il,useIsSevenDayDataAvailable:()=>pl(e=>e.packetCacheState.sevenDayLoadComplete),useIsThreeDayDataAvailable:()=>pl(e=>e.packetCacheState.threeDayLoadComplete),useLastPacketTimestamp:_l,useLiveMode:Dl,useLogs:kl,useLogsLoading:vl,useMaxRetentionDays:()=>pl(e=>e.packetCacheState.maxRetentionDays),usePacketCacheState:Nl,usePacketCount:()=>pl(e=>e.packets.length),usePackets:wl,usePacketsLoading:Cl,usePendingAdvertLocalHash:()=>pl(e=>e.pendingAdvertLocalHash),usePendingAdvertTimestamp:()=>pl(e=>e.pendingAdvertTimestamp),usePrefetchForRoute:Fl,useQuickNeighbors:Ll,useRequestTierData:()=>pl(e=>e.requestTierData),useResourceHistory:qi,useSendAdvert:()=>pl(e=>e.sendAdvert),useSetDutyCycle:()=>pl(e=>e.setDutyCycle),useSetGlobalTimeRange:zl,useSetLiveMode:jl,useSetMode:()=>pl(e=>e.setMode),useSpreadingFactor:ql,useStartMutation:()=>pl(e=>e.startMutation),useStats:bl,useStatsError:yl,useStatsLoading:()=>pl(e=>e.statsLoading),useStatsReady:()=>pl(e=>null!==e.stats),useStore:fl,useTriggerDeepAnalysis:()=>pl(e=>e.triggerDeepAnalysis),useTriggerFlashAdvert:()=>pl(e=>e.triggerFlashAdvert),useTriggerFlashReceived:()=>pl(e=>e.triggerFlashReceived)},Symbol.toStringTag,{value:"Module"})),Vl={5:-2.5,6:-5,7:-7.5,8:-10,9:-12.5,10:-15,11:-17.5,12:-20},Gl={62500:{5:-123,6:-125,7:-127,8:-130,9:-133,10:-136,11:-138,12:-140},125e3:{5:-120,6:-122,7:-124,8:-127,9:-130,10:-133,11:-135,12:-137},25e4:{5:-117,6:-119,7:-121,8:-124,9:-127,10:-130,11:-132,12:-134},5e5:{5:-114,6:-116,7:-118,8:-121,9:-124,10:-127,11:-129,12:-131}},Jl=7;function Kl(e){const t=Math.max(5,Math.min(12,Math.round(e)));return Vl[t]??Vl[7]}function Xl(e,t,a){if(null==e||!Number.isFinite(e))return null;if(null==t||!Number.isFinite(t))return null;const{sf:n,bwHz:r}=a,s=Kl(n),o=function(e,t){let a=62500;a=e>=375e3?5e5:e>=187500?25e4:e>=93750?125e3:62500;const n=Gl[a];return n[Math.max(5,Math.min(12,Math.round(t)))]??n[7]}(r,n),i=e-s,l=t-o;return{snrMargin:i,rssiMargin:l,worstMargin:Math.min(i,l)}}const Yl={EXCELLENT:6,GOOD:3,FAIR:0},Ql={EXCELLENT:10,GOOD:6,FAIR:2};function Zl(e,t){const a=e-Kl(t??7);return a>=Yl.EXCELLENT?"excellent":a>=Yl.GOOD?"good":a>=Yl.FAIR?"fair":a>=Yl.FAIR-3?"poor":"critical"}const ec=["excellent","good","fair","poor","critical"];function tc(e,t){return e>=t.EXCELLENT?"excellent":e>=t.GOOD?"good":e>=t.FAIR?"fair":e>=t.FAIR-3?"poor":"critical"}function ac(e,t){if(0===t)return e;const a=ec.indexOf(e),n=Math.min(a+t,ec.length-1);return ec[n]}function nc(e,t,a=0){const n=function(e,t){return Xl(e,t,{sf:7,bwHz:62500})}(e,t);return n?rc(n,a,"low",!0):null}function rc(e,t,a,n){const r=(s=tc(e.snrMargin,Yl),o=tc(e.rssiMargin,Ql),ec.indexOf(s)>=ec.indexOf(o)?s:o);var s,o;const i=ac(r,t);return{baseGrade:r,finalGrade:i,snrMargin:e.snrMargin,rssiMargin:e.rssiMargin,worstMargin:e.worstMargin,nfPenalty:t,wasDowngraded:t>0&&i!==r,confidence:a,isMarginBased:n}}function sc(e,t,a,n=0){return a&&null!=e?function(e,t,a,n=0){const r=Xl(e,t,a);return r?rc(r,n,"high",!0):null}(e,t,a,n):null!=e&&null!=t?nc(e,t,n):function(e,t=0){if(null==e||!Number.isFinite(e))return null;const a=function(e){return e>=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"poor":"critical"}(e),n=ac(a,t);return{baseGrade:a,finalGrade:n,snrMargin:null,rssiMargin:null,worstMargin:null,nfPenalty:t,wasDowngraded:t>0&&n!==a,confidence:"low",isMarginBased:!1}}(t,n)}function oc(e){if(!e)return[];try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(Number).filter(e=>!isNaN(e))}catch{}return[]}function ic(e){return null!=e&&0!==e&&!Object.is(e,-0)&&!(e>-50||e<-130)}function lc(e,t,a=2,n=!1){if(null===t)return"stable";const r=e-t;return(0!==t?100*Math.abs(r/t):Math.abs(r))0?"up":"down":r>0?"down":"up"}function cc(e,t){const a=3600*t,n=Math.floor(Date.now()/1e3)-a,r=e.filter(e=>e.timestamp>=n&&void 0!==e.lbt_attempts&&e.lbt_attempts>0),s=r.length,o=r.filter(e=>(e.lbt_attempts??0)>1).length,i=s>0?o/s*100:0,l=r.filter(e=>(e.lbt_attempts??0)>1),c=l.length>0?l.reduce((e,t)=>e+(t.lbt_attempts??0),0)/l.length:0,d=r.filter(e=>(e.lbt_attempts??0)>=5).length,u=s>0?d/s*100:0;let h=0,m=1/0,g=0,p=0;for(const C of r){const e=oc(C.lbt_backoff_delays_ms);for(let t=0;tg&&(g=a),p++}}const f=p>0?h/p:0;0===p&&(m=0);const b=a/24,y=[],w=[];for(let C=0;C<24;C++){const e=n+C*b,t=e+b,a=r.filter(a=>a.timestamp>=e&&a.timestamp(e.lbt_attempts??0)>1).length,o=a.length>0?s/a.length*100:0,i=[];for(const n of a){const e=oc(n.lbt_backoff_delays_ms);i.push(...e)}const l=i.length>0?i.reduce((e,t)=>e+t,0)/i.length:0;if(y.push(l),0===a.length)w.push(0);else{const e=a.filter(e=>(e.lbt_attempts??0)>=5).length;let t=0;for(let a=0;at&&(t=i[a]);const n=Math.min(a.length/5,1),r=.15,s=Math.log(1+o*r)/Math.log(1+100*r)*40,c=e/a.length*100,d=Math.min(.5*c,25);let u=0;l>100&&(u=Math.min(8*Math.log10(l/100),15));let h=0;t>500&&l>0&&t>2*l&&(h=Math.min((t-500)/200,5));const m=s+d+u+h;w.push(Math.min(m*n,85))}}return{totalPacketsWithLBT:s,packetsWithRetries:o,retryRate:i,avgRetries:c,channelBusyCount:d,channelBusyRate:u,avgBackoffMs:f,minBackoffMs:m,maxBackoffMs:g,totalBackoffMs:h,sparklineBackoff:y,sparklineCollisionRisk:w,windowHours:t,packetCount:e.length}}function dc(e,t,a){if(0===e.length)return{neighbors:[],networkScore:0,neighborCount:0,bestLink:null,worstLink:null};const n=e.map(e=>{const n=function(e,t,a){const n=sc(e,t,a,0);if(n)switch(n.finalGrade){case"excellent":return 100;case"good":return 80;case"fair":return 60;case"poor":return 40;case"critical":return 20}const r=void 0===e?50:e>=10?100:e>=5?80:e>=0?60:e>=-5?40:20,s=void 0===t?50:t>=-70?100:t>=-80?80:t>=-90?60:t>=-100?40:20;return Math.round(.6*r+.4*s)}(e.avgSnr??void 0,e.avgRssi??void 0,a),r=t[e.hash];return{name:(null==r?void 0:r.name)||(null==r?void 0:r.node_name)||e.prefix,hash:e.hash,rssi:e.avgRssi??-100,snr:e.avgSnr??-10,score:n,advertCount:e.count}});n.sort((e,t)=>t.score-e.score);const r=n.length>0?n.reduce((e,t)=>e+t.score,0)/n.length:0;return{neighbors:n,networkScore:Math.round(r),neighborCount:n.length,bestLink:n.length>0?{name:n[0].name,score:n[0].score}:null,worstLink:n.length>0?{name:n[n.length-1].name,score:n[n.length-1].score}:null}}function uc(e,t,a){const n=e?Math.max(0,Math.min(100,100-5*e.retryRate)):50;let r=50;null!==t&&(r=Math.max(0,Math.min(100,(t+120)/30*100)));const s=(null==a?void 0:a.networkScore)??50,o=Math.round(.35*n+.25*r+.4*s);let i;return i=o>=85?"excellent":o>=70?"good":o>=50?"fair":o>=30?"congested":"critical",{score:o,status:i,components:{lbtHealth:Math.round(n),noiseHealth:Math.round(r),linkHealth:Math.round(s)}}}const hc=F(e=>({history:[],hours:24,isLoading:!1,lastFetchTime:0,initialize:()=>{let t=null,a=24;const n=async t=>{var a;const n=Math.max(t,24);try{const t=await Rs(n);t.success&&(null==(a=t.data)?void 0:a.history)&&e({history:t.data.history,hours:n,isLoading:!1,lastFetchTime:Date.now()})}catch{e({isLoading:!1})}},r=e=>{t&&clearInterval(t),a=e;const r=function(e){return e>=504?72e5:e>=336?36e5:e>=168?18e5:e>=72?6e5:3e5}(e);t=setInterval(()=>n(e),r)},s=fl.getState().globalTimeRangeIndex,o=Math.max(1,Math.ceil(bi[s].minutes/60));a=o,e({isLoading:!0,hours:Math.max(o,24)}),n(o),r(o);let i=s;const l=fl.subscribe(e=>{if(e.globalTimeRangeIndex!==i){i=e.globalTimeRangeIndex;const t=Math.max(1,Math.ceil(bi[e.globalTimeRangeIndex].minutes/60));t!==a&&(n(t),r(t))}});let c=0;const d=()=>{document.hidden?c=Date.now():c>0&&Date.now()-c>12e4&&n(a)};return"undefined"!=typeof document&&document.addEventListener("visibilitychange",d),()=>{t&&clearInterval(t),l(),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",d)}}})),mc=[],gc=[],pc=()=>hc(e=>e.history);function fc(e){const t=hc(e=>e.history);return s.useMemo(()=>{if(0===t.length)return gc;if(null==e)return t;const a=t.reduce((e,t)=>Math.max(e,t.timestamp),0)-3600*e;return t.filter(e=>e.timestamp>=a)},[t,e])}function bc(e){const t=hc(e=>e.history),a=hc(e=>e.hours),n=e??a;return s.useMemo(()=>0===t.length?mc:function(e,t){if(0===e.length)return[];const a=e.reduce((e,t)=>Math.max(e,t.timestamp),0);if(0===a)return[];const n=3600*t,r=a-n,s=n/24,o=[];for(let i=0;i<24;i++){const t=r+i*s,a=t+s,n=e.filter(e=>e.timestamp>=t&&e.timestamp0){const e=n.reduce((e,t)=>e+t.noise_floor_dbm,0)/n.length;o.push(e)}else o.push(o.length>0?o[o.length-1]:-100)}return o}(t,n),[t,n])}function yc(){const e=hc(e=>e.history);return s.useMemo(()=>{if(0===e.length)return null;const t=e.map(e=>e.noise_floor_dbm).filter(e=>null!=e&&e>-200&&e<0);if(0===t.length)return null;const a=[...t].sort((e,t)=>e-t);return a[Math.floor(a.length/2)]},[e])}const wc=hc,Cc={healthy:{p3:"color(display-p3 0.2 1 0.4)",fallback:"#00FF66"},degraded:{p3:"color(display-p3 1 0.7 0.2)",fallback:"#FFB020"},offline:{p3:"color(display-p3 1 0.3 0.3)",fallback:"#EF4444"},connecting:{p3:"color(display-p3 0.4 0.6 1)",fallback:"#6699FF"},rx:{p3:"color(display-p3 0.2 1 0.4)",fallback:"#00FF66"},tx:{p3:"color(display-p3 1 0.9 0.2)",fallback:"#FFDD00"},idle:{p3:"color(display-p3 0.3 0.3 0.35)",fallback:"#4A4A55"}};function kc({color:e,pulse:t=!1,className:a}){var n;return o.jsx("span",{className:E("inline-block rounded-full w-1 h-1",t&&"animate-pulse",a),style:{backgroundColor:e.fallback,...(null==(n=CSS.supports)?void 0:n.call(CSS,"color","color(display-p3 1 1 1)"))&&{backgroundColor:e.p3}}})}function vc({showLabel:e=!1,rotated:t=!1,className:a}){const n=Al(),r=xl(),i=ao(e=>"connected"===e.connectionState),l=vs(),c=ks(e=>e.isInitializing),d=ks(e=>e.meshContext),[u,h]=s.useState("idle"),[m,g]=s.useState(!1),[p,b]=s.useState({x:0,y:0}),y=s.useRef(null),w=s.useRef(0),C=s.useRef(0);s.useEffect(()=>{if(n<=0)return;const e=Date.now();if(e-w.current<50)return;w.current=e,h("rx");const t=setTimeout(()=>h("idle"),100);return()=>clearTimeout(t)},[n]),s.useEffect(()=>{if(r<=0)return;const e=Date.now();if(e-C.current<50)return;C.current=e,h("tx");const t=setTimeout(()=>h("idle"),100);return()=>clearTimeout(t)},[r]);let k=Cc.healthy,v=!1,D="LIVE",A="Real-time (WebSocket)";const x=d.hasTopologyData?` · ${d.edgeCount} edges${d.hubCount>0?`, ${d.hubCount} hub${d.hubCount>1?"s":""}`:""}`:"";c?(k=Cc.connecting,v=!0,D="WAIT",A="Connecting..."):"offline"===l?(k=Cc.offline,v=!0,D="DOWN",A="Cannot reach server"):"degraded"===l?(k=Cc.degraded,D="POLL",A="Real-time unavailable, using REST polling"+x):i?(k=Cc.healthy,D="LIVE",A="Real-time (WebSocket)"+x):(k=Cc.healthy,D="POLL",A="Database polling"+x);const F="rx"===u?Cc.rx:"tx"===u?Cc.tx:Cc.idle;if(t){const e=()=>{if(y.current){const e=y.current.getBoundingClientRect();b({x:e.right+8,y:e.top+e.height/2})}g(!0)};return o.jsxs("span",{ref:y,className:E("relative inline-flex",a),onMouseEnter:e,onMouseLeave:()=>g(!1),children:[o.jsxs("span",{className:"inline-flex items-center justify-center gap-1 px-1.5 h-4 rounded-full depth-raised-soft bg-surface",style:{transform:"rotate(-90deg)"},children:[o.jsx(kc,{color:k,pulse:v}),o.jsx(kc,{color:F})]}),m&&f.createPortal(o.jsx("span",{className:"fixed px-2 py-1 rounded bg-zinc-900 text-[10px] text-fg-secondary whitespace-nowrap shadow-lg ring-1 ring-edge-subtle pointer-events-none",style:{left:p.x,top:p.y,transform:"translateY(-50%)",zIndex:9999},children:A}),document.body)]})}return o.jsxs("span",{className:E("inline-flex items-center gap-1.5",a),title:A,children:[o.jsxs("span",{className:"inline-flex items-center justify-center gap-1 px-1.5 h-4 rounded-full depth-raised-soft bg-surface",children:[o.jsx(kc,{color:k,pulse:v}),o.jsx(kc,{color:F})]}),e&&o.jsx("span",{className:E("type-data-xs","DOWN"===D?"text-status-danger":"WAIT"===D?"text-sys-blue":"POLL"===D?"text-status-warning":"text-fg-muted"),children:D})]})}const Dc="undefined"!=typeof window&&(null==(e=CSS.supports)?void 0:e.call(CSS,"color","color(display-p3 1 1 1)")),Ac=Dc?"color(display-p3 0.227 0.51 0.965)":"var(--sys-blue)",xc=Dc?"drop-shadow(0 0 4px color-mix(in oklch, var(--sys-blue) 50%, transparent))":"drop-shadow(0 0 3px color-mix(in oklch, var(--sys-blue) 40%, transparent))";function Ec({borderRadius:e,width:t,height:a}){const n=s.useMemo(()=>function(e,t,a){const n=Math.min(a,e/2,t/2);return 2*(e-2*n)+2*(t-2*n)+2*Math.PI*n}(t,a,e),[t,a,e]),r=.15*n,i=n-r;return o.jsx(_.svg,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{opacity:{duration:.2,ease:[.4,0,.2,1]}},width:t,height:a,viewBox:`0 0 ${t} ${a}`,fill:"none",className:"animate-[shimmer-pulse_2s_ease-in-out_infinite]",style:{position:"absolute",inset:0,zIndex:2,pointerEvents:"none","--shimmer-shadow":xc,filter:xc},children:o.jsx(_.rect,{x:1,y:1,width:t-2,height:a-2,rx:e-1,ry:e-1,stroke:Ac,strokeWidth:2,strokeDasharray:`${r} ${i}`,strokeLinecap:"round",initial:{strokeDashoffset:0},animate:{strokeDashoffset:-n},transition:{duration:2,ease:"linear",repeat:1/0}})})}function Fc({children:e,isLoading:t=!0,className:a,borderRadius:n=12}){const r=s.useRef(null),[i,l]=s.useState({w:0,h:0});return s.useEffect(()=>{const e=r.current;if(!e)return;const t=new ResizeObserver(([e])=>{const{width:t,height:a}=e.contentRect;l(e=>e.w===t&&e.h===a?e:{w:t,h:a})});return t.observe(e),()=>t.disconnect()},[]),o.jsxs("div",{ref:r,className:E("relative overflow-hidden",a),style:{borderRadius:n},children:[o.jsx(T,{children:t&&i.w>0&&o.jsx(Ec,{borderRadius:n,width:i.w,height:i.h})}),o.jsx("div",{className:"relative z-10",children:e})]})}function Bc({className:e}){return o.jsx("div",{className:E("relative w-14 h-2 rounded-full overflow-hidden sparkle-bar-track",e),children:o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full w-full overflow-hidden",children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]})})}const jc=F(e=>({sparklines:new Map,isComputing:!1,lastUpdated:0,nodeCount:0,setSparklines:t=>e({sparklines:t,lastUpdated:Date.now(),nodeCount:t.size,isComputing:!1}),setComputing:t=>e({isComputing:t})}));"undefined"!=typeof window&&setTimeout(()=>{to.subscribe((e,t)=>{const a=jc.getState();t&&!a.isComputing?a.setComputing(!0):!t&&e.size>0?a.setSparklines(e):!t&&a.isComputing&&a.setComputing(!1)})},0);const Sc=jc,Mc=()=>jc(e=>e.sparklines),Nc=()=>jc(e=>e.isComputing),Lc=[],Tc=new Map;function _c(e){return jc(t=>{const a=t.sparklines.get(e);if(!a||0===a.length)return Lc;const n=Tc.get(e);return n===a?n:(Tc.set(e,a),a)})}const Rc="pymc_room_seen_",zc="pymc_room_selected";function Pc(e){try{const t=localStorage.getItem(`${Rc}${e}`);return t?Number(t):0}catch{return 0}}function Ic(e){const t=new Map;for(const a of e){const e=Math.floor(a.post_timestamp/30),n=`${a.author_pubkey}|${e}|${a.message_text}`,r=t.get(n);(!r||a.idr&&e{let a=null;return{rooms:[],selectedRoom:null,messages:[],clients:[],identities:[],unreadCount:0,lastSeenMap:new Map,isLoading:!1,error:null,initialize:()=>{if(!a)return t().fetchRooms(),a=setInterval(()=>{t().fetchRooms()},1e4),()=>{a&&(clearInterval(a),a=null)}},fetchRooms:async()=>{try{const[a,n]=await Promise.all([eo(),Ks()]),r=a.success&&a.data?a.data.rooms:[],s=(n.success&&n.data?n.data.configured:[]).filter(e=>"room_server"===e.type),o=new Set(s.map(e=>e.name)),i=r.filter(e=>o.has(e.room_name)),l=new Map;for(const e of i)l.set(e.room_name,Pc(e.room_name));const c=qc(i,l);e({rooms:i,identities:s,lastSeenMap:l,unreadCount:c,error:null});const{selectedRoom:d}=t();if(i.length,s.length,!d&&i.length>0){const e=function(){try{return localStorage.getItem(zc)}catch{return null}}(),a=e&&i.some(t=>t.room_name===e)?e:i[0].room_name;t().selectRoom(a)}}catch(a){e({error:a instanceof Error?a.message:"Failed to fetch rooms"})}},selectRoom:async a=>{const{selectedRoom:n}=t();e(n!==a?{selectedRoom:a,messages:[],clients:[],isLoading:!0}:{selectedRoom:a,isLoading:!0}),function(e){try{localStorage.setItem(zc,e)}catch{}}(a),await Promise.all([t().fetchMessages(),t().fetchClients()]),e({isLoading:!1})},fetchMessages:async a=>{var n,r;const{selectedRoom:s,messages:o}=t();if(!s)return;const i={room_name:s,limit:200};if((null==a?void 0:a.incremental)&&o.length>0){const e=Math.max(...o.map(e=>e.post_timestamp));i.since_timestamp=e}try{const t=await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),void 0!==e.limit&&t.set("limit",e.limit.toString()),void 0!==e.offset&&t.set("offset",e.offset.toString()),void 0!==e.since_timestamp&&t.set("since_timestamp",e.since_timestamp.toString()),Fs(`/api/room_messages?${t.toString()}`)}(i);if(t.success,t.data,null==(r=null==(n=t.data)?void 0:n.messages)||r.length,!t.success||!t.data)return;if((null==a?void 0:a.incremental)&&o.length>0){const a=new Set(o.map(e=>e.id)),n=t.data.messages.filter(e=>!a.has(e.id));n.length>0&&e({messages:Ic([...o,...n])})}else e({messages:Ic(t.data.messages)})}catch(l){console.error("[RoomStore] fetchMessages error:",l)}},postMessage:async e=>{try{return!!(await async function(e){return Fs("/api/room_post_message",{method:"POST",body:JSON.stringify(e)})}(e)).success&&(await t().fetchMessages(),!0)}catch{return!1}},deleteMessage:async a=>{const{selectedRoom:n}=t();if(!n)return!1;try{return!!(await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),t.set("message_id",e.message_id.toString()),Fs(`/api/room_message?${t.toString()}`,{method:"DELETE"})}({room_name:n,message_id:a})).success&&(e({messages:t().messages.filter(e=>e.id!==a)}),!0)}catch{return!1}},clearMessages:async()=>{const{selectedRoom:a}=t();if(!a)return!1;try{return!!(await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),Fs(`/api/room_messages_clear?${t.toString()}`,{method:"DELETE"})}({room_name:a})).success&&(e({messages:[]}),!0)}catch{return!1}},fetchClients:async()=>{const{selectedRoom:a}=t();if(a)try{const t=await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),Fs(`/api/room_clients?${t.toString()}`)}({room_name:a});t.success&&t.data&&e({clients:t.data.clients.filter(e=>e.in_acl)})}catch{}},markAsRead:()=>{const{selectedRoom:a,rooms:n,lastSeenMap:r}=t();if(!a)return;const s=Math.floor(Date.now()/1e3);!function(e,t){try{localStorage.setItem(`${Rc}${e}`,String(t))}catch{}}(a,s);const o=new Map(r);o.set(a,s),e({lastSeenMap:o,unreadCount:qc(n,o)})},createRoom:async e=>{try{return!!(await async function(e){return Fs("/api/create_identity",{method:"POST",body:JSON.stringify(e)})}(e)).success&&(await t().fetchRooms(),!0)}catch{return!1}},updateRoom:async e=>{try{return!!(await async function(e){return Fs("/api/update_identity",{method:"PUT",body:JSON.stringify(e)})}(e)).success&&(await t().fetchRooms(),!0)}catch{return!1}},deleteRoom:async a=>{try{const n=await async function(e){return Fs(`/api/delete_identity?name=${encodeURIComponent(e)}`,{method:"DELETE"})}(a);if(n.success){const{selectedRoom:n}=t();return n===a&&e({selectedRoom:null,messages:[],clients:[]}),await t().fetchRooms(),!0}return!1}catch{return!1}},sendAdvert:async e=>{try{const t=await async function(e){return Fs("/api/send_room_server_advert",{method:"POST",body:JSON.stringify({name:e})})}(e);return!!t.success}catch{return!1}},startActivePolling:()=>{const e=setInterval(()=>{t().fetchMessages({incremental:!0}),t().fetchClients()},5e3);return()=>clearInterval(e)}}}),Hc=()=>Oc(e=>e.rooms),Wc=()=>Oc(e=>e.selectedRoom),Uc=()=>Oc(e=>e.messages),Vc=()=>Oc(e=>e.clients),Gc=()=>Oc(e=>e.identities),Jc=()=>Oc(e=>e.isLoading),Kc=()=>Oc(e=>e.rooms.find(t=>t.room_name===e.selectedRoom)??null),Xc=()=>Oc(e=>e.identities.find(t=>{var a;return t.name===e.selectedRoom||(null==(a=t.settings)?void 0:a.node_name)===e.selectedRoom})??null);function Yc(e){if(e<60)return`${Math.floor(e)}s`;const t=Math.floor(e/86400),a=Math.floor(e%86400/3600),n=Math.floor(e%3600/60),r=[];return t>0&&r.push(`${t}d`),a>0&&r.push(`${a}h`),(n>0||0===r.length)&&r.push(`${n}m`),r.join(" ")}function Qc(e){const t=Date.now()/1e3-e;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function Zc(e){const t=Date.now()/1e3-e;return t<60?`${Math.floor(t)}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function ed(e){return new Date(1e3*e).toLocaleString()}function td(e){const t=new Date(1e3*e);return`${t.toLocaleString("en-US",{month:"short"})} ${t.getDate()}, ${t.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}`}function ad(e){return new Date(1e3*e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function nd(e){return`${(e/1e6).toFixed(3)} MHz`}function rd(e){return`${(e/1e3).toFixed(1)} kHz`}function sd(e){e<0&&(e=0);const t=Math.floor(e/1e3),a=Math.floor(t/60),n=Math.floor(a/60);if(n>0){const e=a%60;return e>0?`${n}h ${e}m`:`${n}h`}if(a>0){const e=t%60;return e>0?`${a}m ${e}s`:`${a}m`}if(t>0){const a=e%1e3;return a>0?`${t}.${Math.floor(a/100)}s`:`${t}s`}return`${e}ms`}function od(e){return e<1024?`${e}B`:e<1048576?`${(e/1024).toFixed(1)}K`:`${(e/1048576).toFixed(1)}M`}s.memo(function({options:e,data:t,className:a="",onCreate:n}){const r=s.useRef(null),i=s.useRef(null);return s.useEffect(()=>{const a=r.current;if(!a)return;const s=a.getBoundingClientRect(),o=Math.floor(s.width)||400,l=Math.floor(s.height)||200,c=new D({...e,width:o,height:l},t,a);return i.current=c,null==n||n(c),()=>{c.destroy(),i.current=null}},[e]),s.useEffect(()=>{i.current&&t&&i.current.setData(t)},[t]),s.useEffect(()=>{const e=r.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!i.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&i.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),o.jsx("div",{ref:r,className:`w-full h-full ${a}`,style:{minHeight:100}})});const id=s.memo(function({items:e,direction:t="horizontal",size:a="sm",className:n,highlightedKey:r,onItemClick:s,onItemHover:i}){const l="horizontal"===t,c="sm"===a;return o.jsx("div",{className:E("flex font-mono",l?"flex-wrap gap-x-4 gap-y-1":"flex-col gap-1",c?"text-xs":"text-sm",n),children:e.map(e=>{const t=null!=r&&r!==e.key,a=s||i;return o.jsxs("div",{className:E("flex items-center gap-1.5 transition-opacity",t&&"opacity-30",a&&"cursor-pointer hover:opacity-80"),onClick:()=>null==s?void 0:s(e.key),onMouseEnter:()=>null==i?void 0:i(e.key),onMouseLeave:()=>null==i?void 0:i(null),children:[o.jsx("div",{className:E("shrink-0 rounded-xs",c?"w-3 h-3":"w-4 h-4"),style:{backgroundColor:e.color}}),o.jsx("span",{className:"text-fg-secondary whitespace-nowrap",children:e.label}),void 0!==e.value&&o.jsx("span",{className:"text-fg-muted tabular-nums",children:e.formatValue?e.formatValue(e.value):e.value})]},e.key)})})}),ld={4:me.blue,5:me.indigo,6:me.purple,0:me.cyan,2:me.teal,7:me.green,1:me.yellow,10:me.amber,8:me.orange,9:me.red,3:me.pink,15:me.brown},cd=me.brown;function dd(e){return ld[e]??cd}let ud=null,hd=0;const md=1e3;function gd({activeTypes:e,totalByType:t}){const a=[...e].reverse().map(e=>({key:String(e),label:nt[e]??`TYPE_${e}`,color:dd(e),value:t[e]??0,formatValue:e=>od(e)}));return o.jsx(id,{items:a})}const pd=s.memo(function({buckets:e,activeTypes:t,onHover:a,gridColor:n,axisTickColor:r}){const i=s.useRef(null),l=s.useRef(null),c=s.useRef(e),d=s.useRef(t),u="undefined"!=typeof document&&"light"!==document.documentElement.dataset.mode,h=n||(u?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.1)"),m=r||(u?"rgba(255,255,255,0.6)":"rgba(0,0,0,0.6)"),g=s.useRef({gridColor:h,axisTickColor:m});c.current=e,d.current=t,g.current={gridColor:h,axisTickColor:m};const p=e.length,f=s.useMemo(()=>[e.map(e=>e.start),e.map(()=>1)],[p]),b=s.useCallback(t=>{if(!i.current||0===e.length)return;const n=i.current.getBoundingClientRect(),r=(t.clientX-n.left-48)/(n.width-48-8);if(r<0||r>1)return void(null==a||a(null,null,null));const s=Math.min(e.length-1,Math.max(0,Math.floor(r*e.length)));null==a||a(s,e[s],r)},[e,a]),y=s.useCallback(()=>{null==a||a(null,null,null)},[a]);return s.useEffect(()=>{if(!i.current||0===p)return;const e=i.current,t=e.getBoundingClientRect(),a={width:Math.floor(t.width)||400,height:Math.floor(t.height)||200,padding:[8,8,28,48],cursor:{show:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[e=>{const t=e.ctx,{left:a,top:n,width:r,height:s}=e.bbox,o=window.devicePixelRatio||1,i=g.current;!function(e,t,a,n,r,s,o){if(0===t.length||0===a.length)return;const i=t.length,l=s/i;let c=0;for(const d of t)d.totalBytes>c&&(c=d.totalBytes);0===c&&(c=1);for(let d=0;dc&&(c=b.totalBytes);if(0===c)return;const d=function(){const e=performance.now();if(ud&&e-hd{const t=e.getBoundingClientRect();t.width>0&&t.height>0&&l.current&&l.current.setSize({width:Math.floor(t.width),height:Math.floor(t.height)})});return r.observe(e),()=>{r.disconnect(),n.destroy(),l.current=null}},[p]),s.useEffect(()=>{l.current&&l.current.redraw()},[e,t]),0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:i,className:"w-full h-full",onMouseMove:b,onMouseLeave:y})}),fd=new Map;function bd(e){var t;if(!e.startsWith("var("))return e;const a=fd.get(e);if(a)return a;const n=e.match(/var\(([^,)]+)(?:,\s*([^)]+))?\)/);if(!n)return e;const r=n[1].trim(),s=(null==(t=n[2])?void 0:t.trim())||"#888888",o=getComputedStyle(document.documentElement).getPropertyValue(r).trim()||s;return fd.set(e,o),o}const yd="undefined"!=typeof document&&"light"!==document.documentElement.dataset.mode?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.3)";function wd(e,t,a=!1){if(t.length<2)return;if(e.beginPath(),e.moveTo(t[0].x,t[0].y),2===t.length)return void e.lineTo(t[1].x,t[1].y);const n=.5;for(let r=0;r{g.current=e,p.current=t,f.current=n,b.current=a});const w=s.useRef({band:r,innerBand:i,mean:l,median:c,average:d,cursor:u});s.useLayoutEffect(()=>{w.current={band:r,innerBand:i,mean:l,median:c,average:d,cursor:u}});const C=s.useMemo(()=>[e.map(e=>e.timestamp),e.map(e=>e.max)],[e]),k=s.useMemo(()=>{const e=function(e,t,a,n){return{hooks:{draw:r=>{const s=e.current,o=t.current,i=a.current,l=n.current;if(0===s.length)return;const c=r.ctx,d=r.bbox,u=d.left,h=d.top,m=d.width,g=d.height;if(m<=0||g<=0)return;const p=r.data[0],f=p.length;if(0===f)return;const b=p[0],y=p[f-1]-b||1,w=e=>u+(e-b)/y*m,C=e=>h+g*(1-e/o),k={min:s.map(e=>({x:w(e.timestamp),y:C(e.min)})),max:s.map(e=>({x:w(e.timestamp),y:C(e.max)})),p5:s.map(e=>({x:w(e.timestamp),y:C(e.p5)})),p95:s.map(e=>({x:w(e.timestamp),y:C(e.p95)})),p25:s.map(e=>({x:w(e.timestamp),y:C(e.p25)})),p75:s.map(e=>({x:w(e.timestamp),y:C(e.p75)})),mean:s.map(e=>({x:w(e.timestamp),y:C(e.mean)})),median:s.map(e=>({x:w(e.timestamp),y:C(e.median)})),average:s.map(e=>({x:w(e.timestamp),y:C(e.average)}))},v=(e,t)=>i?i===e?Math.min(1,1.5*t):"minMax"===i||"p5p95"===i||"p25p75"===i?.3*t:t:t,D=e=>i?i===e?1:"mean"===i||"median"===i||"average"===i?.3:1:1,A={band:bd(l.band),innerBand:bd(l.innerBand),mean:bd(l.mean),median:bd(l.median),average:bd(l.average)};c.save(),c.strokeStyle=A.average,c.lineWidth=4,c.globalAlpha=D("average"),wd(c,k.average),c.stroke(),c.globalAlpha=v("minMax",.15),c.fillStyle=A.band,c.beginPath(),wd(c,k.max);const x=[...k.min].reverse();for(const e of x)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.globalAlpha=v("p5p95",.3),c.fillStyle=A.band,c.beginPath(),wd(c,k.p95);const E=[...k.p5].reverse();for(const e of E)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.globalAlpha=v("p25p75",.55),c.fillStyle=A.innerBand,c.beginPath(),wd(c,k.p75);const F=[...k.p25].reverse();for(const e of F)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.strokeStyle=A.median,c.lineWidth=1.5,c.globalAlpha=D("median"),c.setLineDash([4,4]),wd(c,k.median),c.stroke(),c.strokeStyle=A.mean,c.lineWidth=1.5,c.globalAlpha=D("mean"),c.setLineDash([]),wd(c,k.mean),c.stroke(),c.restore()}}}}(g,p,f,w);return{width:400,height:200,padding:[4,4,4,4],cursor:{show:!0,x:!0,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,t]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],hooks:{setCursor:[e=>{var t,a;const n=e.cursor.idx;null!=n&&n>=0?null==(t=b.current)||t.call(b,n):null==(a=b.current)||a.call(b,null)}]},plugins:[e]}},[t]);s.useEffect(()=>{const t=h.current;if(!t||0===e.length)return;const a=y.current,n=e.length,r=Math.abs(n-a);if(!(!m.current||r>100||a>0&&r/a>.1)&&m.current)return m.current.setData(C),void(y.current=n);m.current&&m.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...k,width:o,height:i},C,t);return m.current=l,y.current=n,()=>{l.destroy(),m.current=null}},[k,C,e.length]),s.useEffect(()=>{const e=h.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!m.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&m.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{m.current&&m.current.redraw()},[n,e]);const v=s.useCallback(()=>{null==a||a(null)},[a]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:h,className:"w-full h-full rounded-2xl overflow-hidden",onMouseLeave:v})});const Cd="undefined"!=typeof window&&(null==(a=null==(t=window.matchMedia)?void 0:t.call(window,"(color-gamut: p3)"))?void 0:a.matches);let kd=null,vd=0;function Dd(){const e=performance.now();if(kd&&e-vd<1e3)return kd;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--chart-axis-tick").trim()||(n?"rgba(255, 255, 255, 0.4)":"rgba(0, 0, 0, 0.4)"),s=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)"),o=t.getPropertyValue("--text-muted").trim()||"#727272",i=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),l=t.getPropertyValue("--signal-critical").trim()||"#EF4444",c=t.getPropertyValue("--bg-body").trim()||(n?"#171717":"#F5F5F5");return kd={fontFamily:a,axisColor:r,gridColor:s,textMuted:o,textPrimary:i,signalCritical:l,bgBody:c},vd=e,kd}const Ad=["min","max","p75","p95","p99","mean","median","average","midpoint"];function xd(e){const t=ct(function(e){const{colormap:t,baseIndex:a,halfSize:n}=ht(),r=Math.max(0,Math.min(1,e)),s=Math.min(a+Math.floor(r*(n-1)),t.discrete.length-1);return t.discrete[s]}(e)),a=`color(display-p3 ${(t.r/255).toFixed(3)} ${(t.g/255).toFixed(3)} ${(t.b/255).toFixed(3)})`;return{...t,p3:a}}function Ed(e,t,a,n,r,s,o,i,l,c=null,d=null,u=1,h=null,m="airtime",g=.5){if(0===t.length)return;const p=e.ctx,{left:f,top:b,width:y,height:w}=e.bbox,C=window.devicePixelRatio||1;if(y<=0||w<=0)return;const k=e.data[0],v=k.length;if(0===v)return;const D=k[0],A=k[v-1],x=a,E="share"===m,F=E?function(e){const t=[10,20,25,50,100,200,250,500,1e3],a=e/4.5;for(const n of t)if(n>=a)return n;return e>5e3?1e3*Math.ceil(a/1e3):100*Math.ceil(a/100)}(x):5,B=s.signalCritical,j=s.bgBody;p.save(),p.fillStyle="#000000";const S=8*C;p.beginPath(),p.roundRect(f,b,y,w,S),p.fill(),p.restore();const M=parseInt(j.slice(1,3),16)||23,N=parseInt(j.slice(3,5),16)||23,L=parseInt(j.slice(5,7),16)||23;if(!E&&x>=20){p.save();const e=b+w*(1-20/x);p.fillStyle=`rgba(${M}, ${N}, ${L}, 0.5)`,p.fillRect(f,b,y,e-b),p.restore()}p.save(),p.lineWidth=1*C,p.setLineDash([4*C,4*C]);for(let _=F;_a+r)return;const i=Dd().textPrimary;e.save(),e.strokeStyle=i,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()}(p,h,f,b,y,w,C),o){!function(e,t,a,n,r,s,o=null,i=null,l=1,c=25){const{points:d,rawValues:u,count:h,packetTypes:m,timestamps:g}=t,p=1*l*(window.devicePixelRatio||1);e.globalCompositeOperation="source-over";const f=o?parseInt(o.replace("TYPE_",""),10):null;for(let b=0;b=i.start&&e0&&function(e,t,a,n,r,s,o,i,l,c,d=.5){if(0===t.length)return;const u=l-i||1,h=function(e,t=1.3,a=.15){const n=function(e){const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t){const e=parseFloat(t[1]),a=parseFloat(t[2]),n=parseFloat(t[3]);return{r:Math.round(255*e),g:Math.round(255*a),b:Math.round(255*n),p3r:e,p3g:a,p3b:n}}if(e.startsWith("#")){const t=e.replace("#",""),a=parseInt(t.slice(0,2),16),n=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16);return{r:a,g:n,b:r,p3r:a/255,p3g:n/255,p3b:r/255}}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);if(a){const e=Math.round(parseFloat(a[1])),t=Math.round(parseFloat(a[2])),n=Math.round(parseFloat(a[3]));return{r:e,g:t,b:n,p3r:e/255,p3g:t/255,p3b:n/255}}return{r:255,g:255,b:255,p3r:1,p3g:1,p3b:1}}(e),r=function(e,t,a,n=1.25,r=.15){const s=(Math.max(e,t,a)+Math.min(e,t,a))/2;return{p3r:Math.min(1,s+(e-s)*n+r),p3g:Math.min(1,s+(t-s)*n+r),p3b:Math.min(1,s+(a-s)*n+r)}}(n.p3r,n.p3g,n.p3b,t,a);return{r:Math.round(255*Math.min(1,r.p3r)),g:Math.round(255*Math.min(1,r.p3g)),b:Math.round(255*Math.min(1,r.p3b)),p3r:Math.min(1,r.p3r),p3g:Math.min(1,r.p3g),p3b:Math.min(1,r.p3b)}}(Dd().signalCritical);e.save(),e.globalAlpha=d,e.fillStyle=Cd?`color(display-p3 ${h.p3r} ${h.p3g} ${h.p3b})`:`rgb(${h.r}, ${h.g}, ${h.b})`;for(const m of t){if(m.endTsl)continue;const t=n+(Math.max(m.startTs,i)-i)/u*s,a=n+(Math.min(m.endTs,l)-i)/u*s,d=Math.max(a-t,2*c);e.fillRect(t,r,d,o)}e.restore()}(p,i,0,f,b,y,w,D,A,C,d?Math.max(.03,.03*g):g)}s.memo(function({data:e,maxValue:t,visibleLines:a=Ad,highlightedLine:n=null,onHover:r,scatterData:i=null,noiseFloorAnomalies:l=null,showNoiseFloorOverlay:c=!1,overlayOpacity:d=.5,highlightedType:u=null,hoveredTimeRange:h=null,timeRangeHours:m=24,yAxisMode:g="airtime"}){const p=s.useRef(null),f=s.useRef(null),b=s.useRef(e),y=s.useRef(t),w=s.useRef(a),C=s.useRef(n),k=s.useRef(r),v=s.useRef(i),A=s.useRef(l),x=s.useRef(c),E=s.useRef(u),F=s.useRef(h),B=s.useRef(null),j=s.useRef(null),S=s.useRef(g),M=s.useRef(d),N=m<=12?1.2:1,L=s.useRef(N),T=s.useRef(e.length);s.useLayoutEffect(()=>{b.current=e,y.current=t,w.current=a,C.current=n,k.current=r,v.current=i,A.current=l,x.current=c,E.current=u,F.current=h,L.current=N,S.current=g,M.current=d}),s.useEffect(()=>{B.current=Dd()},[]);const _=s.useMemo(()=>[e.map(e=>e.timestamp),new Array(e.length).fill(1)],[e]),R=s.useMemo(()=>({hooks:{draw:e=>{const t=B.current||Dd();Ed(e,b.current,y.current,w.current,C.current,t,v.current,A.current,x.current,E.current,F.current,L.current,j.current,S.current,M.current)}}}),[]),z=s.useMemo(()=>({width:400,height:200,padding:[8,0,8,28],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[R]}),[R]);s.useEffect(()=>{const t=p.current;if(!t||0===e.length)return;const a=T.current,n=e.length,r=Math.abs(n-a);if(!(!f.current||r>100||a>0&&r/a>.1)&&f.current)return f.current.setData(_),void(T.current=n);f.current&&f.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...z,width:o,height:i},_,t);return f.current=l,T.current=n,()=>{l.destroy(),f.current=null}},[z,_,e.length]),s.useEffect(()=>{const e=p.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!f.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&f.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{f.current&&f.current.redraw()},[n,a,e,i,l,c,d,u,h,N]);const P=s.useCallback(t=>{var a,n;const r=p.current,s=f.current;if(!r||!s||0===e.length)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,c=s.bbox,d=c.left/l,u=c.width/l;if(id+u)return j.current=null,s.redraw(),void(null==(a=k.current)||a.call(k,null));j.current=i*l;const h=(i-d)/u,m=e.length,g=Math.floor(h*m),b=Math.max(0,Math.min(m-1,g));s.redraw(),null==(n=k.current)||n.call(k,b)},[e.length]),I=s.useCallback(()=>{var e;j.current=null,f.current&&f.current.redraw(),null==(e=k.current)||e.call(k,null)},[]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:p,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:P,onMouseLeave:I})});const Fd=(()=>{const e=lt.lajolla.discrete.map(e=>{const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}),t=new Uint8Array(768);for(let a=0;a<256;a++){const n=a/255*(e.length-1),r=Math.floor(n),s=Math.min(r+1,e.length-1),o=n-r;t[3*a]=Math.round(e[r][0]+(e[s][0]-e[r][0])*o),t[3*a+1]=Math.round(e[r][1]+(e[s][1]-e[r][1])*o),t[3*a+2]=Math.round(e[r][2]+(e[s][2]-e[r][2])*o)}return t})();let Bd=null;const jd=-70;let Sd=null,Md=0;function Nd(e,t){if(0===e.length)return 0;const a=t/100*(e.length-1),n=Math.floor(a),r=Math.ceil(a);return n===r?e[n]:e[n]+(e[r]-e[n])*(a-n)}function Ld(e){const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\)/);if(t)return{r:Math.round(255*parseFloat(t[1])),g:Math.round(255*parseFloat(t[2])),b:Math.round(255*parseFloat(t[3]))};const a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return a?{r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)}:{r:250,g:189,b:47}}function Td(e,t,a){const n=Math.max(0,Math.min(1,e));return{r:Math.round(t.r+(a.r-t.r)*n),g:Math.round(t.g+(a.g-t.g)*n),b:Math.round(t.b+(a.b-t.b)*n)}}const _d=s.memo(function({timestamps:e,values:t,onStatsChange:a,compact:n=!1,height:r}){var i,l;const[c,d]=s.useState(!1),[u,h]=s.useState(!1),m=s.useRef(null),g=s.useRef(null),p=s.useRef(null),f=s.useRef(null),b=s.useRef(null),y=s.useRef(n),w=s.useRef(u),C=s.useMemo(()=>{const e=t.filter(e=>e<=jd);if(0===e.length)return null;let a=e[0],n=e[0];for(let t=1;tn&&(n=e[t]);const r=e.reduce((e,t)=>e+t,0)/e.length,s=[...e].sort((e,t)=>e-t);return{min:a,max:n,avg:r,p5:Nd(s,5),p95:Nd(s,95)}},[t]);s.useEffect(()=>{null==a||a(C)},[C]);const k=s.useCallback(()=>{d(e=>!e)},[]),v=s.useCallback(()=>{h(e=>!e)},[]),{heatmapData:A,xLabels:x,yLabels:E}=s.useMemo(()=>{if(0===e.length||0===t.length||!C)return{heatmapData:null,xLabels:[],yLabels:[]};let a,r;if(c){const e=t.filter(e=>e<=jd);if(0===e.length)return{heatmapData:null,xLabels:[],yLabels:[]};const n=[...e].sort((e,t)=>e-t),s=Nd(n,5),o=Nd(n,95),i=.1*(o-s||1);a=s-i,r=o+i}else{const e=t.filter(e=>e<=jd);if(0===e.length)return{heatmapData:null,xLabels:[],yLabels:[]};let n=e[0],s=e[0];for(let t=1;ts&&(s=e[t]);const o=.1*(s-n||1);a=n-o,r=s+o}const s=r-a,o=e[0],i=e[e.length-1],l=i-o||1,d=200,u=60,h=new Float32Array(12e3),m=[];for(let n=0;njd)continue;const c=(e[n]-o)/l,g=1-(Math.max(a,Math.min(r,i))-a)/s;h[Math.min(199,Math.floor(c*d))*u+Math.min(59,Math.floor(g*u))]++,m.push(e[n])}let g=0;for(let e=0;eg&&(g=h[e]);const p=[],f=[];for(let e=0;et&&(t=n,a=r)}if(-1===a||0===t)continue;const n=r-(a+.5)/u*s,i=o+(e+.5)/d*l;p.push(i),f.push(n)}const b=f.length>=2?200:0,y=f.length>=2?function(e,t,a,n){const r=e.length;if(0===r)return[];if(1===r)return new Array(n).fill(t[0]);if(2===r){const e=new Array(n);for(let a=0;ae-t),h=Math.max(u[s-1],1e-10);let m=0,g=0,p=0,f=0,b=0;for(let n=0;n=1)continue;const s=r*r*r,o=(1-s)*(1-s)*(1-s),i=e[n]-a;m+=o,g+=o*i,p+=o*t[n],f+=o*i*i,b+=o*i*t[n]}if(0===m){l[d]=t[Math.min(r-1,Math.round(d/(n-1)*(r-1)))];continue}const y=m*f-g*g;Math.abs(y)<1e-10?l[d]=p/m:l[d]=(f*p-g*b)/y}return l}(p,f,0,b):[];let w=a,k=r,v=s;if(n&&y.length>0){let e=y[0],t=y[0];for(let n=1;nt&&(t=y[n]);const a=.4*(t-e||1);w=e-a,k=t+a,v=k-w}const D=[];for(let e=0;e{b.current=A,y.current=n,w.current=u});const F=s.useMemo(()=>{if(0===e.length)return[[],[]];const t=new Array(e.length).fill(1);return[e,t]},[e]),B=s.useMemo(()=>({hooks:{draw:e=>{!function(e,t,a,n){if(!t)return;const r=e.ctx,{left:s,top:o,width:i,height:l}=e.bbox,c=window.devicePixelRatio||1;if(i<=0||l<=0)return;const d=function(){const e=performance.now();if(Sd&&e-Md<1e3)return Sd;const t=getComputedStyle(document.documentElement);return Sd={stabilityHot:Ld(t.getPropertyValue("--sys-amber").trim()),stabilityCool:Ld(t.getPropertyValue("--sys-blue").trim()),typography:{fontFamily:t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',textMuted:t.getPropertyValue("--text-muted").trim()||"#727272",textSecondary:t.getPropertyValue("--text-secondary").trim()||"#A0A0A0",gridColor:t.getPropertyValue("--chart-grid-line").trim()||"rgba(255,255,255,0.06)"}},Md=e,Sd}();r.clearRect(s,o,i,l),a||function(e,t,a,n,r,s,o){e.save(),e.strokeStyle=o,e.lineWidth=1*s,e.setLineDash([3*s,3*s]);for(const i of[0,.25,.5,.75,1]){const s=Math.round(a+r*i)+.5;e.beginPath(),e.moveTo(t,s),e.lineTo(t+n,s),e.stroke()}e.restore()}(r,s,o,i,l,c,d.typography.gridColor),a||function(e,t,a,n,r,s){const{densityGrid:o,xBins:i,yBins:l,maxDensity:c}=t;if(0===c)return;Bd&&Bd.width===i&&Bd.height===l||(Bd=document.createElement("canvas"),Bd.width=i,Bd.height=l);const d=Bd.getContext("2d"),u=d.createImageData(i,l),h=u.data,m=Math.log1p(c);for(let g=0;go&&(o=a)}const i=(t+o)/2,u=(o-t)/2||.01;for(let h=1;h{const t=p.current,a=f.current;if(!t&&!a||y.current)return;const{left:n,top:r}=e.cursor,s=b.current;if(null==n||null==r||n<0||r<0||!s)return t&&(t.style.display="none"),void(a&&(a.style.display="none"));const o=window.devicePixelRatio||1,i=e.bbox.width/o,l=e.bbox.height/o,c=n/i,d=r/l;if(c<0||c>1||d<0||d>1)return t&&(t.style.display="none"),void(a&&(a.style.display="none"));const u=Math.min(s.xBins-1,Math.max(0,Math.floor(c*s.xBins))),h=Math.min(s.yBins-1,Math.max(0,Math.floor(d*s.yBins))),m=s.densityGrid[u*s.yBins+h],g=s.minTime+(u+.5)/s.xBins*s.timeRange,w=s.yMax-(h+.5)/s.yBins*s.yRange,C=new Date(1e3*g).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});if(a){a.style.display="block";const e=a.children;e[0].style.transform=`translateX(${Math.round(n)}px)`,e[1].style.transform=`translateY(${Math.round(r)}px)`;const t=i/s.xBins,o=l/s.yBins,c=e[2];c.style.left=u*t+"px",c.style.top=h*o+"px",c.style.width=`${t}px`,c.style.height=`${o}px`,c.style.opacity=m>0?"1":"0.5"}if(t){const e=t.children;e[0].textContent=C,e[1].textContent=`${Math.round(w)} dBm`,e[2].textContent=m>0?`${m} sample${1!==m?"s":""}`:"no data";const a=n>i-130,s=r>l-64;t.style.display="block",t.style.left=`${n+(a?-116:12)}px`,t.style.top=`${r+(s?-58:8)}px`}}}}),[]),j=s.useMemo(()=>({width:400,height:200,padding:[0,0,0,0],cursor:n?{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}}:{show:!0,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[B]}),[B,n]);return s.useEffect(()=>{const t=m.current;if(!t||0===e.length)return;g.current&&g.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...j,width:n,height:r},F,t);return g.current=s,()=>{s.destroy(),g.current=null}},[j,F,e.length]),s.useEffect(()=>{const e=m.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!g.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&g.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{g.current&&g.current.redraw()},[A,c,u]),A?n?o.jsx("div",{ref:m,className:"w-full",style:{height:r??28},role:"img","aria-label":"Noise floor sparkline"}):o.jsxs("div",{className:"relative w-full h-full",role:"img","aria-label":`RF noise floor heatmap showing values from ${(null==(i=null==C?void 0:C.min)?void 0:i.toFixed(0))??"N/A"} to ${(null==(l=null==C?void 0:C.max)?void 0:l.toFixed(0))??"N/A"} dBm`,children:[o.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},"aria-hidden":"true",children:E.map((e,t)=>{const a=0===t?"translateY(-100%)":t===E.length-1?"none":"translateY(-50%)";return o.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:a,right:0},children:e.label},t)})}),o.jsxs("div",{ref:m,className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:[o.jsxs("div",{ref:f,className:"absolute inset-0 z-10 pointer-events-none",style:{display:"none"},children:[o.jsx("div",{className:"absolute top-0 bottom-0 w-px bg-subtle-fill-strong"}),o.jsx("div",{className:"absolute left-0 right-0 h-px bg-subtle-fill-strong"}),o.jsx("div",{className:"absolute bg-subtle-fill-strong ring-1 ring-inset ring-edge-strong"})]}),o.jsxs("div",{ref:p,className:"absolute z-20 pointer-events-none radius-inner bg-tooltip-bg px-2.5 py-1.5 shadow-lg",style:{display:"none"},children:[o.jsx("div",{className:"type-data-xs text-fg-muted"}),o.jsx("div",{className:"type-data-xs text-fg-primary"}),o.jsx("div",{className:"type-data-xs text-fg-muted"})]}),o.jsxs("div",{className:"absolute top-1 right-1 z-10 flex items-center gap-1",children:[o.jsx("button",{type:"button",onClick:v,className:"p-1.5 rounded bg-zinc-900/90 hover:bg-zinc-800 active:bg-zinc-700 ring-1 ring-inset ring-zinc-600 transition-colors touch-manipulation",title:u?"Hide LOESS trend line":"Show LOESS trend line","aria-label":u?"Hide trend line":"Show trend line","aria-pressed":u,children:o.jsx(W,{className:"w-3.5 h-3.5 transition-colors "+(u?"text-zinc-100":"text-zinc-400"),"aria-hidden":"true"})}),o.jsx("button",{type:"button",onClick:k,className:"p-1.5 rounded bg-zinc-900/90 hover:bg-zinc-800 active:bg-zinc-700 ring-1 ring-inset ring-zinc-600 transition-colors touch-manipulation",title:c?"Show full range (min/max)":"Show trimmed range (P5-P95)","aria-label":c?"Expand to show full data range":"Shrink to show trimmed percentile range","aria-pressed":!c,children:c?o.jsx(U,{className:"w-3.5 h-3.5 text-zinc-100","aria-hidden":"true"}):o.jsx(V,{className:"w-3.5 h-3.5 text-zinc-100","aria-hidden":"true"})})]})]}),o.jsx("div",{className:"absolute left-0 right-0 bottom-0",style:{left:32,height:20},"aria-hidden":"true",children:x.map((e,t)=>o.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${e.pos}%`,transform:0===t?"none":t===x.length-1?"translateX(-100%)":"translateX(-50%)"},children:e.label},t))})]}):n?o.jsx("div",{className:"w-full rounded bg-subtle/50",style:{height:r??28},"aria-hidden":"true"}):o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No noise floor data available"})});let Rd=null,zd=0;function Pd(){const e=performance.now();if(Rd&&e-zd<1e3)return Rd;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--chart-axis-tick").trim()||(n?"rgba(255, 255, 255, 0.4)":"rgba(0, 0, 0, 0.4)"),s=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)"),o=t.getPropertyValue("--text-muted").trim()||"#727272",i=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),l=t.getPropertyValue("--signal-critical").trim()||"#EF4444",c=t.getPropertyValue("--bg-body").trim()||(n?"#171717":"#F5F5F5");return Rd={fontFamily:a,axisColor:r,gridColor:s,textMuted:o,textPrimary:i,signalCritical:l,bgBody:c},zd=e,Rd}function Id(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}function $d(e){return Id(dd(e))}const qd=s.memo(function({scatterData:e,yAxisMode:t,onHover:a,noiseFloorAnomalies:n=null,showNoiseFloorOverlay:r=!1,overlayOpacity:i=.5,highlightedType:l=null,timeRangeHours:c=24,yAxisMaxOverride:d,dotSize:u=.8,dotOpacity:h=.5,startTs:m,endTs:g,externalAxes:p=!1}){const f=s.useRef(null),b=s.useRef(null),y=s.useRef(e),w=s.useRef(t),C=s.useRef(a),k=s.useRef(n),v=s.useRef(r),A=s.useRef(i),x=s.useRef(l),E=s.useRef(null),F=s.useRef(null),B=c<=12?1.2:1,j=s.useRef(B),S=s.useRef(u),M=s.useRef(h),N=s.useRef(p),L=d??(null==e?void 0:e.maxValue)??("share"===t?200:10),T=s.useRef(L);s.useLayoutEffect(()=>{y.current=e,w.current=t,C.current=a,k.current=n,v.current=r,A.current=i,x.current=l,j.current=B,T.current=L,S.current=u,M.current=h,N.current=p}),s.useEffect(()=>{E.current=Pd()},[]);const _=s.useMemo(()=>{if(!e||0===e.count)return void 0!==m&&void 0!==g?[[m,g],[1,1]]:[[0],[0]];const t=[];for(let n=0;ne-t),void 0!==m&&t[0]>m&&t.unshift(m),void 0!==g&&t[t.length-1]1);return[t,a]},[e,m,g]),R=s.useMemo(()=>({hooks:{draw:e=>{const t=E.current||Pd();!function(e,t,a,n,r,s,o,i,l,c,d,u,h,m=!1){if(!t||0===t.count)return;const g=e.ctx,{left:p,top:f,width:b,height:y}=e.bbox,w=window.devicePixelRatio||1;if(b<=0||y<=0)return;const C=e.data[0],k=C.length;if(0===k)return;const v=C[0],D=C[k-1],A="share"===n,x=function(e,t){if("airtime"===t)return 5;const a=[10,20,25,50,100,200,250,500,1e3],n=e/4.5;for(const r of a)if(r>=n)return r;return e>5e3?1e3*Math.ceil(n/1e3):100*Math.ceil(n/100)}(a,n);if(!A&&a>=20){g.save();const e=f+y*(1-20/a),t=r.signalCritical,n=parseInt(t.slice(1,3),16)||239,s=parseInt(t.slice(3,5),16)||68,o=parseInt(t.slice(5,7),16)||68;g.fillStyle=`rgba(${n}, ${s}, ${o}, 0.025)`,g.fillRect(p,f,b,e-f),g.restore()}g.save(),g.lineWidth=1*w,g.setLineDash([4*w,4*w]);for(let E=x;Ea+r||(e.save(),e.strokeStyle=i.textPrimary,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()))}(g,d,p,f,b,y,w,r),function(e,t,a,n,r,s,o,i,l,c,d){const{points:u,rawValues:h,count:m,packetTypes:g}=t,p=c*i*(window.devicePixelRatio||1),f=2*p;e.globalCompositeOperation="source-over";const b=o?parseInt(o.replace("TYPE_",""),10):null,y=.066*d;for(let w=0;w0&&function(e,t,a,n,r,s,o,i,l,c,d){if(0===t.length)return;const u=i-o||1,h=Id(d.signalCritical);e.save(),e.globalAlpha=c,e.fillStyle=`rgb(${h.r}, ${h.g}, ${h.b})`;for(const m of t){if(m.endTsi)continue;const t=a+(Math.max(m.startTs,o)-o)/u*r,c=a+(Math.min(m.endTs,i)-o)/u*r,d=Math.max(c-t,2*l);e.fillRect(t,n,d,s)}e.restore()}(g,s,p,f,b,y,v,D,w,i,r)}(e,y.current,T.current,w.current,t,k.current,v.current,A.current,x.current,j.current,F.current,S.current,M.current,N.current)}}}),[]),z=s.useMemo(()=>({width:400,height:200,padding:p?[0,0,0,0]:[8,0,8,28],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[R]}),[R]);s.useEffect(()=>{const t=f.current;if(!t||!e||0===e.count)return;b.current&&b.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...z,width:n,height:r},_,t);return b.current=s,()=>{s.destroy(),b.current=null}},[z,_,null==e?void 0:e.count]),s.useEffect(()=>{const e=f.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!b.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&b.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{b.current&&b.current.redraw()},[e,n,r,i,l,B,t,u,h]);const P=s.useCallback(t=>{var a,n;const r=f.current,s=b.current;if(!r||!s||!e||0===e.count)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,c=s.bbox,d=c.left/l,u=c.width/l;if(id+u)return F.current=null,s.redraw(),void(null==(a=C.current)||a.call(C,null,void 0));F.current=i*l;const h=(i-d)/u,m=Math.floor(h*e.count),g=Math.max(0,Math.min(e.count-1,m));s.redraw(),null==(n=C.current)||n.call(C,g,h)},[null==e?void 0:e.count]),I=s.useCallback(()=>{var e;F.current=null,b.current&&b.current.redraw(),null==(e=C.current)||e.call(C,null,void 0)},[]);return e&&0!==e.count?o.jsx("div",{ref:f,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:P,onMouseLeave:I}):o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"})}),Od=new class{constructor(){r(this,"observer",null),r(this,"subscribers",new Set),r(this,"isObserving",!1)}subscribe(e){return this.subscribers.add(e),this.isObserving||this.startObserving(),()=>{this.subscribers.delete(e),0===this.subscribers.size&&this.stopObserving()}}get subscriberCount(){return this.subscribers.size}startObserving(){"undefined"!=typeof window&&(this.isObserving||(this.observer=new MutationObserver(e=>{for(const t of e)if("data-theme"===t.attributeName||"data-color-scheme"===t.attributeName||"class"===t.attributeName){setTimeout(()=>this.notifySubscribers(),50);break}}),this.observer.observe(document.documentElement,{attributes:!0}),this.isObserving=!0))}stopObserving(){this.observer&&(this.observer.disconnect(),this.observer=null),this.isObserving=!1}notifySubscribers(){for(const t of this.subscribers)try{t()}catch(e){console.error("ThemeObserver callback error:",e)}}};function Hd(e){if(!e)return null;const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t)return{r:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[1])))),g:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[2])))),b:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[3]))))};if(e.startsWith("#")){const t=e.replace("#","");if(3===t.length)return{r:parseInt(t[0]+t[0],16),g:parseInt(t[1]+t[1],16),b:parseInt(t[2]+t[2],16)};if(t.length>=6)return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);return a?{r:Math.round(parseFloat(a[1])),g:Math.round(parseFloat(a[2])),b:Math.round(parseFloat(a[3]))}:null}function Wd(e){return"undefined"==typeof window?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()}function Ud(e){return function(e){if(!e)return"";if(e.startsWith("#"))return e;const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t){const e=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[1])))),a=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[2])))),n=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[3]))));return`#${e.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);if(a){const e=Math.round(parseFloat(a[1])),t=Math.round(parseFloat(a[2])),n=Math.round(parseFloat(a[3]));return`#${e.toString(16).padStart(2,"0")}${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}return e}(Wd(e))}function Vd(e,t){const[a,n]=s.useState(t),r=s.useCallback(()=>{n(e())},[e]);return s.useEffect(()=>(r(),Od.subscribe(r)),[r]),a}const Gd={chart1:me.blue,chart2:me.teal,chart3:me.amber,chart4:me.orange,chart5:me.pink,chart6:me.purple,chart7:me.cyan,chart8:ge[500]},Jd={excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red},Kd={primary:"#ffffff",secondary:ge[400],muted:ge[500]},Xd={nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hubColor:me.purple,hubStroke:"rgba(255,255,255,0.9)",gatewayColor:me.indigo,gatewayStroke:"rgba(255,255,255,0.85)",localColor:me.amber,neighborColor:me.amber,neighborStroke:"rgba(0,0,0,0.4)",mobileColor:me.orange,roomColor:me.pink,ghostColor:me.cyan};function Yd(){return"undefined"==typeof window?Gd:{chart1:Wd("--chart-1")||Gd.chart1,chart2:Wd("--chart-2")||Gd.chart2,chart3:Wd("--chart-3")||Gd.chart3,chart4:Wd("--chart-4")||Gd.chart4,chart5:Wd("--chart-5")||Gd.chart5,chart6:Wd("--chart-6")||Gd.chart6,chart7:Wd("--chart-7")||Gd.chart7,chart8:Wd("--chart-8")||Gd.chart8}}function Qd(){return"undefined"==typeof window?Kd:{primary:Wd("--text-primary")||Kd.primary,secondary:Wd("--text-secondary")||Kd.secondary,muted:Wd("--text-muted")||Kd.muted}}function Zd(){return Vd(Yd,Gd)}function eu(){return Vd(Qd,Kd)}function tu(){return"undefined"==typeof window?Xd:{nodeFill:Wd("--map-node-fill")||Xd.nodeFill,nodeStroke:Wd("--map-node-stroke")||Xd.nodeStroke,hubColor:Wd("--map-hub-color")||Xd.hubColor,hubStroke:Wd("--map-hub-stroke")||Xd.hubStroke,gatewayColor:Wd("--map-gateway-color")||Xd.gatewayColor,gatewayStroke:Wd("--map-gateway-stroke")||Xd.gatewayStroke,localColor:Wd("--map-local-color")||Xd.localColor,neighborColor:Wd("--map-neighbor-color")||Xd.neighborColor,neighborStroke:Wd("--map-neighbor-stroke")||Xd.neighborStroke,mobileColor:Wd("--map-mobile-color")||Xd.mobileColor,roomColor:Wd("--map-room-color")||Xd.roomColor,ghostColor:Wd("--map-ghost-color")||Xd.ghostColor}}function au(){return Vd(tu,Xd)}const nu={nodeStroke:"rgba(0,0,0,0.6)",hubStroke:"rgba(0,0,0,0.5)",gatewayStroke:"rgba(0,0,0,0.45)",neighborStroke:"rgba(0,0,0,0.5)"},ru={nodeStroke:"rgba(255,255,255,0.9)",hubStroke:"rgba(255,255,255,0.9)",gatewayStroke:"rgba(255,255,255,0.85)",neighborStroke:"rgba(0,0,0,0.4)"};function su(e){if("undefined"==typeof window)return Xd;const t="light"===function(){if("undefined"==typeof window)return"dark";const e=document.querySelector("[data-basemap]");return e&&e.getAttribute("data-basemap")||"dark"}()?nu:ru;return{nodeFill:Ud("--map-node-fill")||Xd.nodeFill,nodeStroke:t.nodeStroke,hubColor:Ud("--map-hub-color")||Xd.hubColor,hubStroke:t.hubStroke,gatewayColor:Ud("--map-gateway-color")||Xd.gatewayColor,gatewayStroke:t.gatewayStroke,localColor:Ud("--map-local-color")||Xd.localColor,neighborColor:Ud("--map-neighbor-color")||Xd.neighborColor,neighborStroke:t.neighborStroke,mobileColor:Ud("--map-mobile-color")||Xd.mobileColor,roomColor:Ud("--map-room-color")||Xd.roomColor,ghostColor:Ud("--map-ghost-color")||Xd.ghostColor}}const ou={rest:"rgba(255, 255, 255, 0.25)",restBright:"rgba(255, 255, 255, 0.35)",restDim:"rgba(255, 255, 255, 0.15)",hoverDirect:me.cyan,hoverLoop:me.purple,hoverStandard:ge[400],hoverNeighbor:me.amber,highlight:"#FFD700"},iu={rest:"rgba(0, 0, 0, 0.20)",restBright:"rgba(0, 0, 0, 0.30)",restDim:"rgba(0, 0, 0, 0.12)"},lu={rest:"rgba(255, 255, 255, 0.25)",restBright:"rgba(255, 255, 255, 0.35)",restDim:"rgba(255, 255, 255, 0.15)"};function cu(e){if("undefined"==typeof window)return ou;const t="light"===e?iu:lu;return{rest:t.rest,restBright:t.restBright,restDim:t.restDim,hoverDirect:Ud("--map-edge-hover-direct")||ou.hoverDirect,hoverLoop:Ud("--map-edge-hover-loop")||ou.hoverLoop,hoverStandard:Ud("--map-edge-hover-standard")||ou.hoverStandard,hoverNeighbor:Ud("--map-edge-hover-neighbor")||ou.hoverNeighbor,highlight:Ud("--map-edge-highlight")||ou.highlight}}const du={grid:"rgba(191, 191, 191, 0.15)",axisTick:ge[400],cursor:"rgba(255, 255, 255, 0.2)"};function uu(){return"undefined"==typeof window?du:{grid:Wd("--chart-grid")||du.grid,axisTick:Wd("--chart-axis-tick")||du.axisTick,cursor:Wd("--chart-cursor")||du.cursor}}function hu(){return Vd(uu,du)}function mu(e,t){return Wd(`--palette-${e}-${t}`)||""}function gu(){const e=[];for(let t=0;t<24;t++){const a=t/23,n=1-a,r=mu("aqua",[900,800,700,600,500,400,300,200,100,50][Math.min(8,Math.floor(9*n))]),s=parseInt(r.slice(1,3),16)||0,o=parseInt(r.slice(3,5),16)||0,i=parseInt(r.slice(5,7),16)||0,l=Math.round(80+130*a);e.push([s,o,i,l])}return e}function pu(){const e=Wd("--signal-excellent")||Jd.excellent,t=Wd("--signal-good")||Jd.good,a=Wd("--signal-fair")||Jd.fair,n=Wd("--signal-poor")||Jd.poor,r=Wd("--signal-critical")||Jd.critical,s=[];for(let o=0;o<24;o++){let i;i=o<5?e:o<10?t:o<15?a:o<20?n:r,s.push(i)}return s}function fu(){const e=Ud("--signal-excellent")||Jd.excellent,t=Ud("--signal-good")||Jd.good,a=Ud("--signal-fair")||Jd.fair,n=Ud("--signal-poor")||Jd.poor,r=Ud("--signal-critical")||Jd.critical,s=[];for(let o=0;o<24;o++){let i;i=o<5?e:o<10?t:o<15?a:o<20?n:r,s.push(i)}return s}function bu(){const[e,t]=s.useState(()=>pu());return s.useEffect(()=>{const e=()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t(pu())})})};return e(),Od.subscribe(e)},[]),e}function yu(e,t){const a=e-Kl(t??7),n=(Math.max(-6,Math.min(9,a))- -6)/15;return Math.round(23*(1-n))}const wu={...me};function Cu(){return"undefined"==typeof window?wu:{red:Ud("--sys-red")||wu.red,orange:Ud("--sys-orange")||wu.orange,amber:Ud("--sys-amber")||wu.amber,yellow:Ud("--sys-yellow")||wu.yellow,brown:Ud("--sys-brown")||wu.brown,green:Ud("--sys-green")||wu.green,teal:Ud("--sys-teal")||wu.teal,cyan:Ud("--sys-cyan")||wu.cyan,blue:Ud("--sys-blue")||wu.blue,indigo:Ud("--sys-indigo")||wu.indigo,purple:Ud("--sys-purple")||wu.purple,pink:Ud("--sys-pink")||wu.pink}}function ku(){const e=s.useCallback(()=>"undefined"==typeof document||"light"!==document.documentElement.dataset.mode,[]),[t,a]=s.useState(e);return s.useEffect(()=>(a(e()),Od.subscribe(()=>a(e()))),[e]),t}function vu(){return"undefined"==typeof document||"light"!==document.documentElement.dataset.mode}let Du=null,Au=0;function xu(){const e=performance.now();if(Du&&e-Au<1e3)return Du;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),s=t.getPropertyValue("--text-secondary").trim()||(n?"#BFBFBF":"#4A4A4A"),o=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)");return Du={fontFamily:a,textPrimary:r,textSecondary:s,gridColor:o},Au=e,Du}function Eu(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}let Fu=null,Bu=0;function ju(e,t){return"airtime"===t?`${e}%`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(0)}K`:`${e}`}function Su(e,t,a,n,r,s,o,i,l,c,d,u=.9,h=!1,m,g){if(0===t.length)return;const p=m??t[0].timestamp,f=(g??t[t.length-1].timestamp)-p||1;if(e.save(),e.strokeStyle=`rgba(${n.r}, ${n.g}, ${n.b}, ${u})`,e.lineWidth=d*c,e.lineCap="round",e.lineJoin="round",h){e.beginPath();let n=!1,c=0,d=0;for(let u=0;u{u.current=e,h.current=t,m.current=a,g.current=n,b.current=r,y.current=i,w.current=l}),s.useEffect(()=>{p.current=xu()},[]);const C=s.useMemo(()=>0===e.length?[[0],[0]]:[e.map(e=>e.timestamp),e.map(()=>1)],[e]),k=s.useMemo(()=>({hooks:{draw:e=>{const t=p.current||xu();!function(e,t,a,n,r,s,o,i,l=!1){if(0===t.length)return;const c=e.ctx,{left:d,top:u,width:h,height:m}=e.bbox,g=window.devicePixelRatio||1;if(h<=0||m<=0)return;const p=function(){const e=performance.now();return Fu&&e-Bu<1e3||(Fu=Cu(),Bu=e),Fu}(),f=Eu(p.blue),b=Eu(p.red),y=Eu(p.yellow),w=(C=a,"airtime"===n?C<=5?1:C<=10?2:C<=20?5:Math.ceil(C/5):C<=100?25:C<=500?100:C<=1e3?200:C<=5e3?1e3:C<=1e4?2e3:1e3*Math.ceil(C/5e3));var C;c.save(),c.strokeStyle=r.textSecondary,c.globalAlpha=.3,c.lineWidth=1*g,c.setLineDash([3*g,3*g]);for(let k=w;ka+r||(e.save(),e.strokeStyle=i.textPrimary,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()))}(c,s,d,u,h,m,g,r),Su(c,t,"rxSmooth",y,d,u,h,m,a,g,2,1,!0,o,i),Su(c,t,"tx",b,d,u,h,m,a,g,2.5,.9,!1,o,i),Su(c,t,"rx",f,d,u,h,m,a,g,2.5,.9,!1,o,i)}(e,u.current,m.current,h.current,t,f.current,b.current,y.current,w.current)}}}),[]),v=s.useMemo(()=>({width:400,height:200,padding:l?[0,0,0,0]:[8,8,8,44],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0,range:(e,t,a)=>[b.current??t,y.current??a]},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[k]}),[k]);s.useEffect(()=>{const t=c.current;if(!t||0===e.length)return;d.current&&d.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...v,width:n,height:r},C,t);return d.current=s,()=>{s.destroy(),d.current=null}},[v,C,e.length]),s.useEffect(()=>{const e=c.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!d.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&d.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{d.current&&d.current.redraw()},[e,a,t]);const A=s.useCallback(t=>{var a,n;const r=c.current,s=d.current;if(!r||!s||0===e.length)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,u=s.bbox,h=u.left/l,m=u.width/l;if(ih+m)return f.current=null,s.redraw(),void(null==(a=g.current)||a.call(g,null));f.current=i*l;const p=(i-h)/m,b=Math.floor(p*e.length),y=Math.max(0,Math.min(e.length-1,b));s.redraw(),null==(n=g.current)||n.call(g,y)},[e.length]),x=s.useCallback(()=>{var e;f.current=null,d.current&&d.current.redraw(),null==(e=g.current)||e.call(g,null)},[]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:c,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:A,onMouseLeave:x})}),Nu=s.memo(function({className:e}){const{theme:t,setTheme:a}=tt(),n="breeze dark"===t.themeId,r=s.useCallback(()=>{a(n?"breeze light":"breeze dark")},[n,a]);return o.jsx("button",{onClick:r,"aria-label":n?"Switch to light mode":"Switch to dark mode",title:n?"Switch to light mode":"Switch to dark mode",className:E("flex items-center justify-center rounded-md p-1.5","hover:bg-zinc-500/20","transition-colors duration-150",e),children:n?o.jsx(G,{className:"w-3.5 h-3.5 text-sys-amber"}):o.jsx(J,{className:"w-3.5 h-3.5 text-sys-blue"})})}),Lu=[{name:"Dashboard",to:"/",icon:K},{name:"Contacts",to:"/contacts",icon:X},{name:"Statistics",to:"/statistics",icon:Y},{name:"Packets",to:"/packets",icon:Q},{name:"Terminal",to:"/terminal",icon:Z},{name:"Room Server",to:"/room-server",icon:ee},{name:"MeshGraph",to:"/meshgraph",icon:te},{name:"System",to:"/system",icon:ae},{name:"Logs",to:"/logs",icon:ne},{name:"Configuration",to:"/configuration",icon:re}];function Tu(){var e,t,a,n,r,i;const{pathname:l}=B(),c=j(),{stats:d,setMode:u,setDutyCycle:h,sendAdvert:m}=fl(),g=cn(),p=Fl(),f=Nl(),b=Pl(),y=Rl(),w=Nc(),C=Or(),k=Rr(e=>e.topology.nodeMetrics.size),v=Oc(e=>e.unreadCount),D=wl(),A=s.useMemo(()=>{const e=Date.now()/1e3-60*bi[y].minutes;return D.filter(t=>t.timestamp>=e).length},[D,y]);let x=null;try{x=function(){const e=s.useContext(oa);if(!e)throw new Error("useSidebar must be used within a SidebarLayout");return e}()}catch{}const[F,S]=s.useState(!1),[M,N]=s.useState("idle"),[L,T]=s.useState(null),[_,R]=s.useState(!1),[z,P]=s.useState(null),I=fc(bi[y].minutes/60);s.useEffect(()=>{let e=!1;const t=async()=>{try{const t=await Zs();!e&&t.success&&t.data&&P(t.data.total_clients)}catch{}};t();const a=setInterval(t,3e4);return()=>{e=!0,clearInterval(a)}},[]);const $=s.useRef(null),q=s.useCallback(e=>{e!==l&&($.current&&clearTimeout($.current),$.current=setTimeout(()=>{p(e)},100))},[l,p]),H=s.useCallback(()=>{$.current&&(clearTimeout($.current),$.current=null)},[]),W=null==d?void 0:d.noise_floor_dbm,U=(null==(t=null==(e=null==d?void 0:d.config)?void 0:e.repeater)?void 0:t.mode)??"forward",V=(null==(n=null==(a=null==d?void 0:d.config)?void 0:a.duty_cycle)?void 0:n.enforcement_enabled)??!1,G=V?(null==(i=null==(r=null==d?void 0:d.config)?void 0:r.duty_cycle)?void 0:i.max_airtime_percent)??10:100,J=f.isLoading||f.isBackgroundLoading||f.isTopologyLoading,K=J||w||C,X=f.loadProgress,Y=s.useCallback((e,t)=>{e.preventDefault(),null==x||x.close(),c(t)},[c,x]);return o.jsxs(Qt,{children:[o.jsxs(Zt,{className:"px-5 pt-3 pb-4 border-b-0",children:[o.jsx("h1",{className:"sr-only",children:"pyMC Console"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Oa,{responsive:!0,className:"block flex-1"}),o.jsx(vc,{rotated:!0})]}),o.jsxs("div",{className:"flex items-center gap-1.5 mt-1.5",children:[o.jsxs("span",{className:"inline-flex px-1.5 py-0.5 rounded text-[10px] font-medium tabular-nums font-mono bg-surface text-fg-muted",children:["v",$a]}),o.jsx(Nu,{})]})]}),o.jsxs(ea,{className:"pt-[13px] pb-0",children:[o.jsx(aa,{children:Lu.map(e=>{const t=l===e.to,a="/terminal"===e.to,n="#6545EE";return o.jsxs(na,{href:e.to,current:t,accentColor:a?n:void 0,onClick:t=>Y(t,e.to),onMouseEnter:()=>q(e.to),onMouseLeave:H,children:[o.jsxs("span",{className:"relative",children:[o.jsx(e.icon,{className:E("size-4",t&&!a&&"text-sys-blue"),style:t&&a?{color:n}:void 0}),"/room-server"===e.to&&v>0&&o.jsx("span",{className:"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sys-red ring-2 ring-body"})]}),o.jsx(ra,{children:e.name}),"/contacts"===e.to&&k>0&&o.jsx(sa,{variant:"accent",children:o.jsx("span",{children:k})}),"/packets"===e.to&&A>0&&o.jsx(sa,{variant:"default",children:o.jsx("span",{children:A>=1e4?`${(A/1e3).toFixed(1)}k`:A.toLocaleString()})}),"/meshgraph"===e.to&&o.jsx(sa,{variant:"default",children:"Beta"})]},e.name)})}),K&&o.jsx("div",{className:"px-0 py-3",children:o.jsx(Fc,{isLoading:J,borderRadius:12,children:o.jsxs("div",{className:"bg-surface/50 rounded-xl px-2 py-3",children:[o.jsxs("div",{className:"flex items-center gap-2 px-1 py-0.5",children:[o.jsxs("div",{className:"relative flex h-2 w-2",children:[o.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-sys-blue opacity-75"}),o.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-sys-blue"})]}),o.jsx("span",{className:"type-data-xs text-fg-secondary flex-1 truncate",children:f.isLoading&&X?"Loading 24h history...":f.isBackgroundLoading&&X?f.statusMessage||`Loading ${b} history...`:f.isTopologyLoading?"Loading topology data...":w?"Computing sparklines":C?"Building topology":"Analyzing database"}),null!==(null==X?void 0:X.percent)&&void 0!==(null==X?void 0:X.percent)&&J&&o.jsxs("span",{className:"type-data-xs text-fg-secondary tabular-nums",children:[X.percent,"%"]})]}),o.jsx("div",{className:"mx-1 mt-2 h-2 bg-subtle-fill rounded-full overflow-hidden sparkle-bar-track",children:null!==(null==X?void 0:X.percent)&&void 0!==(null==X?void 0:X.percent)&&J?o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full transition-all duration-300 ease-out overflow-hidden",style:{width:`${X.percent}%`},children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]}):o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full w-full overflow-hidden",children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]})}),o.jsxs("div",{className:"mt-2 flex items-center gap-1.5 px-1",children:[o.jsxs("span",{className:"type-data-xs text-fg-muted tabular-nums",children:[J&&(null==X?void 0:X.loaded)?X.loaded>=1e3?`${(X.loaded/1e3).toFixed(1)}k`:X.loaded.toLocaleString():f.packetCount>=1e3?`${(f.packetCount/1e3).toFixed(1)}k`:f.packetCount.toLocaleString()," pkts"]}),!J&&o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"text-fg-muted/30",children:"·"}),o.jsx("span",{className:"type-data-xs text-sys-blue",children:(e=>{switch(e){case"24h":return"24 hours";case"3d":return"3 days";case"7d":return"7 days";case"14d":return"14 days";default:return e}})(b)})]})]})]})})}),o.jsx("div",{className:"flex-1"}),void 0!==(null==d?void 0:d.uptime_seconds)&&o.jsx("div",{className:"mb-1",children:o.jsxs("div",{className:"flex items-center justify-center px-3 py-1 rounded-full text-sys-blue bg-sys-blue/10 font-mono text-[10px] tracking-wider tabular-nums",children:[Yc(d.uptime_seconds)," uptime"]})}),o.jsx(Fa,{label:"Controls",icon:o.jsx(le,{className:"w-5 h-5 text-sys-blue"}),defaultOpen:!1,direction:"up",dataId:"controls",children:o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx(Mt,{color:"success"===M?"success":"error"===M?"danger":"primary",onClick:async()=>{S(!0),N("idle"),T(null);const e=await m();S(!1),e.success?(N("success"),setTimeout(()=>N("idle"),1500)):(N("error"),T(e.error||"Failed to send"),setTimeout(()=>{N("idle"),T(null)},3e3))},disabled:F,className:"w-full justify-center",children:F?o.jsxs(o.Fragment,{children:[o.jsxs("svg",{"data-slot":"icon",className:"animate-spin",viewBox:"0 0 24 24",fill:"none",children:[o.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3"}),o.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]}),"Sending..."]}):"success"===M?o.jsxs(o.Fragment,{children:[o.jsx("svg",{"data-slot":"icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:o.jsx("polyline",{points:"20 6 9 17 4 12"})}),"Sent!"]}):"error"===M?o.jsxs(o.Fragment,{children:[o.jsxs("svg",{"data-slot":"icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[o.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),o.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),"Failed"]}):o.jsxs(o.Fragment,{children:[o.jsx(se,{"data-slot":"icon"}),"Send Advert"]})}),L&&o.jsx("p",{className:"text-sys-red text-xs text-center",children:L}),o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"text-xs text-fg-muted",children:"Repeat"}),o.jsx("span",{className:E("text-xs font-medium","forward"===U?"text-sys-green":"text-sys-indigo"),children:"forward"===U?"ON":"OFF"})]}),o.jsx(Mt,{color:"forward"===U?"success":"warning",onClick:()=>{u("forward"===U?"monitor":"forward")},className:"w-full justify-center",children:"forward"===U?o.jsxs(o.Fragment,{children:[o.jsx(oe,{"data-slot":"icon"}),"Repeating"]}):o.jsxs(o.Fragment,{children:[o.jsx(ie,{"data-slot":"icon"}),"Monitor Only"]})}),o.jsxs("div",{className:"flex items-center justify-between gap-2 mt-1",children:[o.jsx("span",{className:"text-xs text-fg-muted",children:"Duty Cycle"}),o.jsx("span",{className:E("text-xs font-medium tabular-nums",V?"text-sys-indigo":"text-fg-muted"),children:V?`${G}%`:"100%"})]}),o.jsxs(Mt,{color:V?"warning":"muted",onClick:()=>{h(!V)},className:"w-full justify-center",children:[o.jsx(ae,{"data-slot":"icon"}),V?`Limited to ${G}%`:"No Limit"]})]})})]}),o.jsx(ta,{children:o.jsxs("div",{className:"px-3 pt-0.5 pb-3 flex flex-col",children:[o.jsxs("button",{onClick:e=>{e.preventDefault(),null==x||x.close(),c("/sessions")},className:E("group w-full flex items-center gap-3 px-3 py-2 rounded-none bg-surface depth-stroke-raised","hover:bg-elevated hover:text-fg-primary transition-colors","/sessions"===l&&"bg-sys-blue/10"),children:[o.jsx(ce,{className:"w-5 h-5 text-sys-blue flex-shrink-0"}),o.jsx("span",{className:"type-micro text-fg-muted",children:"Sessions"}),o.jsx("span",{className:"ml-auto data-box",children:null!==z?z:"—"})]}),o.jsxs("div",{className:"mt-0.5 rounded-none bg-surface depth-stroke-raised py-2",children:[o.jsxs("div",{className:"flex items-center gap-3 px-3",children:[o.jsx(de,{className:"w-5 h-5 text-sys-blue flex-shrink-0"}),o.jsx("span",{className:"type-micro text-fg-muted flex-1",children:"Noise Floor"}),o.jsx("span",{className:"data-box",children:null!=W?`${W.toFixed(0)} dBm`:"—"})]}),I.length>0&&o.jsx("div",{className:"mt-2.5 px-2",children:o.jsx("div",{className:"relative radius-inner depth-stroke-inset overflow-hidden py-1.5",style:{backgroundColor:"var(--sparkline-bg)"},children:o.jsx(_d,{timestamps:I.map(e=>e.timestamp),values:I.map(e=>e.noise_floor_dbm),compact:!0,height:28})})})]}),(null==d?void 0:d.version)&&o.jsxs("button",{onClick:()=>{navigator.clipboard.writeText(`pyMC_Repeater v${d.version}`),R(!0),setTimeout(()=>R(!1),2e3)},title:`pyMC_Repeater v${d.version} — Click to copy`,className:"mt-0.5 group w-full rounded-none rounded-b-lg bg-surface depth-stroke-raised px-3 py-2 text-left hover:bg-elevated hover:text-fg-primary transition-colors flex items-center gap-2",children:[o.jsxs("span",{className:"type-data-xs text-fg-muted truncate flex-1",children:["pyMC_Repeater v",d.version]}),_?o.jsx(O,{className:"w-3 h-3 text-sys-green flex-shrink-0"}):o.jsx(ue,{className:"w-3 h-3 text-fg-muted opacity-40 group-hover:opacity-70 transition-opacity flex-shrink-0"})]}),o.jsxs("button",{onClick:()=>{an(),window.location.href="/login"},className:"mt-1 group w-full flex items-center gap-3 px-3 py-3.5 radius-inset bg-sys-red/10 text-fg-muted hover:bg-sys-red hover:text-body hover:shadow-none transition-all duration-150",style:{boxShadow:"inset 0 0 0 2px color-mix(in srgb, var(--sys-red) 20%, transparent)"},children:[o.jsx(he,{className:"w-5 h-5 flex-shrink-0"}),o.jsx("span",{className:"type-body-sm !text-inherit",children:"Sign Out"}),g&&o.jsxs("span",{className:"ml-auto type-data-xs !text-inherit",children:["(",g,")"]})]})]})})]})}function _u(){const e=Nl(),t=e.isLoading||e.isBackgroundLoading||e.isTopologyLoading;return o.jsxs(da,{children:[o.jsxs(ua,{children:[o.jsx("h1",{className:"sr-only",children:"pyMC Console"}),o.jsx(Oa,{height:26,className:"block"}),t&&o.jsx(Bc,{className:"ml-2"})]}),o.jsx(ha,{}),o.jsxs(ua,{children:[o.jsx(Nu,{}),o.jsxs("p",{className:"type-data-xs text-fg-muted",children:["v",$a]}),o.jsx(vc,{})]})]})}const Ru=s.memo(function(){const{theme:e}=tt(),{themeId:t,brightness:a}=e,n=Ee(t),r=null==n?void 0:n.meta.backgroundImage,s=null==n?void 0:n.meta.backgroundColor,i=(100-a)/100;return o.jsxs(o.Fragment,{children:[r?o.jsx("div",{className:"fixed inset-0 -z-20",style:{contain:"paint"},"aria-hidden":"true",children:o.jsx("div",{className:"absolute inset-0 bg-cover bg-center bg-no-repeat transition-opacity duration-300 ease-out",style:{backgroundImage:`url(${r})`}})}):s?o.jsx("div",{className:"fixed inset-0 -z-20 transition-colors duration-300 ease-out",style:{backgroundColor:s,contain:"paint"},"aria-hidden":"true"}):null,o.jsx("div",{className:"fixed inset-0 -z-10 bg-black pointer-events-none transition-opacity duration-200 ease-out",style:{opacity:i,contain:"paint"},"aria-hidden":"true"})]})}),zu=20,Pu=12,Iu=s.createContext(null);function $u({children:e}){const[t,a]=s.useState({content:null,mouseX:0,mouseY:0,visible:!1}),n=s.useRef(null),[r,i]=s.useState({x:0,y:0}),l=s.useCallback((e,t,n)=>{a({content:e,mouseX:t,mouseY:n,visible:!0})},[]),c=s.useCallback(()=>{a(e=>({...e,visible:!1}))},[]),d=s.useCallback((e,t)=>{a(a=>a.visible?{...a,mouseX:e,mouseY:t}:a)},[]);s.useEffect(()=>{if(!t.visible||!n.current)return;const e=n.current.getBoundingClientRect(),{mouseX:a,mouseY:r}=t,s=window.innerWidth,o=window.innerHeight;let l,c;l=a+zu+e.width+Pu>s?a-zu-e.width:a+zu,l=Math.max(Pu,Math.min(l,s-e.width-Pu)),c=r-zu-e.height{c.current&&(clearTimeout(c.current),c.current=null)},h=s.useCallback(t=>{u(),c.current=setTimeout(()=>{d.current=!0,n(e,t.clientX,t.clientY)},a)},[n,e,a]),m=s.useCallback(e=>{d.current&&i(e.clientX,e.clientY)},[i]),g=s.useCallback(()=>{u(),d.current=!1,r()},[r]),p=s.useCallback(()=>{if(u(),!l.current)return;const t=l.current.getBoundingClientRect();c.current=setTimeout(()=>{d.current=!0,n(e,t.left+t.width/2,t.top)},a)},[n,e,a]),f=s.useCallback(()=>{u(),d.current=!1,r()},[r]);return s.useEffect(()=>()=>{u(),d.current&&(d.current=!1,r())},[r]),s.useEffect(()=>{const e=()=>{d.current&&(u(),d.current=!1,r())};return document.addEventListener("click",e,!0),()=>document.removeEventListener("click",e,!0)},[r]),o.jsx("span",{ref:l,onMouseEnter:h,onMouseMove:m,onMouseLeave:g,onFocus:p,onBlur:f,className:"contents",children:t})}async function Ou(e,t){const a=`${e}`;ln()&&await un();const n=en(),r=n?{Authorization:`Bearer ${n}`}:{},s=await fetch(a,{...t,headers:{...r,...null==t?void 0:t.headers}});if(!s.ok)throw new Error(`Analytics API error: ${s.status} ${s.statusText}`);return s.json()}async function Hu(e=!1){return Ou("/api/analytics/topology"+(e?"?rebuild=true":""))}let Wu=[];function Uu({label:e}){return o.jsx("div",{className:"min-h-[50vh]","aria-label":`Loading ${e}`,"aria-busy":"true"})}function Vu(){return o.jsx(Uu,{label:"dashboard"})}function Gu(){return o.jsx(Uu,{label:"list"})}function Ju(){return o.jsx(Uu,{label:"map"})}function Ku(){return o.jsx(Uu,{label:"charts"})}function Xu(){return o.jsx(Uu,{label:"settings"})}function Yu(){return o.jsx(Uu,{label:"system"})}function Qu({children:e}){return o.jsx(o.Fragment,{children:e})}F((e,t)=>({backendAvailable:null,checkingBackend:!1,topology:null,topologyLoading:!1,topologyError:null,topologyLastUpdated:0,disambiguationStats:null,disambiguationLoading:!1,lastHopNeighbors:null,neighborsLoading:!1,neighborAffinity:null,affinityLoading:!1,mobileNodes:null,mobileLoading:!1,pathHealth:null,pathHealthLoading:!1,txRecommendation:null,txRecommendationLoading:!1,sparklines:new Map,sparklinesLoading:!1,sparklineHours:168,bucketedStats:null,bucketedStatsPreset:"1h",bucketedStatsLoading:!1,checkBackendAvailability:async()=>{e({checkingBackend:!0});try{const t=await Hu(),a=!1!==t.success&&!t.error;return e({backendAvailable:a,checkingBackend:!1}),a}catch{return e({backendAvailable:!1,checkingBackend:!1}),!1}},fetchTopology:async(t=!1)=>{e({topologyLoading:!0,topologyError:null});try{const a=await Hu(t);if(!1===a.success)return void e({topologyError:a.error||"Failed to fetch topology",topologyLoading:!1});e({topology:a||a,topologyLoading:!1,topologyLastUpdated:Date.now()})}catch(a){e({topologyError:a instanceof Error?a.message:"Failed to fetch topology",topologyLoading:!1})}},fetchDisambiguationStats:async()=>{e({disambiguationLoading:!0});try{const t=await async function(){return Ou("/api/analytics/disambiguation")}();!1!==t.success?e({disambiguationStats:t,disambiguationLoading:!1}):e({disambiguationLoading:!1})}catch{e({disambiguationLoading:!1})}},fetchLastHopNeighbors:async(t=168)=>{e({neighborsLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/last_hop_neighbors?hours=${e}`)}(t);!1!==a.success?e({lastHopNeighbors:a,neighborsLoading:!1}):e({neighborsLoading:!1})}catch{e({neighborsLoading:!1})}},fetchNeighborAffinity:async(t=168)=>{e({affinityLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/neighbor_affinity?hours=${e}`)}(t);!1!==a.success?e({neighborAffinity:a,affinityLoading:!1}):e({affinityLoading:!1})}catch{e({affinityLoading:!1})}},fetchMobileNodes:async(t=168)=>{e({mobileLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/mobile_nodes?hours=${e}`)}(t);!1!==a.success?e({mobileNodes:a,mobileLoading:!1}):e({mobileLoading:!1})}catch{e({mobileLoading:!1})}},fetchPathHealth:async(t=20)=>{e({pathHealthLoading:!0});try{const a=await async function(e=20){return Ou(`/api/analytics/path_health?limit=${e}`)}(t);!1!==a.success?e({pathHealth:a.paths??[],pathHealthLoading:!1}):e({pathHealthLoading:!1})}catch{e({pathHealthLoading:!1})}},fetchTxRecommendation:async(t=24)=>{e({txRecommendationLoading:!0});try{const a=await async function(e=24){return Ou(`/api/analytics/tx_recommendations?hours=${e}`)}(t);!1!==a.success?e({txRecommendation:a,txRecommendationLoading:!1}):e({txRecommendationLoading:!1})}catch{e({txRecommendationLoading:!1})}},fetchSparklines:async(t=168)=>{e({sparklinesLoading:!0,sparklineHours:t});try{const a=await async function(e=168){return Ou(`/api/analytics/sparklines?hours=${e}`)}(t);if(!1!==a.success){const t=a,n=new Map;if(t.sparklines)for(const[e,a]of Object.entries(t.sparklines))n.set(e,a);e({sparklines:n,sparklinesLoading:!1})}else e({sparklinesLoading:!1})}catch{e({sparklinesLoading:!1})}},fetchBucketedStats:async t=>{e({bucketedStatsLoading:!0,bucketedStatsPreset:t});try{const a=await async function(e){return Ou(`/api/analytics/bucketed_stats?preset=${e}`)}(t);!1!==a.success?e({bucketedStats:a,bucketedStatsLoading:!1}):e({bucketedStatsLoading:!1})}catch{e({bucketedStatsLoading:!1})}},initialize:async()=>{if(await t().checkBackendAvailability()&&(await Promise.all([t().fetchTopology(),t().fetchDisambiguationStats(),t().fetchLastHopNeighbors(),t().fetchMobileNodes(),t().fetchPathHealth(),t().fetchSparklines(),t().fetchBucketedStats("1h")]),"undefined"!=typeof window)){const e=setInterval(()=>{t().backendAvailable&&t().fetchTopology()},6e4),a=setInterval(()=>{t().backendAvailable&&t().fetchLastHopNeighbors()},3e4),n=setInterval(()=>{t().backendAvailable&&t().fetchBucketedStats(t().bucketedStatsPreset)},3e4);Wu=[e,a,n]}},refreshAll:async()=>{const{backendAvailable:e}=t();e&&await Promise.all([t().fetchTopology(!0),t().fetchDisambiguationStats(),t().fetchLastHopNeighbors(),t().fetchNeighborAffinity(),t().fetchMobileNodes(),t().fetchPathHealth(),t().fetchTxRecommendation(),t().fetchSparklines(),t().fetchBucketedStats(t().bucketedStatsPreset)])}}));const Zu=s.lazy(()=>A(()=>import("./Login-AaBhF2Vi.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11]))),eh=s.lazy(()=>A(()=>import("./Dashboard-CyVZY-Lj.js"),__vite__mapDeps([12,1,2,3,13,4,14,6,8,7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,9,10,11]))),th=s.lazy(()=>A(()=>import("./Packets-BgwWZIr7.js"),__vite__mapDeps([34,1,2,3,4,8,18,19,20,14,21,22,23,24,16,25,26,6,27,35,13,28,33,7,9,10,11]))),ah=s.lazy(()=>A(()=>import("./Contacts-Dlk8XXyy.js").then(e=>e.C),__vite__mapDeps([36,1,2,3,4,37,16,13,38,8,6,28,14,22,23,39,40,26,21,41,42]))),nh=s.lazy(()=>A(()=>import("./Statistics-CvVaUNEa.js"),__vite__mapDeps([43,1,2,3,4,8,14,44,6,28,13,26,15,39,40,29,35,16,24,25,33,7,9,42,10,11]))),rh=s.lazy(()=>A(()=>import("./MeshGraph-DIhPFkau.js"),__vite__mapDeps([45,1,2,3,14,46,25,4,6,8,26,21,17,7,9,10,11]))),sh=s.lazy(()=>A(()=>import("./System-ClKsjWUq.js"),__vite__mapDeps([47,1,2,3,4,13,7,8,33,6,9,10,11]))),oh=s.lazy(()=>A(()=>import("./Logs-0I5VPDkH.js"),__vite__mapDeps([48,1,2,3,4,13,8,6,7,9,10,11]))),ih=s.lazy(()=>A(()=>import("./Terminal-Bhtd_bQn.js"),__vite__mapDeps([49,1,2,3,4,50,25,37,20,51,5,13,52,53,8,6,7,9,54,10,11]))),lh=s.lazy(()=>A(()=>import("./Configuration-BqjgQq_Y.js"),__vite__mapDeps([55,1,2,3,4,51,41,8,31,13,26,53,33,7,6,9,10,11]))),ch=s.lazy(()=>A(()=>import("./RoomServer-COraO77j.js"),__vite__mapDeps([56,1,2,3,13,4,33,16,8,38,6,52,53,41,32,22,7,9,10,11]))),dh=s.lazy(()=>A(()=>import("./PacketObservatory-ChFmVrLE.js"),__vite__mapDeps([57,1,2,3,24,16,25,4,19,20,7,6,8,9,10,11]))),uh=s.lazy(()=>A(()=>import("./Sessions-C8xhZKXf.js"),__vite__mapDeps([58,1,2,3,4,41,8,26,13,33,7,6,9,10,11])));function hh({children:e}){const t=B(),a=j();return s.useEffect(()=>(Ha=a,()=>{Ha=null}),[a]),nn()?o.jsx(o.Fragment,{children:e}):o.jsx(N,{to:"/login",state:{from:t},replace:!0})}class mh extends s.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var e;return this.state.hasError?o.jsxs("div",{className:"surface-base rounded-2xl p-8 text-center",children:[o.jsx("p",{className:"type-subheading text-sys-red mb-2",children:"Page failed to render"}),o.jsx("p",{className:"type-body text-fg-muted mb-4",children:(null==(e=this.state.error)?void 0:e.message)||"Unknown error"}),o.jsx("button",{onClick:()=>this.setState({hasError:!1}),className:"px-4 py-2 bg-sys-blue/20 text-sys-blue rounded-lg hover:bg-sys-blue/30 transition-colors",children:"Try Again"})]}):this.props.children}}function gh(){const e=El(),t=nn();return s.useEffect(()=>{if(t)return function(e){e();const t=ks.getState().initialize(),a=Oc.getState().initialize(),n=wc.getState().initialize();mn();const r=setInterval(()=>{mn()},3e4),s=function(){if(gn)return()=>{};if("undefined"==typeof document)return()=>{};const e=async()=>{if("visible"!==document.visibilityState)return;if(!en())return;if(sn())return an(),void("undefined"==typeof window||window.location.pathname.includes("/login")||Wa("token_expired_away"));const e=on();e>0&&e<300&&(await un()||console.warn("[Auth] Token refresh failed on visibility change"))};return document.addEventListener("visibilitychange",e),gn=!0,"visible"===document.visibilityState&&e(),()=>{document.removeEventListener("visibilitychange",e),gn=!1}}();return()=>{t(),n(),null==a||a(),s(),clearInterval(r),Hl(),function(){for(const e of Wu)clearInterval(e);Wu=[]}()}}(e)},[e,t]),o.jsxs($u,{children:[o.jsx(Ru,{}),o.jsxs(S,{children:[o.jsx(M,{path:"/login",element:o.jsx(s.Suspense,{fallback:o.jsx("div",{className:"min-h-screen bg-body"}),children:o.jsx(Zu,{})})}),o.jsx(M,{path:"/*",element:o.jsx(hh,{children:o.jsx(ca,{sidebar:o.jsx(Tu,{}),navbar:o.jsx(_u,{}),children:o.jsx("div",{className:"px-1 sm:px-4 lg:px-4 pt-5 pb-4 sm:pb-6 lg:pb-8 max-w-7xl mx-auto",children:o.jsx(mh,{children:o.jsxs(S,{children:[o.jsx(M,{path:"/",element:o.jsx(s.Suspense,{fallback:o.jsx(Vu,{}),children:o.jsx(Qu,{children:o.jsx(eh,{})})})}),o.jsx(M,{path:"/packets",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(th,{})})})}),o.jsx(M,{path:"/contacts",element:o.jsx(s.Suspense,{fallback:o.jsx(Ju,{}),children:o.jsx(Qu,{children:o.jsx(ah,{})})})}),o.jsx(M,{path:"/statistics",element:o.jsx(s.Suspense,{fallback:o.jsx(Ku,{}),children:o.jsx(Qu,{children:o.jsx(nh,{})})})}),o.jsx(M,{path:"/meshgraph",element:o.jsx(s.Suspense,{fallback:o.jsx(Ku,{}),children:o.jsx(Qu,{children:o.jsx(rh,{})})})}),o.jsx(M,{path:"/system",element:o.jsx(s.Suspense,{fallback:o.jsx(Yu,{}),children:o.jsx(Qu,{children:o.jsx(sh,{})})})}),o.jsx(M,{path:"/logs",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(oh,{})})})}),o.jsx(M,{path:"/terminal",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(ih,{})})})}),o.jsx(M,{path:"/room-server",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(ch,{})})})}),o.jsx(M,{path:"/configuration",element:o.jsx(s.Suspense,{fallback:o.jsx(Xu,{}),children:o.jsx(Qu,{children:o.jsx(lh,{})})})}),o.jsx(M,{path:"/raw",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(dh,{})})})}),o.jsx(M,{path:"/sessions",element:o.jsx(s.Suspense,{fallback:o.jsx(Xu,{}),children:o.jsx(Qu,{children:o.jsx(uh,{})})})})]})})})})})})]})]})}const ph=console.warn;console.warn=(...e)=>{const t=e[0];"string"==typeof t&&t.includes("Unable to load glyph range")||ph.apply(console,e)},v.createRoot(document.getElementById("root")).render(o.jsx(s.StrictMode,{children:o.jsx(et,{children:o.jsx(L,{children:o.jsx(gh,{})})})}));export{yl as $,dc as A,Mt as B,Ia as C,bi as D,uc as E,lc as F,_l as G,Hi as H,Ta as I,qu as J,ga as K,vc as L,di as M,gi as N,hi as O,mi as P,Un as Q,pi as R,gd as S,Ma as T,pd as U,Qc as V,zl as W,fo as X,Ot as Y,ge as Z,Ut as _,Yt as a,Li as a$,$l as a0,Nl as a1,Is as a2,nt as a3,rt as a4,wt as a5,ad as a6,mr as a7,hr as a8,Dt as a9,Zr as aA,Il as aB,Mc as aC,Wl as aD,it as aE,ot as aF,sc as aG,Cu as aH,Ss as aI,Ms as aJ,Mu as aK,pt as aL,qd as aM,Xe as aN,bu as aO,Zd as aP,eu as aQ,ku as aR,vi as aS,as as aT,rs as aU,$s as aV,Da as aW,pc as aX,yi as aY,ki as aZ,_d as a_,Gi as aa,Rt as ab,Vn as ac,ed as ad,bo as ae,oi as af,ql as ag,pu as ah,yu as ai,td as aj,_s as ak,Xr as al,qr as am,ss as an,ui as ao,Et as ap,sd as aq,st as ar,ns as as,os as at,Ct as au,fl as av,Ml as aw,Ir as ax,$r as ay,Qr as az,Gt as b,Vc as b$,Xt as b0,$a as b1,Ui as b2,Pr as b3,ls as b4,is as b5,hs as b6,cs as b7,es as b8,Yr as b9,Vs as bA,yo as bB,Ks as bC,Zs as bD,eo as bE,Ds as bF,Wt as bG,Kt as bH,Jt as bI,vs as bJ,cn as bK,ks as bL,Fs as bM,tt as bN,xe as bO,go as bP,nd as bQ,rd as bR,_a as bS,Vt as bT,Oc as bU,Qs as bV,Hc as bW,Wc as bX,Kc as bY,Xc as bZ,Uc as b_,yc as ba,me as bb,Zc as bc,Na as bd,vu as be,pe as bf,Pi as bg,Ii as bh,$i as bi,Oi as bj,qi as bk,Yc as bl,Hs as bm,kl as bn,vl as bo,Bl as bp,jl as bq,Di as br,fa as bs,xi as bt,Od as bu,Ls as bv,Os as bw,Us as bx,Js as by,Gs as bz,dd as c,ur as c$,Gc as c0,Jc as c1,pr as c2,fr as c3,yr as c4,br as c5,nc as c6,lr as c7,cr as c8,dr as c9,En as cA,Uo as cB,wo as cC,Co as cD,Gn as cE,Oo as cF,Yn as cG,ko as cH,Wo as cI,Io as cJ,$o as cK,qo as cL,Jn as cM,Qn as cN,Kn as cO,Wn as cP,In as cQ,Ln as cR,Nn as cS,Hn as cT,On as cU,Tn as cV,$n as cW,_n as cX,Rn as cY,Xn as cZ,Ho as c_,Zl as ca,Aa as cb,xa as cc,Ea as cd,fn as ce,zn as cf,Pn as cg,ri as ch,si as ci,qn as cj,zr as ck,gs as cl,ps as cm,fs as cn,Sc as co,pn as cp,Al as cq,wr as cr,Wi as cs,Vi as ct,_i as cu,vn as cv,Mn as cw,Dn as cx,An as cy,xn as cz,Ci as d,nr as d0,rr as d1,sr as d2,or as d3,ar as d4,tr as d5,er as d6,Zn as d7,ir as d8,Xs as d9,Ys as da,fu as db,Hd as dc,Nr as dd,su as de,cu as df,au as dg,ms as dh,Jl as di,Kl as dj,gu as dk,_c as dl,Nc as dm,ws as dn,Tl as dp,io as dq,Or as dr,Hr as ds,Fc as dt,fi as du,Ul as dv,ka as e,ba as f,Ya as g,xt as h,nn as i,ts as j,Ws as k,dn as l,wl as m,Cl as n,Dl as o,bl as p,va as q,Ll as r,Qa as s,Sl as t,hu as u,Rl as v,cc as w,ic as x,bc as y,fc as z}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Login-DV-gJNAt.js","assets/vendor-react-alRNW2nb.js","assets/vendor-virt-BytWoLhu.js","assets/cosmograph-DqYT4sUA.js","assets/vendor-core-FtpmsTnh.js","assets/ascii-burst-CXC_pYgi.js","assets/vendor-motion-DNp0Qg4F.js","assets/vendor-charts-C916_-gs.js","assets/vendor-icons-TO0PZKGR.js","assets/vendor-fonts-CRZaZSFf.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/Dashboard-Bbh9RnDT.js","assets/PageLayout-BWMUVZgC.js","assets/consumer-registry-BUFl6buY.js","assets/AnimatedNumber-DACuG-ay.js","assets/node-types-DRVunROD.js","assets/meshcore-tx-constants-BDLT5LMb.js","assets/PacketList-BJFBF77t.js","assets/primitives-Bgn6Ik6L.js","assets/payload-decoders-_TRhCJrs.js","assets/badge-colors-BxLppqaF.js","assets/chat-utils-mqGCinix.js","assets/SignalIndicator-Bdj3-1hL.js","assets/usePipelineStore-CLEA3Bev.js","assets/geo-utils-DJn8DnxF.js","assets/DataBox-DpDXI-WX.js","assets/useMapViewStore-sFZdb1_p.js","assets/TimeRangeStepper-CsLZzi5t.js","assets/LightSparkline-BAD3v4m9.js","assets/link-scoring-C0BjaK96.js","assets/NodeInformationCard-tOZNdmfP.js","assets/ChatBubble-OmHlf-X1.js","assets/Grid-m53vqd2Y.js","assets/Packets-DNzcKpej.js","assets/AnalyzerFilterPanel-o1lp_Gs8.js","assets/Contacts-CcN2zB34.js","assets/ping-DPgnsJJf.js","assets/listbox-DrzA7Ewq.js","assets/CollisionExplorerModal-BUHEIiWh.js","assets/BasemapLayer-CSqjQAiA.js","assets/ConfirmModal-B6Rz8ROW.js","assets/maplibre-gl-B1CfjdFi.css","assets/Statistics-DEmWOGLC.js","assets/easing-GXZYrvDD.js","assets/MeshGraph-BfYUTS82.js","assets/DeepAnalysisModal-L9EkN490.js","assets/System-RKAKlnZ6.js","assets/Logs-CVA2ZaR8.js","assets/Terminal-DKt0bGFF.js","assets/xterm-WPd9ZkSt.js","assets/system-OS35JnnX.js","assets/KeycapButton-DdWNfiky.js","assets/keycap-sfx-Bpx9zhkt.js","assets/xterm-6GBZ9nXN.css","assets/Configuration-CobIQjJB.js","assets/RoomServer-BvhmmII2.js","assets/PacketObservatory-DF8DSfgt.js","assets/Sessions-DBjQm7_J.js"])))=>i.map(i=>d[i]); +var e,t,a,n=Object.defineProperty,r=(e,t,a)=>((e,t,a)=>t in e?n(e,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[t]=a)(e,"symbol"!=typeof t?t+"":t,a);import{r as s,j as o,c as i,L as l,h as c,z as d,Q as u,y as h,x as m,X as g,d as p,a as f,W as b,t as y,Z as w,M as C,K as k,e as v}from"./vendor-react-alRNW2nb.js";import{u as D}from"./vendor-charts-C916_-gs.js";import{_ as A}from"./cosmograph-DqYT4sUA.js";import{L as x,c as E,a as F,u as B,b as j,R as S,d as M,N,B as L}from"./vendor-core-FtpmsTnh.js";import{A as T,m as _,L as R}from"./vendor-motion-DNp0Qg4F.js";import{M as z,X as P,C as I,I as $,L as q,a as O,b as H,T as W,E as U,S as V,c as G,d as J,e as K,f as X,g as Y,h as Q,i as Z,j as ee,W as te,G as ae,F as ne,k as re,l as se,P as oe,m as ie,n as le,U as ce,R as de,o as ue,p as he}from"./vendor-icons-TO0PZKGR.js";import"./vendor-fonts-CRZaZSFf.js";import"./vendor-virt-BytWoLhu.js";!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const a of e)if("childList"===a.type)for(const e of a.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const me={red:"#E5484D",orange:"#F76B15",amber:"#FFB224",yellow:"#F5D90A",brown:"#AD7F58",green:"#46A758",teal:"#12A594",cyan:"#00A2C7",blue:"#3B82F6",indigo:"#5B5BD6",purple:"#8E4EC6",pink:"#D6409F"},ge={50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"};function pe(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const fe={surfaces:{defaults:{tint:"#252525",light:"#ffffff",dark:"#000000",reflexLight:.15,reflexDark:.8,blur:6,blurElevated:8,brightness:1,opacity:8,opacityElevated:12},card:{radius:"1.125rem",padding:"1.25rem",paddingCompact:"0.75rem"},sidebar:{tint:"rgba(113, 156, 223, 0.06)",width:"16rem",drawerWidth:"85vw"},modal:{radius:"1.125rem",backdropBlur:"8px",backdropColor:"rgba(0, 0, 0, 0.6)"}},colors:{bg:{body:ge[950],surface:ge[900],elevated:ge[800],subtle:ge[800]},border:{subtle:ge[800],strong:ge[600]},text:{primary:"#ffffff",secondary:ge[400],muted:ge[500],inverse:ge[950]},accent:{primary:me.blue,secondary:me.purple,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[500]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[500]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[500],grid:"rgba(191, 191, 191, 0.15)",axis:ge[400],cursor:"rgba(255, 255, 255, 0.2)"},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[700],edgeHover:me.cyan}},typography:{font:{title:"'Inter', system-ui, sans-serif",display:"'Inter', system-ui, sans-serif",mono:"'JetBrains Mono', 'SF Mono', Monaco, monospace"},size:{xs:"0.64rem",sm:"0.8rem",base:"1rem",md:"1.125rem",lg:"1.25rem",xl:"1.563rem",xxl:"1.953rem",hero:"3.052rem"},weight:{normal:400,medium:500,semibold:600,bold:700},leading:{tight:1.1,snug:1.25,normal:1.5},tracking:{tight:"-0.02em",normal:"0",wide:"0.05em"}},spacing:{space:{gap:"1.5rem",gapMobile:"0.75rem",page:"1.5rem",pageMobile:"1rem",section:"2rem"},radius:{sm:"0.5rem",md:"0.875rem",lg:"1.125rem",xl:"1.5rem",pill:"9999px"}},motion:{fast:"0.1s",normal:"0.15s",slow:"0.4s",easing:"ease-out"}};function be(e){const t=e.replace("#","");if(6!==t.length&&3!==t.length)return e;let a,n,r;return 3===t.length?(a=parseInt(t[0]+t[0],16)/255,n=parseInt(t[1]+t[1],16)/255,r=parseInt(t[2]+t[2],16)/255):(a=parseInt(t.slice(0,2),16)/255,n=parseInt(t.slice(2,4),16)/255,r=parseInt(t.slice(4,6),16)/255),`color(display-p3 ${a.toFixed(3)} ${n.toFixed(3)} ${r.toFixed(3)})`}function ye(){return"undefined"!=typeof window&&CSS.supports("color","color(display-p3 1 1 1)")}function we(e,t){const a={...e};for(const n of Object.keys(t)){const r=t[n],s=e[n];void 0!==r&&("object"!=typeof r||null===r||Array.isArray(r)||"object"!=typeof s||null===s||Array.isArray(s)?a[n]=r:a[n]=we(s,r))}return a}function Ce(e){return{meta:e.meta,display:e.display,surfaces:e.surfaces?we(fe.surfaces,e.surfaces):fe.surfaces,colors:e.colors?we(fe.colors,e.colors):fe.colors,typography:e.typography?we(fe.typography,e.typography):fe.typography,spacing:e.spacing?we(fe.spacing,e.spacing):fe.spacing,motion:e.motion?we(fe.motion,e.motion):fe.motion}}function ke(e){const t=e.replace("#","");return 6===t.length?`${parseInt(t.slice(0,2),16)}, ${parseInt(t.slice(2,4),16)}, ${parseInt(t.slice(4,6),16)}`:"255, 255, 255"}const ve={"Breeze Dark":Ce({meta:{id:"",name:"",dataTheme:"",previewColor:me.blue,backgroundImage:"",backgroundBrightness:100,isDark:!0},display:{font:"Inter, sans-serif",color:ge[400],size:1,palette:[[me.blue,me.green,me.amber,me.orange,me.red],[ge[950],ge[900],ge[800],ge[700],ge[50]]]},typography:{font:{title:"Inter, sans-serif",display:"Inter, sans-serif",mono:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'},weight:{normal:400,medium:500,semibold:600,bold:700,badge:700},tracking:{tight:"-0.02em",normal:"0",wide:"0.025em"},badge:{textTransform:"capitalize"}},surfaces:{defaults:{tint:ge[900],light:ge[700],dark:ge[950],reflexLight:0,reflexDark:0,blur:0,blurElevated:0,brightness:1,opacity:100,opacityElevated:100,catalystMode:!0},sidebar:{tint:`${ge[800]}80`},card:{radius:"0.5rem"},modal:{radius:"0.75rem"}},colors:{bg:{body:ge[950],surface:ge[900],elevated:ge[800],subtle:ge[900]},border:{subtle:ge[800],strong:ge[600]},text:{primary:"#fff",secondary:ge[400],muted:ge[500],inverse:ge[950]},accent:{primary:me.blue,secondary:me.amber,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[500]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[500]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[500],grid:`${ge[50]}0d`,axis:`${ge[50]}33`,cursor:`${me.blue}33`},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:`${ge[50]}e6`,hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[700],edgeHover:me.blue}}}),"Breeze Light":Ce({meta:{id:"",name:"",dataTheme:"",previewColor:me.blue,backgroundImage:"",backgroundColor:ge[200],backgroundBrightness:100,isDark:!1},display:{font:"Inter, sans-serif",color:ge[600],size:1,palette:[[me.blue,me.green,me.amber,me.orange,me.red],[ge[200],ge[50],ge[100],ge[500],ge[900]]]},typography:{font:{title:"Inter, sans-serif",display:"Inter, sans-serif",mono:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'},weight:{normal:400,medium:500,semibold:600,bold:700,badge:700},tracking:{tight:"-0.02em",normal:"0",wide:"0.025em"},badge:{textTransform:"capitalize"}},surfaces:{defaults:{tint:ge[50],light:ge[200],dark:ge[400],reflexLight:0,reflexDark:0,blur:0,blurElevated:0,brightness:1,opacity:100,opacityElevated:100,catalystMode:!0},sidebar:{tint:"rgba(0, 0, 0, 0.02)"},card:{radius:"0.5rem"},modal:{radius:"0.75rem"}},colors:{bg:{body:ge[200],surface:ge[50],elevated:"#FFFFFF",subtle:ge[100]},border:{subtle:"#DEE0E2",strong:"#BFC2C5"},text:{primary:ge[900],secondary:ge[600],muted:ge[500],inverse:"#FFFFFF"},accent:{primary:me.blue,secondary:me.amber,tertiary:me.cyan,success:me.green,danger:me.red},signal:{excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red,unknown:ge[400]},status:{success:me.green,warning:me.amber,danger:me.red,info:me.blue,muted:ge[400]},chart:{c1:me.blue,c2:me.teal,c3:me.amber,c4:me.orange,c5:me.pink,c6:me.purple,c7:me.cyan,c8:ge[400],grid:`${ge[900]}0d`,axis:`${ge[900]}80`,cursor:`${me.blue}1a`},metric:{received:me.blue,forwarded:me.teal,transmitted:me.orange,dropped:me.red},map:{nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hub:me.purple,local:me.amber,neighbor:me.green,mobile:me.orange,room:me.pink,edge:ge[400],edgeHover:me.blue},sidebar:{bg:"rgba(0, 0, 0, 0.02)",navHoverBg:"rgba(0, 0, 0, 0.04)",navActiveBg:"rgba(59, 130, 246, 0.10)",navActiveText:me.blue}}})};function De(e,t){const a=e.toLowerCase();return{...t,meta:{...t.meta,id:a,name:e,dataTheme:a}}}const Ae=Object.fromEntries(Object.entries(ve).map(([e,t])=>[e,De(e,t)])),xe=Object.values(Ae);function Ee(e){return xe.find(t=>t.meta.id===e)}function Fe(e){return"string"==typeof e&&xe.some(t=>t.meta.id===e)}new Map(Object.entries(Ae));const Be=Ae["Breeze Dark"],je=Be.meta.id;Be.meta.backgroundImage;const Se={themeId:je,brightness:Be.meta.backgroundBrightness},Me="pymc-theme-id",Ne="pymc-bg-brightness",Le="pymc-color-scheme",Te="pymc-background";const _e={50:.97,100:.92,200:.84,300:.73,400:.62,500:.5,600:.4,700:.32,800:.24,900:.16},Re=[50,100,200,300,400,500,600,700,800,900],ze=["red","orange","yellow","green","aqua","blue","purple"];function Pe(e,t,a){const n=e=>Math.round(Math.max(0,Math.min(255,e))).toString(16).padStart(2,"0");return`#${n(e)}${n(t)}${n(a)}`}function Ie(e){const t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function $e(e){const t=e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055;return Math.round(255*t)}function qe(e,t,a){const n=a*(Math.PI/180),r=t*Math.cos(n),s=t*Math.sin(n),o=e+.3963377774*r+.2158037573*s,i=e-.1055613458*r-.0638541728*s,l=e-.0894841775*r-1.291485548*s,c=o*o*o,d=i*i*i,u=l*l*l,h=-1.2684380046*c+2.6097574011*d-.3413193965*u,m=-.0041960863*c-.7034186147*d+1.707614701*u;return[$e(4.0767416621*c-3.3077115913*d+.2309699292*u),$e(h),$e(m)]}function Oe(e){const[t,a,n]=function(e){const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}(e),[,r,s]=function(e,t,a){const n=Ie(e),r=Ie(t),s=Ie(a),o=.4122214708*n+.5363325363*r+.0514459929*s,i=.2119034982*n+.6806995451*r+.1073969566*s,l=.0883024619*n+.2817188376*r+.6299787005*s,c=Math.cbrt(o),d=Math.cbrt(i),u=Math.cbrt(l),h=.2104542553*c+.793617785*d-.0040720468*u,m=1.9779984951*c-2.428592205*d+.4505937099*u,g=.0259040371*c+.7827717662*d-.808675766*u,p=Math.sqrt(m*m+g*g);let f=Math.atan2(g,m)*(180/Math.PI);return f<0&&(f+=360),[h,p,f]}(t,a,n),o={};for(const i of Re){const e=_e[i],t=r*(1-.3*Math.abs(e-.5)),[a,n,l]=qe(e,t,s);o[i]=Pe(a,n,l)}return o}function He(e){return"undefined"==typeof window?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()}function We(e,t){"undefined"!=typeof document&&document.documentElement.style.setProperty(e,t)}const Ue=new Map;function Ve(e){var t;if(!e.startsWith("var("))return e;const a=Ue.get(e);if(a)return a;const n=e.match(/var\(([^,)]+)(?:,\s*([^)]+))?\)/);if(!n)return e;const r=n[1].trim(),s=(null==(t=n[2])?void 0:t.trim())||"#888888",o=getComputedStyle(document.documentElement).getPropertyValue(r).trim()||s;return Ue.set(e,o),o}function Ge(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(t)return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)];const a=/^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(e);return a?[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]:[0,0,0]}let Je=null,Ke=0;const Xe=s.memo(function({timestamps:e,series:t,onHover:a,onSeriesHover:n,highlightedKey:r=null,cursorColor:i,overlayLine:l=null,startTs:c,endTs:d,externalAxes:u=!1}){const h=s.useRef(null),m=s.useRef(null),g=s.useRef(t),p=s.useRef(r),f=s.useRef(l),b=s.useRef(a),y=s.useRef(n),w=s.useRef(null),C=s.useRef(c),k=s.useRef(d),v=s.useRef(u),A=s.useRef(e.length);s.useLayoutEffect(()=>{g.current=t,p.current=r,f.current=l,b.current=a,y.current=n,C.current=c,k.current=d,v.current=u});const x=s.useMemo(()=>{const t=new Array(e.length).fill(1);return[e,t]},[e]),E=s.useMemo(()=>({hooks:{draw:e=>{(function(e,t,a,n,r,s){if(0===t.length)return;const o=e.ctx,i=e.bbox,l=i.left,c=i.top,d=i.width,u=i.height;if(d<=0||u<=0)return;const h=8*(window.devicePixelRatio||1);o.save(),o.beginPath(),o.roundRect(l,c,d,u,h),o.clip();const m=e.data[0],g=m.length;if(0===g)return;const p=r??m[0],f=(s??m[g-1])-p||1,b=g>1?m[1]-m[0]:f/g,y=e=>l+(e-p)/f*d,w=e=>c+u*(1-e);for(let C=0;C=0;t--){const e=m[t],a=w(r[t]),n=y(t0&&o.lineTo(s,w(r[t-1]))}o.closePath(),o.fill(),o.restore()}n&&n.values.length>0&&function(e,t,a,n){const r=e.ctx,s=e.bbox,o=s.left,i=s.top,l=s.width,c=s.height;if(l<=0||c<=0)return;const d=e.data[0],u=d.length,h=t.values;if(0===u||0===h.length)return;const m=window.devicePixelRatio||1,g=a??d[0],p=(n??d[u-1])-g||1,f=e=>o+(e-g)/p*l,b=e=>i+c*(1-e),y=Ve(t.color),w=(t.lineWidth??2)*m;r.save(),r.strokeStyle=y,r.lineWidth=w,r.lineCap="round",r.lineJoin="round",r.beginPath();let C=0;for(;C=u)return void r.restore();const k=f(d[C]),v=b(h[C]);r.moveTo(k,v);for(let A=C+1;A({width:400,height:200,padding:u?[0,0,0,0]:[8,0,0,32],cursor:{show:!0,x:!0,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0,range:(e,t,a)=>[C.current??t,k.current??a]},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],hooks:{setCursor:[e=>{var t,a,n,r;const s=e.cursor.idx;if(null!=s&&s>=0){const n=e.data[0][s];null==(t=b.current)||t.call(b,s,n);const r=e.cursor.left,o=e.cursor.top;if(void 0!==r&&void 0!==o&&null!==r&&null!==o){const t=window.devicePixelRatio||1,n=e.ctx,s=Math.round((e.bbox.left/t+r)*t),i=Math.round((e.bbox.top/t+o)*t),l=n.getImageData(s,i,1,1).data,c=l[0],d=l[1],u=l[2];let h=null;if(l[3]>10){const e=g.current;for(const t of e){const e=Ve(t.color),[a,n,r]=Ge(e),s=30;if(Math.abs(c-a)<=s&&Math.abs(d-n)<=s&&Math.abs(u-r)<=s){h=t.key;break}}}h!==w.current&&(w.current=h,null==(a=y.current)||a.call(y,h))}}else null==(n=b.current)||n.call(b,null,null),null!==w.current&&(w.current=null,null==(r=y.current)||r.call(y,null))}]},plugins:[E]}),[E]);s.useEffect(()=>{const t=h.current;if(!t||0===e.length)return;const a=A.current,n=e.length,r=Math.abs(n-a);if(!(!m.current||r>100||a>0&&r/a>.1)&&m.current)return m.current.setData(x),void(A.current=n);m.current&&m.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...F,width:o,height:i},x,t);return m.current=l,A.current=n,()=>{l.destroy(),m.current=null}},[F,x,e.length]),s.useEffect(()=>{const e=h.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!m.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&m.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{m.current&&m.current.redraw()},[r,t,l]);const B=s.useCallback(()=>{null==a||a(null,null),null==n||n(null),w.current=null},[a,n]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:h,className:"w-full h-full overflow-hidden",onMouseLeave:B})}),Ye=s.createContext(null),Qe={blksand:"breeze dark",magma:"breeze dark",waves:"breeze dark",stars:"breeze dark",folds:"breeze dark","kde breeze":"breeze dark",ribbon:"breeze light"};function Ze(e){const t=Ee(e);t&&function(e){if("undefined"==typeof document)return;const t=function(e){var t;const a={},n=e.surfaces.defaults;a["--default-tint"]=n.tint,a["--default-light"]=n.light,a["--default-dark"]=n.dark,a["--default-reflex-light"]=String(n.reflexLight),a["--default-reflex-dark"]=String(n.reflexDark),a["--default-blur"]=`${n.blur}px`,a["--default-blur-elevated"]=`${n.blurElevated}px`,a["--default-brightness"]=String(n.brightness),a["--default-bg-opacity"]=`${n.opacity}%`,a["--default-bg-opacity-elevated"]=`${n.opacityElevated}%`,a["--default-stroke-only"]=n.strokeOnly?"1":"0",a["--default-stroke-width"]=n.strokeWidth?`${n.strokeWidth}px`:"0px",a["--default-stroke-color"]=n.strokeColor||"transparent",a["--sidebar-tint"]=e.surfaces.sidebar.tint;const r=e.meta.isDark;a["--tooltip-bg"]=r?e.colors.bg.elevated:"#FFFFFF",a["--tooltip-fg"]=r?"#FFFFFF":e.colors.text.primary,a["--tooltip-border"]=r?e.colors.border.subtle:"rgba(0, 0, 0, 0.12)",a["--tooltip-shadow"]=r?"0 4px 12px rgba(0, 0, 0, 0.4)":"0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.08)",a["--hover-tint"]=`rgba(${ke(e.colors.accent.primary)}, 0.08)`,a["--shadow-tint"]=`rgba(${ke(e.colors.accent.primary)}, 0.35)`,a["--body"]=e.colors.bg.body,a["--surface"]=e.colors.bg.surface,a["--elevated"]=e.colors.bg.elevated,a["--subtle"]=e.colors.bg.subtle,a["--edge-subtle"]=e.colors.border.subtle,a["--edge-strong"]=e.colors.border.strong,a["--fg-primary"]=e.colors.text.primary,a["--fg-secondary"]=e.colors.text.secondary,a["--fg-muted"]=e.colors.text.muted,a["--fg-invert"]=e.colors.text.inverse,a["--signal-excellent"]=e.colors.signal.excellent,a["--signal-good"]=e.colors.signal.good,a["--signal-fair"]=e.colors.signal.fair,a["--signal-poor"]=e.colors.signal.poor,a["--signal-critical"]=e.colors.signal.critical,a["--signal-unknown"]=e.colors.signal.unknown,a["--sparkline-excellent"]=e.colors.signal.excellent,a["--sparkline-good"]=e.colors.signal.good,a["--sparkline-fair"]=e.colors.signal.fair,a["--sparkline-poor"]=e.colors.signal.poor,a["--sparkline-critical"]=e.colors.signal.critical,a["--sparkline-bg"]=e.meta.isDark?"rgba(9, 9, 11, 0.5)":"transparent",a["--status-success"]=e.colors.status.success,a["--status-warning"]=e.colors.status.warning,a["--status-danger"]=e.colors.status.danger,a["--status-info"]=e.colors.status.info,a["--status-muted"]=e.colors.status.muted;const s=e.colors.chart;a["--pkt-advert"]=s.c3,a["--pkt-flood"]=s.c7,a["--pkt-txt-msg"]=e.colors.signal.excellent,a["--pkt-ack"]=s.c8,a["--pkt-trace"]=s.c3,a["--pkt-req"]=s.c2,a["--pkt-response"]=s.c5,a["--pkt-grp-txt"]=e.colors.map.room,a["--pkt-grp-data"]=e.colors.status.danger,a["--pkt-path"]=s.c3,a["--pkt-anon"]=s.c3,a["--pkt-control"]=s.c6,a["--pkt-unknown"]=e.colors.status.muted,a["--route-flood"]=s.c1,a["--route-direct"]=s.c3,a["--route-transport"]=s.c8,a["--chart-1"]=s.c1,a["--chart-2"]=s.c2,a["--chart-3"]=s.c3,a["--chart-4"]=s.c4,a["--chart-5"]=s.c5,a["--chart-6"]=s.c6,a["--chart-7"]=s.c7,a["--chart-8"]=s.c8,a["--chart-grid"]=s.grid,a["--chart-axis-tick"]=s.axis,a["--chart-cursor"]=s.cursor,a["--metric-received"]=e.colors.metric.received,a["--metric-forwarded"]=e.colors.metric.forwarded,a["--metric-transmitted"]=e.colors.metric.transmitted,a["--metric-dropped"]=e.colors.metric.dropped,a["--metric-neutral"]=e.colors.text.secondary,a["--log-debug"]=e.colors.status.muted,a["--log-info"]=e.colors.status.info,a["--log-warning"]=e.colors.status.warning,a["--log-error"]=e.colors.status.danger,a["--log-critical"]=e.colors.status.danger;const o=e.colors.map;a["--map-node-fill"]=me.blue,a["--map-node-stroke"]="rgba(255,255,255,0.9)",a["--map-hub-color"]=me.purple,a["--map-hub-stroke"]="rgba(255,255,255,0.9)",a["--map-gateway-color"]=me.indigo,a["--map-gateway-stroke"]="rgba(255,255,255,0.85)",a["--map-local-color"]=me.amber,a["--map-neighbor-color"]=me.amber,a["--map-neighbor-stroke"]="rgba(0,0,0,0.4)",a["--map-mobile-color"]=me.orange,a["--map-room-color"]=me.pink,a["--map-ghost-color"]=me.cyan,a["--map-edge-rest"]=o.edge,a["--map-edge-rest-bright"]=e.colors.border.strong,a["--map-edge-rest-dim"]=e.colors.bg.subtle,a["--map-edge-hover-direct"]=o.edgeHover,a["--map-edge-hover-loop"]=me.purple,a["--map-edge-hover-standard"]=e.colors.text.muted,a["--map-edge-hover-neighbor"]=me.amber,a["--link-strong"]=e.colors.signal.excellent,a["--link-medium"]=s.c3,a["--link-weak"]=e.colors.status.danger,a["--hop-0"]=s.c7,a["--hop-1"]=e.colors.signal.excellent,a["--hop-2"]=s.c2,a["--hop-3"]=s.c3,a["--hop-distant"]=e.colors.text.muted,a["--hop-hub"]=o.local;const i=e.colors.icon;a["--icon-page-title"]=(null==i?void 0:i.pageTitle)??s.c1,a["--icon-card-title"]=(null==i?void 0:i.cardTitle)??s.c1,a["--icon-widget"]=(null==i?void 0:i.widget)??e.colors.text.secondary,a["--icon-action"]=(null==i?void 0:i.action)??e.colors.text.secondary,a["--icon-nav"]=(null==i?void 0:i.nav)??e.colors.text.muted,a["--icon-nav-active"]=(null==i?void 0:i.navActive)??s.c1,a["--toggle-on"]=e.colors.signal.excellent,a["--toggle-off"]=e.colors.bg.elevated;const l=e.meta.isDark,c=e.colors.sidebar;a["--sidebar-bg"]=(null==c?void 0:c.bg)??"transparent",a["--sidebar-nav-hover-bg"]=(null==c?void 0:c.navHoverBg)??(l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.04)"),a["--sidebar-nav-active-bg"]=(null==c?void 0:c.navActiveBg)??`color-mix(in srgb, ${s.c1} 15%, transparent)`,a["--sidebar-nav-active-text"]=(null==c?void 0:c.navActiveText)??s.c1,a["--data-box-bg"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--data-box-border"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--subtle-fill"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--subtle-fill-hover"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.05)",a["--subtle-fill-strong"]=l?"rgba(255, 255, 255, 0.08)":"rgba(0, 0, 0, 0.06)",a["--color-pill-bg"]=l?"rgba(0, 0, 0, 0.3)":"rgba(255, 255, 255, 0.3)",a["--terminal-bg"]=l?"rgba(0, 0, 0, 0.4)":"rgba(0, 0, 0, 0.03)",a["--terminal-bg-input"]=l?"rgba(0, 0, 0, 0.5)":"rgba(0, 0, 0, 0.05)",a["--terminal-bg-status"]=l?"rgba(0, 0, 0, 0.3)":"rgba(0, 0, 0, 0.04)",a["--terminal-border"]=l?"rgba(255, 255, 255, 0.1)":"rgba(0, 0, 0, 0.1)",a["--terminal-autocomplete-bg"]=l?"rgba(0, 0, 0, 0.8)":"rgba(255, 255, 255, 0.95)",a["--terminal-autocomplete-border"]=l?"rgba(255, 255, 255, 0.2)":"rgba(0, 0, 0, 0.15)",a["--terminal-autocomplete-hover"]=l?"rgba(255, 255, 255, 0.1)":"rgba(0, 0, 0, 0.05)",a["--livedot-idle"]=l?"#666677":"#999999",a["--ctrl-panel-top"]=l?"rgba(30, 30, 30, 0.95)":"rgba(240, 240, 240, 0.95)",a["--ctrl-panel-mid"]=l?"rgba(25, 25, 25, 0.95)":"rgba(235, 235, 235, 0.95)",a["--ctrl-panel-bottom"]=l?"rgba(20, 20, 20, 0.95)":"rgba(230, 230, 230, 0.95)",a["--ctrl-panel-border"]=l?"rgba(60, 60, 60, 1)":"rgba(200, 200, 200, 1)",a["--chart-grid-line"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--chart-inner"]=l?"#111113":"#f7f7f8",a["--surface-ring"]=l?"inset 0 0 0 1px rgba(255, 255, 255, 0.1)":"inset 0 0 0 1px rgba(0, 0, 0, 0.08)",a["--surface-ring-strong"]=l?"inset 0 0 0 1px rgba(255, 255, 255, 0.15)":"inset 0 0 0 1px rgba(0, 0, 0, 0.12)",a["--surface-tint-subtle"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.02)",a["--surface-tint-light"]=l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.03)",a["--surface-border-subtle"]=l?"rgba(255, 255, 255, 0.05)":"rgba(0, 0, 0, 0.06)",a["--map-control-active-amber"]=l?"rgba(251, 191, 36, 0.15)":"rgba(217, 119, 6, 0.12)",a["--map-control-active-sky"]=l?"rgba(56, 189, 248, 0.15)":"rgba(14, 165, 233, 0.12)",a["--map-control-active-teal"]=l?"rgba(45, 212, 191, 0.15)":"rgba(20, 184, 166, 0.12)",a["--sidebar-action-active-green"]=l?"rgba(10, 26, 10, 1)":"rgba(220, 252, 231, 1)",a["--sidebar-action-active-teal"]=l?"rgba(10, 36, 32, 1)":"rgba(204, 251, 241, 1)",a["--sidebar-action-active-amber"]=l?"rgba(26, 20, 8, 1)":"rgba(254, 243, 199, 1)",a["--thumbnail-brightness"]=l?"1.5":"1.8",a["--input-bg"]=l?"rgba(255, 255, 255, 0.03)":"rgba(0, 0, 0, 0.03)",a["--input-border"]=l?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.08)",a["--font-title"]=e.typography.font.title,a["--font-display"]=e.typography.font.display,a["--font-data"]=e.typography.font.mono,a["--font-card-title"]=e.typography.font.cardTitle??e.typography.font.display,a["--font-badge"]=e.typography.font.badge??e.typography.font.display,a["--font-normal"]=String(e.typography.weight.normal),a["--font-medium"]=String(e.typography.weight.medium),a["--font-semibold"]=String(e.typography.weight.semibold),a["--font-bold"]=String(e.typography.weight.bold),a["--font-card-title-weight"]=String(e.typography.weight.cardTitle??e.typography.weight.semibold),a["--font-badge-weight"]=String(e.typography.weight.badge??e.typography.weight.medium),a["--badge-text-transform"]=(null==(t=e.typography.badge)?void 0:t.textTransform)??"none";const d=e.typography.size;d.xxl&&(a["--text-2xl"]=d.xxl),d.xl&&(a["--text-xl"]=d.xl),d.lg&&(a["--text-lg"]=d.lg),d.md&&(a["--text-md"]=d.md),d.base&&(a["--text-base"]=d.base),d.sm&&(a["--text-sm"]=d.sm),d.xs&&(a["--text-xs"]=d.xs),d.hero&&(a["--text-5xl"]=d.hero),d.cardTitle&&(a["--text-card-title"]=d.cardTitle);const u=e.typography.tracking;return u&&(a["--tracking-tight"]=u.tight,a["--tracking-normal"]=u.normal,a["--tracking-wide"]=u.wide),a["--theme-transition"]=`${e.motion.slow} ${e.motion.easing}`,function(e){if(!ye())return e;const t={},a=/^#[0-9A-Fa-f]{3,6}$/;for(const[n,r]of Object.entries(e))t[n]=a.test(r)?be(r):r;return t}(a)}(e),a=document.documentElement;for(const[n,r]of Object.entries(t))a.style.setProperty(n,r);e.surfaces.defaults.strokeOnly?a.classList.add("stroke-only"):a.classList.remove("stroke-only"),e.surfaces.defaults.catalystMode?a.classList.add("catalyst-mode"):a.classList.remove("catalyst-mode"),a.dataset.mode=e.meta.isDark?"dark":"light"}(t),document.documentElement.dataset.themeId=e}function et({children:e}){const[t,a]=s.useState(()=>function(){if("undefined"==typeof window)return Se;try{let e=localStorage.getItem(Me);const t=localStorage.getItem(Ne);if(!e){const t=localStorage.getItem(Le),a=localStorage.getItem(Te);t?e=t:a&&(e=a),e&&(localStorage.setItem(Me,e),localStorage.removeItem(Le),localStorage.removeItem("pymc-background-image"),localStorage.removeItem(Te))}e&&e in Qe&&(e=Qe[e],localStorage.setItem(Me,e));const a=e&&Fe(e)?e:Se.themeId;let n=Se.brightness;if(t){const e=parseInt(t,10);!isNaN(e)&&e>=0&&e<=100&&(n=e)}return{themeId:a,brightness:n}}catch{return Se}}()),n=s.useRef(!1),r=s.useRef(null),[i,l]=s.useState(null);s.useEffect(()=>{r.current&&(clearTimeout(r.current),r.current=null),n.current&&(l("#808080"),r.current=setTimeout(()=>{l(null),r.current=null},1800)),n.current=!0,Ze(t.themeId),Ue.clear(),requestAnimationFrame(()=>{!function(){if("undefined"==typeof window)return;for(const t of ze){const e=He(`--palette-${t}-bright`),a=He(`--palette-${t}`),n=e||a;if(!n)continue;const r=Oe(n);for(const s of Re)We(`--palette-${t}-${s}`,r[s])}const e=He("--palette-bg-4");if(e){const t=Oe(e);for(const e of Re)We(`--palette-neutral-${e}`,t[e])}}()})},[t.themeId]),s.useEffect(()=>{!function(e){if("undefined"!=typeof window)try{localStorage.setItem(Me,e.themeId),localStorage.setItem(Ne,String(e.brightness))}catch{}}(t)},[t]),s.useEffect(()=>{xe.forEach(e=>{var t;e.meta.backgroundImage&&(t=e.meta.backgroundImage)&&((new Image).src=t)})},[]);const c=s.useCallback(e=>{if(!Fe(e))return;const t=Ee(e);t&&a(a=>({...a,themeId:e,brightness:t.meta.backgroundBrightness}))},[]),d=s.useCallback(e=>{const t=Math.max(0,Math.min(100,Math.round(e)));a(e=>({...e,brightness:t}))},[]),u=s.useMemo(()=>({theme:t,setTheme:c,setBrightness:d}),[t,c,d]);return o.jsxs(Ye.Provider,{value:u,children:[e,i&&o.jsx("div",{className:"fixed inset-0 pointer-events-none z-[9999]",style:{backgroundColor:i,animation:"theme-crossfade 1.8s ease-out forwards"}},t.themeId),o.jsx("style",{children:"\n @keyframes theme-crossfade {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n "})]})}function tt(){const e=s.useContext(Ye);if(!e)throw new Error("useTheme must be used within a ThemeProvider. Wrap your app with in App.tsx.");return e}const at=s.forwardRef(function(e,t){const{href:a,...n}=e;return a.startsWith("http://")||a.startsWith("https://")||a.startsWith("//")?o.jsx(i,{children:o.jsx("a",{...n,href:a,ref:t})}):o.jsx(i,{children:o.jsx(x,{...n,to:a,ref:t})})}),nt={0:"REQ",1:"RESPONSE",2:"TXT_MSG",3:"ACK",4:"ADVERT",5:"GRP_TXT",6:"GRP_DATA",7:"ANON_REQ",8:"PATH",9:"TRACE",10:"MULTIPART",11:"CONTROL",15:"RAW_CUSTOM"},rt={0:"T_FLOOD",1:"FLOOD",2:"DIRECT",3:"T_DIRECT"},st={REQ:0,RESPONSE:1,TXT_MSG:2,ACK:3,ADVERT:4,GRP_TXT:5,GRP_DATA:6,ANON_REQ:7,PATH:8,TRACE:9,MULTIPART:10,RAW_CUSTOM:15};function ot(e){return 1===e||0===e}function it(e){return 2===e||3===e}const lt={acton:{discrete:["#260D40","#2B1345","#2F194B","#342152","#382657","#3C2C5C","#403261","#443766","#483E6C","#4C4371","#504876","#544D7B","#57527F","#5D5884","#625C88","#685F8A","#6E618C","#74628D","#7B638D","#81638E","#88648E","#8E648E","#95658F","#9D658F","#A4668F","#AB6690","#B26790","#BB6992","#C26B94","#C86F97","#CD749B","#D07AA0","#D382A7","#D688AC","#D88FB2","#D995B8","#DB9CBD","#DEA4C4","#DFABC9","#E1B1CE","#E3B7D3","#E5BED8","#E6C5DE","#E8CBE2","#E9D0E6","#EBD6EA","#ECDBEE","#EDE1F3","#EFE6F6","#F0EAFA"],categorical:["#260D40","#F0EAFA","#A76690","#DDA1C2","#585380","#7D638E","#E8CAE1","#CF789E","#403261","#4C4371","#ECDBEE","#69608B","#E3B6D2","#D78CB0","#91648F","#BE6A92","#342152","#EAD3E8","#524B79","#73628D","#463A69","#605B86","#E5C0DA","#D382A7","#C86F97","#86648E","#EEE3F4","#DA97B9","#9B658F","#B26790","#2D1749","#E0ACCA","#3A2959","#8B648E","#311C4D","#EBD7EB","#EDDFF1","#AC6790","#A1668F","#6E618C","#E6C5DE","#78628D","#433665","#DEA7C6","#81638E","#554F7C","#B86891","#3D2D5D","#4F4775","#EFE7F7","#E9CEE4","#D27DA3","#2A1244","#655D89","#C36C94","#E1B1CE","#493F6D","#5C5783","#CC739A","#DB9CBD","#D892B4","#D587AB","#96658F","#E4BBD6","#362455","#4E4573","#7F638E","#D37FA5","#E1AECC","#382657","#EBD9ED","#DFA9C8","#A4668F","#8E648E","#99658F","#675F8A","#B56891","#BB6992","#E5BED8","#E2B4D0","#D07AA0","#71618C","#E6C2DC","#AA6690","#625C88","#EDE1F3","#E8CCE3","#AF6790","#CA7199","#C16B93","#453867","#57517E","#84638E","#4B416F","#E7C7DF","#423463","#514977","#3E2F5F","#544D7B","#93658F"]},bam:{discrete:["#65024B","#701057","#7B1B61","#88276E","#923078","#9B3881","#A4418A","#AC4993","#B5549C","#BC5CA3","#C266AB","#C970B2","#CF7AB9","#D587C1","#DA93C8","#DF9ECE","#E3AAD4","#E7B5DA","#EBC2E0","#EECCE5","#F1D5E9","#F3DDED","#F5E4F0","#F6EBF1","#F6EFF1","#F5F2F0","#F3F3ED","#EFF3E6","#EBF1DF","#E5EFD5","#DDEBCA","#D4E6BD","#C8DEAB","#BCD79B","#B0CE8C","#A3C67D","#97BC6F","#88B161","#7CA856","#72A04D","#679845","#5E903D","#538735","#4B7F2E","#427827","#397021","#306819","#245D10","#195507","#0D4C00"],categorical:["#65024B","#701057","#7B1B61","#88276E","#923078","#9B3881","#A4418A","#AC4993","#B5549C","#BC5CA3","#C266AB","#C970B2","#CF7AB9","#D587C1","#DA93C8","#DF9ECE","#E3AAD4","#E7B5DA","#EBC2E0","#EECCE5","#F1D5E9","#F3DDED","#F5E4F0","#F6EBF1","#F6EFF1","#F5F2F0","#F3F3ED","#EFF3E6","#EBF1DF","#E5EFD5","#DDEBCA","#D4E6BD","#C8DEAB","#BCD79B","#B0CE8C","#A3C67D","#97BC6F","#88B161","#7CA856","#72A04D","#679845","#5E903D","#538735","#4B7F2E","#427827","#397021","#306819","#245D10","#195507","#0D4C00"]},bamako:{discrete:["#003B47","#023C46","#053E45","#083F43","#0A4141","#0D4340","#0F443E","#12463C","#16483A","#194A38","#1C4D36","#204F34","#235132","#28542F","#2C572C","#305A2A","#355C27","#395F24","#3F6321","#44661E","#49691A","#4E6D17","#537014","#5A7410","#5F780D","#657C09","#6A7F05","#718302","#788501","#7F8700","#858800","#8C8A00","#948C01","#9B8E04","#A1920B","#A89713","#AE9C1B","#B7A225","#BEA82E","#C5AD37","#CBB341","#D2B84D","#D9BF5B","#DEC567","#E4CA73","#E9D07E","#EFD58A","#F5DB97","#FAE0A3","#FFE5AD"],categorical:["#003B47","#FFE5AD","#61790B","#B4A022","#245231","#406420","#898900","#DDC464","#0F443E","#EFD58A","#CAB23F","#194A38","#748401","#506E16","#9E9108","#315A29","#083F43","#A99815","#948C01","#6A7F05","#BFA930","#7F8700","#14473B","#1E4E35","#F7DD9C","#2A562D","#043D45","#597411","#E6CC77","#385F25","#48691B","#D4BB51","#0B4241","#8F8A00","#44661E","#1B4C37","#547113","#6F8203","#12463D","#998E03","#27542F","#4C6B18","#A4940E","#2E582B","#355C27","#B9A529","#215033","#EAD181","#FBE1A5","#C5AD37","#3C6122","#848800","#063E44","#E2C86E","#D9BF5B","#CFB648","#16493A","#798600","#023C46","#667C08","#5D770E","#0D433F","#AE9C1B","#F3D993","#094042","#A69611","#8C8A00","#053E45","#0C4240","#365E26","#6D8004","#9C8F05","#4A6A1A","#D6BD56","#B19E1F","#F9DFA0","#647B0A","#2F592A","#10453D","#818800","#C7AF3B","#46681C","#0E443F","#265330","#174A39","#335B28","#5B750F","#778501","#5F780D","#E8CF7C","#718302","#F1D78E","#978D02","#F5DB97","#204F34","#AC9A18","#29552E","#A1920B","#B7A225","#033C46"]},bamo:{discrete:["#4F3043","#56304B","#603354","#6D3961","#793F6B","#834675","#8D4E7E","#965587","#A05E91","#A86698","#B06EA0","#B877A7","#BF81AF","#C78DB8","#CD98BE","#D2A3C4","#D6ADC8","#D9B5CB","#DABECC","#DAC3CC","#D9C7CA","#D8CAC8","#D6CBC6","#D4CDC2","#D1CDBE","#CCCDB9","#C6CBB1","#BCC5A4","#B2BE97","#A7B58A","#9CAB7E","#92A174","#889669","#808D62","#79855C","#737D56","#6D7552","#666C4C","#616548","#5C5D45","#575642","#54503F","#50493D","#4D453C","#4B403B","#4A3C3A","#49393A","#49343B","#4A313E","#4E3042"],categorical:["#4F3043","#56304B","#603354","#6D3961","#793F6B","#834675","#8D4E7E","#965587","#A05E91","#A86698","#B06EA0","#B877A7","#BF81AF","#C78DB8","#CD98BE","#D2A3C4","#D6ADC8","#D9B5CB","#DABECC","#DAC3CC","#D9C7CA","#D8CAC8","#D6CBC6","#D4CDC2","#D1CDBE","#CCCDB9","#C6CBB1","#BCC5A4","#B2BE97","#A7B58A","#9CAB7E","#92A174","#889669","#808D62","#79855C","#737D56","#6D7552","#666C4C","#616548","#5C5D45","#575642","#54503F","#50493D","#4D453C","#4B403B","#4A3C3A","#49393A","#49343B","#4A313E","#4E3042"]},batlow:{discrete:["#011959","#06215B","#0A285C","#0D315D","#0E375E","#103D5F","#114260","#124761","#144D62","#165162","#195662","#1C5A62","#205E61","#26635F","#2C665D","#33695A","#3A6C57","#416F53","#4A724E","#52744A","#5A7745","#627941","#6A7B3D","#747E38","#7D8134","#868330","#8F862D","#9B892B","#A58B2C","#AF8D2E","#B98F32","#C29037","#CD923F","#D69446","#DE964F","#E69858","#ED9A62","#F39E70","#F8A17B","#FAA587","#FCA993","#FDAC9E","#FDB1AB","#FDB4B6","#FDB8C0","#FDBCCB","#FCBFD6","#FCC4E3","#FBC8EF","#FACCFA"],categorical:["#011959","#FACCFA","#828231","#226061","#F29D6D","#4D734D","#114360","#C09036","#FDB4B4","#DD954D","#356A59","#FCBFD6","#175262","#677B3E","#A18A2B","#0D315D","#FCA890","#FBC6E8","#2B655E","#B18D2F","#5A7745","#FDAEA2","#CF9340","#0F3B5F","#E9995C","#FDBAC4","#416F53","#91862D","#1B5962","#08255B","#747E38","#134B61","#F9A380","#8A842F","#0E365E","#124761","#154F62","#E39754","#7B8034","#1E5D62","#99882C","#195662","#0B2B5C","#FDB7BC","#C8913B","#FCC3DF","#EE9B64","#A98C2C","#FDB1AB","#FDBCCD","#FBC9F1","#051F5A","#F6A077","#607942","#FDAB9A","#477150","#3B6D56","#B98F32","#26635F","#537549","#D69446","#6D7C3B","#30685C","#103F60","#FBA689","#BD8F34","#CB923E","#EB9A60","#FDB8C0","#FBC7EC","#F09C69","#8E852E","#FDBBC9","#7F8133","#031C5A","#114160","#FDAC9E","#5D7844","#FCA995","#185462","#787F36","#A58B2C","#0A285C","#9D892B","#33695A","#0D335E","#637A40","#165062","#124561","#205E61","#144D62","#1D5B62","#0C2E5D","#D9954A","#3E6E55","#AD8C2D","#F49F72","#868330","#B58E30","#577647"]},batlowk:{discrete:["#04050A","#0A0D15","#0F141E","#121B29","#152233","#18293D","#1C3146","#21384F","#274156","#2C485B","#314E5E","#36535F","#3B575F","#405C5E","#445F5D","#49625B","#4D6558","#526756","#586B52","#5E6E4F","#63724B","#6A7548","#717845","#797D41","#81813E","#8A853B","#938839","#9F8D38","#A99139","#B3943B","#BE973E","#C89A43","#D39D4C","#DB9F54","#E2A15D","#E8A366","#EEA570","#F3A77C","#F6A986","#F8AC91","#FAAE9A","#FCB1A4","#FDB4B0","#FDB7B9","#FDBAC3","#FDBDCD","#FDC1D8","#FCC5E4","#FBC8EF","#FACCFA"],categorical:["#04050A","#FDC0D6","#787C41","#38555F","#E5A160","#536855","#AF933A","#FAAE9A","#1A2E43","#FDB6B7","#294458","#455F5C","#63724B","#CD9B47","#91883A","#F3A77E","#111A27","#F7AB8D","#FDBBC5","#FCB2AA","#D99E52","#A18E38","#4C6459","#21384F","#3F5B5E","#152335","#0C1019","#EEA570","#5B6D50","#6C7647","#314E5E","#85823D","#BE973E","#7E7F3F","#FBB0A2","#49625B","#576A53","#0F151F","#2D495B","#DFA059","#727944","#FDBDCD","#253E54","#EAA368","#C69942","#3C585F","#998B38","#677449","#F1A678","#F9AC92","#141F2F","#1D3248","#506657","#090C13","#A99139","#5F6F4E","#35525F","#435D5D","#FDB8BD","#F5A984","#B5953B","#FDB5B2","#17273B","#D39D4C","#8C853B","#9D8C38","#415C5E","#1F354B","#33505E","#FCB1A6","#101723","#3E595F","#121C2B","#757B43","#06080F","#FCB3AE","#3A565F","#274156","#61704D","#88843C","#2B475A","#FDBED1","#6A7548","#596C51","#192B3F","#6F7845","#233B51","#C99A45","#F0A574","#DC9F55","#2F4B5D","#47615C","#F6AA88","#FDB9C1","#C29840","#4A635A","#FAAD96","#81813E","#7B7E40","#E7A264"]},batloww:{discrete:["#011959","#06215B","#0A285C","#0D315D","#0E375E","#103D5F","#114260","#124761","#144C62","#165062","#185562","#1B5962","#1F5D62","#246261","#2A665F","#30695D","#366C5A","#3D7056","#467352","#4E764E","#56794A","#5E7C46","#667F42","#70823D","#798539","#828936","#8C8C33","#989032","#A29433","#AD9738","#B79B3F","#C19E48","#CBA154","#D3A45E","#D9A669","#DFA872","#E4AA7C","#E9AC88","#EEAF91","#F2B39C","#F6B9A8","#F9C0B5","#FCCAC4","#FED3CF","#FFDBDA","#FFE3E2","#FFEAEA","#FFF2F2","#FFF8F8","#FFFEFE"],categorical:["#FFFEFE","#011959","#7E8737","#205F61","#E7AB84","#497451","#114360","#FED1CD","#BF9D46","#637E44","#9E9233","#FFEAEA","#0D315D","#326B5C","#F5B7A6","#165162","#D7A564","#0F3B5F","#1A5862","#3D7056","#FFF5F5","#FFDFDD","#FAC3BA","#134A61","#08255B","#70823D","#EEB094","#56794A","#E0A874","#8E8D33","#28655F","#AF9839","#CBA154","#EBAD8B","#1D5C62","#051F5A","#124761","#FFE5E4","#B79B3F","#A79535","#386D59","#5C7B47","#185562","#DBA76D","#F8BDAF","#FFF0F0","#246261","#F2B39C","#868A35","#4F774D","#E4AA7C","#2D685E","#77853A","#FED8D6","#103F60","#FFFAF9","#968F32","#D1A35C","#144E62","#FCCAC4","#437254","#698040","#0E365E","#0B2B5C","#C59F4C","#30695D","#1C5A62","#A29433","#407155","#FFDBDA","#0C2E5D","#F7BAAA","#E5AB80","#175362","#828936","#1F5D62","#BB9C42","#E9AC88","#FFF7F7","#3A6E58","#9A9132","#8A8B34","#4C754F","#FFEDED","#D9A669","#144C62","#266460","#FDCDC9","#FCC6BF","#FFE2E1","#FFFCFC","#7B8639","#2B675E","#155062","#5F7C45","#F9C0B5","#356C5A","#F3B5A1","#EDAF8F","#FED5D2"]},berlin:{discrete:["#9EB0FF","#93AFFA","#87ADF4","#79ABED","#6CA9E6","#60A5DF","#54A0D5","#489ACA","#3E90BC","#3787AF","#327EA3","#2D7597","#296B8B","#25607C","#225771","#1E4E65","#1B465A","#183D4F","#153342","#122C38","#11242E","#101D25","#11181C","#121214","#160E0D","#1B0B07","#210B03","#270D01","#2D0E00","#340F00","#3B1100","#421301","#4B1602","#541905","#5D1E09","#68240F","#732B16","#803620","#8A3F2A","#944834","#9E513F","#A85A4A","#B46658","#BE6F63","#C8796F","#D2837A","#DD8D86","#EA9995","#F4A3A1","#FFADAD"],categorical:["#9EB0FF","#93AFFA","#87ADF4","#79ABED","#6CA9E6","#60A5DF","#54A0D5","#489ACA","#3E90BC","#3787AF","#327EA3","#2D7597","#296B8B","#25607C","#225771","#1E4E65","#1B465A","#183D4F","#153342","#122C38","#11242E","#101D25","#11181C","#121214","#160E0D","#1B0B07","#210B03","#270D01","#2D0E00","#340F00","#3B1100","#421301","#4B1602","#541905","#5D1E09","#68240F","#732B16","#803620","#8A3F2A","#944834","#9E513F","#A85A4A","#B46658","#BE6F63","#C8796F","#D2837A","#DD8D86","#EA9995","#F4A3A1","#FFADAD"]},bilbao:{discrete:["#4C0001","#54070B","#5B0E13","#64161A","#6B1D20","#712227","#77282D","#7D2E34","#84343B","#8A3A41","#8F4047","#94464B","#984C4F","#9B5253","#9D5754","#9E5C56","#A06057","#A16458","#A26959","#A36D5A","#A4715B","#A5745B","#A6785C","#A77C5D","#A8805E","#A9845F","#AA875F","#AC8C60","#AD9061","#AE9463","#AF9864","#B19D68","#B3A36E","#B6A975","#B8AD7E","#BBB287","#BDB590","#C0B99A","#C2BCA3","#C4BFAA","#C6C2B2","#C8C5B9","#CBCAC1","#CFCEC9","#D5D4D1","#DBDBDA","#E3E3E2","#EDEDED","#F6F6F6","#FFFFFF"],categorical:["#4C0001","#F8F8F8","#A9815E","#984D50","#BEB794","#AF9965","#CCCAC3","#78292F","#A26A59","#9F5D56","#64161A","#B6AA77","#C4C0AC","#A6765C","#8A3A41","#AC8C60","#DDDDDB","#A16358","#C7C5B7","#B3A16B","#A4705A","#6E2024","#EAEAE9","#92434A","#BAB185","#9C5554","#AD9262","#580B10","#813137","#C1BCA1","#AA865F","#D2D2CE","#A77C5D","#D7D7D4","#BCB48D","#B4A571","#C0B99A","#9E5955","#AB8960","#A6795C","#A36D5A","#8E3F46","#85353C","#A16758","#732529","#CAC7BD","#F1F1F0","#520509","#AC8F61","#5E1115","#C6C2B2","#E3E3E2","#691B1F","#B8AD7E","#95484D","#AE9663","#B19D68","#A5735B","#A06057","#9A5152","#A87E5D","#7D2E34","#A9835E","#C3BEA6","#CFCEC9","#A46E5A","#F4F4F4","#DADAD8","#B29F69","#EDEDED","#BBB289","#9D5754","#AF9764","#904148","#994F51","#B3A36E","#A87F5E","#A26859","#AC8D61","#BDB590","#AA875F","#A77A5D","#AB8A60","#A4715B","#611418","#BFB897","#E6E6E6","#9B5353","#D5D4D1","#974A4F","#C8C6BA","#A16558","#9F5E56","#76272C","#67191D","#8C3C43","#B9AF82","#C3BFA9","#B5A874","#4F0205"]},broc:{discrete:["#2C1A4C","#2B2154","#2B295B","#2A3164","#29396C","#284174","#29497C","#2A5183","#305C8C","#376593","#416D9A","#4B76A0","#567FA6","#6489AD","#6F92B3","#7B9BBA","#86A3C0","#92ACC6","#A0B7CD","#ACC0D3","#B8C9DA","#C4D2E0","#D0DBE6","#DEE5EC","#E7ECED","#EDEFE9","#EDEEE1","#E9E9D4","#E4E4C8","#DEDEBD","#D8D8B1","#D2D2A5","#C9C996","#C1C18A","#B8B87E","#AEAE73","#A3A369","#97975E","#8D8D56","#83834D","#797945","#70703D","#646434","#5B5B2C","#525224","#49491D","#404016","#36360F","#2E2E08","#262600"],categorical:["#2C1A4C","#2B2154","#2B295B","#2A3164","#29396C","#284174","#29497C","#2A5183","#305C8C","#376593","#416D9A","#4B76A0","#567FA6","#6489AD","#6F92B3","#7B9BBA","#86A3C0","#92ACC6","#A0B7CD","#ACC0D3","#B8C9DA","#C4D2E0","#D0DBE6","#DEE5EC","#E7ECED","#EDEFE9","#EDEEE1","#E9E9D4","#E4E4C8","#DEDEBD","#D8D8B1","#D2D2A5","#C9C996","#C1C18A","#B8B87E","#AEAE73","#A3A369","#97975E","#8D8D56","#83834D","#797945","#70703D","#646434","#5B5B2C","#525224","#49491D","#404016","#36360F","#2E2E08","#262600"]},broco:{discrete:["#372F38","#36303D","#363144","#36354E","#363957","#373F60","#39456A","#3C4D75","#415780","#47608A","#4D6992","#55729A","#5D7BA2","#6886AA","#728FB1","#7C97B7","#86A0BD","#91A8C2","#9DB2C8","#A7BACC","#B1C1CE","#BAC8D0","#C2CDD0","#CAD1CD","#CED3C8","#CFD3C2","#CFD1B9","#CBCCAD","#C6C6A2","#BFBF96","#B8B78B","#AFAF7F","#A4A472","#9B9A68","#91915E","#888755","#7E7E4C","#737243","#6B693D","#626137","#5B5932","#54512E","#4C482B","#474229","#423D29","#3F3829","#3C352B","#39322E","#383032","#372F37"],categorical:["#372F38","#36303D","#363144","#36354E","#363957","#373F60","#39456A","#3C4D75","#415780","#47608A","#4D6992","#55729A","#5D7BA2","#6886AA","#728FB1","#7C97B7","#86A0BD","#91A8C2","#9DB2C8","#A7BACC","#B1C1CE","#BAC8D0","#C2CDD0","#CAD1CD","#CED3C8","#CFD3C2","#CFD1B9","#CBCCAD","#C6C6A2","#BFBF96","#B8B78B","#AFAF7F","#A4A472","#9B9A68","#91915E","#888755","#7E7E4C","#737243","#6B693D","#626137","#5B5932","#54512E","#4C482B","#474229","#423D29","#3F3829","#3C352B","#39322E","#383032","#372F37"]},buda:{discrete:["#B301B3","#B30BAE","#B314AA","#B31CA6","#B323A2","#B3289F","#B32E9D","#B4339A","#B53998","#B63E96","#B84394","#B94892","#BB4C91","#BD528F","#BE568D","#C05B8C","#C15F8A","#C36389","#C46987","#C66D86","#C77184","#C97583","#CA7982","#CB7E80","#CD837F","#CE877E","#CF8B7D","#D0917B","#D1957A","#D29979","#D49E78","#D5A277","#D6A776","#D7AC75","#D8B073","#D9B572","#DAB971","#DCBF70","#DDC36F","#DEC86E","#DFCC6C","#E0D16B","#E2D76A","#E4DC69","#E6E168","#E9E667","#EDEC67","#F3F366","#F9F966","#FFFF66"],categorical:["#B301B3","#FFFF66","#CD857E","#BC4E90","#DBBD70","#C56A87","#B32F9C","#E3DB69","#D4A177","#EDEC67","#D1937B","#B73F95","#C05C8B","#DFCB6D","#C97882","#B31CA6","#D8AE74","#E7E368","#DAB572","#B311AC","#D39A79","#C36389","#C77184","#B53798","#E1D36B","#BE558E","#B94793","#CB7E80","#CF8C7C","#DDC46E","#B326A0","#F6F566","#D6A875","#DAB971","#C66E86","#E2D76A","#B32B9E","#B317A9","#B4339A","#BA4B91","#C46788","#C2608A","#B309AF","#D49E78","#B63B97","#BD528F","#DCC06F","#EAE767","#FAFA66","#D2977A","#F1F066","#D0907C","#CE897D","#C87483","#CC827F","#D5A576","#B321A3","#E5DF68","#B84394","#D9B273","#E0CF6C","#CA7B81","#DEC86E","#BF598C","#D7AB75","#E6E168","#D1957A","#CC8080","#D39C78","#E0CD6C","#CD847F","#B63D96","#C87384","#C66C86","#F8F866","#D49F78","#D9B473","#DAB772","#BF578D","#CB7D81","#CF8A7D","#B32D9D","#D08E7C","#DBBB71","#C2628A","#E2D56A","#DCBF70","#BC508F","#C46987","#C05B8C","#DFCA6D","#DDC26F","#C15E8B","#D7AD74","#F3F366","#DEC66E","#D5A377","#B31AA7","#BA4992","#CE877E"]},bukavu:{discrete:["#1A3333","#1B373D","#1C3C47","#1E4255","#1F4762","#214E71","#235582","#255E92","#2969A1","#2C73AD","#2F7CB8","#3485C2","#3B8EC7","#4799C8","#50A1C9","#59AAC9","#62B2CA","#6BBACB","#76C3CB","#81CCCD","#92D5D1","#A4DED5","#B6E7DA","#CCF2DF","#DDFBE3","#034224","#08491F","#115119","#1C5914","#2B6212","#3D6915","#4E6E1B","#617224","#6F742B","#7B7631","#867836","#917B3C","#9E7E45","#AA844F","#B48D5D","#BC976C","#C3A27C","#CAB08F","#CFBBA0","#D5C6B0","#DACFC1","#DFD7D0","#E4DFE0","#E9E6ED","#EDEDFC"],categorical:["#1A3333","#1B373D","#1C3C47","#1E4255","#1F4762","#214E71","#235582","#255E92","#2969A1","#2C73AD","#2F7CB8","#3485C2","#3B8EC7","#4799C8","#50A1C9","#59AAC9","#62B2CA","#6BBACB","#76C3CB","#81CCCD","#92D5D1","#A4DED5","#B6E7DA","#CCF2DF","#DDFBE3","#034224","#08491F","#115119","#1C5914","#2B6212","#3D6915","#4E6E1B","#617224","#6F742B","#7B7631","#867836","#917B3C","#9E7E45","#AA844F","#B48D5D","#BC976C","#C3A27C","#CAB08F","#CFBBA0","#D5C6B0","#DACFC1","#DFD7D0","#E4DFE0","#E9E6ED","#EDEDFC"]},cork:{discrete:["#2C194C","#2B2254","#2B295C","#2A3265","#293A6D","#284275","#284A7C","#2A5284","#2F5C8D","#366493","#3F6C99","#49749F","#527CA4","#5E85AA","#688DB0","#7395B6","#7E9DBB","#8AA6C2","#99B1C9","#A5BBD0","#B2C5D7","#C0CFDE","#CDD9E5","#DCE5EB","#E5ECED","#E6EEEA","#E0EAE1","#D4E2D4","#C8DBC8","#BCD3BC","#B0CAB0","#A4C2A3","#95B895","#89B088","#7DA87D","#71A071","#669966","#599059","#4F894E","#458244","#3B7B3A","#317430","#266A25","#1F611D","#1A5816","#174E12","#14450E","#123A0A","#103107","#0F2903"],categorical:["#2C194C","#2B2254","#2B295C","#2A3265","#293A6D","#284275","#284A7C","#2A5284","#2F5C8D","#366493","#3F6C99","#49749F","#527CA4","#5E85AA","#688DB0","#7395B6","#7E9DBB","#8AA6C2","#99B1C9","#A5BBD0","#B2C5D7","#C0CFDE","#CDD9E5","#DCE5EB","#E5ECED","#E6EEEA","#E0EAE1","#D4E2D4","#C8DBC8","#BCD3BC","#B0CAB0","#A4C2A3","#95B895","#89B088","#7DA87D","#71A071","#669966","#599059","#4F894E","#458244","#3B7B3A","#317430","#266A25","#1F611D","#1A5816","#174E12","#14450E","#123A0A","#103107","#0F2903"]},corko:{discrete:["#3F3E3A","#3E3D3F","#3E3D44","#3E3D4B","#3E3F52","#3E425A","#3F4762","#414C6C","#445578","#485D82","#4E658B","#546E94","#5C779C","#6581A5","#6E8AAC","#7792B2","#809BB8","#89A3BD","#94ACC2","#9CB3C5","#A3BAC7","#A9C0C8","#AEC5C7","#B0C9C4","#B0CABF","#ADCAB9","#A9C9B2","#A2C5A8","#9BC19F","#93BC95","#8BB68B","#82B081","#78A775","#709F6A","#689760","#608E56","#5A864C","#537B42","#4F733B","#4B6B35","#486431","#465D2E","#44562C","#43512C","#424D2D","#42492E","#414630","#404333","#404036","#3F3E3A"],categorical:["#3F3E3A","#3E3D3F","#3E3D44","#3E3D4B","#3E3F52","#3E425A","#3F4762","#414C6C","#445578","#485D82","#4E658B","#546E94","#5C779C","#6581A5","#6E8AAC","#7792B2","#809BB8","#89A3BD","#94ACC2","#9CB3C5","#A3BAC7","#A9C0C8","#AEC5C7","#B0C9C4","#B0CABF","#ADCAB9","#A9C9B2","#A2C5A8","#9BC19F","#93BC95","#8BB68B","#82B081","#78A775","#709F6A","#689760","#608E56","#5A864C","#537B42","#4F733B","#4B6B35","#486431","#465D2E","#44562C","#43512C","#424D2D","#42492E","#414630","#404333","#404036","#3F3E3A"]},davos:{discrete:["#00054A","#010E51","#041459","#081C61","#0C2368","#102A6F","#133075","#17377C","#1C3F83","#204588","#244C8D","#295291","#2D5895","#335F98","#38649A","#3C699C","#416E9D","#46729D","#4C779D","#517B9C","#567F9B","#5A829A","#5F8598","#658996","#698C94","#6E8F92","#739290","#78968D","#7D998C","#829D8A","#88A089","#8DA488","#95AA87","#9BAF88","#A3B489","#ABBB8C","#B4C190","#BFCA96","#C9D29E","#D2D9A6","#DBE0AF","#E3E7B8","#EBEDC4","#F0F1CD","#F4F4D6","#F7F7DE","#FAF9E6","#FCFCF0","#FDFDF7","#FEFEFE"],categorical:["#00054A","#FDFDF4","#688B94","#2D5895","#B2C08F","#E8EBC0","#87A089","#133075","#4B769D","#5A829A","#204588","#76958E","#D0D8A4","#99AD88","#F6F6DB","#3C699C","#081C61","#031256","#1A3B7F","#537C9C","#A4B68A","#C1CC98","#7E9A8B","#FAFAE8","#356199","#0E266B","#DEE3B3","#274F90","#6F9091","#618697","#8FA588","#F0F1CD","#43709D","#1D4084","#47739D","#F3F4D4","#658996","#567F9B","#17367A","#FCFBEE","#4F799D","#C9D29E","#93A987","#39659B","#D8DEAB","#ABBB8C","#739290","#B9C693","#F8F8E1","#234A8C","#112B70","#7A978D","#9EB188","#315C97","#829D8A","#05175B","#010C50","#3F6C9D","#0B2065","#5D8499","#2A5392","#8BA388","#6B8D93","#EDEFC7","#E3E7B8","#22488A","#638897","#122E73","#00094D","#AEBD8D","#4D789D","#CDD5A1","#5F8598","#58819A","#071A5E","#0C2368","#18387D","#91A787","#37639A","#EBEDC4","#F2F2D0","#FBFBEB","#74938F","#2F5A96","#335F98","#809B8B","#BDC995","#49759D","#719191","#9BAF88","#F7F7DE","#1B3E82","#A8B88B","#849E89","#557E9B","#E6E9BC","#45719D","#1E4386","#96AB87","#89A188"]},devon:{discrete:["#2C1A4C","#2B1E51","#2B2356","#2A295B","#2A2D60","#293265","#29376A","#283B6E","#274174","#27467A","#274C7F","#275186","#28568C","#2A5C95","#2D609C","#3064A3","#3468AA","#396BB1","#3F70B9","#4774C0","#4F79C6","#597DCC","#6382D1","#6F88D7","#798CDB","#8290DF","#8C95E2","#969AE6","#9E9EE9","#A6A3EB","#ACA7ED","#B1ACEF","#B7B1F0","#BBB5F1","#BFB9F2","#C3BEF3","#C7C2F4","#CCC7F4","#D0CCF5","#D4D0F6","#D8D4F7","#DCD9F8","#E1DEF9","#E5E3FA","#E9E7FB","#EDECFB","#F2F0FC","#F7F6FD","#FBFAFE","#FFFFFF"],categorical:["#2C1A4C","#F8F8FE","#758AD9","#C6C0F3","#28568C","#29376A","#AAA5ED","#DEDCF8","#3D6EB7","#EBE9FB","#9197E4","#3063A2","#274579","#577CCB","#D2CEF6","#2A285A","#BAB3F1","#B2ADEF","#F2F0FC","#274E82","#2A2F62","#CCC7F4","#9E9EE9","#4875C1","#C0BAF2","#2B5D98","#3669AD","#2B2154","#E4E2FA","#8290DF","#D8D4F7","#6784D3","#283E71","#C9C4F4","#BDB7F1","#DBD8F8","#283A6D","#4F79C6","#A4A2EB","#EEEDFC","#CFCBF5","#E8E5FA","#5F80CF","#4272BC","#B6B0F0","#2B1D50","#AEA9EE","#275287","#2A2B5E","#989BE7","#293366","#27497D","#8A94E1","#295A92","#3266A7","#F5F4FD","#7B8DDC","#274174","#2D609C","#2B2558","#6F88D7","#E1DEF9","#3A6CB2","#D5D1F6","#C3BEF3","#2E629F","#3165A4","#8D95E3","#3468AA","#DAD6F7","#D1CDF5","#9B9CE8","#275084","#B8B2F0","#27477B","#6382D1","#4573BF","#A2A0EA","#F7F6FD","#C7C2F4","#F3F2FD","#274376","#8692E0","#2B1F52","#CAC6F4","#ACA7ED","#E3E0F9","#F0EEFC","#E6E4FA","#386AB0","#2C1C4E","#6B86D5","#28396B","#283C6F","#2A5C95","#2A2D60","#BEB9F2","#C2BCF2","#7E8FDD","#3F70B9"]},fes:{discrete:["#0D0D0D","#181818","#212121","#2B2B2B","#343434","#3C3C3C","#454545","#4D4D4D","#565656","#5E5E5E","#656565","#6D6D6D","#747474","#7C7C7C","#848484","#8B8B8B","#939393","#9C9C9C","#A7A7A7","#B1B1B1","#BBBBBB","#C5C5C5","#D1D1D1","#DFDFDF","#ECECEC","#094225","#184822","#2B4F20","#3A5420","#485822","#555B24","#615E26","#6F6229","#7A652B","#86682E","#926B30","#9F7035","#AD7940","#B6834D","#BD8E5C","#C2996C","#C6A47C","#CCB18F","#D1BCA0","#D5C6B0","#DACFC1","#DFD7CF","#E4DFE0","#E8E6ED","#EDEDFC"],categorical:["#0D0D0D","#181818","#212121","#2B2B2B","#343434","#3C3C3C","#454545","#4D4D4D","#565656","#5E5E5E","#656565","#6D6D6D","#747474","#7C7C7C","#848484","#8B8B8B","#939393","#9C9C9C","#A7A7A7","#B1B1B1","#BBBBBB","#C5C5C5","#D1D1D1","#DFDFDF","#ECECEC","#094225","#184822","#2B4F20","#3A5420","#485822","#555B24","#615E26","#6F6229","#7A652B","#86682E","#926B30","#9F7035","#AD7940","#B6834D","#BD8E5C","#C2996C","#C6A47C","#CCB18F","#D1BCA0","#D5C6B0","#DACFC1","#DFD7CF","#E4DFE0","#E8E6ED","#EDEDFC"]},glasgow:{discrete:["#361338","#3B1434","#401530","#45172C","#491828","#4D1924","#511B21","#561C1D","#5B1E18","#602014","#662210","#6B260B","#6F2B07","#723203","#743802","#743E01","#754300","#744900","#744F01","#745402","#735905","#725F0B","#716413","#70691E","#6E6E27","#6C7231","#6B763A","#697B46","#677F4F","#658359","#648763","#628B6C","#618F78","#609381","#60978A","#619B94","#659F9D","#6CA5A8","#74A9B0","#7DADB8","#86B1BF","#8EB4C6","#99B9CE","#A1BCD5","#AABFDB","#B2C3E1","#BBC6E7","#C6CBF0","#D0CFF7","#DBD3FF"],categorical:["#361338","#DBD3FF","#6D702B","#69A3A5","#702D06","#A0BBD3","#638968","#521B20","#745101","#84B0BE","#754001","#5F9587","#BBC6E7","#612013","#45172C","#687D4A","#726210","#618F78","#4B1926","#3E1532","#629C96","#658359","#CACCF3","#76AAB2","#6B763A","#744900","#6A250C","#ADC1DD","#735905","#92B6C9","#591D1A","#743702","#70681C","#4F1A23","#754400","#6D2909","#60998E","#41162F","#744D00","#745503","#B4C3E2","#697A42","#7DADB8","#628C70","#8BB3C3","#561C1D","#D2D0F9","#99B9CE","#3A1435","#6F6C23","#743B01","#60927F","#662210","#648661","#659F9D","#678051","#725E0A","#481829","#6FA6AB","#6C7332","#5D1E17","#A6BED8","#C2C9ED","#723203","#716617","#68240E","#6F6A20","#C6CBF0","#79ABB5","#72600D","#754200","#43162D","#67A1A1","#6B7536","#5F1F15","#735B07","#571C1B","#72A8AF","#744F01","#BEC8EA","#381337","#8EB4C6","#628B6C","#677E4D","#60917B","#639E9A","#4A1827","#A3BDD6","#3C1433","#743901","#632112","#B7C5E5","#4D1924","#65845D","#618E74","#609483","#9CBAD1","#46172A","#87B1C1","#6D712F"]},grayc:{discrete:["#000000","#090909","#111111","#171717","#1C1C1C","#212121","#252525","#2A2A2A","#303030","#343434","#393939","#3D3D3D","#424242","#474747","#4B4B4B","#505050","#545454","#585858","#5D5D5D","#616161","#656565","#696969","#6D6D6D","#717171","#757575","#797979","#7D7D7D","#818181","#858585","#898989","#8E8E8E","#929292","#979797","#9C9C9C","#A1A1A1","#A6A6A6","#ABABAB","#B1B1B1","#B6B6B6","#BCBCBC","#C1C1C1","#C7C7C7","#CECECE","#D5D5D5","#DBDBDB","#E2E2E2","#E8E8E8","#F1F1F1","#F8F8F8","#FFFFFF"],categorical:["#070707","#F9F9F9","#777777","#454545","#AEAEAE","#909090","#292929","#5F5F5F","#D1D1D1","#9E9E9E","#525252","#E4E4E4","#6C6C6C","#BFBFBF","#1A1A1A","#373737","#848484","#595959","#222222","#B6B6B6","#A6A6A6","#3E3E3E","#7D7D7D","#666666","#969696","#8A8A8A","#4B4B4B","#DADADA","#C8C8C8","#313131","#717171","#131313","#EFEFEF","#C4C4C4","#A2A2A2","#424242","#878787","#252525","#2D2D2D","#4F4F4F","#3B3B3B","#808080","#1E1E1E","#BBBBBB","#AAAAAA","#EAEAEA","#696969","#7A7A7A","#DFDFDF","#636363","#565656","#B2B2B2","#0E0E0E","#9A9A9A","#5C5C5C","#747474","#F3F3F3","#333333","#6E6E6E","#D5D5D5","#8D8D8D","#939393","#494949","#CCCCCC","#171717","#BDBDBD","#575757","#C1C1C1","#404040","#828282","#E2E2E2","#151515","#1C1C1C","#0B0B0B","#9C9C9C","#858585","#2F2F2F","#B4B4B4","#888888","#242424","#272727","#3C3C3C","#B0B0B0","#353535","#545454","#5B5B5B","#393939","#D7D7D7","#A4A4A4","#A8A8A8","#959595","#767676","#646464","#989898","#444444","#474747","#111111","#F6F6F6","#ECECEC","#4D4D4D"]},hawaii:{discrete:["#8C0273","#8E0D6E","#8F1569","#901D63","#91235F","#91285A","#922D56","#933252","#94384D","#943D4A","#954246","#964742","#964C3F","#97523B","#985638","#985C34","#996131","#9A662E","#9B6C2A","#9B7226","#9C7823","#9C7E20","#9D841E","#9D8C1C","#9C921C","#9B991D","#9AA021","#97A828","#94AE30","#91B439","#8CB942","#88BE4C","#82C359","#7EC663","#79CA6E","#74CE79","#70D183","#6AD591","#66D89C","#62DCA7","#60DFB2","#5FE2BD","#61E6CA","#67E9D5","#6FEBDE","#7AEEE7","#87EFEE","#98F1F5","#A6F1F9","#B3F2FD"],categorical:["#8C0273","#B3F2FD","#9C951C","#6CD48C","#964D3E","#8ABC48","#9B6D29","#66E8D3","#922E55","#9C801F","#87EFEE","#995D34","#7BC969","#901D63","#60DEB0","#96AA2B","#943D4A","#975439","#82C359","#5FE4C2","#9AA021","#73CE7B","#65D99E","#954544","#9D8A1C","#8E126B","#91B439","#9DF1F7","#73ECE2","#91265C","#9C7724","#9A652E","#93364F","#922A59","#996131","#9D851D","#9D901C","#9A692C","#68D695","#902160","#9B9A1E","#985836","#9B7226","#933252","#77CC72","#9C7B21","#954147","#8D0A6F","#93AF32","#62DCA7","#92F0F3","#8F1867","#7DEEE8","#97513C","#6CEBDB","#61E6CA","#A8F2FA","#964941","#7FC661","#86BF50","#98A526","#70D183","#5FE1B9","#8DB840","#94394D","#9C7923","#8F1569","#985A35","#60E0B4","#9A6B2A","#91245E","#97A828","#9B7425","#6AD591","#95AD2E","#5FE2BD","#60E5C6","#953F48","#933054","#63E7CF","#84C154","#8D0671","#82EFEB","#9B9D1F","#99A323","#88BE4C","#6ED288","#6FEBDE","#9A672D","#91285A","#75CD76","#995F32","#68E9D7","#9B7028","#61DDAB","#943B4B","#933450","#8DF0F0","#8F1A65","#81C45D"]},imola:{discrete:["#1A33B3","#1C37B1","#1E3AAF","#203EAD","#2242AB","#2345AA","#2548A8","#274CA6","#2950A4","#2A53A3","#2C56A1","#2E599F","#2F5D9E","#32609B","#346499","#366797","#386A95","#3B6C92","#3E708F","#41738C","#44768A","#467987","#4A7C85","#4E8082","#518480","#56887E","#5A8C7D","#5F927B","#64967A","#689B79","#6DA078","#72A576","#78AB75","#7DB074","#82B572","#87BA71","#8CBF70","#93C66E","#98CB6D","#9ED06C","#A4D66A","#ACDB69","#B5E268","#BFE767","#C8EB67","#D3F066","#DDF466","#EAF866","#F5FB66","#FFFF66"],categorical:["#1A33B3","#FFFF66","#54867F","#305E9D","#91C36F","#3F718E","#2549A8","#BDE667","#70A377","#2B53A2","#376896","#80B373","#A3D56B","#DDF466","#203EAD","#487B86","#62947A","#2D59A0","#88BB71","#5B8D7D","#CDED66","#4E8082","#EEF966","#33639A","#284EA5","#44768A","#2344AA","#AFDE69","#3B6C92","#78AB75","#1D39B0","#99CC6D","#699C79","#3D6F90","#2C56A1","#2F5B9E","#5E917B","#4B7D84","#9ED06C","#1F3CAE","#C4EA67","#84B772","#274CA6","#D5F066","#2951A4","#74A776","#578A7E","#2446A9","#1C36B1","#A9D96A","#95C86E","#467888","#2141AC","#7CAF74","#356598","#B5E268","#66987A","#396A94","#F7FC66","#8CBF70","#E6F666","#32609B","#518380","#41738C","#6DA078","#6B9E78","#B9E468","#7AAD74","#528580","#32629B","#86B971","#3C6E91","#5C8F7C","#C8EB67","#ACDB69","#D1EF66","#E2F566","#97CA6D","#1B35B2","#1C37B0","#2345AA","#2F5D9E","#1F3DAE","#457789","#3A6B93","#598B7D","#D9F266","#346499","#386995","#A6D76A","#366797","#274DA6","#56887E","#A1D36B","#42748B","#7EB173","#72A576","#477987","#4C7F83","#F2FB66"]},lajolla:{discrete:["#191900","#1E1B02","#221C05","#271E08","#2C200B","#31220E","#362411","#3C2614","#442817","#4B2B1B","#532D1F","#5B3023","#633328","#6E362D","#783932","#813C37","#8B3F3B","#96423F","#A24543","#AD4746","#B74A48","#C04D49","#C9514B","#D1564C","#D75C4D","#DB634E","#DD694F","#E0714F","#E17750","#E37D50","#E48351","#E58951","#E79052","#E89652","#E99C52","#EAA253","#EBA853","#EDAF54","#EEB555","#F0BC57","#F1C25A","#F3CA5F","#F5D369","#F7DA74","#F9E282","#FBE890","#FCEF9F","#FDF5B0","#FEFABE","#FFFECB"],categorical:["#191900","#FFFECB","#D85F4D","#ECAC54","#653329","#F7D971","#A44544","#E58751","#362411","#E1744F","#C44E4A","#E99A52","#4B2B1B","#833D38","#F1C159","#FCEF9F","#271E08","#FEF7B6","#402716","#D0554C","#FAE587","#E79052","#EFB655","#B54947","#201C04","#E37D50","#743830","#DD694F","#EBA353","#94413E","#572F21","#F4CD61","#2E210C","#FDF3AB","#32220F","#241D06","#F5D369","#7B3B34","#1D1B02","#F0BC57","#5E3125","#F8DF7C","#512D1E","#CA514B","#E48251","#E68C51","#EA9E53","#E89552","#BC4C49","#6C362C","#EDB154","#9C4341","#E27950","#FBEA93","#3B2513","#FEFBC0","#452918","#EBA853","#F2C75C","#8B3F3B","#DB644E","#AD4746","#DF6E4F","#D55A4D","#2B200A","#783932","#E79352","#D75C4D","#FEF9BB","#EDAF54","#E0714F","#7F3C36","#613227","#F7DC77","#C7504B","#F1C45A","#30210D","#F4D065","#1E1B03","#FAE78D","#F9E282","#DA614E","#392412","#4E2C1D","#E99C52","#EFB956","#221C05","#EBA553","#FDF5B0","#984240","#E38050","#8F403D","#542E20","#ECAA54","#E68E51","#70372E","#DE6C4F","#B94A48","#291F09","#1B1A01"]},lapaz:{discrete:["#1A0C64","#1C1368","#1E196D","#202071","#212675","#222B79","#23317D","#253681","#263C85","#274189","#29478C","#2A4C8F","#2C5192","#2E5795","#305C98","#32609A","#35659C","#386A9E","#3C70A0","#3F74A1","#4379A2","#487DA3","#4D81A3","#5386A4","#588AA3","#5E8EA3","#6591A2","#6C95A1","#7398A0","#7A9A9E","#809D9D","#879F9B","#90A199","#97A397","#9EA596","#A5A795","#ADAA95","#B7AD96","#BFB199","#C8B69C","#D2BBA2","#DAC1A8","#E4C9B2","#EBCFBB","#F1D5C4","#F5DBCD","#F9E1D6","#FBE8E1","#FDEDEA","#FEF2F3"],categorical:["#1A0C64","#FEF2F3","#5B8BA3","#B3AC96","#2C5292","#3C70A0","#EACEB9","#859E9C","#24327E","#6F96A1","#33619A","#202071","#D0BAA0","#9BA496","#F9E1D6","#4A7FA3","#284289","#90A199","#FCEAE5","#1D176B","#37699D","#F3D8C8","#A7A895","#5285A4","#7A9A9E","#2F5A97","#4278A2","#263A84","#6591A2","#C1B299","#DEC3AB","#222978","#2A4B8E","#5688A4","#D7BEA6","#FDEEEC","#608EA3","#EFD3C0","#A1A696","#6A94A1","#FBE6DD","#ADAA95","#F6DDCF","#4E82A3","#2E5695","#3A6D9F","#C8B69C","#1C1268","#232D7B","#3F74A1","#467BA3","#1E1C6E","#7F9C9D","#BAAF97","#253681","#315E99","#29478C","#E4C9B2","#74989F","#273E87","#212575","#95A398","#8AA09A","#35659C","#2B4F91","#23307C","#E7CBB5","#F1D5C4","#2B4D90","#202373","#588AA3","#D3BCA3","#5487A4","#447AA2","#6792A2","#24347F","#253882","#ECD0BD","#879F9B","#305C98","#E1C6AF","#1E196D","#5D8DA3","#AAA995","#386B9E","#487DA3","#77999F","#F7DFD3","#BEB098","#1F1E70","#325F99","#4176A2","#F4DACB","#4C80A3","#2D5494","#8DA099","#6C95A1","#FAE3DA","#FDECE8","#B7AD96"]},lipari:{discrete:["#031326","#05192F","#062038","#092844","#0C2E4D","#103557","#163C5F","#1E4368","#294B70","#345075","#3E5578","#47587A","#4F5B7B","#575C7A","#5D5D79","#635E78","#695E76","#6E5F75","#765F73","#7C6071","#826070","#89606E","#90616C","#98616A","#A06268","#A86266","#B06364","#BA6462","#C36660","#CB685F","#D46B5E","#DB705F","#E27760","#E77E63","#E98567","#EA8D6B","#EA946F","#E89C75","#E7A279","#E6A87E","#E5AF84","#E5B58A","#E6BD92","#E7C49A","#EACCA3","#EDD3AD","#F0DBB7","#F5E5C4","#F9EDCF","#FDF5DA"],categorical:["#031326","#FDF5DA","#A56267","#525B7A","#E99B74","#785F72","#DA6F5E","#183E61","#E7C398","#8D616D","#365176","#092844","#655E77","#E98466","#BF6561","#F0DBB7","#E5AD82","#B26364","#EBCFA7","#5C5D79","#061D35","#25486D","#0E3353","#EA906D","#98616A","#E37861","#E5B88C","#826070","#CD685F","#6E5F75","#45587A","#F6E8C9","#E7A37A","#615E78","#E77E63","#D46B5E","#9F6268","#E99570","#93616B","#87606E","#7D6071","#F3E1C0","#575C7A","#0B2D4B","#2D4D72","#E6A87E","#E9C99F","#FAEED1","#1E4368","#EA8A69","#B86462","#6A5E76","#AB6365","#735F74","#DF735F","#E5B287","#13385A","#05182D","#E6BD92","#3E5578","#EDD5AF","#07223C","#C6665F","#4C5A7A","#E8A077","#B56363","#FBF1D6","#A26267","#E6C095","#0A2A48","#F8EBCD","#EACCA3","#AE6364","#7A5F72","#635E78","#E98768","#041629","#715F74","#ECD2AB","#A86266","#8A606E","#96616B","#545C7A","#EFD8B3","#F5E5C4","#9B6169","#F2DEBB","#765F73","#6C5F75","#294B70","#22466B","#E89D76","#E88165","#BC6461","#E6A67C","#85606F","#C36660","#1B4064","#D06A5E","#103557"]},lisbon:{discrete:["#E6E5FF","#D8DCF7","#CBD2EF","#BBC6E5","#ADBCDE","#A0B3D6","#93A9CE","#86A0C6","#7794BD","#6A8BB5","#5E81AC","#5177A4","#456E9B","#38628F","#2F5984","#274F78","#20476D","#1B3F61","#173653","#142E48","#12283E","#112233","#111D2A","#121921","#15181B","#181A18","#1E1D17","#252419","#2D2B1C","#353220","#3E3A25","#46422A","#514C31","#5A5536","#645E3C","#6D6741","#777047","#837B4F","#8D8556","#988F5E","#A29A67","#ADA470","#B9B17D","#C3BC89","#CDC795","#D7D2A2","#E0DCAF","#ECE9BE","#F5F4CB","#FFFFD9"],categorical:["#E6E5FF","#D8DCF7","#CBD2EF","#BBC6E5","#ADBCDE","#A0B3D6","#93A9CE","#86A0C6","#7794BD","#6A8BB5","#5E81AC","#5177A4","#456E9B","#38628F","#2F5984","#274F78","#20476D","#1B3F61","#173653","#142E48","#12283E","#112233","#111D2A","#121921","#15181B","#181A18","#1E1D17","#252419","#2D2B1C","#353220","#3E3A25","#46422A","#514C31","#5A5536","#645E3C","#6D6741","#777047","#837B4F","#8D8556","#988F5E","#A29A67","#ADA470","#B9B17D","#C3BC89","#CDC795","#D7D2A2","#E0DCAF","#ECE9BE","#F5F4CB","#FFFFD9"]},managua:{discrete:["#FFCF67","#F9C564","#F3BB60","#EBB05D","#E5A659","#DF9D56","#D99554","#D38C51","#CC824D","#C67B4B","#C07348","#B96C46","#B36444","#AB5C41","#A4553F","#9D4F3D","#95483C","#8E423A","#843B39","#7C3639","#743139","#6D2D3A","#662A3D","#5F2941","#5A2846","#552A4C","#522C53","#4F315D","#4D3566","#4C3B6F","#4C4179","#4C4883","#4D518E","#4F5897","#51609F","#5367A7","#556FAE","#5878B6","#5B80BC","#5E88C2","#6190C8","#6498CE","#68A3D5","#6BACDB","#6FB5E1","#72BEE6","#76C7EC","#7AD3F3","#7DDDF9","#81E7FF"],categorical:["#FFCF67","#F9C564","#F3BB60","#EBB05D","#E5A659","#DF9D56","#D99554","#D38C51","#CC824D","#C67B4B","#C07348","#B96C46","#B36444","#AB5C41","#A4553F","#9D4F3D","#95483C","#8E423A","#843B39","#7C3639","#743139","#6D2D3A","#662A3D","#5F2941","#5A2846","#552A4C","#522C53","#4F315D","#4D3566","#4C3B6F","#4C4179","#4C4883","#4D518E","#4F5897","#51609F","#5367A7","#556FAE","#5878B6","#5B80BC","#5E88C2","#6190C8","#6498CE","#68A3D5","#6BACDB","#6FB5E1","#72BEE6","#76C7EC","#7AD3F3","#7DDDF9","#81E7FF"]},navia:{discrete:["#031327","#041930","#051E3A","#052546","#062B50","#06315A","#073764","#083E6D","#0B4578","#0E4C80","#115286","#15588B","#195E8E","#1E6491","#216991","#246D91","#27718F","#2A748E","#2D788C","#307A8A","#337D89","#368087","#398385","#3C8683","#3F8981","#428C7F","#468F7D","#4A937A","#4E9678","#529A76","#579E73","#5BA271","#62A86E","#67AD6B","#6EB269","#76B768","#7FBD68","#8CC56A","#98CB6F","#A4D176","#B1D67F","#BCDB89","#C9E096","#D3E3A1","#DCE7AC","#E3EAB6","#EAEDBF","#F1F0CA","#F7F2D2","#FCF4D9"],categorical:["#031327","#FCF4D9","#408A80","#87C269","#1B608F","#59A072","#073966","#D1E39F","#2F798B","#EAEDBF","#052546","#266F90","#6BB06A","#0E4D81","#AED57D","#4C947A","#378186","#DFE8B0","#337D89","#2A748E","#14578A","#051C36","#9ACC70","#0A4374","#468F7D","#529A76","#F4F1CD","#062F56","#C1DC8D","#206891","#78B968","#62A86E","#3C8583","#569D74","#236C91","#F8F3D3","#D8E5A8","#0C487B","#04182E","#71B469","#B8D985","#07345E","#05213E","#4F9778","#5DA470","#3E8882","#062A4E","#7FBD68","#EFEFC6","#C9E096","#115286","#2C768D","#1E6491","#49917B","#66AC6C","#28718F","#A4D176","#90C76C","#438C7F","#175C8D","#083E6D","#E5EAB8","#317B8A","#357F87","#398385","#B3D781","#0D4A7E","#1C6290","#052342","#579F73","#9FCE73","#448D7E","#051A32","#FAF3D6","#428B7F","#29738F","#104F84","#5FA66F","#509877","#8CC56A","#094071","#2D788C","#083B6A","#D5E4A3","#2B758D","#226A91","#04162B","#BCDB89","#47907C","#4D9579","#E2E9B4","#7BBB68","#6EB269","#135488","#4A937A","#F1F0CA","#5BA271","#C5DE92","#F6F2D0","#CDE19B"]},naviaw:{discrete:["#041427","#051A31","#05203B","#062747","#072D52","#08345C","#0A3A66","#0C416F","#0F4979","#135080","#175686","#1B5D8A","#1F628D","#23698F","#276D8F","#2A728F","#2D758E","#30798D","#347D8B","#378089","#3A8388","#3D8686","#408984","#448C82","#489080","#4B937E","#50977C","#559C79","#5AA077","#5FA575","#65AA73","#6CAF71","#76B671","#7FBD71","#89C474","#95CB78","#A2D27F","#B1D98A","#BEDF95","#C9E5A1","#D3E9AD","#DBEDB9","#E4F1C6","#E9F4D0","#EEF6D9","#F2F8E1","#F6FAE9","#F9FCF1","#FCFDF7","#FEFEFD"],categorical:["#041427","#FBFDF6","#478F80","#9FD07D","#1F628D","#64A973","#E3F0C4","#0A3A66","#337C8B","#C7E49E","#7DBC71","#549B7A","#2A718F","#135080","#F2F8E1","#3C8586","#062747","#D7EBB2","#418A83","#B4DB8C","#2E778D","#6FB271","#EBF5D4","#0E4574","#051D37","#4D957D","#256B8F","#195A88","#388189","#F7FAEC","#5CA276","#8CC574","#073056","#31798C","#367E8A","#69AD72","#E7F3CC","#104A7A","#95CB78","#EFF6DB","#0B406D","#2C748E","#4A927F","#DDEEBB","#50987C","#165584","#589E78","#76B671","#3F8785","#05192F","#BEDF95","#448C82","#22678E","#06223F","#A9D684","#08355E","#CFE8A8","#F9FCF1","#286E8F","#85C172","#072C50","#F5F9E7","#1C5F8B","#3A8387","#60A675","#F3F9E4","#0C4271","#266D8F","#81BE72","#0A3D6A","#4B937E","#9ACD7B","#EDF5D7","#90C876","#A4D381","#378089","#1B5D8A","#489080","#145282","#DAECB6","#67AB73","#CBE6A3","#B9DD90","#3D8686","#23698F","#6CAF71","#FAFCF3","#79B971","#D3E9AD","#5AA077","#458E81","#72B471","#327B8C","#E5F1C8","#051B33","#F8FBEE","#062443","#398288","#2B728F","#06294C"]},nuuk:{discrete:["#05598C","#0E5B8B","#155C89","#1C5E87","#226085","#276184","#2C6383","#326682","#386982","#3E6C82","#446F82","#4A7283","#517584","#587A86","#5F7D88","#66818A","#6C858C","#73898E","#7B8E91","#819192","#879594","#8D9996","#939C97","#99A097","#9EA498","#A2A798","#A6AA97","#ABAD96","#AEAF95","#B1B194","#B3B492","#B6B690","#B8B88E","#BABA8C","#BDBC8A","#BFBE88","#C1C187","#C4C385","#C7C684","#CAC983","#CDCD83","#D2D184","#D7D787","#DDDD8B","#E3E290","#E8E895","#EEEE9C","#F4F4A4","#F9F9AB","#FEFEB2"],categorical:["#05598C","#FEFEB2","#A1A698","#537785","#C3C385","#B5B591","#7D8F91","#2D6483","#DDDD8B","#919B96","#BCBC8B","#3F6C82","#CDCD83","#1C5E87","#ADAE95","#68838B","#EEEE9C","#A7AA97","#879594","#C8C783","#F6F6A7","#135C89","#B9B98E","#497183","#73898E","#366882","#C0BF88","#D4D486","#99A097","#B1B293","#5E7D88","#256185","#E6E693","#829293","#788C90","#9DA398","#AAAC96","#E1E18F","#3B6A82","#638089","#B3B492","#A4A897","#446F82","#BABA8C","#D8D888","#185D88","#8C9895","#215F86","#BEBD89","#B7B78F","#CACA83","#4E7484","#C1C186","#959E97","#F2F2A1","#AFB094","#326682","#587A86","#296284","#FAFAAD","#6E868C","#C5C584","#D1D084","#0D5B8B","#E9E997","#DFDF8D","#66818A","#B0B194","#5B7B87","#2B6383","#859493","#CCCB83","#F8F8AA","#D2D285","#1F5F86","#70878D","#4B7383","#768B8F","#FCFCAF","#A9AB97","#BFBE88","#C9C983","#346782","#DBDA89","#236085","#BDBD8A","#BAB98D","#B8B88E","#2F6583","#939C97","#9FA498","#A2A798","#CFCF84","#B4B591","#C4C485","#979F97","#F0F09E","#155C89","#9BA298","#517584"]},oleron:{discrete:["#1A2659","#212E61","#293568","#323F72","#3A477A","#424F82","#4A578A","#535F92","#5D699C","#6572A5","#6E7BAE","#7784B7","#808DC0","#8B97CA","#94A1D3","#9DAADC","#A6B3E5","#AFBCEC","#B9C6F2","#C0CDF5","#C7D4F7","#CEDAF9","#D4E1FB","#DCE9FD","#E3F0FE","#1F4E00","#2C5100","#3A5600","#445900","#4F5C02","#5A6005","#65660C","#736D18","#7E7423","#8A7B2E","#94823A","#9F8945","#AC9253","#B79A5E","#C3A36A","#CEAC75","#D9B581","#E5C090","#EDC99D","#F2D2A9","#F6DAB5","#F8E2C0","#FAECCE","#FBF4DA","#FDFDE6"],categorical:["#1A2659","#212E61","#293568","#323F72","#3A477A","#424F82","#4A578A","#535F92","#5D699C","#6572A5","#6E7BAE","#7784B7","#808DC0","#8B97CA","#94A1D3","#9DAADC","#A6B3E5","#AFBCEC","#B9C6F2","#C0CDF5","#C7D4F7","#CEDAF9","#D4E1FB","#DCE9FD","#E3F0FE","#1F4E00","#2C5100","#3A5600","#445900","#4F5C02","#5A6005","#65660C","#736D18","#7E7423","#8A7B2E","#94823A","#9F8945","#AC9253","#B79A5E","#C3A36A","#CEAC75","#D9B581","#E5C090","#EDC99D","#F2D2A9","#F6DAB5","#F8E2C0","#FAECCE","#FBF4DA","#FDFDE6"]},oslo:{discrete:["#010101","#04070B","#060C13","#0A121B","#0C1620","#0D1927","#0E1D2D","#0F2133","#10263C","#112A43","#122E4A","#133251","#153758","#173C61","#194169","#1B4670","#1E4A78","#214F80","#255589","#295A91","#2E5F99","#3364A1","#3A6AA9","#4371B2","#4B77B9","#537DBE","#5B83C3","#6489C6","#6B8EC8","#7292C9","#7896C9","#7E9ACA","#859ECA","#8BA2C9","#91A6C9","#97A9C9","#9DADC9","#A4B2CA","#AAB6CA","#B1BBCB","#B8BFCD","#BFC5CF","#C7CCD3","#CFD2D8","#D7D9DD","#DEE0E2","#E6E7E9","#EFF0F1","#F7F7F8","#FFFFFF"],categorical:["#030609","#F9F9F9","#507BBC","#163B5E","#A0AFC9","#7B98CA","#27588E","#0E2032","#CACED5","#122D48","#3767A6","#1D4875","#8DA3C9","#E2E3E5","#678BC7","#B4BDCC","#0C151F","#BFC5CF","#97A9C9","#4371B2","#10263D","#080E16","#7292C9","#215081","#2E5F99","#AAB6CA","#ECEDEE","#0D1A28","#143454","#D5D8DC","#5B83C3","#19426A","#859ECA","#13314E","#0E1D2D","#3D6CAC","#6C8FC8","#7795C9","#F3F3F4","#4976B8","#245488","#DBDDE0","#112A43","#92A6C9","#C5C9D2","#809BCA","#0F2337","#3263A0","#050A10","#B9C1CD","#1F4C7B","#183E64","#A5B3CA","#0A121B","#9CACC9","#6187C5","#0D1824","#8AA1CA","#2A5B93","#547EBF","#D1D3D9","#E6E7E9","#1B456F","#B0BACB","#153758","#7494C9","#D8DADE","#6A8DC8","#90A5C9","#99ABC9","#235285","#133251","#060C13","#406EAF","#7E9ACA","#173C61","#4C78BA","#122F4B","#1C4772","#87A0CA","#CED1D7","#C2C7D1","#0F253A","#2C5D96","#C7CCD3","#112B45","#EFF0F1","#6F90C9","#0E1E2F","#ADB8CB","#7997CA","#4673B5","#15395B","#091018","#194067","#30619C","#94A8C9","#F6F6F6","#0F2135","#A3B1CA"]},roma:{discrete:["#7E1700","#832504","#883008","#8F3C0C","#934610","#984E14","#9C5717","#A05F1B","#A5681F","#A97023","#AD7826","#B0802B","#B58930","#BA9437","#BE9D3E","#C2A647","#C7B051","#CBBA5D","#CFC66D","#D1CF7B","#D2D78A","#D2DE98","#D0E4A6","#CBE8B4","#C4EABE","#BDEAC6","#B3E9CD","#A6E6D2","#9BE2D5","#8EDDD7","#81D7D7","#74CFD6","#64C6D5","#59BDD2","#4FB5D0","#46ACCC","#3EA4C9","#379AC5","#3292C2","#2E8ABF","#2B82BB","#287AB8","#2471B4","#2269B0","#1F60AD","#1C58A9","#194FA5","#1344A0","#0C3B9C","#033198"],categorical:["#7E1700","#832504","#883008","#8F3C0C","#934610","#984E14","#9C5717","#A05F1B","#A5681F","#A97023","#AD7826","#B0802B","#B58930","#BA9437","#BE9D3E","#C2A647","#C7B051","#CBBA5D","#CFC66D","#D1CF7B","#D2D78A","#D2DE98","#D0E4A6","#CBE8B4","#C4EABE","#BDEAC6","#B3E9CD","#A6E6D2","#9BE2D5","#8EDDD7","#81D7D7","#74CFD6","#64C6D5","#59BDD2","#4FB5D0","#46ACCC","#3EA4C9","#379AC5","#3292C2","#2E8ABF","#2B82BB","#287AB8","#2471B4","#2269B0","#1F60AD","#1C58A9","#194FA5","#1344A0","#0C3B9C","#033198"]},romao:{discrete:["#733957","#773850","#7A3849","#7E3942","#823C3D","#863F38","#8A4334","#8E4831","#94502E","#98572C","#9D5F2B","#A3672C","#A8712E","#AF7D32","#B58837","#BB933F","#C19F47","#C6AA52","#CDB761","#D1C26E","#D4CB7B","#D6D388","#D5D995","#D3DEA3","#CEE0AD","#C8E1B6","#C1E1BE","#B6DEC5","#ABDBC9","#A0D6CC","#94D0CE","#88C9CF","#7BC0CE","#70B8CD","#67AFCA","#5FA6C7","#589CC4","#5291BE","#4F88B9","#4E7EB3","#4F75AC","#516BA4","#55609A","#595891","#5D5087","#62497D","#664474","#6B3F69","#6F3B60","#723959"],categorical:["#733957","#773850","#7A3849","#7E3942","#823C3D","#863F38","#8A4334","#8E4831","#94502E","#98572C","#9D5F2B","#A3672C","#A8712E","#AF7D32","#B58837","#BB933F","#C19F47","#C6AA52","#CDB761","#D1C26E","#D4CB7B","#D6D388","#D5D995","#D3DEA3","#CEE0AD","#C8E1B6","#C1E1BE","#B6DEC5","#ABDBC9","#A0D6CC","#94D0CE","#88C9CF","#7BC0CE","#70B8CD","#67AFCA","#5FA6C7","#589CC4","#5291BE","#4F88B9","#4E7EB3","#4F75AC","#516BA4","#55609A","#595891","#5D5087","#62497D","#664474","#6B3F69","#6F3B60","#723959"]},tofino:{discrete:["#DED9FF","#D0CFF9","#C3C6F3","#B3BBEC","#A6B1E6","#98A8E1","#8B9FDB","#7E95D4","#6E89CB","#617FC3","#5575B8","#4A6BAC","#4262A0","#395790","#334F83","#2E4776","#293F6A","#24385D","#1F304F","#1B2943","#172338","#141D2E","#111824","#0F151B","#0D1516","#0D1712","#0F1B12","#112113","#142716","#162F19","#1A361C","#1D3E20","#224825","#26512A","#2A5A2E","#2E6233","#336C38","#39773E","#3F8144","#488B4A","#529551","#5FA059","#70AB63","#7FB46B","#8EBD73","#9DC57B","#ACCD83","#BDD68C","#CCDE94","#DBE69B"],categorical:["#DED9FF","#D0CFF9","#C3C6F3","#B3BBEC","#A6B1E6","#98A8E1","#8B9FDB","#7E95D4","#6E89CB","#617FC3","#5575B8","#4A6BAC","#4262A0","#395790","#334F83","#2E4776","#293F6A","#24385D","#1F304F","#1B2943","#172338","#141D2E","#111824","#0F151B","#0D1516","#0D1712","#0F1B12","#112113","#142716","#162F19","#1A361C","#1D3E20","#224825","#26512A","#2A5A2E","#2E6233","#336C38","#39773E","#3F8144","#488B4A","#529551","#5FA059","#70AB63","#7FB46B","#8EBD73","#9DC57B","#ACCD83","#BDD68C","#CCDE94","#DBE69B"]},tokyo:{discrete:["#1C0E34","#241036","#2D1339","#37163D","#3F1A40","#481E43","#4F2345","#562948","#5D304A","#62354C","#663B4D","#69404E","#6B454F","#6D4B50","#6E4F50","#6F5251","#6F5651","#705951","#715C52","#715F52","#716252","#726452","#726753","#736B53","#736E53","#747153","#757554","#757A54","#767E55","#778355","#788856","#798E57","#7B9558","#7C9B5A","#7EA25C","#81A95E","#84B062","#88B968","#8DC16E","#93CA76","#9BD27F","#A4DA8A","#AFE398","#BAEAA4","#C5EFB0","#CFF4BB","#D8F7C5","#E2F9CF","#E9FBD7","#EFFCDD"],categorical:["#1C0E34","#EFFCDD","#747053","#6C4750","#87B666","#B8E8A1","#512446","#715D52","#798B56","#7D9F5B","#37163D","#726653","#99D07D","#63374C","#6F5451","#D8F7C5","#767C54","#705951","#5B2D49","#7B9558","#441D41","#291238","#E5FAD2","#C9F1B4","#716252","#81AA5F","#683F4E","#736B53","#6E4E50","#757654","#8EC370","#A7DD8E","#778455","#747354","#84B062","#231036","#93CA76","#DFF9CC","#30143A","#A0D785","#7FA45D","#EAFBD8","#6A434F","#C1EDAB","#736D53","#562948","#6D4B50","#7A9057","#7C9A59","#4B2044","#715F52","#663B4D","#D1F4BD","#705651","#8ABD6A","#6E5151","#AFE398","#5F324B","#757954","#3E193F","#726853","#726452","#778055","#705B52","#788756","#61344C","#746E53","#ABE093","#532747","#85B364","#7EA25C","#261137","#736C53","#E8FBD5","#4E2245","#88B968","#798E57","#767E55","#726753","#757754","#715E52","#3A183E","#6E4F51","#778255","#7B9759","#DCF8C9","#EDFCDA","#411B40","#7D9C5A","#767B54","#726352","#6F5551","#726552","#82AD60","#D5F6C1","#34153C","#9CD481","#747454","#C5EFB0","#481E43"]},turku:{discrete:["#000000","#090908","#111110","#181816","#1D1D1A","#22221F","#272723","#2C2C27","#33322B","#38382F","#3D3D32","#424235","#474738","#4E4D3C","#53523E","#585841","#5D5D43","#626246","#686848","#6E6D4B","#73724D","#797750","#7F7D52","#878356","#8E8859","#968E5C","#9D9360","#A79864","#AF9C68","#B69F6C","#BEA270","#C4A474","#CCA579","#D1A67D","#D7A781","#DBA886","#E0A98B","#E6AB92","#EAAD98","#EFB09F","#F2B4A7","#F6B9AE","#F9BFB7","#FBC4BF","#FDC9C6","#FECFCC","#FED4D3","#FFDBDA","#FFE0E0","#FFE6E6"],categorical:["#070707","#FFE6E6","#948D5B","#E5AA90","#4D4C3B","#2C2C27","#C3A374","#6D6C4A","#FBC4BF","#D6A780","#F2B4A7","#1C1C19","#3D3D32","#AC9A67","#7E7C52","#FED6D4","#5D5D43","#35342D","#DDA888","#141312","#55543F","#242420","#FDCDCA","#F7BCB3","#898456","#B8A06D","#ECAE9B","#CDA57A","#FFDEDD","#646447","#454537","#9F9461","#76744E","#71704C","#30302A","#414135","#181816","#FCC8C4","#EFB1A1","#838054","#F5B8AD","#E1A98C","#C8A477","#686848","#595941","#20201D","#8E8859","#D1A67D","#B29D6A","#E9AC95","#BEA270","#FED1CF","#0E0E0D","#A59764","#DAA784","#282823","#F9C0B9","#51503D","#393930","#FFDAD9","#49493A","#606045","#FFE2E1","#9A915E","#797750","#F4B6AA","#F6BAB0","#CBA578","#FFD8D6","#FECFCC","#262622","#C0A272","#868255","#1A1A18","#FAC2BC","#8B8658","#E3AA8E","#161614","#4F4E3C","#C6A475","#2E2E28","#BBA16F","#6B6A49","#E7AB93","#CFA67C","#626246","#53523E","#5B5B42","#FED3D1","#7C7A51","#817E53","#73724D","#FFDCDB","#37372E","#F8BEB6","#0B0B0A","#575740","#DFA98A","#474738","#B59F6C"]},vanimo:{discrete:["#FFCDFD","#F7BEF2","#F0B0E8","#E6A0DC","#DE93D2","#D786C8","#CF7ABF","#C76FB5","#BD63AA","#B45AA1","#AB5198","#A1498E","#964184","#883977","#7C326B","#6E2C60","#612654","#542148","#451C3B","#391931","#2F1728","#281521","#22141C","#1D1417","#1A1414","#191612","#191811","#1B1D11","#1D2212","#212913","#253014","#2B3916","#324419","#384D1B","#3F561E","#456021","#4C6924","#547427","#5A7C2A","#60852E","#678E32","#6E9737","#77A33F","#7FAE47","#88BA51","#92C65D","#9CD26B","#A9E27F","#B3EF92","#BEFDA5"],categorical:["#FFCDFD","#F7BEF2","#F0B0E8","#E6A0DC","#DE93D2","#D786C8","#CF7ABF","#C76FB5","#BD63AA","#B45AA1","#AB5198","#A1498E","#964184","#883977","#7C326B","#6E2C60","#612654","#542148","#451C3B","#391931","#2F1728","#281521","#22141C","#1D1417","#1A1414","#191612","#191811","#1B1D11","#1D2212","#212913","#253014","#2B3916","#324419","#384D1B","#3F561E","#456021","#4C6924","#547427","#5A7C2A","#60852E","#678E32","#6E9737","#77A33F","#7FAE47","#88BA51","#92C65D","#9CD26B","#A9E27F","#B3EF92","#BEFDA5"]},vik:{discrete:["#001261","#011A66","#02226B","#022B71","#023376","#023A7B","#034280","#034A85","#06548B","#0B5D91","#136697","#1E6F9D","#2B79A4","#3C85AC","#4B90B3","#5A9ABA","#6AA4C1","#7AAEC8","#8DBAD0","#9DC4D6","#ADCDDD","#BDD6E3","#CCDFE8","#DEE6E9","#E8E7E5","#EEE3DC","#EEDBD0","#EBD0C0","#E7C6B2","#E3BCA5","#DFB298","#DBA88B","#D69D7C","#D29470","#CE8B64","#CA8258","#C6794C","#C26E3F","#BE6533","#B85C28","#B2511D","#A94512","#9C3709","#912D06","#872406","#7E1D06","#741506","#6A0D07","#620607","#590008"],categorical:["#001261","#011A66","#02226B","#022B71","#023376","#023A7B","#034280","#034A85","#06548B","#0B5D91","#136697","#1E6F9D","#2B79A4","#3C85AC","#4B90B3","#5A9ABA","#6AA4C1","#7AAEC8","#8DBAD0","#9DC4D6","#ADCDDD","#BDD6E3","#CCDFE8","#DEE6E9","#E8E7E5","#EEE3DC","#EEDBD0","#EBD0C0","#E7C6B2","#E3BCA5","#DFB298","#DBA88B","#D69D7C","#D29470","#CE8B64","#CA8258","#C6794C","#C26E3F","#BE6533","#B85C28","#B2511D","#A94512","#9C3709","#912D06","#872406","#7E1D06","#741506","#6A0D07","#620607","#590008"]},viko:{discrete:["#4F1A3D","#4B1D43","#48214A","#432653","#3F2C5B","#3C3263","#38396C","#354174","#334B7F","#345487","#365E8F","#3B6797","#42719E","#4D7DA6","#5787AD","#6391B4","#709ABA","#7DA4BF","#8EAEC4","#9BB5C7","#A9BBC8","#B5C0C8","#C0C2C5","#CBC2BF","#D2C0B8","#D6BDAF","#D9B7A6","#D9AF99","#D8A88D","#D6A082","#D39776","#CF8D6B","#C8825D","#C27752","#BB6D47","#B3623D","#AA5633","#9F492A","#953E25","#8C3521","#822C1F","#7A251E","#721F1F","#6B1A21","#661824","#611627","#5C152B","#571631","#531736","#50193C"],categorical:["#4F1A3D","#4B1D43","#48214A","#432653","#3F2C5B","#3C3263","#38396C","#354174","#334B7F","#345487","#365E8F","#3B6797","#42719E","#4D7DA6","#5787AD","#6391B4","#709ABA","#7DA4BF","#8EAEC4","#9BB5C7","#A9BBC8","#B5C0C8","#C0C2C5","#CBC2BF","#D2C0B8","#D6BDAF","#D9B7A6","#D9AF99","#D8A88D","#D6A082","#D39776","#CF8D6B","#C8825D","#C27752","#BB6D47","#B3623D","#AA5633","#9F492A","#953E25","#8C3521","#822C1F","#7A251E","#721F1F","#6B1A21","#661824","#611627","#5C152B","#571631","#531736","#50193C"]}};function ct(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const dt={waves:"batlow",blksand:"tokyo",breeze:"imola",magma:"batlow",ribbon:"hawaii",stars:"batlow",folds:"imola"},ut={[st.ADVERT]:1,[st.TXT_MSG]:4,[st.GRP_TXT]:2,[st.RESPONSE]:8,[st.REQ]:13,[st.ANON_REQ]:7,[st.ACK]:11,[st.PATH]:24,[st.TRACE]:16,[st.GRP_DATA]:34,[st.MULTIPART]:52,[st.RAW_CUSTOM]:14};function ht(){let e="breeze dark",t=!0;if("undefined"!=typeof window){e=localStorage.getItem("pymc-theme-id")||"breeze dark";const a=Ee(e);t=(null==a?void 0:a.meta.isDark)??!0}const a=dt[e]??"batlow",n=lt[a],r=n.discrete.length,s=Math.floor(r/2);return{colormap:n,colormapName:a,isDark:t,baseIndex:t?s:0,halfSize:s}}let mt=null;function gt(e){const{colormap:t,isDark:a}=ht();if("number"!=typeof e)return a?"#A5A5A5":"#666666";const n=ut[e];if(void 0===n)return a?"#A5A5A5":"#666666";const r=t.categorical;return r[Math.min(n,r.length-1)]}function pt(e){const t=gt(e);return null===mt&&(mt=ye()),mt?function(e){return ye()?be(e):e}(t):t}function ft(e){return ct(gt(e))}function bt(e,t){return(Math.max(e,t)+.05)/(Math.min(e,t)+.05)}function yt(e){const t=function(e){const t=e.replace("#",""),a=parseInt(t.slice(0,2),16)/255,n=parseInt(t.slice(2,4),16)/255,r=parseInt(t.slice(4,6),16)/255,s=e=>e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4);return.2126*s(a)+.7152*s(n)+.0722*s(r)}(e);return bt(t,1)>bt(t,0)?"light":"dark"}function wt(e){return 1===e||!0===e}function Ct(e){return void 0===e?"bg-[var(--signal-unknown)]":e>=5?"bg-[var(--signal-excellent)]":e>=0?"bg-[var(--signal-good)]":e>=-5?"bg-[var(--signal-fair)]":e>=-10?"bg-[var(--signal-poor)]":"bg-[var(--signal-critical)]"}const kt=E("inline-flex items-center gap-1","radius-badge px-1.5 py-0.5","text-xs"),vt={fontFamily:"var(--font-badge)",fontWeight:"var(--font-badge-weight)",textTransform:"var(--badge-text-transform, none)"},Dt={red:"var(--sys-red)",orange:"var(--sys-orange)",amber:"var(--sys-amber)",yellow:"var(--sys-yellow)",lime:"var(--sys-green)",green:"var(--sys-green)",emerald:"var(--sys-green)",teal:"var(--sys-teal)",cyan:"var(--sys-cyan)",sky:"var(--sys-cyan)",blue:"var(--sys-blue)",indigo:"var(--sys-indigo)",violet:"var(--sys-indigo)",purple:"var(--sys-purple)",fuchsia:"var(--sys-pink)",pink:"var(--sys-pink)",rose:"var(--sys-red)",brown:"var(--sys-brown)",zinc:"var(--fg-muted)"};function At(e){if(!e.startsWith("var("))return e;if("undefined"!=typeof window){const t=e.match(/var\((--[^,)]+)/);if(t){const e=getComputedStyle(document.documentElement).getPropertyValue(t[1]).trim();if(e&&e.startsWith("#"))return e}}return"#666666"}function xt({color:e="zinc",customColor:t,filled:a=!1,compact:n=!1,className:r,title:i,children:l}){const c=s.useMemo(()=>{const n=t??Dt[e];if(a){if(t){const e=yt(At(t));return{backgroundColor:t,color:"light"===e?"rgba(255,255,255,0.95)":"rgba(0,0,0,0.85)"}}return{backgroundColor:n,color:["amber","yellow","lime"].includes(e)?"rgba(0,0,0,0.85)":"rgba(255,255,255,0.95)"}}return{backgroundColor:`color-mix(in srgb, ${n} 15%, transparent)`,color:n}},[e,t,a]);return o.jsx("span",{className:E(kt,n&&"!px-1 !py-0 !text-[10px]",r),style:{...vt,...c},"data-color":e,title:i,children:l})}const Et=s.forwardRef(function({color:e="zinc",customColor:t,filled:a=!1,compact:n=!1,className:r,children:i,...c},d){const u=s.useMemo(()=>{const n=t??Dt[e];if(a){if(t){const e=yt(At(t));return{backgroundColor:t,color:"light"===e?"rgba(255,255,255,0.95)":"rgba(0,0,0,0.85)"}}return{backgroundColor:n,color:["amber","yellow","lime"].includes(e)?"rgba(0,0,0,0.85)":"rgba(255,255,255,0.95)"}}return{backgroundColor:`color-mix(in srgb, ${n} 15%, transparent)`,color:n}},[e,t,a]),h=E(kt,n&&"!px-1 !py-0 !text-[10px]","interactive hover-opacity",r);return"href"in c&&void 0!==c.href?o.jsx(at,{...c,ref:d,className:h,style:{...vt,...u},children:i}):o.jsx(l,{...c,ref:d,className:h,style:{...vt,...u},children:i})}),Ft=E("relative inline-flex items-center justify-center gap-2","text-sm font-medium whitespace-nowrap","radius-inner px-3 py-1.5","ring-focus","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-base","[&>[data-slot=icon]]:w-4 [&>[data-slot=icon]]:h-4 [&>[data-slot=icon]]:shrink-0"),Bt={primary:E("bg-sys-blue text-white","hover:bg-sys-blue","active:bg-sys-blue/80","border-[1.5px] border-sys-blue"),success:E("bg-sys-green text-white","hover:bg-sys-green","active:bg-sys-green/80","border-[1.5px] border-sys-green"),danger:E("bg-sys-red text-white","hover:bg-sys-red","active:bg-sys-red/80","border-[1.5px] border-sys-red"),warning:E("bg-sys-indigo text-bg-body","hover:bg-sys-indigo","active:bg-sys-indigo/80","border-[1.5px] border-sys-indigo"),muted:E("bg-elevated text-fg-primary","hover:bg-subtle","active:bg-elevated","border-[1.5px] border-edge-subtle"),pink:E("bg-sys-pink text-white","hover:bg-sys-pink","active:bg-sys-pink/80","border-[1.5px] border-sys-pink"),amber:E("bg-sys-amber text-zinc-900","hover:bg-sys-amber","active:bg-sys-amber/80","border-[1.5px] border-sys-amber"),indigo:E("bg-sys-indigo text-white","hover:bg-sys-indigo","active:bg-sys-indigo/80","border-[1.5px] border-sys-indigo"),purple:E("bg-sys-purple text-white","hover:bg-sys-purple","active:bg-sys-purple/80","border-[1.5px] border-sys-purple"),zinc:E("bg-zinc-500 text-white","hover:bg-zinc-500","active:bg-zinc-500/80","border-[1.5px] border-zinc-500")},jt={primary:E("bg-transparent text-sys-blue","border-[1.5px] border-sys-blue","hover:bg-sys-blue hover:text-white hover:border-sys-blue","active:bg-sys-blue/90 active:text-white"),success:E("bg-transparent text-sys-green","border-[1.5px] border-sys-green","hover:bg-sys-green hover:text-white hover:border-sys-green","active:bg-sys-green/90 active:text-white"),danger:E("bg-transparent text-sys-red","border-[1.5px] border-sys-red","hover:bg-sys-red hover:text-white hover:border-sys-red","active:bg-sys-red/90 active:text-white"),warning:E("bg-transparent text-sys-indigo","border-[1.5px] border-sys-indigo","hover:bg-sys-indigo hover:text-bg-body hover:border-sys-indigo","active:bg-sys-indigo/90 active:text-bg-body"),muted:E("bg-transparent text-fg-muted","border-[1.5px] border-edge-subtle","hover:bg-subtle hover:text-fg-primary hover:border-edge-strong","active:bg-elevated"),pink:E("bg-transparent text-sys-pink","border-[1.5px] border-sys-pink","hover:bg-sys-pink hover:text-white hover:border-sys-pink","active:bg-sys-pink/90 active:text-white"),amber:E("bg-transparent text-sys-amber","border-[1.5px] border-sys-amber","hover:bg-sys-amber hover:text-zinc-900 hover:border-sys-amber","active:bg-sys-amber/90 active:text-zinc-900"),indigo:E("bg-transparent text-sys-indigo","border-[1.5px] border-sys-indigo","hover:bg-sys-indigo hover:text-white hover:border-sys-indigo","active:bg-sys-indigo/90 active:text-white"),purple:E("bg-transparent text-sys-purple","border-[1.5px] border-sys-purple","hover:bg-sys-purple hover:text-white hover:border-sys-purple","active:bg-sys-purple/90 active:text-white"),zinc:E("bg-transparent text-fg-muted","border-[1.5px] border-edge-subtle","hover:bg-zinc-500 hover:text-white hover:border-zinc-500","active:bg-zinc-500/90 active:text-white")},St={primary:E("bg-transparent text-sys-blue border-transparent","hover:bg-sys-blue hover:text-white","active:bg-sys-blue/90 active:text-white"),success:E("bg-transparent text-sys-green border-transparent","hover:bg-sys-green hover:text-white","active:bg-sys-green/90 active:text-white"),danger:E("bg-transparent text-sys-red border-transparent","hover:bg-sys-red hover:text-white","active:bg-sys-red/90 active:text-white"),warning:E("bg-transparent text-sys-indigo border-transparent","hover:bg-sys-indigo hover:text-bg-body","active:bg-sys-indigo/90 active:text-bg-body"),muted:E("bg-transparent text-fg-muted border-transparent","hover:bg-subtle hover:text-fg-primary","active:bg-elevated"),pink:E("bg-transparent text-sys-pink border-transparent","hover:bg-sys-pink hover:text-white","active:bg-sys-pink/90 active:text-white"),amber:E("bg-transparent text-sys-amber border-transparent","hover:bg-sys-amber hover:text-zinc-900","active:bg-sys-amber/90 active:text-zinc-900"),indigo:E("bg-transparent text-sys-indigo border-transparent","hover:bg-sys-indigo hover:text-white","active:bg-sys-indigo/90 active:text-white"),purple:E("bg-transparent text-sys-purple border-transparent","hover:bg-sys-purple hover:text-white","active:bg-sys-purple/90 active:text-white"),zinc:E("bg-transparent text-zinc-400 border-transparent","hover:bg-zinc-500 hover:text-white","active:bg-zinc-500/90 active:text-white")},Mt=s.forwardRef(function({color:e="muted",outline:t=!1,plain:a=!1,className:n,children:r,...s},i){const c=E(Ft,a?St[e]:t?jt[e]:Bt[e],n);return"href"in s&&void 0!==s.href?o.jsx(at,{...s,ref:i,className:c,children:r}):o.jsx(l,{...s,ref:i,className:c,children:r})}),Nt={duration:.15,ease:[.4,0,.2,1]},Lt={type:"tween",duration:.25,ease:[.4,0,.2,1]},Tt={type:"tween",duration:.3,ease:[.4,0,.2,1]},_t=s.createContext(!1);function Rt(){return s.useContext(_t)}const zt=s.createContext(void 0);function Pt(){return s.useContext(zt)}const It="#1A1A1A",$t="#737373",qt={xs:"sm:max-w-xs",sm:"sm:max-w-sm",md:"sm:max-w-md",lg:"sm:max-w-lg",xl:"sm:max-w-xl","2xl":"sm:max-w-2xl","3xl":"sm:max-w-3xl","4xl":"sm:max-w-4xl","5xl":"sm:max-w-5xl",full:"sm:max-w-[calc(100vw-2rem)]"};function Ot({open:e,onClose:t,size:a="md",className:n,children:r,bottomSheet:i=!0,motionPlus:l=!1,basemapMode:u,solid:h=!1}){const m="light"===u,[g,p]=s.useState(!1),f=s.useRef(null);s.useEffect(()=>(f.current&&(clearTimeout(f.current),f.current=null),e?f.current=setTimeout(()=>{p(!0)},350):queueMicrotask(()=>p(!1)),()=>{f.current&&(clearTimeout(f.current),f.current=null)}),[e]);const b=s.useCallback((e,a)=>{(a.offset.y>100||a.velocity.y>500)&&t()},[t]),y=l?Tt:Lt,w=l?.98:.99,C=i?8:4;return o.jsx(T,{mode:"wait",children:e&&o.jsxs(c,{static:!0,open:e,onClose:t,className:"relative z-[10010]",children:[o.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:Nt,className:"fixed inset-0 bg-black/50 backdrop-blur-sm","aria-hidden":"true"}),o.jsx("div",{className:"fixed inset-0 overflow-y-auto",children:o.jsx("div",{className:E("flex min-h-full justify-center",i?"items-end sm:items-center sm:p-4":"items-center p-4"),children:o.jsx(_.div,{drag:!!i&&"y",dragConstraints:{top:0,bottom:0},dragElastic:{top:0,bottom:.4},onDragEnd:b,initial:{opacity:0,scale:w,y:C},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.99,y:i?40:4},transition:y,style:{willChange:"transform, opacity"},className:E(i&&"w-full sm:w-auto"),children:o.jsx(d,{className:E("relative w-full shadow-2xl flex flex-col",!u&&!h&&"bg-surface/80 backdrop-blur-xl",!u&&h&&"bg-surface",!u&&"ring-1 ring-inset ring-edge-subtle",qt[a],i?"radius-card overflow-hidden pb-safe":"radius-card overflow-hidden",n),style:u?{backgroundColor:m?"#F8F8F8":"var(--surface)",boxShadow:"inset 0 0 0 1px "+(m?"rgba(0, 0, 0, 0.08)":"rgba(255, 255, 255, 0.1)")}:void 0,children:o.jsx(zt.Provider,{value:u,children:o.jsx(_t.Provider,{value:g,children:r})})})})})})]})})}function Ht({className:e,...t}){const a=Pt(),n="light"===a;return o.jsx(u,{...t,className:E("text-base font-semibold sm:text-lg",!a&&"text-fg-primary",e),style:a?{color:n?It:"var(--fg-primary)"}:void 0})}function Wt({icon:e,title:t,onClose:a,className:n}){const r=Pt(),s="light"===r;return o.jsxs("div",{className:E("flex items-center justify-between px-4 sm:px-6 py-3 sm:py-4 border-b",!r&&"border-edge-subtle",n),style:r?{borderColor:s?"rgba(0, 0, 0, 0.12)":"var(--edge-subtle)"}:void 0,children:[o.jsxs("div",{className:"flex items-center gap-3",children:[e&&o.jsx("div",{className:E(!r&&"text-icon-card-title"),style:r?{color:s?"#4A4A4A":"var(--icon-card-title)"}:void 0,children:e}),o.jsx(Ht,{children:t})]}),a&&o.jsxs(o.Fragment,{children:[o.jsx("button",{onClick:a,className:"sm:hidden min-h-[44px] min-w-[44px] px-3 flex items-center justify-center text-[15px] font-medium text-sys-blue active:text-sys-blue/70 transition-base radius-inner active:bg-subtle-fill",children:"Done"}),o.jsx("button",{onClick:a,className:E("hidden sm:flex items-center justify-center p-2 radius-inner transition-colors",!r&&"text-fg-muted hover:text-fg-primary hover:bg-subtle"),style:r?{color:s?$t:"var(--fg-muted)"}:void 0,onMouseEnter:e=>{r&&(e.currentTarget.style.color=s?It:"var(--fg-primary)",e.currentTarget.style.backgroundColor=s?"rgba(0, 0, 0, 0.06)":"var(--subtle)")},onMouseLeave:e=>{r&&(e.currentTarget.style.color=s?$t:"var(--fg-muted)",e.currentTarget.style.backgroundColor="transparent")},"aria-label":"Close",children:o.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]})]})}function Ut({className:e,...t}){return o.jsx("div",{...t,className:E("px-6 py-5",e)})}function Vt({className:e,...t}){return o.jsx("div",{...t,className:E("flex flex-col-reverse gap-3 px-6 pb-6 pt-0","sm:flex-row sm:justify-end","*:w-full sm:*:w-auto",e)})}const Gt={snappy:{type:"spring",stiffness:500,damping:30},smooth:{type:"spring",stiffness:300,damping:30},gentle:{type:"spring",stiffness:200,damping:25}},Jt={fast:.15,normal:.2,medium:.3},Kt={easeOut:[0,0,.2,1],easeIn:[.4,0,1,1]},Xt={dropdown:{type:"spring",stiffness:500,damping:30},fade:{duration:Jt.fast,ease:Kt.easeOut},numberTicker:{type:"spring",visualDuration:.4,bounce:.15,opacity:{duration:.15,ease:"linear"}},numberReveal:{type:"spring",visualDuration:.6,bounce:.25,opacity:{duration:.2,ease:"linear"}}},Yt={normal:.05};function Qt({className:e,...t}){return o.jsx("nav",{...t,className:E(e,"flex h-full min-h-0 flex-col")})}function Zt({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex flex-col border-b border-edge-subtle p-4","[&>[data-slot=section]+[data-slot=section]]:mt-2.5")})}function ea({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex flex-1 flex-col p-3","overflow-y-auto sidebar-scroll","[&>[data-slot=section]+[data-slot=section]]:mt-6")})}function ta({className:e,...t}){return o.jsx("div",{...t,className:E(e,"mt-auto flex flex-col","[&>[data-slot=section]+[data-slot=section]]:mt-2.5")})}function aa({className:e,...t}){const a=s.useId();return o.jsx(R,{id:a,children:o.jsx("div",{...t,"data-slot":"section",className:E(e,"flex flex-col gap-0.5")})})}const na=s.forwardRef(function(e,t){const{current:a,className:n,children:r,accentColor:s,...i}=e,c=!!s,d=E("relative isolate flex w-full items-center gap-3 radius-inner px-3 py-2 text-left","min-h-[38px]","text-sm font-medium","[&>svg]:w-4 [&>svg]:h-4 [&>svg]:flex-shrink-0",a?c?"text-white":"text-white [&_svg]:text-sys-blue":"text-fg-muted hover:text-fg-primary hover:bg-elevated [&_svg]:text-fg-muted hover:[&_svg]:text-fg-primary","transition-all duration-150"),u=c?{willChange:"transform",backgroundColor:s,boxShadow:[`0 0 10px 2px color-mix(in oklch, ${s} 50%, transparent)`,`0 0 4px 0 color-mix(in oklch, ${s} 70%, transparent)`].join(", ")}:{willChange:"transform"},h=c?{willChange:"transform",background:"transparent",boxShadow:[`inset 0 0 0 1.5px ${s}`,`inset 0 0 3px 0.5px color-mix(in oklch, ${s} 30%, transparent)`,`inset 0 0 6px 1px color-mix(in oklch, ${s} 14%, transparent)`,`inset 0 0 10px 2px color-mix(in oklch, ${s} 5%, transparent)`,`0 0 20px -4px color-mix(in oklch, ${s} 22%, transparent)`,`0 0 8px -2px color-mix(in oklch, ${s} 14%, transparent)`].join(", ")}:{willChange:"transform"};return o.jsxs("span",{className:E(n,"relative"),children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-indicator",className:E("absolute inset-y-2 -left-3 w-0.5 rounded-full",!c&&"bg-sys-blue sidebar-neo-indicator"),style:u,transition:Gt.snappy}),"string"==typeof i.href?o.jsxs(x,{to:i.href,onClick:i.onClick,onMouseEnter:i.onMouseEnter,onMouseLeave:i.onMouseLeave,className:d,"data-current":a?"true":void 0,ref:t,children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-highlight",className:E("absolute inset-0 radius-inner z-[-1]",!c&&"sidebar-neo-highlight"),style:h,transition:Gt.snappy}),r]}):o.jsxs(l,{...i,className:E("cursor-default",d),"data-current":a?"true":void 0,ref:t,children:[a&&o.jsx(_.span,{layout:"position",layoutId:"sidebar-current-highlight",className:E("absolute inset-0 radius-inner z-[-1]",!c&&"sidebar-neo-highlight"),style:h,transition:Gt.snappy}),r]})]})});function ra({className:e,...t}){return o.jsx("span",{...t,className:E(e,"truncate")})}function sa({className:e,variant:t="default",...a}){return o.jsx("span",{...a,className:E("ml-auto flex items-center gap-1 px-1.5 py-0.5 rounded-full","text-xs font-medium",{default:"bg-subtle text-fg-muted",accent:"bg-sys-blue/20 text-sys-blue",success:"bg-sys-green/20 text-sys-green",warning:"bg-sys-indigo/20 text-sys-indigo",danger:"bg-sys-red/20 text-sys-red"}[t],e)})}const oa=s.createContext(null),ia={type:"spring",visualDuration:.35,bounce:.15};function la({open:e,onClose:t,children:a}){return o.jsx(T,{children:e&&o.jsxs(c,{static:!0,open:e,onClose:t,className:"lg:hidden relative z-[10002]",children:[o.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.25,ease:"easeOut"},className:"fixed inset-0 bg-black/60 backdrop-blur-sm","aria-hidden":"true"}),o.jsx(_.div,{initial:{x:"-100%"},animate:{x:0},exit:{x:"-100%"},transition:ia,className:"fixed inset-y-0 left-0 w-72 max-w-[85vw] z-[10003]",children:o.jsx(d,{className:"h-full",children:o.jsxs("div",{className:"flex h-full flex-col sidebar-panel",children:[o.jsx("div",{className:"absolute top-4 right-4 z-10",children:o.jsx(h,{className:"p-2 rounded-lg text-fg-muted hover:text-fg-primary hover:bg-subtle-fill transition-colors","aria-label":"Close navigation",children:o.jsx(P,{className:"w-5 h-5"})})}),a]})})})]})})}function ca({sidebar:e,navbar:t,children:a,className:n}){const[r,i]=s.useState(!1),l=()=>i(!0),c=()=>i(!1),d={isOpen:r,open:l,close:c,toggle:()=>i(e=>!e)};return o.jsx(oa.Provider,{value:d,children:o.jsxs("div",{className:"flex h-screen overflow-hidden bg-body",children:[o.jsx("aside",{className:"hidden lg:flex flex-col w-64 flex-shrink-0 h-full relative sidebar-panel",children:e}),o.jsx(la,{open:r,onClose:c,children:e}),o.jsxs("div",{className:"flex-1 flex flex-col min-w-0",children:[o.jsx("header",{className:"lg:hidden sticky top-0 z-[10001] h-14 mobile-header",children:o.jsxs("div",{className:"flex items-center h-full px-4",children:[o.jsx("button",{onClick:l,className:"w-10 h-10 flex items-center justify-center rounded-lg hover:bg-subtle-fill active:bg-subtle-fill transition-colors mr-2","aria-label":"Open navigation",children:o.jsx(z,{className:"w-5 h-5 text-fg-primary"})}),o.jsx("div",{className:"flex-1 min-w-0",children:t})]})}),o.jsx("main",{className:E("flex-1 overflow-y-auto main-content",n),children:a})]})]})})}function da({className:e,...t}){return o.jsx("nav",{...t,className:E(e,"flex flex-1 items-center gap-3")})}function ua({className:e,...t}){return o.jsx("div",{...t,className:E(e,"flex items-center gap-3")})}function ha({className:e,...t}){return o.jsx("div",{"aria-hidden":"true",...t,className:E(e,"flex-1")})}const ma=[45,72,33,58,80,42,65,28,55,75,38,62];function ga({className:e,style:t}){return o.jsx("div",{className:E("animate-pulse bg-subtle-fill radius-badge",e),style:t})}function pa(){return o.jsx("div",{className:"p-3 radius-inner border-card bg-subtle",children:o.jsxs("div",{className:"flex items-start gap-3",children:[o.jsx(ga,{className:"w-14 h-6 rounded shrink-0"}),o.jsxs("div",{className:"flex-1 min-w-0 space-y-2",children:[o.jsx(ga,{className:"h-4 w-full"}),o.jsx(ga,{className:"h-4 w-3/4"}),o.jsx(ga,{className:"h-3 w-32 mt-1"})]})]})})}function fa({count:e=8}){return o.jsx("div",{className:"space-y-2",children:Array.from({length:e}).map((e,t)=>o.jsx(pa,{},t))})}function ba(){return o.jsxs("div",{className:"flex flex-col gap-3 h-full","aria-hidden":"true",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]}),o.jsx(ga,{className:"h-8 w-20"}),o.jsxs("div",{className:"flex-1 flex flex-col justify-end gap-2",children:[o.jsx(ga,{className:"h-3 w-full"}),o.jsx(ga,{className:"h-3 w-3/4"})]})]})}function ya(){return o.jsxs("div",{className:"flex flex-col gap-3 h-full","aria-hidden":"true",children:[o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]}),o.jsx("div",{className:"flex-1 flex items-end gap-1",children:ma.slice(0,8).map((e,t)=>o.jsx(ga,{className:"flex-1",style:{height:`${e}%`}},t))})]})}function wa({rows:e=5}){return o.jsxs("div",{className:"flex flex-col h-full","aria-hidden":"true",children:[o.jsx("div",{className:"pb-3 border-b border-edge-subtle",children:o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(ga,{className:"w-5 h-5"}),o.jsx(ga,{className:"h-4 w-24"})]})}),o.jsx("div",{className:"flex-1 pt-3 flex flex-col gap-3",children:Array.from({length:e}).map((e,t)=>o.jsx(ga,{className:"h-6 w-full"},t))})]})}const Ca={sm:"radius-inner",md:"radius-inset",lg:"radius-card",xl:"radius-hero",full:"radius-pill",none:"radius-none"},ka=s.forwardRef(function({children:e,elevated:t,compact:a,noPadding:n,radius:r="lg",glass:s=!0,stroke:i=!0,shadow:l,reflex:c=!1,glow:d=!1,neomorphic:u=!0,onClick:h,className:m,style:g,isLoaded:p=!0,skeletonType:f="card",...b},y){const w={...g,...c?{"--surface-reflex":"1"}:{}},C=E(Ca[r],s&&(t?"bg-surface/85 backdrop-blur-xl":"bg-surface/80 backdrop-blur-lg"),!s&&"bg-surface",u&&"depth-raised",i&&!u&&!d&&"ring-1 ring-inset ring-edge-subtle",d&&"ring-1 ring-inset ring-sys-blue/40",(l??t??!1)&&(t?"shadow-xl":"shadow-lg"),c&&"surface-reflex","h-full flex flex-col relative",!n&&(a?"p-3 sm:p-4":"p-4 sm:p-5"),h&&"cursor-pointer",m);return p?o.jsx("div",{ref:y,"data-card-surface":!0,className:C,style:w,onClick:h,...b,children:e}):o.jsx("div",{ref:y,"data-card-surface":!0,className:C,style:w,...b,children:(()=>{switch(f){case"chart":return o.jsx(ya,{});case"list":return o.jsx(wa,{});default:return o.jsx(ba,{})}})()})});function va({title:e,icon:t,badge:a,badgeColor:n="teal",subtitle:r,actions:s,iconColor:i="text-icon-card-title",listHeader:l=!1,stackActionsOnMobile:c=!1,stackBreakpoint:d="sm",titleExtra:u,onClick:h,className:m}){const g="px-5 py-4 border-b border-edge-subtle",p=o.jsxs(o.Fragment,{children:[t&&o.jsx("span",{className:E("icon-md flex items-center justify-center",i),children:t}),o.jsx("span",{className:"type-micro",children:e}),a&&o.jsx(xt,{color:n,children:a}),u]}),f=h?"button":"div",b=h?{onClick:h,type:"button"}:{};return c&&s?o.jsxs(f,{...b,className:E("flex flex-col gap-1 flex-shrink-0",l?g:"mb-3",h&&"w-full text-left cursor-pointer",m),children:[o.jsxs("div",{className:{sm:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 min-h-[32px]",md:"flex flex-col md:flex-row md:items-center md:justify-between gap-2 min-h-[32px]",lg:"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-2 min-h-[32px]"}[d],children:[o.jsx("div",{className:"flex items-center gap-3",children:p}),o.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:s})]}),r&&o.jsx("p",{className:"type-label text-fg-muted ml-8",children:r})]}):o.jsxs(f,{...b,className:E("flex flex-col gap-1 flex-shrink-0",l?g:"mb-3",h&&"w-full text-left cursor-pointer",m),children:[o.jsxs("div",{className:"flex items-center justify-between gap-2 min-h-[32px]",children:[o.jsx("div",{className:"flex items-center gap-3",children:p}),s&&o.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:s})]}),r&&o.jsx("p",{className:"type-label text-fg-muted ml-8",children:r})]})}s.forwardRef(function({children:e,icon:t,className:a,...n},r){return o.jsxs("h3",{ref:r,className:E("flex items-center gap-2","text-base font-semibold text-fg-primary",a),...n,children:[t&&o.jsx("span",{className:"text-icon-card-title w-5 h-5 flex-shrink-0",children:t}),e]})}),s.forwardRef(function({children:e,className:t,...a},n){return o.jsx("p",{ref:n,className:E("text-sm text-fg-muted",t),...a,children:e})});const Da=s.forwardRef(function({children:e,centered:t,className:a,...n},r){return o.jsx("div",{ref:r,className:E("flex-1 min-h-0",t&&"flex items-center justify-center",a),...n,children:e})});function Aa({defaultOpen:e=!1,className:t,children:a}){return o.jsx(g,{defaultOpen:e,children:o.jsx("div",{className:E("flex flex-col",t),children:a})})}s.forwardRef(function({children:e,className:t,...a},n){return o.jsx("div",{ref:n,className:E("flex items-center justify-end gap-3","pt-4 mt-4","border-t border-edge-subtle",t),...a,children:e})}),s.forwardRef(function({children:e,border:t,className:a,...n},r){return o.jsx("div",{ref:r,className:E(t&&"pt-4 mt-4 border-t border-edge-subtle",a),...n,children:e})});const xa=s.forwardRef(function({className:e,icon:t,children:a,...n},r){return o.jsx(m,{ref:r,className:E("flex w-full items-center justify-between gap-3","px-3 py-2 radius-inner","text-sm font-medium text-fg-muted","row-hover hover:text-fg-primary","ring-focus",e),...n,children:({open:e})=>o.jsxs(o.Fragment,{children:[a,o.jsx("span",{className:E("transition-transform duration-200",e?"rotate-180":"rotate-0"),children:t||o.jsx(I,{className:"w-4 h-4"})})]})})});function Ea({direction:e="down",className:t,children:a}){const n={hidden:{height:0,opacity:0,y:"up"===e?8:-8},visible:{height:"auto",opacity:1,y:0}};return o.jsx(p,{static:!0,children:({open:r})=>o.jsx(T,{initial:!1,children:r&&o.jsx(_.div,{initial:"hidden",animate:"visible",exit:"hidden",variants:n,transition:{height:{duration:.2,ease:[.4,0,.2,1]},opacity:{duration:.15},y:{duration:.15}},className:E("overflow-hidden",t),children:o.jsx("div",{className:E("up"===e?"pb-2":"pt-2"),children:a})})})})}function Fa({label:e,icon:t,defaultOpen:a=!0,direction:n="down",className:r,dataId:s,children:i}){const l=s?{[`data-${s}-disclosure`]:!0}:{},c=o.jsxs("span",{className:"flex items-center gap-3",children:[t&&o.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:t}),o.jsx("span",{className:"type-micro",children:e})]});return"up"===n?o.jsx(g,{defaultOpen:a,children:({open:a})=>o.jsxs("div",{className:E("relative",r),children:[o.jsx(p,{static:!0,className:"relative z-50",children:o.jsx(T,{initial:!1,mode:"wait",children:a&&o.jsxs(_.div,{initial:{y:12,scale:.97,opacity:0},animate:{y:0,scale:1,opacity:1},exit:{y:6,scale:.98,opacity:0},transition:{type:"spring",stiffness:400,damping:32,mass:.8,opacity:{duration:.15,ease:[.4,0,.2,1]}},className:"absolute bottom-full left-0 right-0 z-50 mb-1 origin-bottom radius-inset shadow-lg border-card bg-surface/75 backdrop-blur-sm",children:[o.jsxs("div",{className:"flex items-center justify-between px-3 py-2",children:[o.jsxs("span",{className:"flex items-center gap-3",children:[t&&o.jsx("span",{className:"icon-md flex items-center justify-center text-icon-card-title",children:t}),o.jsx("span",{className:"type-micro",children:e})]}),o.jsx(m,{className:"p-1 rounded hover:bg-subtle-fill-strong transition-colors",children:o.jsx(_.span,{initial:{rotate:0},animate:{rotate:180},exit:{rotate:0},transition:{type:"spring",stiffness:400,damping:25},children:o.jsx(I,{className:"w-4 h-4"})})})]}),o.jsx("div",{className:"px-3 pb-3",children:i})]})})}),o.jsx(_.div,{animate:{opacity:a?.4:1,scale:a?.98:1},transition:{type:"spring",stiffness:500,damping:35},children:o.jsxs(m,{...l,className:E("flex w-full items-center justify-between gap-3","px-3 py-3.5 rounded-none rounded-t-lg","bg-surface depth-stroke-raised","text-sm font-medium text-fg-muted","hover:bg-elevated hover:text-fg-primary transition-colors","ring-focus"),children:[c,o.jsx(_.span,{animate:{rotate:a?180:0},transition:{type:"spring",stiffness:400,damping:25},children:o.jsx(I,{className:"w-4 h-4"})})]})})]})}):o.jsxs(Aa,{defaultOpen:a,className:r,children:[o.jsx(xa,{...l,children:c}),o.jsx(Ea,{direction:"down",children:o.jsx("div",{className:"bg-subtle-fill radius-inset mx-1 mt-1",children:i})})]})}function Ba({placement:e}){const t=E("absolute w-2 h-2 rotate-45","top"===e&&"bottom-[-4px] left-1/2 -translate-x-1/2","bottom"===e&&"top-[-4px] left-1/2 -translate-x-1/2","left"===e&&"right-[-4px] top-1/2 -translate-y-1/2","right"===e&&"left-[-4px] top-1/2 -translate-y-1/2");return o.jsx("span",{className:t,style:{backgroundColor:"var(--tooltip-bg)"}})}function ja({content:e,children:t,placement:a="top",delay:n=200,arrow:r=!0,disabled:i=!1,className:l}){const[c,d]=s.useState(!1),[u,h]=s.useState({top:0,left:0}),[m,g]=s.useState(!1),p=s.useRef(null),b=s.useRef(null),y=s.useRef();s.useEffect(()=>{g(!0)},[]),s.useEffect(()=>{if(!c||!p.current||!b.current)return;const e=p.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),n=function(e,t,a){const n=window.scrollY,r=window.scrollX;switch(a){case"top":return{top:e.top+n-t.height-8,left:e.left+r+(e.width-t.width)/2};case"bottom":return{top:e.bottom+n+8,left:e.left+r+(e.width-t.width)/2};case"left":return{top:e.top+n+(e.height-t.height)/2,left:e.left+r-t.width-8};case"right":return{top:e.top+n+(e.height-t.height)/2,left:e.right+r+8}}}(e,t,a),r=window.innerWidth-t.width-8,s=window.innerHeight+window.scrollY-t.height-8;h({top:Math.max(8,Math.min(n.top,s)),left:Math.max(8,Math.min(n.left,r))})},[c,a]);const w=s.useCallback(()=>{i||(y.current=setTimeout(()=>{d(!0)},n))},[n,i]),C=s.useCallback(()=>{y.current&&clearTimeout(y.current),d(!1)},[]);if(s.useEffect(()=>()=>{y.current&&clearTimeout(y.current)},[]),!s.isValidElement(t))return t;const k=s.cloneElement(t,{ref:p,onMouseEnter:e=>{var a,n;w(),null==(n=(a=t.props).onMouseEnter)||n.call(a,e)},onMouseLeave:e=>{var a,n;C(),null==(n=(a=t.props).onMouseLeave)||n.call(a,e)},onFocus:e=>{var a,n;w(),null==(n=(a=t.props).onFocus)||n.call(a,e)},onBlur:e=>{var a,n;C(),null==(n=(a=t.props).onBlur)||n.call(a,e)}}),v=(e=>({hidden:{opacity:0,scale:.96,...{top:{y:4},bottom:{y:-4},left:{x:4},right:{x:-4}}[e]},visible:{opacity:1,scale:1,x:0,y:0}}))(a),D=o.jsx(T,{children:c&&o.jsxs(_.div,{ref:b,initial:"hidden",animate:"visible",exit:"hidden",variants:v,transition:{duration:.15,ease:"easeOut"},className:E("fixed z-[10020] px-2.5 py-1.5 text-xs font-medium","rounded-lg","pointer-events-none",l),style:{top:u.top,left:u.left,backgroundColor:"var(--tooltip-bg)",color:"var(--tooltip-fg)",border:"1px solid var(--tooltip-border)",boxShadow:"var(--tooltip-shadow)"},role:"tooltip",children:[e,r&&o.jsx(Ba,{placement:a})]})});return o.jsxs(o.Fragment,{children:[k,m&&f.createPortal(D,document.body)]})}const Sa={sm:{track:"h-5 w-9",thumb:"h-3.5 w-3.5",translate:"translate-x-[18px]",icon:"w-3 h-3",dot:"w-2 h-2"},md:{track:"h-6 w-11",thumb:"h-4 w-4",translate:"translate-x-[22px]",icon:"w-4 h-4",dot:"w-2.5 h-2.5"},lg:{track:"h-7 w-14",thumb:"h-5 w-5",translate:"translate-x-[30px]",icon:"w-4 h-4",dot:"w-3 h-3"}},Ma=s.forwardRef(function({enabled:e,onChange:t,label:a,description:n,tooltip:r,size:s="md",color:i="muted",dangerOff:l=!1,disabled:c=!1,status:d="idle",name:u,className:h},m){const g=Sa[s],p="loading"===d,f="muted"===i;return o.jsxs(b,{disabled:c||p,className:E("flex items-center gap-3",h),children:[o.jsx(y,{ref:m,checked:e,onChange:t,name:u,className:E(f?"toggle-switch-track":"group relative inline-flex shrink-0 items-center rounded-full border-2",g.track,!f&&(e?"bg-toggle-on border-toggle-on":"bg-toggle-off border-edge-subtle"),"disabled:opacity-50 disabled:cursor-not-allowed","ring-focus","transition-all duration-200"),"data-size":s,children:o.jsx("span",{className:E(f?"toggle-switch-thumb":"relative inline-flex items-center justify-center bg-white shadow-lg","transform rounded-full transition-transform duration-200",g.thumb,e?g.translate:"translate-x-[4px]"),children:f&&o.jsx("span",{className:E("toggle-switch-dot",g.dot,l?E("opacity-100",!e&&"toggle-switch-dot-danger"):e?"opacity-100":"opacity-0")})})}),(a||n||r)&&o.jsxs("div",{className:"flex items-center gap-1.5 min-w-0",children:[a&&o.jsx(w,{className:E("text-sm font-medium cursor-pointer select-none",c?"text-fg-muted":"text-fg-primary"),children:a}),r&&o.jsx(ja,{content:r,placement:"top",children:o.jsx("span",{className:"text-fg-muted hover:text-fg-secondary cursor-help transition-colors",children:o.jsx($,{className:"w-3.5 h-3.5"})})}),n&&!r&&o.jsx(C,{className:"text-xs text-fg-muted",children:n})]}),"idle"!==d&&o.jsxs("div",{className:"flex items-center shrink-0",children:["loading"===d&&o.jsx(q,{className:E(g.icon,"text-fg-muted animate-spin")}),"success"===d&&o.jsx(O,{className:E(g.icon,"text-sys-green")}),"error"===d&&o.jsx(P,{className:E(g.icon,"text-sys-red")})]})]})}),Na=s.forwardRef(function({enabled:e,onChange:t,size:a="md",disabled:n=!1,"aria-label":r,className:s},i){const l=Sa[a];return o.jsx(y,{ref:i,checked:e,onChange:t,disabled:n,"aria-label":r,className:E("toggle-switch-track",l.track,"disabled:opacity-50 disabled:cursor-not-allowed","ring-focus","transition-all duration-200",s),"data-size":a,children:o.jsx("span",{className:E("toggle-switch-thumb","transform rounded-full transition-transform duration-200",l.thumb,e?l.translate:"translate-x-[4px]"),children:o.jsx("span",{className:E("toggle-switch-dot",l.dot,e?"opacity-100":"opacity-0")})})})}),La={sm:{input:"h-8 text-sm px-3",icon:"w-4 h-4",iconPadding:"pl-8",trailingIconPadding:"pr-8"},md:{input:"h-[38px] text-sm px-4",icon:"w-4 h-4",iconPadding:"pl-10",trailingIconPadding:"pr-10"},lg:{input:"h-11 text-base px-4",icon:"w-5 h-5",iconPadding:"pl-11",trailingIconPadding:"pr-11"}},Ta=s.forwardRef(function({type:e="text",size:t="md",invalid:a=!1,leadingIcon:n,trailingIcon:r,leadingAddon:s,trailingAddon:i,className:l,disabled:c,...d},u){const h=La[t],m=n||s,g=r||i;return s||i?o.jsxs("div",{className:E("flex",l),children:[s&&o.jsx("span",{className:E("inline-flex items-center px-3 rounded-l-lg border border-r-0","bg-input-bg text-fg-muted text-sm",a?"border-sys-red":"border-input-border"),children:s}),o.jsx("input",{ref:u,type:e,disabled:c,className:E("flex-1 min-w-0 font-mono",h.input,"bg-input-bg",a?"border border-sys-red":"border border-input-border","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!c&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors",s&&!i&&"rounded-r-lg",i&&!s&&"rounded-l-lg",!s&&!i&&"radius-inner"),...d}),i&&o.jsx("span",{className:E("inline-flex items-center px-3 rounded-r-lg border border-l-0","bg-input-bg text-fg-muted text-sm",a?"border-sys-red":"border-input-border"),children:i})]}):o.jsxs("div",{className:E("relative",l),children:[n&&o.jsx("div",{className:E("absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none","text-fg-muted"),children:o.jsx("span",{className:h.icon,children:n})}),o.jsx("input",{ref:u,type:e,disabled:c,className:E("w-full radius-inner font-mono",h.input,m&&h.iconPadding,g&&h.trailingIconPadding,"bg-input-bg",a?"border border-sys-red":"border border-input-border","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!c&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors"),...d}),r&&o.jsx("div",{className:E("absolute inset-y-0 right-0 flex items-center pr-3","text-fg-muted"),children:o.jsx("span",{className:h.icon,children:r})})]})}),_a=s.forwardRef(function({label:e,description:t,errorMessage:a,required:n,invalid:r,className:s,...i},l){const c=r&&a;return o.jsxs(b,{className:E("flex flex-col gap-1.5",s),children:[e&&o.jsxs(w,{className:"text-sm font-medium text-fg-primary",children:[e,n&&o.jsx("span",{className:"text-sys-red ml-0.5",children:"*"})]}),t&&!c&&o.jsx(C,{className:"text-xs text-fg-muted -mt-0.5",children:t}),o.jsx(Ta,{ref:l,invalid:r,...i}),c&&o.jsx("p",{className:"text-xs text-sys-red",children:a})]})});s.forwardRef(function({value:e,onChange:t,min:a,max:n,step:r=1,precision:s,...i},l){const c=void 0!==s&&"number"==typeof e?e.toFixed(s):e;return o.jsx(Ta,{ref:l,type:"number",value:c,onChange:e=>{const r=e.target.value;if(""===r||"-"===r)return void t(0);const s=parseFloat(r);if(!isNaN(s)){const e=void 0!==a&&void 0!==n?Math.min(Math.max(s,a),n):void 0!==a?Math.max(s,a):void 0!==n?Math.min(s,n):s;t(e)}},min:a,max:n,step:r,...i})});const Ra={none:"resize-none",vertical:"resize-y",horizontal:"resize-x",both:"resize"},za=s.forwardRef(function({rows:e=3,resize:t="vertical",invalid:a=!1,disabled:n,className:r,...s},i){return o.jsx("textarea",{ref:i,rows:e,disabled:n,className:E("w-full radius-inner px-4 py-3 text-sm",Ra[t],"bg-subtle",a?"border border-sys-red":"border-control","text-fg-primary placeholder:text-fg-muted",a?"ring-focus-error":"ring-focus-inset",!n&&"hover:border-edge-strong","disabled:opacity-50 disabled:cursor-not-allowed","transition-colors",r),...s})});s.forwardRef(function({label:e,description:t,errorMessage:a,required:n,invalid:r,showCount:s,maxLength:i,value:l,className:c,...d},u){const h=r&&a,m="string"==typeof l?l.length:0;return o.jsxs(b,{className:E("flex flex-col gap-1.5",c),children:[e&&o.jsxs(w,{className:"text-sm font-medium text-fg-primary",children:[e,n&&o.jsx("span",{className:"text-sys-red ml-0.5",children:"*"})]}),t&&!h&&o.jsx(C,{className:"text-xs text-fg-muted -mt-0.5",children:t}),o.jsx(za,{ref:u,invalid:r,maxLength:i,value:l,...d}),o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[h?o.jsx("p",{className:"text-xs text-sys-red flex-1",children:a}):o.jsx("span",{}),s&&i&&o.jsxs("span",{className:E("text-xs",m>i?"text-sys-red":"text-fg-muted"),children:[m,"/",i]})]})]})});const Pa={sm:{box:"h-4 w-4",icon:"h-3 w-3",radius:"rounded"},md:{box:"h-5 w-5",icon:"h-3.5 w-3.5",radius:"rounded-md"},lg:{box:"h-6 w-6",icon:"h-4 w-4",radius:"rounded-md"}},Ia=s.forwardRef(function({checked:e,onChange:t,indeterminate:a=!1,label:n,description:r,size:s="md",disabled:i=!1,name:l,value:c,className:d},u){const h=Pa[s];return o.jsxs(b,{disabled:i,className:E("flex items-start gap-3",d),children:[o.jsxs(k,{ref:u,checked:e,onChange:t,name:l,value:c,className:E("group relative flex shrink-0 items-center justify-center",h.box,h.radius,"border-2 transition-all duration-150",!e&&!a&&"border-edge-subtle bg-subtle",(e||a)&&"border-sys-blue bg-sys-blue",!e&&!a&&!i&&"hover:border-edge-strong","ring-focus","disabled:opacity-50 disabled:cursor-not-allowed"),children:[e&&!a&&o.jsx(O,{className:E(h.icon,"text-white stroke-[3]")}),a&&o.jsx(H,{className:E(h.icon,"text-white stroke-[3]")})]}),(n||r)&&o.jsxs("div",{className:"flex-1 min-w-0 select-none",children:[n&&o.jsx(w,{className:E("text-sm font-medium cursor-pointer",i?"text-fg-muted":"text-fg-primary"),children:n}),r&&o.jsx(C,{className:"text-xs text-fg-muted mt-0.5",children:r})]})]})});s.createContext({variant:"default",divider:"subtle",grid:!0});const $a="0.9.286",qa="'JetBrains Mono', monospace",Oa=s.memo(function({height:e=16,responsive:t=!1,className:a=""}){const n="var(--sys-blue)",r="var(--fg-primary)";if(t){const e=145,t=24;return o.jsxs("svg",{className:a,viewBox:`0 0 ${e} ${t}`,preserveAspectRatio:"xMidYMid meet",role:"img","aria-label":"pyMC:Console",style:{display:"block",width:"80%",height:"auto"},children:[o.jsx("style",{children:`\n .logo-text {\n font-family: ${qa};\n }\n .logo-accent {\n fill: var(--sys-blue, #719CDF);\n }\n .logo-main {\n fill: var(--fg-primary, #FFFFFF);\n }\n `}),o.jsxs("text",{x:"0",y:"18",className:"logo-text",fontSize:"20",fontWeight:"400",letterSpacing:"-0.02em",children:[o.jsx("tspan",{className:"logo-accent",children:"py"}),o.jsx("tspan",{className:"logo-main",children:"MC"}),o.jsx("tspan",{className:"logo-accent",children:":"}),o.jsx("tspan",{className:"logo-main",children:"Console"})]})]})}const s="string"==typeof e?parseFloat(e):e,i={fontFamily:qa,fontSize:.8*s+"px",fontWeight:400,lineHeight:1,letterSpacing:"-0.02em",whiteSpace:"nowrap"};return o.jsxs("span",{className:a,style:i,role:"img","aria-label":"pyMC:Console",children:[o.jsx("span",{style:{color:n},children:"py"}),o.jsx("span",{style:{color:r},children:"MC"}),o.jsx("span",{style:{color:n},children:":"}),o.jsx("span",{style:{color:r},children:"Console"})]})});let Ha=null;function Wa(e){if(e)try{sessionStorage.setItem("auth_redirect_reason",e)}catch{}Ha?Ha("/login",{replace:!0}):window.location.replace("/login")}const Ua="pymc_jwt_token",Va="pymc_client_id",Ga="pymc_remember_me",Ja=new Set;function Ka(e){for(const a of Ja)try{a(e)}catch(t){console.error("[Auth] Token change callback error:",t)}}function Xa(){let e=localStorage.getItem(Va);return e||(e=`${Date.now()}-${Math.random().toString(36).substring(2,15)}`,localStorage.setItem(Va,e)),e}function Ya(){return"true"===localStorage.getItem(Ga)}function Qa(e){e?localStorage.setItem(Ga,"true"):localStorage.removeItem(Ga)}function Za(){return Ya()?localStorage:sessionStorage}function en(){return Za().getItem(Ua)||localStorage.getItem(Ua)||sessionStorage.getItem(Ua)}function tn(e){Za().setItem(Ua,e),Ya()?sessionStorage.removeItem(Ua):localStorage.removeItem(Ua),Ka(e)}function an(){localStorage.removeItem(Ua),sessionStorage.removeItem(Ua),Ka(null)}function nn(){return!(!en()||sn()&&(an(),1))}function rn(e){try{const t=e.split(".")[1].replace(/-/g,"+").replace(/_/g,"/"),a=decodeURIComponent(atob(t).split("").map(e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)).join(""));return JSON.parse(a)}catch{return null}}function sn(){const e=en();if(!e)return!0;const t=rn(e);return!t||!t.exp||Date.now()>=1e3*t.exp-6e4}function on(){const e=en();if(!e)return 0;const t=rn(e);return t&&t.exp?Math.max(0,Math.floor((1e3*t.exp-Date.now())/1e3)):0}function ln(){const e=en();if(!e)return!1;const t=rn(e);if(!t||!t.exp)return!1;const a=1e3*t.exp-Date.now();return a>0&&a<3e5}function cn(){const e=en();if(!e)return null;const t=rn(e);return t&&t.sub?t.sub:null}async function dn(e,t,a=!1){Qa(a);try{const a=await fetch("/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,password:t,client_id:Xa()})}),n=a.headers.get("content-type");if(!n||!n.includes("application/json"))return console.error("Login response not JSON:",a.status),{success:!1,error:`Server error: ${a.status}`};const r=await a.json();return r.success&&r.token?(tn(r.token),{success:!0}):{success:!1,error:r.error||"Login failed"}}catch(n){return console.error("Login error:",n),{success:!1,error:"Connection error. Please try again."}}}async function un(){const e=en();if(!e)return console.warn("[Auth] refreshToken: No token to refresh"),!1;const t=rn(e);(null==t?void 0:t.exp)&&Math.floor((1e3*t.exp-Date.now())/1e3);try{const t=await fetch("/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({client_id:Xa()})});if(!t.ok){let e="";try{const a=await t.json();e=a.error||JSON.stringify(a)}catch{e=t.statusText}return console.warn(`[Auth] Token refresh failed: ${t.status} - ${e}`),!1}const a=await t.json();if(a.success&&a.token){tn(a.token);const e=rn(a.token);return(null==e?void 0:e.exp)&&Math.floor((1e3*e.exp-Date.now())/1e3),!0}return console.warn("[Auth] Token refresh response invalid:",a),!1}catch(a){return console.error("[Auth] Token refresh error:",a),!1}}let hn=null;async function mn(){const e=en();if(!e)return!1;const t=rn(e);return(null==t?void 0:t.exp)&&Math.floor((1e3*t.exp-Date.now())/1e3),!ln()||hn||(hn=un().finally(()=>{hn=null}),hn)}let gn=!1;const pn=new class{constructor(){r(this,"listeners",new Set)}get active(){return this.listeners.size>0}emit(e,t){if(0===this.listeners.size)return;const a={type:e,ts:performance.now(),data:t};for(const n of this.listeners)n(a)}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}clear(){this.listeners.clear()}},fn=new class{constructor(){r(this,"ws",null),r(this,"connectionState","disconnected"),r(this,"reconnectAttempts",0),r(this,"pingIntervalId",null),r(this,"lastPongTime",Date.now()),r(this,"reconnectTimeoutId",null),r(this,"packetListeners",new Set),r(this,"statsListeners",new Set),r(this,"systemStatsListeners",new Set),r(this,"packetStatsListeners",new Set),r(this,"connectionListeners",new Set),r(this,"unsubscribeTokenChange",null),r(this,"wsSupported",!0)}buildWsUrl(){const e=en(),t=Xa(),a=new URLSearchParams;e&&a.set("token",e),t&&a.set("client_id",t);const n=a.toString()?`?${a.toString()}`:"";return`${"https:"===window.location.protocol?"wss:":"ws:"}//${window.location.host}/ws/packets${n}`}connect(){var e,t;if((null==(e=this.ws)?void 0:e.readyState)!==WebSocket.OPEN&&(null==(t=this.ws)?void 0:t.readyState)!==WebSocket.CONNECTING&&this.wsSupported){this.setConnectionState("connecting");try{const e=this.buildWsUrl();this.ws=new WebSocket(e),this.ws.onopen=this.handleOpen.bind(this),this.ws.onmessage=this.handleMessage.bind(this),this.ws.onerror=this.handleError.bind(this),this.ws.onclose=this.handleClose.bind(this),this.unsubscribeTokenChange||(this.unsubscribeTokenChange=(a=e=>{e&&"connected"===this.connectionState&&(this.disconnect(),this.connect())},Ja.add(a),()=>Ja.delete(a)))}catch(n){console.error("[WS] Failed to create WebSocket:",n),this.wsSupported=!1,this.setConnectionState("disconnected")}var a}}disconnect(){this.clearPingInterval(),this.clearReconnectTimeout(),this.ws&&(this.ws.onopen=null,this.ws.onmessage=null,this.ws.onerror=null,this.ws.onclose=null,this.ws.readyState!==WebSocket.OPEN&&this.ws.readyState!==WebSocket.CONNECTING||this.ws.close(1e3,"Client disconnect"),this.ws=null),this.setConnectionState("disconnected"),this.reconnectAttempts=0}isConnected(){var e;return(null==(e=this.ws)?void 0:e.readyState)===WebSocket.OPEN}getConnectionState(){return this.connectionState}isSupported(){return this.wsSupported}resetSupported(){this.wsSupported||(this.wsSupported=!0,this.reconnectAttempts=0)}send(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)return console.warn("[WS] Cannot send: not connected"),!1;try{return this.ws.send(JSON.stringify(e)),!0}catch(t){return console.error("[WS] Send failed:",t),!1}}onPacket(e){return this.packetListeners.add(e),()=>this.packetListeners.delete(e)}onStats(e){return this.statsListeners.add(e),()=>this.statsListeners.delete(e)}onSystemStats(e){return this.systemStatsListeners.add(e),()=>this.systemStatsListeners.delete(e)}onPacketStats(e){return this.packetStatsListeners.add(e),()=>this.packetStatsListeners.delete(e)}onConnectionChange(e){return this.connectionListeners.add(e),e(this.connectionState,this.reconnectAttempts),()=>this.connectionListeners.delete(e)}handleOpen(){this.setConnectionState("connected"),this.reconnectAttempts=0,pn.active&&pn.emit("transport:ws:state",{state:"connected"}),this.lastPongTime=Date.now();const e=en();e&&this.ws&&this.ws.send(JSON.stringify({type:"auth",token:e})),this.startPingInterval()}handleMessage(e){var t;try{const a=JSON.parse(e.data);switch(a.type){case"packet":pn.active&&pn.emit("transport:ws:packet",{hash:null==(t=a.data)?void 0:t.packet_hash}),this.notifyPacketListeners(a.data);break;case"stats":{pn.active&&pn.emit("transport:ws:stats");const e=a.data;e&&"noise_floor_dbm"in e&&this.notifyStatsListeners(e),(null==e?void 0:e.packet_stats)&&this.notifyPacketStatsListeners(e.packet_stats),(null==e?void 0:e.system_stats)&&this.notifySystemStatsListeners(e.system_stats);break}case"packet_stats":{const e=a.data;this.notifyPacketStatsListeners(e);break}case"system_stats":this.notifySystemStatsListeners(a.data);break;case"ping":this.lastPongTime=Date.now(),this.send({type:"pong"});break;case"pong":this.lastPongTime=Date.now();break;default:a.type}}catch(a){console.error("[WS] Failed to parse message:",a)}}handleError(e){console.error("[WS] Error:",e)}handleClose(e){e.code,e.reason,pn.active&&pn.emit("transport:ws:state",{state:"disconnected",code:e.code}),this.clearPingInterval(),1e3!==e.code?(1006===e.code&&this.reconnectAttempts,this.scheduleReconnect()):this.setConnectionState("disconnected")}setConnectionState(e){if(this.connectionState!==e){this.connectionState=e;for(const a of this.connectionListeners)try{a(e,this.reconnectAttempts)}catch(t){console.error("[WS] Connection listener error:",t)}}}notifyPacketListeners(e){for(const a of this.packetListeners)try{a(e)}catch(t){console.error("[WS] Packet listener error:",t)}}notifyStatsListeners(e){for(const a of this.statsListeners)try{a(e)}catch(t){console.error("[WS] Stats listener error:",t)}}notifySystemStatsListeners(e){for(const a of this.systemStatsListeners)try{a(e)}catch(t){console.error("[WS] System stats listener error:",t)}}notifyPacketStatsListeners(e){for(const a of this.packetStatsListeners)try{a(e)}catch(t){console.error("[WS] Packet stats listener error:",t)}}startPingInterval(){this.clearPingInterval(),this.pingIntervalId=setInterval(()=>{var e;if((null==(e=this.ws)?void 0:e.readyState)===WebSocket.OPEN){this.send({type:"ping"});const e=Date.now()-this.lastPongTime;e>6e4&&(console.warn(`[WS] No pong in ${Math.round(e/1e3)}s, reconnecting...`),this.disconnect(),this.connect())}},3e4)}async verifyConnection(e=5e3){return!(!this.ws||this.ws.readyState!==WebSocket.OPEN)&&new Promise(t=>{const a=Date.now(),n=this.lastPongTime;this.send({type:"ping"});const r=setInterval(()=>{this.lastPongTime>n?(clearInterval(r),t(!0)):Date.now()-a>e&&(clearInterval(r),console.warn("[WS] Connection verification failed - no pong received"),t(!1))},100)})}clearPingInterval(){this.pingIntervalId&&(clearInterval(this.pingIntervalId),this.pingIntervalId=null)}scheduleReconnect(){if(this.reconnectAttempts>=20)return console.error("[WS] Max reconnection attempts (20) reached"),this.wsSupported=!1,void this.setConnectionState("disconnected");this.setConnectionState("reconnecting");const e=Math.min(1e3*Math.pow(2,Math.min(this.reconnectAttempts,5)),3e4);this.reconnectAttempts,this.reconnectAttempts++,this.reconnectTimeoutId=setTimeout(()=>{this.reconnectTimeoutId=null,this.connect()},e)}clearReconnectTimeout(){this.reconnectTimeoutId&&(clearTimeout(this.reconnectTimeoutId),this.reconnectTimeoutId=null)}terminate(){this.disconnect(),this.unsubscribeTokenChange&&(this.unsubscribeTokenChange(),this.unsubscribeTokenChange=null),this.packetListeners.clear(),this.statsListeners.clear(),this.systemStatsListeners.clear(),this.packetStatsListeners.clear(),this.connectionListeners.clear()}};function bn(e){return{paths:e.paths,byEndpoints:new Map(e.byEndpointsEntries),canonicalPaths:new Map(e.canonicalPathsEntries),totalObservations:e.totalObservations,uniquePathCount:e.uniquePathCount}}function yn(){return{paths:[],byEndpoints:new Map,canonicalPaths:new Map,totalObservations:0,uniquePathCount:0}}async function wn(e,t,a,n,r=!1){const s=`/api/bulk_packets?${new URLSearchParams({limit:String(a),start_timestamp:String(e),end_timestamp:String(t)})}`,o={Accept:"application/json"},i=en();i&&(o.Authorization=`Bearer ${i}`);const l=new AbortController,c=setTimeout(()=>l.abort(),6e4);try{const i=await fetch(s,{headers:o,signal:l.signal});if(401===i.status&&!r&&await un())return wn(e,t,a,n,!0);if(!i.ok)throw new Error(`API ${i.status}`);const c=await i.json();return c.success&&c.data?c.data:[]}finally{clearTimeout(c)}}async function Cn(e,t,a,n,r,s){try{const o=await async function(e,t,a,n,r,s){const o=3600*(s??6),i=[];for(let d=r??Math.floor(Date.now()/1e3);d>e;d-=o)i.push({start:Math.max(e,d-o),end:d});i.length;let l=0,c=0;null==t||t({loaded:0,phase:"fetching",chunk:0});for(let d=0;d0&&await new Promise(e=>setTimeout(e,100));const e=i.slice(d,d+2);c++;const r=await Promise.all(e.map(e=>kn(e.start,e.end,n,a)));for(const t of r)l+=t;null==t||t({loaded:l,phase:"fetching",chunk:c})}return null==t||t({loaded:l,phase:"complete",chunk:c}),l}(e,t,a,n,r,s);if(o>0)return o}catch{}return async function(e,t,a,n,r){let s=0,o=0,i=r??Math.floor(Date.now()/1e3);for(new Date(1e3*e).toISOString(),new Date(1e3*i).toISOString(),null==t||t({loaded:0,phase:"fetching",chunk:0});i>e&&o<100;){o++;try{const r=await wn(e,i,1e4,n);if(0===r.length)break;s+=r.length;let l=i;for(let e=0;e=i){console.warn(`[bulk] Cursor stuck at ${i}`);break}if(i=c,null==a||a(r),null==t||t({loaded:s,phase:"fetching",chunk:o}),r.length<1e4)break}catch(l){if(l instanceof Error&&"AbortError"===l.name)break;console.error(`[bulk] Chunk ${o} failed:`,l);break}}return null==t||t({loaded:s,phase:"complete",chunk:o}),s}(e,t,a,n,r)}async function kn(e,t,a,n){let r=t,s=0,o=0;for(;r>e&&o<100;){o++;const t=await wn(e,r,5e3,a);if(0===t.length)break;s+=t.length,null==n||n(t);let i=r;for(let e=0;e=r)break;if(r=l,t.length<5e3)break}return s}"undefined"!=typeof window&&(window.diagnoseBulkFetch=async()=>{var e;Date.now();const t=en();try{const a=`/api/bulk_packets?limit=100&start_timestamp=0&end_timestamp=${Math.floor(Date.now()/1e3)}`,n={Accept:"application/json"};t&&(n.Authorization=`Bearer ${t}`);const r=await fetch(a,{headers:n});r.status,Object.fromEntries(r.headers.entries());const s=await r.text();s.length,Date.now();try{const t=JSON.parse(s);null==(e=t.data)||e.length,t.success||t.error}catch{s.slice(0,500)}}catch(a){console.error("[diag] Fetch failed:",a)}});const vn=3,Dn=2,An=15,xn=6,En=3,Fn=0,Bn=1,jn=2,Sn=3,Mn={[Fn]:"T_FLOOD",[Bn]:"FLOOD",[jn]:"DIRECT",[Sn]:"T_DIRECT"},Nn=0,Ln=1,Tn=2,_n=3,Rn=4,zn=5,Pn=6,In=7,$n=8,qn=9,On=10,Hn=11,Wn=15,Un={REQ:0,RESPONSE:1,TXT_MSG:2,ACK:3,ADVERT:4,GRP_TXT:5,GRP_DATA:6,ANON_REQ:7,PATH:8,TRACE:9},Vn={[Nn]:"REQ",[Ln]:"RESPONSE",[Tn]:"TXT_MSG",[_n]:"ACK",[Rn]:"ADVERT",[zn]:"GRP_TXT",[Pn]:"GRP_DATA",[In]:"ANON_REQ",[$n]:"PATH",[qn]:"TRACE",[On]:"MULTIPART",[Hn]:"CONTROL",[Wn]:"RAW_CUSTOM"},Gn=1,Jn=32,Kn=64,Xn=2,Yn=64,Qn=4,Zn=1,er=2,tr=3,ar=4,nr=16,rr=32,sr=64,or=128,ir=15;function lr(e){return 1===e||0===e}function cr(e){return 2===e||3===e}function dr(e){return 0===e||3===e}function ur(e){const t=[];switch(15&e){case 1:t.push("is companion");break;case 2:t.push("is repeater");break;case 3:t.push("is room server");break;case 4:t.push("is sensor")}return 16&e&&t.push("has location"),32&e&&t.push("has feature 1"),64&e&&t.push("has feature 2"),128&e&&t.push("has name"),t.join(", ")||"none"}function hr(e){return null==e?"UNKNOWN":Mn[e]??`UNKNOWN(${e})`}function mr(e){return null==e?"UNKNOWN":Vn[e]??`UNKNOWN(${e})`}const gr=Object.freeze({advertSender:null,advertNodeType:null,advertFlags:null,advertHasLocation:null,advertHasName:null,advertName:null,advertLatitude:null,advertLongitude:null});function pr(e,t){if(4!==t||!e||e.length<6)return gr;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return gr;const n=3&a;let r=2;if(0!==n&&3!==n||(r+=8),r+2>e.length)return gr;const s=parseInt(e.slice(r,r+2),16);if(isNaN(s))return gr;if(r+=2+2*s,r+64>e.length)return gr;const o=e.slice(r,r+64).toLowerCase(),i=r+200;if(i+2>e.length)return{...gr,advertSender:o};const l=parseInt(e.slice(i,i+2),16);if(isNaN(l))return{...gr,advertSender:o};const c=!!(16&l),d=!!(128&l);let u=null,h=null;if(c){const t=i+2;if(t+16<=e.length){const a=[0,1,2,3].map(a=>parseInt(e.slice(t+2*a,t+2*a+2),16)),n=[0,1,2,3].map(a=>parseInt(e.slice(t+8+2*a,t+8+2*a+2),16));a.every(e=>!isNaN(e))&&n.every(e=>!isNaN(e))&&(u=(a[0]|a[1]<<8|a[2]<<16|a[3]<<24)/1e6,h=(n[0]|n[1]<<8|n[2]<<16|n[3]<<24)/1e6)}}let m=null;if(d){let t=i+2;if(c&&(t+=16),32&l&&(t+=4),64&l&&(t+=4),t0){const e=new TextDecoder("utf-8",{fatal:!1}).decode(new Uint8Array(a)).replace(/\uFFFD/g,"").replace(/[\x00-\x1F\x7F]/g,"").trim();e.length>0&&(m=e)}}}return{advertSender:o,advertNodeType:15&l,advertFlags:l,advertHasLocation:c,advertHasName:d,advertName:m,advertLatitude:u,advertLongitude:h}}function fr(e,t){if(5!==t&&6!==t||!e||e.length<6)return null;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return null;const n=3&a;let r=2;if(0!==n&&3!==n||(r=10),r+2>e.length)return null;const s=parseInt(e.slice(r,r+2),16);return isNaN(s)?null:(r+=2+2*s,r+2>e.length?null:e.slice(r,r+2).toUpperCase())}function br(e){const t=Array.isArray(e.original_path)?e.original_path:[],a=e.route??e.route_type;let n;return n=0===a||1===a?Math.max(0,t.length-1):2===a||3===a?t.length:e.path_length??t.length,{hopCount:n,isZeroHop:0===n}}function yr(e,t){if(e&&/^[0-9a-fA-F]+$/.test(e)&&e.length%2==0)return e.length/2;const a=t.length??t.payload_length;if(a&&a>0){let e=2;const n=t.route??t.route_type;return 0!==n&&3!==n||(e+=4),null!=t.path_length?e+=t.path_length:Array.isArray(t.original_path)&&(e+=t.original_path.length),a+e}}function wr(e,t){if(9!==t||!e||e.length<6)return null;const a=parseInt(e.slice(0,2),16);if(isNaN(a))return null;const n=3&a;let r=2;if(0!==n&&3!==n||(r+=8),r+2>e.length)return null;const s=parseInt(e.slice(r,r+2),16);if(isNaN(s)||0===s)return null;r+=2;const o=r+2*s;if(o>e.length)return null;const i=[];for(let l=r;lthis.listeners.delete(e)}getState(){return{isLoading:this.isLoading,isBackgroundLoading:this.isBackgroundLoading,isTopologyLoading:this.isTopologyLoading,backgroundLoadComplete:this.meta.backgroundLoadComplete,topologyLoadComplete:this.meta.topologyLoadComplete,packetCount:this.packets.size,statusMessage:this.statusMessage,loadProgress:this.loadProgress,dataTier:this.meta.dataTier,threeDayLoadComplete:this.meta.threeDayLoadComplete,sevenDayLoadComplete:this.meta.sevenDayLoadComplete,fourteenDayLoadComplete:this.meta.fourteenDayLoadComplete,twentyOneDayLoadComplete:this.meta.twentyOneDayLoadComplete,thirtyDayLoadComplete:this.meta.thirtyDayLoadComplete,ninetyDayLoadComplete:this.meta.ninetyDayLoadComplete,maxRetentionDays:this.getMaxRetentionDays()}}getDataTier(){return this.meta.dataTier}getMaxRetentionDays(){if(!(this.meta.threeDayLoadComplete||this.meta.sevenDayLoadComplete||this.meta.fourteenDayLoadComplete||this.meta.twentyOneDayLoadComplete||this.meta.thirtyDayLoadComplete||this.meta.ninetyDayLoadComplete))return;const e=this.meta.oldestTimestamp;if(!e||e===1/0)return;const t=(Date.now()/1e3-e)/86400;return Math.ceil(t)+1}getPackets(){return this.sortedDirty&&(this.sortedPackets=Array.from(this.packets.values()).sort((e,t)=>(e.timestamp??0)-(t.timestamp??0)),this.sortedDirty=!1),this.sortedPackets}getPacketCount(){return this.packets.size}getPacketsUnsorted(){return Array.from(this.packets.values())}getNewestTimestamp(){return this.meta.newestTimestamp}getOldestTimestamp(){return this.meta.oldestTimestamp}isStale(){return 0===this.packets.size||Date.now()-this.meta.lastUpdated>vr}isHeavyLoadInProgress(){return this.isBackgroundLoading||this.isTopologyLoading}async initialLoad(e){if(this.meta.backgroundLoadComplete&&this.packets.size>0)return this.getPackets();0===this.packets.size&&(this.meta.oldestTimestamp=1/0,this.meta.newestTimestamp=0),this.sortedDirty=!0,this.isLoading=!0,this.loadProgress={loaded:this.packets.size,target:3e4,percent:0},this.notifyListeners();const t=Math.floor((Date.now()-864e5)/1e3);try{await Cn(t,e=>{this.loadProgress={loaded:e.loaded,target:Math.max(3e4,e.loaded),percent:"complete"===e.phase?100:Math.min(95,10*e.chunk)},e.chunk%2==0&&this.notifyListeners()},t=>{this.bulkInsert(t),null==e||e()}),this.meta.packetCount=this.packets.size,this.meta.backgroundLoadComplete=!0,this.meta.dataTier="24h",this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100},this.packets.size,this.saveToStorage(),this.scheduleInternHotTier()}catch(a){console.error("[PacketCache] Load failed:",a)}finally{this.isLoading=!1,this.loadProgress=null,this.notifyListeners()}return this.getPackets()}bulkInsert(e){let t=this.meta.oldestTimestamp;t!==1/0&&0!==t||(t=Number.MAX_SAFE_INTEGER);let a=this.meta.newestTimestamp;for(let n=0;na&&(a=o),this.extractAdvertData(r)}t0&&o<1/0?o:r;if(i<=s){const t={"3d":["threeDayLoadComplete"],"7d":["threeDayLoadComplete","sevenDayLoadComplete"],"14d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete"],"21d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete"],"30d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete","thirtyDayLoadComplete"],"90d":["threeDayLoadComplete","sevenDayLoadComplete","fourteenDayLoadComplete","twentyOneDayLoadComplete","thirtyDayLoadComplete","ninetyDayLoadComplete"]};for(const a of t[e]??[])this.meta[a]=!0;return this.meta.dataTier=e,this.isBackgroundLoading=!1,void this.notifyListeners()}const l={"3d":2,"7d":6,"14d":13,"21d":20,"30d":29,"90d":89},c={"3d":6,"7d":6,"14d":6,"21d":12,"30d":12,"90d":24},d=3e4*(l[e]??13),u=this.packets.size,h=u+d;this.loadProgress={loaded:u,target:h,percent:0},this.statusMessage=`Loading ${e} history...`,this.notifyListeners();let m=0;try{await Cn(s,e=>{this.loadProgress={loaded:u+e.loaded,target:Math.max(h,u+e.loaded),percent:Math.min(99,Math.round((u+e.loaded)/h*100))},e.chunk%2==0&&this.notifyListeners()},e=>{const t=this.packets.size;this.bulkInsert(e),m+=this.packets.size-t,null==a||a()},void 0,i,c[e]);const t=Date.now()-1e3*this.meta.oldestTimestamp;"3d"===e?(this.meta.threeDayLoadComplete=t>=Dr,this.meta.threeDayLoadComplete&&(this.meta.dataTier="3d")):"7d"===e?(this.meta.sevenDayLoadComplete=t>=Ar,this.meta.sevenDayLoadComplete&&(this.meta.dataTier="7d")):"14d"===e?(this.meta.fourteenDayLoadComplete=t>=xr,this.meta.fourteenDayLoadComplete&&(this.meta.dataTier="14d")):"21d"===e?(this.meta.twentyOneDayLoadComplete=t>=Er,this.meta.twentyOneDayLoadComplete&&(this.meta.dataTier="21d")):"30d"===e?(this.meta.thirtyDayLoadComplete=t>=Fr,this.meta.thirtyDayLoadComplete&&(this.meta.dataTier="30d")):"90d"===e&&(this.meta.ninetyDayLoadComplete=t>=Br,this.meta.ninetyDayLoadComplete&&(this.meta.dataTier="90d")),this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100};const n=(t/864e5).toFixed(1);Number(n),this.packets.size.toLocaleString(),m.toLocaleString(),this.notifyListeners(),this.saveToStorage()}catch(g){console.error(`[PacketCache] ${e} load failed:`,g),this.statusMessage=`${e} load failed`}finally{this.isBackgroundLoading=!1,this.statusMessage="",this.loadProgress=null,this.notifyListeners()}}isDataTierAvailable(e){switch(e){case"24h":return this.meta.backgroundLoadComplete;case"3d":return this.meta.threeDayLoadComplete;case"7d":return this.meta.sevenDayLoadComplete;case"14d":return this.meta.fourteenDayLoadComplete;case"21d":return this.meta.twentyOneDayLoadComplete;case"30d":return this.meta.thirtyDayLoadComplete;case"90d":return this.meta.ninetyDayLoadComplete;default:return!1}}async topologyLoad(){if(!this.meta.topologyLoadComplete&&!this.isTopologyLoading)return this.doTopologyLoad()}async forceTopologyLoad(){if(!this.isTopologyLoading)return this.meta.topologyLoadComplete=!1,this.doTopologyLoad()}async forceDeepLoad(){return this.forceTopologyLoad()}async doTopologyLoad(){this.isTopologyLoading=!0;const e=Date.now(),t=Math.floor(e/1e3),a=Math.floor((e-xr)/1e3),n=this.meta.oldestTimestamp,r=n>0&&n<1/0?n:t;if(r<=a)return this.meta.topologyLoadComplete=!0,void(this.isTopologyLoading=!1);const s=this.packets.size,o=s+42e4;this.statusMessage="Loading topology data...",this.loadProgress={loaded:s,target:o,percent:0},this.notifyListeners();let i=0;try{await Cn(a,e=>{this.loadProgress={loaded:s+e.loaded,target:Math.max(o,s+e.loaded),percent:Math.min(99,Math.round((s+e.loaded)/o*100))},e.chunk%2==0&&this.notifyListeners()},e=>{const t=this.packets.size;this.bulkInsert(e),i+=this.packets.size-t},void 0,r),this.statusMessage=`Processing ${this.packets.size.toLocaleString()} packets...`,this.loadProgress={loaded:this.packets.size,target:this.packets.size,percent:100},this.notifyListeners(),this.meta.topologyLoadComplete=!0,this.meta.threeDayLoadComplete=!0,this.meta.sevenDayLoadComplete=!0,this.meta.fourteenDayLoadComplete=!0,this.meta.dataTier="14d",this.saveToStorage(),this.packets.size}catch(l){console.error("[PacketCache] Topology load failed:",l),this.statusMessage="Load failed"}finally{this.isTopologyLoading=!1,this.statusMessage="",this.loadProgress=null,this.notifyListeners()}}async poll(){try{const e=await this.fetchRecentPackets(100);if(e.success&&e.data){const t=this.packets.size;this.mergePackets(e.data);const a=this.packets.size-t;return a>0&&(this.saveToStorage(),this.notifyListeners()),a}}catch(e){console.error("[PacketCache] Poll failed:",e)}return 0}clear(){this.packets.clear(),this.sortedPackets=[],this.sortedDirty=!0,this.stringPool.clear(),this.stripScheduled=!1,this.meta={oldestTimestamp:0,newestTimestamp:0,lastUpdated:0,packetCount:0,backgroundLoadComplete:!1,topologyLoadComplete:!1,dataTier:"24h",threeDayLoadComplete:!1,sevenDayLoadComplete:!1,fourteenDayLoadComplete:!1,twentyOneDayLoadComplete:!1,thirtyDayLoadComplete:!1,ninetyDayLoadComplete:!1},this.clearStorage(),this.notifyListeners()}mergePacketsDirectly(e){const t=this.packets.size;this.mergePackets(e);const a=this.packets.size-t;return a>0&&(this.saveToStorage(),this.notifyListeners()),a}mergePackets(e){let t=!1;for(const a of e){const e=a.packet_hash;if(!e)continue;const n=a.timestamp??0,r=`${e}:${n}`;this.packets.has(r)||(this.packets.set(r,a),t=!0),(0===this.meta.oldestTimestamp||nthis.meta.newestTimestamp&&(this.meta.newestTimestamp=n)}if(t){this.sortedDirty=!0;for(const t of e)this.internPacketStrings(t),this.extractAdvertData(t),this.extractChannelHash(t),this.extractByteLength(t),this.extractHopData(t);this.scheduleStrip()}this.meta.lastUpdated=Date.now(),this.meta.packetCount=this.packets.size}notifyListeners(){const e=this.getState();for(const t of this.listeners)t(e)}scheduleStrip(){this.stripScheduled||this.packets.size<=Sr||"undefined"!=typeof window&&(this.stripScheduled=!0,"requestIdleCallback"in window?requestIdleCallback(()=>this.stripWarmPackets(),{timeout:5e3}):setTimeout(()=>this.stripWarmPackets(),500))}stripWarmPackets(){this.stripScheduled=!1;const e=this.packets.size;if(e<=Sr)return;const t=Array.from(this.packets.values());t.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0));const a=e-Sr;let n=0;for(let r=0;r=5e3&&rt.length)return null;const s=parseInt(t.slice(r,r+2),16);if(isNaN(s))return null;if(r+=2+2*s,r>=t.length)return null;const o=t.slice(r);return o.length>=38?o.slice(0,38):o}extractTraceTag(e){if(!e||e.length<8)return null;const t=parseInt(e.slice(0,2),16),a=parseInt(e.slice(2,4),16),n=parseInt(e.slice(4,6),16),r=parseInt(e.slice(6,8),16);return isNaN(t)||isNaN(a)||isNaN(n)||isNaN(r)?null:((t|a<<8|n<<16|r<<24)>>>0).toString(16).toUpperCase().padStart(8,"0")}extractTracePathHashes(e){if(!e||e.length<20)return null;const t=e.slice(18);if(0===t.length)return null;const a=[];for(let n=0;n0?a:null}internPacketStrings(e){if(e.src_hash&&(e.src_hash=this.intern(e.src_hash)),e.dst_hash&&(e.dst_hash=this.intern(e.dst_hash)),e.path_hash&&(e.path_hash=this.intern(e.path_hash)),e.original_path&&"string"==typeof e.original_path)try{e.original_path=JSON.parse(e.original_path)}catch{e.original_path=void 0}if(e.forwarded_path&&"string"==typeof e.forwarded_path)try{e.forwarded_path=JSON.parse(e.forwarded_path)}catch{e.forwarded_path=void 0}if(Array.isArray(e.original_path))for(let t=0;t5e4&&this.stringPool.clear();const t=this.stringPool.get(e);return void 0!==t?t:(this.stringPool.set(e,e),e)}scheduleInternHotTier(){if("undefined"==typeof window)return;const e=()=>{for(const e of this.packets.values())e._stripped||(this.internPacketStrings(e),this.extractAdvertData(e))};"requestIdleCallback"in window?requestIdleCallback(()=>e(),{timeout:1e4}):setTimeout(e,1e3)}loadFromStorage(){if("undefined"!=typeof window)try{const e=localStorage.getItem(kr);e&&(this.meta=JSON.parse(e));const t=localStorage.getItem(Cr);if(t){const e=JSON.parse(t);let a=1/0,n=0;for(const t of e)if(t.packet_hash){const e=t.timestamp??0,r=`${t.packet_hash}:${e}`;this.packets.set(r,t),this.extractAdvertData(t),e>0&&en&&(n=e)}this.packets.size>0&&a!==1/0&&(this.meta.oldestTimestamp=a,this.meta.newestTimestamp=n)}if(this.meta.lastUpdated>0&&Date.now()-this.meta.lastUpdated>vr)return void this.clear();this.meta.backgroundLoadComplete=!1,this.meta.threeDayLoadComplete=!1,this.meta.sevenDayLoadComplete=!1,this.meta.fourteenDayLoadComplete=!1,this.meta.twentyOneDayLoadComplete=!1,this.meta.thirtyDayLoadComplete=!1,this.meta.ninetyDayLoadComplete=!1,this.meta.dataTier="24h";const a=37500;this.meta.topologyLoadComplete&&this.packets.size{this.saveTimer=null,this.flushToStorage()},e.SAVE_DEBOUNCE_MS)))}flushToStorage(){try{let e;if(localStorage.setItem(kr,JSON.stringify(this.meta)),this.packets.size<=3e3)e=Array.from(this.packets.values());else if(this.sortedDirty){const t=Array.from(this.packets.values()),a=new Float64Array(t.length);for(let e=0;e(e.timestamp??0)>=n),e.sort((e,t)=>(e.timestamp??0)-(t.timestamp??0))}else e=this.sortedPackets.slice(-3e3);localStorage.setItem(Cr,JSON.stringify(e))}catch(e){if(e instanceof DOMException&&"QuotaExceededError"===e.name){console.warn("[PacketCache] Storage quota exceeded, clearing packet data to save meta");try{localStorage.removeItem(Cr),localStorage.setItem(kr,JSON.stringify(this.meta))}catch{console.warn("[PacketCache] Unable to save even meta data")}}else console.warn("[PacketCache] Failed to save to storage:",e)}}clearStorage(){if("undefined"!=typeof window)try{localStorage.removeItem(Cr),localStorage.removeItem(kr)}catch(e){console.warn("[PacketCache] Failed to clear storage:",e)}}async fetchRecentPackets(e=1e3,t=!1){const a=`/api/recent_packets?limit=${e}`,n=en(),r={Accept:"application/json"};n&&(r.Authorization=`Bearer ${n}`);const s=await fetch(a,{headers:r});if(401===s.status&&!t&&await un())return this.fetchRecentPackets(e,!0);if(!s.ok)throw new Error(`API error: ${s.status}`);return s.json()}};r(Mr,"SAVE_DEBOUNCE_MS",1e4);const Nr=new Mr,Lr=3e5,Tr=class e{constructor(){r(this,"worker",null),r(this,"listeners",new Set),r(this,"currentTopology",{edges:[],validatedEdges:[],weakEdges:[],certainEdges:[],uncertainEdges:[],edgeMap:new Map,maxPacketCount:0,maxCertainCount:0,neighborAffinity:new Map,fullAffinity:new Map,localPrefix:null,centrality:new Map,hubNodes:[],gatewayNodes:[],loops:[],loopEdgeKeys:new Set,txDelayRecommendations:new Map,pathRegistry:yn(),edgeBetweenness:new Map,backboneEdges:[],nodeMobility:new Map,mobileNodes:[],pathHealth:[],lastHopNeighbors:[],disambiguationStats:{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:[],viterbiStats:{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map,communityCount:0,backboneNodes:[],traceLinks:new Map,traceLinkSummary:{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:{confirmedResolutions:new Map,confirmedLinks:[]}}),r(this,"isComputing",!1),r(this,"pendingRequest",null),r(this,"debounceTimer",null),r(this,"restartCount",0),r(this,"lastInputFingerprint",""),r(this,"lastComputeTime",0),r(this,"lastComputePacketCount",0),r(this,"lastComputeNeighborCount",0),r(this,"lastComputeNewestTs",0),r(this,"lastComputeWindowHours",null),r(this,"knownPrefixPairs",new Set),r(this,"pendingFingerprint",""),r(this,"pendingPacketCount",0),r(this,"pendingNeighborCount",0),r(this,"pendingNewestTs",0),r(this,"pendingWindowHours",null)}getDebounceMs(e=!1){return e?100:Nr.isHeavyLoadInProgress()?5e3:Nr.getPacketCount()>1e5?500:100}buildFingerprint(e,t,a,n){return`${e}:${t}:${a??""}:${n??""}`}captureKnownPrefixPairs(){const e=new Set;for(const t of this.currentTopology.edgeMap.keys()){const a=t.split("→");2===a.length&&e.add(`${a[0].slice(0,2)}→${a[1].slice(0,2)}`)}this.knownPrefixPairs=e}hasNewPrefixPairs(e){var t;if(0===e.length||0===this.knownPrefixPairs.size)return!0;const a=e.length-this.lastComputePacketCount;if(a<=0)return!1;if(a>500)return!0;const n=this.lastComputeNewestTs;for(let r=e.length-1;r>=0;r--){const a=e[r];if((a.timestamp??0)<=n)break;const s=a.original_path??a.forwarded_path,o=null==(t=a.src_hash)?void 0:t.slice(0,2);if(o&&s&&s.length>0){const e=String(s[0]).slice(0,2);if(!this.knownPrefixPairs.has(`${o}→${e}`))return!0}if(s&&s.length>=2)for(let e=0;e{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[TopologyService] Worker error:",e),this.isComputing=!1;for(const t of this.listeners)try{t(this.currentTopology,0)}catch{}this.restartWorker()}}catch(e){console.error("[TopologyService] Failed to initialize worker:",e)}return this.worker}restartWorker(){this.restartCount>=e.MAX_RESTARTS?console.warn("[TopologyService] Max restarts reached, not restarting"):(this.restartCount++,console.warn(`[TopologyService] Restarting worker (attempt ${this.restartCount})`),this.worker&&(this.worker.terminate(),this.worker=null))}handleWorkerMessage(e){if(this.isComputing=!1,"error"!==e.type){var t;this.currentTopology={edges:(t=e.payload).edges??[],validatedEdges:t.validatedEdges??[],weakEdges:t.weakEdges??[],certainEdges:t.certainEdges??[],uncertainEdges:t.uncertainEdges??[],maxPacketCount:t.maxPacketCount??0,maxCertainCount:t.maxCertainCount??0,localPrefix:t.localPrefix??null,hubNodes:t.hubNodes??[],gatewayNodes:t.gatewayNodes??[],edgeMap:new Map(t.edgeMapEntries??[]),neighborAffinity:new Map(t.neighborAffinityEntries??[]),fullAffinity:new Map(t.fullAffinityEntries??[]),centrality:new Map(t.centralityEntries??[]),loops:t.loops??[],loopEdgeKeys:new Set(t.loopEdgeKeyEntries??[]),txDelayRecommendations:new Map(t.txDelayRecommendationEntries??[]),pathRegistry:t.pathRegistry?bn(t.pathRegistry):yn(),edgeBetweenness:new Map(t.edgeBetweennessEntries??[]),backboneEdges:t.backboneEdges??[],nodeMobility:new Map(t.nodeMobilityEntries??[]),mobileNodes:t.mobileNodes??[],pathHealth:t.pathHealth??[],lastHopNeighbors:t.lastHopNeighbors??[],disambiguationStats:t.disambiguationStats??{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:t.discoveredNodes??[],viterbiStats:t.viterbiStats??{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map(t.nodeMetricsEntries??[]),communityCount:t.communityCount??0,backboneNodes:t.backboneNodes??[],traceLinks:new Map(t.traceLinkEntries??[]),traceLinkSummary:t.traceLinkSummary??{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:t.traceDisambiguationFeedbackEntries?{confirmedResolutions:new Map(t.traceDisambiguationFeedbackEntries.confirmedResolutions??[]),confirmedLinks:t.traceDisambiguationFeedbackEntries.confirmedLinks??[]}:{confirmedResolutions:new Map,confirmedLinks:[]}},this.lastInputFingerprint=this.pendingFingerprint,this.lastComputeTime=Date.now(),this.lastComputePacketCount=this.pendingPacketCount,this.lastComputeNeighborCount=this.pendingNeighborCount,this.lastComputeNewestTs=this.pendingNewestTs,this.lastComputeWindowHours=this.pendingWindowHours,this.captureKnownPrefixPairs(),pn.active&&pn.emit("worker:topology:done",{ms:e.computeTimeMs,edges:this.currentTopology.edges.length});for(const t of this.listeners)try{t(this.currentTopology,e.computeTimeMs)}catch(a){console.error("[TopologyService] Listener error:",a)}if(this.pendingRequest){const e=this.pendingRequest;this.pendingRequest=null,this.computeInternal(e)}}else console.error("[TopologyService] Worker computation error:",e.error)}computeInternal(e){const t=this.ensureWorker();if(!t)return void console.warn("[TopologyService] Worker not available");this.isComputing=!0,pn.active&&pn.emit("worker:topology:start",{packets:e.packets.length});const a={type:"compute",payload:e};t.postMessage(a)}compute(e,t,a,n,r,s,o,i,l,c,d){const u=Object.keys(t).length,h=this.buildFingerprint(e.length,u,a,c),m=Date.now()-this.lastComputeTime;if(h===this.lastInputFingerprint&&m0&&mthis.lastComputePacketCount&&!this.hasNewPrefixPairs(e))return;const g=c!==this.lastComputeWindowHours;this.pendingFingerprint=h,this.pendingPacketCount=e.length,this.pendingNeighborCount=u,this.pendingWindowHours=c??null,this.pendingNewestTs=e.length>0?e[e.length-1].timestamp??0:0;const p=this.currentTopology.traceDisambiguationFeedback,f=p.confirmedResolutions.size>0||p.confirmedLinks.length>0?{confirmedResolutions:Array.from(p.confirmedResolutions.entries()),confirmedLinks:p.confirmedLinks}:void 0,b={packets:e,neighbors:t,localHash:a,localLat:n,localLon:r,airtimeMs:s,zeroHopNeighbors:o,terrainGrid:i,enableTerrainAware:void 0!==i,srcHashResolverEntries:l?Array.from(l.entries()):void 0,windowHours:c,spreadingFactor:d,previousTraceEvidenceSerialized:f};this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.isComputing?this.pendingRequest=b:this.computeInternal(b)},this.getDebounceMs(g))}subscribe(e){return this.listeners.add(e),this.currentTopology.edges.length>0&&e(this.currentTopology,0),()=>{this.listeners.delete(e)}}getTopology(){return this.currentTopology}isWorking(){return this.isComputing}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}};r(Tr,"MAX_RESTARTS",1);const _r=new Tr,Rr=F(e=>({topology:{edges:[],validatedEdges:[],weakEdges:[],certainEdges:[],uncertainEdges:[],edgeMap:new Map,maxPacketCount:0,maxCertainCount:0,neighborAffinity:new Map,fullAffinity:new Map,localPrefix:null,centrality:new Map,hubNodes:[],gatewayNodes:[],loops:[],loopEdgeKeys:new Set,txDelayRecommendations:new Map,pathRegistry:yn(),edgeBetweenness:new Map,backboneEdges:[],nodeMobility:new Map,mobileNodes:[],pathHealth:[],lastHopNeighbors:[],disambiguationStats:{totalPrefixes:0,unambiguousPrefixes:0,collisionPrefixes:0,collisionRate:0,avgConfidence:0,lowConfidencePrefixes:[],highCollisionPrefixes:[],totalResolutions:0},discoveredNodes:[],viterbiStats:{totalPaths:0,pathsWithGhosts:0,avgPathCost:0,avgPathConfidence:0,observationOverrideCount:0,tracePacketsProcessed:0,pathPacketsProcessed:0,distantEdgesDiscovered:0,duplicateGroupsFound:0,duplicatePathsUnique:0,echolocationEdgesInferred:0},nodeMetrics:new Map,communityCount:0,backboneNodes:[],traceLinks:new Map,traceLinkSummary:{totalDirectedLinks:0,totalTraces:0,totalObservations:0,bidirectionalLinks:0,meanSnr:0,medianSnr:0,avgConfidence:0,trendCounts:{improving:0,stable:0,degrading:0,insufficient:0},qualityCounts:{excellent:0,good:0,fair:0,poor:0,critical:0},windowHours:null},traceDisambiguationFeedback:{confirmedResolutions:new Map,confirmedLinks:[]}},isComputing:!1,lastComputeTimeMs:0,lastUpdated:0,setTopology:(t,a)=>e({topology:t,lastComputeTimeMs:a,lastUpdated:Date.now(),isComputing:!1}),setComputing:t=>e({isComputing:t})}));"undefined"!=typeof window&&_r.subscribe((e,t)=>{Rr.getState().setTopology(e,t)});const zr=Rr,Pr=()=>Rr(e=>e.topology),Ir=()=>Rr(e=>e.topology.hubNodes),$r=()=>Rr(e=>e.topology.centrality),qr=()=>Rr(e=>e.topology.fullAffinity),Or=()=>Rr(e=>e.isComputing),Hr=()=>Rr(e=>e.lastUpdated);let Wr=null,Ur=null,Vr=null,Gr=null,Jr=null,Kr=null;const Xr=()=>Rr(e=>(e.topology.hubNodes!==Ur&&(Ur=e.topology.hubNodes,Wr=new Set(e.topology.hubNodes)),Wr)),Yr=()=>Rr(e=>e.topology.txDelayRecommendations),Qr=()=>Rr(e=>e.topology.pathRegistry.canonicalPaths),Zr=()=>Rr(e=>(e.topology.mobileNodes!==Gr&&(Gr=e.topology.mobileNodes,Vr=new Set(e.topology.mobileNodes)),Vr)),es=()=>Rr(e=>e.topology.pathHealth),ts=()=>Rr(e=>e.topology.lastHopNeighbors),as=()=>Rr(e=>e.topology.disambiguationStats),ns=()=>Rr(e=>e.topology.disambiguationStats.highCollisionPrefixes),rs=()=>Rr(e=>e.topology.disambiguationStats.totalPrefixes>0),ss=()=>Rr(e=>e.topology.discoveredNodes),os=()=>Rr(e=>e.topology.viterbiStats),is=()=>Rr(e=>(e.topology.discoveredNodes!==Kr&&(Kr=e.topology.discoveredNodes,Jr=e.topology.discoveredNodes.filter(e=>e.isLikelyReal)),Jr)),ls=()=>Rr(e=>e.topology.nodeMetrics),cs=()=>Rr(e=>e.topology.communityCount);let ds=null,us=null;const hs=()=>Rr(e=>{if(e.topology.nodeMetrics!==us){us=e.topology.nodeMetrics,ds={local:0,hub:0,gateway:0,backbone:0,neighbor:0,mobile:0,ghost:0,standard:0};for(const t of e.topology.nodeMetrics.values())ds[t.nodeClass]++}return ds}),ms=()=>Rr(e=>e.topology.traceLinks),gs=()=>Rr(e=>e.topology.traceLinkSummary),ps=()=>Rr(e=>e.topology.traceLinks.size>0),fs=()=>Rr(e=>e.topology.traceDisambiguationFeedback);let bs=null,ys=null;const ws=()=>Rr(e=>{const t=e.topology.traceLinks;if(t!==ys){ys=t;const e=new Map,a=new Map,n=new Set;for(const o of t.values()){const t=o.fromHash0?(i.mean*i.count+l.mean*l.count)/e:0,median:e>0?(i.median*i.count+l.median*l.count)/e:0,min:Math.min(i.min,l.min),max:Math.max(i.max,l.max),stdDev:Math.max(i.stdDev,l.stdDev),count:e}}else i?c=i:l&&(c=l);const d=i&&l?Math.abs(i.mean-l.mean):null,u=i&&l?Math.min(i.mean,l.mean):(null==i?void 0:i.mean)??(null==l?void 0:l.mean)??0,h=u>=10?"excellent":u>=5?"good":u>=0?"fair":u>=-5?"poor":"critical",m=Math.max((null==n?void 0:n.confidence)??0,(null==o?void 0:o.confidence)??0),[g,p]=t.split("|");r.push({nodeA:{hash:g,name:null,prefix:(null==n?void 0:n.fromPrefix)??(null==o?void 0:o.toPrefix)??g.slice(0,2)},nodeB:{hash:p,name:null,prefix:(null==n?void 0:n.toPrefix)??(null==o?void 0:o.fromPrefix)??p.slice(0,2)},aToB:i,bToA:l,composite:c,asymmetryDb:d,quality:h,confidence:m})}r.sort((e,t)=>t.composite.mean-e.composite.mean),bs=r}return bs});function Cs(e,t,a,n){return!t&&n>=3?"offline":a?"connected"!==e&&t||n>0&&n<3?"degraded":"connected":"offline"}const ks=F((e,t)=>({wsState:"disconnected",wsReconnectAttempt:0,restHealthy:!0,lastSuccessfulFetch:null,consecutiveFailures:0,authValid:!0,authExpiresIn:null,meshContext:{edgeCount:0,hubCount:0,lastTopologyUpdate:0,hasTopologyData:!1},health:"connected",bannerDismissed:!1,isInitializing:!0,initialize:()=>{const a=fn.onConnectionChange((a,n)=>{const{restHealthy:r,authValid:s,consecutiveFailures:o,health:i,isInitializing:l}=t(),c=l&&"connected"===a,d=Cs(a,r,s,o);e({wsState:a,wsReconnectAttempt:n??0,health:d,isInitializing:!c&&l,bannerDismissed:(d===i||"connected"!==d)&&t().bannerDismissed})});t().updateAuthState();const n=zr.subscribe(a=>{const{topology:n,lastUpdated:r}=a,s={edgeCount:n.edges.length,hubCount:n.hubNodes.length,lastTopologyUpdate:r,hasTopologyData:n.edges.length>0},o=t().meshContext;o.edgeCount===s.edgeCount&&o.hubCount===s.hubCount&&o.lastTopologyUpdate===s.lastTopologyUpdate||e({meshContext:s})}),r=setTimeout(()=>{t().isInitializing&&e({isInitializing:!1})},1e4),s=setInterval(()=>{t().updateAuthState()},3e4);return()=>{a(),n(),clearTimeout(r),clearInterval(s)}},updateRestHealth:a=>{const{wsState:n,authValid:r,consecutiveFailures:s,health:o}=t(),i=a?0:s+1,l=a||i<3,c=a?Date.now():t().lastSuccessfulFetch,d=Cs(n,l,r,i);e({restHealthy:l,lastSuccessfulFetch:c,consecutiveFailures:i,health:d,bannerDismissed:"connected"!==d&&d===o&&t().bannerDismissed})},updateAuthState:()=>{const a=nn()&&!sn(),n=on(),{wsState:r,restHealthy:s,consecutiveFailures:o,health:i}=t(),l=Cs(r,s,a,o);e({authValid:a,authExpiresIn:n>0?n:null,health:l,bannerDismissed:l===i&&t().bannerDismissed})},dismissBanner:()=>{e({bannerDismissed:!0})}})),vs=()=>ks(e=>e.health),Ds="";class As extends Error{constructor(e,t){super(`Request timed out after ${t}ms: ${e}`),this.endpoint=e,this.timeoutMs=t,this.name="TimeoutError"}}const xs=new Map;let Es=!1;async function Fs(e,t,a=!1){const n=function(e,t){return(null==t?void 0:t.method)&&"GET"!==t.method?"":e}(e,t);if(n){const e=xs.get(n);if(e)return e}const r=`${e}`;!a&&ln()&&(await un()||console.warn("[API] Proactive token refresh failed, continuing with existing token"));const s=en();if(!s&&!e.includes("/auth/"))throw console.warn("[API] No auth token available for protected endpoint:",e),Wa("no_token"),new Error("Not authenticated");const o={Accept:"application/json",...s?{Authorization:`Bearer ${s}`}:{}};if(null==t?void 0:t.headers){const e=t.headers;e instanceof Headers?e.forEach((e,t)=>{o[t]=e}):Array.isArray(e)?e.forEach(([e,t])=>{o[e]=t}):Object.assign(o,e)}(null==t?void 0:t.body)&&(o["Content-Type"]="application/json");const i=!(null==t?void 0:t.method)||"GET"===t.method,l=(null==t?void 0:t.timeout)??(i?15e3:3e4),c=new AbortController,d=setTimeout(()=>c.abort(),l);(null==t?void 0:t.signal)&&(t.signal.aborted?(clearTimeout(d),c.abort()):t.signal.addEventListener("abort",()=>c.abort(),{once:!0}));const u=(async()=>{try{const n=await fetch(r,{...t,headers:o,signal:c.signal});if(clearTimeout(d),401===n.status){if(!a&&!Es){if(await un())return Fs(e,t,!0);console.warn("[API] Token refresh failed")}throw Es||(Es=!0,an(),Wa("session_expired")),new Error("Session expired. Please log in again.")}if(!n.ok)throw new Error(`API error: ${n.status} ${n.statusText} (${e})`);return n.json()}catch(n){if(clearTimeout(d),n instanceof DOMException&&"AbortError"===n.name)throw ks.getState().updateRestHealth(!1),new As(e,l);throw n}})();return n&&(xs.set(n,u),u.finally(()=>{xs.delete(n)})),u}const Bs={spreadingFactor:7,bandwidthHz:125e3,codingRate:5,preambleLength:8,crcEnabled:!0,explicitHeader:!0};function js(e){let t=2;const a=e.route??e.route_type;return 0!==a&&3!==a||(t+=4),null!=e.path_length?t+=e.path_length:Array.isArray(e.original_path)&&(t+=e.original_path.length),t}function Ss(e){if(void 0!==e._byteLength)return e._byteLength;if(e.raw_packet){const t=e.raw_packet;if(/^[0-9a-fA-F]+$/.test(t)&&t.length%2==0)return t.length/2;if(/^[A-Za-z0-9+/=]+$/.test(t)){const e=(t.match(/=+$/)||[""])[0].length;return Math.floor(3*t.length/4)-e}return t.length}if(e.length&&e.length>0)return e.length+js(e);if(e.payload_length&&e.payload_length>0)return e.payload_length+js(e);if(e.payload){const t=e.payload;return/^[0-9a-fA-F]+$/.test(t)&&t.length%2==0?t.length/2:t.length}return 32}function Ms(e,t={}){return void 0!==e.airtime_ms&&e.airtime_ms>0?e.airtime_ms:function(e,t={}){const a=t.spreadingFactor??Bs.spreadingFactor,n=t.bandwidthHz??Bs.bandwidthHz,r=t.codingRate??Bs.codingRate,s=t.preambleLength??Bs.preambleLength??8,o=t.crcEnabled??Bs.crcEnabled?1:0,i=t.explicitHeader??Bs.explicitHeader?0:1,l=a>=11&&n<=125e3?1:0,c=n/1e3,d=Math.pow(2,a)/c,u=(s+4.25)*d,h=Math.max(8*e-4*a+28+16*o-20*i,0),m=4*(a-2*l);return u+(8+Math.ceil(h/m)*r)*d}(Ss(e),t)}function Ns(e){return e&&"chat node"===e.toLowerCase()?"Companion":e}async function Ls(){return function(e){if(e.neighbors)for(const t of Object.values(e.neighbors))t.contact_type=Ns(t.contact_type);return e}(await Fs("/api/stats"))}async function Ts(){return Fs("/api/logs")}async function _s(e){return Fs(`/api/packet_by_hash?packet_hash=${e}`)}async function Rs(e=24){return Fs(`/api/noise_floor_history?hours=${e}`)}const zs=new Map;function Ps(e=!1){if(e)zs.clear();else for(const[t]of zs)parseInt(t.split("-")[0],10)<=60&&zs.delete(t)}function Is(e,t,a,n){const r=60*e/t,s=Math.floor(Date.now()/1e3),o=Math.floor(s/r)*r,i=o-60*e,l=a.filter(e=>e.timestamp>=i&&e.timestamp<=o),c=n?function(e){var t;const a=null==(t=null==e?void 0:e.config)?void 0:t.radio;return{spreadingFactor:(null==a?void 0:a.spreading_factor)??Bs.spreadingFactor,bandwidthHz:(null==a?void 0:a.bandwidth)??Bs.bandwidthHz,codingRate:(null==a?void 0:a.coding_rate)??Bs.codingRate,preambleLength:(null==a?void 0:a.preamble_length)??Bs.preambleLength,crcEnabled:!0,explicitHeader:!0}}(n):Bs,d=function(e,t,a,n,r){const s=new Array(t),o=new Array(t),i=new Array(t),l=new Array(t),c=new Array(t),d=new Array(t),u=new Array(t);for(let m=0;m=t)continue;const p=Ms(h,r),f=h.packet_origin;if("tx_local"===f?(i[g].count++,i[g].airtime_ms+=p):"tx_forward"===f||h.transmitted?(l[g].count++,l[g].airtime_ms+=p):h.drop_reason&&(c[g].count++,c[g].airtime_ms+=p),"tx_local"!==f){s[g].count++,s[g].airtime_ms+=p,d[g].snr+=h.snr||0,d[g].rssi+=h.rssi||0,d[g].count++;const e=h.packet_hash;e&&!u[g].has(e)&&(u[g].add(e),o[g].count++,o[g].airtime_ms+=p)}}for(let m=0;m0&&(s[m].avg_snr=d[m].snr/d[m].count,s[m].avg_rssi=d[m].rssi/d[m].count);return{received:s,unique_received:o,transmitted:i,forwarded:l,dropped:c}}(l,t,i,r,c);return{time_range_minutes:e,bucket_count:t,bucket_duration_seconds:r,start_time:i,end_time:o,...d}}async function $s(e=24){try{return await Fs(`/api/crc_count?hours=${e}`)}catch{return{success:!1,error:"Not available"}}}let qs=1;async function Os(){var e,t;const a=await Fs("/api/hardware_stats");return a.success&&(null==(t=null==(e=a.data)?void 0:e.cpu)?void 0:t.count)&&(qs=a.data.cpu.count),a}async function Hs(){var e;const t=await Fs("/api/hardware_processes");if(t.success&&(null==(e=t.data)?void 0:e.processes)&&qs>1)for(const a of t.data.processes)a.cpu_percent=a.cpu_percent/qs;return t}async function Ws(e){const t={...e};return null!=e.frequency_mhz&&(t.frequency=Math.round(1e6*e.frequency_mhz),delete t.frequency_mhz),null!=e.bandwidth_khz&&(t.bandwidth=Math.round(1e3*e.bandwidth_khz),delete t.bandwidth_khz),Fs("/api/update_radio_config",{method:"POST",body:JSON.stringify(t)})}async function Us(){return Fs("/api/send_advert",{method:"POST",body:"{}"})}async function Vs(e){return Fs("/api/set_mode",{method:"POST",body:JSON.stringify({mode:e})})}async function Gs(e){return Fs("/api/set_duty_cycle",{method:"POST",body:JSON.stringify({enabled:e})})}async function Js(e){try{return await Fs("/api/log_level",{method:"POST",body:JSON.stringify({level:e})})}catch(t){return{success:!1,error:t instanceof Error?t.message:"Unknown error"}}}async function Ks(){return Fs("/api/identities")}async function Xs(){return Fs("/api/acl_info")}async function Ys(e){const t=(new URLSearchParams).toString();return Fs("/api/acl_clients"+(t?"?"+t:""))}async function Qs(e){return Fs("/api/acl_remove_client",{method:"POST",body:JSON.stringify(e)})}async function Zs(){return Fs("/api/acl_stats")}async function eo(e){const t=(new URLSearchParams).toString();return Fs("/api/room_stats"+(t?"?"+t:""))}const to=new class{constructor(){r(this,"worker",null),r(this,"listeners",new Set),r(this,"sparklines",new Map),r(this,"isComputing",!1),r(this,"lastComputeTimeMs",0),r(this,"pendingRequest",null),r(this,"debounceTimer",null),r(this,"debounceMs",150)}ensureWorker(){if(this.worker)return!0;if("undefined"==typeof window)return!1;try{return this.worker=new Worker(new URL("/assets/sparkline.worker-CmKhBAy5.js",import.meta.url),{type:"module"}),this.worker.onmessage=e=>{this.handleWorkerMessage(e.data)},this.worker.onerror=e=>{console.error("[SparklineService] Worker error:",e),this.isComputing=!1,this.notifyListeners()},!0}catch(e){return console.error("[SparklineService] Failed to initialize worker:",e),!1}}handleWorkerMessage(e){if(this.isComputing=!1,"error"===e.type)return console.error("[SparklineService] Worker computation error:",e.error),void this.notifyListeners();if(this.sparklines=new Map(e.payload.sparklineEntries),this.lastComputeTimeMs=e.computeTimeMs,pn.active&&pn.emit("worker:sparkline:done",{ms:e.computeTimeMs,nodes:this.sparklines.size}),this.notifyListeners(),this.pendingRequest){const e=this.pendingRequest;this.pendingRequest=null,this.computeInternal(e.packets,e.nodeHashes)}}computeInternal(e,t){if(!this.ensureWorker())return void console.warn("[SparklineService] Worker not available");if(0===t.length)return this.isComputing=!1,void this.notifyListeners();this.isComputing=!0,pn.active&&pn.emit("worker:sparkline:start",{nodes:t.length,packets:e.length}),this.notifyListeners();const a={type:"compute",payload:{packets:e,nodeHashes:t}};this.worker.postMessage(a)}notifyListeners(){for(const t of this.listeners)try{t(this.sparklines,this.isComputing)}catch(e){console.error("[SparklineService] Listener error:",e)}}compute(e,t){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.isComputing?this.pendingRequest={packets:e,nodeHashes:t}:this.computeInternal(e,t)},this.debounceMs)}getSparkline(e){return this.sparklines.get(e)??[]}getAllSparklines(){return this.sparklines}hasSparkline(e){return this.sparklines.has(e)}isWorking(){return this.isComputing}getLastComputeTime(){return this.lastComputeTimeMs}subscribe(e){return this.listeners.add(e),e(this.sparklines,this.isComputing),()=>{this.listeners.delete(e)}}clear(){this.sparklines.clear(),this.notifyListeners()}terminate(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.worker&&(this.worker.terminate(),this.worker=null),this.listeners.clear()}},ao=F(e=>({connectionState:"disconnected",isSupported:!0,reconnectAttempt:0,lastConnected:null,initialize:()=>{fn.onConnectionChange((t,a)=>{e(e=>({connectionState:t,reconnectAttempt:a??0,isSupported:fn.isSupported(),lastConnected:"connected"===t?Date.now():e.lastConnected}))}),fn.connect()}})),no=.05,ro=1e3,so="terrarium";function oo(e,t,a){try{return e.queryTerrainElevation({lng:t,lat:a})??0}catch{return 0}}const io=F((e,t)=>({terrainGrid:null,isLoading:!1,error:null,lastLoadedAt:null,cachedBounds:null,terrainDisambiguationEnabled:!0,loadTerrain:async(a,n)=>{const r=t();if(!(r.isLoading||(s=r.cachedBounds,o=a,s&&s.minLat<=o.minLat&&s.maxLat>=o.maxLat&&s.minLng<=o.minLng&&s.maxLng>=o.maxLng))){var s,o;e({isLoading:!0,error:null});try{n.getTerrain()||(n.getSource(so)||(n.addSource(so,{type:"raster-dem",tiles:["https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"],encoding:"terrarium",tileSize:256}),await new Promise((e,t)=>{const a=setTimeout(()=>t(new Error("Terrain source load timeout")),1e4),r=t=>{t.sourceId===so&&t.isSourceLoaded&&(clearTimeout(a),n.off("sourcedata",r),e())};n.on("sourcedata",r)})),n.setTerrain({source:so}),await new Promise(e=>setTimeout(e,500)));const t=await async function(e,t){const{minLat:a,maxLat:n,minLng:r,maxLng:s}=t;let o=Math.ceil((s-r)/.001),i=Math.ceil((n-a)/.001);o>ro&&(o=ro),i>ro&&(i=ro);const l=(s-r)/o,c=(n-a)/i,d=Math.max(l,c),u=new Float32Array(o*i);let h=0;for(let m=0;msetTimeout(e,0))}}return{origin:[a,r],cellSize:d,width:o,height:i,elevations:u}}(n,a);e({terrainGrid:t,isLoading:!1,lastLoadedAt:Date.now(),cachedBounds:a})}catch(i){const t=i instanceof Error?i.message:"Unknown error loading terrain";console.error("[TerrainStore] Load error:",t),e({isLoading:!1,error:t})}}},preloadFromNodes:async(e,a)=>{const n=function(e){const t=e.filter(e=>void 0!==e.latitude&&void 0!==e.longitude&&(0!==e.latitude||0!==e.longitude));if(0===t.length)return null;let a=1/0,n=-1/0,r=1/0,s=-1/0;for(const o of t)a=Math.min(a,o.latitude),n=Math.max(n,o.latitude),r=Math.min(r,o.longitude),s=Math.max(s,o.longitude);return{minLat:a-no,maxLat:n+no,minLng:r-no,maxLng:s+no}}(e);n&&await t().loadTerrain(n,a)},clearTerrain:()=>{e({terrainGrid:null,cachedBounds:null,lastLoadedAt:null,error:null})},setTerrainDisambiguationEnabled:t=>{e({terrainDisambiguationEnabled:t})},getTerrainGridForDisambiguation:()=>{const e=t();return e.terrainDisambiguationEnabled?e.terrainGrid:null}})),lo="pymc-stealth-location";function co(e){if("undefined"!=typeof window)try{localStorage.setItem(lo,JSON.stringify(e))}catch{}}function uo(e){return!isNaN(e)&&e>=-90&&e<=90}function ho(e){return!isNaN(e)&&e>=-180&&e<=180}const mo=function(){if("undefined"==typeof window)return{};try{const e=localStorage.getItem(lo);if(!e)return{};const t=JSON.parse(e);if("number"==typeof t.latitude&&"number"==typeof t.longitude&&"boolean"==typeof t.enabled&&uo(t.latitude)&&ho(t.longitude))return t}catch{}return{}}(),go=F((e,t)=>({latitude:mo.latitude??null,longitude:mo.longitude??null,enabled:mo.enabled??!1,setLocation:(a,n)=>{uo(a)&&ho(n)?(e({latitude:a,longitude:n}),co({latitude:a,longitude:n,enabled:t().enabled})):console.warn("[StealthStore] Invalid coordinates:",a,n)},enable:()=>{const{latitude:a,longitude:n}=t();null!==a&&null!==n?(e({enabled:!0}),co({latitude:a,longitude:n,enabled:!0})):console.warn("[StealthStore] Cannot enable without coordinates")},disable:()=>{e({enabled:!1});const{latitude:a,longitude:n}=t();null!==a&&null!==n&&co({latitude:a,longitude:n,enabled:!1})},clear:()=>{e({latitude:null,longitude:null,enabled:!1}),function(){if("undefined"!=typeof window)try{localStorage.removeItem(lo)}catch{}}()},getEffectiveLocation:()=>{const{latitude:e,longitude:a,enabled:n}=t();return n&&null!==e&&null!==a?{latitude:e,longitude:a}:null},isActive:()=>{const{latitude:e,longitude:a,enabled:n}=t();return n&&null!==e&&null!==a}})),po=class e{constructor(){r(this,"worker",null),r(this,"isReady",!1),r(this,"restartCount",0),r(this,"pendingRequests",[]),r(this,"currentRequest",null),this.initWorker()}initWorker(){if("undefined"!=typeof window)try{this.worker=new Worker(new URL("/assets/decryption.worker-CsyRC9O1.js",import.meta.url),{type:"module"}),this.worker.onmessage=this.handleMessage.bind(this),this.worker.onerror=e=>{console.error("[DecryptionService] Worker error:",e),this.currentRequest&&(this.currentRequest.onBatchComplete(0,0,0),this.currentRequest=null),this.restartWorker()}}catch(e){console.error("[DecryptionService] Failed to initialize worker:",e)}}restartWorker(){this.restartCount>=e.MAX_RESTARTS?console.warn("[DecryptionService] Max restarts reached, not restarting"):(this.restartCount++,console.warn(`[DecryptionService] Restarting worker (attempt ${this.restartCount})`),this.worker&&(this.worker.terminate(),this.worker=null),this.isReady=!1,this.initWorker())}handleMessage(e){var t,a,n,r;const s=e.data;switch(s.type){case"ready":this.isReady=!0,this.processNextRequest();break;case"progress":(null==(t=this.currentRequest)?void 0:t.onProgress)&&this.currentRequest.onProgress(s.processed,s.total);break;case"result":(null==(a=this.currentRequest)?void 0:a.onResult)&&this.currentRequest.onResult(s.result);break;case"results":if(null==(n=this.currentRequest)?void 0:n.onResults)this.currentRequest.onResults(s.results);else if(null==(r=this.currentRequest)?void 0:r.onResult)for(const e of s.results)this.currentRequest.onResult(e);break;case"batchComplete":pn.active&&pn.emit("worker:decryption:batch",{success:s.successCount,total:s.totalCount,ms:s.computeTimeMs}),this.currentRequest&&(this.currentRequest.onBatchComplete(s.successCount,s.totalCount,s.computeTimeMs),this.currentRequest=null),this.processNextRequest();break;case"error":console.error("[DecryptionService] Worker error:",s.error),this.currentRequest&&(this.currentRequest.onBatchComplete(0,0,0),this.currentRequest=null),this.processNextRequest()}}processNextRequest(){if(!this.isReady||!this.worker||this.currentRequest)return;const e=this.pendingRequests.shift();if(!e)return;this.currentRequest={onProgress:e.onProgress,onResult:e.onResult,onResults:e.onResults,onBatchComplete:e.onBatchComplete};const t={type:"decrypt",packets:e.packets,knownKey:e.knownKey};this.worker.postMessage(t)}decrypt(e,t){return new Promise(a=>{const n=e.map(e=>({packet_hash:e.packet_hash,raw_packet:e.raw_packet||"",timestamp:e.timestamp??0,rssi:e.rssi,snr:e.snr,type:e.type,payload_type:e.payload_type}));this.pendingRequests.push({packets:n,knownKey:null==t?void 0:t.knownKey,onProgress:null==t?void 0:t.onProgress,onResults:null==t?void 0:t.onResults,onResult:null==t?void 0:t.onResult,onBatchComplete:(e,t,n)=>{a({successCount:e,totalCount:t,computeTimeMs:n})}}),this.processNextRequest()})}isServiceReady(){return this.isReady}isProcessing(){return null!==this.currentRequest}getPendingCount(){return this.pendingRequests.length}pause(){if(this.worker){const e={type:"pause"};this.worker.postMessage(e)}}resume(){if(this.worker){const e={type:"resume"};this.worker.postMessage(e)}}terminate(){if(this.worker){const e={type:"stop"};this.worker.postMessage(e),this.worker.terminate(),this.worker=null}this.isReady=!1,this.pendingRequests=[],this.currentRequest=null}};r(po,"MAX_RESTARTS",1);const fo=new po;function bo(e){const t=e.replace(/^0x/i,"").replace(/\s/g,"");if(t.length%2!=0)throw new Error("Invalid hex string: odd number of characters");const a=new Uint8Array(t.length/2);for(let n=0;ne.toString(16).padStart(2,"0")).join("");return t&&(n=n.toUpperCase()),a&&(n="0x"+n),n}function wo(e,t=!0){const a=(255&e).toString(16).padStart(2,"0");return t?a.toUpperCase():a}function Co(e,t,a,n){if(e+t>a)throw new Error(n)}function ko(e){if(e>256)throw new Error(`payload too large: ${e} > 256`)}function vo(){return"undefined"!=typeof crypto&&void 0!==crypto.subtle&&"function"==typeof crypto.subtle.digest}const Do=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Ao=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);function xo(e,t){return(e>>>t|e<<32-t)>>>0}function Eo(e,t){let a=e[0],n=e[1],r=e[2],s=e[3],o=e[4],i=e[5],l=e[6],c=e[7];for(let d=0;d<64;d++){if(d>=16){const e=xo(t[d-15&15],7)^xo(t[d-15&15],18)^t[d-15&15]>>>3,a=xo(t[d-2&15],17)^xo(t[d-2&15],19)^t[d-2&15]>>>10;t[15&d]=t[15&d]+e+t[d-7&15]+a>>>0}const e=c+(xo(o,6)^xo(o,11)^xo(o,25))+(o&i^~o&l)+Do[d]+t[15&d]>>>0,u=a&n^a&r^n&r;c=l,l=i,i=o,o=s+e>>>0,s=r,r=n,n=a,a=e+((xo(a,2)^xo(a,13)^xo(a,22))+u>>>0)>>>0}e[0]=e[0]+a>>>0,e[1]=e[1]+n>>>0,e[2]=e[2]+r>>>0,e[3]=e[3]+s>>>0,e[4]=e[4]+o>>>0,e[5]=e[5]+i>>>0,e[6]=e[6]+l>>>0,e[7]=e[7]+c>>>0}function Fo(e){const t=new Uint32Array(Ao),a=new Uint32Array(16),n=8*e.length,r=e.length+9+63&-64,s=new Uint8Array(r);s.set(e),s[e.length]=128;const o=new DataView(s.buffer);o.setUint32(r-4,n,!1);for(let c=0;c>=1}return a}function Lo(e){let t=e[13];e[13]=e[9],e[9]=e[5],e[5]=e[1],e[1]=t,t=e[2],e[2]=e[10],e[10]=t,t=e[6],e[6]=e[14],e[14]=t,t=e[3],e[3]=e[7],e[7]=e[11],e[11]=e[15],e[15]=t}function To(e){for(let t=0;t<16;t++)e[t]=So[e[t]]}function _o(e,t){for(let a=0;a<16;a++)e[a]^=t[a]}function Ro(e){for(let t=0;t<4;t++){const a=4*t,n=e[a],r=e[a+1],s=e[a+2],o=e[a+3];e[a]=No(14,n)^No(11,r)^No(13,s)^No(9,o),e[a+1]=No(9,n)^No(14,r)^No(11,s)^No(13,o),e[a+2]=No(13,n)^No(9,r)^No(14,s)^No(11,o),e[a+3]=No(11,n)^No(13,r)^No(9,s)^No(14,o)}}function zo(e,t){const a=new Uint8Array(e);_o(a,t[10]);for(let n=9;n>=1;n--)Lo(a),To(a),_o(a,t[n]),Ro(a);return Lo(a),To(a),_o(a,t[0]),a}function Po(e,t){const a=function(e){const t=[],a=new Uint8Array(176);a.set(e.slice(0,16));for(let n=16;n<176;n+=4){let e=a[n-4],t=a[n-3],r=a[n-2],s=a[n-1];if(n%16==0){const a=e;e=jo[t]^Mo[n/16-1],t=jo[r],r=jo[s],s=jo[a]}a[n]=a[n-16]^e,a[n+1]=a[n-15]^t,a[n+2]=a[n-14]^r,a[n+3]=a[n-13]^s}for(let n=0;n<11;n++)t.push(a.slice(16*n,16*(n+1)));return t}(e),n=new Uint8Array(t.length);for(let r=0;r>>0}function Oo(e,t){return e[t]|e[t+1]<<8}function Ho(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0}function Wo(e,t,a){t[a]=255&e,t[a+1]=e>>8&255}function Uo(e){return(e instanceof Uint8Array?Array.from(e):e).map(e=>wo(e,!0)).join("->")}const Vo={name:"Public",secret:"8b3387e9c5cdea6ac9e5edbaa115cd72"},Go=["southbay","south-bay","bot","ventura","weather","wardrive","test","icewatch","sbcountymesh","sb-county-mesh","sbcounty","sb-county","meshbud","mesh-bud","ai-bot","aibot","hdmesh","hd-mesh","hdme","hdme7","hdme7yard","hdmeyard","hdmeshtayrd","hdmestayrd","hdmestyard","hdmetayrd","hdmeshtnyard","mustard","socalmesh","socal-mesh","meshla","mesh-la","lamesh","la-mesh","westcoast","west-coast","wcmesh","wc-mesh","eastcoast","east-coast","midwest","southwest","northwest","northeast","southeast","california","cali","santaclarita","santa-clarita","scv","newhall","valencia","saugus","castaic","palmdale","lancaster","antelopevalley","antelope-valley","avmesh","av-mesh","highdesert","high-desert","mojave","victorville","hesperia","barstow","pomona","claremont","glendora","azusa","covina","westcovina","west-covina","walnut","diamondbar","diamond-bar","whittier","brea","yorbalinda","yorba-linda","montebello","montereypark","monterey-park","alhambra","arcadia","monrovia","duarte","hermosabeach","hermosa-beach","manhattanbeach","manhattan-beach","redondobeach","redondo-beach","palosverdes","palos-verdes","sanpedro","san-pedro","ojai","fillmore","santapaula","santa-paula","porthueneme","port-hueneme","general","public","main","default","chat","local","mesh","network","emergency","sos","help","news","info","status","alerts","announce","random","offtopic","off-topic","lobby","lounge","hangout","testing","dev","development","beta","alpha","experimental","personaltest","personal-test","mytest","my-test","testchannel","test-channel","meshcore","mesh-core","meshtastic","lora","lo-ra","lorawan","lora-wan","radio","ham","amateur","hamradio","ham-radio","amateurradio","repeater","repeaters","gateway","node","nodes","rf","rfmesh","offgrid","off-grid","prepper","preppers","emcomm","ares","races","socal","so-cal","southerncalifornia","southern-california","losangeles","los-angeles","la","laarea","la-area","greaterla","sfv","sfvalley","sf-valley","sanfernandovalley","san-fernando-valley","sanfernando","san-fernando","valley","thevalley","the-valley","westla","west-la","eastla","east-la","southla","south-la","dtla","downtown","downtownla","downtown-la","hollywood","beverlyhills","beverly-hills","santamonica","santa-monica","culvercity","culver-city","marinadelrey","marina-del-rey","longbeach","long-beach","torrance","carson","compton","inglewood","pasadena","glendale","burbank","noho","northhollywood","north-hollywood","encino","tarzana","woodland","woodlandhills","woodland-hills","calabasas","malibu","topanga","agoura","agourahills","agoura-hills","thousandoaks","thousand-oaks","simivalley","simi-valley","simi","venturacounty","ventura-county","oxnard","camarillo","moorpark","santabarbara","santa-barbara","sb","goleta","carpinteria","orangecounty","orange-county","oc","irvine","anaheim","fullerton","costamesa","costa-mesa","newportbeach","newport-beach","huntingtonbeach","inlandempire","inland-empire","ie","riverside","sanbernardino","san-bernardino","ontario","rancho","ranchocucamonga","rancho-cucamonga","fontana","corona","palmsprings","palm-springs","palmdesert","palm-desert","coachella","temecula","murrieta","hemet","perris","menifee","sandiego","san-diego","sd","sdmesh","sd-mesh","norcal","nor-cal","northerncalifornia","northern-california","bayarea","bay-area","sfbay","sf-bay","sfbayarea","sf-bay-area","sanfrancisco","san-francisco","sf","sfmesh","sf-mesh","oakland","berkeley","eastbay","east-bay","alameda","sanjose","san-jose","sj","southbay","south-bay","siliconvalley","silicon-valley","santaclara","santa-clara","sunnyvale","mountainview","mountain-view","paloalto","palo-alto","menlopark","menlo-park","redwoodcity","redwood-city","fremont","hayward","unioncity","union-city","newark","milpitas","santacruz","santa-cruz","watsonville","monterey","montereybay","monterey-bay","salinas","carmel","pacificgrove","pacific-grove","sacramento","sac","sactown","westsac","west-sac","roseville","folsom","fresno","bakersfield","stockton","modesto","visalia","seattle","seattlemesh","seattle-mesh","pnw","pacificnorthwest","pacific-northwest","portland","pdx","portlandmesh","portland-mesh","oregon","denver","denvermesh","denver-mesh","colorado","boulder","fortcollins","austin","austinmesh","austin-mesh","atx","texas","sanantonio","san-antonio","dallas","dfw","dallasmesh","dallas-mesh","fortworth","fort-worth","houston","houstonmesh","houston-mesh","htx","phoenix","phoenixmesh","phoenix-mesh","arizona","az","tucson","mesa","tempe","lasvegas","las-vegas","vegas","vegasmesh","vegas-mesh","nevada","henderson","saltlake","salt-lake","slc","saltlakecity","salt-lake-city","utah","chicago","chicagomesh","chicago-mesh","chitown","illinois","detroit","detroitmesh","detroit-mesh","michigan","annarbor","ann-arbor","minneapolis","twincities","twin-cities","minnesota","stpaul","st-paul","atlanta","atlantamesh","atlanta-mesh","atl","georgia","miami","miamimesh","miami-mesh","florida","tampa","orlando","jacksonville","boston","bostonmesh","boston-mesh","massachusetts","cambridge","newyork","new-york","nyc","nycmesh","nyc-mesh","brooklyn","manhattan","queens","newjersey","new-jersey","nj","jersey","philly","philadelphia","philadelphiamesh","philadelphia-mesh","pennsylvania","dc","washingtondc","washington-dc","dmv","nova","maryland","virginia","raleigh","durham","rdu","triangle","northcarolina","north-carolina","charlotte","clt","southcarolina","south-carolina","nashville","tennessee","memphis","knoxville","neworleans","new-orleans","nola","louisiana","hawaii","oahu","honolulu","maui","bigisland","big-island","alaska","anchorage","fairbanks","canada","toronto","vancouver","montreal","calgary","edmonton","ottawa","uk","london","manchester","birmingham","edinburgh","glasgow","bristol","germany","berlin","munich","hamburg","frankfurt","cologne","france","paris","lyon","marseille","spain","madrid","barcelona","italy","rome","milan","netherlands","amsterdam","rotterdam","brabant","flevoland","gelderland","noordbrabant","noordholland","zuid-holland","zuidholland","zeeland","twente","alkmaar","almere","amstelland","capelleaandenijssel","denhaag","dordrecht","drechtsteden","eindhoven","haarlem","hellevoetsluis","hilversum","katwijk","lelystad","maassluis","middelburg","rijnmond","tilburg","utrecht","vlissingen","voorburg","voorne-putten","walcheren","west-friesland","zaandam","zaanstreek-waterland","024-bot","afrithonbot","ai","amradio","analyser","angrynerds","bemesh","buch","burgernet","chatgpt","dares","dekroeg","dtis","english","evenvroegopstaan","fosdem","gezellig","gmr","gmrbot","goedemorgen","gyverbot","haagscourant","hackerspacenijmegen","hamradionederland","hetweerinjegemeente","hsnl","jokes","kanalen","koffie","linux","nerd","nl-alert","nl-prio","noodkanaal","nsagov","pi4hm","pi4utr","pingbot","sensemakers","sports","survival","uitdagingen","valleibot","valleirug","vleesboek","wardrive","weer","australia","sydney","melbourne","brisbane","perth","adelaide","newzealand","new-zealand","auckland","wellington","japan","tokyo","osaka","kyoto","southkorea","south-korea","korea","seoul","taiwan","taipei","singapore","hongkong","hong-kong","india","mumbai","delhi","bangalore","brazil","saopaulo","sao-paulo","rio","mexico","mexicocity","mexico-city","guadalajara","tijuana","gps","location","tracking","tracker","position","coordinates","sensor","sensors","telemetry","data","iot","aprs","beacon","beacons","ping","pings","debug","admin","ops","operations","monitor","monitoring","security","secure","private","encrypted","hiking","camping","outdoors","outdoor","backcountry","trails","offroad","off-road","overlanding","jeep","offroading","sailing","boating","marine","maritime","aviation","flying","pilots","drone","drones","weather","wx","storm","storms","skywarn","traffic","commute","transit","community","group","team","club","family","friends","neighbors","neighborhood","block","street","local","town","city","county","region","north","south","east","west","central","downtown","uptown","midtown","home","house","cabin","ranch","farm","test1","test2","test3","test4","test5","channel1","channel2","channel3","mesh1","mesh2","mesh3","group1","group2","group3","team1","team2","team3","net1","net2","net3","relay","relays","link","links","hub","hubs","core","backbone","qso","ragchew","net","nets","roundtable","simplex","duplex","vhf","uhf","hf","2m","70cm","33cm","23cm","900mhz","915mhz","ism","ism-band","ism915","ism868","license-free","event","events","exercise","drill","training","practice","race","marathon","cycling","running","triathlon","ironman","festival","concert","gathering","meetup","meet-up","convention","hamfest","ham-fest","field-day","fieldday","winter-field-day","sota","pota","summits","parks","parks-on-the-air","2024","2025","2026","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec","winter","spring","summer","fall","autumn","mountain","mountains","hills","peak","summit","ridge","canyon","beach","coast","coastal","shore","bay","lake","river","creek","park","forest","woods","desert","island","peninsula","urban","suburban","rural","metro","area","zone","sector","base","mobile","portable","handheld","fixed","station","primary","secondary","backup","alternate","spare","alpha","bravo","charlie","delta","echo","foxtrot","red","blue","green","yellow","orange","purple","black","white","trace","traces","log","logs","metrics","stats","statistics","raw","stream","feed","live","realtime","real-time","sync","replication","mirror","copy","archive","open","closed","free","premium","pro","plus","lite","basic","new","old","legacy","current","next","future","one","two","three","four","five","six","seven","eight","nine","ten","hamradio","ham-radio","amateurradio","amateur-radio","arrl","dxcc","dxing","morsecode","morse-code","fldigi","js8call","winlink","vara","pactor","packet","ax25","aprsmesh","qrp","qro","qrz","qsl","qth","ragchew","rag-chew","elmer","elmers","technician","amateur","microwave","satellite","ariss","amsat","cubesat","sdr","rtlsdr","rtl-sdr","hackrf","portapack","yaesu","icom","kenwood","elecraft","flexradio","alinco","baofeng","quansheng","antennas","dipole","vertical","yagi","efhw","endfed","wwff","iota","contesting","cwops","auxcomm","satern","maker","makers","makerspace","maker-space","hackerspace","hacker-space","fablab","fab-lab","doityourself","homebrew","home-brew","fromscratch","arduino","esp32","esp8266","stm32","teensy","pico","rp2040","attiny","raspberrypi","raspberry-pi","rpi","beaglebone","beagle-bone","orangepi","orange-pi","kicad","eagle","altium","oshpark","jlcpcb","pcbway","soldering","throughhole","oscilloscope","multimeter","logicanalyzer","logic-analyzer","testbench","3dprinting","3d-printing","3dprint","printer","prusa","ender","creality","bambu","voron","lasercutter","laser-cutter","woodworking","metalworking","welding","resin","fdm","sla","fusion360","fusion-360","freecad","openscad","solidworks","programming","coding","software","developer","developers","devops","sysadmin","linux","unix","bsd","freebsd","openbsd","netbsd","macos","windows","android","ios","python","javascript","typescript","rust","golang","java","kotlin","swift","ruby","perl","csharp","dotnet","haskell","lisp","clojure","elixir","erlang","react","angular","svelte","nodejs","deno","nextjs","nuxt","docker","kubernetes","terraform","ansible","puppet","vagrant","github","gitlab","bitbucket","opensource","open-source","foss","floss","homelab","home-lab","selfhost","self-host","selfhosted","self-hosted","homelabbers","homeassistant","home-assistant","hass","openhab","domoticz","nodered","node-red","mqtt","zigbee","zwave","thread","wifi","bluetooth","rfid","infosec","cybersec","cybersecurity","cyber-security","netsec","opsec","hacking","hacker","hackers","pentest","pentesting","redteam","red-team","blueteam","blue-team","capture-the-flag","bugbounty","bug-bounty","vuln","exploit","malware","reverse","defcon","blackhat","bsides","shmoocon","derbycon","toorcon","hacktheplanet","lockpicking","locksport","toool","deviant","socialeng","social-eng","osint","privacy","anonymity","encryption","crypto","signal","hiking","hiker","hikers","backpacking","backpacker","thru-hike","thruhike","camper","campers","glamping","dispersed","primitive","wilderness","climbing","climber","climbers","rockclimbing","rock-climbing","bouldering","trad","sport","mountaineering","alpine","peaks","fourteeners","14ers","highpoints","skiing","skier","snowboard","snowboarder","backcountry-ski","touring","splitboard","kayak","kayaking","kayaker","canoe","canoeing","paddle","paddling","paddleboard","surfing","surfer","surfers","bodyboard","longboard","shortboard","waves","scuba","freedive","freediving","snorkel","underwater","spearfishing","fishing","angler","anglers","flyfishing","fly-fishing","trout","hunting","hunter","hunters","archery","bowhunting","bow-hunting","rifle","shotgun","cyclist","biking","bicycle","bicycling","roadbike","road-bike","mountainbike","mountain-bike","mountainbiking","mountain-biking","trailriding","ebike","e-bike","ebikes","electric-bike","peloton","strava","zwift","gravel","gravelbike","gravel-bike","bikepacking","bike-packing","randonneur","fixie","fixedgear","fixed-gear","singlespeed","single-speed","commuter","offroading","off-roading","fourwheeling","4wd","awd","jeeping","wrangler","gladiator","tacoma","runner","4runner","overland","overlander","rooftoptent","rooftop-tent","expedition","utv","sxs","sidebyside","side-by-side","rzr","canam","polaris","dirtbike","dirt-bike","motocross","enduro","dualsport","dual-sport","motorcycle","moto","harley","sportbike","cruiser","rving","motorhome","campervan","camper-van","vanlife","van-life","skoolie","trucker","trucking","diesel","semi","bigrig","big-rig","pilot","pilots","flying","flight","airplane","aircraft","planes","cessna","piper","cirrus","beechcraft","mooney","bonanza","skyhawk","helicopter","heli","rotor","rotorcraft","chopper","robinson","glider","gliding","soaring","sailplane","paraglider","paragliding","hangglider","drones","uav","uas","fpv","quadcopter","multirotor","mavic","phantom","rocketry","rockets","hpr","nar","tripoli","model-rocket","amateur-rocket","spacex","nasa","esa","starlink","starship","falcon","artemis","boat","boats","boater","boaters","yachting","yacht","sail","sailor","powerboat","speedboat","fishing-boat","pontoon","jetski","jet-ski","pwc","waverunner","marina","harbor","harbour","dock","pier","anchorage","mooring","liveaboard","cruising","bluewater","blue-water","inshore","intracoastal","marine-radio","marineradio","ais","chartplotter","navionics","opencpn","prepper","preppers","prepping","survival","survivalist","shtf","teotwawki","bol","bugout","bug-out","bugin","bug-in","edc","everyday-carry","loadout","firstaid","first-aid","trauma","tccc","stopthebleed","aed","waterpurification","water-purification","berkey","sawyer","lifestraw","foodstorage","food-storage","canning","dehydrating","freezedried","freeze-dried","battery","generator","inverter","offgrid","off-grid","griddown","grid-down","communications","gmrs","frs","murs","citizens-band","shortwave","homestead","homesteading","homesteader","farming","farmer","farmers","ranching","garden","gardening","gardener","permaculture","organic","regenerative","sustainable","chickens","poultry","goats","sheep","cattle","pigs","livestock","beekeeping","bees","apiary","greenhouse","hydroponics","aquaponics","vertical-farm","indoor-garden","growroom","grow-room","meteorology","stormchasing","storm-chasing","tornado","hurricane","earthquake","quake","seismic","tsunami","volcano","volcanic","geology","geologist","astronomy","stargazing","telescope","astrophotography","astrophoto","deepsky","deep-sky","citizen-science","citizenscience","research","science","stem","education","learning","gaming","gamer","gamers","videogames","video-games","pcgaming","pc-gaming","console","esports","e-sports","competitive","tournament","lan-party","retrogaming","minecraft","terraria","valheim","rust-game","dayz","tarkov","pubg","fortnite","apex","virtualreality","virtual-reality","augmentedreality","augmented-reality","oculus","tabletop","boardgames","board-games","dungeons-dragons","ttrpg","pathfinder","musician","musicians","bands","livemusic","live-music","concerts","guitar","guitarist","bassist","drums","drummer","keyboard","synth","synthesizer","production","producer","producers","beatmaking","beat-making","ableton","flstudio","audiophile","hifi","hi-fi","vinyl","records","turntable","headphones","speakers","podcast","podcasting","podcaster","streaming","streamer","twitch","youtube","content","photography","photographer","photographers","photog","cameras","dslr","mirrorless","canon","nikon","fuji","fujifilm","panasonic","olympus","leica","hasselblad","portrait","wildlife","macro","nightsky","night-sky","timelapse","videography","videographer","filmmaker","filmmaking","cinematography","editing","premiere","davinci","finalcut","final-cut","aftereffects","after-effects","vfx","artist","artists","artwork","creative","creatives","designer","designers","illustration","illustrator","drawing","sketch","sketching","digital-art","digitalart","graphicdesign","graphic-design","uiux","ui-ux","webdesign","web-design","animation","animator","motion","motiongraphics","motion-graphics","3dart","3d-art","blender","foodie","foodies","cooking","cooks","chef","chefs","culinary","kitchen","barbecue","grilling","smoking","smoker","brisket","ribs","pulled-pork","lownslow","baking","baker","sourdough","pastry","dessert","cakes","cookies","brewing","craft-beer","craftbeer","ipa","lager","stout","espresso","barista","roasting","whiskey","bourbon","cocktails","fitness","workout","lifting","weightlifting","powerlifting","bodybuilding","crossfit","hiit","cardio","runners","ultramarathon","triathlete","swimming","swimmer","openwater","open-water","yoga","pilates","meditation","mindfulness","wellness","nutrition","basketball","football","soccer","baseball","hockey","tennis","volleyball","dogs","puppy","puppies","canine","dogtraining","dog-training","cats","kitten","kittens","feline","meow","pets","animals","birding","birdwatching","bird-watching","aquarium","reeftank","reef-tank","saltwater","freshwater","planted-tank","reptiles","reptile","snakes","lizard","gecko","bearded-dragon","neighborhood","nextdoor","meet-up","volunteer","volunteering","nonprofit","non-profit","charity","mutual-aid","mutualaid","parents","parenting","families","children","youth","teens","seniors","lgbtq","pride","queer","nonbinary","ally","allies","inclusive","diversity","burningman","burning-man","playa","blackrock","coachella","sxsw","defcon","hope","layerone","layer-one","supercon","makerfaire","maker-faire","bamboozle","lightning","ragbrai","burnitdown","burning","regional","decomp","toorcamp","chaos","congress","hackathon","ctf-event","capture","wardriving","foxhunt","fox-hunt","brc","ttitd","center-camp","centercamp","esplanade","deep-playa","effigy","temple","soundcamp","sound-camp","mutant-vehicle","art-car","ranger","rangers","lamplighters","dgs","leave-no-trace","moop","gifting","radical-self","immediacy","participation","decommodification","overlandexpo","overland-expo","overlandtrail","overland-trail","overlandbound","overlandjournal","adventurebike","adventure-bike","dirtevery","rubicontrail","rubicon-trail","moab","deathvalley","death-valley","joshua-tree","joshuatree","bigbear","big-bear","mammoth","tahoe","yosemite","sequoia","kingscyn","kings-canyon","meshcore","mesh-core","meshcore-test","meshcore-dev","meshcore-beta","mctest","mc-test","mcdev","mc-dev","mcmain","mc-main","mcpublic","meshcorebot","meshcore-bot","mcbot","mc-bot","meshchat","mesh-chat","meshnet","mesh-net","meshnetwork","mesh-network","meshlink","mesh-link","meshhub","mesh-hub","meshnode","mesh-node","meshrelay","mesh-relay","meshgateway","mesh-gateway","meshbridge","mesh-bridge","meshrouter","meshtalk","mesh-talk","meshvoice","mesh-voice","meshdata","mesh-data","meshsensor","mesh-sensor","meshtrack","mesh-track","meshgps","mesh-gps","meshmap","mesh-map","meshstatus","mesh-status","meshping","mesh-ping","meshtest","mesh-test","meshtesting","mesh-testing","meshdev","mesh-dev","meshops","mesh-ops","meshadmin","mesh-admin","meshmon","mesh-mon","meshlog","mesh-log","meshdebug","mesh-debug","meshdiag","mesh-diag","meshcore-alpha","meshcore-stable","meshcore-main","meshcore-local","mc-alpha","mc-beta","mc-stable","mc-local","mc-ops","mc-admin","meshcoretest","meshcoredev","meshcorebeta","meshcorealpha","meshcoremain","meshcorelocal","meshcoreops","meshcoreadmin","meshcoremon","meshcorelog","meshcorechat","meshcorenet","meshcorelink","meshcorehub","meshcorenode","meshcorerelay","meshcoregateway","meshcorebridge","meshcorerouter","meshcoresensor","meshcoretrack","meshcoregps","meshcoremap","meshcoreping","mcnetwork","mc-network","mcchat","mc-chat","mclink","mc-link","mchub","mc-hub","mcnode","mc-node","mcrelay","mc-relay","mcgateway","mc-gateway","mcbridge","mc-bridge","mcrouter","mc-router","mcsensor","mc-sensor","mctrack","mc-track","mcgps","mc-gps","mcmap","mc-map","mcstatus","mc-status","mcping","mc-ping","mcmon","mc-mon","mclog","mc-log","mcdebug","mc-debug","mcdiag","mc-diag","meshroom","mesh-room","meshrooms","mesh-rooms","meshserver","mesh-server","meshclient","mesh-client","meshcompanion","mesh-companion","meshrepeater","mesh-repeater","meshbase","mesh-base","meshportal","mesh-portal","meshtastic","mesh-tastic","meshtastictest","meshtastic-test","meshtasticdev","meshtastic-dev","meshtasticlocal","meshtastic-local","mttest","mt-test","mtdev","mt-dev","mtlocal","mt-local","longfast","long-fast","longmod","long-mod","longslow","long-slow","shortfast","short-fast","shortslow","short-slow","medfast","med-fast","medslow","med-slow","verylongslow","very-long-slow","meshtastic-alpha","meshtastic-beta","meshtastic-main","meshtastic-stable","meshtasticbeta","meshtasticalpha","meshtasticmain","meshtasticstable","mtbeta","mt-beta","mtalpha","mt-alpha","mtmain","mt-main","mtstable","mt-stable","mtops","mt-ops","mtadmin","mt-admin","mtchat","mt-chat","mtnet","mt-net","mtlink","mt-link","mthub","mt-hub","mtnode","mt-node","mtrelay","mt-relay","longrange","long-range","shortrange","short-range","medrange","med-range","ultralong","ultra-long","ultrafast","ultra-fast","ultraslow","ultra-slow","mediumfast","medium-fast","mediumslow","medium-slow","mediummod","medium-mod","turbofast","turbo-fast","turboslow","turbo-slow","lora","lo-ra","lorawan","lora-wan","loratest","lora-test","loradev","lora-dev","loranet","lora-net","loramesh","lora-mesh","loralink","lora-link","lorahub","lora-hub","loranode","lora-node","lora915","lora-915","lora868","lora-868","lora433","lora-433","sx1262","sx1276","sx1278","semtech","chirp","chirpstack","lorabeta","lora-beta","loraalpha","lora-alpha","loramain","lora-main","lorastable","lora-stable","loraops","lora-ops","loraadmin","lora-admin","lorachat","lora-chat","lorarelay","lora-relay","loragateway","lora-gateway","lorabridge","lora-bridge","lorarouter","lora-router","loraserver","lora-server","lorasensor","lora-sensor","loratrack","lora-track","loragps","lora-gps","loramap","lora-map","lorastatus","lora-status","loraping","lora-ping","loramon","lora-mon","loralog","lora-log","loradebug","lora-debug","lora923","lora-923","lora865","lora-865","lora470","lora-470","sx1261","sx1280","sx1268","sx126x","sx127x","sx128x","llcc68","lr1110","lr1120","lr1121","stm32wl","ra01","ra02","heltec","heltec-lora","ttgo","ttgo-lora","lilygo","lilygo-lora","rak","rak-lora","rak4631","rak3172","rak811","wisblock","test","testing","test1","test2","test3","test123","testchannel","test-channel","testnet","test-net","testmesh","test-mesh","dev","devel","develop","development","devtest","dev-test","sandbox","playground","scratch","temp","temporary","tmp","debug","debugging","diag","diagnostic","diagnostics","alpha","beta","gamma","canary","nightly","unstable","stable","experiment","experimental","trial","pilot","prototype","poc","test4","test5","test6","test7","test8","test9","test10","test01","test02","test03","test-1","test-2","test-3","testA","testB","testC","test-a","test-b","test-c","testing1","testing2","testing3","testing-1","testing-2","testing-3","devnet","dev-net","devmesh","dev-mesh","devchannel","dev-channel","stagenet","stage-net","staging","stage","stagetest","stage-test","qanet","qa-net","qa","qatest","qa-test","qachannel","qa-channel","labnet","lab-net","lab","labtest","lab-test","testlab","test-lab","benchnet","bench-net","benchmark","bench","perftest","perf-test","loadtest","load-test","stresstest","stress-test","smoketest","smoke-test","unittest","unit-test","integtest","integ-test","e2etest","e2e-test","mocknet","mock-net","mock","faker","dummy","sample","example","demonet","demo-net","demo","showcase","preview","prerelease","pre-release","release","rc","release-candidate","releasecandidate","final","production","emergency","emergencies","emer","emerg","911","999","112","sos","mayday","help","rescue","distress","urgent","priority","alert","alerts","warning","warnings","alarm","alarms","safety","safe","danger","hazard","caution","critical","evacuation","evac","evacuate","shelter","shelterinplace","shelter-in-place","lockdown","allclear","all-clear","fire","fires","wildfire","wildfires","brushfire","forestfire","flood","floods","flooding","flashflood","flash-flood","quake","earthquake","aftershock","tsunami","tremor","tornado","hurricane","cyclone","typhoon","storm","severe","missing","missingperson","missing-person","amber","silveralert","medical","medic","ems","ambulance","paramedic","firstaid","first-aid","police","sheriff","lawenforcement","law-enforcement","cert","cert-team","certteam","voad","redcross","red-cross","emergencynet","emergency-net","emergencychannel","emergency-channel","emeralert","emer-alert","sosnet","sos-net","soschannel","sos-channel","maydaynet","mayday-net","maydaychannel","mayday-channel","helpnet","help-net","helpchannel","help-channel","helpline","help-line","rescuenet","rescue-net","rescuechannel","rescue-channel","rescueteam","rescue-team","disaster","disasters","disasternet","disaster-net","disasterrelief","disaster-relief","crisis","crisisnet","crisis-net","crisischannel","crisis-channel","incident","incidentnet","incident-net","incidentchannel","incident-channel","alertnet","alert-net","alertchannel","alert-channel","alertsystem","alert-system","warningnet","warning-net","warningchannel","warning-channel","safetynet","safety-net","safetychannel","safety-channel","safetycheck","safety-check","hazardnet","hazard-net","hazardchannel","hazard-channel","hazmat","haz-mat","firenet","fire-net","firechannel","fire-channel","firefighter","fire-fighter","firedept","fire-dept","firehouse","fire-house","firestation","fire-station","wildfirenet","wildfire-net","wildfirechannel","wildfire-channel","campfire","camp-fire","structurefire","structure-fire","grassfire","grass-fire","floodnet","flood-net","floodchannel","flood-channel","floodwatch","flood-watch","floodwarning","flood-warning","highwater","high-water","risingwater","rising-water","earthquakenet","earthquake-net","earthquakechannel","earthquake-channel","tornadonet","tornado-net","tornadochannel","tornado-channel","hurricanenet","hurricane-net","hurricanechannel","hurricane-channel","stormnet","storm-net","stormchannel","storm-channel","severeweather","severe-weather","medicalnet","medical-net","medicalchannel","medical-channel","traumanet","trauma-net","traumachannel","trauma-channel","traumacenter","trauma-center","hospital","hospitals","clinic","clinics","urgent-care","urgentcare","poisoncontrol","poison-control","cpr-net","cprnet","lifesaver","life-saver","searchandrescue","search-and-rescue","sar","sarnet","sar-net","sarteam","sar-team","coastguard","coast-guard","uscg","lifeguard","life-guard","beachpatrol","beach-patrol","mountainrescue","mountain-rescue","caverescue","cave-rescue","swiftwater","swift-water","k9unit","k9-unit","searchdog","search-dog","rescuedog","rescue-dog","civildefense","civil-defense","fema","dhs","oem","eoc","eocnet","eoc-net","weather","wx","wxalert","wx-alert","wxwatch","wx-watch","wxwarning","wx-warning","wxreport","wx-report","wxupdate","wx-update","forecast","conditions","climate","temperature","temp","temps","rain","rainfall","precipitation","precip","snow","snowfall","wind","winds","windy","gust","gusts","breeze","humidity","humid","dewpoint","dew-point","barometer","pressure","sunny","cloudy","overcast","fog","foggy","mist","haze","smog","heat","heatwave","heat-wave","cold","coldsnap","cold-snap","freeze","lightning","thunder","thunderstorm","tstorm","t-storm","hail","sleet","ice","icy","blackice","black-ice","frost","noaa","nws","skywarn","spotter","spotters","stormspotter","weathernet","weather-net","weatherchannel","weather-channel","wxnet","wx-net","wxchannel","wx-channel","wxstation","wx-station","forecastnet","forecast-net","forecastchannel","forecast-channel","localwx","local-wx","localweather","local-weather","dailywx","daily-wx","hourlywx","hourly-wx","weeklyforecast","weekly-forecast","rainnet","rain-net","rainchannel","rain-channel","rainalert","rain-alert","rainwatch","rain-watch","rainwarning","rain-warning","heavyrain","heavy-rain","snownet","snow-net","snowchannel","snow-channel","snowalert","snow-alert","snowwatch","snow-watch","snowwarning","snow-warning","heavysnow","heavy-snow","blizzard","blizzardwatch","blizzard-watch","blizzardwarning","blizzard-warning","windnet","wind-net","windchannel","wind-channel","windalert","wind-alert","windwatch","wind-watch","windwarning","wind-warning","highwind","high-wind","tempnet","temp-net","tempchannel","temp-channel","tempalert","temp-alert","heatnet","heat-net","heatchannel","heat-channel","heatalert","heat-alert","heatwatch","heat-watch","heatwarning","heat-warning","extremeheat","extreme-heat","coldnet","cold-net","coldchannel","cold-channel","coldalert","cold-alert","coldwatch","cold-watch","coldwarning","cold-warning","extremecold","extreme-cold","winterstorm","winter-storm","icestorm","ice-storm","freezingrain","freezing-rain","thunderstormnet","thunderstorm-net","thunderstormwatch","thunderstorm-watch","thunderstormwarning","thunderstorm-warning","severethunderstorm","severe-thunderstorm","lightningnet","lightning-net","lightningchannel","lightning-channel","lightningalert","lightning-alert","lightningwatch","lightning-watch","tornadowatch","tornado-watch","tornadowarning","tornado-warning","hurricanewatch","hurricane-watch","hurricanewarning","hurricane-warning","tropicalstorm","tropical-storm","tropicaldepression","tropical-depression","stormwatch","storm-watch","stormwarning","storm-warning","stormalert","storm-alert","skywarnnet","skywarn-net","skywarnchannel","skywarn-channel","spotternetwork","spotter-network","stormchase","storm-chase","stormchaser","storm-chaser","amateurwx","amateur-wx","citizenwx","citizen-wx","pwswx","pws-wx","weatherstation","weather-station","wxstation","wx-station","metar","taf","status","stat","stats","statistics","metrics","health","healthcheck","monitor","monitoring","mon","watch","watcher","watchdog","uptime","downtime","outage","outages","incident","incidents","report","reports","reporting","update","updates","bulletin","announce","announcement","announcements","broadcast","broadcasts","notify","notification","notifications","ping","pong","heartbeat","check","checkin","check-in","checkout","check-out","rollcall","roll-call","statusnet","status-net","statuschannel","status-channel","statusupdate","status-update","statusreport","status-report","statuscheck","status-check","statusboard","status-board","monitornet","monitor-net","monitorchannel","monitor-channel","monitoringnet","monitoring-net","monitoringchannel","monitoring-channel","watchnet","watch-net","watchchannel","watch-channel","watchlist","watch-list","healthnet","health-net","healthchannel","health-channel","healthstatus","health-status","uptimenet","uptime-net","uptimechannel","uptime-channel","uptimemonitor","uptime-monitor","outagenet","outage-net","outagechannel","outage-channel","outagereport","outage-report","incidentnet","incident-net","incidentchannel","incident-channel","incidentreport","incident-report","incidentresponse","incident-response","alertsnet","alerts-net","alertschannel","alerts-channel","updatenet","update-net","updatechannel","update-channel","updatefeed","update-feed","bulletinnet","bulletin-net","bulletinchannel","bulletin-channel","bulletinboard","bulletin-board","noticeboard","notice-board","announcenet","announce-net","announcechannel","announce-channel","broadcastnet","broadcast-net","broadcastchannel","broadcast-channel","notifynet","notify-net","notifychannel","notify-channel","pingnet","ping-net","pingchannel","ping-channel","pingtest","ping-test","heartbeatnet","heartbeat-net","heartbeatchannel","heartbeat-channel","rollcallnet","rollcall-net","rollcallchannel","rollcall-channel","checkinnet","checkin-net","checkinchannel","checkin-channel","headcount","head-count","accountability","welfare","wellbeing","well-being","ops","operations","opsnet","ops-net","opschannel","ops-channel","admin","admins","administrator","root","superuser","sudo","control","command","cmd","hq","headquarters","base","basecamp","dispatch","dispatcher","coord","coordinate","coordination","tactical","tac","tacnet","tac-net","tacchannel","tac-channel","logistics","logi","supply","supplies","resource","resources","comms","comm","communications","radio","radionet","radio-net","opsteam","ops-team","opsgroup","ops-group","opscenter","ops-center","opsroom","ops-room","opsdesk","ops-desk","opslead","ops-lead","adminnet","admin-net","adminchannel","admin-channel","adminteam","admin-team","adminops","admin-ops","admingroup","admin-group","admindesk","admin-desk","controlnet","control-net","controlchannel","control-channel","controlroom","control-room","controlcenter","control-center","commandnet","command-net","commandchannel","command-channel","commandpost","command-post","commandcenter","command-center","hqnet","hq-net","hqchannel","hq-channel","hqops","hq-ops","dispatchnet","dispatch-net","dispatchchannel","dispatch-channel","dispatchcenter","dispatch-center","dispatchdesk","dispatch-desk","coordnet","coord-net","coordchannel","coord-channel","coordteam","coord-team","coordcenter","coord-center","coordinationcenter","coordination-center","tacops","tac-ops","tacteam","tac-team","tacgroup","tac-group","taccom","tac-com","taccomms","tac-comms","tacradio","tac-radio","logisticsnet","logistics-net","logisticschannel","logistics-channel","logisticsteam","logistics-team","logisticsops","logistics-ops","supplynet","supply-net","supplychannel","supply-channel","supplychain","supply-chain","resourcenet","resource-net","resourcechannel","resource-channel","commsnet","comms-net","commschannel","comms-channel","commsteam","comms-team","commsops","comms-ops","commscheck","comms-check","commstest","comms-test","radioops","radio-ops","radioteam","radio-team","radiocheck","radio-check","netcontrol","net-control","netops","net-ops","noc","nocnet","noc-net","info","information","infochannel","info-channel","fyi","news","newsfeed","news-feed","headlines","breaking","latest","traffic","trafficreport","traffic-report","roadconditions","road-conditions","transit","bus","train","subway","metro","commute","commuter","events","calendar","schedule","agenda","upcoming","whats-on","infonet","info-net","infohub","info-hub","infodesk","info-desk","infoboard","info-board","infopoint","info-point","infoline","info-line","newsnet","news-net","newschannel","news-channel","newshub","news-hub","newsdesk","news-desk","newsroom","news-room","newsflash","news-flash","breakingnews","breaking-news","latestnews","latest-news","topnews","top-news","localnews","local-news","regionalnews","regional-news","worldnews","world-news","trafficnet","traffic-net","trafficchannel","traffic-channel","trafficupdate","traffic-update","trafficalert","traffic-alert","roadnet","road-net","roadchannel","road-channel","roadupdate","road-update","transitnet","transit-net","transitchannel","transit-channel","transitupdate","transit-update","transitalert","transit-alert","busnet","bus-net","buschannel","bus-channel","busupdate","bus-update","trainnet","train-net","trainchannel","train-channel","trainupdate","train-update","subwaynet","subway-net","subwaychannel","subway-channel","metronet","metro-net","metrochannel","metro-channel","metroupdate","metro-update","commuternet","commuter-net","commuterchannel","commuter-channel","eventsnet","events-net","eventschannel","events-channel","eventshub","events-hub","eventcalendar","event-calendar","localevents","local-events","calendarnet","calendar-net","calendarchannel","calendar-channel","schedulenet","schedule-net","schedulechannel","schedule-channel","agendanet","agenda-net","agendachannel","agenda-channel","upcomingnet","upcoming-net","upcomingchannel","upcoming-channel","location","locations","gps","position","positions","coordinates","track","tracker","tracking","trace","tracer","tracing","beacon","beacons","waypoint","waypoints","checkpoint","checkpoints","geofence","geolocation","geo","mapping","maps","navigate","navigation","locationnet","location-net","locationchannel","location-channel","locationtrack","location-track","locationshare","location-share","gpsnet","gps-net","gpschannel","gps-channel","gpstrack","gps-track","gpsshare","gps-share","gpslog","gps-log","gpsdata","gps-data","positionnet","position-net","positionchannel","position-channel","positiontrack","position-track","positionshare","position-share","coordnet","coord-net","coordchannel","coord-channel","coordshare","coord-share","tracknet","track-net","trackchannel","track-channel","trackshare","track-share","trackingnet","tracking-net","trackingchannel","tracking-channel","tracernet","tracer-net","tracerchannel","tracer-channel","beaconnet","beacon-net","beaconchannel","beacon-channel","beacontrack","beacon-track","beaconshare","beacon-share","waypointnet","waypoint-net","waypointchannel","waypoint-channel","waypointshare","waypoint-share","waypointlog","waypoint-log","checkpointnet","checkpoint-net","checkpointchannel","checkpoint-channel","geofencenet","geofence-net","geofencechannel","geofence-channel","geofencealert","geofence-alert","geozonenet","geozone-net","geonet","geo-net","geochannel","geo-channel","geotrack","geo-track","mappingnet","mapping-net","mappingchannel","mapping-channel","mapnet","map-net","mapchannel","map-channel","mapshare","map-share","navnet","nav-net","navchannel","nav-channel","navtrack","nav-track","navigationnet","navigation-net","navigationchannel","navigation-channel","fleettrack","fleet-track","fleetnet","fleet-net","assettrack","asset-track","whereis","where-is","findme","find-me","locateme","locate-me","nocap","no-cap","frfr","fr-fr","bussin","sheesh","slay","slaps","goated","goat","goats","based","cringe","mid","lowkey","highkey","vibe","vibes","vibing","vibecheck","vibe-check","goodvibes","good-vibes","sus","sussy","sussy-baka","imposter","amongus","among-us","bet","bets","yeet","yeeted","yoink","skibidi","rizz","ohio","bruh","bruv","fam","bestie","besties","squad","squadgoals","squad-goals","slayyy","periodt","purr","queen","king","icon","iconic","legend","main-character","maincharacter","npc","npcs","side-quest","sidequest","understood-the-assignment","ate","served","mother","mothering","rent-free","rentfree","living-rent-free","touch-grass","touchgrass","copium","hopium","doom","doomer","bloomer","zoomer","zoomers","ratio","ratiod","caught-in-4k","receipts","tea","spillthetea","spill-the-tea","simp","simping","stan","stanning","oomf","moots","mutuals","tiktok","fyp","foryou","for-you","foryoupage","trending","viral","cheugy","basic","pick-me","pickme","girlboss","girl-boss","iykyk","iyky","ifykyk","valid","hits-different","hitsdifferent","unhinged","chaotic","feral","unalive","delulu","delusion","bereal","be-real","dump","photodump","photo-dump","core","coded","aesthetic","cottagecore","darkacademia","dark-academia","goblinmode","goblin-mode","softlaunch","soft-launch","hardlaunch","hard-launch","ngl","tbh","ong","on-god","ongod","deadass","dead-ass","fr","real","cap","capping","no-cap-fr","nocapfr","respectfully","allegedly","understood","assignment","ate-that","atethat","devoured","cleared","snatched","slayed","bodied","ended","finished","done","over","deceased","screaming","crying","sobbing","im-weak","imweak","sending-me","sendingme","its-giving","itsgiving","giving","serve","serving","ate-left-no-crumbs","main","protagonist","background-character","backgroundcharacter","side-character","sidecharacter","villain-era","villainera","redemption-arc","character-development","characterdevelopment","plot-twist","plottwist","lore","lore-drop","loredrop","deep-lore","deeplore","canon","fanon","ick","icks","red-flag","redflag","green-flag","greenflag","beige-flag","situationship","talking-stage","talkingstage","roster","rotation","era","eras","villain-arc","healing-era","flop-era","flopping","ate-and-left","understood-assignment","no-thoughts","nothoughts","brain-rot","brainrot","rotted","chronically-online","chronicallyonline","parasocial","hyperfixation","hyperfixating","special-interest","infodump","info-dump","infodumping","yapping","yap","yapper","glazing","glaze","glazer","meat-riding","meatriding","dickriding","aura","aura-points","aurapoints","negative-aura","positiveaura","sigma","sigma-grindset","sigmagrindset","alpha","beta","omega","mewing","mew","looksmax","looksmaxxing","mogging","mog","mogger","gyat","gyatt","bussin-bussin","respectfully-disrespectfully","real-ones","realones","day-ones","dayones","ride-or-die","rideordie","caught-lacking","caughtlacking","down-bad","downbad","down-tremendous","downhorrendous","down-horrendous","astronomically-down","abysmal","its-joever","joever","its-so-over","we-are-so-back","weareback","lock-in","lockin","locked-in","lockedin","locked-tf-in","cooked","cooking","cookin","chef","michelin","gourmet","fr-ong","frong","no-diddy","nodiddy","pause","unpause","resume","edging","edged","gooning","gooned","fanum-tax","fanumtax","hawk-tuah","hawktuah","kai-cenat","speed","ishowspeed","prime","adulting","adult","grown","grownup","grown-up","oldmillennial","avocadotoast","avocado-toast","brunch","brunching","mimosas","doggo","doggie","pupper","puppers","floof","chonk","chonky","birb","smol","smoll","smolbean","smol-bean","boop","snoot","blep","mlem","feels","allthefeels","all-the-feels","rightinthefeels","right-in-the-feels","mood","bigmood","big-mood","sadboi","sad-boi","sadgirl","sad-girl","aesthetic","vsco","vsco-girl","vscogirl","sksksk","andioop","and-i-oop","netflix","netflixandchill","netflix-and-chill","binge","bingewatch","throwback","tbt","throwbackthursday","throwback-thursday","flashback","nostalgia","nostalgic","90skid","90s-kid","80skid","80s-kid","pokemon","pikachu","nintendo","zelda","mario","sonic","sega","harrypotter","harry-potter","hogwarts","hufflepuff","gryffindor","slytherin","ravenclaw","muggle","potterhead","potter-head","starwars","star-wars","jedi","sith","mandalorian","mando","yoda","marvel","mcu","avengers","thanos","ironman","iron-man","spiderman","lotr","lordoftherings","lord-of-the-rings","hobbit","gandalf","frodo","gameofthrones","game-of-thrones","got","thrones","winteriscoming","nailed-it","nailedit","winning","fail","fails","epic","epicfail","fml","yolo","swag","swagger","legit","literally","literally-cant","cant-even","canteven","dying","dead","imdead","im-dead","deceased","goals","lifegoals","life-goals","relationshipgoals","relationship-goals","bae","babe","babes","hubby","wifey","fiance","soulmate","soul-mate","foodporn","food-porn","foodie","nomnom","nom-nom","yummy","delish","wanderlust","travelbug","travel-bug","jetset","jet-set","jetsetter","selfie","selfies","selfietime","selfie-time","groupie","photobomb","blessed","grateful","thankful","humbled","mindblown","mind-blown","extra","salty","shook","triggered","woke","cancelled","cancel","ghosting","ghosted","ghost","friendzone","friend-zone","friendzoned","shade","throwing-shade","tea","spill","spilltea","spill-tea","savage","clap-back","clapback","drag","dragged","read","receipts","tfw","mfw","mrw","dae","eli5","tldr","tl-dr","ama","iama","reddit","redditor","upvote","downvote","karma","cakeday","cake-day","meme","memes","dank","dankmemes","dank-memes","memelord","meme-lord","oldmillenial","xennial","geriatricmillennial","geriatric-millennial","youngmillennial","young-millennial","eldermillennial","elder-millennial","millennialproblems","millennial-problems","millenniallife","millennial-life","firstworldproblems","first-world-problems","struggle","struggles","thestruggle","broke","brokemillennial","broke-millennial","studentloans","student-loans","sidehustle","side-hustle","hustleculture","hustle-culture","grind","grinding","worklifebalance","work-life-balance","burnout","burn-out","selfcare","self-care","treatyoself","treat-yo-self","treatyourself","indulgence","splurge","athleisure","leggings","yoga","yogapants","yoga-pants","pilates","kale","quinoa","acai","matcha","oatmilk","oat-milk","plantbased","plant-based","glutenfree","gluten-free","organic","nongmo","non-gmo","farmtotable","farm-to-table","craftbeer","craft-beer","craftcocktails","craft-cocktails","speakeasy","rooftopbar","rooftop-bar","happyhour","happy-hour","winenight","wine-night","tacotuesday","taco-tuesday","pizzanight","pizza-night","takeout","take-out","doordash","ubereats","uber-eats","grubhub","postmates","instacart","plantmom","plant-mom","plantdad","plant-dad","plantparent","plant-parent","crazycatlady","crazy-cat-lady","dogmom","dog-mom","dogdad","dog-dad","furbaby","fur-baby","furbabies","rescuedog","rescue-dog","adoptdontshop","engagement","engaged","shesaidyes","she-said-yes","weddingplanning","wedding-planning","bridesquad","bride-squad","groomsmen","bachelorette","bachelor","honeymoon","firsthome","first-home","homeowner","home-owner","housegoals","house-goals","diy","diyer","fixer-upper","fixerupper","hgtv","pinterestfail","pinterest-fail","netflix-queue","netflixqueue","bingeing","binge-watching","streamingwars","truecrimeobsessed","true-crime-obsessed","truecrime","true-crime","murderino","podcastaddict","podcast-addict","serialpodcast","serial-podcast","officelife","office-life","corporatelife","corporate-life","cubicle","openoffice","slack","slackchannel","slack-channel","zoomlife","zoom-life","zoommeetings","wfh","workfromhome","work-from-home","remotework","remote-work","hybridwork","quietquitting","quiet-quitting","thegreatresignation","thegreatreshuffling","sundayscaries","sunday-scaries","mondaymotivation","monday-motivation","humpday","hump-day","tgif","fridayfeeling","friday-feeling","fridayvibes","itstheweekend","weekendvibes","weekend-vibes","weekendmode","weekend-mode","lol","lmao","lmfao","rofl","roflmao","omg","wtf","ftw","smh","tbh","icymi","fomo","jomo","fwiw","imho","imo","brb","gtg","ttyl","nbd","idk","idgaf","stfu","nsfw","tmi","btw","afaik","iirc","ymmv","ianal","whatever","whatev","whatevs","meh","blah","ugh","duh","psych","noway","no-way","asif","as-if","getreal","get-real","talktotheh","talk-to-the-hand","nottt","not","sike","syke","psyche","gnarly","rad","radical","tubular","bodacious","righteous","excellent","bogus","heinous","grody","gag-me","gagme","barf","barfbag","gross","dude","dudes","dudette","bro","bros","broski","homie","homies","homes","peeps","posse","crew","gang","clique","tribe","chill","chillax","chillaxin","chilling","chillin","kickin","kickback","kick-back","hangout","hang-out","hangtime","hang-time","couch","couchpotato","couch-potato","vegging","veggingout","vegging-out","slacker","slackers","slack","slacking","procrastinate","procrastinating","grunge","grungy","alternative","alt","indie","underground","mtv","vh1","headbangers","headbanging","moshing","moshpit","mosh-pit","nirvana","cobain","soundgarden","pearljam","pearl-jam","aliceinchains","beavis","butthead","beavisandbutthead","daria","simpsons","bartman","waynesworld","waynes-world","partyon","party-on","schwing","excellent","billted","bill-ted","bogusjourney","bogus-journey","stationn","ferris","ferrisbueller","ferris-bueller","dayoff","day-off","buellerr","breakfast-club","breakfastclub","sixteen-candles","sixteencandles","pretty-in-pink","prettyinpink","mollyringwald","molly-ringwald","johnhughes","john-hughes","hughes","brat-pack","bratpack","pager","beeper","pagenme","page-me","callme","call-me","hitmeup","snailmail","snail-mail","aol","aim","icq","uh-oh","a-s-l","asl","netscape","geocities","angelfire","tripod","webcrawler","askjeeves","gen-x","genx","genxer","gen-xer","xer","xers","forgottengeneration","latchkeykid","latchkey-kid","latchkey","unsupervised","freerange","free-range","mtv-generation","mtvgeneration","mtvkids","mtv-kids","videokilled","video-killed","reagan-era","reaganera","coldwar","cold-war","coldwarkids","cold-war-kids","afterschoolspecial","after-school-special","justdontdoit","saynotodrugs","dareprogram","dare-program","scared-straight","scaredstraight","whatcha-talkin-bout","diffrentstrokes","factsoflife","facts-of-life","familyties","family-ties","growinpains","growin-pains","cosby","cheers","thirtysomething","thirty-something","madaboutyou","mad-about-you","seinfeld","seinfeldian","kramers","masterofyourdomain","yada-yada-yada","friends","centralpark","central-perk","rachel","ross","chandler","monica","melrose","melroseplace","melrose-place","90210","beverlyhills90210","myso-called-life","mysocalledlife","angela","jordan-catalano","jordancatalano","freaksandgeeks","freaks-and-geeks","lindsay","undeclared","realworld","real-world","truestory","true-story","roadrules","road-rules","unplugged","mtv-unplugged","mtvunplugged","acoustic","coffehouse","grunge-era","grungeera","seattlesound","seattle-sound","subpop","sub-pop","smellsliketeenspirit","smells-like-teen-spirit","nevermind","bleach","ten","superunknown","dirt","facelift","jaroffies","jar-of-flies","greenday","green-day","dookie","basketcase","basket-case","wheniseptember","blink182","blink-182","enema","whats-my-age-again","allthesmallthings","sublime","santeria","wrongway","wrong-way","40oz","forty-oz","rage","ratm","rageagainstthemachine","killinginthename","bulls-on-parade","tool","lateralus","aenima","undertow","opiate","spiralout","spiral-out","nineinchnails","nine-inch-nails","nin","closer","headlikeahole","smashingpumpkins","smashing-pumpkins","siamesedream","mellon-collie","radiohead","okcomputer","ok-computer","creep","karma-police","paranoidandroid","beck","loser","odelay","whereitsat","where-its-at","twoturnstables","pulpfiction","pulp-fiction","royalewithcheese","saywhatagain","ezekiel","clerks","viewaskew","view-askew","jayandsilentbob","snootchie","officespace","office-space","tpsreports","tps-reports","piecesofflair","thematrix","the-matrix","redpill","bluepill","neo","morpheus","followthewhiterabbit","fightclub","fight-club","firstrandbeof","projectmayhem","tylerdurden","xfiles","x-files","mulderandscully","thetruthisoutthere","iwanttobelieve","buffy","buffythevampireslayer","buffy-tvs","scoobygang","sunnydale","groovy","far-out","farout","outtasite","outta-sight","righteous","cool","coolio","coolcat","cool-cat","coolbeans","cool-beans","neato","solid","solidgold","solid-gold","golden","goldies","oldies","classics","keen","swell","peachy","peachykeen","peachy-keen","hunky-dory","hunkydory","hip","hipster","hipcat","hip-cat","hep","hepcat","hep-cat","jazzy","square","squares","squaresville","uptight","uncool","unhip","bread","dough","moolah","bucks","clams","greenbacks","benjamins","pad","crib","digs","joint","spot","place","casa","hacienda","wheels","ride","whip","jalopy","hooptie","beater","clunker","oldtimer","old-timer","oldschool","old-school","vintage","retro","classic","backyard","frontporch","front-porch","patio","deck","garage","workshop","hamshack","ham-shack","radioshack","radio-shack","basement","attic","lodge","elks","moose","eagles","vfw","legion","american-legion","rotary","kiwanis","lions","shriners","masons","masonic","fraternal","church","chapel","parish","congregation","fellowship","ministry","sunday","sabbath","potluck","pot-luck","social","supper","supperclub","bridge","bridgeclub","bridge-club","cards","cardgame","card-game","bingo","bunco","poker","pokernight","poker-night","gamenight","game-night","bowling","bowlingalley","bowling-alley","bowlingleague","bowling-league","golf","golfclub","golf-club","teeoff","tee-off","links","fairway","fishing","fishinghole","fishing-hole","fishingbuddy","fishing-buddy","hunting","huntingcamp","hunting-camp","deercamp","deer-camp","cabin","rv","rvclub","rv-club","camper","campground","koa","goodsam","good-sam","snowbird","snowbirds","sunbird","sunbirds","winter-texan","wintertexan","retired","retirement","goldenage","golden-age","goldenyears","golden-years","aarp","seniors","seniormoments","senior-moments","grandkids","grandchildren","boomer","boomers","babyboomer","baby-boomer","babyboomers","baby-boomers","woodstock","woodstocknation","woodstock-nation","hippie","hippies","hippy","peacelove","peace-love","peacesign","peace-sign","makelovenotowar","flowerpower","flower-power","flowerchild","flower-child","summerofove","counterculture","counter-culture","freebird","free-bird","freespirit","tune-in-turn-on","dropmeout","trippingout","tripping-out","psychedelic","grateful-dead","gratefuldead","deadhead","dead-head","deadheads","beatles","beatlemania","fab-four","fabfour","johnpaugeorgeringo","rollingstones","rolling-stones","stones","jagger","keithrichards","thewho","the-who","mygeneration","my-generation","tommyboy","ledzeppelin","led-zeppelin","zeppelin","stairway","stairwaytoheaven","pinkfloyd","pink-floyd","thewall","the-wall","darkside","darksidemoon","doors","thedoors","jimmorrison","jim-morrison","lightmyfire","riders","hendrix","jimi","jimihendrix","purplehaze","purple-haze","voodoo-child","janis","janisjoplin","janis-joplin","mercedesbenz","piecemyheart","ccr","creedence","creedence-clearwater","fortunateson","badmoonrising","eagles","hotelcalifornia","hotel-california","desperado","takiteasy","fleetwood","fleetwoodmac","fleetwood-mac","rumours","dreams","thchain","carlysimon","carly-simon","youresovain","anticipation","simongarfunkel","simon-garfunkel","soundofsilence","bridgeovertroubledwater","caroleking","carole-king","tapestry","youvegotafriend","naturalwoman","crosbystillsnash","crosby-stills-nash","csny","suite-judy-blue-eyes","vietnam","vietnamera","vietnam-era","vietnamvet","vietnam-vet","napalm","civilrights","civil-rights","mlk","martin-luther-king","ihaveadream","moonlanding","moon-landing","apollo","apollo11","onesmallstep","jfk","kennedy","camelot","asknotwhat","cubanmissilecrisis","coldwars","watergate","nixon","rosemarywoods","18minutes","deepthroat","mash","allinthefamily","all-in-the-family","archie","archiebunker","happydays","happy-days","fonzie","thfonz","aaayyyy","jumptheshark","laverne-shirley","laverneshirley","schlemiel","schlimazel","marytylermore","mary-tyler-moore","rhoda","lou-grant","lourant","bobnehart","bob-newhart","newhart","hiimbob","thisislarrybrother","sanford-son","sanfordandson","bigdummy","elizabethimcoming","jeffersons","thejeffersons","movingonup","moving-on-up","deluxe","goodtimes","good-times","dynomite","dy-no-mite","jj","chico-man","chicoman","chicoandtheman","lookingfordwardo","kolchak","nightstalker","night-stalker","barnaby","barnabyjones","columbo","onmorething","one-more-thing","justonemorething","magnum","magnumpi","magnum-pi","selleck","tomelleck","ferrari308","rockfordfiles","rockford-files","jimrockford","answeringmachine","dallastv","dallas-tv","whoshotjr","who-shot-jr","ewingsouthfork","dynasty","alexis","crystalcarrington","catfight","shoulderpads","sixmilliondollarman","bionicwoman","bionic-woman","wecanrebuildhim","the","be","to","of","and","a","in","that","have","i","it","for","not","on","with","he","as","you","do","at","this","but","his","by","from","they","we","say","her","she","or","an","will","my","one","all","would","there","their","what","so","up","out","if","about","who","get","which","go","me","when","make","can","like","time","no","just","him","know","take","people","into","year","your","good","some","could","them","see","other","than","then","now","look","only","come","its","over","think","also","back","after","use","two","how","our","work","first","well","way","even","new","want","because","any","these","give","day","most","us","is","are","was","were","been","good","bad","great","best","worst","first","last","next","only","own","free","open","close","closed","new","old","young","big","small","little","long","short","high","low","fast","slow","quick","hot","cold","warm","cool","hard","soft","easy","difficult","simple","complex","clear","dark","light","bright","deep","shallow","wide","narrow","thick","thin","heavy","full","empty","clean","dirty","wet","dry","loud","quiet","silent","strong","weak","rich","poor","cheap","expensive","safe","dangerous","healthy","sick","happy","sad","angry","calm","busy","lazy","crazy","smart","stupid","clever","wise","dumb","funny","serious","strange","normal","weird","perfect","broken","whole","complete","partial","ready","active","passive","alive","dead","awake","asleep","aware","blind","bold","brave","calm","careful","certain","chief","common","curious","current","direct","double","early","entire","exact","extra","fair","false","famous","final","fine","firm","flat","former","forward","fresh","front","frozen","general","giant","global","golden","grand","green","gross","guilty","hidden","hollow","honest","huge","human","humble","hungry","ideal","ill","inner","instant","intense","internal","joint","just","keen","key","kind","known","large","late","latter","leading","legal","likely","limited","linear","liquid","live","living","local","logical","lonely","loose","lost","lovely","lower","lucky","mad","magic","main","major","male","female","manual","married","massive","master","maximum","mean","medium","mental","middle","military","minimum","minor","missing","mixed","mobile","modern","monthly","moral","mutual","naked","narrow","nasty","native","natural","nearby","neat","negative","nervous","neutral","next","nice","noble","noisy","normal","northern","novel","obvious","odd","official","ok","okay","olympic","only","open","opening","opposite","optional","orange","ordinary","organic","original","other","outdoor","outer","outside","overall","overseas","owing","own","pale","parallel","partial","particular","past","patient","peaceful","peculiar","permanent","personal","petty","physical","pink","plain","pleasant","plenty","plus","pointed","polite","political","popular","positive","possible","potential","powerful","practical","precious","precise","pregnant","present","presidential","pretty","previous","primary","prime","principal","prior","private","probable","productive","professional","profound","progressive","prominent","proper","prospective","protective","proud","provincial","psychological","public","pure","purple","qualified","quick","quiet","radical","random","rapid","rare","raw","ready","real","realistic","reasonable","recent","red","redundant","regional","regular","relative","relevant","reliable","religious","reluctant","remaining","remarkable","remote","representative","resident","resistant","respective","responsible","resulting","revolutionary","rich","ridiculous","right","rigid","rising","risky","rival","romantic","rough","round","royal","ruling","running","rural","sacred","sad","safe","salty","same","sample","go","come","get","give","take","make","do","say","see","look","find","use","tell","ask","work","seem","feel","try","leave","call","keep","let","begin","start","show","hear","play","run","move","live","believe","hold","bring","happen","write","provide","sit","stand","lose","pay","meet","include","continue","set","learn","change","lead","understand","watch","follow","stop","create","speak","read","allow","add","spend","grow","open","walk","win","offer","remember","love","consider","appear","buy","wait","serve","die","send","expect","build","stay","fall","cut","reach","kill","remain","suggest","raise","pass","sell","require","report","decide","pull","break","push","throw","catch","jump","kick","hit","fly","swim","drive","ride","climb","dance","sing","cook","eat","drink","sleep","wake","wash","dress","fight","help","save","teach","study","test","check","join","connect","link","share","post","send","receive","accept","reject","approve","deny","confirm","cancel","reset","restart","refresh","reload","update","upgrade","install","uninstall","download","upload","sync","backup","restore","recover","repair","fix","solve","resolve","complete","finish","time","year","people","way","day","man","woman","child","world","life","hand","part","place","case","week","company","system","program","question","work","government","number","night","point","home","water","room","mother","area","money","story","fact","month","lot","right","study","book","eye","job","word","business","issue","side","kind","head","house","service","friend","father","power","hour","game","line","end","member","law","car","city","community","name","president","team","minute","idea","kid","body","information","back","parent","face","others","level","office","door","health","person","art","war","history","party","result","change","morning","reason","research","girl","guy","moment","air","teacher","force","education","hello","hi","hey","hola","bonjour","ciao","aloha","howdy","greetings","welcome","goodbye","bye","farewell","later","peace","cheers","thanks","thankyou","thank-you","please","sorry","excuse","pardon","congrats","congratulations","bravo","wow","amazing","awesome","cool","nice","great","excellent","perfect","wonderful","fantastic","incredible","unbelievable","omg","wtf","lol","lmao","rofl","haha","hehe","xoxo","hugs","kisses","python","javascript","typescript","java","csharp","cpp","cplusplus","golang","go-lang","rust","rustlang","rust-lang","ruby","php","perl","swift","kotlin","scala","haskell","lisp","clojure","erlang","elixir","fsharp","ocaml","lua","r-lang","rlang","julia","dart","fortran","cobol","assembly","asm","wasm","webassembly","sql","nosql","graphql","mongodb","postgres","postgresql","mysql","mariadb","sqlite","redis","memcached","cassandra","dynamodb","firebase","supabase","prisma","sequelize","typeorm","react","reactjs","react-native","reactnative","angular","angularjs","vue","vuejs","svelte","sveltekit","nextjs","next-js","nuxt","nuxtjs","gatsby","remix","astro","solid","solidjs","preact","qwik","htmx","alpine","tailwind","tailwindcss","bootstrap","bulma","foundation","materialui","chakra","antd","ant-design","shadcn","radix","headlessui","daisyui","nodejs","node-js","deno","bun","express","fastify","koa","nestjs","django","flask","fastapi","rails","rubyonrails","laravel","symfony","spring","springboot","spring-boot","dotnet","aspnet","blazor","maui","electron","tauri","flutter","ionic","capacitor","cordova","xamarin","unity","unreal","godot","pygame","phaser","threejs","three-js","babylon","webpack","vite","rollup","parcel","esbuild","swc","babel","eslint","prettier","jest","vitest","mocha","jasmine","cypress","playwright","selenium","puppeteer","storybook","chromatic","ladle","histoire","docker","kubernetes","k8s","k3s","minikube","helm","istio","envoy","podman","containerd","crio","rancher","openshift","nomad","consul","terraform","pulumi","crossplane","ansible","puppet","chef","saltstack","vagrant","packer","vault","boundary","waypoint","atlantis","argocd","argo-cd","fluxcd","flux-cd","jenkins","circleci","travisci","travis-ci","github-actions","githubactions","gitlab-ci","gitlabci","bitbucket-pipelines","azure-devops","azuredevops","teamcity","bamboo","drone","tekton","spinnaker","aws","amazon","azure","gcp","google-cloud","googlecloud","digitalocean","linode","vultr","hetzner","ovh","scaleway","upcloud","heroku","vercel","netlify","cloudflare","fastly","akamai","cloudfront","railway","render","fly-io","flyio","deno-deploy","workers","cloudflare-workers","lambda","serverless","faas","paas","iaas","saas","baas","kaas","daas","nginx","apache","caddy","traefik","haproxy","envoy","kong","apisix","grafana","prometheus","loki","tempo","jaeger","zipkin","datadog","newrelic","splunk","elastic","elasticsearch","kibana","logstash","elk","fluentd","fluentbit","vector","telegraf","influxdb","timescaledb","questdb","pagerduty","opsgenie","victorops","statuspage","incident-io","rootly","ai","artificial-intelligence","ml","machine-learning","machinelearning","deep-learning","deeplearning","neural","neuralnet","neural-network","tensorflow","pytorch","keras","jax","flax","scikit","sklearn","scipy","numpy","pandas","matplotlib","seaborn","plotly","bokeh","altair","huggingface","hugging-face","transformers","diffusers","datasets","openai","gpt","gpt4","gpt-4","chatgpt","chat-gpt","claude","anthropic","gemini","bard","palm","llama","llama2","llama-2","mistral","mixtral","falcon","mpt","dolly","alpaca","vicuna","orca","phi","zephyr","yi","qwen","deepseek","codellama","code-llama","starcoder","codegen","copilot","cursor","tabnine","codeium","replit","sourcegraph","cody","continue","langchain","llamaindex","llama-index","autogpt","auto-gpt","babyagi","agentgpt","superagi","crewai","autogen","semantic-kernel","guidance","ollama","lmstudio","lm-studio","localai","local-ai","gpt4all","koboldai","oobabooga","text-generation-webui","vllm","tgi","triton","tensorrt","stable-diffusion","stablediffusion","midjourney","dalle","dall-e","imagen","sdxl","controlnet","lora","dreambooth","textual-inversion","automatic1111","comfyui","invokeai","fooocus","kohya","runpod","replicate","banana","modal","anyscale","ray","mlflow","weights-biases","wandb","comet","neptune","clearml","dvc","lakefs","pachyderm","kubeflow","mlrun","seldon","bentoml","mlserver","torchserve","triton-inference","sagemaker","vertex","azure-ml","databricks","snowflake","dbt","airbyte","fivetran","security","cybersec","infosec","netsec","appsec","devsecops","secops","hacking","hacker","hackers","pentest","pentesting","redteam","red-team","blueteam","blue-team","purpleteam","purple-team","bugbounty","bug-bounty","ctf","capture-the-flag","wargames","hackthebox","tryhackme","picoctf","overthewire","vulnhub","exploit","exploits","exploit-db","cve","nvd","mitre","attck","att-ck","owasp","sans","nist","iso27001","soc2","gdpr","hipaa","pci","pci-dss","compliance","audit","forensics","malware","ransomware","trojan","virus","worm","rootkit","botnet","phishing","spearphishing","whaling","vishing","smishing","social-eng","osint","recon","reconnaissance","footprinting","scanning","enumeration","privilege-escalation","privesc","lateral-movement","persistence","exfil","firewall","ids","ips","waf","siem","soar","edr","xdr","mdr","ndr","vpn","proxy","tor","onion","i2p","freenet","darknet","darkweb","encryption","decryption","cipher","hash","hashing","sha","md5","bcrypt","argon2","scrypt","aes","rsa","ecc","ecdsa","ed25519","curve25519","ssl","tls","https","certificates","pki","x509","acme","letsencrypt","oauth","oauth2","oidc","saml","jwt","tokens","sessions","cookies","mfa","2fa","totp","hotp","fido","fido2","webauthn","passkeys","biometrics","password","passwords","passphrase","keychain","vault","secrets","keys","nmap","masscan","zmap","shodan","censys","greynoise","binaryedge","burp","burpsuite","zap","owasp-zap","nikto","sqlmap","metasploit","cobalt-strike","cobaltstrike","empire","covenant","sliver","mythic","mimikatz","bloodhound","responder","impacket","crackmapexec","evil-winrm","hashcat","john","johntheripper","hydra","medusa","aircrack","aircrack-ng","wireshark","tcpdump","tshark","scapy","ettercap","bettercap","mitmproxy","ghidra","ida","radare2","r2","binary-ninja","hopper","cutter","x64dbg","immunity","ollydbg","gdb","lldb","windbg","frida","objection","cycript","blockchain","crypto","cryptocurrency","defi","de-fi","cefi","ce-fi","bitcoin","btc","ethereum","eth","solana","sol","cardano","ada","polkadot","dot","avalanche","avax","polygon","matic","arbitrum","arb","optimism","op","base","zksync","zk-sync","starknet","scroll","linea","cosmos","atom","osmosis","osmo","celestia","tia","injective","inj","near","nearprotocol","aptos","apt","sui","mina","algorand","algo","tezos","xtz","hedera","hbar","fantom","ftm","harmony","one","elrond","egld","flow","icp","internet-computer","filecoin","fil","arweave","ar","storj","sia","akash","akt","render","rndr","chainlink","link","thegraph","grt","api3","band","uma","tellor","uniswap","uni","sushiswap","sushi","pancakeswap","cake","curve","crv","aave","compound","comp","makerdao","maker","mkr","dai","synthetix","lido","steth","rocketpool","reth","frax","convex","cvx","yearn","yfi","dydx","gmx","perpetual","perp","vertex","hyperliquid","drift","opensea","blur","looksrare","x2y2","sudoswap","nftx","rarible","foundation","nft","nfts","pfp","generative","ordinals","inscriptions","brc20","brc-20","wallet","wallets","metamask","phantom","rainbow","rabby","frame","zerion","ledger","trezor","coldcard","bitbox","keystone","hardware-wallet","seed","seedphrase","seed-phrase","mnemonic","private-key","privatekey","mining","miner","miners","hashrate","hash-rate","pow","pos","dpos","staking","stake","validator","validators","delegation","slashing","gas","gwei","eip","eip1559","erc20","erc721","erc1155","erc4626","dao","daos","governance","proposal","voting","snapshot","tally","multisig","multi-sig","gnosis","safe","timelock","vesting","airdrop","hardware","electronics","circuits","pcb","breadboard","soldering","arduino","esp32","esp8266","stm32","teensy","pico","rp2040","attiny","raspberrypi","raspberry-pi","rpi","rpi4","rpi5","rpi-zero","rpizero","beaglebone","beagle-bone","orangepi","orange-pi","bananapi","banana-pi","jetson","nvidia-jetson","nano","xavier","orin","coral","edge-tpu","fpga","verilog","vhdl","systemverilog","chisel","myhdl","amaranth","xilinx","altera","intel-fpga","lattice","gowin","efinix","anlogic","asic","risc","risc-v","riscv","arm","arm64","aarch64","x86","x64","mips","powerpc","sparc","xtensa","avr","pic","msp430","8051","microcontroller","mcu","soc","cpu","gpu","npu","tpu","dpu","ipu","memory","ram","dram","sram","flash","eeprom","rom","nvram","mram","ssd","nvme","hdd","storage","raid","nas","san","das","iscsi","usb","usb-c","thunderbolt","pcie","sata","nvlink","hdmi","displayport","ethernet","wifi","bluetooth","ble","zigbee","zwave","thread","matter","lora","lorawan","sigfox","nbiot","nb-iot","lte-m","catm1","5g","4g","antenna","antennas","rf","sdr","rtl-sdr","hackrf","limesdr","pluto","oscilloscope","logic-analyzer","multimeter","power-supply","signal-gen","3dprinter","3d-printer","3dprinting","fdm","sla","resin","filament","cnc","laser","lasercutter","laser-cutter","plasma","waterjet","edm","physics","quantum","quantum-physics","quantumphysics","quantummechanics","relativity","einstein","newton","particle","particles","hadron","cern","fermion","boson","higgs","quark","lepton","neutrino","photon","electron","proton","neutron","atom","atoms","atomic","nuclear","fission","fusion","plasma","magnetism","electromagnetism","gravity","gravitation","spacetime","blackhole","black-hole","singularity","wormhole","darkmatter","dark-matter","darkenergy","dark-energy","cosmology","bigbang","big-bang","inflation","astronomy","astrophysics","cosmos","universe","multiverse","galaxy","galaxies","milkyway","milky-way","andromeda","nebula","nebulae","pulsar","quasar","magnetar","supernova","nova","dwarf","whitedwarf","reddwarf","star","stars","stellar","solar","sun","sunspot","corona","flare","planet","planets","planetary","exoplanet","mercury","venus","earth","mars","jupiter","saturn","uranus","neptune","pluto","ceres","eris","moon","moons","lunar","asteroid","asteroids","comet","comets","meteor","telescope","telescopes","hubble","webb","jwst","james-webb","chandra","spitzer","kepler","tess","gaia","vlt","elt","keck","alma","ska","nasa","esa","jaxa","isro","roscosmos","cnsa","spacex","blueorigin","virgin-galactic","rocketlab","relativity-space","firefly","astra","chemistry","chem","chemical","chemicals","molecule","molecules","molecular","organic","inorganic","polymer","polymers","catalyst","reaction","synthesis","element","elements","periodic","periodic-table","hydrogen","helium","lithium","carbon","nitrogen","oxygen","sulfur","phosphorus","potassium","calcium","iron","copper","zinc","silver","gold","platinum","uranium","plutonium","biology","bio","biological","bioscience","lifescience","life-science","cell","cells","cellular","dna","rna","mrna","gene","genes","genetic","genetics","genomics","genome","chromosome","protein","proteins","enzyme","bacteria","bacterial","virus","viral","microbe","microbes","microbiology","fungus","fungi","yeast","algae","plankton","protozoa","amoeba","evolution","darwin","natural-selection","species","taxonomy","phylogeny","ecology","ecosystem","biodiversity","conservation","endangered","extinction","botany","botanical","plant","plants","flora","flower","flowers","tree","trees","forest","forests","rainforest","jungle","grassland","savanna","zoology","animal","animals","fauna","mammal","mammals","reptile","reptiles","amphibian","amphibians","bird","birds","avian","fish","fishes","marine","insect","insects","arthropod","arachnid","spider","spiders","butterfly","earth","earthscience","earth-science","geology","geological","geologist","rock","rocks","mineral","minerals","crystal","crystals","gem","gems","volcano","volcanoes","volcanic","lava","magma","eruption","tectonic","earthquake","earthquakes","seismic","seismology","fault","faults","mountain","mountains","peak","peaks","summit","ridge","range","alps","himalayas","rockies","andes","everest","kilimanjaro","fuji","denali","ocean","oceans","oceanic","atlantic","pacific","indian","arctic","antarctic","sea","seas","mediterranean","caribbean","baltic","adriatic","aegean","river","rivers","stream","streams","creek","creeks","delta","estuary","lake","lakes","pond","ponds","reservoir","wetland","wetlands","swamp","island","islands","peninsula","cape","bay","gulf","strait","channel","continent","continents","africa","asia","europe","northamerica","southamerica","australia","oceania","antarctica","arctic","polar","tropical","equator","climate","weather","meteorology","atmosphere","stratosphere","troposphere","temperature","precipitation","humidity","pressure","wind","winds","storm","storms","hurricane","typhoon","cyclone","tornado","tornadoes","lightning","thunder","thunderstorm","monsoon","blizzard","drought","environment","environmental","eco","ecology","green","sustainable","sustainability","renewable","renewables","solar","solar-power","solarpower","wind-power","windpower","hydro","hydroelectric","geothermal","biomass","nuclear-power","nuclearpower","fusion-power","fusionpower","clean-energy","carbon","carbon-neutral","carbonneutral","netzero","net-zero","emissions","greenhouse","co2","methane","ozone","pollution","pollutants","smog","recycle","recycling","compost","composting","waste","zerowaste","zero-waste","plastic","plastics","microplastic","biodegradable","reusable","disposable","organic","natural","vegan","vegetarian","plantbased","plant-based","climate-change","climatechange","global-warming","globalwarming","ipcc","paris-agreement","cop","cop28","unfccc","epa","wwf","greenpeace","sports","sport","athletics","athletic","athlete","athletes","fitness","workout","workouts","exercise","exercises","training","trainer","gym","football","nfl","soccer","fifa","worldcup","world-cup","premier-league","champions-league","laliga","la-liga","bundesliga","seriea","serie-a","basketball","nba","wnba","ncaa","march-madness","hoops","dunk","slam","baseball","mlb","homerun","home-run","worldseries","world-series","hockey","nhl","ice-hockey","icehockey","puck","slap-shot","goalie","tennis","atp","wta","wimbledon","usopen","us-open","roland-garros","golf","pga","lpga","masters","ryder-cup","birdie","eagle","hole-in-one","boxing","mma","ufc","bellator","wrestling","wwe","aew","judo","karate","taekwondo","jiu-jitsu","jiujitsu","bjj","muay-thai","kickboxing","kung-fu","olympics","olympic","paralympics","paralympic","commonwealthgames","running","runner","runners","marathon","marathons","half-marathon","5k","10k","ultra","ultramarathon","trail-running","trailrunning","cross-country","cycling","cyclist","cycling","tour-de-france","tourdefrance","giro","vuelta","time-trial","peloton","velodrome","bmx","mountainbike","mtb","swimming","swimmer","swimmers","pool","freestyle","backstroke","butterfly","triathlon","triathlete","ironman","sprint-tri","olympic-tri","duathlon","weightlifting","powerlifting","crossfit","bodybuilding","strongman","yoga","pilates","aerobics","zumba","hiit","cardio","stretching","mobility","surfing","surf","surfer","surfers","waves","barrel","pipeline","wsl","skateboarding","skate","skater","skaters","sk8","halfpipe","vert","street","snowboarding","snowboard","snowboarder","skiing","ski","skier","slopes","climbing","climber","climbers","bouldering","trad","sport-climbing","parkour","freerunning","free-running","traceur","movement","calisthenics","music","musician","musicians","musical","song","songs","album","albums","artist","artists","band","bands","singer","singers","vocalist","voice","rock","rock-music","rockmusic","rocknroll","rock-n-roll","classic-rock","pop","pop-music","popmusic","kpop","k-pop","jpop","j-pop","cpop","c-pop","hiphop","hip-hop","rap","rapper","rappers","trap","drill","grime","rnb","r-n-b","soul","funk","disco","motown","reggae","dancehall","ska","jazz","jazz-music","jazzmusic","bebop","swing","bigband","big-band","blues","blues-music","bluesmusic","delta-blues","chicago-blues","electric","country","country-music","countrymusic","bluegrass","americana","folk","electronic","edm","techno","house","trance","dubstep","drum-and-bass","dnb","drumnbass","ambient","chillout","chill-out","lofi","lo-fi","beats","classical","classical-music","classicalmusic","orchestra","symphony","opera","choir","choral","chamber","baroque","romantic","contemporary","metal","heavy-metal","heavymetal","death-metal","black-metal","thrash","punk","punk-rock","punkrock","hardcore","emo","screamo","post-punk","indie","indie-rock","indierock","indie-pop","indiepop","alternative","grunge","shoegaze","dream-pop","dreampop","noise","experimental","world-music","worldmusic","latin","salsa","merengue","bachata","cumbia","afrobeat","afro-beat","afropop","afro-pop","highlife","juju","mbalax","guitar","guitarist","bass","bassist","drums","drummer","percussion","keyboard","keyboardist","piano","pianist","synth","synthesizer","keys","violin","violinist","cello","cellist","viola","bass","doublebass","saxophone","sax","trumpet","trombone","clarinet","flute","oboe","horn","dj","deejay","turntable","turntables","mixing","mixer","scratching","producer","producers","production","beatmaker","beat-maker","beats","recording","studio","studios","mastering","mixing","mixing-board","spotify","apple-music","applemusic","tidal","deezer","soundcloud","bandcamp","youtube-music","youtubemusic","amazon-music","amazonmusic","vinyl","records","record","lp","ep","single","singles","discography","concert","concerts","gig","gigs","tour","touring","festival","festivals","coachella","glastonbury","lollapalooza","bonnaroo","burning-man","sxsw","grammy","grammys","brit-awards","vma","ama","billboard","rolling-stone","movies","movie","film","films","cinema","cinematic","theater","theatre","hollywood","bollywood","nollywood","tollywood","anime","animation","documentary","documentaries","doc","docs","docuseries","docu-series","tv","television","series","show","shows","episode","episodes","season","drama","dramas","comedy","comedies","romcom","rom-com","sitcom","sitcoms","action","adventure","thriller","thrillers","horror","scary","slasher","scifi","sci-fi","science-fiction","sciencefiction","fantasy","dystopia","superhero","superheroes","marvel","mcu","dc","dceu","batman","superman","spiderman","spider-man","avengers","xmen","x-men","fantastic-four","starwars","star-wars","startrek","star-trek","trekkie","trekkies","lotr","lord-of-the-rings","lordoftherings","hobbit","tolkien","middle-earth","harrypotter","harry-potter","hogwarts","wizarding","potterhead","gameofthrones","game-of-thrones","got","westeros","houseofdragon","stranger-things","strangerthings","breaking-bad","breakingbad","bettercallsaul","netflix","hulu","disney-plus","disneyplus","hbo","hbomax","max","amazon-prime","amazonprime","primevideo","prime-video","appletv","paramount-plus","paramountplus","peacock","criterion","mubi","shudder","director","directors","filmmaker","filmmakers","cinematographer","dop","actor","actors","actress","actresses","cast","casting","audition","screenwriter","screenwriting","script","scripts","screenplay","storyboard","oscar","oscars","academy-awards","academyawards","emmy","emmys","golden-globe","goldenglobes","bafta","cannes","sundance","tribeca","toronto","tiff","venice","berlinale","sxsw-film","telluride","gaming","gamer","gamers","games","game","videogames","video-games","pc-gaming","pcgaming","console","consoles","handheld","mobile-gaming","playstation","ps5","ps4","ps3","psn","xbox","xboxone","xbox-series","nintendo","switch","switch-2","wii","wiiu","gamecube","n64","snes","nes","steam","steamdeck","steam-deck","epic","epicgames","epic-games","gog","rpg","jrpg","mmorpg","mmo","fps","tps","rts","moba","battle-royale","sandbox","survival","roguelike","roguelite","metroidvania","souls-like","platformer","puzzle","adventure","simulation","sim","sims","strategy","minecraft","fortnite","valorant","csgo","cs2","counterstrike","counter-strike","league","leagueoflegends","league-of-legends","lol","dota","dota2","overwatch","ow2","apex","apexlegends","apex-legends","warzone","callofduty","gta","grandtheftauto","grand-theft-auto","gta6","gta5","rockstar","eldenring","elden-ring","darksouls","dark-souls","bloodborne","sekiro","zelda","totk","botw","tears-of-the-kingdom","breath-of-the-wild","link","mario","supermario","super-mario","mariokart","mario-kart","smashbros","pokemon","pokemongo","pokemon-go","pikachu","scarlet","violet","finalfantasy","final-fantasy","ff16","ff14","ffxiv","squareenix","destiny","destiny2","bungie","halo","haloinfinite","343industries","diablo","diablo4","worldofwarcraft","world-of-warcraft","wow","blizzard","starcraft","hearthstone","overwatch","battlenet","battle-net","assassinscreed","assassins-creed","farcry","far-cry","watchdogs","ubisoft","cyberpunk","cyberpunk2077","witcher","witcher3","cdprojekt","cdpr","baldursgate","baldurs-gate","bg3","larian","divinity","dos2","esports","e-sports","competitive","tournament","tournaments","lan","twitch","streamer","streamers","streaming","youtube-gaming","kick","speedrun","speedrunner","speedrunning","gdq","agdq","sgdq","food","foods","foodie","foodies","cooking","cook","cooks","chef","chefs","recipe","recipes","kitchen","kitchens","culinary","gastronomy","gourmet","restaurant","restaurants","dining","dine","eat","eating","meal","meals","breakfast","brunch","lunch","dinner","supper","snack","snacks","dessert","appetizer","appetizers","entree","entrees","side","sides","course","pizza","pizzas","burger","burgers","sandwich","sandwiches","wrap","wraps","taco","tacos","burrito","burritos","quesadilla","nachos","enchilada","sushi","sashimi","ramen","udon","soba","tempura","teriyaki","bento","pasta","spaghetti","lasagna","ravioli","gnocchi","risotto","italian","steak","steaks","bbq","barbeque","barbecue","grill","grilling","smoker","chicken","beef","pork","lamb","fish","seafood","shrimp","lobster","crab","vegetarian","vegan","plantbased","plant-based","meatless","tofu","tempeh","salad","salads","soup","soups","stew","stews","chili","curry","curries","bread","breads","baking","baker","bakery","pastry","pastries","cake","cookies","brownies","pie","pies","tart","tarts","donut","donuts","coffee","espresso","latte","cappuccino","mocha","americano","coldbrew","tea","teas","greentea","green-tea","blacktea","black-tea","herbal","chai","beer","beers","craft-beer","craftbeer","ipa","lager","stout","ale","brew","wine","wines","redwine","red-wine","whitewine","white-wine","rose","sparkling","cocktail","cocktails","mixology","bartender","bartending","spirits","whiskey","whisky","bourbon","scotch","vodka","gin","rum","tequila","fashion","style","styling","stylist","stylish","trendy","trend","trends","clothing","clothes","outfit","outfits","ootd","lookbook","wardrobe","dress","dresses","shirt","shirts","pants","jeans","shorts","skirt","jacket","jackets","coat","coats","sweater","hoodie","hoodies","blazer","shoes","sneakers","boots","heels","sandals","loafers","footwear","accessories","accessory","jewelry","jewellery","watch","watches","bag","bags","handbag","purse","wallet","sunglasses","hat","hats","scarf","designer","designers","luxury","luxe","haute-couture","hautecouture","runway","catwalk","model","models","modeling","modelling","supermodel","vogue","elle","harpers-bazaar","gq","esquire","cosmopolitan","instyle","beauty","beautiful","gorgeous","stunning","glam","glamour","glamorous","makeup","make-up","cosmetics","lipstick","mascara","eyeliner","eyeshadow","foundation","concealer","blush","bronzer","highlighter","contour","skincare","skin-care","skincareroutine","cleanser","moisturizer","serum","sunscreen","spf","anti-aging","antiaging","wrinkles","acne","pores","hair","haircare","hair-care","hairstyle","hairstyles","haircut","haircolor","blonde","brunette","redhead","highlights","balayage","ombre","extensions","nails","manicure","pedicure","nailart","nail-art","gelnails","acrylics","fragrance","perfume","cologne","scent","scents","aromatherapy","essentials","travel","traveling","travelling","traveler","traveller","travelers","trip","trips","vacation","vacations","holiday","holidays","getaway","adventure","adventures","explore","exploring","explorer","wanderlust","backpacking","backpacker","backpackers","hostel","hostels","hotel","hotels","airbnb","vrbo","booking","expedia","tripadvisor","kayak","skyscanner","flight","flights","airline","airlines","airport","airports","terminal","cruise","cruises","cruising","sailing","yacht","charter","island-hopping","roadtrip","road-trip","roadtrips","driving","scenic","route","routes","hiking","hike","hikes","trail","trails","trek","trekking","camping","beach","beaches","coastal","seaside","oceanfront","beachfront","shore","mountain","mountains","alpine","summit","peak","valley","canyon","gorge","city","cities","urban","metropolitan","downtown","cityscape","skyline","village","villages","town","towns","countryside","rural","scenic","landmark","landmarks","monument","monuments","heritage","unesco","historic","paris","london","newyork","new-york","tokyo","rome","barcelona","amsterdam","berlin","vienna","prague","budapest","lisbon","madrid","athens","istanbul","dubai","singapore","hongkong","hong-kong","bangkok","seoul","taipei","sydney","melbourne","auckland","capetown","cape-town","cairo","marrakech","nairobi","rio","buenosaires","buenos-aires","mexicocity","mexico-city","lima","bogota","sanfrancisco","san-francisco","losangeles","los-angeles","chicago","miami","lasvegas","las-vegas","seattle","boston","austin","denver","portland","vancouver","toronto","montreal","calgary","ottawa","quebec","edmonton","family","families","familytime","family-time","familyfirst","famfam","parents","parenting","parent","parenthood","parentlife","parent-life","mom","moms","momlife","mom-life","mommy","mother","mothers","motherhood","dad","dads","dadlife","dad-life","daddy","father","fathers","fatherhood","kids","kid","children","child","childhood","kidlife","kid-life","toddler","baby","babies","newborn","infant","pregnancy","pregnant","expecting","grandparents","grandma","grandpa","grandmother","grandfather","nana","papa","siblings","sibling","brother","brothers","sister","sisters","twins","friends","friend","friendship","friendships","bestfriend","best-friend","bff","besties","bestie","squad","squadgoals","squad-goals","crew","gang","dating","date","dates","relationship","relationships","couple","couples","boyfriend","girlfriend","partner","partners","significant-other","so","engaged","engagement","fiance","fiancee","wedding","weddings","bride","groom","married","marriage","spouse","husband","wife","newlyweds","anniversary","anniversaries","love","loving","romance","romantic","single","singles","singlelife","single-life","bachelor","bachelorette","divorce","divorced","separated","coparenting","co-parenting","stepparent","blended","blendedfamily","blended-family","adoption","adopted","foster","lgbtq","lgbt","lgbtqia","queer","pride","pridemonth","pride-month","gay","gays","lesbian","lesbians","bisexual","bi","pansexual","pan","transgender","trans","nonbinary","non-binary","nb","genderfluid","genderqueer","asexual","ace","aromantic","aro","demisexual","demi","intersex","ally","coming-out","comingout","outandproud","out-and-proud","loveislove","love-is-love","feminist","feminism","feminists","womensrights","womens-rights","equality","civilrights","civil-rights","humanrights","human-rights","socialjustice","blm","blacklivesmatter","black-lives-matter","antiracism","anti-racism","indigenous","native","firstnations","first-nations","aboriginal","tribal","disability","disabled","accessibility","a11y","inclusion","inclusive","neurodivergent","adhd","autism","autistic","dyslexia","dyslexic","mental-health","mentalhealth","anxiety","depression","bipolar","ptsd","ocd","therapy","selfcare","self-care","wellness","wellbeing","well-being","mindfulness","meditation","meditate","mindful","zen","calm","peace","peaceful","serenity","recovery","sober","sobriety","clean","aa","na","12steps","12-steps","support","supportgroup","support-group","community","communities","tribe","religion","religious","faith","faithful","belief","believe","believer","spiritual","spirituality","spirit","spirits","soul","souls","divine","christian","christianity","christians","church","churches","jesus","christ","catholic","catholicism","catholics","protestant","evangelical","baptist","methodist","lutheran","presbyterian","orthodox","episcopal","anglican","mormon","lds","latterday","latter-day","jehovah","adventist","pentecostal","jewish","judaism","jews","hebrew","israel","israeli","kosher","sabbath","torah","talmud","synagogue","temple","rabbi","hanukkah","passover","yom-kippur","muslim","islam","islamic","muslims","quran","koran","allah","muhammad","mosque","masjid","imam","halal","ramadan","eid","hajj","mecca","medina","hindu","hinduism","hindus","vedic","yoga","karma","dharma","mantra","temple","temples","krishna","shiva","vishnu","ganesh","diwali","holi","buddhist","buddhism","buddhists","buddha","zen","tibetan","dalai-lama","meditation","enlightenment","nirvana","sangha","dharma","sutra","sikh","sikhism","sikhs","guru","gurus","gurdwara","punjabi","pagan","paganism","wicca","wiccan","witchcraft","witch","witches","atheist","atheism","agnostic","agnosticism","secular","humanist","humanism","prayer","prayers","praying","worship","worshipping","praise","praising","blessing","blessings","blessed","miracle","miracles","grace","salvation","heaven","hell","afterlife","eternal","eternity","resurrection","redemption","work","working","worker","workers","workplace","worklife","work-life","job","jobs","career","careers","profession","professional","professionals","office","offices","corporate","corporation","company","companies","business","startup","startups","entrepreneur","entrepreneurs","entrepreneurship","founder","ceo","cto","cfo","coo","cmo","ciso","vp","director","manager","lead","employee","employees","employer","employers","hr","humanresources","human-resources","hiring","hire","recruit","recruiting","recruitment","talent","headhunter","interview","interviews","interviewing","resume","cv","linkedin","networking","salary","salaries","compensation","benefits","perks","bonus","bonuses","promotion","promoted","raise","negotiation","negotiate","contract","contracts","remote","remotework","remote-work","wfh","workfromhome","work-from-home","hybrid","flexible","flexibility","freelance","freelancer","freelancing","gig","gigeconomy","gig-economy","sideproject","side-project","sidehustle","meeting","meetings","presentation","presentations","conference","conferences","project","projects","deadline","deadlines","milestone","milestones","deliverable","team","teams","teamwork","collaboration","collaborate","agile","scrum","kanban","leadership","leader","leaders","management","manage","managing","productivity","efficiency","efficient","effective","performance","kpi","okr","metrics","burnout","stress","stressed","workload","overtime","quit","quitting","resign","retirement","retired","retiring","pension","401k","ira","savings","invest","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","42","50","60","69","70","80","88","90","99","100","101","111","123","200","222","247","300","333","365","400","404","420","444","500","555","666","700","777","800","888","900","911","999","1000","1111","1234","2000","2020","2021","2022","2023","2024","2025","2026","2027","2028","2029","2030","2050","3000","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch10","ch11","ch12","ch13","ch14","ch15","ch16","ch17","ch18","ch19","ch20","channel1","channel2","channel3","channel4","channel5","channel6","channel7","channel8","channel9","channel10","channel11","channel12","channel13","room1","room2","room3","room4","room5","room6","room7","room8","room9","room10","group1","group2","group3","group4","group5","group6","group7","group8","group9","group10","team1","team2","team3","team4","team5","team6","team7","team8","team9","team10","zone1","zone2","zone3","zone4","zone5","zone6","zone7","zone8","zone9","zone10","area1","area2","area3","area4","area5","area6","area7","area8","area9","area10","sector1","sector2","sector3","sector4","sector5","sector6","sector7","sector8","net1","net2","net3","net4","net5","net6","net7","net8","net9","net10","link1","link2","link3","link4","link5","link6","link7","link8","link9","link10","node1","node2","node3","node4","node5","node6","node7","node8","node9","node10","hub1","hub2","hub3","hub4","hub5","hub6","hub7","hub8","hub9","hub10","mesh1","mesh2","mesh3","mesh4","mesh5","mesh6","mesh7","mesh8","mesh9","mesh10","radio1","radio2","radio3","radio4","radio5","radio6","radio7","radio8","radio9","relay1","relay2","relay3","relay4","relay5","relay6","relay7","relay8","relay9","base1","base2","base3","base4","base5","base6","base7","base8","base9","base10","unit1","unit2","unit3","unit4","unit5","unit6","unit7","unit8","unit9","unit10","server1","server2","server3","server4","server5","server6","server7","server8","dev1","dev2","dev3","dev4","dev5","prod1","prod2","prod3","stage1","stage2","test1","test2","test3","test4","test5","test6","test7","test8","test9","test10","user1","user2","user3","user4","user5","admin1","admin2","admin3","ops1","ops2","alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel","india","juliet","kilo","lima","mike","november","oscar","papa","quebec","romeo","sierra","tango","uniform","victor","whiskey","xray","x-ray","yankee","zulu","alpha1","bravo1","charlie1","delta1","echo1","foxtrot1","alpha-team","bravo-team","charlie-team","delta-team","echo-team","team-alpha","team-bravo","team-charlie","team-delta","team-echo","red","blue","green","yellow","orange","purple","pink","black","white","gray","grey","brown","gold","silver","bronze","copper","platinum","cyan","magenta","teal","navy","maroon","olive","lime","aqua","coral","crimson","indigo","violet","turquoise","beige","ivory","tan","khaki","red-team","blue-team","green-team","yellow-team","orange-team","purple-team","team-red","team-blue","team-green","team-yellow","team-orange","team-purple","rednet","bluenet","greennet","blacknet","whitenet","darknet","clearnet","monday","tuesday","wednesday","thursday","friday","saturday","sunday","mon","tue","wed","thu","fri","sat","sun","weekday","weekend","january","february","march","april","may","june","july","august","september","october","november","december","jan","feb","mar","apr","jun","jul","aug","sep","oct","nov","dec","spring","summer","fall","autumn","winter","season","seasons","seasonal","morning","afternoon","evening","night","midnight","noon","dawn","dusk","daily","weekly","monthly","yearly","annual","quarterly","hourly","today","tomorrow","yesterday","now","later","soon","always","never","24-7","247","round-the-clock","nonstop","non-stop","always-on","alwayson","north","south","east","west","northeast","northwest","southeast","southwest","northern","southern","eastern","western","central","middle","center","up","down","left","right","top","bottom","front","back","side","upper","lower","inner","outer","inside","outside","above","below","near","far","close","distant","local","remote","nearby","faraway","here","there","everywhere","anywhere","somewhere","nowhere","wherever","mini","micro","nano","tiny","small","little","medium","large","big","huge","giant","massive","mega","giga","tera","peta","exa","ultra","super","hyper","extreme","max","maximum","min","minimum","plus","extra","lite","light","heavy","full","empty","half","partial","complete","total","all-chat","allchat","main-chat","mainchat","public-chat","publicchat","general-chat","generalchat","global-chat","globalchat","world-chat","worldchat","local-chat","localchat","open-chat","openchat","free-chat","freechat","random-chat","randomchat","voice-chat","voicechat","text-chat","textchat","all-net","allnet","main-net","mainnet","test-net","testnet","dev-net","devnet","local-net","localnet","global-net","globalnet","public-net","publicnet","mesh-net","meshnet","radio-net","radionet","ham-net","hamnet","emerg-net","emergnet","all-hands","allhands","town-hall","townhall","standby","stand-by","on-call","oncall","help-desk","helpdesk","support","tech-support","techsupport","customer-support","feedback","suggestions","ideas","feature-requests","featurerequests","bug-reports","watercooler","water-cooler","coffee-break","coffeebreak","break-room","breakroom","off-topic","offtopic","random","misc","miscellaneous","other","everything-else","introductions","intro","intros","welcome","new-members","newmembers","onboarding","announcements","announce","news","updates","changelog","releases","roadmap","rules","guidelines","faq","faqs","help","how-to","howto","tutorial","tutorials","resources","links","useful-links","usefullinks","bookmarks","reference","docs","showcase","show-and-tell","showandtell","gallery","portfolio","projects","builds","jobs","hiring","careers","opportunities","gigs","freelance","classifieds","buy-sell","buysell","marketplace","trade","trading","swap","swaps","deals","events","meetups","meetup","gatherings","conferences","workshops","webinars","study-group","studygroup","book-club","bookclub","movie-night","movienight","game-night","gamenight","trivia","quiz","contests","challenges","competitions","reddit","twitter","x","facebook","fb","instagram","ig","insta","tiktok","youtube","yt","pinterest","snapchat","snap","linkedin","tumblr","threads","mastodon","fediverse","bluesky","bsky","discord","slack","telegram","signal","whatsapp","messenger","wechat","line","kakao","viber","matrix","element","clubhouse","spaces","periscope","vine","myspace","digg","stumbleupon","quora","medium","substack","patreon","onlyfans","fanhouse","gumroad","behance","dribbble","deviantart","artstation","pixiv","flickr","500px","meme","memes","dank","dankmemes","dank-memes","cursed","blessed","blursed","cringe","based","redpill","redpilled","blackpill","copium","hopium","cope","poggers","pog","pogchamp","pepe","wojak","gigachad","chad","virgin","simp","simping","stan","stanning","parasocial","irl","afk","brb","ttyl","fomo","yolo","goat","goated","lit","fire","slay","slaying","periodt","sus","sussy","imposter","amogus","amongus","among-us","crewmate","ratio","ratiod","L","W","big-L","big-W","touch-grass","touchgrass","npc","npcs","normie","normies","sheeple","boomer","zoomer","doomer","coomer","consoomer","wagie","neet","incel","volcel","blackpilled","glowie","janny","jannie","based-and-redpilled","keyed","kino","sovl","tfw","mfw","mrw","imo","imho","afaik","eli5","tldr","tl-dr","reddit-moment","leddit","hivemind","groupthink","echo-chamber","circlejerk","wholesome","wholesome100","chungus","big-chungus","keanu","reeves","stonks","not-stonks","diamond-hands","diamondhands","paper-hands","hodl","to-the-moon","tothemoon","moon","mooning","ape","apes","ape-together","tendies","gme","gamestop","wallstreetbets","wsb","yeet","yeeted","yoink","noob","newb","newbie","scrub","pwned","owned","rekt","wrecked","gg","ggwp","ggez","ez","ezpz","no-cap","nocap","cap","capping","fr","frfr","bussin","valid","bet","no-shot","sheesh","sheeesh","ong","ongggg","mid","L-take","W-take","hot-take","cold-take","spicy","spicy-take","rent-free","rentfree","living-rent-free","unhinged","brainrot","brain-rot","vtuber","vtubers","vtubing","hololive","nijisanji","vshoujo","idol","content","content-creator","contentcreator","creator","creators","influencer","influencers","viral","viralvideo","viral-video","trending","fyp","foryou","for-you","foryoupage","algorithm","algo","engagement","analytics","metrics","subscriber","subscribers","subs","sub","follower","followers","following","like","likes","share","shares","repost","reposts","retweet","rt","quote","comment","comments","reply","replies","dm","dms","direct-message","inbox","notification","notifications","notif","notifs","ping","pings","mention","highlight","highlights","clip","clips","vod","vods","archive","archives","premiere","premieres","watchparty","watch-party","reaction","reactions","react","reacting","review","reviews","tier-list","tierlist","ranking","collab","collabs","collaboration","crossover","feature","featured","guest","host","hosting","cohost","co-host","panel","panels","podcast","podcasts","episode","ep","eps","season","seasons","series","miniseries","mini-series","subreddit","subreddits","sub","subs","thread","threads","post","posts","forum","forums","board","boards","chan","chans","4chan","8chan","8kun","imageboard","textboard","bbs","bulletin-board","usenet","newsgroup","irc","ircnet","efnet","freenode","libera","oftc","rizon","undernet","xmpp","jabber","mumble","teamspeak","ts3","ventrilo","vent","raidcall","wiki","wikipedia","wikia","fandom","tvtropes","knowyourmeme","kym","encyclopediadramatica","ed","urban-dictionary","urbandictionary","ud","google","alphabet","apple","microsoft","msft","amazon","meta","facebook","nvidia","nvda","amd","intel","qualcomm","broadcom","samsung","tsmc","oracle","sap","salesforce","adobe","autodesk","vmware","dell","hp","hpe","ibm","cisco","juniper","arista","palo-alto","fortinet","crowdstrike","palantir","snowflake","databricks","mongodb","elastic","splunk","datadog","zoom","webex","teams","meet","slack","atlassian","jira","confluence","notion","airtable","coda","asana","monday","clickup","trello","basecamp","figma","sketch","invision","zeplin","framer","webflow","squarespace","wix","shopify","bigcommerce","magento","woocommerce","stripe","paypal","square","plaid","brex","ramp","affirm","klarna","afterpay","coinbase","binance","robinhood","fidelity","vanguard","schwab","etrade","interactive-brokers","uber","lyft","doordash","grubhub","instacart","postmates","deliveroo","airbnb","vrbo","booking","expedia","kayak","tripadvisor","yelp","spotify","apple-music","pandora","soundcloud","bandcamp","tidal","deezer","dropbox","box","onedrive","gdrive","google-drive","icloud","mega","nintendo","sony","playstation","xbox","microsoft-gaming","activision","blizzard","activision-blizzard","ea","electronic-arts","ubisoft","epic","valve","steam","rockstar","take-two","2k","bethesda","zenimax","id-software","bioware","dice","respawn","bungie","343","naughtydog","insomniac","santa-monica","guerrilla","sucker-punch","bend","bluepoint","housemarque","fromsoftware","from-software","bandainamco","bandai-namco","capcom","konami","sega","atlus","squareenix","square-enix","enix","square","level5","gamefreak","game-freak","creatures","pokemon-company","mihoyo","hoyoverse","riot","riot-games","tencent","netease","nexon","ncsoft","krafton","pubg","supercell","king","rovio","zynga","playtika","scopely","jam-city","paradox","firaxis","amplitude","creative-assembly","relic","obsidian","larian","cd-projekt","cdpr","techland","4a-games","remedy","io-interactive","disney","pixar","marvel","lucasfilm","warner","warnerbros","warner-bros","universal","paramount","sony-pictures","lionsgate","mgm","dreamworks","illumination","laika","ghibli","studio-ghibli","toei","sunrise","bones","madhouse","mappa","wit","trigger","kyoani","kyoto-animation","ufotable","a1-pictures","cloverworks","shaft","gainax","khara","production-ig","ig","netflix","hulu","hbo","max","disney-plus","prime-video","peacock","paramount-plus","apple-tv","crunchyroll","funimation","hidive","vrv","cbs","nbc","abc","fox","cw","amc","fx","showtime","starz","epix","bbc","itv","channel4","sky","britbox","hayu","acorn","curiositystream","discovery","discovery-plus","history","natgeo","nat-geo","animal-planet","tesla","rivian","lucid","nio","xpeng","byd","polestar","fisker","ford","gm","general-motors","chevy","chevrolet","dodge","ram","jeep","chrysler","toyota","honda","nissan","mazda","subaru","mitsubishi","hyundai","kia","genesis","volkswagen","vw","audi","bmw","mercedes","porsche","lamborghini","ferrari","maserati","alfa-romeo","fiat","volvo","land-rover","range-rover","jaguar","bentley","rolls-royce","aston-martin","mclaren","bugatti","koenigsegg","pagani","rimac","lotus","alpine","medical","medicine","healthcare","health-care","hospital","hospitals","doctor","doctors","dr","physician","physicians","surgeon","surgeons","nurse","nurses","nursing","rn","lpn","cna","np","pa","physician-assistant","pharmacy","pharmacist","pharmacists","pharma","pharmaceutical","rx","dentist","dentists","dental","dentistry","orthodontist","orthodontics","optometrist","ophthalmologist","optometry","vision","eye-care","eyecare","therapist","therapists","therapy","counselor","counseling","psychologist","psychiatrist","psychiatry","psychology","mental-health","mentalhealth","physical-therapy","pt","occupational-therapy","ot","speech-therapy","slp","chiropractor","chiropractic","acupuncture","acupuncturist","naturopath","emt","paramedic","paramedics","ems","emergency","er","icu","nicu","radiology","radiologist","xray","mri","ct","ultrasound","imaging","pathology","pathologist","lab","laboratory","diagnostics","testing","oncology","oncologist","cancer","tumor","chemotherapy","radiation","cardiology","cardiologist","heart","cardiac","cardiovascular","cv","neurology","neurologist","neuro","brain","spine","neurosurgery","pediatrics","pediatrician","peds","children","child-health","childhealth","geriatrics","geriatrician","elderly","senior-care","seniorcare","aging","dermatology","dermatologist","derm","skin","skincare","skin-care","orthopedics","orthopedic","ortho","bone","joint","sports-medicine","gastroenterology","gastro","gi","digestive","gut","intestinal","endocrinology","endocrine","diabetes","thyroid","hormone","hormones","pulmonology","pulmonologist","respiratory","lung","lungs","breathing","nephrology","nephrologist","kidney","kidneys","renal","dialysis","urology","urologist","bladder","prostate","urinary","reproductive","obgyn","ob-gyn","obstetrics","gynecology","obstetrician","gynecologist","fertility","ivf","reproductive-health","reproductivehealth","prenatal","legal","lawyer","lawyers","attorney","attorneys","law","laws","lawfirm","paralegal","paralegals","legal-assistant","legalassistant","clerk","clerks","judge","judges","court","courts","courthouse","trial","trials","jury","litigation","litigator","litigators","lawsuit","lawsuits","case","cases","criminal","criminal-law","defense","defender","prosecution","prosecutor","civil","civil-law","tort","torts","injury","personal-injury","malpractice","corporate-law","corporatelaw","business-law","commercial","contracts","intellectual-property","ip","patent","patents","trademark","copyright","family-law","familylaw","divorce","custody","child-support","alimony","immigration","immigration-law","visa","visas","citizenship","naturalization","real-estate-law","property-law","estate","estates","probate","trusts","tax-law","taxlaw","irs","tax-attorney","taxattorney","audit","audits","employment-law","labor-law","hr-law","discrimination","harassment","constitutional","constitutional-law","civil-rights","human-rights","environmental-law","epa","regulation","regulations","compliance","bankruptcy","restructuring","insolvency","creditor","debtor","debt","education","educator","educators","teach","teaching","teacher","teachers","professor","professors","prof","profs","faculty","academic","academics","student","students","pupil","pupils","learner","learners","learning","school","schools","elementary","primary","middle-school","middleschool","high-school","highschool","secondary","k12","k-12","grade","grades","college","colleges","university","universities","uni","campus","campuses","undergraduate","undergrad","graduate","grad","postgrad","phd","doctorate","masters","bachelors","associates","degree","degrees","diploma","diplomas","curriculum","syllabus","course","courses","class","classes","lecture","seminar","seminars","workshop","workshops","lab","labs","laboratory","tutor","tutors","tutoring","mentor","mentors","mentoring","mentorship","homeschool","homeschooling","unschool","unschooling","montessori","waldorf","stem","steam","science","math","mathematics","calculus","algebra","english","literature","writing","grammar","composition","rhetoric","history","geography","social-studies","socialstudies","civics","economics","art","arts","music","drama","theater","theatre","dance","visual-arts","physical-education","pe","gym","athletics","sports","health","wellness","construction","contractor","contractors","builder","builders","building","carpenter","carpenters","carpentry","woodwork","woodworking","woodworker","electrician","electricians","electrical","electric","wiring","power","plumber","plumbers","plumbing","pipes","piping","drainage","sewage","hvac","heating","cooling","ac","air-conditioning","ventilation","duct","roofer","roofers","roofing","roof","roofs","shingles","gutters","mason","masons","masonry","brick","bricks","stone","concrete","cement","painter","painters","painting","paint","wallpaper","drywall","finishing","welder","welders","welding","fabrication","fabricator","metalwork","machinist","machinists","machining","lathe","mill","milling","turning","mechanic","mechanics","mechanical","automotive","auto","car-repair","landscaper","landscapers","landscaping","lawn","garden","gardening","surveyor","surveyors","surveying","survey","land","property","boundary","architect","architects","architecture","architectural","design","drafting","engineer","engineers","engineering","structural","civil-engineering","inspector","inspectors","inspection","code","codes","permit","permits","firefighter","firefighters","fire","fire-department","firedepartment","fd","police","police-officer","policeofficer","cop","cops","officer","officers","sheriff","sheriffs","deputy","deputies","detective","detectives","state-trooper","trooper","troopers","highway-patrol","patrol","patrolling","swat","tactical","k9","k-9","canine","bomb-squad","bombsquad","hostage","emt","emts","paramedic","paramedics","ambulance","ems","first-responder","dispatcher","dispatchers","dispatch","911","emergency","emergencies","search-rescue","sar","rescue","rescuer","rescuers","coast-guard","lifeguard","hazmat","hazardous","decon","decontamination","chemical","biological","military","armed-forces","armedforces","defense","defence","dod","mod","army","soldier","soldiers","infantry","armor","artillery","cavalry","navy","sailor","sailors","naval","fleet","submarine","surface","carrier","airforce","air-force","pilot","pilots","aviator","aviation","fighter","marines","marine","marinecorps","marine-corps","leatherneck","oorah","coastguard","coast-guard","uscg","maritime","port","harbor","border","spaceforce","space-force","ussf","space","satellite","orbital","launch","national-guard","nationalguard","guard","reserve","reserves","reservist","veteran","veterans","vet","vets","retired","retiree","retirees","officer","officers","enlisted","nco","warrant","general","admiral","special-ops","specialops","specops","sof","delta","seals","rangers","green-berets","greenberets","airborne","paratrooper","paratroopers","outdoor","outdoors","outside","nature","wilderness","wild","backcountry","hiking","hiker","hikers","backpacking","backpacker","thru-hike","thruhike","camping","camper","campers","campsite","tent","tenting","glamping","rv","rving","campervan","vanlife","van-life","overlanding","overland","fishing","fisher","fishers","angler","anglers","angling","fly-fishing","hunting","hunter","hunters","hunt","game","wildlife","deer","elk","duck","birding","birdwatching","bird-watching","birder","birders","ornithology","foraging","forager","foragers","mushroom","mushrooms","fungi","mycology","kayaking","kayak","kayaker","kayakers","canoeing","canoe","paddling","rafting","raft","rafts","whitewater","white-water","rapids","river","scuba","diving","diver","divers","snorkeling","snorkel","freediving","sailing","sailor","sailors","sail","sailboat","yacht","yachting","rock-climbing","rockclimbing","bouldering","climber","climbers","crag","mountaineering","mountaineer","alpinism","alpine","summit","peak-bagging","caving","caver","cavers","spelunking","spelunker","cave","caves","offroad","off-road","atv","utv","sxs","dirtbike","dirt-bike","quad","photography","photographer","photographers","photo","photos","camera","videography","videographer","video","videos","filming","filmmaking","painting","painter","painters","canvas","acrylic","oil","watercolor","drawing","drawer","drawers","sketch","sketching","pencil","charcoal","sculpting","sculptor","sculptors","sculpture","clay","pottery","ceramics","knitting","knitter","knitters","knit","yarn","wool","needles","pattern","crocheting","crochet","crocheter","hook","hooks","amigurumi","blanket","sewing","sewer","sewers","seamstress","tailor","fabric","quilting","embroidery","embroiderer","cross-stitch","crossstitch","needlepoint","woodworking","woodworker","woodworkers","carpentry","furniture","lathe","metalworking","metalworker","blacksmith","blacksmithing","forge","forging","leatherworking","leatherwork","leather","leathercraft","tanning","tooling","jewelry-making","jewelrymaking","jeweler","beading","beads","wirework","origami","paper-craft","papercraft","scrapbooking","scrapbook","cardmaking","calligraphy","calligrapher","lettering","hand-lettering","handlettering","candle-making","candlemaking","soap-making","soapmaking","bath-bombs","collecting","collector","collectors","collection","collections","collectible","stamps","stamp","philately","philatelist","postage","postal","letters","coins","coin","numismatics","numismatist","currency","bullion","precious","cards","card","trading-cards","tradingcards","tcg","ccg","mtg","pokemon-tcg","comics","comic","comic-books","comicbooks","graphic-novels","graphicnovels","manga","manhwa","manhua","webtoon","webtoons","light-novel","lightnovel","figurines","figure","figures","statue","statues","action-figures","toys","funko","funko-pop","funkopop","pop","pops","nendoroid","figma","sh-figuarts","model-kits","modelkits","gunpla","gundam","plamo","scale-models","miniatures","lego","legos","bricks","moc","mocs","afol","tfol","kfol","megabloks","antiques","antique","vintage","retro","thrift","thrifting","estate-sale","vinyl","records","record","lp","lps","turntable","audiophile","hifi","watches","watch","horology","horologist","timepiece","wristwatch","pocket","boardgame","boardgames","board-games","board-game","tabletop","table-top","cardgame","cardgames","card-games","card-game","deckbuilder","deck-builder","rpg","rpgs","tabletop-rpg","ttrpg","pen-and-paper","roleplay","roleplaying","dnd","d-and-d","dungeons-and-dragons","dungeonsanddragons","dungeon","dragon","pathfinder","starfinder","call-of-cthulhu","coc","shadowrun","cyberpunk-red","warhammer","warhammer40k","40k","age-of-sigmar","aos","sigmar","gw","warmachine","hordes","infinity","malifaux","necromunda","kill-team","killteam","miniature","miniatures","minis","mini","wargaming","wargames","wargamer","painting-minis","paintingminis","mini-painting","minipainting","terrain","chess","checkers","go","baduk","weiqi","shogi","mahjong","mah-jong","poker","blackjack","bridge","canasta","rummy","hearts","spades","solitaire","catan","settlers","ticket-to-ride","tickettoride","pandemic","wingspan","gloomhaven","spirit-island","spiritisland","terraforming-mars","scythe","pets","pet","petcare","pet-care","petowner","pet-owner","petparents","dogs","dog","puppy","puppies","pupper","doggo","doggos","canine","k9","cats","cat","kitten","kittens","kitty","kitties","feline","meow","birds","bird","parrot","parrots","parakeet","budgie","cockatiel","finch","fish","aquarium","aquariums","fishtank","fish-tank","freshwater","saltwater","reef","reeftank","reef-tank","coral","corals","marine","aquascape","reptiles","reptile","snake","snakes","lizard","lizards","gecko","bearded","turtle","turtles","tortoise","tortoises","terrapin","amphibian","frog","rabbit","rabbits","bunny","bunnies","hare","lagomorph","binky","binkies","hamster","hamsters","gerbil","gerbils","mouse","mice","rat","rats","guinea-pig","guineapig","guinea","cavy","cavies","chinchilla","ferret","horse","horses","equine","equestrian","pony","ponies","riding","stable","farm","farming","farmlife","farm-life","livestock","chicken","chickens","goat","goats","sheep","lamb","lambs","pig","pigs","cow","cows","cattle","english","spanish","espanol","french","francais","german","deutsch","italian","italiano","portuguese","portugues","russian","russkiy","japanese","nihongo","chinese","mandarin","cantonese","zhongwen","korean","hangul","hangugeo","arabic","hindi","urdu","bengali","turkish","turkce","persian","farsi","dutch","nederlands","polish","swedish","svenska","norwegian","norsk","danish","dansk","finnish","greek","ellinika","hebrew","ivrit","vietnamese","tiengviet","thai","indonesian","bahasa","malay","tagalog","filipino","swahili","kiswahili","czech","cestina","hungarian","magyar","romanian","romana","ukrainian","usa","united-states","unitedstates","america","american","americans","canada","canadian","canadians","mexico","mexican","mexicans","brasil","brazil","brazilian","argentina","argentine","chile","chilean","peru","colombia","colombian","venezuela","venezuelan","ecuador","uruguay","uk","united-kingdom","unitedkingdom","britain","british","england","scotland","scottish","wales","welsh","ireland","irish","northern-ireland","france","french","germany","german","germans","italy","italian","italians","spain","spanish","portugal","portuguese","netherlands","dutch","belgium","switzerland","swiss","austria","austrian","poland","polish","czech","russia","russian","russians","ukraine","ukrainian","ukrainians","belarus","china","chinese","taiwan","taiwanese","hongkong","hong-kong","macau","japan","japanese","korea","korean","koreans","north-korea","south-korea","india","indian","indians","pakistan","pakistani","bangladesh","bangladeshi","australia","australian","australians","aussie","aussies","nz","newzealand","new-zealand","kiwi","kiwis","fiji","fijian","samoa","samoan","tonga","philippines","filipino","filipinos","pinoy","pinay","vietnam","vietnamese","thailand","thai","thais","indonesia","indonesian","malaysia","malaysian","singapore","singaporean","brunei","myanmar","burmese","cambodia","cambodian","laos","laotian","nepal","nepali","srilanka","sri-lanka","srilankan","egypt","egyptian","egyptians","morocco","moroccan","algeria","algerian","tunisia","tunisian","libya","libyan","sudan","sudanese","ethiopia","kenya","kenyan","kenyans","tanzania","tanzanian","uganda","ugandan","nigeria","nigerian","nigerians","ghana","ghanaian","senegal","senegalese","southafrica","south-africa","southafrican","south-african","namibia","botswana","zimbabwe","zambia","mozambique","angola","congo","congolese","israel","israeli","israelis","palestine","palestinian","palestinians","jordan","jordanian","lebanon","lebanese","syria","syrian","iraq","iraqi","iran","iranian","iranians","persian","persians","saudi","saudi-arabia","uae","emirates","emirati","dubai","abudhabi","abu-dhabi","qatar","qatari","kuwait","kuwaiti","bahrain","bahraini","oman","omani","yemen","yemeni","turkey","turkish","turks","greece","greek","greeks","cyprus","cypriot","scandinavia","scandinavian","nordic","norway","norwegian","sweden","swedish","denmark","danish","finland","finnish","finns","iceland","icelandic","baltics","baltic","estonia","estonian","latvia","latvian","lithuania","balkans","balkan","serbia","serbian","croatia","croatian","bosnia","slovenia","slovenian","macedonia","macedonian","albania","albanian","romania","romanian","bulgaria","bulgarian","hungary","hungarian","slovakia","slovak","slovakian","moldova","moldovan","georgia","georgian","armenia","armenian","azerbaijan","azerbaijani","kazakhstan","kazakh","uzbekistan","uzbek","turkmenistan","kyrgyzstan","tajikistan","mongolia","caribbean","jamaica","jamaican","bahamas","bahamian","barbados","trinidad","cuba","cuban","haiti","haitian","dominican","puerto-rico","puertorico","latin","latino","latina","latinx","hispanic","latinoamerica","latam","california","cali","ca","socal","norcal","bayarea","bay-area","la","texas","tx","houston","dallas","austin","sanantonio","san-antonio","florida","fl","miami","orlando","tampa","jacksonville","fortlauderdale","newyork","new-york","ny","nyc","brooklyn","manhattan","queens","bronx","pennsylvania","pa","philly","philadelphia","pittsburgh","harrisburg","illinois","il","chicago","chi","chiraq","chitown","springfield","ohio","oh","cleveland","columbus","cincinnati","toledo","akron","georgia","ga","atlanta","atl","savannah","augusta","macon","northcarolina","north-carolina","nc","charlotte","raleigh","durham","southcarolina","south-carolina","sc","charleston","columbia","greenville","michigan","mi","detroit","annarbor","ann-arbor","grandrapids","lansing","newjersey","new-jersey","nj","jersey","newark","trenton","atlantic-city","virginia","va","richmond","norfolk","vb","virginia-beach","alexandria","washington","wa","seattle","tacoma","spokane","olympia","bellevue","arizona","az","phoenix","phx","tucson","scottsdale","mesa","tempe","massachusetts","ma","boston","cambridge","worcester","springfield","tennessee","tn","nashville","memphis","knoxville","chattanooga","indiana","in","indianapolis","indy","fortwayne","fort-wayne","southbend","missouri","mo","stlouis","st-louis","kansascity","kansas-city","springfield","maryland","md","baltimore","bmore","annapolis","bethesda","rockville","wisconsin","wi","milwaukee","madison","greenbay","green-bay","kenosha","colorado","co","denver","boulder","coloradosprings","colorado-springs","minnesota","mn","minneapolis","stpaul","st-paul","twincities","twin-cities","alabama","al","birmingham","montgomery","mobile","huntsville","tuscaloosa","louisiana","la","neworleans","new-orleans","nola","batonrouge","baton-rouge","kentucky","ky","louisville","lexington","bowling-green","frankfort","oregon","or","portland","pdx","eugene","salem","bend","medford","oklahoma","ok","okc","oklahomacity","oklahoma-city","tulsa","norman","connecticut","ct","hartford","newhaven","new-haven","stamford","bridgeport","utah","ut","saltlakecity","salt-lake-city","slc","provo","ogden","iowa","ia","desmoines","des-moines","cedarrapids","cedar-rapids","davenport","nevada","nv","lasvegas","las-vegas","vegas","reno","henderson","sparks","arkansas","ar","littlerock","little-rock","fayetteville","fortsmith","mississippi","ms","jackson","gulfport","biloxi","hattiesburg","southaven","kansas","ks","wichita","overlandpark","overland-park","kansascity","topeka","newmexico","new-mexico","nm","albuquerque","santafe","santa-fe","lascruces","nebraska","ne","omaha","lincoln","bellevue","grandisland","grand-island","idaho","id","boise","meridian","nampa","idahofalls","idaho-falls","pocatello","westvirginia","west-virginia","wv","charleston","huntington","morgantown","hawaii","hi","honolulu","maui","oahu","kauai","bigisland","big-island","newhampshire","new-hampshire","nh","manchester","nashua","concord","portsmouth","maine","me","portland","lewiston","bangor","auburn","augusta","rhodeisland","rhode-island","ri","providence","warwick","cranston","newport","montana","mt","billings","missoula","greatfalls","great-falls","bozeman","delaware","de","wilmington","dover","newark","middletown","smyrna","southdakota","south-dakota","sd","siouxfalls","sioux-falls","rapidcity","northdakota","north-dakota","nd","fargo","bismarck","grandforks","grand-forks","alaska","ak","anchorage","fairbanks","juneau","sitka","ketchikan","vermont","vt","burlington","essex","rutland","colchester","bennington","wyoming","wy","cheyenne","casper","laramie","gillette","rocksprings","dc","washingtondc","washington-dc","dmv","nova","northern-virginia","puertorico","puerto-rico","pr","sanjuan","san-juan","bayamon","carolina","midwest","midwestern","northeast","northeastern","southeast","southeastern","southwest","southwestern","northwest","northwestern","pacificnorthwest","pnw","newengland","new-england","deepouth","deep-south","sunbelt","sun-belt","rustbelt","rust-belt","biblebelt","bible-belt","cornbelt","corn-belt"];async function Jo(e){const t=function(e){let t=e.startsWith("#")?e.slice(1):e;return t=t.toLowerCase().replace(/[^a-z0-9-]/g,""),t=t.replace(/-+/g,"-"),t=t.replace(/^-+|-+$/g,""),t}(e);if(!t)throw new Error(`Invalid channel name: "${e}" filters to empty string`);const a=`#${t}`,n=(new TextEncoder).encode(a),r=(await Bo(n)).slice(0,16),s=(await Bo(r))[0],o=new Uint8Array(32);return o.set(r),{name:`#${t}`,channelHash:s,aesKey:r,hmacKey:o,autoDiscovered:!0}}let Ko=null,Xo=null;const Yo=new Map;let Qo=null;const Zo="pymc_discovered_channels";function ei(e){Yo.set(e.channelHash,e),e.autoDiscovered&&function(){try{const e=[];for(const t of Yo.values())t.autoDiscovered&&e.push({name:t.name,hash:t.channelHash});localStorage.setItem(Zo,JSON.stringify(e))}catch(e){console.warn("[ChannelKeys] Failed to save stored channels:",e)}}()}async function ti(){Ko||(Xo||(Xo=(async()=>{await async function(){try{const e=localStorage.getItem(Zo);if(!e)return;const t=JSON.parse(e);for(const{name:a}of t)try{const e=await Jo(a);Yo.set(e.channelHash,e)}catch{}t.length>0&&t.length}catch(e){console.warn("[ChannelKeys] Failed to load stored channels:",e)}}();const e=await async function(){const{default:e}=await A(async()=>{const{default:e}=await import("./generated-geo-channels-CkSMgZLG.js");return{default:e}},[]);return[...Go,...e]}(),t=new Map;for(const a of e)try{const e=await Jo(a),n=t.get(e.channelHash)||[];n.push(e),t.set(e.channelHash,n)}catch{}Ko=t,e.length,t.size})()),await Xo)}async function ai(e,t,a){const n=await async function(e,t){if(vo())try{const a=new ArrayBuffer(e.length);new Uint8Array(a).set(e);const n=new ArrayBuffer(t.length);new Uint8Array(n).set(t);const r=await crypto.subtle.importKey("raw",a,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),s=await crypto.subtle.sign("HMAC",r,n);return new Uint8Array(s)}catch{}return async function(e,t){const a=64;let n;e.length>a?(n=new Uint8Array(a),n.set(Fo(e))):(n=new Uint8Array(a),n.set(e));const r=new Uint8Array(a),s=new Uint8Array(a);for(let c=0;c=2024&&a<=2030;if(!n)return{valid:!1,confidence:"low"};const r=e.slice(5);if(0===r.length)return{valid:!1,confidence:"low"};let s=0,o=!1;for(let l=0;l=32&&e<=126||0===e||10===e||13===e||9===e)&&s++,58===e&&(o=!0)}const i=s/r.length;return i>=.85&&o&&n?{valid:!0,confidence:"high"}:i>=.7&&n?{valid:!0,confidence:"medium"}:{valid:!1,confidence:"low"}}async function ri(e,t,a){await ti();const n=await async function(){return Qo||(Qo=await async function(e,t=!1){const a=bo(e.secret),n=(await Bo(a))[0],r=new Uint8Array(32);return r.set(a.slice(0,32)),{name:e.name,channelHash:n,aesKey:r.slice(0,16),hmacKey:r,autoDiscovered:t}}(Vo)),Qo}();if(n.channelHash===e&&await ai(n.hmacKey,t,a))return{channelName:"Public",plaintext:Po(n.aesKey,a),keys:n};const r=Yo.get(e);if(r&&await ai(r.hmacKey,t,a)){const e=Po(r.aesKey,a);return{channelName:r.name,plaintext:e,keys:r}}const s=(null==Ko?void 0:Ko.get(e))||[],o=[];for(const l of s){if(await ai(l.hmacKey,t,a)){ei(l);const e=Po(l.aesKey,a);return{channelName:l.name,plaintext:e,keys:l}}o.push(l)}let i=null;for(const l of o)try{const e=Po(l.aesKey,a),t=ni(e);if(t.valid){if("high"===t.confidence)return{channelName:l.name,plaintext:e,keys:l,macCorrupted:!0};"medium"!==t.confidence||i||(i={keys:l,plaintext:e,confidence:"medium"})}}catch{}return i?{channelName:i.keys.name,plaintext:i.plaintext,keys:i.keys,macCorrupted:!0}:null}async function si(e){return await ti(),((null==Ko?void 0:Ko.get(e))||[]).map(e=>e.name)}async function oi(e,t,a,n){try{const r=await Jo(e);if(r.channelHash!==t)return{success:!1,error:`Hash mismatch: "${e}" has hash 0x${r.channelHash.toString(16).toUpperCase().padStart(2,"0")}, packet has 0x${t.toString(16).toUpperCase().padStart(2,"0")}`};if(!(await ai(r.hmacKey,a,n)))return{success:!1,error:"MAC verification failed - wrong channel name or corrupted data"};const s=Po(r.aesKey,n);return ei(r),{success:!0,result:{channelName:r.name,plaintext:s,keys:r}}}catch(r){return{success:!1,error:`Error: ${r instanceof Error?r.message:String(r)}`}}}let ii=null,li=[];function ci(e){return{decoded:e.success?{type:"grp_txt",channelHash:e.channelHash,channelName:e.channelName,text:e.text??"",decrypted:!0,senderName:e.senderName,timestamp:e.timestamp,flags:e.flags,macCorrupted:e.macCorrupted,isPublicHashChannel:!0}:null,timestamp:e.packetTimestamp,rssi:e.rssi,snr:e.snr}}const di=F((e,t)=>{let a=!1;return{messages:new Map,stableMessages:new Map,lastSnapshotUpdate:0,processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1},initialDecodeComplete:!1,_successCount:0,queueDecryption:async(n,r)=>{const{messages:s,processing:o}=t(),i=(null==r?void 0:r.quickMode)??!1;let l=n.filter(e=>(e.type??e.payload_type)===Un.GRP_TXT&&e.raw_packet&&!s.has(e.packet_hash)&&!o.has(e.packet_hash));if(0===l.length)return;if(i&&l.length>100&&(l=l.sort((e,t)=>(t.timestamp??0)-(e.timestamp??0)).slice(0,100)),a){const e=new Set(li.map(e=>e.packet_hash)),t=l.filter(t=>!e.has(t.packet_hash));return void(t.length>0&&(li.push(...t),t.length))}a=!0;const c=new Set(l.map(e=>e.packet_hash));e(e=>({processing:new Set([...e.processing,...c]),progress:{total:l.length,processed:0,percent:0,isDecoding:!0}}));try{const{totalCount:a}=await fo.decrypt(l,{onProgress:(t,a)=>{e({progress:{total:a,processed:t,percent:Math.round(t/a*100),isDecoding:!0}})},onResults:a=>{const{messages:n}=t();let r=0;for(const e of a)n.set(e.packetHash,ci(e)),e.success&&!e.macCorrupted&&r++;e(e=>({messages:n,_successCount:e._successCount+r})),ii&&clearTimeout(ii),ii=setTimeout(()=>{e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now()})},500)}});ii&&(clearTimeout(ii),ii=null);const n=t().messages;if(n.size>5e4){const e=Array.from(n.entries()).sort((e,t)=>e[1].timestamp-t[1].timestamp).slice(0,n.size-5e4);for(const[t]of e)n.delete(t)}if(e({messages:n,stableMessages:new Map(n),lastSnapshotUpdate:Date.now(),processing:new Set,initialDecodeComplete:!0,progress:{total:a,processed:a,percent:100,isDecoding:!1}}),li.length>0){const e=li;li=[],e.length,setTimeout(()=>{t().queueDecryption(e)},50)}}catch(d){console.error("[DecodedMessages] Worker decryption failed:",d),e({processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1}})}finally{a=!1}},queueChannelDecryption:async(n,r)=>{const{messages:s,processing:o}=t(),i=await async function(e){const t=await async function(e){return Jo(e.startsWith("#")?e.slice(1):e)}(e);return{name:t.name,channelHash:t.channelHash,aesKeyHex:yo(t.aesKey),hmacKeyHex:yo(t.hmacKey)}}(r),l=n.filter(e=>{if((e.type??e.payload_type)!==Un.GRP_TXT||!e.raw_packet)return!1;if(s.has(e.packet_hash)||o.has(e.packet_hash))return!1;const t=e.raw_packet;if(t.length<4)return!1;const a=3&parseInt(t.slice(0,2),16);let n=2;return 0!==a&&3!==a||(n=10),n+=2+2*parseInt(t.slice(n,n+2),16),parseInt(t.slice(n,n+2),16)===i.channelHash});if(0===l.length)return;if(a)return;a=!0;const c=new Set(l.map(e=>e.packet_hash));e(e=>({processing:new Set([...e.processing,...c]),progress:{total:l.length,processed:0,percent:0,isDecoding:!0}}));try{l.length;const{totalCount:a}=await fo.decrypt(l,{knownKey:i,onProgress:(t,a)=>{e({progress:{total:a,processed:t,percent:Math.round(t/a*100),isDecoding:!0}})},onResults:a=>{const{messages:n}=t();let r=0;for(const e of a)n.set(e.packetHash,ci(e)),e.success&&!e.macCorrupted&&r++;e(e=>({messages:n,_successCount:e._successCount+r})),ii&&clearTimeout(ii),ii=setTimeout(()=>{e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now()})},500)}});ii&&(clearTimeout(ii),ii=null),e({stableMessages:new Map(t().messages),lastSnapshotUpdate:Date.now(),processing:new Set,progress:{total:a,processed:a,percent:100,isDecoding:!1}})}catch(d){console.error("[DecodedMessages] Fast-path decryption failed:",d),e({processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1}})}finally{a=!1}},getMessage:e=>t().messages.get(e),getSuccessfulMessages:()=>{var e;const{messages:a}=t(),n=[];for(const t of a.values())(null==(e=t.decoded)?void 0:e.decrypted)&&!t.decoded.macCorrupted&&n.push(t);return n.sort((e,t)=>e.timestamp-t.timestamp)},clear:()=>{ii&&(clearTimeout(ii),ii=null),e({messages:new Map,stableMessages:new Map,lastSnapshotUpdate:0,processing:new Set,progress:{total:0,processed:0,percent:0,isDecoding:!1},initialDecodeComplete:!1,_successCount:0})}}});function ui(e){return di(t=>t.messages.get(e))}function hi(){return di(e=>e.progress)}function mi(){return di(e=>e.initialDecodeComplete)}function gi(){return di(e=>e.stableMessages)}function pi(){return di(e=>e.stableMessages)}const fi=Object.freeze(Object.defineProperty({__proto__:null,hasAttemptedPacket:function(e){return di.getState().messages.has(e)},useAttemptedPackets:pi,useDecodedMessage:ui,useDecodedMessageCount:function(){return di(e=>e._successCount)},useDecodedMessagesStore:di,useDecryptionProgress:hi,useInitialDecodeComplete:mi,useStableMessages:gi},Symbol.toStringTag,{value:"Module"})),bi=[{label:"20m",minutes:20,buckets:80},{label:"1h",minutes:60,buckets:80},{label:"3h",minutes:180,buckets:80},{label:"12h",minutes:720,buckets:80},{label:"24h",minutes:1440,buckets:80},{label:"3d",minutes:4320,buckets:80},{label:"7d",minutes:10080,buckets:80},{label:"14d",minutes:20160,buckets:80},{label:"21d",minutes:30240,buckets:80},{label:"30d",minutes:43200,buckets:80},{label:"90d",minutes:129600,buckets:80}],yi=[{label:"1h",hours:1},{label:"3h",hours:3},{label:"12h",hours:12},{label:"24h",hours:24},{label:"3d",hours:72},{label:"7d",hours:168},{label:"14d",hours:336},{label:"21d",hours:504},{label:"30d",hours:720},{label:"90d",hours:2160}];function wi(e,t=12){return Math.max(t,Math.round(e/15))}const Ci={hero:wi(1200),statsCard:wi(380)};function ki(e){switch(e){case 1:return 3600;case 3:case 12:return 5400;case 24:return 8640;case 72:case 168:case 336:case 504:case 720:case 2160:return 720;default:{const t=3600*e,a=Math.round(t/10);return Math.min(Math.max(360,a),720)}}}const vi="'JetBrains Mono', 'SF Mono', Monaco, monospace",Di={stats:3e3,logs:2e3,system:3e3},Ai={DEBUG:"text-sys-orange",INFO:"text-sys-cyan",WARNING:"text-sys-amber",ERROR:"text-sys-red",CRITICAL:"text-sys-pink"};function xi(e){return Ai[e]??"text-fg-muted border-edge-subtle"}function Ei(e){return e?(e.startsWith("0x")?e.slice(2):e).slice(0,2).toUpperCase():""}function Fi(e,t){if(!e)return"expired";const a=t/1e3-e;return a<=10800?"active":a<=86400?"stale":"expired"}function Bi(e,t,a=Date.now()){if(!e)return[];const n=Object.keys(e);if(0===n.length)return[];const r=[];for(let s=0;st.count!==e.count?t.count-e.count:t.lastSeen-e.lastSeen),r}const ji={critical:0,high:150,medium:300,low:450};let Si=!1;const Mi=[],Ni=new Set;function Li(e,t="medium"){if(Si){const a=setTimeout(()=>{e(),Ni.delete(a)},ji[t]);return Ni.add(a),()=>{clearTimeout(a),Ni.delete(a)}}{const a={callback:e,priority:t};return Mi.push(a),()=>{const e=Mi.indexOf(a);-1!==e&&Mi.splice(e,1)}}}let Ti;function _i(e){Ti=e}const Ri=F((e,t)=>({hardwareStats:null,hardwareStatsLoading:!1,hardwareStatsError:null,resourceHistory:[],lastResourceFetch:0,fetchHardwareStats:async()=>{try{const a=await Os();if(a.success&&a.data){const n=a.data;e({hardwareStats:n,hardwareStatsLoading:!1,hardwareStatsError:null});const r=80;t().addResourceDataPoint(n.cpu.usage_percent,n.memory.usage_percent,r)}else e({hardwareStatsError:a.error??"Failed to fetch hardware stats",hardwareStatsLoading:!1})}catch(a){e({hardwareStatsError:a instanceof Error?a.message:"Failed to fetch hardware stats",hardwareStatsLoading:!1})}},addResourceDataPoint:(a,n,r)=>{const s=Date.now(),{lastResourceFetch:o,resourceHistory:i}=t();if(s-o<1e3)return;const l={timestamp:s,time:new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}),cpu:a,memory:n};let c;i.length>=r?(c=i.slice(1),c.push(l)):c=[...i,l],e({resourceHistory:c,lastResourceFetch:s})},initialize:()=>{t().fetchHardwareStats();const e=setInterval(()=>{"undefined"!=typeof document&&document.hidden||t().fetchHardwareStats()},Di.system);return()=>{clearInterval(e)}}})),zi=Ri,Pi=()=>Ri(e=>e.hardwareStats),Ii=()=>Ri(e=>e.hardwareStatsLoading),$i=()=>Ri(e=>e.hardwareStatsError),qi=()=>Ri(e=>e.resourceHistory),Oi=()=>Ri(e=>e.fetchHardwareStats);function Hi(e){return e.startsWith("0x")||e.startsWith("0X")?e.slice(2,4).toUpperCase():e.slice(0,2).toUpperCase()}function Wi(e,t){let a=e.forwarded_path??e.original_path;if("string"==typeof a)try{a=JSON.parse(a)}catch{return null}if(!a||!Array.isArray(a)||0===a.length)return null;const n=a.map(e=>String(e).toUpperCase()),r=t?Hi(t):null,s=n[n.length-1],o=null!==r&&s===r,i=o?n.slice(0,-1):[...n];return{effective:i,original:n,hadLocal:o,effectiveLength:i.length}}function Ui(e,t){let a=e;if("string"==typeof a)try{a=JSON.parse(a)}catch{return null}if(!a||!Array.isArray(a)||0===a.length)return null;const n=a.map(e=>String(e).toUpperCase()),r=t?Hi(t):null,s=n[n.length-1],o=null!==r&&s===r,i=o?n.slice(0,-1):[...n];return{effective:i,original:n,hadLocal:o,effectiveLength:i.length}}function Vi(e,t){return t-e}function Gi(e,t){const a=e.toUpperCase();return t.startsWith("0x")||t.startsWith("0X")?t.slice(2).toUpperCase().startsWith(a):t.toUpperCase().startsWith(a)}function Ji(e){return 4===(e.type??e.payload_type)&&!0!==e.transmitted&&function(e){if(null!=e._isZeroHop)return e._isZeroHop;const t=function(e){if(Array.isArray(e))return e;if("string"==typeof e&&e.startsWith("["))try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}return[]}(e.original_path),a=e.route??e.route_type;return it(a)?0===t.length:ot(a)?t.length<=1:0===t.length}(e)}function Ki(e,t,a,n){if(!e)return null;let r=e;if(e.length<=4){const n=e.replace(/^0x/i,"").toUpperCase();if(n===t)return null;const s=a.get(n);if(!s)return null;r=s}return n.has(r)?Hi(r)===t?null:r:null}function Xi(e,t){e.count++,void 0!==t.rssi&&null!==t.rssi&&(e.rssiSum+=t.rssi,e.rssiCount++),void 0!==t.snr&&null!==t.snr&&(e.snrSum+=t.snr,e.snrCount++);const a=t.timestamp??0;a>e.lastSeen&&(e.lastSeen=a)}function Yi(e){return{hash:e,count:0,rssiSum:0,rssiCount:0,snrSum:0,snrCount:0,lastSeen:0}}function Qi(e,t){const a=function(e,t){const a=t-1e3*e;return a<=6048e5?"active":a<=12096e5?"stale":"expired"}(e.lastSeen,t);return"expired"===a?null:{hash:e.hash,prefix:Hi(e.hash),count:e.count,avgRssi:e.rssiCount>0?e.rssiSum/e.rssiCount:null,avgSnr:e.snrCount>0?e.snrSum/e.snrCount:null,lastSeen:e.lastSeen,status:a}}const Zi="pymc-hidden-contacts",el="pymc-quick-neighbors",tl="pymc-local-hash",al="pymc-global-time-range";let nl=null;function rl(){if("undefined"==typeof window)return[];try{const e=localStorage.getItem(el);if(e)return JSON.parse(e)}catch{}return[]}function sl(e){"undefined"!=typeof window&&(nl&&clearTimeout(nl),nl=setTimeout(()=>{try{localStorage.setItem(el,JSON.stringify(e))}catch{}nl=null},1e3))}function ol(){if("undefined"!=typeof window)try{const e=localStorage.getItem(tl);if(e)return e}catch{}}function il(e){if("undefined"!=typeof window)try{localStorage.setItem(tl,e)}catch{}}function ll(){if("undefined"==typeof window)return new Set;try{const e=localStorage.getItem(Zi);if(e)return new Set(JSON.parse(e))}catch{}return new Set}function cl(){if("undefined"==typeof window)return 4;try{const e=localStorage.getItem(al);if(e){const t=parseInt(e,10);if(!isNaN(t)&&t>=0&&t<=10)return t>4?4:t}}catch{}return 4}function dl(e,t){"undefined"!=typeof window&&"requestIdleCallback"in window?requestIdleCallback(()=>e(),{timeout:t}):setTimeout(e,100)}function ul(e,t=200,a=1500){let n=0,r=0;return()=>{const s=Date.now();s-n>=t&&(n=s,e({lastPacketTimestamp:Nr.getNewestTimestamp()})),s-r>=a&&(r=s,e({packets:Nr.getPackets()}))}}function hl(e,t,a={}){const{idleTimeout:n=2e3,decryptMode:r="full",includeAnimationReady:s=!1}=a;0!==t.length&&(pn.active&&pn.emit("cascade:hydrate",{packetCount:t.length,decryptMode:r}),dl(()=>e().triggerTopologyCompute(),n),dl(()=>e().triggerSparklineCompute(),Math.max(n-1e3,500)),s&&setTimeout(()=>function(){if(!Si){Si=!0;for(const e of Mi){const t=ji[e.priority],a=setTimeout(()=>{e.callback(),Ni.delete(a)},t);Ni.add(a)}Mi.length=0}}(),16),"quick"===r?setTimeout(()=>{di.getState().queueDecryption(t)},500):"full"===r&&dl(()=>{di.getState().queueDecryption(t)},n),Ps())}const ml={"3d":{load:e=>Nr.loadTier("3d",e),idleTimeout:2e3},"7d":{load:e=>Nr.loadTier("7d",e),idleTimeout:2e3},"14d":{load:e=>Nr.loadTier("14d",e),idleTimeout:5e3},"21d":{load:e=>Nr.loadTier("21d",e),idleTimeout:5e3},"30d":{load:e=>Nr.loadTier("30d",e),idleTimeout:8e3},"90d":{load:e=>Nr.loadTier("90d",e),idleTimeout:1e4}},gl={5:"3d",6:"7d",7:"14d",8:"21d",9:"30d",10:"90d"},pl=F((e,t)=>({stats:null,statsLoading:!1,statsError:null,packets:Nr.getPackets(),packetsLoading:!1,packetsError:null,lastPacketTimestamp:Nr.getNewestTimestamp(),logs:[],logsLoading:!1,liveMode:!0,flashReceived:0,flashAdvert:0,pendingAdvertLocalHash:null,pendingAdvertTimestamp:null,hiddenContacts:ll(),quickNeighbors:rl(),cachedLocalHash:ol(),initialized:!1,packetCacheState:Nr.getState(),mutationsInFlight:new Set,globalTimeRangeIndex:cl(),initializeApp:async()=>{const{initialized:a}=t();if(a)return;e({initialized:!0,statsLoading:!0,packetsLoading:!0}),Nr.subscribe(t=>{e({packetCacheState:t})});const{hiddenContacts:n}=t(),r=ul(e,50,1500);Ls().then(t=>{const a=Bi(t.neighbors,n),r=t.local_hash;e({stats:t,statsLoading:!1,quickNeighbors:a,cachedLocalHash:r}),sl(a),r&&il(r)}).catch(t=>{e({statsError:t instanceof Error?t.message:"Failed to fetch stats",statsLoading:!1})}),Nr.initialLoad(r).then(a=>{if(a.length>0){const n=Nr.getNewestTimestamp();e({packets:a,packetsLoading:!1,lastPacketTimestamp:n}),hl(t,a,{idleTimeout:2e3,decryptMode:"quick",includeAnimationReady:!0})}else e({packetsLoading:!1})}).catch(t=>{e({packetsError:t instanceof Error?t.message:"Failed to load packets",packetsLoading:!1})}),ao.getState().initialize();let s=null,o=Nr.getPacketCount();fn.onPacket(a=>{const{lastPacketTimestamp:n,mutationsInFlight:r}=t();if(r.size>0)return;Nr.mergePacketsDirectly([a]),pn.active&&pn.emit("store:packets:ws-merge",{hash:a.packet_hash});const i=a.timestamp??0;i>n&&(e({lastPacketTimestamp:i}),s||(s=setTimeout(()=>{if(s=null,!Nr.isHeavyLoadInProgress()){const a=Nr.getPacketCount();if(a!==o){o=a;const n=Nr.getPackets();e({packets:n,flashReceived:t().flashReceived+1}),Ps()}}},500))),di.getState().queueDecryption([a])}),fn.onStats(a=>{const{mutationsInFlight:n,hiddenContacts:r}=t();if(n.size>0)return;const s=Bi(a.neighbors,r),o=a.local_hash,i=t().quickNeighbors;s.length!==i.length||s.some((e,t)=>{var a;return e.hash!==(null==(a=i[t])?void 0:a.hash)})?(e({stats:a,statsLoading:!1,statsError:null,quickNeighbors:s,cachedLocalHash:o}),sl(s)):e({stats:a,statsLoading:!1,statsError:null,cachedLocalHash:o}),o&&il(o)}),fn.onPacketStats(a=>{const{stats:n,mutationsInFlight:r}=t();if(!n||r.size>0)return;const s={...n,rx_count:a.rx_count??n.rx_count,tx_count:a.tx_count??n.tx_count,forwarded_count:a.forwarded_count??n.forwarded_count,dropped_count:a.dropped_count??n.dropped_count};e({stats:s})});const i=function(e){const t=setInterval(()=>{Nr.isHeavyLoadInProgress()||e().mutationsInFlight.size>0||e().fetchStats().then(()=>{ks.getState().updateRestHealth(!0)}).catch(()=>{ks.getState().updateRestHealth(!1)})},Di.stats);let a,n=!0;if(function t(){if(!n)return;const a=fn.isConnected()?15e3:3e3;setTimeout(async()=>{n&&(e().liveMode&&!Nr.isHeavyLoadInProgress()&&await e().fetchPackets(),t())},a)}(),"undefined"!=typeof document){let t=Date.now();const n=3e5,r=async()=>{if(document.hidden)t=Date.now();else{const a=Date.now()-t,r=a>n;Math.round(a/1e3),r&&(fn.resetSupported(),fn.isConnected()?await fn.verifyConnection(3e3)||(console.warn("[useStore] WS stale after wake, reconnecting..."),fn.disconnect(),fn.connect()):fn.isSupported()&&fn.connect()),e().fetchStats({force:!0}),e().fetchPackets()}};document.addEventListener("visibilitychange",r),a=()=>document.removeEventListener("visibilitychange",r)}return()=>{clearInterval(t),n=!1,null==a||a()}}(t),l=zi.getState().initialize();Ol=()=>{i(),l()}},prefetchForRoute:e=>{switch(e){case"/logs":Ts().catch(()=>{});break;case"/system":Os().catch(()=>{});break;case"/statistics":(async function(e=24){return Fs(`/api/packet_type_graph_data?hours=${e}`)})(3).catch(()=>{}),Rs(3).catch(()=>{});break;case"/settings":(async function(){return Fs("/api/radio_presets")})().catch(()=>{})}},fetchStats:async a=>{const{stats:n,mutationsInFlight:r,hiddenContacts:s}=t();if(r.size>0&&!(null==a?void 0:a.force))return;n||e({statsLoading:!0}),e({statsError:null});const o=performance.now();try{const a=await Ls();pn.active&&pn.emit("transport:rest:stats",{durationMs:performance.now()-o,ok:!0});const n=Bi(a.neighbors,s),r=a.local_hash,i=t().quickNeighbors;n.length!==i.length||n.some((e,t)=>{var a;return e.hash!==(null==(a=i[t])?void 0:a.hash)})?(e({stats:a,statsLoading:!1,quickNeighbors:n,cachedLocalHash:r}),sl(n)):e({stats:a,statsLoading:!1,cachedLocalHash:r}),r&&il(r)}catch(i){pn.active&&pn.emit("transport:rest:stats",{durationMs:performance.now()-o,ok:!1}),e({statsError:i instanceof Error?i.message:"Failed to fetch stats",statsLoading:!1})}},fetchPackets:async()=>{const{packets:a,lastPacketTimestamp:n}=t();0===a.length&&e({packetsLoading:!0}),e({packetsError:null});const r=performance.now();try{const a=await Nr.poll();if(pn.active&&pn.emit("transport:rest:packets",{durationMs:performance.now()-r,count:a}),a>0){const r=Nr.getPackets(),s=Nr.getNewestTimestamp();s>n&&n>0&&(e({flashReceived:t().flashReceived+1}),Ps()),e({packets:r,packetsLoading:!1,lastPacketTimestamp:s||n}),di.getState().queueDecryption(r),a>50&&n>0&&hl(t,r,{idleTimeout:500,decryptMode:"skip"})}else e({packetsLoading:!1})}catch(s){e({packetsError:s instanceof Error?s.message:"Failed to fetch packets",packetsLoading:!1})}},fetchLogs:async()=>{const{logs:a}=t();0===a.length&&e({logsLoading:!0});try{const t=await Ts();e({logs:t.logs,logsLoading:!1})}catch{e({logsLoading:!1})}},setLiveMode:t=>{e({liveMode:t})},setMode:async a=>{const n="setMode",{mutationsInFlight:r}=t(),s=new Set(r);s.add(n),e({mutationsInFlight:s});try{if(!(await Vs(a)).success)throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}catch(o){const{mutationsInFlight:a}=t(),r=new Set(a);throw r.delete(n),e({mutationsInFlight:r}),o}},clearModeMutation:()=>{const{mutationsInFlight:a}=t(),n=new Set(a);n.delete("setMode"),e({mutationsInFlight:n})},setDutyCycle:async a=>{const n="setDutyCycle",{mutationsInFlight:r}=t(),s=new Set(r);s.add(n),e({mutationsInFlight:s});try{if(!(await Gs(a)).success)throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}finally{const{mutationsInFlight:a}=t(),r=new Set(a);r.delete(n),e({mutationsInFlight:r})}},setDutyCycleConfig:async a=>{var n;const r="setDutyCycleConfig",{mutationsInFlight:s}=t(),o=new Set(s);o.add(r),e({mutationsInFlight:o});try{const e=await async function(e){return Fs("/api/update_duty_cycle_config",{method:"POST",body:JSON.stringify(e)})}(a);if(!e.success&&!(null==(n=e.data)?void 0:n.persisted))throw new Error("Backend returned unsuccessful response");await t().fetchStats({force:!0})}catch(i){const{mutationsInFlight:a}=t(),n=new Set(a);throw n.delete(r),e({mutationsInFlight:n}),i}},clearDutyCycleMutation:()=>{const{mutationsInFlight:a}=t(),n=new Set(a);n.delete("setDutyCycleConfig"),e({mutationsInFlight:n})},startMutation:a=>{const{mutationsInFlight:n}=t(),r=new Set(n);r.add(a),e({mutationsInFlight:r})},clearMutation:a=>{const{mutationsInFlight:n}=t(),r=new Set(n);r.delete(a),e({mutationsInFlight:r})},sendAdvert:async()=>{try{const a=await Us();return a.success?(e({flashAdvert:t().flashAdvert+1}),{success:!0}):{success:!1,error:a.error||"Failed to send advert"}}catch(a){const e=a instanceof Error?a.message:"Unknown error";return console.error("Failed to send advert:",e),{success:!1,error:e}}},triggerFlashReceived:()=>{e({flashReceived:t().flashReceived+1})},triggerFlashAdvert:()=>{e({flashAdvert:t().flashAdvert+1})},hideContact:a=>{const{hiddenContacts:n}=t(),r=new Set(n);r.add(a),e({hiddenContacts:r}),function(e){if("undefined"!=typeof window)try{localStorage.setItem(Zi,JSON.stringify([...e]))}catch{}}(r)},clearPacketCache:()=>{Nr.clear(),e({packets:[],lastPacketTimestamp:0}),Nr.initialLoad().then(a=>{a.length>0&&(e({packets:a,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(t,a,{idleTimeout:2e3,decryptMode:"full"}))})},triggerTopologyCompute:()=>{var e,a,n,r,s,o,i;const{stats:l,hiddenContacts:c}=t(),d=Nr.getPacketsUnsorted();if(0===d.length||!l)return;const u=l.neighbors??{},h=Object.fromEntries(Object.entries(u).filter(([e])=>!c.has(e))),m=l.local_hash;let g=null==(a=null==(e=l.config)?void 0:e.repeater)?void 0:a.latitude,p=null==(r=null==(n=l.config)?void 0:n.repeater)?void 0:r.longitude;if(!g||!p||0===g&&0===p){const e=go.getState().getEffectiveLocation();e&&(g=e.latitude,p=e.longitude)}const f=[];for(const[t,D]of Object.entries(h))D.zero_hop&&f.push({hash:t,advertCount:D.advert_count??1,avgRssi:D.rssi??null,avgSnr:D.snr??null,lastSeen:D.last_seen??0,latitude:D.latitude,longitude:D.longitude});const b=io.getState().getTerrainGridForDisambiguation(),y=Ti,w=y&&y.size>0?y:void 0,{globalTimeRangeIndex:C}=t(),k=(null==(s=bi[C])?void 0:s.minutes)?bi[C].minutes/60:null,v=null==(i=null==(o=l.config)?void 0:o.radio)?void 0:i.spreading_factor;_r.compute(d,h,m,g,p,void 0,f,b??void 0,w,k,v)},triggerDeepAnalysis:async()=>{await Nr.forceDeepLoad();const a=Nr.getPackets();a.length>0&&(e({packets:a,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(t,a,{idleTimeout:3e3,decryptMode:"full"}))},updateQuickNeighbors:()=>{const{packets:a,stats:n,hiddenContacts:r}=t();if(0===a.length||!n)return;const s=n.neighbors??{},o=function(e,t,a){if(!a||0===e.length||0===Object.keys(t).length)return[];const n=Date.now(),r=Hi(a),s=new Set(Object.keys(t)),o=function(e){var t,a;const n=new Map;for(const r of Object.keys(e)){const s=Hi(r),o=n.get(s);if(o){const i=null==(t=e[o])?void 0:t.zero_hop;(null==(a=e[r])?void 0:a.zero_hop)&&!i&&n.set(s,r)}else n.set(s,r)}return n}(t),i=new Map;for(const c of e){if(!Ji(c))continue;const e=Ki(c.src_hash,r,o,s);if(!e)continue;let t=i.get(e);t||(t=Yi(e),i.set(e,t)),Xi(t,c)}for(const[c,d]of Object.entries(t))Hi(c)!==r&&d.zero_hop&&!i.has(c)&&i.set(c,{hash:c,count:d.advert_count??0,rssiSum:d.rssi??0,rssiCount:void 0!==d.rssi?1:0,snrSum:d.snr??0,snrCount:void 0!==d.snr?1:0,lastSeen:d.last_seen??0});const l=[];for(const c of i.values()){const e=Qi(c,n);e&&l.push(e)}return l.sort((e,t)=>t.count!==e.count?t.count-e.count:t.lastSeen-e.lastSeen),l}(a,Object.fromEntries(Object.entries(s).filter(([e])=>!r.has(e))),n.local_hash),i=t().quickNeighbors;(o.length!==i.length||o.some((e,t)=>{var a,n;return e.hash!==(null==(a=i[t])?void 0:a.hash)||e.count!==(null==(n=i[t])?void 0:n.count)}))&&(e({quickNeighbors:o}),sl(o))},triggerSparklineCompute:()=>{const{stats:e,hiddenContacts:a}=t();if(!e)return;const n=Nr.getPacketsUnsorted();if(0===n.length)return;const r=e.neighbors??{},s=Object.keys(r).filter(e=>!a.has(e));0!==s.length&&to.compute(n,s)},requestTierData:async a=>{const n=ml[a];await async function(e,t,a,n){const r=ul(a);await e(r);const s=Nr.getPackets();a({packets:s,lastPacketTimestamp:Nr.getNewestTimestamp()}),hl(n,s,{idleTimeout:t,decryptMode:"full"})}(n.load,n.idleTimeout,e,t)},setGlobalTimeRange:a=>{e({globalTimeRangeIndex:a}),function(e){if("undefined"!=typeof window)try{localStorage.setItem(al,e.toString())}catch{}}(a);const{packetCacheState:n}=t(),r=gl[a];!r||function(e,t){return{"3d":e.threeDayLoadComplete,"7d":e.sevenDayLoadComplete,"14d":e.fourteenDayLoadComplete,"21d":e.twentyOneDayLoadComplete,"30d":e.thirtyDayLoadComplete,"90d":e.ninetyDayLoadComplete}[t]}(n,r)||n.isBackgroundLoading?(Ps(),dl(()=>t().triggerTopologyCompute(),1e3)):t().requestTierData(r)}})),fl=pl,bl=()=>pl(e=>e.stats),yl=()=>pl(e=>e.statsError),wl=()=>pl(e=>e.packets),Cl=()=>pl(e=>e.packetsLoading),kl=()=>pl(e=>e.logs),vl=()=>pl(e=>e.logsLoading),Dl=()=>pl(e=>e.liveMode),Al=()=>pl(e=>e.flashReceived),xl=()=>pl(e=>e.flashAdvert),El=()=>pl(e=>e.initializeApp),Fl=()=>pl(e=>e.prefetchForRoute),Bl=()=>pl(e=>e.fetchLogs),jl=()=>pl(e=>e.setLiveMode),Sl=()=>pl(e=>e.hiddenContacts),Ml=()=>pl(e=>e.hideContact),Nl=()=>pl(e=>e.packetCacheState),Ll=()=>pl(e=>e.quickNeighbors),Tl=()=>pl(e=>e.cachedLocalHash),_l=()=>pl(e=>e.lastPacketTimestamp),Rl=()=>pl(e=>e.globalTimeRangeIndex),zl=()=>pl(e=>e.setGlobalTimeRange),Pl=()=>pl(e=>e.packetCacheState.dataTier),Il=()=>pl(e=>null!==e.stats&&e.packetCacheState.backgroundLoadComplete),$l=()=>pl(e=>e.packets.length>0),ql=()=>pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.radio)?void 0:n.spreading_factor});let Ol=null;function Hl(){null==Ol||Ol(),Ol=null,pl.setState({initialized:!1})}function Wl(){const e=pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.repeater)?void 0:n.latitude}),t=pl(e=>{var t,a,n;return null==(n=null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.repeater)?void 0:n.longitude}),a=pl(e=>{var t,a,n;return(null==(a=null==(t=e.stats)?void 0:t.config)?void 0:a.node_name)||(null==(n=e.stats)?void 0:n.node_name)||"Local Node"}),n=go(e=>e.latitude),r=go(e=>e.longitude),s=go(e=>e.enabled);return e&&t&&(0!==e||0!==t)?{latitude:e,longitude:t,name:a,isStealth:!1}:s&&null!==n&&null!==r?{latitude:n,longitude:r,name:a,isStealth:!0}:null}const Ul=Object.freeze(Object.defineProperty({__proto__:null,teardownPolling:Hl,useAddResourceDataPoint:()=>Ri(e=>e.addResourceDataPoint),useCachedLocalHash:Tl,useClearMutation:()=>pl(e=>e.clearMutation),useClearPacketCache:()=>pl(e=>e.clearPacketCache),useDataTier:Pl,useEffectiveLocalLocation:Wl,useFetchHardwareStats:Oi,useFetchLogs:Bl,useFetchPackets:()=>pl(e=>e.fetchPackets),useFetchStats:()=>pl(e=>e.fetchStats),useFlashAdvert:xl,useFlashReceived:Al,useGlobalTimeRangeIndex:Rl,useHardwareStats:Pi,useHardwareStatsError:$i,useHardwareStatsLoading:Ii,useHasPackets:$l,useHiddenContacts:Sl,useHideContact:Ml,useInitializeApp:El,useIsFourteenDayDataAvailable:()=>pl(e=>e.packetCacheState.fourteenDayLoadComplete),useIsLoaded:Il,useIsSevenDayDataAvailable:()=>pl(e=>e.packetCacheState.sevenDayLoadComplete),useIsThreeDayDataAvailable:()=>pl(e=>e.packetCacheState.threeDayLoadComplete),useLastPacketTimestamp:_l,useLiveMode:Dl,useLogs:kl,useLogsLoading:vl,useMaxRetentionDays:()=>pl(e=>e.packetCacheState.maxRetentionDays),usePacketCacheState:Nl,usePacketCount:()=>pl(e=>e.packets.length),usePackets:wl,usePacketsLoading:Cl,usePendingAdvertLocalHash:()=>pl(e=>e.pendingAdvertLocalHash),usePendingAdvertTimestamp:()=>pl(e=>e.pendingAdvertTimestamp),usePrefetchForRoute:Fl,useQuickNeighbors:Ll,useRequestTierData:()=>pl(e=>e.requestTierData),useResourceHistory:qi,useSendAdvert:()=>pl(e=>e.sendAdvert),useSetDutyCycle:()=>pl(e=>e.setDutyCycle),useSetGlobalTimeRange:zl,useSetLiveMode:jl,useSetMode:()=>pl(e=>e.setMode),useSpreadingFactor:ql,useStartMutation:()=>pl(e=>e.startMutation),useStats:bl,useStatsError:yl,useStatsLoading:()=>pl(e=>e.statsLoading),useStatsReady:()=>pl(e=>null!==e.stats),useStore:fl,useTriggerDeepAnalysis:()=>pl(e=>e.triggerDeepAnalysis),useTriggerFlashAdvert:()=>pl(e=>e.triggerFlashAdvert),useTriggerFlashReceived:()=>pl(e=>e.triggerFlashReceived)},Symbol.toStringTag,{value:"Module"})),Vl={5:-2.5,6:-5,7:-7.5,8:-10,9:-12.5,10:-15,11:-17.5,12:-20},Gl={62500:{5:-123,6:-125,7:-127,8:-130,9:-133,10:-136,11:-138,12:-140},125e3:{5:-120,6:-122,7:-124,8:-127,9:-130,10:-133,11:-135,12:-137},25e4:{5:-117,6:-119,7:-121,8:-124,9:-127,10:-130,11:-132,12:-134},5e5:{5:-114,6:-116,7:-118,8:-121,9:-124,10:-127,11:-129,12:-131}},Jl=7;function Kl(e){const t=Math.max(5,Math.min(12,Math.round(e)));return Vl[t]??Vl[7]}function Xl(e,t,a){if(null==e||!Number.isFinite(e))return null;if(null==t||!Number.isFinite(t))return null;const{sf:n,bwHz:r}=a,s=Kl(n),o=function(e,t){let a=62500;a=e>=375e3?5e5:e>=187500?25e4:e>=93750?125e3:62500;const n=Gl[a];return n[Math.max(5,Math.min(12,Math.round(t)))]??n[7]}(r,n),i=e-s,l=t-o;return{snrMargin:i,rssiMargin:l,worstMargin:Math.min(i,l)}}const Yl={EXCELLENT:6,GOOD:3,FAIR:0},Ql={EXCELLENT:10,GOOD:6,FAIR:2};function Zl(e,t){const a=e-Kl(t??7);return a>=Yl.EXCELLENT?"excellent":a>=Yl.GOOD?"good":a>=Yl.FAIR?"fair":a>=Yl.FAIR-3?"poor":"critical"}const ec=["excellent","good","fair","poor","critical"];function tc(e,t){return e>=t.EXCELLENT?"excellent":e>=t.GOOD?"good":e>=t.FAIR?"fair":e>=t.FAIR-3?"poor":"critical"}function ac(e,t){if(0===t)return e;const a=ec.indexOf(e),n=Math.min(a+t,ec.length-1);return ec[n]}function nc(e,t,a=0){const n=function(e,t){return Xl(e,t,{sf:7,bwHz:62500})}(e,t);return n?rc(n,a,"low",!0):null}function rc(e,t,a,n){const r=(s=tc(e.snrMargin,Yl),o=tc(e.rssiMargin,Ql),ec.indexOf(s)>=ec.indexOf(o)?s:o);var s,o;const i=ac(r,t);return{baseGrade:r,finalGrade:i,snrMargin:e.snrMargin,rssiMargin:e.rssiMargin,worstMargin:e.worstMargin,nfPenalty:t,wasDowngraded:t>0&&i!==r,confidence:a,isMarginBased:n}}function sc(e,t,a,n=0){return a&&null!=e?function(e,t,a,n=0){const r=Xl(e,t,a);return r?rc(r,n,"high",!0):null}(e,t,a,n):null!=e&&null!=t?nc(e,t,n):function(e,t=0){if(null==e||!Number.isFinite(e))return null;const a=function(e){return e>=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"poor":"critical"}(e),n=ac(a,t);return{baseGrade:a,finalGrade:n,snrMargin:null,rssiMargin:null,worstMargin:null,nfPenalty:t,wasDowngraded:t>0&&n!==a,confidence:"low",isMarginBased:!1}}(t,n)}function oc(e){if(!e)return[];try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(Number).filter(e=>!isNaN(e))}catch{}return[]}function ic(e){return null!=e&&0!==e&&!Object.is(e,-0)&&!(e>-50||e<-130)}function lc(e,t,a=2,n=!1){if(null===t)return"stable";const r=e-t;return(0!==t?100*Math.abs(r/t):Math.abs(r))0?"up":"down":r>0?"down":"up"}function cc(e,t){const a=3600*t,n=Math.floor(Date.now()/1e3)-a,r=e.filter(e=>e.timestamp>=n&&void 0!==e.lbt_attempts&&e.lbt_attempts>0),s=r.length,o=r.filter(e=>(e.lbt_attempts??0)>1).length,i=s>0?o/s*100:0,l=r.filter(e=>(e.lbt_attempts??0)>1),c=l.length>0?l.reduce((e,t)=>e+(t.lbt_attempts??0),0)/l.length:0,d=r.filter(e=>(e.lbt_attempts??0)>=5).length,u=s>0?d/s*100:0;let h=0,m=1/0,g=0,p=0;for(const C of r){const e=oc(C.lbt_backoff_delays_ms);for(let t=0;tg&&(g=a),p++}}const f=p>0?h/p:0;0===p&&(m=0);const b=a/24,y=[],w=[];for(let C=0;C<24;C++){const e=n+C*b,t=e+b,a=r.filter(a=>a.timestamp>=e&&a.timestamp(e.lbt_attempts??0)>1).length,o=a.length>0?s/a.length*100:0,i=[];for(const n of a){const e=oc(n.lbt_backoff_delays_ms);i.push(...e)}const l=i.length>0?i.reduce((e,t)=>e+t,0)/i.length:0;if(y.push(l),0===a.length)w.push(0);else{const e=a.filter(e=>(e.lbt_attempts??0)>=5).length;let t=0;for(let a=0;at&&(t=i[a]);const n=Math.min(a.length/5,1),r=.15,s=Math.log(1+o*r)/Math.log(1+100*r)*40,c=e/a.length*100,d=Math.min(.5*c,25);let u=0;l>100&&(u=Math.min(8*Math.log10(l/100),15));let h=0;t>500&&l>0&&t>2*l&&(h=Math.min((t-500)/200,5));const m=s+d+u+h;w.push(Math.min(m*n,85))}}return{totalPacketsWithLBT:s,packetsWithRetries:o,retryRate:i,avgRetries:c,channelBusyCount:d,channelBusyRate:u,avgBackoffMs:f,minBackoffMs:m,maxBackoffMs:g,totalBackoffMs:h,sparklineBackoff:y,sparklineCollisionRisk:w,windowHours:t,packetCount:e.length}}function dc(e,t,a){if(0===e.length)return{neighbors:[],networkScore:0,neighborCount:0,bestLink:null,worstLink:null};const n=e.map(e=>{const n=function(e,t,a){const n=sc(e,t,a,0);if(n)switch(n.finalGrade){case"excellent":return 100;case"good":return 80;case"fair":return 60;case"poor":return 40;case"critical":return 20}const r=void 0===e?50:e>=10?100:e>=5?80:e>=0?60:e>=-5?40:20,s=void 0===t?50:t>=-70?100:t>=-80?80:t>=-90?60:t>=-100?40:20;return Math.round(.6*r+.4*s)}(e.avgSnr??void 0,e.avgRssi??void 0,a),r=t[e.hash];return{name:(null==r?void 0:r.name)||(null==r?void 0:r.node_name)||e.prefix,hash:e.hash,rssi:e.avgRssi??-100,snr:e.avgSnr??-10,score:n,advertCount:e.count}});n.sort((e,t)=>t.score-e.score);const r=n.length>0?n.reduce((e,t)=>e+t.score,0)/n.length:0;return{neighbors:n,networkScore:Math.round(r),neighborCount:n.length,bestLink:n.length>0?{name:n[0].name,score:n[0].score}:null,worstLink:n.length>0?{name:n[n.length-1].name,score:n[n.length-1].score}:null}}function uc(e,t,a){const n=e?Math.max(0,Math.min(100,100-5*e.retryRate)):50;let r=50;null!==t&&(r=Math.max(0,Math.min(100,(t+120)/30*100)));const s=(null==a?void 0:a.networkScore)??50,o=Math.round(.35*n+.25*r+.4*s);let i;return i=o>=85?"excellent":o>=70?"good":o>=50?"fair":o>=30?"congested":"critical",{score:o,status:i,components:{lbtHealth:Math.round(n),noiseHealth:Math.round(r),linkHealth:Math.round(s)}}}const hc=F(e=>({history:[],hours:24,isLoading:!1,lastFetchTime:0,initialize:()=>{let t=null,a=24;const n=async t=>{var a;const n=Math.max(t,24);try{const t=await Rs(n);t.success&&(null==(a=t.data)?void 0:a.history)&&e({history:t.data.history,hours:n,isLoading:!1,lastFetchTime:Date.now()})}catch{e({isLoading:!1})}},r=e=>{t&&clearInterval(t),a=e;const r=function(e){return e>=504?72e5:e>=336?36e5:e>=168?18e5:e>=72?6e5:3e5}(e);t=setInterval(()=>n(e),r)},s=fl.getState().globalTimeRangeIndex,o=Math.max(1,Math.ceil(bi[s].minutes/60));a=o,e({isLoading:!0,hours:Math.max(o,24)}),n(o),r(o);let i=s;const l=fl.subscribe(e=>{if(e.globalTimeRangeIndex!==i){i=e.globalTimeRangeIndex;const t=Math.max(1,Math.ceil(bi[e.globalTimeRangeIndex].minutes/60));t!==a&&(n(t),r(t))}});let c=0;const d=()=>{document.hidden?c=Date.now():c>0&&Date.now()-c>12e4&&n(a)};return"undefined"!=typeof document&&document.addEventListener("visibilitychange",d),()=>{t&&clearInterval(t),l(),"undefined"!=typeof document&&document.removeEventListener("visibilitychange",d)}}})),mc=[],gc=[],pc=()=>hc(e=>e.history);function fc(e){const t=hc(e=>e.history);return s.useMemo(()=>{if(0===t.length)return gc;if(null==e)return t;const a=t.reduce((e,t)=>Math.max(e,t.timestamp),0)-3600*e;return t.filter(e=>e.timestamp>=a)},[t,e])}function bc(e){const t=hc(e=>e.history),a=hc(e=>e.hours),n=e??a;return s.useMemo(()=>0===t.length?mc:function(e,t){if(0===e.length)return[];const a=e.reduce((e,t)=>Math.max(e,t.timestamp),0);if(0===a)return[];const n=3600*t,r=a-n,s=n/24,o=[];for(let i=0;i<24;i++){const t=r+i*s,a=t+s,n=e.filter(e=>e.timestamp>=t&&e.timestamp0){const e=n.reduce((e,t)=>e+t.noise_floor_dbm,0)/n.length;o.push(e)}else o.push(o.length>0?o[o.length-1]:-100)}return o}(t,n),[t,n])}function yc(){const e=hc(e=>e.history);return s.useMemo(()=>{if(0===e.length)return null;const t=e.map(e=>e.noise_floor_dbm).filter(e=>null!=e&&e>-200&&e<0);if(0===t.length)return null;const a=[...t].sort((e,t)=>e-t);return a[Math.floor(a.length/2)]},[e])}const wc=hc,Cc={healthy:{p3:"color(display-p3 0.2 1 0.4)",fallback:"#00FF66"},degraded:{p3:"color(display-p3 1 0.7 0.2)",fallback:"#FFB020"},offline:{p3:"color(display-p3 1 0.3 0.3)",fallback:"#EF4444"},connecting:{p3:"color(display-p3 0.4 0.6 1)",fallback:"#6699FF"},rx:{p3:"color(display-p3 0.2 1 0.4)",fallback:"#00FF66"},tx:{p3:"color(display-p3 1 0.9 0.2)",fallback:"#FFDD00"},idle:{p3:"color(display-p3 0.3 0.3 0.35)",fallback:"#4A4A55"}};function kc({color:e,pulse:t=!1,className:a}){var n;return o.jsx("span",{className:E("inline-block rounded-full w-1 h-1",t&&"animate-pulse",a),style:{backgroundColor:e.fallback,...(null==(n=CSS.supports)?void 0:n.call(CSS,"color","color(display-p3 1 1 1)"))&&{backgroundColor:e.p3}}})}function vc({showLabel:e=!1,rotated:t=!1,className:a}){const n=Al(),r=xl(),i=ao(e=>"connected"===e.connectionState),l=vs(),c=ks(e=>e.isInitializing),d=ks(e=>e.meshContext),[u,h]=s.useState("idle"),[m,g]=s.useState(!1),[p,b]=s.useState({x:0,y:0}),y=s.useRef(null),w=s.useRef(0),C=s.useRef(0);s.useEffect(()=>{if(n<=0)return;const e=Date.now();if(e-w.current<50)return;w.current=e,h("rx");const t=setTimeout(()=>h("idle"),100);return()=>clearTimeout(t)},[n]),s.useEffect(()=>{if(r<=0)return;const e=Date.now();if(e-C.current<50)return;C.current=e,h("tx");const t=setTimeout(()=>h("idle"),100);return()=>clearTimeout(t)},[r]);let k=Cc.healthy,v=!1,D="LIVE",A="Real-time (WebSocket)";const x=d.hasTopologyData?` · ${d.edgeCount} edges${d.hubCount>0?`, ${d.hubCount} hub${d.hubCount>1?"s":""}`:""}`:"";c?(k=Cc.connecting,v=!0,D="WAIT",A="Connecting..."):"offline"===l?(k=Cc.offline,v=!0,D="DOWN",A="Cannot reach server"):"degraded"===l?(k=Cc.degraded,D="POLL",A="Real-time unavailable, using REST polling"+x):i?(k=Cc.healthy,D="LIVE",A="Real-time (WebSocket)"+x):(k=Cc.healthy,D="POLL",A="Database polling"+x);const F="rx"===u?Cc.rx:"tx"===u?Cc.tx:Cc.idle;if(t){const e=()=>{if(y.current){const e=y.current.getBoundingClientRect();b({x:e.right+8,y:e.top+e.height/2})}g(!0)};return o.jsxs("span",{ref:y,className:E("relative inline-flex",a),onMouseEnter:e,onMouseLeave:()=>g(!1),children:[o.jsxs("span",{className:"inline-flex items-center justify-center gap-1 px-1.5 h-4 rounded-full depth-raised-soft bg-surface",style:{transform:"rotate(-90deg)"},children:[o.jsx(kc,{color:k,pulse:v}),o.jsx(kc,{color:F})]}),m&&f.createPortal(o.jsx("span",{className:"fixed px-2 py-1 rounded bg-zinc-900 text-[10px] text-fg-secondary whitespace-nowrap shadow-lg ring-1 ring-edge-subtle pointer-events-none",style:{left:p.x,top:p.y,transform:"translateY(-50%)",zIndex:9999},children:A}),document.body)]})}return o.jsxs("span",{className:E("inline-flex items-center gap-1.5",a),title:A,children:[o.jsxs("span",{className:"inline-flex items-center justify-center gap-1 px-1.5 h-4 rounded-full depth-raised-soft bg-surface",children:[o.jsx(kc,{color:k,pulse:v}),o.jsx(kc,{color:F})]}),e&&o.jsx("span",{className:E("type-data-xs","DOWN"===D?"text-status-danger":"WAIT"===D?"text-sys-blue":"POLL"===D?"text-status-warning":"text-fg-muted"),children:D})]})}const Dc="undefined"!=typeof window&&(null==(e=CSS.supports)?void 0:e.call(CSS,"color","color(display-p3 1 1 1)")),Ac=Dc?"color(display-p3 0.227 0.51 0.965)":"var(--sys-blue)",xc=Dc?"drop-shadow(0 0 4px color-mix(in oklch, var(--sys-blue) 50%, transparent))":"drop-shadow(0 0 3px color-mix(in oklch, var(--sys-blue) 40%, transparent))";function Ec({borderRadius:e,width:t,height:a}){const n=s.useMemo(()=>function(e,t,a){const n=Math.min(a,e/2,t/2);return 2*(e-2*n)+2*(t-2*n)+2*Math.PI*n}(t,a,e),[t,a,e]),r=.15*n,i=n-r;return o.jsx(_.svg,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{opacity:{duration:.2,ease:[.4,0,.2,1]}},width:t,height:a,viewBox:`0 0 ${t} ${a}`,fill:"none",className:"animate-[shimmer-pulse_2s_ease-in-out_infinite]",style:{position:"absolute",inset:0,zIndex:2,pointerEvents:"none","--shimmer-shadow":xc,filter:xc},children:o.jsx(_.rect,{x:1,y:1,width:t-2,height:a-2,rx:e-1,ry:e-1,stroke:Ac,strokeWidth:2,strokeDasharray:`${r} ${i}`,strokeLinecap:"round",initial:{strokeDashoffset:0},animate:{strokeDashoffset:-n},transition:{duration:2,ease:"linear",repeat:1/0}})})}function Fc({children:e,isLoading:t=!0,className:a,borderRadius:n=12}){const r=s.useRef(null),[i,l]=s.useState({w:0,h:0});return s.useEffect(()=>{const e=r.current;if(!e)return;const t=new ResizeObserver(([e])=>{const{width:t,height:a}=e.contentRect;l(e=>e.w===t&&e.h===a?e:{w:t,h:a})});return t.observe(e),()=>t.disconnect()},[]),o.jsxs("div",{ref:r,className:E("relative overflow-hidden",a),style:{borderRadius:n},children:[o.jsx(T,{children:t&&i.w>0&&o.jsx(Ec,{borderRadius:n,width:i.w,height:i.h})}),o.jsx("div",{className:"relative z-10",children:e})]})}function Bc({className:e}){return o.jsx("div",{className:E("relative w-14 h-2 rounded-full overflow-hidden sparkle-bar-track",e),children:o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full w-full overflow-hidden",children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]})})}const jc=F(e=>({sparklines:new Map,isComputing:!1,lastUpdated:0,nodeCount:0,setSparklines:t=>e({sparklines:t,lastUpdated:Date.now(),nodeCount:t.size,isComputing:!1}),setComputing:t=>e({isComputing:t})}));"undefined"!=typeof window&&setTimeout(()=>{to.subscribe((e,t)=>{const a=jc.getState();t&&!a.isComputing?a.setComputing(!0):!t&&e.size>0?a.setSparklines(e):!t&&a.isComputing&&a.setComputing(!1)})},0);const Sc=jc,Mc=()=>jc(e=>e.sparklines),Nc=()=>jc(e=>e.isComputing),Lc=[],Tc=new Map;function _c(e){return jc(t=>{const a=t.sparklines.get(e);if(!a||0===a.length)return Lc;const n=Tc.get(e);return n===a?n:(Tc.set(e,a),a)})}const Rc="pymc_room_seen_",zc="pymc_room_selected";function Pc(e){try{const t=localStorage.getItem(`${Rc}${e}`);return t?Number(t):0}catch{return 0}}function Ic(e){const t=new Map;for(const a of e){const e=Math.floor(a.post_timestamp/30),n=`${a.author_pubkey}|${e}|${a.message_text}`,r=t.get(n);(!r||a.idr&&e{let a=null;return{rooms:[],selectedRoom:null,messages:[],clients:[],identities:[],unreadCount:0,lastSeenMap:new Map,isLoading:!1,error:null,initialize:()=>{if(!a)return t().fetchRooms(),a=setInterval(()=>{t().fetchRooms()},1e4),()=>{a&&(clearInterval(a),a=null)}},fetchRooms:async()=>{try{const[a,n]=await Promise.all([eo(),Ks()]),r=a.success&&a.data?a.data.rooms:[],s=(n.success&&n.data?n.data.configured:[]).filter(e=>"room_server"===e.type),o=new Set(s.map(e=>e.name)),i=r.filter(e=>o.has(e.room_name)),l=new Map;for(const e of i)l.set(e.room_name,Pc(e.room_name));const c=qc(i,l);e({rooms:i,identities:s,lastSeenMap:l,unreadCount:c,error:null});const{selectedRoom:d}=t();if(i.length,s.length,!d&&i.length>0){const e=function(){try{return localStorage.getItem(zc)}catch{return null}}(),a=e&&i.some(t=>t.room_name===e)?e:i[0].room_name;t().selectRoom(a)}}catch(a){e({error:a instanceof Error?a.message:"Failed to fetch rooms"})}},selectRoom:async a=>{const{selectedRoom:n}=t();e(n!==a?{selectedRoom:a,messages:[],clients:[],isLoading:!0}:{selectedRoom:a,isLoading:!0}),function(e){try{localStorage.setItem(zc,e)}catch{}}(a),await Promise.all([t().fetchMessages(),t().fetchClients()]),e({isLoading:!1})},fetchMessages:async a=>{var n,r;const{selectedRoom:s,messages:o}=t();if(!s)return;const i={room_name:s,limit:200};if((null==a?void 0:a.incremental)&&o.length>0){const e=Math.max(...o.map(e=>e.post_timestamp));i.since_timestamp=e}try{const t=await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),void 0!==e.limit&&t.set("limit",e.limit.toString()),void 0!==e.offset&&t.set("offset",e.offset.toString()),void 0!==e.since_timestamp&&t.set("since_timestamp",e.since_timestamp.toString()),Fs(`/api/room_messages?${t.toString()}`)}(i);if(t.success,t.data,null==(r=null==(n=t.data)?void 0:n.messages)||r.length,!t.success||!t.data)return;if((null==a?void 0:a.incremental)&&o.length>0){const a=new Set(o.map(e=>e.id)),n=t.data.messages.filter(e=>!a.has(e.id));n.length>0&&e({messages:Ic([...o,...n])})}else e({messages:Ic(t.data.messages)})}catch(l){console.error("[RoomStore] fetchMessages error:",l)}},postMessage:async e=>{try{return!!(await async function(e){return Fs("/api/room_post_message",{method:"POST",body:JSON.stringify(e)})}(e)).success&&(await t().fetchMessages(),!0)}catch{return!1}},deleteMessage:async a=>{const{selectedRoom:n}=t();if(!n)return!1;try{return!!(await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),t.set("message_id",e.message_id.toString()),Fs(`/api/room_message?${t.toString()}`,{method:"DELETE"})}({room_name:n,message_id:a})).success&&(e({messages:t().messages.filter(e=>e.id!==a)}),!0)}catch{return!1}},clearMessages:async()=>{const{selectedRoom:a}=t();if(!a)return!1;try{return!!(await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),Fs(`/api/room_messages_clear?${t.toString()}`,{method:"DELETE"})}({room_name:a})).success&&(e({messages:[]}),!0)}catch{return!1}},fetchClients:async()=>{const{selectedRoom:a}=t();if(a)try{const t=await async function(e){const t=new URLSearchParams;return e.room_name&&t.set("room_name",e.room_name),e.room_hash&&t.set("room_hash",e.room_hash),Fs(`/api/room_clients?${t.toString()}`)}({room_name:a});t.success&&t.data&&e({clients:t.data.clients.filter(e=>e.in_acl)})}catch{}},markAsRead:()=>{const{selectedRoom:a,rooms:n,lastSeenMap:r}=t();if(!a)return;const s=Math.floor(Date.now()/1e3);!function(e,t){try{localStorage.setItem(`${Rc}${e}`,String(t))}catch{}}(a,s);const o=new Map(r);o.set(a,s),e({lastSeenMap:o,unreadCount:qc(n,o)})},createRoom:async e=>{try{return!!(await async function(e){return Fs("/api/create_identity",{method:"POST",body:JSON.stringify(e)})}(e)).success&&(await t().fetchRooms(),!0)}catch{return!1}},updateRoom:async e=>{try{return!!(await async function(e){return Fs("/api/update_identity",{method:"PUT",body:JSON.stringify(e)})}(e)).success&&(await t().fetchRooms(),!0)}catch{return!1}},deleteRoom:async a=>{try{const n=await async function(e){return Fs(`/api/delete_identity?name=${encodeURIComponent(e)}`,{method:"DELETE"})}(a);if(n.success){const{selectedRoom:n}=t();return n===a&&e({selectedRoom:null,messages:[],clients:[]}),await t().fetchRooms(),!0}return!1}catch{return!1}},sendAdvert:async e=>{try{const t=await async function(e){return Fs("/api/send_room_server_advert",{method:"POST",body:JSON.stringify({name:e})})}(e);return!!t.success}catch{return!1}},startActivePolling:()=>{const e=setInterval(()=>{t().fetchMessages({incremental:!0}),t().fetchClients()},5e3);return()=>clearInterval(e)}}}),Hc=()=>Oc(e=>e.rooms),Wc=()=>Oc(e=>e.selectedRoom),Uc=()=>Oc(e=>e.messages),Vc=()=>Oc(e=>e.clients),Gc=()=>Oc(e=>e.identities),Jc=()=>Oc(e=>e.isLoading),Kc=()=>Oc(e=>e.rooms.find(t=>t.room_name===e.selectedRoom)??null),Xc=()=>Oc(e=>e.identities.find(t=>{var a;return t.name===e.selectedRoom||(null==(a=t.settings)?void 0:a.node_name)===e.selectedRoom})??null);function Yc(e){if(e<60)return`${Math.floor(e)}s`;const t=Math.floor(e/86400),a=Math.floor(e%86400/3600),n=Math.floor(e%3600/60),r=[];return t>0&&r.push(`${t}d`),a>0&&r.push(`${a}h`),(n>0||0===r.length)&&r.push(`${n}m`),r.join(" ")}function Qc(e){const t=Date.now()/1e3-e;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function Zc(e){const t=Date.now()/1e3-e;return t<60?`${Math.floor(t)}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function ed(e){return new Date(1e3*e).toLocaleString()}function td(e){const t=new Date(1e3*e);return`${t.toLocaleString("en-US",{month:"short"})} ${t.getDate()}, ${t.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}`}function ad(e){return new Date(1e3*e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function nd(e){return`${(e/1e6).toFixed(3)} MHz`}function rd(e){return`${(e/1e3).toFixed(1)} kHz`}function sd(e){e<0&&(e=0);const t=Math.floor(e/1e3),a=Math.floor(t/60),n=Math.floor(a/60);if(n>0){const e=a%60;return e>0?`${n}h ${e}m`:`${n}h`}if(a>0){const e=t%60;return e>0?`${a}m ${e}s`:`${a}m`}if(t>0){const a=e%1e3;return a>0?`${t}.${Math.floor(a/100)}s`:`${t}s`}return`${e}ms`}function od(e){return e<1024?`${e}B`:e<1048576?`${(e/1024).toFixed(1)}K`:`${(e/1048576).toFixed(1)}M`}s.memo(function({options:e,data:t,className:a="",onCreate:n}){const r=s.useRef(null),i=s.useRef(null);return s.useEffect(()=>{const a=r.current;if(!a)return;const s=a.getBoundingClientRect(),o=Math.floor(s.width)||400,l=Math.floor(s.height)||200,c=new D({...e,width:o,height:l},t,a);return i.current=c,null==n||n(c),()=>{c.destroy(),i.current=null}},[e]),s.useEffect(()=>{i.current&&t&&i.current.setData(t)},[t]),s.useEffect(()=>{const e=r.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!i.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&i.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),o.jsx("div",{ref:r,className:`w-full h-full ${a}`,style:{minHeight:100}})});const id=s.memo(function({items:e,direction:t="horizontal",size:a="sm",className:n,highlightedKey:r,onItemClick:s,onItemHover:i}){const l="horizontal"===t,c="sm"===a;return o.jsx("div",{className:E("flex font-mono",l?"flex-wrap gap-x-4 gap-y-1":"flex-col gap-1",c?"text-xs":"text-sm",n),children:e.map(e=>{const t=null!=r&&r!==e.key,a=s||i;return o.jsxs("div",{className:E("flex items-center gap-1.5 transition-opacity",t&&"opacity-30",a&&"cursor-pointer hover:opacity-80"),onClick:()=>null==s?void 0:s(e.key),onMouseEnter:()=>null==i?void 0:i(e.key),onMouseLeave:()=>null==i?void 0:i(null),children:[o.jsx("div",{className:E("shrink-0 rounded-xs",c?"w-3 h-3":"w-4 h-4"),style:{backgroundColor:e.color}}),o.jsx("span",{className:"text-fg-secondary whitespace-nowrap",children:e.label}),void 0!==e.value&&o.jsx("span",{className:"text-fg-muted tabular-nums",children:e.formatValue?e.formatValue(e.value):e.value})]},e.key)})})}),ld={4:me.blue,5:me.indigo,6:me.purple,0:me.cyan,2:me.teal,7:me.green,1:me.yellow,10:me.amber,8:me.orange,9:me.red,3:me.pink,15:me.brown},cd=me.brown;function dd(e){return ld[e]??cd}let ud=null,hd=0;const md=1e3;function gd({activeTypes:e,totalByType:t}){const a=[...e].reverse().map(e=>({key:String(e),label:nt[e]??`TYPE_${e}`,color:dd(e),value:t[e]??0,formatValue:e=>od(e)}));return o.jsx(id,{items:a})}const pd=s.memo(function({buckets:e,activeTypes:t,onHover:a,gridColor:n,axisTickColor:r}){const i=s.useRef(null),l=s.useRef(null),c=s.useRef(e),d=s.useRef(t),u="undefined"!=typeof document&&"light"!==document.documentElement.dataset.mode,h=n||(u?"rgba(255,255,255,0.1)":"rgba(0,0,0,0.1)"),m=r||(u?"rgba(255,255,255,0.6)":"rgba(0,0,0,0.6)"),g=s.useRef({gridColor:h,axisTickColor:m});c.current=e,d.current=t,g.current={gridColor:h,axisTickColor:m};const p=e.length,f=s.useMemo(()=>[e.map(e=>e.start),e.map(()=>1)],[p]),b=s.useCallback(t=>{if(!i.current||0===e.length)return;const n=i.current.getBoundingClientRect(),r=(t.clientX-n.left-48)/(n.width-48-8);if(r<0||r>1)return void(null==a||a(null,null,null));const s=Math.min(e.length-1,Math.max(0,Math.floor(r*e.length)));null==a||a(s,e[s],r)},[e,a]),y=s.useCallback(()=>{null==a||a(null,null,null)},[a]);return s.useEffect(()=>{if(!i.current||0===p)return;const e=i.current,t=e.getBoundingClientRect(),a={width:Math.floor(t.width)||400,height:Math.floor(t.height)||200,padding:[8,8,28,48],cursor:{show:!1},scales:{x:{time:!1},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],legend:{show:!1},hooks:{draw:[e=>{const t=e.ctx,{left:a,top:n,width:r,height:s}=e.bbox,o=window.devicePixelRatio||1,i=g.current;!function(e,t,a,n,r,s,o){if(0===t.length||0===a.length)return;const i=t.length,l=s/i;let c=0;for(const d of t)d.totalBytes>c&&(c=d.totalBytes);0===c&&(c=1);for(let d=0;dc&&(c=b.totalBytes);if(0===c)return;const d=function(){const e=performance.now();if(ud&&e-hd{const t=e.getBoundingClientRect();t.width>0&&t.height>0&&l.current&&l.current.setSize({width:Math.floor(t.width),height:Math.floor(t.height)})});return r.observe(e),()=>{r.disconnect(),n.destroy(),l.current=null}},[p]),s.useEffect(()=>{l.current&&l.current.redraw()},[e,t]),0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:i,className:"w-full h-full",onMouseMove:b,onMouseLeave:y})}),fd=new Map;function bd(e){var t;if(!e.startsWith("var("))return e;const a=fd.get(e);if(a)return a;const n=e.match(/var\(([^,)]+)(?:,\s*([^)]+))?\)/);if(!n)return e;const r=n[1].trim(),s=(null==(t=n[2])?void 0:t.trim())||"#888888",o=getComputedStyle(document.documentElement).getPropertyValue(r).trim()||s;return fd.set(e,o),o}const yd="undefined"!=typeof document&&"light"!==document.documentElement.dataset.mode?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.3)";function wd(e,t,a=!1){if(t.length<2)return;if(e.beginPath(),e.moveTo(t[0].x,t[0].y),2===t.length)return void e.lineTo(t[1].x,t[1].y);const n=.5;for(let r=0;r{g.current=e,p.current=t,f.current=n,b.current=a});const w=s.useRef({band:r,innerBand:i,mean:l,median:c,average:d,cursor:u});s.useLayoutEffect(()=>{w.current={band:r,innerBand:i,mean:l,median:c,average:d,cursor:u}});const C=s.useMemo(()=>[e.map(e=>e.timestamp),e.map(e=>e.max)],[e]),k=s.useMemo(()=>{const e=function(e,t,a,n){return{hooks:{draw:r=>{const s=e.current,o=t.current,i=a.current,l=n.current;if(0===s.length)return;const c=r.ctx,d=r.bbox,u=d.left,h=d.top,m=d.width,g=d.height;if(m<=0||g<=0)return;const p=r.data[0],f=p.length;if(0===f)return;const b=p[0],y=p[f-1]-b||1,w=e=>u+(e-b)/y*m,C=e=>h+g*(1-e/o),k={min:s.map(e=>({x:w(e.timestamp),y:C(e.min)})),max:s.map(e=>({x:w(e.timestamp),y:C(e.max)})),p5:s.map(e=>({x:w(e.timestamp),y:C(e.p5)})),p95:s.map(e=>({x:w(e.timestamp),y:C(e.p95)})),p25:s.map(e=>({x:w(e.timestamp),y:C(e.p25)})),p75:s.map(e=>({x:w(e.timestamp),y:C(e.p75)})),mean:s.map(e=>({x:w(e.timestamp),y:C(e.mean)})),median:s.map(e=>({x:w(e.timestamp),y:C(e.median)})),average:s.map(e=>({x:w(e.timestamp),y:C(e.average)}))},v=(e,t)=>i?i===e?Math.min(1,1.5*t):"minMax"===i||"p5p95"===i||"p25p75"===i?.3*t:t:t,D=e=>i?i===e?1:"mean"===i||"median"===i||"average"===i?.3:1:1,A={band:bd(l.band),innerBand:bd(l.innerBand),mean:bd(l.mean),median:bd(l.median),average:bd(l.average)};c.save(),c.strokeStyle=A.average,c.lineWidth=4,c.globalAlpha=D("average"),wd(c,k.average),c.stroke(),c.globalAlpha=v("minMax",.15),c.fillStyle=A.band,c.beginPath(),wd(c,k.max);const x=[...k.min].reverse();for(const e of x)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.globalAlpha=v("p5p95",.3),c.fillStyle=A.band,c.beginPath(),wd(c,k.p95);const E=[...k.p5].reverse();for(const e of E)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.globalAlpha=v("p25p75",.55),c.fillStyle=A.innerBand,c.beginPath(),wd(c,k.p75);const F=[...k.p25].reverse();for(const e of F)c.lineTo(e.x,e.y);c.closePath(),c.fill(),c.strokeStyle=A.median,c.lineWidth=1.5,c.globalAlpha=D("median"),c.setLineDash([4,4]),wd(c,k.median),c.stroke(),c.strokeStyle=A.mean,c.lineWidth=1.5,c.globalAlpha=D("mean"),c.setLineDash([]),wd(c,k.mean),c.stroke(),c.restore()}}}}(g,p,f,w);return{width:400,height:200,padding:[4,4,4,4],cursor:{show:!0,x:!0,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,t]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],hooks:{setCursor:[e=>{var t,a;const n=e.cursor.idx;null!=n&&n>=0?null==(t=b.current)||t.call(b,n):null==(a=b.current)||a.call(b,null)}]},plugins:[e]}},[t]);s.useEffect(()=>{const t=h.current;if(!t||0===e.length)return;const a=y.current,n=e.length,r=Math.abs(n-a);if(!(!m.current||r>100||a>0&&r/a>.1)&&m.current)return m.current.setData(C),void(y.current=n);m.current&&m.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...k,width:o,height:i},C,t);return m.current=l,y.current=n,()=>{l.destroy(),m.current=null}},[k,C,e.length]),s.useEffect(()=>{const e=h.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!m.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&m.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{m.current&&m.current.redraw()},[n,e]);const v=s.useCallback(()=>{null==a||a(null)},[a]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:h,className:"w-full h-full rounded-2xl overflow-hidden",onMouseLeave:v})});const Cd="undefined"!=typeof window&&(null==(a=null==(t=window.matchMedia)?void 0:t.call(window,"(color-gamut: p3)"))?void 0:a.matches);let kd=null,vd=0;function Dd(){const e=performance.now();if(kd&&e-vd<1e3)return kd;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--chart-axis-tick").trim()||(n?"rgba(255, 255, 255, 0.4)":"rgba(0, 0, 0, 0.4)"),s=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)"),o=t.getPropertyValue("--text-muted").trim()||"#727272",i=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),l=t.getPropertyValue("--signal-critical").trim()||"#EF4444",c=t.getPropertyValue("--bg-body").trim()||(n?"#171717":"#F5F5F5");return kd={fontFamily:a,axisColor:r,gridColor:s,textMuted:o,textPrimary:i,signalCritical:l,bgBody:c},vd=e,kd}const Ad=["min","max","p75","p95","p99","mean","median","average","midpoint"];function xd(e){const t=ct(function(e){const{colormap:t,baseIndex:a,halfSize:n}=ht(),r=Math.max(0,Math.min(1,e)),s=Math.min(a+Math.floor(r*(n-1)),t.discrete.length-1);return t.discrete[s]}(e)),a=`color(display-p3 ${(t.r/255).toFixed(3)} ${(t.g/255).toFixed(3)} ${(t.b/255).toFixed(3)})`;return{...t,p3:a}}function Ed(e,t,a,n,r,s,o,i,l,c=null,d=null,u=1,h=null,m="airtime",g=.5){if(0===t.length)return;const p=e.ctx,{left:f,top:b,width:y,height:w}=e.bbox,C=window.devicePixelRatio||1;if(y<=0||w<=0)return;const k=e.data[0],v=k.length;if(0===v)return;const D=k[0],A=k[v-1],x=a,E="share"===m,F=E?function(e){const t=[10,20,25,50,100,200,250,500,1e3],a=e/4.5;for(const n of t)if(n>=a)return n;return e>5e3?1e3*Math.ceil(a/1e3):100*Math.ceil(a/100)}(x):5,B=s.signalCritical,j=s.bgBody;p.save(),p.fillStyle="#000000";const S=8*C;p.beginPath(),p.roundRect(f,b,y,w,S),p.fill(),p.restore();const M=parseInt(j.slice(1,3),16)||23,N=parseInt(j.slice(3,5),16)||23,L=parseInt(j.slice(5,7),16)||23;if(!E&&x>=20){p.save();const e=b+w*(1-20/x);p.fillStyle=`rgba(${M}, ${N}, ${L}, 0.5)`,p.fillRect(f,b,y,e-b),p.restore()}p.save(),p.lineWidth=1*C,p.setLineDash([4*C,4*C]);for(let _=F;_a+r)return;const i=Dd().textPrimary;e.save(),e.strokeStyle=i,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()}(p,h,f,b,y,w,C),o){!function(e,t,a,n,r,s,o=null,i=null,l=1,c=25){const{points:d,rawValues:u,count:h,packetTypes:m,timestamps:g}=t,p=1*l*(window.devicePixelRatio||1);e.globalCompositeOperation="source-over";const f=o?parseInt(o.replace("TYPE_",""),10):null;for(let b=0;b=i.start&&e0&&function(e,t,a,n,r,s,o,i,l,c,d=.5){if(0===t.length)return;const u=l-i||1,h=function(e,t=1.3,a=.15){const n=function(e){const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t){const e=parseFloat(t[1]),a=parseFloat(t[2]),n=parseFloat(t[3]);return{r:Math.round(255*e),g:Math.round(255*a),b:Math.round(255*n),p3r:e,p3g:a,p3b:n}}if(e.startsWith("#")){const t=e.replace("#",""),a=parseInt(t.slice(0,2),16),n=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16);return{r:a,g:n,b:r,p3r:a/255,p3g:n/255,p3b:r/255}}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);if(a){const e=Math.round(parseFloat(a[1])),t=Math.round(parseFloat(a[2])),n=Math.round(parseFloat(a[3]));return{r:e,g:t,b:n,p3r:e/255,p3g:t/255,p3b:n/255}}return{r:255,g:255,b:255,p3r:1,p3g:1,p3b:1}}(e),r=function(e,t,a,n=1.25,r=.15){const s=(Math.max(e,t,a)+Math.min(e,t,a))/2;return{p3r:Math.min(1,s+(e-s)*n+r),p3g:Math.min(1,s+(t-s)*n+r),p3b:Math.min(1,s+(a-s)*n+r)}}(n.p3r,n.p3g,n.p3b,t,a);return{r:Math.round(255*Math.min(1,r.p3r)),g:Math.round(255*Math.min(1,r.p3g)),b:Math.round(255*Math.min(1,r.p3b)),p3r:Math.min(1,r.p3r),p3g:Math.min(1,r.p3g),p3b:Math.min(1,r.p3b)}}(Dd().signalCritical);e.save(),e.globalAlpha=d,e.fillStyle=Cd?`color(display-p3 ${h.p3r} ${h.p3g} ${h.p3b})`:`rgb(${h.r}, ${h.g}, ${h.b})`;for(const m of t){if(m.endTsl)continue;const t=n+(Math.max(m.startTs,i)-i)/u*s,a=n+(Math.min(m.endTs,l)-i)/u*s,d=Math.max(a-t,2*c);e.fillRect(t,r,d,o)}e.restore()}(p,i,0,f,b,y,w,D,A,C,d?Math.max(.03,.03*g):g)}s.memo(function({data:e,maxValue:t,visibleLines:a=Ad,highlightedLine:n=null,onHover:r,scatterData:i=null,noiseFloorAnomalies:l=null,showNoiseFloorOverlay:c=!1,overlayOpacity:d=.5,highlightedType:u=null,hoveredTimeRange:h=null,timeRangeHours:m=24,yAxisMode:g="airtime"}){const p=s.useRef(null),f=s.useRef(null),b=s.useRef(e),y=s.useRef(t),w=s.useRef(a),C=s.useRef(n),k=s.useRef(r),v=s.useRef(i),A=s.useRef(l),x=s.useRef(c),E=s.useRef(u),F=s.useRef(h),B=s.useRef(null),j=s.useRef(null),S=s.useRef(g),M=s.useRef(d),N=m<=12?1.2:1,L=s.useRef(N),T=s.useRef(e.length);s.useLayoutEffect(()=>{b.current=e,y.current=t,w.current=a,C.current=n,k.current=r,v.current=i,A.current=l,x.current=c,E.current=u,F.current=h,L.current=N,S.current=g,M.current=d}),s.useEffect(()=>{B.current=Dd()},[]);const _=s.useMemo(()=>[e.map(e=>e.timestamp),new Array(e.length).fill(1)],[e]),R=s.useMemo(()=>({hooks:{draw:e=>{const t=B.current||Dd();Ed(e,b.current,y.current,w.current,C.current,t,v.current,A.current,x.current,E.current,F.current,L.current,j.current,S.current,M.current)}}}),[]),z=s.useMemo(()=>({width:400,height:200,padding:[8,0,8,28],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[R]}),[R]);s.useEffect(()=>{const t=p.current;if(!t||0===e.length)return;const a=T.current,n=e.length,r=Math.abs(n-a);if(!(!f.current||r>100||a>0&&r/a>.1)&&f.current)return f.current.setData(_),void(T.current=n);f.current&&f.current.destroy();const s=t.getBoundingClientRect(),o=Math.floor(s.width)||400,i=Math.floor(s.height)||200,l=new D({...z,width:o,height:i},_,t);return f.current=l,T.current=n,()=>{l.destroy(),f.current=null}},[z,_,e.length]),s.useEffect(()=>{const e=p.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!f.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&f.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{f.current&&f.current.redraw()},[n,a,e,i,l,c,d,u,h,N]);const P=s.useCallback(t=>{var a,n;const r=p.current,s=f.current;if(!r||!s||0===e.length)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,c=s.bbox,d=c.left/l,u=c.width/l;if(id+u)return j.current=null,s.redraw(),void(null==(a=k.current)||a.call(k,null));j.current=i*l;const h=(i-d)/u,m=e.length,g=Math.floor(h*m),b=Math.max(0,Math.min(m-1,g));s.redraw(),null==(n=k.current)||n.call(k,b)},[e.length]),I=s.useCallback(()=>{var e;j.current=null,f.current&&f.current.redraw(),null==(e=k.current)||e.call(k,null)},[]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:p,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:P,onMouseLeave:I})});const Fd=(()=>{const e=lt.lajolla.discrete.map(e=>{const t=e.replace("#","");return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}),t=new Uint8Array(768);for(let a=0;a<256;a++){const n=a/255*(e.length-1),r=Math.floor(n),s=Math.min(r+1,e.length-1),o=n-r;t[3*a]=Math.round(e[r][0]+(e[s][0]-e[r][0])*o),t[3*a+1]=Math.round(e[r][1]+(e[s][1]-e[r][1])*o),t[3*a+2]=Math.round(e[r][2]+(e[s][2]-e[r][2])*o)}return t})();let Bd=null;const jd=-70;let Sd=null,Md=0;function Nd(e,t){if(0===e.length)return 0;const a=t/100*(e.length-1),n=Math.floor(a),r=Math.ceil(a);return n===r?e[n]:e[n]+(e[r]-e[n])*(a-n)}function Ld(e){const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\)/);if(t)return{r:Math.round(255*parseFloat(t[1])),g:Math.round(255*parseFloat(t[2])),b:Math.round(255*parseFloat(t[3]))};const a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return a?{r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)}:{r:250,g:189,b:47}}function Td(e,t,a){const n=Math.max(0,Math.min(1,e));return{r:Math.round(t.r+(a.r-t.r)*n),g:Math.round(t.g+(a.g-t.g)*n),b:Math.round(t.b+(a.b-t.b)*n)}}const _d=s.memo(function({timestamps:e,values:t,onStatsChange:a,compact:n=!1,height:r}){var i,l;const[c,d]=s.useState(!1),[u,h]=s.useState(!1),m=s.useRef(null),g=s.useRef(null),p=s.useRef(null),f=s.useRef(null),b=s.useRef(null),y=s.useRef(n),w=s.useRef(u),C=s.useMemo(()=>{const e=t.filter(e=>e<=jd);if(0===e.length)return null;let a=e[0],n=e[0];for(let t=1;tn&&(n=e[t]);const r=e.reduce((e,t)=>e+t,0)/e.length,s=[...e].sort((e,t)=>e-t);return{min:a,max:n,avg:r,p5:Nd(s,5),p95:Nd(s,95)}},[t]);s.useEffect(()=>{null==a||a(C)},[C]);const k=s.useCallback(()=>{d(e=>!e)},[]),v=s.useCallback(()=>{h(e=>!e)},[]),{heatmapData:A,xLabels:x,yLabels:E}=s.useMemo(()=>{if(0===e.length||0===t.length||!C)return{heatmapData:null,xLabels:[],yLabels:[]};let a,r;if(c){const e=t.filter(e=>e<=jd);if(0===e.length)return{heatmapData:null,xLabels:[],yLabels:[]};const n=[...e].sort((e,t)=>e-t),s=Nd(n,5),o=Nd(n,95),i=.1*(o-s||1);a=s-i,r=o+i}else{const e=t.filter(e=>e<=jd);if(0===e.length)return{heatmapData:null,xLabels:[],yLabels:[]};let n=e[0],s=e[0];for(let t=1;ts&&(s=e[t]);const o=.1*(s-n||1);a=n-o,r=s+o}const s=r-a,o=e[0],i=e[e.length-1],l=i-o||1,d=200,u=60,h=new Float32Array(12e3),m=[];for(let n=0;njd)continue;const c=(e[n]-o)/l,g=1-(Math.max(a,Math.min(r,i))-a)/s;h[Math.min(199,Math.floor(c*d))*u+Math.min(59,Math.floor(g*u))]++,m.push(e[n])}let g=0;for(let e=0;eg&&(g=h[e]);const p=[],f=[];for(let e=0;et&&(t=n,a=r)}if(-1===a||0===t)continue;const n=r-(a+.5)/u*s,i=o+(e+.5)/d*l;p.push(i),f.push(n)}const b=f.length>=2?200:0,y=f.length>=2?function(e,t,a,n){const r=e.length;if(0===r)return[];if(1===r)return new Array(n).fill(t[0]);if(2===r){const e=new Array(n);for(let a=0;ae-t),h=Math.max(u[s-1],1e-10);let m=0,g=0,p=0,f=0,b=0;for(let n=0;n=1)continue;const s=r*r*r,o=(1-s)*(1-s)*(1-s),i=e[n]-a;m+=o,g+=o*i,p+=o*t[n],f+=o*i*i,b+=o*i*t[n]}if(0===m){l[d]=t[Math.min(r-1,Math.round(d/(n-1)*(r-1)))];continue}const y=m*f-g*g;Math.abs(y)<1e-10?l[d]=p/m:l[d]=(f*p-g*b)/y}return l}(p,f,0,b):[];let w=a,k=r,v=s;if(n&&y.length>0){let e=y[0],t=y[0];for(let n=1;nt&&(t=y[n]);const a=.4*(t-e||1);w=e-a,k=t+a,v=k-w}const D=[];for(let e=0;e{b.current=A,y.current=n,w.current=u});const F=s.useMemo(()=>{if(0===e.length)return[[],[]];const t=new Array(e.length).fill(1);return[e,t]},[e]),B=s.useMemo(()=>({hooks:{draw:e=>{!function(e,t,a,n){if(!t)return;const r=e.ctx,{left:s,top:o,width:i,height:l}=e.bbox,c=window.devicePixelRatio||1;if(i<=0||l<=0)return;const d=function(){const e=performance.now();if(Sd&&e-Md<1e3)return Sd;const t=getComputedStyle(document.documentElement);return Sd={stabilityHot:Ld(t.getPropertyValue("--sys-amber").trim()),stabilityCool:Ld(t.getPropertyValue("--sys-blue").trim()),typography:{fontFamily:t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',textMuted:t.getPropertyValue("--text-muted").trim()||"#727272",textSecondary:t.getPropertyValue("--text-secondary").trim()||"#A0A0A0",gridColor:t.getPropertyValue("--chart-grid-line").trim()||"rgba(255,255,255,0.06)"}},Md=e,Sd}();r.clearRect(s,o,i,l),a||function(e,t,a,n,r,s,o){e.save(),e.strokeStyle=o,e.lineWidth=1*s,e.setLineDash([3*s,3*s]);for(const i of[0,.25,.5,.75,1]){const s=Math.round(a+r*i)+.5;e.beginPath(),e.moveTo(t,s),e.lineTo(t+n,s),e.stroke()}e.restore()}(r,s,o,i,l,c,d.typography.gridColor),a||function(e,t,a,n,r,s){const{densityGrid:o,xBins:i,yBins:l,maxDensity:c}=t;if(0===c)return;Bd&&Bd.width===i&&Bd.height===l||(Bd=document.createElement("canvas"),Bd.width=i,Bd.height=l);const d=Bd.getContext("2d"),u=d.createImageData(i,l),h=u.data,m=Math.log1p(c);for(let g=0;go&&(o=a)}const i=(t+o)/2,u=(o-t)/2||.01;for(let h=1;h{const t=p.current,a=f.current;if(!t&&!a||y.current)return;const{left:n,top:r}=e.cursor,s=b.current;if(null==n||null==r||n<0||r<0||!s)return t&&(t.style.display="none"),void(a&&(a.style.display="none"));const o=window.devicePixelRatio||1,i=e.bbox.width/o,l=e.bbox.height/o,c=n/i,d=r/l;if(c<0||c>1||d<0||d>1)return t&&(t.style.display="none"),void(a&&(a.style.display="none"));const u=Math.min(s.xBins-1,Math.max(0,Math.floor(c*s.xBins))),h=Math.min(s.yBins-1,Math.max(0,Math.floor(d*s.yBins))),m=s.densityGrid[u*s.yBins+h],g=s.minTime+(u+.5)/s.xBins*s.timeRange,w=s.yMax-(h+.5)/s.yBins*s.yRange,C=new Date(1e3*g).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});if(a){a.style.display="block";const e=a.children;e[0].style.transform=`translateX(${Math.round(n)}px)`,e[1].style.transform=`translateY(${Math.round(r)}px)`;const t=i/s.xBins,o=l/s.yBins,c=e[2];c.style.left=u*t+"px",c.style.top=h*o+"px",c.style.width=`${t}px`,c.style.height=`${o}px`,c.style.opacity=m>0?"1":"0.5"}if(t){const e=t.children;e[0].textContent=C,e[1].textContent=`${Math.round(w)} dBm`,e[2].textContent=m>0?`${m} sample${1!==m?"s":""}`:"no data";const a=n>i-130,s=r>l-64;t.style.display="block",t.style.left=`${n+(a?-116:12)}px`,t.style.top=`${r+(s?-58:8)}px`}}}}),[]),j=s.useMemo(()=>({width:400,height:200,padding:[0,0,0,0],cursor:n?{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}}:{show:!0,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[B]}),[B,n]);return s.useEffect(()=>{const t=m.current;if(!t||0===e.length)return;g.current&&g.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...j,width:n,height:r},F,t);return g.current=s,()=>{s.destroy(),g.current=null}},[j,F,e.length]),s.useEffect(()=>{const e=m.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!g.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&g.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{g.current&&g.current.redraw()},[A,c,u]),A?n?o.jsx("div",{ref:m,className:"w-full",style:{height:r??28},role:"img","aria-label":"Noise floor sparkline"}):o.jsxs("div",{className:"relative w-full h-full",role:"img","aria-label":`RF noise floor heatmap showing values from ${(null==(i=null==C?void 0:C.min)?void 0:i.toFixed(0))??"N/A"} to ${(null==(l=null==C?void 0:C.max)?void 0:l.toFixed(0))??"N/A"} dBm`,children:[o.jsx("div",{className:"absolute top-0 left-0 flex flex-col justify-between",style:{width:32,bottom:20},"aria-hidden":"true",children:E.map((e,t)=>{const a=0===t?"translateY(-100%)":t===E.length-1?"none":"translateY(-50%)";return o.jsx("span",{className:"type-data-xs text-fg-secondary text-right pr-1.5",style:{position:"absolute",top:`${e.pos}%`,transform:a,right:0},children:e.label},t)})}),o.jsxs("div",{ref:m,className:"absolute overflow-hidden radius-inner ring-1 ring-inset ring-edge-subtle bg-chart-inner",style:{left:32,right:0,top:0,bottom:20},children:[o.jsxs("div",{ref:f,className:"absolute inset-0 z-10 pointer-events-none",style:{display:"none"},children:[o.jsx("div",{className:"absolute top-0 bottom-0 w-px bg-subtle-fill-strong"}),o.jsx("div",{className:"absolute left-0 right-0 h-px bg-subtle-fill-strong"}),o.jsx("div",{className:"absolute bg-subtle-fill-strong ring-1 ring-inset ring-edge-strong"})]}),o.jsxs("div",{ref:p,className:"absolute z-20 pointer-events-none radius-inner bg-tooltip-bg px-2.5 py-1.5 shadow-lg",style:{display:"none"},children:[o.jsx("div",{className:"type-data-xs text-fg-muted"}),o.jsx("div",{className:"type-data-xs text-fg-primary"}),o.jsx("div",{className:"type-data-xs text-fg-muted"})]}),o.jsxs("div",{className:"absolute top-1 right-1 z-10 flex items-center gap-1",children:[o.jsx("button",{type:"button",onClick:v,className:"p-1.5 rounded bg-zinc-900/90 hover:bg-zinc-800 active:bg-zinc-700 ring-1 ring-inset ring-zinc-600 transition-colors touch-manipulation",title:u?"Hide LOESS trend line":"Show LOESS trend line","aria-label":u?"Hide trend line":"Show trend line","aria-pressed":u,children:o.jsx(W,{className:"w-3.5 h-3.5 transition-colors "+(u?"text-zinc-100":"text-zinc-400"),"aria-hidden":"true"})}),o.jsx("button",{type:"button",onClick:k,className:"p-1.5 rounded bg-zinc-900/90 hover:bg-zinc-800 active:bg-zinc-700 ring-1 ring-inset ring-zinc-600 transition-colors touch-manipulation",title:c?"Show full range (min/max)":"Show trimmed range (P5-P95)","aria-label":c?"Expand to show full data range":"Shrink to show trimmed percentile range","aria-pressed":!c,children:c?o.jsx(U,{className:"w-3.5 h-3.5 text-zinc-100","aria-hidden":"true"}):o.jsx(V,{className:"w-3.5 h-3.5 text-zinc-100","aria-hidden":"true"})})]})]}),o.jsx("div",{className:"absolute left-0 right-0 bottom-0",style:{left:32,height:20},"aria-hidden":"true",children:x.map((e,t)=>o.jsx("span",{className:"type-data-xs text-fg-secondary absolute top-1",style:{left:`${e.pos}%`,transform:0===t?"none":t===x.length-1?"translateX(-100%)":"translateX(-50%)"},children:e.label},t))})]}):n?o.jsx("div",{className:"w-full rounded bg-subtle/50",style:{height:r??28},"aria-hidden":"true"}):o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No noise floor data available"})});let Rd=null,zd=0;function Pd(){const e=performance.now();if(Rd&&e-zd<1e3)return Rd;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--chart-axis-tick").trim()||(n?"rgba(255, 255, 255, 0.4)":"rgba(0, 0, 0, 0.4)"),s=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)"),o=t.getPropertyValue("--text-muted").trim()||"#727272",i=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),l=t.getPropertyValue("--signal-critical").trim()||"#EF4444",c=t.getPropertyValue("--bg-body").trim()||(n?"#171717":"#F5F5F5");return Rd={fontFamily:a,axisColor:r,gridColor:s,textMuted:o,textPrimary:i,signalCritical:l,bgBody:c},zd=e,Rd}function Id(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}function $d(e){return Id(dd(e))}const qd=s.memo(function({scatterData:e,yAxisMode:t,onHover:a,noiseFloorAnomalies:n=null,showNoiseFloorOverlay:r=!1,overlayOpacity:i=.5,highlightedType:l=null,timeRangeHours:c=24,yAxisMaxOverride:d,dotSize:u=.8,dotOpacity:h=.5,startTs:m,endTs:g,externalAxes:p=!1}){const f=s.useRef(null),b=s.useRef(null),y=s.useRef(e),w=s.useRef(t),C=s.useRef(a),k=s.useRef(n),v=s.useRef(r),A=s.useRef(i),x=s.useRef(l),E=s.useRef(null),F=s.useRef(null),B=c<=12?1.2:1,j=s.useRef(B),S=s.useRef(u),M=s.useRef(h),N=s.useRef(p),L=d??(null==e?void 0:e.maxValue)??("share"===t?200:10),T=s.useRef(L);s.useLayoutEffect(()=>{y.current=e,w.current=t,C.current=a,k.current=n,v.current=r,A.current=i,x.current=l,j.current=B,T.current=L,S.current=u,M.current=h,N.current=p}),s.useEffect(()=>{E.current=Pd()},[]);const _=s.useMemo(()=>{if(!e||0===e.count)return void 0!==m&&void 0!==g?[[m,g],[1,1]]:[[0],[0]];const t=[];for(let n=0;ne-t),void 0!==m&&t[0]>m&&t.unshift(m),void 0!==g&&t[t.length-1]1);return[t,a]},[e,m,g]),R=s.useMemo(()=>({hooks:{draw:e=>{const t=E.current||Pd();!function(e,t,a,n,r,s,o,i,l,c,d,u,h,m=!1){if(!t||0===t.count)return;const g=e.ctx,{left:p,top:f,width:b,height:y}=e.bbox,w=window.devicePixelRatio||1;if(b<=0||y<=0)return;const C=e.data[0],k=C.length;if(0===k)return;const v=C[0],D=C[k-1],A="share"===n,x=function(e,t){if("airtime"===t)return 5;const a=[10,20,25,50,100,200,250,500,1e3],n=e/4.5;for(const r of a)if(r>=n)return r;return e>5e3?1e3*Math.ceil(n/1e3):100*Math.ceil(n/100)}(a,n);if(!A&&a>=20){g.save();const e=f+y*(1-20/a),t=r.signalCritical,n=parseInt(t.slice(1,3),16)||239,s=parseInt(t.slice(3,5),16)||68,o=parseInt(t.slice(5,7),16)||68;g.fillStyle=`rgba(${n}, ${s}, ${o}, 0.025)`,g.fillRect(p,f,b,e-f),g.restore()}g.save(),g.lineWidth=1*w,g.setLineDash([4*w,4*w]);for(let E=x;Ea+r||(e.save(),e.strokeStyle=i.textPrimary,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()))}(g,d,p,f,b,y,w,r),function(e,t,a,n,r,s,o,i,l,c,d){const{points:u,rawValues:h,count:m,packetTypes:g}=t,p=c*i*(window.devicePixelRatio||1),f=2*p;e.globalCompositeOperation="source-over";const b=o?parseInt(o.replace("TYPE_",""),10):null,y=.066*d;for(let w=0;w0&&function(e,t,a,n,r,s,o,i,l,c,d){if(0===t.length)return;const u=i-o||1,h=Id(d.signalCritical);e.save(),e.globalAlpha=c,e.fillStyle=`rgb(${h.r}, ${h.g}, ${h.b})`;for(const m of t){if(m.endTsi)continue;const t=a+(Math.max(m.startTs,o)-o)/u*r,c=a+(Math.min(m.endTs,i)-o)/u*r,d=Math.max(c-t,2*l);e.fillRect(t,n,d,s)}e.restore()}(g,s,p,f,b,y,v,D,w,i,r)}(e,y.current,T.current,w.current,t,k.current,v.current,A.current,x.current,j.current,F.current,S.current,M.current,N.current)}}}),[]),z=s.useMemo(()=>({width:400,height:200,padding:p?[0,0,0,0]:[8,0,8,28],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[R]}),[R]);s.useEffect(()=>{const t=f.current;if(!t||!e||0===e.count)return;b.current&&b.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...z,width:n,height:r},_,t);return b.current=s,()=>{s.destroy(),b.current=null}},[z,_,null==e?void 0:e.count]),s.useEffect(()=>{const e=f.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!b.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&b.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{b.current&&b.current.redraw()},[e,n,r,i,l,B,t,u,h]);const P=s.useCallback(t=>{var a,n;const r=f.current,s=b.current;if(!r||!s||!e||0===e.count)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,c=s.bbox,d=c.left/l,u=c.width/l;if(id+u)return F.current=null,s.redraw(),void(null==(a=C.current)||a.call(C,null,void 0));F.current=i*l;const h=(i-d)/u,m=Math.floor(h*e.count),g=Math.max(0,Math.min(e.count-1,m));s.redraw(),null==(n=C.current)||n.call(C,g,h)},[null==e?void 0:e.count]),I=s.useCallback(()=>{var e;F.current=null,b.current&&b.current.redraw(),null==(e=C.current)||e.call(C,null,void 0)},[]);return e&&0!==e.count?o.jsx("div",{ref:f,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:P,onMouseLeave:I}):o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"})}),Od=new class{constructor(){r(this,"observer",null),r(this,"subscribers",new Set),r(this,"isObserving",!1)}subscribe(e){return this.subscribers.add(e),this.isObserving||this.startObserving(),()=>{this.subscribers.delete(e),0===this.subscribers.size&&this.stopObserving()}}get subscriberCount(){return this.subscribers.size}startObserving(){"undefined"!=typeof window&&(this.isObserving||(this.observer=new MutationObserver(e=>{for(const t of e)if("data-theme"===t.attributeName||"data-color-scheme"===t.attributeName||"class"===t.attributeName){setTimeout(()=>this.notifySubscribers(),50);break}}),this.observer.observe(document.documentElement,{attributes:!0}),this.isObserving=!0))}stopObserving(){this.observer&&(this.observer.disconnect(),this.observer=null),this.isObserving=!1}notifySubscribers(){for(const t of this.subscribers)try{t()}catch(e){console.error("ThemeObserver callback error:",e)}}};function Hd(e){if(!e)return null;const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t)return{r:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[1])))),g:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[2])))),b:Math.round(255*Math.min(1,Math.max(0,parseFloat(t[3]))))};if(e.startsWith("#")){const t=e.replace("#","");if(3===t.length)return{r:parseInt(t[0]+t[0],16),g:parseInt(t[1]+t[1],16),b:parseInt(t[2]+t[2],16)};if(t.length>=6)return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);return a?{r:Math.round(parseFloat(a[1])),g:Math.round(parseFloat(a[2])),b:Math.round(parseFloat(a[3]))}:null}function Wd(e){return"undefined"==typeof window?"":getComputedStyle(document.documentElement).getPropertyValue(e).trim()}function Ud(e){return function(e){if(!e)return"";if(e.startsWith("#"))return e;const t=e.match(/color\(display-p3\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/);if(t){const e=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[1])))),a=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[2])))),n=Math.round(255*Math.min(1,Math.max(0,parseFloat(t[3]))));return`#${e.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}const a=e.match(/rgba?\(([\d.]+),?\s*([\d.]+),?\s*([\d.]+)/);if(a){const e=Math.round(parseFloat(a[1])),t=Math.round(parseFloat(a[2])),n=Math.round(parseFloat(a[3]));return`#${e.toString(16).padStart(2,"0")}${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}`}return e}(Wd(e))}function Vd(e,t){const[a,n]=s.useState(t),r=s.useCallback(()=>{n(e())},[e]);return s.useEffect(()=>(r(),Od.subscribe(r)),[r]),a}const Gd={chart1:me.blue,chart2:me.teal,chart3:me.amber,chart4:me.orange,chart5:me.pink,chart6:me.purple,chart7:me.cyan,chart8:ge[500]},Jd={excellent:me.green,good:me.yellow,fair:me.amber,poor:me.orange,critical:me.red},Kd={primary:"#ffffff",secondary:ge[400],muted:ge[500]},Xd={nodeFill:me.blue,nodeStroke:"rgba(255,255,255,0.9)",hubColor:me.purple,hubStroke:"rgba(255,255,255,0.9)",gatewayColor:me.indigo,gatewayStroke:"rgba(255,255,255,0.85)",localColor:me.amber,neighborColor:me.amber,neighborStroke:"rgba(0,0,0,0.4)",mobileColor:me.orange,roomColor:me.pink,ghostColor:me.cyan};function Yd(){return"undefined"==typeof window?Gd:{chart1:Wd("--chart-1")||Gd.chart1,chart2:Wd("--chart-2")||Gd.chart2,chart3:Wd("--chart-3")||Gd.chart3,chart4:Wd("--chart-4")||Gd.chart4,chart5:Wd("--chart-5")||Gd.chart5,chart6:Wd("--chart-6")||Gd.chart6,chart7:Wd("--chart-7")||Gd.chart7,chart8:Wd("--chart-8")||Gd.chart8}}function Qd(){return"undefined"==typeof window?Kd:{primary:Wd("--text-primary")||Kd.primary,secondary:Wd("--text-secondary")||Kd.secondary,muted:Wd("--text-muted")||Kd.muted}}function Zd(){return Vd(Yd,Gd)}function eu(){return Vd(Qd,Kd)}function tu(){return"undefined"==typeof window?Xd:{nodeFill:Wd("--map-node-fill")||Xd.nodeFill,nodeStroke:Wd("--map-node-stroke")||Xd.nodeStroke,hubColor:Wd("--map-hub-color")||Xd.hubColor,hubStroke:Wd("--map-hub-stroke")||Xd.hubStroke,gatewayColor:Wd("--map-gateway-color")||Xd.gatewayColor,gatewayStroke:Wd("--map-gateway-stroke")||Xd.gatewayStroke,localColor:Wd("--map-local-color")||Xd.localColor,neighborColor:Wd("--map-neighbor-color")||Xd.neighborColor,neighborStroke:Wd("--map-neighbor-stroke")||Xd.neighborStroke,mobileColor:Wd("--map-mobile-color")||Xd.mobileColor,roomColor:Wd("--map-room-color")||Xd.roomColor,ghostColor:Wd("--map-ghost-color")||Xd.ghostColor}}function au(){return Vd(tu,Xd)}const nu={nodeStroke:"rgba(0,0,0,0.6)",hubStroke:"rgba(0,0,0,0.5)",gatewayStroke:"rgba(0,0,0,0.45)",neighborStroke:"rgba(0,0,0,0.5)"},ru={nodeStroke:"rgba(255,255,255,0.9)",hubStroke:"rgba(255,255,255,0.9)",gatewayStroke:"rgba(255,255,255,0.85)",neighborStroke:"rgba(0,0,0,0.4)"};function su(e){if("undefined"==typeof window)return Xd;const t="light"===function(){if("undefined"==typeof window)return"dark";const e=document.querySelector("[data-basemap]");return e&&e.getAttribute("data-basemap")||"dark"}()?nu:ru;return{nodeFill:Ud("--map-node-fill")||Xd.nodeFill,nodeStroke:t.nodeStroke,hubColor:Ud("--map-hub-color")||Xd.hubColor,hubStroke:t.hubStroke,gatewayColor:Ud("--map-gateway-color")||Xd.gatewayColor,gatewayStroke:t.gatewayStroke,localColor:Ud("--map-local-color")||Xd.localColor,neighborColor:Ud("--map-neighbor-color")||Xd.neighborColor,neighborStroke:t.neighborStroke,mobileColor:Ud("--map-mobile-color")||Xd.mobileColor,roomColor:Ud("--map-room-color")||Xd.roomColor,ghostColor:Ud("--map-ghost-color")||Xd.ghostColor}}const ou={rest:"rgba(255, 255, 255, 0.25)",restBright:"rgba(255, 255, 255, 0.35)",restDim:"rgba(255, 255, 255, 0.15)",hoverDirect:me.cyan,hoverLoop:me.purple,hoverStandard:ge[400],hoverNeighbor:me.amber,highlight:"#FFD700"},iu={rest:"rgba(0, 0, 0, 0.20)",restBright:"rgba(0, 0, 0, 0.30)",restDim:"rgba(0, 0, 0, 0.12)"},lu={rest:"rgba(255, 255, 255, 0.25)",restBright:"rgba(255, 255, 255, 0.35)",restDim:"rgba(255, 255, 255, 0.15)"};function cu(e){if("undefined"==typeof window)return ou;const t="light"===e?iu:lu;return{rest:t.rest,restBright:t.restBright,restDim:t.restDim,hoverDirect:Ud("--map-edge-hover-direct")||ou.hoverDirect,hoverLoop:Ud("--map-edge-hover-loop")||ou.hoverLoop,hoverStandard:Ud("--map-edge-hover-standard")||ou.hoverStandard,hoverNeighbor:Ud("--map-edge-hover-neighbor")||ou.hoverNeighbor,highlight:Ud("--map-edge-highlight")||ou.highlight}}const du={grid:"rgba(191, 191, 191, 0.15)",axisTick:ge[400],cursor:"rgba(255, 255, 255, 0.2)"};function uu(){return"undefined"==typeof window?du:{grid:Wd("--chart-grid")||du.grid,axisTick:Wd("--chart-axis-tick")||du.axisTick,cursor:Wd("--chart-cursor")||du.cursor}}function hu(){return Vd(uu,du)}function mu(e,t){return Wd(`--palette-${e}-${t}`)||""}function gu(){const e=[];for(let t=0;t<24;t++){const a=t/23,n=1-a,r=mu("aqua",[900,800,700,600,500,400,300,200,100,50][Math.min(8,Math.floor(9*n))]),s=parseInt(r.slice(1,3),16)||0,o=parseInt(r.slice(3,5),16)||0,i=parseInt(r.slice(5,7),16)||0,l=Math.round(80+130*a);e.push([s,o,i,l])}return e}function pu(){const e=Wd("--signal-excellent")||Jd.excellent,t=Wd("--signal-good")||Jd.good,a=Wd("--signal-fair")||Jd.fair,n=Wd("--signal-poor")||Jd.poor,r=Wd("--signal-critical")||Jd.critical,s=[];for(let o=0;o<24;o++){let i;i=o<5?e:o<10?t:o<15?a:o<20?n:r,s.push(i)}return s}function fu(){const e=Ud("--signal-excellent")||Jd.excellent,t=Ud("--signal-good")||Jd.good,a=Ud("--signal-fair")||Jd.fair,n=Ud("--signal-poor")||Jd.poor,r=Ud("--signal-critical")||Jd.critical,s=[];for(let o=0;o<24;o++){let i;i=o<5?e:o<10?t:o<15?a:o<20?n:r,s.push(i)}return s}function bu(){const[e,t]=s.useState(()=>pu());return s.useEffect(()=>{const e=()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t(pu())})})};return e(),Od.subscribe(e)},[]),e}function yu(e,t){const a=e-Kl(t??7),n=(Math.max(-6,Math.min(9,a))- -6)/15;return Math.round(23*(1-n))}const wu={...me};function Cu(){return"undefined"==typeof window?wu:{red:Ud("--sys-red")||wu.red,orange:Ud("--sys-orange")||wu.orange,amber:Ud("--sys-amber")||wu.amber,yellow:Ud("--sys-yellow")||wu.yellow,brown:Ud("--sys-brown")||wu.brown,green:Ud("--sys-green")||wu.green,teal:Ud("--sys-teal")||wu.teal,cyan:Ud("--sys-cyan")||wu.cyan,blue:Ud("--sys-blue")||wu.blue,indigo:Ud("--sys-indigo")||wu.indigo,purple:Ud("--sys-purple")||wu.purple,pink:Ud("--sys-pink")||wu.pink}}function ku(){const e=s.useCallback(()=>"undefined"==typeof document||"light"!==document.documentElement.dataset.mode,[]),[t,a]=s.useState(e);return s.useEffect(()=>(a(e()),Od.subscribe(()=>a(e()))),[e]),t}function vu(){return"undefined"==typeof document||"light"!==document.documentElement.dataset.mode}let Du=null,Au=0;function xu(){const e=performance.now();if(Du&&e-Au<1e3)return Du;const t=getComputedStyle(document.documentElement),a=t.getPropertyValue("--font-data").trim()||'"JetBrains Mono", ui-monospace, monospace',n="light"!==document.documentElement.dataset.mode,r=t.getPropertyValue("--text-primary").trim()||(n?"#FFFFFF":"#1A1A1A"),s=t.getPropertyValue("--text-secondary").trim()||(n?"#BFBFBF":"#4A4A4A"),o=t.getPropertyValue("--chart-grid").trim()||(n?"rgba(255, 255, 255, 0.06)":"rgba(0, 0, 0, 0.06)");return Du={fontFamily:a,textPrimary:r,textSecondary:s,gridColor:o},Au=e,Du}function Eu(e){const t=e.replace("#","");return{r:parseInt(t.slice(0,2),16),g:parseInt(t.slice(2,4),16),b:parseInt(t.slice(4,6),16)}}let Fu=null,Bu=0;function ju(e,t){return"airtime"===t?`${e}%`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(0)}K`:`${e}`}function Su(e,t,a,n,r,s,o,i,l,c,d,u=.9,h=!1,m,g){if(0===t.length)return;const p=m??t[0].timestamp,f=(g??t[t.length-1].timestamp)-p||1;if(e.save(),e.strokeStyle=`rgba(${n.r}, ${n.g}, ${n.b}, ${u})`,e.lineWidth=d*c,e.lineCap="round",e.lineJoin="round",h){e.beginPath();let n=!1,c=0,d=0;for(let u=0;u{u.current=e,h.current=t,m.current=a,g.current=n,b.current=r,y.current=i,w.current=l}),s.useEffect(()=>{p.current=xu()},[]);const C=s.useMemo(()=>0===e.length?[[0],[0]]:[e.map(e=>e.timestamp),e.map(()=>1)],[e]),k=s.useMemo(()=>({hooks:{draw:e=>{const t=p.current||xu();!function(e,t,a,n,r,s,o,i,l=!1){if(0===t.length)return;const c=e.ctx,{left:d,top:u,width:h,height:m}=e.bbox,g=window.devicePixelRatio||1;if(h<=0||m<=0)return;const p=function(){const e=performance.now();return Fu&&e-Bu<1e3||(Fu=Cu(),Bu=e),Fu}(),f=Eu(p.blue),b=Eu(p.red),y=Eu(p.yellow),w=(C=a,"airtime"===n?C<=5?1:C<=10?2:C<=20?5:Math.ceil(C/5):C<=100?25:C<=500?100:C<=1e3?200:C<=5e3?1e3:C<=1e4?2e3:1e3*Math.ceil(C/5e3));var C;c.save(),c.strokeStyle=r.textSecondary,c.globalAlpha=.3,c.lineWidth=1*g,c.setLineDash([3*g,3*g]);for(let k=w;ka+r||(e.save(),e.strokeStyle=i.textPrimary,e.globalAlpha=.5,e.lineWidth=1*o,e.setLineDash([4*o,4*o]),e.beginPath(),e.moveTo(Math.round(t)+.5,n),e.lineTo(Math.round(t)+.5,n+s),e.stroke(),e.restore()))}(c,s,d,u,h,m,g,r),Su(c,t,"rxSmooth",y,d,u,h,m,a,g,2,1,!0,o,i),Su(c,t,"tx",b,d,u,h,m,a,g,2.5,.9,!1,o,i),Su(c,t,"rx",f,d,u,h,m,a,g,2.5,.9,!1,o,i)}(e,u.current,m.current,h.current,t,f.current,b.current,y.current,w.current)}}}),[]),v=s.useMemo(()=>({width:400,height:200,padding:l?[0,0,0,0]:[8,8,8,44],cursor:{show:!1,x:!1,y:!1,drag:{x:!1,y:!1},points:{show:!1}},scales:{x:{time:!0,range:(e,t,a)=>[b.current??t,y.current??a]},y:{range:[0,1]}},axes:[{show:!1},{show:!1}],series:[{},{show:!1}],plugins:[k]}),[k]);s.useEffect(()=>{const t=c.current;if(!t||0===e.length)return;d.current&&d.current.destroy();const a=t.getBoundingClientRect(),n=Math.floor(a.width)||400,r=Math.floor(a.height)||200,s=new D({...v,width:n,height:r},C,t);return d.current=s,()=>{s.destroy(),d.current=null}},[v,C,e.length]),s.useEffect(()=>{const e=c.current;if(!e)return;const t=new ResizeObserver(e=>{const t=e[0];if(!t||!d.current)return;const{width:a,height:n}=t.contentRect;a>0&&n>0&&d.current.setSize({width:Math.floor(a),height:Math.floor(n)})});return t.observe(e),()=>{t.disconnect()}},[]),s.useEffect(()=>{d.current&&d.current.redraw()},[e,a,t]);const A=s.useCallback(t=>{var a,n;const r=c.current,s=d.current;if(!r||!s||0===e.length)return;const o=r.getBoundingClientRect(),i=t.clientX-o.left,l=window.devicePixelRatio||1,u=s.bbox,h=u.left/l,m=u.width/l;if(ih+m)return f.current=null,s.redraw(),void(null==(a=g.current)||a.call(g,null));f.current=i*l;const p=(i-h)/m,b=Math.floor(p*e.length),y=Math.max(0,Math.min(e.length-1,b));s.redraw(),null==(n=g.current)||n.call(g,y)},[e.length]),x=s.useCallback(()=>{var e;f.current=null,d.current&&d.current.redraw(),null==(e=g.current)||e.call(g,null)},[]);return 0===e.length?o.jsx("div",{className:"h-full flex items-center justify-center text-fg-muted",children:"No data available"}):o.jsx("div",{ref:c,className:"w-full h-full rounded-lg overflow-hidden",onMouseMove:A,onMouseLeave:x})}),Nu=s.memo(function({className:e}){const{theme:t,setTheme:a}=tt(),n="breeze dark"===t.themeId,r=s.useCallback(()=>{a(n?"breeze light":"breeze dark")},[n,a]);return o.jsx("button",{onClick:r,"aria-label":n?"Switch to light mode":"Switch to dark mode",title:n?"Switch to light mode":"Switch to dark mode",className:E("flex items-center justify-center rounded-md p-1.5","hover:bg-zinc-500/20","transition-colors duration-150",e),children:n?o.jsx(G,{className:"w-3.5 h-3.5 text-sys-amber"}):o.jsx(J,{className:"w-3.5 h-3.5 text-sys-blue"})})}),Lu=[{name:"Dashboard",to:"/",icon:K},{name:"Contacts",to:"/contacts",icon:X},{name:"Statistics",to:"/statistics",icon:Y},{name:"Packets",to:"/packets",icon:Q},{name:"Terminal",to:"/terminal",icon:Z},{name:"Room Server",to:"/room-server",icon:ee},{name:"MeshGraph",to:"/meshgraph",icon:te},{name:"System",to:"/system",icon:ae},{name:"Logs",to:"/logs",icon:ne},{name:"Configuration",to:"/configuration",icon:re}];function Tu(){var e,t,a,n,r,i;const{pathname:l}=B(),c=j(),{stats:d,setMode:u,setDutyCycle:h,sendAdvert:m}=fl(),g=cn(),p=Fl(),f=Nl(),b=Pl(),y=Rl(),w=Nc(),C=Or(),k=Rr(e=>e.topology.nodeMetrics.size),v=Oc(e=>e.unreadCount),D=wl(),A=s.useMemo(()=>{const e=Date.now()/1e3-60*bi[y].minutes;return D.filter(t=>t.timestamp>=e).length},[D,y]);let x=null;try{x=function(){const e=s.useContext(oa);if(!e)throw new Error("useSidebar must be used within a SidebarLayout");return e}()}catch{}const[F,S]=s.useState(!1),[M,N]=s.useState("idle"),[L,T]=s.useState(null),[_,R]=s.useState(!1),[z,P]=s.useState(null),I=fc(bi[y].minutes/60);s.useEffect(()=>{let e=!1;const t=async()=>{try{const t=await Zs();!e&&t.success&&t.data&&P(t.data.total_clients)}catch{}};t();const a=setInterval(t,3e4);return()=>{e=!0,clearInterval(a)}},[]);const $=s.useRef(null),q=s.useCallback(e=>{e!==l&&($.current&&clearTimeout($.current),$.current=setTimeout(()=>{p(e)},100))},[l,p]),H=s.useCallback(()=>{$.current&&(clearTimeout($.current),$.current=null)},[]),W=null==d?void 0:d.noise_floor_dbm,U=(null==(t=null==(e=null==d?void 0:d.config)?void 0:e.repeater)?void 0:t.mode)??"forward",V=(null==(n=null==(a=null==d?void 0:d.config)?void 0:a.duty_cycle)?void 0:n.enforcement_enabled)??!1,G=V?(null==(i=null==(r=null==d?void 0:d.config)?void 0:r.duty_cycle)?void 0:i.max_airtime_percent)??10:100,J=f.isLoading||f.isBackgroundLoading||f.isTopologyLoading,K=J||w||C,X=f.loadProgress,Y=s.useCallback((e,t)=>{e.preventDefault(),null==x||x.close(),c(t)},[c,x]);return o.jsxs(Qt,{children:[o.jsxs(Zt,{className:"px-5 pt-3 pb-4 border-b-0",children:[o.jsx("h1",{className:"sr-only",children:"pyMC Console"}),o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx(Oa,{responsive:!0,className:"block flex-1"}),o.jsx(vc,{rotated:!0})]}),o.jsxs("div",{className:"flex items-center gap-1.5 mt-1.5",children:[o.jsxs("span",{className:"inline-flex px-1.5 py-0.5 rounded text-[10px] font-medium tabular-nums font-mono bg-surface text-fg-muted",children:["v",$a]}),o.jsx(Nu,{})]})]}),o.jsxs(ea,{className:"pt-[13px] pb-0",children:[o.jsx(aa,{children:Lu.map(e=>{const t=l===e.to,a="/terminal"===e.to,n="#6545EE";return o.jsxs(na,{href:e.to,current:t,accentColor:a?n:void 0,onClick:t=>Y(t,e.to),onMouseEnter:()=>q(e.to),onMouseLeave:H,children:[o.jsxs("span",{className:"relative",children:[o.jsx(e.icon,{className:E("size-4",t&&!a&&"text-sys-blue"),style:t&&a?{color:n}:void 0}),"/room-server"===e.to&&v>0&&o.jsx("span",{className:"absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-sys-red ring-2 ring-body"})]}),o.jsx(ra,{children:e.name}),"/contacts"===e.to&&k>0&&o.jsx(sa,{variant:"accent",children:o.jsx("span",{children:k})}),"/packets"===e.to&&A>0&&o.jsx(sa,{variant:"default",children:o.jsx("span",{children:A>=1e4?`${(A/1e3).toFixed(1)}k`:A.toLocaleString()})}),"/meshgraph"===e.to&&o.jsx(sa,{variant:"default",children:"Beta"})]},e.name)})}),K&&o.jsx("div",{className:"px-0 py-3",children:o.jsx(Fc,{isLoading:J,borderRadius:12,children:o.jsxs("div",{className:"bg-surface/50 rounded-xl px-2 py-3",children:[o.jsxs("div",{className:"flex items-center gap-2 px-1 py-0.5",children:[o.jsxs("div",{className:"relative flex h-2 w-2",children:[o.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-sys-blue opacity-75"}),o.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-sys-blue"})]}),o.jsx("span",{className:"type-data-xs text-fg-secondary flex-1 truncate",children:f.isLoading&&X?"Loading 24h history...":f.isBackgroundLoading&&X?f.statusMessage||`Loading ${b} history...`:f.isTopologyLoading?"Loading topology data...":w?"Computing sparklines":C?"Building topology":"Analyzing database"}),null!==(null==X?void 0:X.percent)&&void 0!==(null==X?void 0:X.percent)&&J&&o.jsxs("span",{className:"type-data-xs text-fg-secondary tabular-nums",children:[X.percent,"%"]})]}),o.jsx("div",{className:"mx-1 mt-2 h-2 bg-subtle-fill rounded-full overflow-hidden sparkle-bar-track",children:null!==(null==X?void 0:X.percent)&&void 0!==(null==X?void 0:X.percent)&&J?o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full transition-all duration-300 ease-out overflow-hidden",style:{width:`${X.percent}%`},children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]}):o.jsxs("div",{className:"relative h-full sparkle-bar-fill rounded-full w-full overflow-hidden",children:[o.jsx("div",{className:"sparkle-bar-depth"}),o.jsx("div",{className:"sparkle-bar-sweep"})]})}),o.jsxs("div",{className:"mt-2 flex items-center gap-1.5 px-1",children:[o.jsxs("span",{className:"type-data-xs text-fg-muted tabular-nums",children:[J&&(null==X?void 0:X.loaded)?X.loaded>=1e3?`${(X.loaded/1e3).toFixed(1)}k`:X.loaded.toLocaleString():f.packetCount>=1e3?`${(f.packetCount/1e3).toFixed(1)}k`:f.packetCount.toLocaleString()," pkts"]}),!J&&o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"text-fg-muted/30",children:"·"}),o.jsx("span",{className:"type-data-xs text-sys-blue",children:(e=>{switch(e){case"24h":return"24 hours";case"3d":return"3 days";case"7d":return"7 days";case"14d":return"14 days";default:return e}})(b)})]})]})]})})}),o.jsx("div",{className:"flex-1"}),void 0!==(null==d?void 0:d.uptime_seconds)&&o.jsx("div",{className:"mb-1",children:o.jsxs("div",{className:"flex items-center justify-center px-3 py-1 rounded-full text-sys-blue bg-sys-blue/10 font-mono text-[10px] tracking-wider tabular-nums",children:[Yc(d.uptime_seconds)," uptime"]})}),o.jsx(Fa,{label:"Controls",icon:o.jsx(le,{className:"w-5 h-5 text-sys-blue"}),defaultOpen:!1,direction:"up",dataId:"controls",children:o.jsxs("div",{className:"flex flex-col gap-2",children:[o.jsx(Mt,{color:"success"===M?"success":"error"===M?"danger":"primary",onClick:async()=>{S(!0),N("idle"),T(null);const e=await m();S(!1),e.success?(N("success"),setTimeout(()=>N("idle"),1500)):(N("error"),T(e.error||"Failed to send"),setTimeout(()=>{N("idle"),T(null)},3e3))},disabled:F,className:"w-full justify-center",children:F?o.jsxs(o.Fragment,{children:[o.jsxs("svg",{"data-slot":"icon",className:"animate-spin",viewBox:"0 0 24 24",fill:"none",children:[o.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3"}),o.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]}),"Sending..."]}):"success"===M?o.jsxs(o.Fragment,{children:[o.jsx("svg",{"data-slot":"icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:o.jsx("polyline",{points:"20 6 9 17 4 12"})}),"Sent!"]}):"error"===M?o.jsxs(o.Fragment,{children:[o.jsxs("svg",{"data-slot":"icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",children:[o.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),o.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),"Failed"]}):o.jsxs(o.Fragment,{children:[o.jsx(se,{"data-slot":"icon"}),"Send Advert"]})}),L&&o.jsx("p",{className:"text-sys-red text-xs text-center",children:L}),o.jsxs("div",{className:"flex items-center justify-between gap-2",children:[o.jsx("span",{className:"text-xs text-fg-muted",children:"Repeat"}),o.jsx("span",{className:E("text-xs font-medium","forward"===U?"text-sys-green":"text-sys-indigo"),children:"forward"===U?"ON":"OFF"})]}),o.jsx(Mt,{color:"forward"===U?"success":"warning",onClick:()=>{u("forward"===U?"monitor":"forward")},className:"w-full justify-center",children:"forward"===U?o.jsxs(o.Fragment,{children:[o.jsx(oe,{"data-slot":"icon"}),"Repeating"]}):o.jsxs(o.Fragment,{children:[o.jsx(ie,{"data-slot":"icon"}),"Monitor Only"]})}),o.jsxs("div",{className:"flex items-center justify-between gap-2 mt-1",children:[o.jsx("span",{className:"text-xs text-fg-muted",children:"Duty Cycle"}),o.jsx("span",{className:E("text-xs font-medium tabular-nums",V?"text-sys-indigo":"text-fg-muted"),children:V?`${G}%`:"100%"})]}),o.jsxs(Mt,{color:V?"warning":"muted",onClick:()=>{h(!V)},className:"w-full justify-center",children:[o.jsx(ae,{"data-slot":"icon"}),V?`Limited to ${G}%`:"No Limit"]})]})})]}),o.jsx(ta,{children:o.jsxs("div",{className:"px-3 pt-0.5 pb-3 flex flex-col",children:[o.jsxs("button",{onClick:e=>{e.preventDefault(),null==x||x.close(),c("/sessions")},className:E("group w-full flex items-center gap-3 px-3 py-2 rounded-none bg-surface depth-stroke-raised","hover:bg-elevated hover:text-fg-primary transition-colors","/sessions"===l&&"bg-sys-blue/10"),children:[o.jsx(ce,{className:"w-5 h-5 text-sys-blue flex-shrink-0"}),o.jsx("span",{className:"type-micro text-fg-muted",children:"Sessions"}),o.jsx("span",{className:"ml-auto data-box",children:null!==z?z:"—"})]}),o.jsxs("div",{className:"mt-0.5 rounded-none bg-surface depth-stroke-raised py-2",children:[o.jsxs("div",{className:"flex items-center gap-3 px-3",children:[o.jsx(de,{className:"w-5 h-5 text-sys-blue flex-shrink-0"}),o.jsx("span",{className:"type-micro text-fg-muted flex-1",children:"Noise Floor"}),o.jsx("span",{className:"data-box",children:null!=W?`${W.toFixed(0)} dBm`:"—"})]}),I.length>0&&o.jsx("div",{className:"mt-2.5 px-2",children:o.jsx("div",{className:"relative radius-inner depth-stroke-inset overflow-hidden py-1.5",style:{backgroundColor:"var(--sparkline-bg)"},children:o.jsx(_d,{timestamps:I.map(e=>e.timestamp),values:I.map(e=>e.noise_floor_dbm),compact:!0,height:28})})})]}),(null==d?void 0:d.version)&&o.jsxs("button",{onClick:()=>{navigator.clipboard.writeText(`pyMC_Repeater v${d.version}`),R(!0),setTimeout(()=>R(!1),2e3)},title:`pyMC_Repeater v${d.version} — Click to copy`,className:"mt-0.5 group w-full rounded-none rounded-b-lg bg-surface depth-stroke-raised px-3 py-2 text-left hover:bg-elevated hover:text-fg-primary transition-colors flex items-center gap-2",children:[o.jsxs("span",{className:"type-data-xs text-fg-muted truncate flex-1",children:["pyMC_Repeater v",d.version]}),_?o.jsx(O,{className:"w-3 h-3 text-sys-green flex-shrink-0"}):o.jsx(ue,{className:"w-3 h-3 text-fg-muted opacity-40 group-hover:opacity-70 transition-opacity flex-shrink-0"})]}),o.jsxs("button",{onClick:()=>{an(),window.location.href="/login"},className:"mt-1 group w-full flex items-center gap-3 px-3 py-3.5 radius-inset bg-sys-red/10 text-fg-muted hover:bg-sys-red hover:text-body hover:shadow-none transition-all duration-150",style:{boxShadow:"inset 0 0 0 2px color-mix(in srgb, var(--sys-red) 20%, transparent)"},children:[o.jsx(he,{className:"w-5 h-5 flex-shrink-0"}),o.jsx("span",{className:"type-body-sm !text-inherit",children:"Sign Out"}),g&&o.jsxs("span",{className:"ml-auto type-data-xs !text-inherit",children:["(",g,")"]})]})]})})]})}function _u(){const e=Nl(),t=e.isLoading||e.isBackgroundLoading||e.isTopologyLoading;return o.jsxs(da,{children:[o.jsxs(ua,{children:[o.jsx("h1",{className:"sr-only",children:"pyMC Console"}),o.jsx(Oa,{height:26,className:"block"}),t&&o.jsx(Bc,{className:"ml-2"})]}),o.jsx(ha,{}),o.jsxs(ua,{children:[o.jsx(Nu,{}),o.jsxs("p",{className:"type-data-xs text-fg-muted",children:["v",$a]}),o.jsx(vc,{})]})]})}const Ru=s.memo(function(){const{theme:e}=tt(),{themeId:t,brightness:a}=e,n=Ee(t),r=null==n?void 0:n.meta.backgroundImage,s=null==n?void 0:n.meta.backgroundColor,i=(100-a)/100;return o.jsxs(o.Fragment,{children:[r?o.jsx("div",{className:"fixed inset-0 -z-20",style:{contain:"paint"},"aria-hidden":"true",children:o.jsx("div",{className:"absolute inset-0 bg-cover bg-center bg-no-repeat transition-opacity duration-300 ease-out",style:{backgroundImage:`url(${r})`}})}):s?o.jsx("div",{className:"fixed inset-0 -z-20 transition-colors duration-300 ease-out",style:{backgroundColor:s,contain:"paint"},"aria-hidden":"true"}):null,o.jsx("div",{className:"fixed inset-0 -z-10 bg-black pointer-events-none transition-opacity duration-200 ease-out",style:{opacity:i,contain:"paint"},"aria-hidden":"true"})]})}),zu=20,Pu=12,Iu=s.createContext(null);function $u({children:e}){const[t,a]=s.useState({content:null,mouseX:0,mouseY:0,visible:!1}),n=s.useRef(null),[r,i]=s.useState({x:0,y:0}),l=s.useCallback((e,t,n)=>{a({content:e,mouseX:t,mouseY:n,visible:!0})},[]),c=s.useCallback(()=>{a(e=>({...e,visible:!1}))},[]),d=s.useCallback((e,t)=>{a(a=>a.visible?{...a,mouseX:e,mouseY:t}:a)},[]);s.useEffect(()=>{if(!t.visible||!n.current)return;const e=n.current.getBoundingClientRect(),{mouseX:a,mouseY:r}=t,s=window.innerWidth,o=window.innerHeight;let l,c;l=a+zu+e.width+Pu>s?a-zu-e.width:a+zu,l=Math.max(Pu,Math.min(l,s-e.width-Pu)),c=r-zu-e.height{c.current&&(clearTimeout(c.current),c.current=null)},h=s.useCallback(t=>{u(),c.current=setTimeout(()=>{d.current=!0,n(e,t.clientX,t.clientY)},a)},[n,e,a]),m=s.useCallback(e=>{d.current&&i(e.clientX,e.clientY)},[i]),g=s.useCallback(()=>{u(),d.current=!1,r()},[r]),p=s.useCallback(()=>{if(u(),!l.current)return;const t=l.current.getBoundingClientRect();c.current=setTimeout(()=>{d.current=!0,n(e,t.left+t.width/2,t.top)},a)},[n,e,a]),f=s.useCallback(()=>{u(),d.current=!1,r()},[r]);return s.useEffect(()=>()=>{u(),d.current&&(d.current=!1,r())},[r]),s.useEffect(()=>{const e=()=>{d.current&&(u(),d.current=!1,r())};return document.addEventListener("click",e,!0),()=>document.removeEventListener("click",e,!0)},[r]),o.jsx("span",{ref:l,onMouseEnter:h,onMouseMove:m,onMouseLeave:g,onFocus:p,onBlur:f,className:"contents",children:t})}async function Ou(e,t){const a=`${e}`;ln()&&await un();const n=en(),r=n?{Authorization:`Bearer ${n}`}:{},s=await fetch(a,{...t,headers:{...r,...null==t?void 0:t.headers}});if(!s.ok)throw new Error(`Analytics API error: ${s.status} ${s.statusText}`);return s.json()}async function Hu(e=!1){return Ou("/api/analytics/topology"+(e?"?rebuild=true":""))}let Wu=[];function Uu({label:e}){return o.jsx("div",{className:"min-h-[50vh]","aria-label":`Loading ${e}`,"aria-busy":"true"})}function Vu(){return o.jsx(Uu,{label:"dashboard"})}function Gu(){return o.jsx(Uu,{label:"list"})}function Ju(){return o.jsx(Uu,{label:"map"})}function Ku(){return o.jsx(Uu,{label:"charts"})}function Xu(){return o.jsx(Uu,{label:"settings"})}function Yu(){return o.jsx(Uu,{label:"system"})}function Qu({children:e}){return o.jsx(o.Fragment,{children:e})}F((e,t)=>({backendAvailable:null,checkingBackend:!1,topology:null,topologyLoading:!1,topologyError:null,topologyLastUpdated:0,disambiguationStats:null,disambiguationLoading:!1,lastHopNeighbors:null,neighborsLoading:!1,neighborAffinity:null,affinityLoading:!1,mobileNodes:null,mobileLoading:!1,pathHealth:null,pathHealthLoading:!1,txRecommendation:null,txRecommendationLoading:!1,sparklines:new Map,sparklinesLoading:!1,sparklineHours:168,bucketedStats:null,bucketedStatsPreset:"1h",bucketedStatsLoading:!1,checkBackendAvailability:async()=>{e({checkingBackend:!0});try{const t=await Hu(),a=!1!==t.success&&!t.error;return e({backendAvailable:a,checkingBackend:!1}),a}catch{return e({backendAvailable:!1,checkingBackend:!1}),!1}},fetchTopology:async(t=!1)=>{e({topologyLoading:!0,topologyError:null});try{const a=await Hu(t);if(!1===a.success)return void e({topologyError:a.error||"Failed to fetch topology",topologyLoading:!1});e({topology:a||a,topologyLoading:!1,topologyLastUpdated:Date.now()})}catch(a){e({topologyError:a instanceof Error?a.message:"Failed to fetch topology",topologyLoading:!1})}},fetchDisambiguationStats:async()=>{e({disambiguationLoading:!0});try{const t=await async function(){return Ou("/api/analytics/disambiguation")}();!1!==t.success?e({disambiguationStats:t,disambiguationLoading:!1}):e({disambiguationLoading:!1})}catch{e({disambiguationLoading:!1})}},fetchLastHopNeighbors:async(t=168)=>{e({neighborsLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/last_hop_neighbors?hours=${e}`)}(t);!1!==a.success?e({lastHopNeighbors:a,neighborsLoading:!1}):e({neighborsLoading:!1})}catch{e({neighborsLoading:!1})}},fetchNeighborAffinity:async(t=168)=>{e({affinityLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/neighbor_affinity?hours=${e}`)}(t);!1!==a.success?e({neighborAffinity:a,affinityLoading:!1}):e({affinityLoading:!1})}catch{e({affinityLoading:!1})}},fetchMobileNodes:async(t=168)=>{e({mobileLoading:!0});try{const a=await async function(e=168){return Ou(`/api/analytics/mobile_nodes?hours=${e}`)}(t);!1!==a.success?e({mobileNodes:a,mobileLoading:!1}):e({mobileLoading:!1})}catch{e({mobileLoading:!1})}},fetchPathHealth:async(t=20)=>{e({pathHealthLoading:!0});try{const a=await async function(e=20){return Ou(`/api/analytics/path_health?limit=${e}`)}(t);!1!==a.success?e({pathHealth:a.paths??[],pathHealthLoading:!1}):e({pathHealthLoading:!1})}catch{e({pathHealthLoading:!1})}},fetchTxRecommendation:async(t=24)=>{e({txRecommendationLoading:!0});try{const a=await async function(e=24){return Ou(`/api/analytics/tx_recommendations?hours=${e}`)}(t);!1!==a.success?e({txRecommendation:a,txRecommendationLoading:!1}):e({txRecommendationLoading:!1})}catch{e({txRecommendationLoading:!1})}},fetchSparklines:async(t=168)=>{e({sparklinesLoading:!0,sparklineHours:t});try{const a=await async function(e=168){return Ou(`/api/analytics/sparklines?hours=${e}`)}(t);if(!1!==a.success){const t=a,n=new Map;if(t.sparklines)for(const[e,a]of Object.entries(t.sparklines))n.set(e,a);e({sparklines:n,sparklinesLoading:!1})}else e({sparklinesLoading:!1})}catch{e({sparklinesLoading:!1})}},fetchBucketedStats:async t=>{e({bucketedStatsLoading:!0,bucketedStatsPreset:t});try{const a=await async function(e){return Ou(`/api/analytics/bucketed_stats?preset=${e}`)}(t);!1!==a.success?e({bucketedStats:a,bucketedStatsLoading:!1}):e({bucketedStatsLoading:!1})}catch{e({bucketedStatsLoading:!1})}},initialize:async()=>{if(await t().checkBackendAvailability()&&(await Promise.all([t().fetchTopology(),t().fetchDisambiguationStats(),t().fetchLastHopNeighbors(),t().fetchMobileNodes(),t().fetchPathHealth(),t().fetchSparklines(),t().fetchBucketedStats("1h")]),"undefined"!=typeof window)){const e=setInterval(()=>{t().backendAvailable&&t().fetchTopology()},6e4),a=setInterval(()=>{t().backendAvailable&&t().fetchLastHopNeighbors()},3e4),n=setInterval(()=>{t().backendAvailable&&t().fetchBucketedStats(t().bucketedStatsPreset)},3e4);Wu=[e,a,n]}},refreshAll:async()=>{const{backendAvailable:e}=t();e&&await Promise.all([t().fetchTopology(!0),t().fetchDisambiguationStats(),t().fetchLastHopNeighbors(),t().fetchNeighborAffinity(),t().fetchMobileNodes(),t().fetchPathHealth(),t().fetchTxRecommendation(),t().fetchSparklines(),t().fetchBucketedStats(t().bucketedStatsPreset)])}}));const Zu=s.lazy(()=>A(()=>import("./Login-DV-gJNAt.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11]))),eh=s.lazy(()=>A(()=>import("./Dashboard-Bbh9RnDT.js"),__vite__mapDeps([12,1,2,3,13,4,14,6,8,7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,9,10,11]))),th=s.lazy(()=>A(()=>import("./Packets-DNzcKpej.js"),__vite__mapDeps([34,1,2,3,4,8,18,19,20,14,21,22,23,24,16,25,26,6,27,35,13,28,33,7,9,10,11]))),ah=s.lazy(()=>A(()=>import("./Contacts-CcN2zB34.js").then(e=>e.C),__vite__mapDeps([36,1,2,3,4,37,16,13,38,8,6,28,14,22,23,39,40,26,21,41,42]))),nh=s.lazy(()=>A(()=>import("./Statistics-DEmWOGLC.js"),__vite__mapDeps([43,1,2,3,4,8,14,44,6,28,13,26,15,39,40,29,35,16,24,25,33,7,9,42,10,11]))),rh=s.lazy(()=>A(()=>import("./MeshGraph-BfYUTS82.js"),__vite__mapDeps([45,1,2,3,14,46,25,4,6,8,26,21,17,7,9,10,11]))),sh=s.lazy(()=>A(()=>import("./System-RKAKlnZ6.js"),__vite__mapDeps([47,1,2,3,4,13,7,8,33,6,9,10,11]))),oh=s.lazy(()=>A(()=>import("./Logs-CVA2ZaR8.js"),__vite__mapDeps([48,1,2,3,4,13,8,6,7,9,10,11]))),ih=s.lazy(()=>A(()=>import("./Terminal-DKt0bGFF.js"),__vite__mapDeps([49,1,2,3,4,50,25,37,20,51,5,13,52,53,8,6,7,9,54,10,11]))),lh=s.lazy(()=>A(()=>import("./Configuration-CobIQjJB.js"),__vite__mapDeps([55,1,2,3,4,51,41,8,31,13,26,53,33,7,6,9,10,11]))),ch=s.lazy(()=>A(()=>import("./RoomServer-BvhmmII2.js"),__vite__mapDeps([56,1,2,3,13,4,33,16,8,38,6,52,53,41,32,22,7,9,10,11]))),dh=s.lazy(()=>A(()=>import("./PacketObservatory-DF8DSfgt.js"),__vite__mapDeps([57,1,2,3,24,16,25,4,19,20,7,6,8,9,10,11]))),uh=s.lazy(()=>A(()=>import("./Sessions-DBjQm7_J.js"),__vite__mapDeps([58,1,2,3,4,41,8,26,13,33,7,6,9,10,11])));function hh({children:e}){const t=B(),a=j();return s.useEffect(()=>(Ha=a,()=>{Ha=null}),[a]),nn()?o.jsx(o.Fragment,{children:e}):o.jsx(N,{to:"/login",state:{from:t},replace:!0})}class mh extends s.Component{constructor(e){super(e),this.state={hasError:!1}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}render(){var e;return this.state.hasError?o.jsxs("div",{className:"surface-base rounded-2xl p-8 text-center",children:[o.jsx("p",{className:"type-subheading text-sys-red mb-2",children:"Page failed to render"}),o.jsx("p",{className:"type-body text-fg-muted mb-4",children:(null==(e=this.state.error)?void 0:e.message)||"Unknown error"}),o.jsx("button",{onClick:()=>this.setState({hasError:!1}),className:"px-4 py-2 bg-sys-blue/20 text-sys-blue rounded-lg hover:bg-sys-blue/30 transition-colors",children:"Try Again"})]}):this.props.children}}function gh(){const e=El(),t=nn();return s.useEffect(()=>{if(t)return function(e){e();const t=ks.getState().initialize(),a=Oc.getState().initialize(),n=wc.getState().initialize();mn();const r=setInterval(()=>{mn()},3e4),s=function(){if(gn)return()=>{};if("undefined"==typeof document)return()=>{};const e=async()=>{if("visible"!==document.visibilityState)return;if(!en())return;if(sn())return an(),void("undefined"==typeof window||window.location.pathname.includes("/login")||Wa("token_expired_away"));const e=on();e>0&&e<300&&(await un()||console.warn("[Auth] Token refresh failed on visibility change"))};return document.addEventListener("visibilitychange",e),gn=!0,"visible"===document.visibilityState&&e(),()=>{document.removeEventListener("visibilitychange",e),gn=!1}}();return()=>{t(),n(),null==a||a(),s(),clearInterval(r),Hl(),function(){for(const e of Wu)clearInterval(e);Wu=[]}()}}(e)},[e,t]),o.jsxs($u,{children:[o.jsx(Ru,{}),o.jsxs(S,{children:[o.jsx(M,{path:"/login",element:o.jsx(s.Suspense,{fallback:o.jsx("div",{className:"min-h-screen bg-body"}),children:o.jsx(Zu,{})})}),o.jsx(M,{path:"/*",element:o.jsx(hh,{children:o.jsx(ca,{sidebar:o.jsx(Tu,{}),navbar:o.jsx(_u,{}),children:o.jsx("div",{className:"px-1 sm:px-4 lg:px-4 pt-5 pb-4 sm:pb-6 lg:pb-8 max-w-7xl mx-auto",children:o.jsx(mh,{children:o.jsxs(S,{children:[o.jsx(M,{path:"/",element:o.jsx(s.Suspense,{fallback:o.jsx(Vu,{}),children:o.jsx(Qu,{children:o.jsx(eh,{})})})}),o.jsx(M,{path:"/packets",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(th,{})})})}),o.jsx(M,{path:"/contacts",element:o.jsx(s.Suspense,{fallback:o.jsx(Ju,{}),children:o.jsx(Qu,{children:o.jsx(ah,{})})})}),o.jsx(M,{path:"/statistics",element:o.jsx(s.Suspense,{fallback:o.jsx(Ku,{}),children:o.jsx(Qu,{children:o.jsx(nh,{})})})}),o.jsx(M,{path:"/meshgraph",element:o.jsx(s.Suspense,{fallback:o.jsx(Ku,{}),children:o.jsx(Qu,{children:o.jsx(rh,{})})})}),o.jsx(M,{path:"/system",element:o.jsx(s.Suspense,{fallback:o.jsx(Yu,{}),children:o.jsx(Qu,{children:o.jsx(sh,{})})})}),o.jsx(M,{path:"/logs",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(oh,{})})})}),o.jsx(M,{path:"/terminal",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(ih,{})})})}),o.jsx(M,{path:"/room-server",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(ch,{})})})}),o.jsx(M,{path:"/configuration",element:o.jsx(s.Suspense,{fallback:o.jsx(Xu,{}),children:o.jsx(Qu,{children:o.jsx(lh,{})})})}),o.jsx(M,{path:"/raw",element:o.jsx(s.Suspense,{fallback:o.jsx(Gu,{}),children:o.jsx(Qu,{children:o.jsx(dh,{})})})}),o.jsx(M,{path:"/sessions",element:o.jsx(s.Suspense,{fallback:o.jsx(Xu,{}),children:o.jsx(Qu,{children:o.jsx(uh,{})})})})]})})})})})})]})]})}const ph=console.warn;console.warn=(...e)=>{const t=e[0];"string"==typeof t&&t.includes("Unable to load glyph range")||ph.apply(console,e)},v.createRoot(document.getElementById("root")).render(o.jsx(s.StrictMode,{children:o.jsx(et,{children:o.jsx(L,{children:o.jsx(gh,{})})})}));export{yl as $,dc as A,Mt as B,Ia as C,bi as D,uc as E,lc as F,_l as G,Hi as H,Ta as I,qu as J,ga as K,vc as L,di as M,gi as N,hi as O,mi as P,Un as Q,pi as R,gd as S,Ma as T,pd as U,Qc as V,zl as W,fo as X,Ot as Y,ge as Z,Ut as _,Yt as a,Li as a$,$l as a0,Nl as a1,Is as a2,nt as a3,rt as a4,wt as a5,ad as a6,mr as a7,hr as a8,Dt as a9,Zr as aA,Il as aB,Mc as aC,Wl as aD,it as aE,ot as aF,sc as aG,Cu as aH,Ss as aI,Ms as aJ,Mu as aK,pt as aL,qd as aM,Xe as aN,bu as aO,Zd as aP,eu as aQ,ku as aR,vi as aS,as as aT,rs as aU,$s as aV,Da as aW,pc as aX,yi as aY,ki as aZ,_d as a_,Gi as aa,Rt as ab,Vn as ac,ed as ad,bo as ae,oi as af,ql as ag,pu as ah,yu as ai,td as aj,_s as ak,Xr as al,qr as am,ss as an,ui as ao,Et as ap,sd as aq,st as ar,ns as as,os as at,Ct as au,fl as av,Ml as aw,Ir as ax,$r as ay,Qr as az,Gt as b,Vc as b$,Xt as b0,$a as b1,Ui as b2,Pr as b3,ls as b4,is as b5,hs as b6,cs as b7,es as b8,Yr as b9,Vs as bA,yo as bB,Ks as bC,Zs as bD,eo as bE,Ds as bF,Wt as bG,Kt as bH,Jt as bI,vs as bJ,cn as bK,ks as bL,Fs as bM,tt as bN,xe as bO,go as bP,nd as bQ,rd as bR,_a as bS,Vt as bT,Oc as bU,Qs as bV,Hc as bW,Wc as bX,Kc as bY,Xc as bZ,Uc as b_,yc as ba,me as bb,Zc as bc,Na as bd,vu as be,pe as bf,Pi as bg,Ii as bh,$i as bi,Oi as bj,qi as bk,Yc as bl,Hs as bm,kl as bn,vl as bo,Bl as bp,jl as bq,Di as br,fa as bs,xi as bt,Od as bu,Ls as bv,Os as bw,Us as bx,Js as by,Gs as bz,dd as c,ur as c$,Gc as c0,Jc as c1,pr as c2,fr as c3,yr as c4,br as c5,nc as c6,lr as c7,cr as c8,dr as c9,En as cA,Uo as cB,wo as cC,Co as cD,Gn as cE,Oo as cF,Yn as cG,ko as cH,Wo as cI,Io as cJ,$o as cK,qo as cL,Jn as cM,Qn as cN,Kn as cO,Wn as cP,In as cQ,Ln as cR,Nn as cS,Hn as cT,On as cU,Tn as cV,$n as cW,_n as cX,Rn as cY,Xn as cZ,Ho as c_,Zl as ca,Aa as cb,xa as cc,Ea as cd,fn as ce,zn as cf,Pn as cg,ri as ch,si as ci,qn as cj,zr as ck,gs as cl,ps as cm,fs as cn,Sc as co,pn as cp,Al as cq,wr as cr,Wi as cs,Vi as ct,_i as cu,vn as cv,Mn as cw,Dn as cx,An as cy,xn as cz,Ci as d,nr as d0,rr as d1,sr as d2,or as d3,ar as d4,tr as d5,er as d6,Zn as d7,ir as d8,Xs as d9,Ys as da,fu as db,Hd as dc,Nr as dd,su as de,cu as df,au as dg,ms as dh,Jl as di,Kl as dj,gu as dk,_c as dl,Nc as dm,ws as dn,Tl as dp,io as dq,Or as dr,Hr as ds,Fc as dt,fi as du,Ul as dv,ka as e,ba as f,Ya as g,xt as h,nn as i,ts as j,Ws as k,dn as l,wl as m,Cl as n,Dl as o,bl as p,va as q,Ll as r,Qa as s,Sl as t,hu as u,Rl as v,cc as w,ic as x,bc as y,fc as z}; diff --git a/frontend/dist/assets/link-scoring-oriFkjrN.js b/frontend/dist/assets/link-scoring-C0BjaK96.js similarity index 94% rename from frontend/dist/assets/link-scoring-oriFkjrN.js rename to frontend/dist/assets/link-scoring-C0BjaK96.js index 7c775fc4..ebc8ef25 100644 --- a/frontend/dist/assets/link-scoring-oriFkjrN.js +++ b/frontend/dist/assets/link-scoring-C0BjaK96.js @@ -1 +1 @@ -import{H as t,aF as e,bb as n}from"./index-D7i6lQrq.js";function o(t){if(Array.isArray(t))return t;if("string"==typeof t&&t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}return[]}function r(n,r,s){const a=new Map;for(const e of r){const n=t(e);a.has(n)||a.set(n,e)}const c=new Map,i=new Map;for(const t of n){const n=t.route??t.route_type;if(!e(n))continue;const r=o(t.original_path);if(0===r.length)continue;const f=r.map(t=>t.toUpperCase());if(!t.transmitted&&f.length>=2){const t=f[f.length-2];if(t){const e=a.get(t);e&&i.set(e,(i.get(e)??0)+1)}}if(f.includes(s))for(const t of f){if(t===s)continue;const e=a.get(t);e&&c.set(e,(c.get(e)??0)+1)}}let f=0,u=0;for(const t of r)f=Math.max(f,c.get(t)??0),u=Math.max(u,i.get(t)??0);const h=new Map;let g=0,d=0,l=0;for(const t of r){const e=c.get(t)??0,n=i.get(t)??0,o=f>0?Math.round(e/f*100):0,r=u>0?Math.round(n/u*100):0,s=o+r;h.set(t,{hash:t,listenerCount:e,loudCount:n,listenerScore:o,loudScore:r,blendedScore:s}),g=Math.max(g,o),d=Math.max(d,r),l=Math.max(l,s)}return{scores:h,maxListenerScore:g,maxLoudScore:d,maxBlendedScore:l}}const s={YELLOW:n.amber,GREEN:n.green,RED:n.red,GRAY:"#505050"};export{s as L,r as c}; +import{H as t,aF as e,bb as n}from"./index-CkRTgHHA.js";function o(t){if(Array.isArray(t))return t;if("string"==typeof t&&t.startsWith("["))try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}return[]}function r(n,r,s){const a=new Map;for(const e of r){const n=t(e);a.has(n)||a.set(n,e)}const c=new Map,i=new Map;for(const t of n){const n=t.route??t.route_type;if(!e(n))continue;const r=o(t.original_path);if(0===r.length)continue;const f=r.map(t=>t.toUpperCase());if(!t.transmitted&&f.length>=2){const t=f[f.length-2];if(t){const e=a.get(t);e&&i.set(e,(i.get(e)??0)+1)}}if(f.includes(s))for(const t of f){if(t===s)continue;const e=a.get(t);e&&c.set(e,(c.get(e)??0)+1)}}let f=0,u=0;for(const t of r)f=Math.max(f,c.get(t)??0),u=Math.max(u,i.get(t)??0);const h=new Map;let g=0,d=0,l=0;for(const t of r){const e=c.get(t)??0,n=i.get(t)??0,o=f>0?Math.round(e/f*100):0,r=u>0?Math.round(n/u*100):0,s=o+r;h.set(t,{hash:t,listenerCount:e,loudCount:n,listenerScore:o,loudScore:r,blendedScore:s}),g=Math.max(g,o),d=Math.max(d,r),l=Math.max(l,s)}return{scores:h,maxListenerScore:g,maxLoudScore:d,maxBlendedScore:l}}const s={YELLOW:n.amber,GREEN:n.green,RED:n.red,GRAY:"#505050"};export{s as L,r as c}; diff --git a/frontend/dist/assets/listbox-BG13Q7Di.js b/frontend/dist/assets/listbox-DrzA7Ewq.js similarity index 96% rename from frontend/dist/assets/listbox-BG13Q7Di.js rename to frontend/dist/assets/listbox-DrzA7Ewq.js index c62ea7a7..75128309 100644 --- a/frontend/dist/assets/listbox-BG13Q7Di.js +++ b/frontend/dist/assets/listbox-DrzA7Ewq.js @@ -1 +1 @@ -import{j as e,i as s,l as a,n as t,o as r,I as n,r as o}from"./vendor-react-alRNW2nb.js";import{c as i}from"./vendor-core-FtpmsTnh.js";import{b0 as l}from"./index-D7i6lQrq.js";import{C as c,a as d}from"./vendor-icons-TO0PZKGR.js";import{A as m,m as u}from"./vendor-motion-DNp0Qg4F.js";function p({value:n,onChange:o,className:d,placeholder:p,disabled:x,"aria-label":b,children:f}){return e.jsx(s,{value:n,onChange:o,disabled:x,children:({open:s})=>e.jsxs("div",{className:i("relative",d),children:[e.jsxs(a,{"aria-label":b,className:i(["relative flex w-full items-center justify-between gap-2","radius-inner px-3 py-2","text-left text-sm text-fg-primary","bg-input-bg border border-input-border","ring-focus-inset","hover:border-edge-strong","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-colors"]),children:[e.jsx(t,{as:"span",options:f,placeholder:p&&e.jsx("span",{className:"text-fg-muted",children:p}),className:"block truncate"}),e.jsx(c,{className:i("w-4 h-4 text-fg-muted transition-transform duration-200",s&&"rotate-180")})]}),e.jsx(m,{children:s&&e.jsx(u.div,{initial:{opacity:0,y:-4,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.98},transition:l.dropdown,className:"absolute z-50 mt-1",children:e.jsx(r,{static:!0,anchor:"bottom start",className:i(["w-[var(--button-width)] min-w-[180px]","max-h-60 overflow-y-auto overscroll-contain scroll-py-1","radius-inset p-1","surface-elevated","focus:outline-none"]),children:f})})})]})})}function x({value:s,disabled:a,className:t,children:r}){return e.jsx(n,{as:o.Fragment,value:s,disabled:a,children:({selected:s,focus:n})=>e.jsxs("div",{className:i("flex items-center gap-2 px-3 py-2 radius-control cursor-default","text-sm",n&&"bg-sys-blue text-white",!n&&"text-fg-primary",s&&!n&&"text-sys-blue",a&&"opacity-50 cursor-not-allowed",t),children:[e.jsx("span",{className:"w-4 flex-shrink-0",children:s&&e.jsx(d,{className:"w-4 h-4"})}),e.jsx("span",{className:"truncate",children:r})]})})}function b({className:s,...a}){return e.jsx("span",{...a,className:i("truncate",s)})}export{p as L,x as a,b}; +import{j as e,i as s,l as a,n as t,o as r,I as n,r as o}from"./vendor-react-alRNW2nb.js";import{c as i}from"./vendor-core-FtpmsTnh.js";import{b0 as l}from"./index-CkRTgHHA.js";import{C as c,a as d}from"./vendor-icons-TO0PZKGR.js";import{A as m,m as u}from"./vendor-motion-DNp0Qg4F.js";function p({value:n,onChange:o,className:d,placeholder:p,disabled:x,"aria-label":b,children:f}){return e.jsx(s,{value:n,onChange:o,disabled:x,children:({open:s})=>e.jsxs("div",{className:i("relative",d),children:[e.jsxs(a,{"aria-label":b,className:i(["relative flex w-full items-center justify-between gap-2","radius-inner px-3 py-2","text-left text-sm text-fg-primary","bg-input-bg border border-input-border","ring-focus-inset","hover:border-edge-strong","disabled:opacity-40 disabled:pointer-events-none disabled:cursor-not-allowed","transition-colors"]),children:[e.jsx(t,{as:"span",options:f,placeholder:p&&e.jsx("span",{className:"text-fg-muted",children:p}),className:"block truncate"}),e.jsx(c,{className:i("w-4 h-4 text-fg-muted transition-transform duration-200",s&&"rotate-180")})]}),e.jsx(m,{children:s&&e.jsx(u.div,{initial:{opacity:0,y:-4,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:-4,scale:.98},transition:l.dropdown,className:"absolute z-50 mt-1",children:e.jsx(r,{static:!0,anchor:"bottom start",className:i(["w-[var(--button-width)] min-w-[180px]","max-h-60 overflow-y-auto overscroll-contain scroll-py-1","radius-inset p-1","surface-elevated","focus:outline-none"]),children:f})})})]})})}function x({value:s,disabled:a,className:t,children:r}){return e.jsx(n,{as:o.Fragment,value:s,disabled:a,children:({selected:s,focus:n})=>e.jsxs("div",{className:i("flex items-center gap-2 px-3 py-2 radius-control cursor-default","text-sm",n&&"bg-sys-blue text-white",!n&&"text-fg-primary",s&&!n&&"text-sys-blue",a&&"opacity-50 cursor-not-allowed",t),children:[e.jsx("span",{className:"w-4 flex-shrink-0",children:s&&e.jsx(d,{className:"w-4 h-4"})}),e.jsx("span",{className:"truncate",children:r})]})})}function b({className:s,...a}){return e.jsx("span",{...a,className:i("truncate",s)})}export{p as L,x as a,b}; diff --git a/frontend/dist/assets/node-types-CiI69Tya.js b/frontend/dist/assets/node-types-DRVunROD.js similarity index 94% rename from frontend/dist/assets/node-types-CiI69Tya.js rename to frontend/dist/assets/node-types-DRVunROD.js index de9962f8..614e21ce 100644 --- a/frontend/dist/assets/node-types-CiI69Tya.js +++ b/frontend/dist/assets/node-types-DRVunROD.js @@ -1 +1 @@ -import{ar as e}from"./index-D7i6lQrq.js";function r(e){var r;const o=(null==(r=e.contact_type)?void 0:r.toLowerCase())??"";return"room server"===o||"room_server"===o||"room"===o||"server"===o?{type:"room_server",isRepeater:!0===e.is_repeater,isCompanion:!1,isRoomServer:!0,isClient:!1,label:"Room Server",badgeText:"ROOM"}:"companion"===o||"chat node"===o||"chat_node"===o||"chat"===o?{type:"companion",isRepeater:!1,isCompanion:!0,isRoomServer:!1,isClient:!1,label:"Companion",badgeText:"COMP"}:"client"===o||"cli"===o?{type:"companion",isRepeater:!1,isCompanion:!1,isRoomServer:!1,isClient:!0,label:"Client",badgeText:"CLI"}:"repeater"===o||"rep"===o||!0===e.is_repeater?{type:"repeater",isRepeater:!0,isCompanion:!1,isRoomServer:!1,isClient:!1,label:"Repeater",badgeText:"RPT"}:{type:"unknown",isRepeater:!1,isCompanion:!1,isRoomServer:!1,isClient:!1,label:"Unknown",badgeText:""}}function o(r){switch(r){case e.GRP_TXT:case e.TXT_MSG:case e.REQ:case e.ANON_REQ:return"companion";case e.TRACE:case e.PATH:return"repeater";case e.GRP_DATA:return"room_server";default:return"unknown"}}function n(e){switch(e){case 1:return"companion";case 2:return"repeater";case 3:return"room_server";default:return"unknown"}}export{r as c,o as i,n as m}; +import{ar as e}from"./index-CkRTgHHA.js";function r(e){var r;const o=(null==(r=e.contact_type)?void 0:r.toLowerCase())??"";return"room server"===o||"room_server"===o||"room"===o||"server"===o?{type:"room_server",isRepeater:!0===e.is_repeater,isCompanion:!1,isRoomServer:!0,isClient:!1,label:"Room Server",badgeText:"ROOM"}:"companion"===o||"chat node"===o||"chat_node"===o||"chat"===o?{type:"companion",isRepeater:!1,isCompanion:!0,isRoomServer:!1,isClient:!1,label:"Companion",badgeText:"COMP"}:"client"===o||"cli"===o?{type:"companion",isRepeater:!1,isCompanion:!1,isRoomServer:!1,isClient:!0,label:"Client",badgeText:"CLI"}:"repeater"===o||"rep"===o||!0===e.is_repeater?{type:"repeater",isRepeater:!0,isCompanion:!1,isRoomServer:!1,isClient:!1,label:"Repeater",badgeText:"RPT"}:{type:"unknown",isRepeater:!1,isCompanion:!1,isRoomServer:!1,isClient:!1,label:"Unknown",badgeText:""}}function o(r){switch(r){case e.GRP_TXT:case e.TXT_MSG:case e.REQ:case e.ANON_REQ:return"companion";case e.TRACE:case e.PATH:return"repeater";case e.GRP_DATA:return"room_server";default:return"unknown"}}function n(e){switch(e){case 1:return"companion";case 2:return"repeater";case 3:return"room_server";default:return"unknown"}}export{r as c,o as i,n as m}; diff --git a/frontend/dist/assets/payload-decoders-DjZO58V7.js b/frontend/dist/assets/payload-decoders-_TRhCJrs.js similarity index 99% rename from frontend/dist/assets/payload-decoders-DjZO58V7.js rename to frontend/dist/assets/payload-decoders-_TRhCJrs.js index f4b04bd3..cd9cd8d7 100644 --- a/frontend/dist/assets/payload-decoders-DjZO58V7.js +++ b/frontend/dist/assets/payload-decoders-_TRhCJrs.js @@ -1 +1 @@ -var t=Object.defineProperty,e=(e,a,s)=>((e,a,s)=>a in e?t(e,a,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[a]=s)(e,"symbol"!=typeof a?a+"":a,s);import{ae as a,cv as s,cw as r,cx as n,cy as h,ac as c,cz as i,cA as o,c9 as p,c7 as l,c8 as u,cB as d,cC as y,bB as g,cD as f,cE as m,cF as x,cG as T,cH as H,cI as C,cJ as w,cK as L,cL as S,cM as N,cN as b,cO as A,cP as _,cQ as $,cR as V,cS as F,cT as U,cU as D,cg as E,cf as M,cV as v,cj as P,cW as B,cX as O,cY as R,cZ as j,c_ as k,c$ as I,d0 as K,d1 as W,d2 as q,d3 as Q,ch as z,ci as G,d4 as J,d5 as X,d6 as Y,d7 as Z,d8 as tt}from"./index-D7i6lQrq.js";class et{constructor(){e(this,"header",0),e(this,"transportCodes",[0,0]),e(this,"pathLen",0),e(this,"path",new Uint8Array(0)),e(this,"payload",new Uint8Array(0)),e(this,"decrypted",{}),e(this,"_rssi",0),e(this,"_snr",0)}static fromBytes(t){const e=new et;try{return e.readFrom(t),{success:!0,packet:e}}catch(a){return{success:!1,error:a instanceof Error?a.message:String(a)}}}static fromHex(t){try{const e=a(t);return et.fromBytes(e)}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}get routeType(){return this.header&s}get routeTypeName(){return r[this.routeType]??`UNKNOWN(${this.routeType})`}get payloadType(){return this.header>>n&h}get payloadTypeName(){return c[this.payloadType]??`UNKNOWN(${this.payloadType})`}get payloadVersion(){return this.header>>i&o}hasTransportCodes(){return p(this.routeType)}isFlood(){return l(this.routeType)}isDirect(){return u(this.routeType)}get pathBytes(){return Array.from(this.path)}get pathString(){return d(this.path)}get pathHexArray(){return Array.from(this.path).map(t=>y(t,!0))}get payloadLen(){return this.payload.length}get payloadHex(){return g(this.payload,!0)}getPayloadAppData(){const t=N+b+A;return this.payload.length>=t?this.payload.slice(t):new Uint8Array(0)}get rssi(){return this._rssi}set rssi(t){this._rssi=t}get snr(){return this._snr}set snr(t){this._snr=t}readFrom(t){let e=0;const a=t.length;f(e,1,a,"Missing header byte"),this.header=t[e++];const s=this.payloadVersion;if(s>m)throw new Error(`Unsupported packet version: ${s}`);if(this.hasTransportCodes()?(f(e,4,a,"Missing transport codes"),this.transportCodes=[x(t,e),x(t,e+2)],e+=4):this.transportCodes=[0,0],f(e,1,a,"Missing path_len"),this.pathLen=t[e++],this.pathLen>T)throw new Error(`path_len too large: ${this.pathLen} > ${T}`);return f(e,this.pathLen,a,"Truncated path"),this.path=t.slice(e,e+this.pathLen),e+=this.pathLen,this.payload=t.slice(e),H(this.payload.length),!0}writeTo(){let t=1;this.hasTransportCodes()&&(t+=4),t+=1,t+=this.path.length,t+=this.payload.length;const e=new Uint8Array(t);let a=0;return e[a++]=this.header,this.hasTransportCodes()&&(C(this.transportCodes[0],e,a),C(this.transportCodes[1],e,a+2),a+=4),e[a++]=this.path.length,e.set(this.path,a),a+=this.path.length,e.set(this.payload,a),e}toHex(){return g(this.writeTo(),!0)}async calculateHash(){return w(this.payloadType,this.pathLen,this.payload)}async calculateHashString(t){return L(this.payloadType,this.pathLen,this.payload,t)}async calculateCRC(){return S(this.payloadType,this.pathLen,this.payload)}getRawLength(){let t=2+this.pathLen+this.payload.length;return this.hasTransportCodes()&&(t+=4),t}getSummary(){return{header:y(this.header,!0),routeType:this.routeTypeName,payloadType:this.payloadTypeName,version:this.payloadVersion,pathLen:this.pathLen,pathStr:this.pathString,transportCodes:this.hasTransportCodes()?[this.transportCodes[0].toString(16).toUpperCase().padStart(4,"0"),this.transportCodes[1].toString(16).toUpperCase().padStart(4,"0")]:null,payloadLen:this.payload.length,payloadHex:this.payloadHex,rawLength:this.getRawLength()}}toString(){const t=[`[${this.routeTypeName}/${this.payloadTypeName} v${this.payloadVersion}]`,`path=${this.pathString||"(empty)"}`,`payload=${this.payload.length}B`];return this.hasTransportCodes()&&t.push(`transport=[${this.transportCodes[0]},${this.transportCodes[1]}]`),t.join(" ")}}function at(t){const e=N+b+A+1;if(t.lengtha&&(o.name=(new TextDecoder).decode(t.slice(a,e)))}return o}function st(t,e){const a=function(t){if(t.length<9)return{type:"trace",traceTag:"00000000",traceTagValue:0,authCode:0,flags:0,pathHashes:[],pathString:"",snrValues:[],isComplete:!1,path:[],targetHash:""};const e=k(t,0),a=e.toString(16).toUpperCase().padStart(8,"0"),s=k(t,4),r=t[8],n=t.slice(9),h=Array.from(n).map(t=>y(t,!0)),c=h.join("->");return{type:"trace",traceTag:a,traceTagValue:e,authCode:s,flags:r,pathHashes:h,pathString:c,snrValues:[],isComplete:!1,path:h,targetHash:h.length>0?h[0]:""}}(t);if(!a)return null;const s=[],r=e instanceof Uint8Array?Array.from(e):e;for(let h=0;h127&&(t-=256);const e=t/4;s.push(Math.max(-20,Math.min(15,e)))}const n=s.length>=a.pathHashes.length;return{...a,snrValues:s,isComplete:n}}function rt(t,e=0){const a=e>=1?2:1,s=j,r=2*a+s;if(t.length=1?4:j,s=1+a+1;if(t.length=5){i.channelName=t.channelName;const e=t.plaintext,a=k(e,0),s=e[4],r=new TextDecoder("utf-8",{fatal:!1}).decode(e.slice(5)).replace(/\uFFFD/g,"").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g,"").replace(/\x00+$/,"").trim();i.decrypted=!0,i.isPublicHashChannel=!0,i.timestamp=a,i.flags=s,t.macCorrupted&&(i.macCorrupted=!0);const n=r.indexOf(": ");n>0?(i.senderName=r.slice(0,n),i.text=r.slice(n+2)):i.text=r}else{const t=await G(r);i.isPublicHashChannel=t.length>0}}catch{}return i}async function ht(t){if(t.length<1+j+1)return null;const e=t[0],a=y(e,!0),s=t.slice(1,1+j),r=t.slice(1+j),n={type:"grp_data",channelHash:a,dataHex:g(r),dataLength:r.length,decrypted:!1,macHex:g(s)};try{const t=await z(e,s,r);t&&(n.channelName=t.channelName,n.decrypted=!0,n.decryptedHex=g(t.plaintext))}catch{}return n}function ct(t,e,a){return{type:"generic",payloadType:e,payloadTypeName:a,rawHex:g(t),length:t.length}}function it(t){const{payload:e,payloadType:a,payloadTypeName:s}=t;switch(a){case R:return at(e)??ct(e,a,s);case O:return function(t){if(t.length<4)return null;const e=k(t,0);return{type:"ack",crc:e.toString(16).toUpperCase().padStart(8,"0"),crcValue:e}}(e)??ct(e,a,s);case B:return function(t){if(0===t.length)return{type:"path",pathLength:0,path:[],pathString:""};const e=t[0];if(t.length<1+e+1){const a=Math.min(e,t.length-1),s=Array.from(t.slice(1,1+a)).map(t=>y(t,!0));return{type:"path",pathLength:e,path:s,pathString:s.join("->")}}const a=Array.from(t.slice(1,1+e)).map(t=>y(t,!0)),s=a.join("->"),r=t[1+e],n=c[r]??`UNKNOWN(${r})`;let h;return t.length>1+e+1&&(h=g(t.slice(1+e+1))),{type:"path",pathLength:e,path:a,pathString:s,extraType:r,extraTypeName:n,extraData:h}}(e)??ct(e,a,s);case P:return st(e,t.path)??ct(e,a,s);case v:return rt(e,t.payloadVersion)??ct(e,a,s);case M:return function(t,e=0){const a=e>=1?4:j,s=1+a+1;if(t.length>4&15,s=15&e,r={8:"DISCOVER_REQ",9:"DISCOVER_RESP"}[a]??`0x${a.toString(16)}`;return{type:"control",controlType:e,subtype:a,subtypeFlags:s,subtypeName:r,dataHex:g(t.slice(1)),dataLength:t.length-1,isInternal:a>=8}}(e)??ct(e,a,s);case F:return function(t){if(t.length<4)return null;const e=y(t[0],!0),a=y(t[1],!0),s=g(t.slice(2,4)),r=t.slice(4);return{type:"req",destHash:e,srcHash:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);case V:return function(t){if(t.length<4)return null;const e=y(t[0],!0),a=y(t[1],!0),s=g(t.slice(2,4)),r=t.slice(4);return{type:"response",destHash:e,srcHash:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);case $:return function(t){if(t.length<35)return null;const e=y(t[0],!0),a=g(t.slice(1,33)),s=g(t.slice(33,35)),r=t.slice(35);return{type:"anon_req",destHash:e,senderPublicKey:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);default:return ct(e,a,s)}}export{et as P,nt as a,ht as b,it as c,rt as d,st as e,at as f}; +var t=Object.defineProperty,e=(e,a,s)=>((e,a,s)=>a in e?t(e,a,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[a]=s)(e,"symbol"!=typeof a?a+"":a,s);import{ae as a,cv as s,cw as r,cx as n,cy as h,ac as c,cz as i,cA as o,c9 as p,c7 as l,c8 as u,cB as d,cC as y,bB as g,cD as f,cE as m,cF as x,cG as T,cH as H,cI as C,cJ as w,cK as L,cL as S,cM as N,cN as b,cO as A,cP as _,cQ as $,cR as V,cS as F,cT as U,cU as D,cg as E,cf as M,cV as v,cj as P,cW as B,cX as O,cY as R,cZ as j,c_ as k,c$ as I,d0 as K,d1 as W,d2 as q,d3 as Q,ch as z,ci as G,d4 as J,d5 as X,d6 as Y,d7 as Z,d8 as tt}from"./index-CkRTgHHA.js";class et{constructor(){e(this,"header",0),e(this,"transportCodes",[0,0]),e(this,"pathLen",0),e(this,"path",new Uint8Array(0)),e(this,"payload",new Uint8Array(0)),e(this,"decrypted",{}),e(this,"_rssi",0),e(this,"_snr",0)}static fromBytes(t){const e=new et;try{return e.readFrom(t),{success:!0,packet:e}}catch(a){return{success:!1,error:a instanceof Error?a.message:String(a)}}}static fromHex(t){try{const e=a(t);return et.fromBytes(e)}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}get routeType(){return this.header&s}get routeTypeName(){return r[this.routeType]??`UNKNOWN(${this.routeType})`}get payloadType(){return this.header>>n&h}get payloadTypeName(){return c[this.payloadType]??`UNKNOWN(${this.payloadType})`}get payloadVersion(){return this.header>>i&o}hasTransportCodes(){return p(this.routeType)}isFlood(){return l(this.routeType)}isDirect(){return u(this.routeType)}get pathBytes(){return Array.from(this.path)}get pathString(){return d(this.path)}get pathHexArray(){return Array.from(this.path).map(t=>y(t,!0))}get payloadLen(){return this.payload.length}get payloadHex(){return g(this.payload,!0)}getPayloadAppData(){const t=N+b+A;return this.payload.length>=t?this.payload.slice(t):new Uint8Array(0)}get rssi(){return this._rssi}set rssi(t){this._rssi=t}get snr(){return this._snr}set snr(t){this._snr=t}readFrom(t){let e=0;const a=t.length;f(e,1,a,"Missing header byte"),this.header=t[e++];const s=this.payloadVersion;if(s>m)throw new Error(`Unsupported packet version: ${s}`);if(this.hasTransportCodes()?(f(e,4,a,"Missing transport codes"),this.transportCodes=[x(t,e),x(t,e+2)],e+=4):this.transportCodes=[0,0],f(e,1,a,"Missing path_len"),this.pathLen=t[e++],this.pathLen>T)throw new Error(`path_len too large: ${this.pathLen} > ${T}`);return f(e,this.pathLen,a,"Truncated path"),this.path=t.slice(e,e+this.pathLen),e+=this.pathLen,this.payload=t.slice(e),H(this.payload.length),!0}writeTo(){let t=1;this.hasTransportCodes()&&(t+=4),t+=1,t+=this.path.length,t+=this.payload.length;const e=new Uint8Array(t);let a=0;return e[a++]=this.header,this.hasTransportCodes()&&(C(this.transportCodes[0],e,a),C(this.transportCodes[1],e,a+2),a+=4),e[a++]=this.path.length,e.set(this.path,a),a+=this.path.length,e.set(this.payload,a),e}toHex(){return g(this.writeTo(),!0)}async calculateHash(){return w(this.payloadType,this.pathLen,this.payload)}async calculateHashString(t){return L(this.payloadType,this.pathLen,this.payload,t)}async calculateCRC(){return S(this.payloadType,this.pathLen,this.payload)}getRawLength(){let t=2+this.pathLen+this.payload.length;return this.hasTransportCodes()&&(t+=4),t}getSummary(){return{header:y(this.header,!0),routeType:this.routeTypeName,payloadType:this.payloadTypeName,version:this.payloadVersion,pathLen:this.pathLen,pathStr:this.pathString,transportCodes:this.hasTransportCodes()?[this.transportCodes[0].toString(16).toUpperCase().padStart(4,"0"),this.transportCodes[1].toString(16).toUpperCase().padStart(4,"0")]:null,payloadLen:this.payload.length,payloadHex:this.payloadHex,rawLength:this.getRawLength()}}toString(){const t=[`[${this.routeTypeName}/${this.payloadTypeName} v${this.payloadVersion}]`,`path=${this.pathString||"(empty)"}`,`payload=${this.payload.length}B`];return this.hasTransportCodes()&&t.push(`transport=[${this.transportCodes[0]},${this.transportCodes[1]}]`),t.join(" ")}}function at(t){const e=N+b+A+1;if(t.lengtha&&(o.name=(new TextDecoder).decode(t.slice(a,e)))}return o}function st(t,e){const a=function(t){if(t.length<9)return{type:"trace",traceTag:"00000000",traceTagValue:0,authCode:0,flags:0,pathHashes:[],pathString:"",snrValues:[],isComplete:!1,path:[],targetHash:""};const e=k(t,0),a=e.toString(16).toUpperCase().padStart(8,"0"),s=k(t,4),r=t[8],n=t.slice(9),h=Array.from(n).map(t=>y(t,!0)),c=h.join("->");return{type:"trace",traceTag:a,traceTagValue:e,authCode:s,flags:r,pathHashes:h,pathString:c,snrValues:[],isComplete:!1,path:h,targetHash:h.length>0?h[0]:""}}(t);if(!a)return null;const s=[],r=e instanceof Uint8Array?Array.from(e):e;for(let h=0;h127&&(t-=256);const e=t/4;s.push(Math.max(-20,Math.min(15,e)))}const n=s.length>=a.pathHashes.length;return{...a,snrValues:s,isComplete:n}}function rt(t,e=0){const a=e>=1?2:1,s=j,r=2*a+s;if(t.length=1?4:j,s=1+a+1;if(t.length=5){i.channelName=t.channelName;const e=t.plaintext,a=k(e,0),s=e[4],r=new TextDecoder("utf-8",{fatal:!1}).decode(e.slice(5)).replace(/\uFFFD/g,"").replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g,"").replace(/\x00+$/,"").trim();i.decrypted=!0,i.isPublicHashChannel=!0,i.timestamp=a,i.flags=s,t.macCorrupted&&(i.macCorrupted=!0);const n=r.indexOf(": ");n>0?(i.senderName=r.slice(0,n),i.text=r.slice(n+2)):i.text=r}else{const t=await G(r);i.isPublicHashChannel=t.length>0}}catch{}return i}async function ht(t){if(t.length<1+j+1)return null;const e=t[0],a=y(e,!0),s=t.slice(1,1+j),r=t.slice(1+j),n={type:"grp_data",channelHash:a,dataHex:g(r),dataLength:r.length,decrypted:!1,macHex:g(s)};try{const t=await z(e,s,r);t&&(n.channelName=t.channelName,n.decrypted=!0,n.decryptedHex=g(t.plaintext))}catch{}return n}function ct(t,e,a){return{type:"generic",payloadType:e,payloadTypeName:a,rawHex:g(t),length:t.length}}function it(t){const{payload:e,payloadType:a,payloadTypeName:s}=t;switch(a){case R:return at(e)??ct(e,a,s);case O:return function(t){if(t.length<4)return null;const e=k(t,0);return{type:"ack",crc:e.toString(16).toUpperCase().padStart(8,"0"),crcValue:e}}(e)??ct(e,a,s);case B:return function(t){if(0===t.length)return{type:"path",pathLength:0,path:[],pathString:""};const e=t[0];if(t.length<1+e+1){const a=Math.min(e,t.length-1),s=Array.from(t.slice(1,1+a)).map(t=>y(t,!0));return{type:"path",pathLength:e,path:s,pathString:s.join("->")}}const a=Array.from(t.slice(1,1+e)).map(t=>y(t,!0)),s=a.join("->"),r=t[1+e],n=c[r]??`UNKNOWN(${r})`;let h;return t.length>1+e+1&&(h=g(t.slice(1+e+1))),{type:"path",pathLength:e,path:a,pathString:s,extraType:r,extraTypeName:n,extraData:h}}(e)??ct(e,a,s);case P:return st(e,t.path)??ct(e,a,s);case v:return rt(e,t.payloadVersion)??ct(e,a,s);case M:return function(t,e=0){const a=e>=1?4:j,s=1+a+1;if(t.length>4&15,s=15&e,r={8:"DISCOVER_REQ",9:"DISCOVER_RESP"}[a]??`0x${a.toString(16)}`;return{type:"control",controlType:e,subtype:a,subtypeFlags:s,subtypeName:r,dataHex:g(t.slice(1)),dataLength:t.length-1,isInternal:a>=8}}(e)??ct(e,a,s);case F:return function(t){if(t.length<4)return null;const e=y(t[0],!0),a=y(t[1],!0),s=g(t.slice(2,4)),r=t.slice(4);return{type:"req",destHash:e,srcHash:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);case V:return function(t){if(t.length<4)return null;const e=y(t[0],!0),a=y(t[1],!0),s=g(t.slice(2,4)),r=t.slice(4);return{type:"response",destHash:e,srcHash:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);case $:return function(t){if(t.length<35)return null;const e=y(t[0],!0),a=g(t.slice(1,33)),s=g(t.slice(33,35)),r=t.slice(35);return{type:"anon_req",destHash:e,senderPublicKey:a,cipherMac:s,ciphertextHex:g(r),ciphertextLength:r.length}}(e)??ct(e,a,s);default:return ct(e,a,s)}}export{et as P,nt as a,ht as b,it as c,rt as d,st as e,at as f}; diff --git a/frontend/dist/assets/ping-5xLx9WS1.js b/frontend/dist/assets/ping-DPgnsJJf.js similarity index 94% rename from frontend/dist/assets/ping-5xLx9WS1.js rename to frontend/dist/assets/ping-DPgnsJJf.js index b957473f..8f118c03 100644 --- a/frontend/dist/assets/ping-5xLx9WS1.js +++ b/frontend/dist/assets/ping-DPgnsJJf.js @@ -1 +1 @@ -import{bM as t}from"./index-D7i6lQrq.js";async function e(e,r=10){return t("/api/ping_neighbor",{method:"POST",body:JSON.stringify({target_id:e,timeout:r})})}const r=["Chat Node","Repeater","Room Server","Hybrid Node","Unknown"];async function s(s,o=10){if(o<1||o>60)return{success:!1,error:"Timeout must be 1-60 seconds"};let n;const a=s.match(/^(0x)?([0-9a-fA-F]{1,2})$/);if(a)n=`0x${a[2].padStart(2,"0")}`;else{const e=await async function(e){const s=e.toLowerCase();for(const o of r)try{const e=await t(`/api/adverts_by_contact_type?contact_type=${encodeURIComponent(o)}&hours=168`),r=e.success&&e.data?e.data:e,n=(Array.isArray(r)?r:[]).find(t=>t.node_name&&t.node_name.toLowerCase()===s);if(n&&n.pubkey)return`0x${n.pubkey.substring(0,2)}`}catch{continue}return null}(s);if(!e)return{success:!1,error:`Node '${s}' not found`};n=e}const c=await e(n,o);if(!c.success||!c.data)return{success:!1,error:c.error||"Ping failed"};const i=(u=c.data).rtt_ms>500||u.rssi<-120?"Poor":u.rtt_ms>250||u.rssi<-100?"Fair":u.rtt_ms>100||u.rssi<-80?"Good":"Excellent";var u;return{success:!0,data:{...c.data,quality:i}}}export{s as a,e as p}; +import{bM as t}from"./index-CkRTgHHA.js";async function e(e,r=10){return t("/api/ping_neighbor",{method:"POST",body:JSON.stringify({target_id:e,timeout:r})})}const r=["Chat Node","Repeater","Room Server","Hybrid Node","Unknown"];async function s(s,o=10){if(o<1||o>60)return{success:!1,error:"Timeout must be 1-60 seconds"};let n;const a=s.match(/^(0x)?([0-9a-fA-F]{1,2})$/);if(a)n=`0x${a[2].padStart(2,"0")}`;else{const e=await async function(e){const s=e.toLowerCase();for(const o of r)try{const e=await t(`/api/adverts_by_contact_type?contact_type=${encodeURIComponent(o)}&hours=168`),r=e.success&&e.data?e.data:e,n=(Array.isArray(r)?r:[]).find(t=>t.node_name&&t.node_name.toLowerCase()===s);if(n&&n.pubkey)return`0x${n.pubkey.substring(0,2)}`}catch{continue}return null}(s);if(!e)return{success:!1,error:`Node '${s}' not found`};n=e}const c=await e(n,o);if(!c.success||!c.data)return{success:!1,error:c.error||"Ping failed"};const i=(u=c.data).rtt_ms>500||u.rssi<-120?"Poor":u.rtt_ms>250||u.rssi<-100?"Fair":u.rtt_ms>100||u.rssi<-80?"Good":"Excellent";var u;return{success:!0,data:{...c.data,quality:i}}}export{s as a,e as p}; diff --git a/frontend/dist/assets/primitives-YN2ynYwE.js b/frontend/dist/assets/primitives-Bgn6Ik6L.js similarity index 98% rename from frontend/dist/assets/primitives-YN2ynYwE.js rename to frontend/dist/assets/primitives-Bgn6Ik6L.js index 70969303..9f6ed851 100644 --- a/frontend/dist/assets/primitives-YN2ynYwE.js +++ b/frontend/dist/assets/primitives-Bgn6Ik6L.js @@ -1 +1 @@ -import{P as e,c as t,e as s,f as n}from"./payload-decoders-DjZO58V7.js";import{a8 as r,a7 as a,ae as l,cr as o,Q as i,cb as c,cc as d,cd as p}from"./index-D7i6lQrq.js";import{j as u,r as x}from"./vendor-react-alRNW2nb.js";function g(s){if(!s||s.length<4)return null;const n=e.fromHex(s);if(!n.success||!n.packet)return null;const l=n.packet,o=function(e){const t=3&e,s=e>>2&15,n=e>>6&3;return[{bits:"0-1",field:"Route Type",value:r(t),binary:(3&t).toString(2).padStart(2,"0")},{bits:"2-5",field:"Payload Type",value:a(s),binary:(15&s).toString(2).padStart(4,"0")},{bits:"6-7",field:"Version",value:n.toString(),binary:(3&n).toString(2).padStart(2,"0")}]}(l.header),i=s.slice(0,2);let c=2,d="";l.hasTransportCodes()&&(d=s.slice(2,10),c=10);const p=s.slice(c,c+2),u=c+2,x=u+2*l.pathLen,g=s.slice(u,x),m=s.slice(x),f=t(l);return{packet:l,headerHex:i,headerFields:o,transportCodesHex:d,pathLengthHex:p,pathDataHex:g,payloadHex:m,pathLenByteOffset:Math.floor(c/2),pathByteOffset:Math.floor(u/2),payloadStartByte:Math.floor(x/2),decoded:f}}function m(e){if(!e||e.length<8)return null;const t=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),n=parseInt(e.slice(4,6),16),r=parseInt(e.slice(6,8),16);return isNaN(t)||isNaN(s)||isNaN(n)||isNaN(r)?null:((t|s<<8|n<<16|r<<24)>>>0).toString(16).toUpperCase().padStart(8,"0")}function f(e){return e>=10?"excellent":e>=5?"good":e>=0?"fair":e>=-5?"poor":"critical"}function y(e){if(!e.payload)return null;try{const t=l(e.payload),n=function(e){if(null!=e._traceSnrPath&&e._traceSnrPath.length>0)return e._traceSnrPath;if(e.raw_packet){const t=e.payload_type??e.type,s=o(e.raw_packet,t);if(s&&s.length>0)return s}return[]}(e),r=s(t,n);return r?{packet:e,decoded:r,timestamp:e.timestamp??0,hopCount:r.snrValues.length,rssi:e.rssi,snr:e.snr}:null}catch{return null}}function h(e){const t=new Map;for(const s of e){const e=y(s);if(!e)continue;const n=e.decoded.traceTag,r=t.get(n)||[];r.push(e),t.set(n,r)}for(const[s,n]of t)n.sort((e,t)=>e.timestamp-t.timestamp),t.set(s,n);return t}function b(e,t){if(0===t.length)return{traceTag:e,traceTagValue:0,targetPath:[],targetHopCount:0,observations:[],observationCount:0,firstSeen:0,lastSeen:0,duration:0,isComplete:!1,maxHopsObserved:0,progressPercent:0,bestObservation:null,hopStats:[],linkQuality:null};const s=[...t].sort((e,t)=>e.timestamp-t.timestamp),n=s.reduce((e,t)=>t.hopCount>e.hopCount?t:e,s[0]),r=s[0].timestamp,a=s[s.length-1].timestamp,l=n.decoded.pathHashes,o=l.length,i=n.hopCount,c=n.decoded.isComplete,d=[],p=n.decoded.snrValues;for(let x=0;x0){const e=Math.min(...p),t=Math.max(...p);u={minSnr:e,maxSnr:t,avgSnr:p.reduce((e,t)=>e+t,0)/p.length,weakestLinkPosition:p.indexOf(e),strongestLinkPosition:p.indexOf(t)}}return{traceTag:e,traceTagValue:n.decoded.traceTagValue,targetPath:l,targetHopCount:o,observations:s,observationCount:s.length,firstSeen:r,lastSeen:a,duration:a-r,isComplete:c,maxHopsObserved:i,progressPercent:o>0?Math.round(i/o*100):0,bestObservation:n,hopStats:d,linkQuality:u,srcHash:n.packet.src_hash,dstHash:n.packet.dst_hash}}function N(e){const t=e.payload_type??e.type;if(t!==i.TRACE||!e.payload)return null;try{const n=l(e.payload);let r=[];if(null!=e._traceSnrPath&&e._traceSnrPath.length>0)r=e._traceSnrPath;else if(e.raw_packet){const s=o(e.raw_packet,t);s&&s.length>0&&(r=s)}return s(n,r)}catch{return null}}function v(e){if(!e)return null;const t=e.trim().match(/(-?\d+\.?\d*)\s*[,\s]\s*(-?\d+\.?\d*)/);if(!t)return null;const s=parseFloat(t[1]),n=parseFloat(t[2]);return isNaN(s)||isNaN(n)||s<-90||s>90||n<-180||n>180||0===s&&0===n?null:{lat:s,lon:n}}function j(e,t){const s=e.payload_type??e.type;if(s===i.TRACE){const t=N(e);if(t)return{kind:"trace",data:t,snrValues:t.snrValues}}if(s===i.ADVERT){const t=function(e){if((e.payload_type??e.type)!==i.ADVERT||!e.payload)return null;try{const t=l(e.payload),s=n(t);if(!s)return null;const r=s.publicKey.slice(0,2).toUpperCase(),a={...s,prefix:r};let o=null;return s.latitude&&s.longitude&&(o={latitude:s.latitude,longitude:s.longitude,name:s.name||`Node ${r||"??"}`,prefix:r,publicKey:s.publicKey}),{data:a,sourceNode:o}}catch{return null}}(e);if(t)return{kind:"advert",data:t.data,sourceNode:t.sourceNode}}return s===i.GRP_TXT&&t?{kind:"grp_txt",decoded:t,wardriveCoords:v(t.text),wardriveSourceNode:function(e){var t,s;if(!e.decrypted)return null;if(!(null==(t=e.channelName)?void 0:t.toLowerCase().includes("wardrive")))return null;const n=v(e.text);return n?{latitude:n.lat,longitude:n.lon,name:e.senderName||"Wardrive Ping",prefix:(null==(s=e.senderName)?void 0:s.slice(0,2).toUpperCase())||"WD",nodeType:"wardrive"}:null}(t)}:{kind:"generic"}}const k={zinc:{stem:"bg-zinc-500/40",dot:"bg-zinc-400",row:"bg-zinc-500/8",text:"text-fg-muted/60",chip:"bg-zinc-500/20 text-fg-muted"},green:{stem:"bg-sys-green/50",dot:"bg-sys-green",row:"bg-sys-green/8",text:"text-sys-green",chip:"bg-sys-green/15 text-sys-green"},amber:{stem:"bg-sys-amber/50",dot:"bg-sys-amber",row:"bg-sys-amber/8",text:"text-sys-amber",chip:"bg-sys-amber/15 text-sys-amber"},red:{stem:"bg-sys-red/50",dot:"bg-sys-red",row:"bg-sys-red/8",text:"text-sys-red",chip:"bg-sys-red/15 text-sys-red"},blue:{stem:"bg-sys-blue/50",dot:"bg-sys-blue",row:"bg-sys-blue/8",text:"text-sys-blue",chip:"bg-sys-blue/15 text-sys-blue"},purple:{stem:"bg-sys-purple/50",dot:"bg-sys-purple",row:"bg-sys-purple/8",text:"text-sys-purple",chip:"bg-sys-purple/15 text-sys-purple"},teal:{stem:"bg-sys-teal/50",dot:"bg-sys-teal",row:"bg-sys-teal/8",text:"text-sys-teal",chip:"bg-sys-teal/15 text-sys-teal"},cyan:{stem:"bg-sys-cyan/50",dot:"bg-sys-cyan",row:"bg-sys-cyan/8",text:"text-sys-cyan",chip:"bg-sys-cyan/15 text-sys-cyan"},sky:{stem:"bg-sys-sky/50",dot:"bg-sys-sky",row:"bg-sys-sky/8",text:"text-sys-sky",chip:"bg-sys-sky/15 text-sys-sky"},pink:{stem:"bg-sys-pink/50",dot:"bg-sys-pink",row:"bg-sys-pink/8",text:"text-sys-pink",chip:"bg-sys-pink/15 text-sys-pink"},orange:{stem:"bg-sys-orange/50",dot:"bg-sys-orange",row:"bg-sys-orange/8",text:"text-sys-orange",chip:"bg-sys-orange/15 text-sys-orange"}};Object.fromEntries(Object.entries(k).map(([e,t])=>[e,t.text]));const w=x.createContext("");function S({prefix:e,children:t}){return u.jsx(w.Provider,{value:e,children:t})}function C(){return x.useContext(w)}function $({children:e,color:t="zinc"}){var s;return u.jsx("span",{className:`inline-flex items-center px-1.5 py-px rounded-full text-[9px] font-mono font-medium leading-tight ${(null==(s=k[t])?void 0:s.chip)??k.zinc.chip}`,children:e})}function P({fn:e,value:t,color:s="zinc"}){var n;const r=C(),a=r?`${r}(${e})`:e;return u.jsxs("span",{title:a,className:"inline-flex items-baseline gap-0 font-mono",children:[u.jsx("span",{className:"text-fg-muted/40",children:e}),u.jsx("span",{className:"text-fg-muted/20",children:"("}),t?u.jsx("span",{className:(null==(n=k[s])?void 0:n.text)??k.zinc.text,children:t}):u.jsx("span",{className:"text-fg-muted/20",children:"·"}),u.jsx("span",{className:"text-fg-muted/20",children:")"})]})}function _({label:e,children:t,mono:s=!0,padY:n=!1}){const r=C(),a=e.trim(),l=r?`${r}(${a})`:a;return u.jsxs("div",{className:"flex items-center gap-2 "+(n?"py-1":"py-0.5"),children:[u.jsx("dt",{className:"text-fg-muted shrink-0 w-28 text-right",children:e}),u.jsx("dd",{title:l,className:s?"text-fg-primary break-all":"text-fg-primary",children:t})]})}function T({value:e,className:t}){const s="number"==typeof e?`0x${e.toString(16).toUpperCase().padStart(2,"0")}`:e.startsWith("0x")?e:`0x${e}`;return u.jsx("span",{className:t??"text-sys-blue",children:s})}function z({value:e}){const t="number"==typeof e?e.toString(16).toUpperCase().padStart(2,"0"):e.replace(/^0x/i,"").toUpperCase();return u.jsxs("span",{className:"px-1 py-px rounded bg-zinc-500/15 text-fg-secondary font-mono text-[11px]",children:["0x",t]})}function H({value:e}){return u.jsx("span",{className:"px-1 py-px rounded bg-zinc-500/10 text-fg-muted font-mono text-[10px]",children:e.toString(2).padStart(8,"0")})}function M({raw:e,children:t}){return u.jsxs("span",{className:"inline-flex items-center gap-1.5 flex-wrap",children:[u.jsx("span",{className:"font-mono text-fg-muted",children:e}),u.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),t]})}const O={blue:"text-sys-blue",amber:"text-sys-amber",green:"text-sys-green",teal:"text-sys-teal",purple:"text-sys-purple"};function V({hops:e,hexPrefix:t,color:s="amber"}){if(0===e.length)return u.jsx("span",{className:"text-fg-muted italic",children:"∅ zero-hop"});const n=O[s]??O.amber;return u.jsxs("span",{className:"inline-flex items-center gap-1 flex-wrap",children:[t&&u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"font-mono text-fg-muted text-[10px]",children:t}),u.jsx("span",{className:"text-fg-muted/40 text-[10px] mx-0.5",children:"→"})]}),e.map((e,t)=>u.jsxs("span",{className:"inline-flex items-center",children:[t>0&&u.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),u.jsx("span",{className:`inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] ${n}`,children:e.toUpperCase()})]},t))]})}function R({title:e}){return u.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:e&&u.jsx("p",{className:"text-sys-amber font-semibold mb-0.5",children:e})})}function U(e){if(!e||e<=0)return"never";const t=Math.floor(Date.now()/1e3)-e;return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function L(e){return e>0?"green":"zinc"}function A({children:e,c:t}){return u.jsx("span",{className:t??"text-fg-muted",children:e})}function D({tokens:e,label:t="emits"}){const s=e.filter(e=>null!=e.value&&""!==e.value);if(0===s.length)return null;const n=[];let r;for(let a=0;a{var s;if("label"===e.type)return u.jsx("span",{className:"text-[8px] text-fg-muted/40 uppercase tracking-wider font-mono",children:e.group},`g-${t}`);const n=e.token,r=n.raw?`${n.fn}(${n.raw} → ${n.value})`:`${n.fn}(${n.value})`;return u.jsx("span",{title:r,className:`inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono cursor-default ${(null==(s=k[n.color??"zinc"])?void 0:s.text)??k.zinc.text}`,children:n.value},e.idx)})})})]})})}export{k as A,H as B,$ as C,z as H,_ as K,V as P,M as R,S,P as T,N as a,b,D as c,j as d,m as e,R as f,h as g,T as h,A as i,U as j,g as p,L as s}; +import{P as e,c as t,e as s,f as n}from"./payload-decoders-_TRhCJrs.js";import{a8 as r,a7 as a,ae as l,cr as o,Q as i,cb as c,cc as d,cd as p}from"./index-CkRTgHHA.js";import{j as u,r as x}from"./vendor-react-alRNW2nb.js";function g(s){if(!s||s.length<4)return null;const n=e.fromHex(s);if(!n.success||!n.packet)return null;const l=n.packet,o=function(e){const t=3&e,s=e>>2&15,n=e>>6&3;return[{bits:"0-1",field:"Route Type",value:r(t),binary:(3&t).toString(2).padStart(2,"0")},{bits:"2-5",field:"Payload Type",value:a(s),binary:(15&s).toString(2).padStart(4,"0")},{bits:"6-7",field:"Version",value:n.toString(),binary:(3&n).toString(2).padStart(2,"0")}]}(l.header),i=s.slice(0,2);let c=2,d="";l.hasTransportCodes()&&(d=s.slice(2,10),c=10);const p=s.slice(c,c+2),u=c+2,x=u+2*l.pathLen,g=s.slice(u,x),m=s.slice(x),f=t(l);return{packet:l,headerHex:i,headerFields:o,transportCodesHex:d,pathLengthHex:p,pathDataHex:g,payloadHex:m,pathLenByteOffset:Math.floor(c/2),pathByteOffset:Math.floor(u/2),payloadStartByte:Math.floor(x/2),decoded:f}}function m(e){if(!e||e.length<8)return null;const t=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),n=parseInt(e.slice(4,6),16),r=parseInt(e.slice(6,8),16);return isNaN(t)||isNaN(s)||isNaN(n)||isNaN(r)?null:((t|s<<8|n<<16|r<<24)>>>0).toString(16).toUpperCase().padStart(8,"0")}function f(e){return e>=10?"excellent":e>=5?"good":e>=0?"fair":e>=-5?"poor":"critical"}function y(e){if(!e.payload)return null;try{const t=l(e.payload),n=function(e){if(null!=e._traceSnrPath&&e._traceSnrPath.length>0)return e._traceSnrPath;if(e.raw_packet){const t=e.payload_type??e.type,s=o(e.raw_packet,t);if(s&&s.length>0)return s}return[]}(e),r=s(t,n);return r?{packet:e,decoded:r,timestamp:e.timestamp??0,hopCount:r.snrValues.length,rssi:e.rssi,snr:e.snr}:null}catch{return null}}function h(e){const t=new Map;for(const s of e){const e=y(s);if(!e)continue;const n=e.decoded.traceTag,r=t.get(n)||[];r.push(e),t.set(n,r)}for(const[s,n]of t)n.sort((e,t)=>e.timestamp-t.timestamp),t.set(s,n);return t}function b(e,t){if(0===t.length)return{traceTag:e,traceTagValue:0,targetPath:[],targetHopCount:0,observations:[],observationCount:0,firstSeen:0,lastSeen:0,duration:0,isComplete:!1,maxHopsObserved:0,progressPercent:0,bestObservation:null,hopStats:[],linkQuality:null};const s=[...t].sort((e,t)=>e.timestamp-t.timestamp),n=s.reduce((e,t)=>t.hopCount>e.hopCount?t:e,s[0]),r=s[0].timestamp,a=s[s.length-1].timestamp,l=n.decoded.pathHashes,o=l.length,i=n.hopCount,c=n.decoded.isComplete,d=[],p=n.decoded.snrValues;for(let x=0;x0){const e=Math.min(...p),t=Math.max(...p);u={minSnr:e,maxSnr:t,avgSnr:p.reduce((e,t)=>e+t,0)/p.length,weakestLinkPosition:p.indexOf(e),strongestLinkPosition:p.indexOf(t)}}return{traceTag:e,traceTagValue:n.decoded.traceTagValue,targetPath:l,targetHopCount:o,observations:s,observationCount:s.length,firstSeen:r,lastSeen:a,duration:a-r,isComplete:c,maxHopsObserved:i,progressPercent:o>0?Math.round(i/o*100):0,bestObservation:n,hopStats:d,linkQuality:u,srcHash:n.packet.src_hash,dstHash:n.packet.dst_hash}}function N(e){const t=e.payload_type??e.type;if(t!==i.TRACE||!e.payload)return null;try{const n=l(e.payload);let r=[];if(null!=e._traceSnrPath&&e._traceSnrPath.length>0)r=e._traceSnrPath;else if(e.raw_packet){const s=o(e.raw_packet,t);s&&s.length>0&&(r=s)}return s(n,r)}catch{return null}}function v(e){if(!e)return null;const t=e.trim().match(/(-?\d+\.?\d*)\s*[,\s]\s*(-?\d+\.?\d*)/);if(!t)return null;const s=parseFloat(t[1]),n=parseFloat(t[2]);return isNaN(s)||isNaN(n)||s<-90||s>90||n<-180||n>180||0===s&&0===n?null:{lat:s,lon:n}}function j(e,t){const s=e.payload_type??e.type;if(s===i.TRACE){const t=N(e);if(t)return{kind:"trace",data:t,snrValues:t.snrValues}}if(s===i.ADVERT){const t=function(e){if((e.payload_type??e.type)!==i.ADVERT||!e.payload)return null;try{const t=l(e.payload),s=n(t);if(!s)return null;const r=s.publicKey.slice(0,2).toUpperCase(),a={...s,prefix:r};let o=null;return s.latitude&&s.longitude&&(o={latitude:s.latitude,longitude:s.longitude,name:s.name||`Node ${r||"??"}`,prefix:r,publicKey:s.publicKey}),{data:a,sourceNode:o}}catch{return null}}(e);if(t)return{kind:"advert",data:t.data,sourceNode:t.sourceNode}}return s===i.GRP_TXT&&t?{kind:"grp_txt",decoded:t,wardriveCoords:v(t.text),wardriveSourceNode:function(e){var t,s;if(!e.decrypted)return null;if(!(null==(t=e.channelName)?void 0:t.toLowerCase().includes("wardrive")))return null;const n=v(e.text);return n?{latitude:n.lat,longitude:n.lon,name:e.senderName||"Wardrive Ping",prefix:(null==(s=e.senderName)?void 0:s.slice(0,2).toUpperCase())||"WD",nodeType:"wardrive"}:null}(t)}:{kind:"generic"}}const k={zinc:{stem:"bg-zinc-500/40",dot:"bg-zinc-400",row:"bg-zinc-500/8",text:"text-fg-muted/60",chip:"bg-zinc-500/20 text-fg-muted"},green:{stem:"bg-sys-green/50",dot:"bg-sys-green",row:"bg-sys-green/8",text:"text-sys-green",chip:"bg-sys-green/15 text-sys-green"},amber:{stem:"bg-sys-amber/50",dot:"bg-sys-amber",row:"bg-sys-amber/8",text:"text-sys-amber",chip:"bg-sys-amber/15 text-sys-amber"},red:{stem:"bg-sys-red/50",dot:"bg-sys-red",row:"bg-sys-red/8",text:"text-sys-red",chip:"bg-sys-red/15 text-sys-red"},blue:{stem:"bg-sys-blue/50",dot:"bg-sys-blue",row:"bg-sys-blue/8",text:"text-sys-blue",chip:"bg-sys-blue/15 text-sys-blue"},purple:{stem:"bg-sys-purple/50",dot:"bg-sys-purple",row:"bg-sys-purple/8",text:"text-sys-purple",chip:"bg-sys-purple/15 text-sys-purple"},teal:{stem:"bg-sys-teal/50",dot:"bg-sys-teal",row:"bg-sys-teal/8",text:"text-sys-teal",chip:"bg-sys-teal/15 text-sys-teal"},cyan:{stem:"bg-sys-cyan/50",dot:"bg-sys-cyan",row:"bg-sys-cyan/8",text:"text-sys-cyan",chip:"bg-sys-cyan/15 text-sys-cyan"},sky:{stem:"bg-sys-sky/50",dot:"bg-sys-sky",row:"bg-sys-sky/8",text:"text-sys-sky",chip:"bg-sys-sky/15 text-sys-sky"},pink:{stem:"bg-sys-pink/50",dot:"bg-sys-pink",row:"bg-sys-pink/8",text:"text-sys-pink",chip:"bg-sys-pink/15 text-sys-pink"},orange:{stem:"bg-sys-orange/50",dot:"bg-sys-orange",row:"bg-sys-orange/8",text:"text-sys-orange",chip:"bg-sys-orange/15 text-sys-orange"}};Object.fromEntries(Object.entries(k).map(([e,t])=>[e,t.text]));const w=x.createContext("");function S({prefix:e,children:t}){return u.jsx(w.Provider,{value:e,children:t})}function C(){return x.useContext(w)}function $({children:e,color:t="zinc"}){var s;return u.jsx("span",{className:`inline-flex items-center px-1.5 py-px rounded-full text-[9px] font-mono font-medium leading-tight ${(null==(s=k[t])?void 0:s.chip)??k.zinc.chip}`,children:e})}function P({fn:e,value:t,color:s="zinc"}){var n;const r=C(),a=r?`${r}(${e})`:e;return u.jsxs("span",{title:a,className:"inline-flex items-baseline gap-0 font-mono",children:[u.jsx("span",{className:"text-fg-muted/40",children:e}),u.jsx("span",{className:"text-fg-muted/20",children:"("}),t?u.jsx("span",{className:(null==(n=k[s])?void 0:n.text)??k.zinc.text,children:t}):u.jsx("span",{className:"text-fg-muted/20",children:"·"}),u.jsx("span",{className:"text-fg-muted/20",children:")"})]})}function _({label:e,children:t,mono:s=!0,padY:n=!1}){const r=C(),a=e.trim(),l=r?`${r}(${a})`:a;return u.jsxs("div",{className:"flex items-center gap-2 "+(n?"py-1":"py-0.5"),children:[u.jsx("dt",{className:"text-fg-muted shrink-0 w-28 text-right",children:e}),u.jsx("dd",{title:l,className:s?"text-fg-primary break-all":"text-fg-primary",children:t})]})}function T({value:e,className:t}){const s="number"==typeof e?`0x${e.toString(16).toUpperCase().padStart(2,"0")}`:e.startsWith("0x")?e:`0x${e}`;return u.jsx("span",{className:t??"text-sys-blue",children:s})}function z({value:e}){const t="number"==typeof e?e.toString(16).toUpperCase().padStart(2,"0"):e.replace(/^0x/i,"").toUpperCase();return u.jsxs("span",{className:"px-1 py-px rounded bg-zinc-500/15 text-fg-secondary font-mono text-[11px]",children:["0x",t]})}function H({value:e}){return u.jsx("span",{className:"px-1 py-px rounded bg-zinc-500/10 text-fg-muted font-mono text-[10px]",children:e.toString(2).padStart(8,"0")})}function M({raw:e,children:t}){return u.jsxs("span",{className:"inline-flex items-center gap-1.5 flex-wrap",children:[u.jsx("span",{className:"font-mono text-fg-muted",children:e}),u.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),t]})}const O={blue:"text-sys-blue",amber:"text-sys-amber",green:"text-sys-green",teal:"text-sys-teal",purple:"text-sys-purple"};function V({hops:e,hexPrefix:t,color:s="amber"}){if(0===e.length)return u.jsx("span",{className:"text-fg-muted italic",children:"∅ zero-hop"});const n=O[s]??O.amber;return u.jsxs("span",{className:"inline-flex items-center gap-1 flex-wrap",children:[t&&u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"font-mono text-fg-muted text-[10px]",children:t}),u.jsx("span",{className:"text-fg-muted/40 text-[10px] mx-0.5",children:"→"})]}),e.map((e,t)=>u.jsxs("span",{className:"inline-flex items-center",children:[t>0&&u.jsx("span",{className:"text-fg-muted/40 text-[10px]",children:"→"}),u.jsx("span",{className:`inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono text-[11px] ${n}`,children:e.toUpperCase()})]},t))]})}function R({title:e}){return u.jsx("div",{className:"mt-2 pt-2 border-t border-edge-subtle",children:e&&u.jsx("p",{className:"text-sys-amber font-semibold mb-0.5",children:e})})}function U(e){if(!e||e<=0)return"never";const t=Math.floor(Date.now()/1e3)-e;return t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:`${Math.floor(t/86400)}d ago`}function L(e){return e>0?"green":"zinc"}function A({children:e,c:t}){return u.jsx("span",{className:t??"text-fg-muted",children:e})}function D({tokens:e,label:t="emits"}){const s=e.filter(e=>null!=e.value&&""!==e.value);if(0===s.length)return null;const n=[];let r;for(let a=0;a{var s;if("label"===e.type)return u.jsx("span",{className:"text-[8px] text-fg-muted/40 uppercase tracking-wider font-mono",children:e.group},`g-${t}`);const n=e.token,r=n.raw?`${n.fn}(${n.raw} → ${n.value})`:`${n.fn}(${n.value})`;return u.jsx("span",{title:r,className:`inline-block border border-edge-subtle rounded px-1.5 py-0.5 font-mono cursor-default ${(null==(s=k[n.color??"zinc"])?void 0:s.text)??k.zinc.text}`,children:n.value},e.idx)})})})]})})}export{k as A,H as B,$ as C,z as H,_ as K,V as P,M as R,S,P as T,N as a,b,D as c,j as d,m as e,R as f,h as g,T as h,A as i,U as j,g as p,L as s}; diff --git a/frontend/dist/assets/system-Circh3O5.js b/frontend/dist/assets/system-OS35JnnX.js similarity index 91% rename from frontend/dist/assets/system-Circh3O5.js rename to frontend/dist/assets/system-OS35JnnX.js index 8e33cdbc..0a957630 100644 --- a/frontend/dist/assets/system-Circh3O5.js +++ b/frontend/dist/assets/system-OS35JnnX.js @@ -1 +1 @@ -import{bM as n}from"./index-D7i6lQrq.js";async function o(){return n("/api/transport_keys")}async function a(o){return n("/api/transport_keys",{method:"POST",body:JSON.stringify(o)})}async function t(o,a){return n(`/api/transport_key/${o}`,{method:"PUT",body:JSON.stringify(a)})}async function r(o){return n(`/api/transport_key/${o}`,{method:"DELETE"})}async function s(){return n("/api/global_flood_policy")}async function i(o){return n("/api/global_flood_policy",{method:"POST",body:JSON.stringify({global_flood_allow:o})})}async function c(o){return n("/api/restart_service",{method:"POST",body:"{}",signal:o})}async function e(){return n("/api/check_pymc_console")}export{s as a,a as b,e as c,r as d,o as g,c as r,i as s,t as u}; +import{bM as n}from"./index-CkRTgHHA.js";async function o(){return n("/api/transport_keys")}async function a(o){return n("/api/transport_keys",{method:"POST",body:JSON.stringify(o)})}async function t(o,a){return n(`/api/transport_key/${o}`,{method:"PUT",body:JSON.stringify(a)})}async function r(o){return n(`/api/transport_key/${o}`,{method:"DELETE"})}async function s(){return n("/api/global_flood_policy")}async function i(o){return n("/api/global_flood_policy",{method:"POST",body:JSON.stringify({global_flood_allow:o})})}async function c(o){return n("/api/restart_service",{method:"POST",body:"{}",signal:o})}async function e(){return n("/api/check_pymc_console")}export{s as a,a as b,e as c,r as d,o as g,c as r,i as s,t as u}; diff --git a/frontend/dist/assets/useMapViewStore-1yyjXCM8.js b/frontend/dist/assets/useMapViewStore-sFZdb1_p.js similarity index 93% rename from frontend/dist/assets/useMapViewStore-1yyjXCM8.js rename to frontend/dist/assets/useMapViewStore-sFZdb1_p.js index 6ed8ddad..2b078201 100644 --- a/frontend/dist/assets/useMapViewStore-1yyjXCM8.js +++ b/frontend/dist/assets/useMapViewStore-sFZdb1_p.js @@ -1 +1 @@ -import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{a}from"./vendor-motion-DNp0Qg4F.js";import{b0 as s}from"./index-D7i6lQrq.js";import{a as o,p as n}from"./vendor-core-FtpmsTnh.js";function r({value:o,format:n,prefix:r,className:l,style:i}){const[d,g]=e.useState("waiting");if(e.useEffect(()=>{const e=setTimeout(()=>g("mounted"),400);return()=>clearTimeout(e)},[]),e.useEffect(()=>{if("mounted"===d){const e=requestAnimationFrame(()=>g("animating"));return()=>cancelAnimationFrame(e)}},[d]),"waiting"===d){const e=(0).toLocaleString(void 0,n);return t.jsxs("span",{className:l,style:i,children:[r,e]})}return t.jsx(a,{className:l,style:i,format:n,prefix:r,transition:s.numberReveal,children:"animating"===d?o:0})}const l=["repeater","companion","room_server","hubs","direct"],i={showTopology:!1,showNeighborLines:!0,show3DTerrain:!1,showMinCut:!1,showLinkQuality:!1,nodeFilters:[...l]},d=o()(n(e=>({viewState:null,setViewState:t=>e({viewState:t,lastSavedAt:Date.now()}),toggles:i,setToggle:(t,a)=>e(e=>({toggles:{...e.toggles,[t]:a},lastSavedAt:Date.now()})),setToggles:t=>e(e=>({toggles:{...e.toggles,...t},lastSavedAt:Date.now()})),hasAnalyzed:!1,setHasAnalyzed:t=>e({hasAnalyzed:t,lastSavedAt:Date.now()}),modalMapOpen:!1,setModalMapOpen:t=>e({modalMapOpen:t}),lastSavedAt:null,reset:()=>e({viewState:null,toggles:i,hasAnalyzed:!1,lastSavedAt:null})}),{name:"pymc-map-view",version:2,migrate:(e,t)=>{const a=e,s=a.toggles??{};if(0===t){const e=s.nodeFilter;let t=[...l];return"hubs"===e?t=["hubs"]:"direct"===e&&(t=["direct"]),{...a,toggles:{...s,nodeFilters:t,nodeFilter:void 0}}}if(1===t){const e=s.nodeFilters,t=e&&e.length>0?e:[...l];return{...a,toggles:{...s,nodeFilters:t}}}return e},partialize:e=>({viewState:e.viewState,toggles:e.toggles,hasAnalyzed:e.hasAnalyzed,lastSavedAt:e.lastSavedAt})}));export{l as A,r as D,d as u}; +import{r as e,j as t}from"./vendor-react-alRNW2nb.js";import{a}from"./vendor-motion-DNp0Qg4F.js";import{b0 as s}from"./index-CkRTgHHA.js";import{a as o,p as n}from"./vendor-core-FtpmsTnh.js";function r({value:o,format:n,prefix:r,className:l,style:i}){const[d,g]=e.useState("waiting");if(e.useEffect(()=>{const e=setTimeout(()=>g("mounted"),400);return()=>clearTimeout(e)},[]),e.useEffect(()=>{if("mounted"===d){const e=requestAnimationFrame(()=>g("animating"));return()=>cancelAnimationFrame(e)}},[d]),"waiting"===d){const e=(0).toLocaleString(void 0,n);return t.jsxs("span",{className:l,style:i,children:[r,e]})}return t.jsx(a,{className:l,style:i,format:n,prefix:r,transition:s.numberReveal,children:"animating"===d?o:0})}const l=["repeater","companion","room_server","hubs","direct"],i={showTopology:!1,showNeighborLines:!0,show3DTerrain:!1,showMinCut:!1,showLinkQuality:!1,nodeFilters:[...l]},d=o()(n(e=>({viewState:null,setViewState:t=>e({viewState:t,lastSavedAt:Date.now()}),toggles:i,setToggle:(t,a)=>e(e=>({toggles:{...e.toggles,[t]:a},lastSavedAt:Date.now()})),setToggles:t=>e(e=>({toggles:{...e.toggles,...t},lastSavedAt:Date.now()})),hasAnalyzed:!1,setHasAnalyzed:t=>e({hasAnalyzed:t,lastSavedAt:Date.now()}),modalMapOpen:!1,setModalMapOpen:t=>e({modalMapOpen:t}),lastSavedAt:null,reset:()=>e({viewState:null,toggles:i,hasAnalyzed:!1,lastSavedAt:null})}),{name:"pymc-map-view",version:2,migrate:(e,t)=>{const a=e,s=a.toggles??{};if(0===t){const e=s.nodeFilter;let t=[...l];return"hubs"===e?t=["hubs"]:"direct"===e&&(t=["direct"]),{...a,toggles:{...s,nodeFilters:t,nodeFilter:void 0}}}if(1===t){const e=s.nodeFilters,t=e&&e.length>0?e:[...l];return{...a,toggles:{...s,nodeFilters:t}}}return e},partialize:e=>({viewState:e.viewState,toggles:e.toggles,hasAnalyzed:e.hasAnalyzed,lastSavedAt:e.lastSavedAt})}));export{l as A,r as D,d as u}; diff --git a/frontend/dist/assets/usePipelineStore-D3dOwDkO.js b/frontend/dist/assets/usePipelineStore-CLEA3Bev.js similarity index 98% rename from frontend/dist/assets/usePipelineStore-D3dOwDkO.js rename to frontend/dist/assets/usePipelineStore-CLEA3Bev.js index 5e3c6d23..3021f3fd 100644 --- a/frontend/dist/assets/usePipelineStore-D3dOwDkO.js +++ b/frontend/dist/assets/usePipelineStore-CLEA3Bev.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-react-alRNW2nb.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-B2A_8ldG.css"])))=>i.map(i=>d[i]); -import{_ as e}from"./cosmograph-DqYT4sUA.js";import{r as t}from"./vendor-react-alRNW2nb.js";import{c as n,m as o,i as s}from"./node-types-CiI69Tya.js";import{H as a,ar as r,cs as i,ct as c,cp as l,cu as d}from"./index-D7i6lQrq.js";import{c as u,P as h}from"./geo-utils-DJn8DnxF.js";import{a as f}from"./vendor-core-FtpmsTnh.js";function p(e){if(e.contact_type){const t=e.contact_type.toLowerCase();if("repeater"===t||"rep"===t)return!0;if("companion"===t||"client"===t||"cli"===t)return!1;if("room server"===t||"room_server"===t||"room"===t||"server"===t)return!1}return!0===e.is_repeater||(e.is_repeater,!1)}function g(e){const t={};for(const[n,o]of Object.entries(e))p(o)&&(t[n]=o);return t}function m(e,t){if(!e||e<=0)return.1;const n=(Math.floor(Date.now()/1e3)-e)/3600;return n<0?1:Math.exp(-n/12)}function v(e){return!(!e||e<=0)&&(Math.floor(Date.now()/1e3)-e)/3600>336}function y(e,t,n,o,s){const r=new Map,l=g(t),d=new Map,f=void 0!==o&&void 0!==s&&(0!==o||0!==s);if(n){const e=a(n),t={hash:n,prefix:e,positionCounts:new Array(5).fill(0),totalAppearances:0,typicalPosition:0,positionConsistency:0,adjacentPrefixCounts:new Map,totalAdjacentObservations:0,latitude:o,longitude:s,distanceToLocal:0,srcGeoEvidenceScore:0,srcGeoEvidenceCount:0,lastSeenTimestamp:Math.floor(Date.now()/1e3),recencyScore:1,positionScore:0,cooccurrenceScore:0,geographicScore:1,combinedScore:0};d.set(e,[t])}for(const[i,c]of Object.entries(l)){const e=a(i),t=c.last_seen??0;if(v(t))continue;let n;const r=!0===c.zero_hop;f&&c.latitude&&c.longitude&&(0!==c.latitude||0!==c.longitude)&&(n=u(o,s,c.latitude,c.longitude));let l=.2;void 0!==n?l=n.01){const e=t>0?(Math.floor(Date.now()/1e3)-t)/3600:1/0,n=Math.exp(-e/72);l=Math.max(l,.95*n)}const g={hash:i,prefix:e,name:c.name||c.node_name,positionCounts:new Array(5).fill(0),totalAppearances:0,typicalPosition:0,positionConsistency:0,adjacentPrefixCounts:new Map,totalAdjacentObservations:0,latitude:c.latitude,longitude:c.longitude,distanceToLocal:n,srcGeoEvidenceScore:0,srcGeoEvidenceCount:0,lastSeenTimestamp:t,recencyScore:p,positionScore:0,cooccurrenceScore:0,geographicScore:l,combinedScore:0},y=d.get(e)||[];y.push(g),d.set(e,y)}for(const a of e){const e=i(a,n);if(!e||0===e.effectiveLength)continue;const o=e.effective,s=a.src_hash,r=s?t[s]:void 0,l=(null==r?void 0:r.latitude)&&(null==r?void 0:r.longitude)&&(0!==r.latitude||0!==r.longitude);for(let t=0;t1&&l&&e.latitude&&e.longitude){const t=u(r.latitude,r.longitude,e.latitude,e.longitude);let n=0;n=t<500?1:t<2e3?.8:t<5e3?.5:t<1e4?.3:.1,void 0!==e.distanceToLocal&&(e.distanceToLocal<500?n*=1.2:e.distanceToLocal<2e3?n*=1:n*=.8),e.srcGeoEvidenceScore+=n,e.srcGeoEvidenceCount++}if(t>0&&s.length>1&&e.latitude&&e.longitude){const n=o[t-1],s=d.get(n);if(s&&s.length>0){let t,n,o=0;if(1===s.length){const e=s[0];e.latitude&&e.longitude&&(t=e.latitude,n=e.longitude,o=1)}else{const e=[...s].sort((e,t)=>t.combinedScore-e.combinedScore),a=e[0],r=e[1];if(a.latitude&&a.longitude&&a.combinedScore>0){const e=r?(a.combinedScore-r.combinedScore)/a.combinedScore:1;o=Math.min(1,e+.3),o>.4&&(t=a.latitude,n=a.longitude)}}if(void 0!==t&&void 0!==n){const s=u(e.latitude,e.longitude,t,n);let a=0;a=s<500?1:s<2e3?.8:s<5e3?.5:s<1e4?.3:.1,a*=o,e.srcGeoEvidenceScore+=a,e.srcGeoEvidenceCount++}}}if(a>1&&s.length>1&&e.latitude&&e.longitude){const n=t+1;if(n0){let t,n,o=0;if(1===s.length){const e=s[0];e.latitude&&e.longitude&&(t=e.latitude,n=e.longitude,o=1)}else{const e=[...s].sort((e,t)=>t.combinedScore-e.combinedScore),a=e[0],r=e[1];if(a.latitude&&a.longitude&&a.combinedScore>0){const e=r?(a.combinedScore-r.combinedScore)/a.combinedScore:1;o=Math.min(1,e+.3),o>.4&&(t=a.latitude,n=a.longitude)}}if(void 0!==t&&void 0!==n){const s=u(e.latitude,e.longitude,t,n);let a=0;a=s<500?1:s<2e3?.8:s<5e3?.5:s<1e4?.3:.1,a*=o,e.srcGeoEvidenceScore+=a,e.srcGeoEvidenceCount++}}}}if(t>0){const n=o[t-1];e.adjacentPrefixCounts.set(n,(e.adjacentPrefixCounts.get(n)||0)+1),e.totalAdjacentObservations++}if(t0){let t=0,n=1;for(let s=0;s<5;s++)e.positionCounts[s]>t&&(t=e.positionCounts[s],n=s+1);e.typicalPosition=n,e.positionConsistency=t/e.totalAppearances;const o=e.totalAppearances/p;e.positionScore=.6*e.positionConsistency+.4*o}if(e.totalAdjacentObservations>0&&(e.cooccurrenceScore=e.totalAdjacentObservations/y),e.combinedScore=.15*e.positionScore+.15*e.cooccurrenceScore+.35*e.geographicScore+.35*e.recencyScore,e.srcGeoEvidenceCount>0){const t=e.srcGeoEvidenceScore/e.srcGeoEvidenceCount*Math.min(e.srcGeoEvidenceCount/50,1)*.3;e.combinedScore+=t}}for(const[a,i]of d){i.sort((e,t)=>t.combinedScore-e.combinedScore);const e=i.length>0?i[0].hash:null;let t=0;if(1===i.length)t=1;else if(i.length>1){const e=i[0].combinedScore,n=i[1].combinedScore;e>0&&(t=Math.min(1,(e-n)/e)),i[0].totalAppearances>2*i[1].totalAppearances&&(t=Math.min(1,t+.2));const o=0,s=i[0].positionCounts[o]||0,a=s+(i[1].positionCounts[o]||0);if(a>=20&&s>=10){const e=s/a;if(e>=.8){const n=.3+1.5*(e-.8);t=Math.min(1,t+n)}}const r=i.reduce((e,t)=>e+t.combinedScore,0);if(r>0){const e=[],n=i.reduce((e,t)=>e+(t.positionCounts[0]||0),0);for(const t of i){const o=n*(t.combinedScore/r);e.push(o)}const o=e[0],s=o+(e[1]||0);if(s>=20&&o>=10){const e=o/s;if(e>=.6){const n=.2+1*(e-.6);t=Math.min(1,t+n)}}}const c=i[0].srcGeoEvidenceScore,l=i[1].srcGeoEvidenceScore;if(i[0].srcGeoEvidenceCount>=10&&c>1.5*l){const e=l>0?c/(c+l):1,n=Math.min(.3,.6*(e-.5));t=Math.min(1,t+n)}}const n=new Map;for(let s=1;s<=5;s++){const e=[...i].sort((e,t)=>{const n=e.positionCounts[s-1]||0;return(t.positionCounts[s-1]||0)-n});if(e.length>0&&e[0].positionCounts[s-1]>0){const t=e[0];let o=1;if(e.length>1){const n=t.positionCounts[s-1],a=n+(e[1].positionCounts[s-1]||0);o=a>0?n/a:0}n.set(s,{hash:t.hash,confidence:o})}}const o={prefix:a,candidates:i,bestMatch:e,confidence:t,isUnambiguous:1===i.length,bestMatchForPosition:n};r.set(a,o)}return r}function w(e,t,n){const o=t.toUpperCase(),s=e.get(o);if(!s||0===s.candidates.length)return{hash:null,confidence:0};if(null==n?void 0:n.isLastHop)return{hash:s.bestMatch,confidence:s.confidence};if(1===(null==n?void 0:n.position))return{hash:s.bestMatch,confidence:s.confidence};if((null==n?void 0:n.position)&&s.bestMatchForPosition.has(n.position)){const e=s.bestMatchForPosition.get(n.position),t=Math.max(e.confidence,s.confidence);return{hash:e.hash,confidence:t}}if((null==n?void 0:n.adjacentPrefixes)&&n.adjacentPrefixes.length>0){let e=s.bestMatch,t=0;for(const o of s.candidates){let s=0;for(const e of n.adjacentPrefixes)s+=o.adjacentPrefixCounts.get(e.toUpperCase())||0;const a=o.combinedScore+s/Math.max(1,o.totalAdjacentObservations)*.3;a>t&&(t=a,e=o.hash)}return{hash:e,confidence:s.confidence}}return{hash:s.bestMatch,confidence:s.confidence}}function _(e){if(!e||e.length<6)return null;const t=e,n=parseInt(t.slice(0,2),16);if(isNaN(n))return null;const o=3&n;let s=2;if(0!==o&&3!==o||(s=10),s+2>t.length)return null;const a=parseInt(t.slice(s,s+2),16);if(isNaN(a))return null;if(s+=2+2*a,s>=t.length)return null;const r=t.slice(s);return r.length>=38?r.slice(0,38):r}function M(e,t="name-only"){const n=e.decoded;if(!n||!n.decrypted)return null;if(n.macCorrupted)switch(t){case"strict":return null;case"name-only":return{senderName:n.senderName||null,channelName:n.channelName||null,channelHash:n.channelHash||null,text:null,corrupted:!0,decrypted:!0}}return{senderName:n.senderName||null,channelName:n.channelName||null,channelHash:n.channelHash||null,text:n.text||null,corrupted:!!n.macCorrupted,decrypted:!0}}function b(e){return e.name||e.node_name||null}function C(e,t,n,o,s,a,r){return{hash:e,type:t,name:n,isRepeater:"repeater"===t,isCompanion:"companion"===t,confident:o,advertObservations:s,topologyNeighborCount:a,topologyAffinity:r}}const S=Object.freeze(C(null,"unknown",null,!1,0,0,0)),T={disambiguationEnabled:!0,recencyDecayHours:12,zeroHopDecayHours:72,confidenceThreshold:.6,macCorruptedPolicy:"name-only"},x={hashToType:new Map,pubKeyMap:new Map,prefixIndex:new Map,crossClassPrefixes:new Set,sameClassAmbiguous:new Set,nameToHash:new Map,hashToName:new Map},N={byPayload:new Map,byApprox:new Map},H=f((e,t)=>({config:T,neighborContext:x,extendedHashToType:new Map,advertNameToHash:new Map,advertHashToName:new Map,resolverMap:new Map,topologyProfiles:new Map,decryptedNameToHash:new Map,decryptedHashToName:new Map,srcHashResolverMap:new Map,contentInheritanceIndex:N,_cache:new Map,_neighborFingerprint:"",_resolverFingerprint:"",_advertScanFingerprint:"",_decodedNameFingerprint:"",_inheritanceFingerprint:"",_decodedContentVersion:0,resolveSource:e=>{const n=t();return n.config.disambiguationEnabled?function(e,t,n,r,i,c,l,d,u,h,f){var p,g,m,v,y,w;const _=e.src_hash,M=null==d?void 0:d.get(e.packet_hash),b=(null==(p=null==M?void 0:M.decoded)?void 0:p.senderName)??null,{nameToHash:T}=t;if(!_){const t=e.type??e.payload_type,a=s(t),i=e._advertName??null;if(b){const e=b.toLowerCase(),t=T.get(e)??r.get(e)??u.get(e);return t?C(t,n.get(t)??a,b,!0):C(null,"unknown"!==a?a:"companion",b,!1)}if("unknown"!==a)return C(null,a,i,!1);if(null!=e._advertNodeType){const t=o(e._advertNodeType);if("unknown"!==t)return C(null,t,i,!1)}return i?C(null,"unknown",i,!1):S}const x=e.type??e.payload_type??-1,N=e._advertSender?`${_}\0${e._advertSender}`:`${_}\0${x}\0${b??""}`,H=f.get(N);if(H)return H;const P=a(_),{pubKeyMap:A,prefixIndex:j,crossClassPrefixes:E,sameClassAmbiguous:k}=t;let O;if(e._advertSender){const t=A.get(e._advertSender);if(t){const e=n.get(t)??"unknown",o=null==(g=j.get(P))?void 0:g.find(e=>e.hash===t);O=C(t,e,(null==o?void 0:o.name)??null,!0)}}if(!O&&b){const e=j.get(P),t=null==e?void 0:e.find(e=>{var t;return(null==(t=e.name)?void 0:t.toLowerCase())===b.toLowerCase()});if(t){const e=n.get(t.hash)??t.type;O=C(t.hash,e,t.name,!0)}else{const e=b.toLowerCase(),t=T.get(e)??r.get(e)??u.get(e);if(t){const e=n.get(t)??"unknown",o=null==(m=j.get(a(t)))?void 0:m.find(e=>e.hash===t);O=C(t,e,(null==o?void 0:o.name)??b,!0)}}}if(!O&&E.has(P)){const t=s(e.type??e.payload_type);if("unknown"!==t){const e=null==(v=j.get(P))?void 0:v.find(e=>e.type===t);e&&(O=C(e.hash,t,e.name,!0))}if(!O){const e=j.get(P),t=c.get(P),o=t?null==e?void 0:e.find(e=>e.hash===t):null==e?void 0:e[0],s=o?n.get(o.hash)??o.type:"unknown",a=!!t&&!!o&&o.hash===t;O=C((null==o?void 0:o.hash)??null,s,(null==o?void 0:o.name)??null,a)}}if(!O){const e=c.get(P);if(e){const t=n.get(e)??"unknown",o=null==(y=j.get(P))?void 0:y.find(t=>t.hash===e);O=C(e,t,(null==o?void 0:o.name)??null,!0)}}if(!O&&k.has(P)){const e=null==(w=j.get(P))?void 0:w[0];O=C((null==e?void 0:e.hash)??null,(null==e?void 0:e.type)??"unknown",(null==e?void 0:e.name)??null,!1)}if(!O){const e=j.get(P);if(1===(null==e?void 0:e.length)){const t=e[0];O=C(t.hash,t.type,t.name,!0)}else O=C(null,s(x),null,!1)}const L=s(x);if("unknown"!==L&&L!==O.type&&(O=C(O.hash,L,O.name,O.confident)),"unknown"===O.type&&null!=e._advertNodeType){const t=o(e._advertNodeType);"unknown"!==t&&(O=C(O.hash,t,O.name,O.confident))}if(O.hash){const t=l.get(P);if(t){const n=t.find(e=>e.hash===O.hash);if(n){let t=0;const o=e.original_path??e.forwarded_path;if(o&&Array.isArray(o)&&o.length>0&&n.totalForwarderObservations>0){const e=new Set;for(const t of o){const n=String(t).toUpperCase().slice(0,2);n.length>=2&&n!==P&&e.add(n)}if(e.size>0){let o=0;for(const t of e)n.forwarderPrefixes.has(t)&&o++;t=o/e.size}}O=C(O.hash,O.type,O.name,O.confident,n.advertCount,n.forwarderPrefixes.size,t)}}}if(null===O.name&&O.hash){const e=t.hashToName.get(O.hash)??i.get(O.hash)??h.get(O.hash)??null;e&&(O=C(O.hash,O.type,e,O.confident,O.advertObservations,O.topologyNeighborCount,O.topologyAffinity))}return f.set(N,O),O}(e,n.neighborContext,n.extendedHashToType,n.advertNameToHash,n.advertHashToName,n.resolverMap,n.topologyProfiles,P,n.decryptedNameToHash,n.decryptedHashToName,n._cache):S},getDecodedContent:e=>{const n=t();return function(e,t,n,o="name-only"){const s=e.payload_type??e.type;if(s!==r.GRP_TXT)return null;const a=t.get(e.packet_hash);if(a)return M(a,o);const i=e._payloadHexPrefix??_(e.raw_packet),c=(i?n.byPayload.get(i):null)??n.byApprox.get(`${s}:${e.payload_length??e.length??0}:${Math.floor((e.timestamp??0)/60)}`);return c?M(c,o):null}(e,P,n.contentInheritanceIndex,n.config.macCorruptedPolicy)},setConfig:n=>{const o={...t().config,...n};e({config:o,_cache:new Map}),null==A||A()},recompute:(s,i,c)=>{const f=t(),{config:p}=f,g=`${Object.keys(i).length}`;let m=f.neighborContext;g!==f._neighborFingerprint&&(m=function(e){const t=new Map,o=new Map,s=new Map,r=new Map,i=new Map,c=new Map,l=new Map;for(const[h,f]of Object.entries(e)){const e=n(f).type;t.set(h,e);const d=(h.startsWith("0x")?h.slice(2):h).toLowerCase();o.set(d,h);const u=a(h),p=b(f);let g=s.get(u);g||(g=[],s.set(u,g)),g.push({hash:h,name:p,type:e});const m=r.get(u)||{repeaters:0,others:0};if("repeater"===e?m.repeaters++:m.others++,r.set(u,m),p){c.set(h,p);const e=p.toLowerCase(),t=l.get(e)??0,n=f.last_seen??0;(!i.has(e)||n>t)&&(i.set(e,h),l.set(e,n))}}const d=new Set,u=new Set;for(const[n,a]of r)a.repeaters>0&&a.others>0&&d.add(n),(a.repeaters>=2||a.others>=2)&&u.add(n);return{hashToType:t,pubKeyMap:o,prefixIndex:s,crossClassPrefixes:d,sameClassAmbiguous:u,nameToHash:i,hashToName:c}}(i));const v=50*Math.floor(s.length/50),y=`${g}:${v}`;let w=f.extendedHashToType,M=f.advertNameToHash,C=f.advertHashToName;if(y!==f._advertScanFingerprint||g!==f._neighborFingerprint){const e=function(e,t,n,s){const a=new Map(t),r=new Map,i=new Map,c=new Map,l=new Map;for(const d of e){if(null==d._advertNodeType&&!d._advertName)continue;const e=d._advertSender;if(null!=d._advertNodeType){let t;if(e&&(t=n.get(e)),!t&&d.src_hash&&a.has(d.src_hash)&&(t=d.src_hash),t){const e=a.get(t);if(!e||"unknown"===e){const e=o(d._advertNodeType);"unknown"!==e&&a.set(t,e)}}}if(d._advertName&&e){const t=n.get(e)??e,o=d.timestamp??0,a=d._advertName.toLowerCase();if(!s.has(a)){const e=c.get(a)??0;(!r.has(a)||o>e)&&(r.set(a,t),c.set(a,o))}const u=l.get(t)??0;(!i.has(t)||o>u)&&(i.set(t,d._advertName),l.set(t,o))}}return{extendedHashToType:a,advertNameToHash:r,advertHashToName:i}}(s,m.hashToType,m.pubKeyMap,m.nameToHash);w=e.extendedHashToType,M=e.advertNameToHash,C=e.advertHashToName}const S=`${Object.keys(i).length}:${v}:${m.crossClassPrefixes.size}:${p.recencyDecayHours}:${p.zeroHopDecayHours}`;let T=f.resolverMap,x=f.topologyProfiles;if(S!==f._resolverFingerprint){const e=function(e,t,n){const o=(null==n?void 0:n.recencyDecayHours)??12,s=(null==n?void 0:n.zeroHopDecayHours)??72,i=new Map,c=new Map;for(const a of Object.keys(t)){const e=(a.startsWith("0x")?a.slice(2):a).toLowerCase();c.set(e,a)}const l=new Map;for(const[r,u]of Object.entries(t)){const e=a(r),t=l.get(e)||[];t.push({hash:r,info:u}),l.set(e,t)}const d=new Set;for(const[a,r]of l)1===r.length?i.set(a,r[0].hash):d.add(a);if(0===d.size)return{resolver:i,topologyProfiles:new Map};const f=new Map,p=Math.floor(Date.now()/1e3);for(const a of d){const e=new Map;for(const t of l.get(a)){let n=0;const a=t.info.last_seen??0;if(t.info.zero_hop&&a>0){const e=(p-a)/3600;n+=50*Math.exp(-e/s)}if(a>0){const e=(p-a)/3600;n+=20*Math.exp(-e/o)}t.info.latitude&&t.info.longitude&&(0!==t.info.latitude||0!==t.info.longitude)&&(n+=5),e.set(t.hash,n)}f.set(a,e)}for(const m of e){if((m.type??m.payload_type)!==r.ADVERT)continue;if(!m.src_hash)continue;const e=a(m.src_hash);if(!d.has(e))continue;const t=m._advertLatitude,n=m._advertLongitude;if(null!=t&&null!=n&&(0!==t||0!==n)){const o=l.get(e),s=f.get(e);for(const e of o){if(!e.info.latitude||!e.info.longitude)continue;if(0===e.info.latitude&&0===e.info.longitude)continue;const o=u(t,n,e.info.latitude,e.info.longitude);o=2&&t!==e&&o.add(t)}if(0===o.size)continue;const s=f.get(e);for(const a of t){if(0===a.totalForwarderObservations)continue;let e=0;for(const t of o)a.forwarderPrefixes.has(t)&&e++;if(e>0){const t=e/o.size*3;s.set(a.hash,(s.get(a.hash)||0)+t)}}}for(const a of d){const e=f.get(a);let t=null,n=-1/0;for(const[o,s]of e)s>n&&(n=s,t=o);t&&i.set(a,t)}return{resolver:i,topologyProfiles:g}}(s,i,{recencyDecayHours:p.recencyDecayHours,zeroHopDecayHours:p.zeroHopDecayHours});T=e.resolver,x=e.topologyProfiles}const N=20*Math.floor(c.size/20),H=`${v}:${N}:${S}`;let P=f.decryptedNameToHash,A=f.decryptedHashToName;if(H!==f._decodedNameFingerprint){const e=function(e,t,n,o,s){var r;const i=new Map,c=new Map;if(0===t.size)return{decryptedNameToHash:i,decryptedHashToName:c};const{prefixIndex:l,nameToHash:d}=n;for(const u of e){if(5!==(u.type??u.payload_type))continue;const e=t.get(u.packet_hash);if(!(null==(r=null==e?void 0:e.decoded)?void 0:r.decrypted)||e.decoded.macCorrupted)continue;const n=e.decoded.senderName;if(!n)continue;const h=u.src_hash;if(!h)continue;const f=a(h);let p=s.get(f);if(!p){const e=l.get(f);1===(null==e?void 0:e.length)&&(p=e[0].hash)}if(!p&&h.length>4&&(p=h),!p)continue;const g=n.toLowerCase();d.has(g)||o.has(g)||i.set(g,p),c.has(p)||c.set(p,n)}return{decryptedNameToHash:i,decryptedHashToName:c}}(s,c,m,M,T);P=e.decryptedNameToHash,A=e.decryptedHashToName}const j=new Map(T);for(const[e,t]of P){const n=a(t),o=m.prefixIndex.get(n);if(!o||o.length<=1)continue;const s=o.find(t=>{var n;return(null==(n=t.name)?void 0:n.toLowerCase())===e});s&&j.get(n)!==s.hash&&j.set(n,s.hash)}for(const[e,t]of M){const n=a(t),o=m.prefixIndex.get(n);if(!o||o.length<=1)continue;const s=o.find(t=>{var n;return(null==(n=t.name)?void 0:n.toLowerCase())===e});s&&j.get(n)!==s.hash&&j.set(n,s.hash)}const E=`${v}:${N}`;let k=f.contentInheritanceIndex;E!==f._inheritanceFingerprint&&(k=function(e,t){var n;const o=new Map,s=new Map;for(const a of e){const e=a.payload_type??a.type;if(e!==r.GRP_TXT)continue;const i=t.get(a.packet_hash);if(!(null==(n=null==i?void 0:i.decoded)?void 0:n.decrypted)||i.decoded.macCorrupted)continue;const c=a._payloadHexPrefix??_(a.raw_packet);c&&!o.has(c)&&o.set(c,i);const l=`${e}:${a.payload_length??a.length??0}:${Math.floor((a.timestamp??0)/60)}`;s.has(l)||s.set(l,i)}return{byPayload:o,byApprox:s}}(s,c)),d(j),l.active&&l.emit("pipeline:disambig:recompute",{packets:s.length,neighbors:Object.keys(i).length,decoded:c.size}),e({neighborContext:m,extendedHashToType:w,advertNameToHash:M,advertHashToName:C,resolverMap:T,topologyProfiles:x,decryptedNameToHash:P,decryptedHashToName:A,srcHashResolverMap:j,contentInheritanceIndex:k,_cache:new Map,_neighborFingerprint:g,_resolverFingerprint:S,_advertScanFingerprint:y,_decodedNameFingerprint:H,_inheritanceFingerprint:E,_decodedContentVersion:f._decodedContentVersion+1})}}));let P=new Map,A=null;if("undefined"!=typeof window){let t,n=function(){i&&clearTimeout(i),i=setTimeout(()=>{var e;if(i=null,!o||!s)return;const t=o.useStore.getState(),n=s.useDecodedMessagesStore.getState(),a=t.packets,r=(null==(e=t.stats)?void 0:e.neighbors)??{},c=n.stableMessages;H.getState().recompute(a,r,c)},c)},o=null,s=null,a=[],r=new Map,i=null;const c=150;A=n,setTimeout(()=>{e(()=>import("./index-D7i6lQrq.js").then(e=>e.dv),__vite__mapDeps([0,1,2,3,4])).then(e=>{var s,r;o=e,e.useStore.subscribe(e=>{var o,s;const r=e.packets!==a,i=(null==(o=e.stats)?void 0:o.neighbors)!==t;(r||i)&&(a=e.packets,t=null==(s=e.stats)?void 0:s.neighbors,n())});const i=e.useStore.getState();a=i.packets,t=null==(s=i.stats)?void 0:s.neighbors;const c=(null==(r=i.stats)?void 0:r.neighbors)??{};(a.length>0||Object.keys(c).length>0)&&H.getState().recompute(a,c,new Map)}),e(()=>import("./index-D7i6lQrq.js").then(e=>e.du),__vite__mapDeps([0,1,2,3,4])).then(e=>{s=e,P=e.useDecodedMessagesStore.getState().messages,e.useDecodedMessagesStore.subscribe(e=>{e.messages!==P&&(P=e.messages),e.stableMessages!==r&&(r=e.stableMessages,n())})})},0)}const j=H;function E(){return H(e=>e.resolveSource)}function k(){const e=H(e=>e.getDecodedContent),n=H(e=>e._decodedContentVersion);return t.useCallback(t=>e(t),[e,n])}const O=Object.freeze(Object.defineProperty({__proto__:null,DEFAULT_PIPELINE_CONFIG:T,useAdvertNameToHash:function(){return H(e=>e.advertNameToHash)},useGetDecodedContent:k,useNeighborContext:function(){return H(e=>e.neighborContext)},usePipelineConfig:function(){return H(e=>e.config)},usePipelineStore:j,useResolveSource:E,useSrcHashResolverMap:function(){return H(e=>e.srcHashResolverMap)},useTopologyProfiles:function(){return H(e=>e.topologyProfiles)}},Symbol.toStringTag,{value:"Module"}));export{E as a,y as b,j as c,O as d,g as f,w as r,k as u}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-react-alRNW2nb.js","assets/vendor-core-FtpmsTnh.js","assets/vendor-charts-D1GxaB_c.css","assets/vendor-fonts-hkYiuhFD.css","assets/index-BawBpZYt.css"])))=>i.map(i=>d[i]); +import{_ as e}from"./cosmograph-DqYT4sUA.js";import{r as t}from"./vendor-react-alRNW2nb.js";import{c as n,m as o,i as s}from"./node-types-DRVunROD.js";import{H as a,ar as r,cs as i,ct as c,cp as l,cu as d}from"./index-CkRTgHHA.js";import{c as u,P as h}from"./geo-utils-DJn8DnxF.js";import{a as f}from"./vendor-core-FtpmsTnh.js";function p(e){if(e.contact_type){const t=e.contact_type.toLowerCase();if("repeater"===t||"rep"===t)return!0;if("companion"===t||"client"===t||"cli"===t)return!1;if("room server"===t||"room_server"===t||"room"===t||"server"===t)return!1}return!0===e.is_repeater||(e.is_repeater,!1)}function g(e){const t={};for(const[n,o]of Object.entries(e))p(o)&&(t[n]=o);return t}function m(e,t){if(!e||e<=0)return.1;const n=(Math.floor(Date.now()/1e3)-e)/3600;return n<0?1:Math.exp(-n/12)}function v(e){return!(!e||e<=0)&&(Math.floor(Date.now()/1e3)-e)/3600>336}function y(e,t,n,o,s){const r=new Map,l=g(t),d=new Map,f=void 0!==o&&void 0!==s&&(0!==o||0!==s);if(n){const e=a(n),t={hash:n,prefix:e,positionCounts:new Array(5).fill(0),totalAppearances:0,typicalPosition:0,positionConsistency:0,adjacentPrefixCounts:new Map,totalAdjacentObservations:0,latitude:o,longitude:s,distanceToLocal:0,srcGeoEvidenceScore:0,srcGeoEvidenceCount:0,lastSeenTimestamp:Math.floor(Date.now()/1e3),recencyScore:1,positionScore:0,cooccurrenceScore:0,geographicScore:1,combinedScore:0};d.set(e,[t])}for(const[i,c]of Object.entries(l)){const e=a(i),t=c.last_seen??0;if(v(t))continue;let n;const r=!0===c.zero_hop;f&&c.latitude&&c.longitude&&(0!==c.latitude||0!==c.longitude)&&(n=u(o,s,c.latitude,c.longitude));let l=.2;void 0!==n?l=n.01){const e=t>0?(Math.floor(Date.now()/1e3)-t)/3600:1/0,n=Math.exp(-e/72);l=Math.max(l,.95*n)}const g={hash:i,prefix:e,name:c.name||c.node_name,positionCounts:new Array(5).fill(0),totalAppearances:0,typicalPosition:0,positionConsistency:0,adjacentPrefixCounts:new Map,totalAdjacentObservations:0,latitude:c.latitude,longitude:c.longitude,distanceToLocal:n,srcGeoEvidenceScore:0,srcGeoEvidenceCount:0,lastSeenTimestamp:t,recencyScore:p,positionScore:0,cooccurrenceScore:0,geographicScore:l,combinedScore:0},y=d.get(e)||[];y.push(g),d.set(e,y)}for(const a of e){const e=i(a,n);if(!e||0===e.effectiveLength)continue;const o=e.effective,s=a.src_hash,r=s?t[s]:void 0,l=(null==r?void 0:r.latitude)&&(null==r?void 0:r.longitude)&&(0!==r.latitude||0!==r.longitude);for(let t=0;t1&&l&&e.latitude&&e.longitude){const t=u(r.latitude,r.longitude,e.latitude,e.longitude);let n=0;n=t<500?1:t<2e3?.8:t<5e3?.5:t<1e4?.3:.1,void 0!==e.distanceToLocal&&(e.distanceToLocal<500?n*=1.2:e.distanceToLocal<2e3?n*=1:n*=.8),e.srcGeoEvidenceScore+=n,e.srcGeoEvidenceCount++}if(t>0&&s.length>1&&e.latitude&&e.longitude){const n=o[t-1],s=d.get(n);if(s&&s.length>0){let t,n,o=0;if(1===s.length){const e=s[0];e.latitude&&e.longitude&&(t=e.latitude,n=e.longitude,o=1)}else{const e=[...s].sort((e,t)=>t.combinedScore-e.combinedScore),a=e[0],r=e[1];if(a.latitude&&a.longitude&&a.combinedScore>0){const e=r?(a.combinedScore-r.combinedScore)/a.combinedScore:1;o=Math.min(1,e+.3),o>.4&&(t=a.latitude,n=a.longitude)}}if(void 0!==t&&void 0!==n){const s=u(e.latitude,e.longitude,t,n);let a=0;a=s<500?1:s<2e3?.8:s<5e3?.5:s<1e4?.3:.1,a*=o,e.srcGeoEvidenceScore+=a,e.srcGeoEvidenceCount++}}}if(a>1&&s.length>1&&e.latitude&&e.longitude){const n=t+1;if(n0){let t,n,o=0;if(1===s.length){const e=s[0];e.latitude&&e.longitude&&(t=e.latitude,n=e.longitude,o=1)}else{const e=[...s].sort((e,t)=>t.combinedScore-e.combinedScore),a=e[0],r=e[1];if(a.latitude&&a.longitude&&a.combinedScore>0){const e=r?(a.combinedScore-r.combinedScore)/a.combinedScore:1;o=Math.min(1,e+.3),o>.4&&(t=a.latitude,n=a.longitude)}}if(void 0!==t&&void 0!==n){const s=u(e.latitude,e.longitude,t,n);let a=0;a=s<500?1:s<2e3?.8:s<5e3?.5:s<1e4?.3:.1,a*=o,e.srcGeoEvidenceScore+=a,e.srcGeoEvidenceCount++}}}}if(t>0){const n=o[t-1];e.adjacentPrefixCounts.set(n,(e.adjacentPrefixCounts.get(n)||0)+1),e.totalAdjacentObservations++}if(t0){let t=0,n=1;for(let s=0;s<5;s++)e.positionCounts[s]>t&&(t=e.positionCounts[s],n=s+1);e.typicalPosition=n,e.positionConsistency=t/e.totalAppearances;const o=e.totalAppearances/p;e.positionScore=.6*e.positionConsistency+.4*o}if(e.totalAdjacentObservations>0&&(e.cooccurrenceScore=e.totalAdjacentObservations/y),e.combinedScore=.15*e.positionScore+.15*e.cooccurrenceScore+.35*e.geographicScore+.35*e.recencyScore,e.srcGeoEvidenceCount>0){const t=e.srcGeoEvidenceScore/e.srcGeoEvidenceCount*Math.min(e.srcGeoEvidenceCount/50,1)*.3;e.combinedScore+=t}}for(const[a,i]of d){i.sort((e,t)=>t.combinedScore-e.combinedScore);const e=i.length>0?i[0].hash:null;let t=0;if(1===i.length)t=1;else if(i.length>1){const e=i[0].combinedScore,n=i[1].combinedScore;e>0&&(t=Math.min(1,(e-n)/e)),i[0].totalAppearances>2*i[1].totalAppearances&&(t=Math.min(1,t+.2));const o=0,s=i[0].positionCounts[o]||0,a=s+(i[1].positionCounts[o]||0);if(a>=20&&s>=10){const e=s/a;if(e>=.8){const n=.3+1.5*(e-.8);t=Math.min(1,t+n)}}const r=i.reduce((e,t)=>e+t.combinedScore,0);if(r>0){const e=[],n=i.reduce((e,t)=>e+(t.positionCounts[0]||0),0);for(const t of i){const o=n*(t.combinedScore/r);e.push(o)}const o=e[0],s=o+(e[1]||0);if(s>=20&&o>=10){const e=o/s;if(e>=.6){const n=.2+1*(e-.6);t=Math.min(1,t+n)}}}const c=i[0].srcGeoEvidenceScore,l=i[1].srcGeoEvidenceScore;if(i[0].srcGeoEvidenceCount>=10&&c>1.5*l){const e=l>0?c/(c+l):1,n=Math.min(.3,.6*(e-.5));t=Math.min(1,t+n)}}const n=new Map;for(let s=1;s<=5;s++){const e=[...i].sort((e,t)=>{const n=e.positionCounts[s-1]||0;return(t.positionCounts[s-1]||0)-n});if(e.length>0&&e[0].positionCounts[s-1]>0){const t=e[0];let o=1;if(e.length>1){const n=t.positionCounts[s-1],a=n+(e[1].positionCounts[s-1]||0);o=a>0?n/a:0}n.set(s,{hash:t.hash,confidence:o})}}const o={prefix:a,candidates:i,bestMatch:e,confidence:t,isUnambiguous:1===i.length,bestMatchForPosition:n};r.set(a,o)}return r}function w(e,t,n){const o=t.toUpperCase(),s=e.get(o);if(!s||0===s.candidates.length)return{hash:null,confidence:0};if(null==n?void 0:n.isLastHop)return{hash:s.bestMatch,confidence:s.confidence};if(1===(null==n?void 0:n.position))return{hash:s.bestMatch,confidence:s.confidence};if((null==n?void 0:n.position)&&s.bestMatchForPosition.has(n.position)){const e=s.bestMatchForPosition.get(n.position),t=Math.max(e.confidence,s.confidence);return{hash:e.hash,confidence:t}}if((null==n?void 0:n.adjacentPrefixes)&&n.adjacentPrefixes.length>0){let e=s.bestMatch,t=0;for(const o of s.candidates){let s=0;for(const e of n.adjacentPrefixes)s+=o.adjacentPrefixCounts.get(e.toUpperCase())||0;const a=o.combinedScore+s/Math.max(1,o.totalAdjacentObservations)*.3;a>t&&(t=a,e=o.hash)}return{hash:e,confidence:s.confidence}}return{hash:s.bestMatch,confidence:s.confidence}}function _(e){if(!e||e.length<6)return null;const t=e,n=parseInt(t.slice(0,2),16);if(isNaN(n))return null;const o=3&n;let s=2;if(0!==o&&3!==o||(s=10),s+2>t.length)return null;const a=parseInt(t.slice(s,s+2),16);if(isNaN(a))return null;if(s+=2+2*a,s>=t.length)return null;const r=t.slice(s);return r.length>=38?r.slice(0,38):r}function M(e,t="name-only"){const n=e.decoded;if(!n||!n.decrypted)return null;if(n.macCorrupted)switch(t){case"strict":return null;case"name-only":return{senderName:n.senderName||null,channelName:n.channelName||null,channelHash:n.channelHash||null,text:null,corrupted:!0,decrypted:!0}}return{senderName:n.senderName||null,channelName:n.channelName||null,channelHash:n.channelHash||null,text:n.text||null,corrupted:!!n.macCorrupted,decrypted:!0}}function b(e){return e.name||e.node_name||null}function C(e,t,n,o,s,a,r){return{hash:e,type:t,name:n,isRepeater:"repeater"===t,isCompanion:"companion"===t,confident:o,advertObservations:s,topologyNeighborCount:a,topologyAffinity:r}}const S=Object.freeze(C(null,"unknown",null,!1,0,0,0)),T={disambiguationEnabled:!0,recencyDecayHours:12,zeroHopDecayHours:72,confidenceThreshold:.6,macCorruptedPolicy:"name-only"},x={hashToType:new Map,pubKeyMap:new Map,prefixIndex:new Map,crossClassPrefixes:new Set,sameClassAmbiguous:new Set,nameToHash:new Map,hashToName:new Map},N={byPayload:new Map,byApprox:new Map},H=f((e,t)=>({config:T,neighborContext:x,extendedHashToType:new Map,advertNameToHash:new Map,advertHashToName:new Map,resolverMap:new Map,topologyProfiles:new Map,decryptedNameToHash:new Map,decryptedHashToName:new Map,srcHashResolverMap:new Map,contentInheritanceIndex:N,_cache:new Map,_neighborFingerprint:"",_resolverFingerprint:"",_advertScanFingerprint:"",_decodedNameFingerprint:"",_inheritanceFingerprint:"",_decodedContentVersion:0,resolveSource:e=>{const n=t();return n.config.disambiguationEnabled?function(e,t,n,r,i,c,l,d,u,h,f){var p,g,m,v,y,w;const _=e.src_hash,M=null==d?void 0:d.get(e.packet_hash),b=(null==(p=null==M?void 0:M.decoded)?void 0:p.senderName)??null,{nameToHash:T}=t;if(!_){const t=e.type??e.payload_type,a=s(t),i=e._advertName??null;if(b){const e=b.toLowerCase(),t=T.get(e)??r.get(e)??u.get(e);return t?C(t,n.get(t)??a,b,!0):C(null,"unknown"!==a?a:"companion",b,!1)}if("unknown"!==a)return C(null,a,i,!1);if(null!=e._advertNodeType){const t=o(e._advertNodeType);if("unknown"!==t)return C(null,t,i,!1)}return i?C(null,"unknown",i,!1):S}const x=e.type??e.payload_type??-1,N=e._advertSender?`${_}\0${e._advertSender}`:`${_}\0${x}\0${b??""}`,H=f.get(N);if(H)return H;const P=a(_),{pubKeyMap:A,prefixIndex:j,crossClassPrefixes:E,sameClassAmbiguous:k}=t;let O;if(e._advertSender){const t=A.get(e._advertSender);if(t){const e=n.get(t)??"unknown",o=null==(g=j.get(P))?void 0:g.find(e=>e.hash===t);O=C(t,e,(null==o?void 0:o.name)??null,!0)}}if(!O&&b){const e=j.get(P),t=null==e?void 0:e.find(e=>{var t;return(null==(t=e.name)?void 0:t.toLowerCase())===b.toLowerCase()});if(t){const e=n.get(t.hash)??t.type;O=C(t.hash,e,t.name,!0)}else{const e=b.toLowerCase(),t=T.get(e)??r.get(e)??u.get(e);if(t){const e=n.get(t)??"unknown",o=null==(m=j.get(a(t)))?void 0:m.find(e=>e.hash===t);O=C(t,e,(null==o?void 0:o.name)??b,!0)}}}if(!O&&E.has(P)){const t=s(e.type??e.payload_type);if("unknown"!==t){const e=null==(v=j.get(P))?void 0:v.find(e=>e.type===t);e&&(O=C(e.hash,t,e.name,!0))}if(!O){const e=j.get(P),t=c.get(P),o=t?null==e?void 0:e.find(e=>e.hash===t):null==e?void 0:e[0],s=o?n.get(o.hash)??o.type:"unknown",a=!!t&&!!o&&o.hash===t;O=C((null==o?void 0:o.hash)??null,s,(null==o?void 0:o.name)??null,a)}}if(!O){const e=c.get(P);if(e){const t=n.get(e)??"unknown",o=null==(y=j.get(P))?void 0:y.find(t=>t.hash===e);O=C(e,t,(null==o?void 0:o.name)??null,!0)}}if(!O&&k.has(P)){const e=null==(w=j.get(P))?void 0:w[0];O=C((null==e?void 0:e.hash)??null,(null==e?void 0:e.type)??"unknown",(null==e?void 0:e.name)??null,!1)}if(!O){const e=j.get(P);if(1===(null==e?void 0:e.length)){const t=e[0];O=C(t.hash,t.type,t.name,!0)}else O=C(null,s(x),null,!1)}const L=s(x);if("unknown"!==L&&L!==O.type&&(O=C(O.hash,L,O.name,O.confident)),"unknown"===O.type&&null!=e._advertNodeType){const t=o(e._advertNodeType);"unknown"!==t&&(O=C(O.hash,t,O.name,O.confident))}if(O.hash){const t=l.get(P);if(t){const n=t.find(e=>e.hash===O.hash);if(n){let t=0;const o=e.original_path??e.forwarded_path;if(o&&Array.isArray(o)&&o.length>0&&n.totalForwarderObservations>0){const e=new Set;for(const t of o){const n=String(t).toUpperCase().slice(0,2);n.length>=2&&n!==P&&e.add(n)}if(e.size>0){let o=0;for(const t of e)n.forwarderPrefixes.has(t)&&o++;t=o/e.size}}O=C(O.hash,O.type,O.name,O.confident,n.advertCount,n.forwarderPrefixes.size,t)}}}if(null===O.name&&O.hash){const e=t.hashToName.get(O.hash)??i.get(O.hash)??h.get(O.hash)??null;e&&(O=C(O.hash,O.type,e,O.confident,O.advertObservations,O.topologyNeighborCount,O.topologyAffinity))}return f.set(N,O),O}(e,n.neighborContext,n.extendedHashToType,n.advertNameToHash,n.advertHashToName,n.resolverMap,n.topologyProfiles,P,n.decryptedNameToHash,n.decryptedHashToName,n._cache):S},getDecodedContent:e=>{const n=t();return function(e,t,n,o="name-only"){const s=e.payload_type??e.type;if(s!==r.GRP_TXT)return null;const a=t.get(e.packet_hash);if(a)return M(a,o);const i=e._payloadHexPrefix??_(e.raw_packet),c=(i?n.byPayload.get(i):null)??n.byApprox.get(`${s}:${e.payload_length??e.length??0}:${Math.floor((e.timestamp??0)/60)}`);return c?M(c,o):null}(e,P,n.contentInheritanceIndex,n.config.macCorruptedPolicy)},setConfig:n=>{const o={...t().config,...n};e({config:o,_cache:new Map}),null==A||A()},recompute:(s,i,c)=>{const f=t(),{config:p}=f,g=`${Object.keys(i).length}`;let m=f.neighborContext;g!==f._neighborFingerprint&&(m=function(e){const t=new Map,o=new Map,s=new Map,r=new Map,i=new Map,c=new Map,l=new Map;for(const[h,f]of Object.entries(e)){const e=n(f).type;t.set(h,e);const d=(h.startsWith("0x")?h.slice(2):h).toLowerCase();o.set(d,h);const u=a(h),p=b(f);let g=s.get(u);g||(g=[],s.set(u,g)),g.push({hash:h,name:p,type:e});const m=r.get(u)||{repeaters:0,others:0};if("repeater"===e?m.repeaters++:m.others++,r.set(u,m),p){c.set(h,p);const e=p.toLowerCase(),t=l.get(e)??0,n=f.last_seen??0;(!i.has(e)||n>t)&&(i.set(e,h),l.set(e,n))}}const d=new Set,u=new Set;for(const[n,a]of r)a.repeaters>0&&a.others>0&&d.add(n),(a.repeaters>=2||a.others>=2)&&u.add(n);return{hashToType:t,pubKeyMap:o,prefixIndex:s,crossClassPrefixes:d,sameClassAmbiguous:u,nameToHash:i,hashToName:c}}(i));const v=50*Math.floor(s.length/50),y=`${g}:${v}`;let w=f.extendedHashToType,M=f.advertNameToHash,C=f.advertHashToName;if(y!==f._advertScanFingerprint||g!==f._neighborFingerprint){const e=function(e,t,n,s){const a=new Map(t),r=new Map,i=new Map,c=new Map,l=new Map;for(const d of e){if(null==d._advertNodeType&&!d._advertName)continue;const e=d._advertSender;if(null!=d._advertNodeType){let t;if(e&&(t=n.get(e)),!t&&d.src_hash&&a.has(d.src_hash)&&(t=d.src_hash),t){const e=a.get(t);if(!e||"unknown"===e){const e=o(d._advertNodeType);"unknown"!==e&&a.set(t,e)}}}if(d._advertName&&e){const t=n.get(e)??e,o=d.timestamp??0,a=d._advertName.toLowerCase();if(!s.has(a)){const e=c.get(a)??0;(!r.has(a)||o>e)&&(r.set(a,t),c.set(a,o))}const u=l.get(t)??0;(!i.has(t)||o>u)&&(i.set(t,d._advertName),l.set(t,o))}}return{extendedHashToType:a,advertNameToHash:r,advertHashToName:i}}(s,m.hashToType,m.pubKeyMap,m.nameToHash);w=e.extendedHashToType,M=e.advertNameToHash,C=e.advertHashToName}const S=`${Object.keys(i).length}:${v}:${m.crossClassPrefixes.size}:${p.recencyDecayHours}:${p.zeroHopDecayHours}`;let T=f.resolverMap,x=f.topologyProfiles;if(S!==f._resolverFingerprint){const e=function(e,t,n){const o=(null==n?void 0:n.recencyDecayHours)??12,s=(null==n?void 0:n.zeroHopDecayHours)??72,i=new Map,c=new Map;for(const a of Object.keys(t)){const e=(a.startsWith("0x")?a.slice(2):a).toLowerCase();c.set(e,a)}const l=new Map;for(const[r,u]of Object.entries(t)){const e=a(r),t=l.get(e)||[];t.push({hash:r,info:u}),l.set(e,t)}const d=new Set;for(const[a,r]of l)1===r.length?i.set(a,r[0].hash):d.add(a);if(0===d.size)return{resolver:i,topologyProfiles:new Map};const f=new Map,p=Math.floor(Date.now()/1e3);for(const a of d){const e=new Map;for(const t of l.get(a)){let n=0;const a=t.info.last_seen??0;if(t.info.zero_hop&&a>0){const e=(p-a)/3600;n+=50*Math.exp(-e/s)}if(a>0){const e=(p-a)/3600;n+=20*Math.exp(-e/o)}t.info.latitude&&t.info.longitude&&(0!==t.info.latitude||0!==t.info.longitude)&&(n+=5),e.set(t.hash,n)}f.set(a,e)}for(const m of e){if((m.type??m.payload_type)!==r.ADVERT)continue;if(!m.src_hash)continue;const e=a(m.src_hash);if(!d.has(e))continue;const t=m._advertLatitude,n=m._advertLongitude;if(null!=t&&null!=n&&(0!==t||0!==n)){const o=l.get(e),s=f.get(e);for(const e of o){if(!e.info.latitude||!e.info.longitude)continue;if(0===e.info.latitude&&0===e.info.longitude)continue;const o=u(t,n,e.info.latitude,e.info.longitude);o=2&&t!==e&&o.add(t)}if(0===o.size)continue;const s=f.get(e);for(const a of t){if(0===a.totalForwarderObservations)continue;let e=0;for(const t of o)a.forwarderPrefixes.has(t)&&e++;if(e>0){const t=e/o.size*3;s.set(a.hash,(s.get(a.hash)||0)+t)}}}for(const a of d){const e=f.get(a);let t=null,n=-1/0;for(const[o,s]of e)s>n&&(n=s,t=o);t&&i.set(a,t)}return{resolver:i,topologyProfiles:g}}(s,i,{recencyDecayHours:p.recencyDecayHours,zeroHopDecayHours:p.zeroHopDecayHours});T=e.resolver,x=e.topologyProfiles}const N=20*Math.floor(c.size/20),H=`${v}:${N}:${S}`;let P=f.decryptedNameToHash,A=f.decryptedHashToName;if(H!==f._decodedNameFingerprint){const e=function(e,t,n,o,s){var r;const i=new Map,c=new Map;if(0===t.size)return{decryptedNameToHash:i,decryptedHashToName:c};const{prefixIndex:l,nameToHash:d}=n;for(const u of e){if(5!==(u.type??u.payload_type))continue;const e=t.get(u.packet_hash);if(!(null==(r=null==e?void 0:e.decoded)?void 0:r.decrypted)||e.decoded.macCorrupted)continue;const n=e.decoded.senderName;if(!n)continue;const h=u.src_hash;if(!h)continue;const f=a(h);let p=s.get(f);if(!p){const e=l.get(f);1===(null==e?void 0:e.length)&&(p=e[0].hash)}if(!p&&h.length>4&&(p=h),!p)continue;const g=n.toLowerCase();d.has(g)||o.has(g)||i.set(g,p),c.has(p)||c.set(p,n)}return{decryptedNameToHash:i,decryptedHashToName:c}}(s,c,m,M,T);P=e.decryptedNameToHash,A=e.decryptedHashToName}const j=new Map(T);for(const[e,t]of P){const n=a(t),o=m.prefixIndex.get(n);if(!o||o.length<=1)continue;const s=o.find(t=>{var n;return(null==(n=t.name)?void 0:n.toLowerCase())===e});s&&j.get(n)!==s.hash&&j.set(n,s.hash)}for(const[e,t]of M){const n=a(t),o=m.prefixIndex.get(n);if(!o||o.length<=1)continue;const s=o.find(t=>{var n;return(null==(n=t.name)?void 0:n.toLowerCase())===e});s&&j.get(n)!==s.hash&&j.set(n,s.hash)}const E=`${v}:${N}`;let k=f.contentInheritanceIndex;E!==f._inheritanceFingerprint&&(k=function(e,t){var n;const o=new Map,s=new Map;for(const a of e){const e=a.payload_type??a.type;if(e!==r.GRP_TXT)continue;const i=t.get(a.packet_hash);if(!(null==(n=null==i?void 0:i.decoded)?void 0:n.decrypted)||i.decoded.macCorrupted)continue;const c=a._payloadHexPrefix??_(a.raw_packet);c&&!o.has(c)&&o.set(c,i);const l=`${e}:${a.payload_length??a.length??0}:${Math.floor((a.timestamp??0)/60)}`;s.has(l)||s.set(l,i)}return{byPayload:o,byApprox:s}}(s,c)),d(j),l.active&&l.emit("pipeline:disambig:recompute",{packets:s.length,neighbors:Object.keys(i).length,decoded:c.size}),e({neighborContext:m,extendedHashToType:w,advertNameToHash:M,advertHashToName:C,resolverMap:T,topologyProfiles:x,decryptedNameToHash:P,decryptedHashToName:A,srcHashResolverMap:j,contentInheritanceIndex:k,_cache:new Map,_neighborFingerprint:g,_resolverFingerprint:S,_advertScanFingerprint:y,_decodedNameFingerprint:H,_inheritanceFingerprint:E,_decodedContentVersion:f._decodedContentVersion+1})}}));let P=new Map,A=null;if("undefined"!=typeof window){let t,n=function(){i&&clearTimeout(i),i=setTimeout(()=>{var e;if(i=null,!o||!s)return;const t=o.useStore.getState(),n=s.useDecodedMessagesStore.getState(),a=t.packets,r=(null==(e=t.stats)?void 0:e.neighbors)??{},c=n.stableMessages;H.getState().recompute(a,r,c)},c)},o=null,s=null,a=[],r=new Map,i=null;const c=150;A=n,setTimeout(()=>{e(()=>import("./index-CkRTgHHA.js").then(e=>e.dv),__vite__mapDeps([0,1,2,3,4])).then(e=>{var s,r;o=e,e.useStore.subscribe(e=>{var o,s;const r=e.packets!==a,i=(null==(o=e.stats)?void 0:o.neighbors)!==t;(r||i)&&(a=e.packets,t=null==(s=e.stats)?void 0:s.neighbors,n())});const i=e.useStore.getState();a=i.packets,t=null==(s=i.stats)?void 0:s.neighbors;const c=(null==(r=i.stats)?void 0:r.neighbors)??{};(a.length>0||Object.keys(c).length>0)&&H.getState().recompute(a,c,new Map)}),e(()=>import("./index-CkRTgHHA.js").then(e=>e.du),__vite__mapDeps([0,1,2,3,4])).then(e=>{s=e,P=e.useDecodedMessagesStore.getState().messages,e.useDecodedMessagesStore.subscribe(e=>{e.messages!==P&&(P=e.messages),e.stableMessages!==r&&(r=e.stableMessages,n())})})},0)}const j=H;function E(){return H(e=>e.resolveSource)}function k(){const e=H(e=>e.getDecodedContent),n=H(e=>e._decodedContentVersion);return t.useCallback(t=>e(t),[e,n])}const O=Object.freeze(Object.defineProperty({__proto__:null,DEFAULT_PIPELINE_CONFIG:T,useAdvertNameToHash:function(){return H(e=>e.advertNameToHash)},useGetDecodedContent:k,useNeighborContext:function(){return H(e=>e.neighborContext)},usePipelineConfig:function(){return H(e=>e.config)},usePipelineStore:j,useResolveSource:E,useSrcHashResolverMap:function(){return H(e=>e.srcHashResolverMap)},useTopologyProfiles:function(){return H(e=>e.topologyProfiles)}},Symbol.toStringTag,{value:"Module"}));export{E as a,y as b,j as c,O as d,g as f,w as r,k as u}; diff --git a/frontend/dist/index.html b/frontend/dist/index.html index b4abc3b8..c195adc9 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -39,12 +39,12 @@ --font-data: 'JetBrains Mono', 'SF Mono', Monaco, monospace; } - + - +
diff --git a/frontend/package.json b/frontend/package.json index d5efd693..72d91743 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "pymc_console", - "version": "0.9.285", + "version": "0.9.286", "description": "Vite + React Dashboard for pyMC_Repeater", "private": true, "type": "module",