@camstack/addon-admin-ui 0.1.35 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1139,7 +1139,7 @@ Please change the parent <Route path="${x}"> to <Route path="${x==="/"?"*":`${x}
|
|
|
1139
1139
|
* This source code is licensed under the MIT license found in the
|
|
1140
1140
|
* LICENSE file in the root directory of this source tree.
|
|
1141
1141
|
*/var Tr=mm;function S9(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var C9=typeof Object.is=="function"?Object.is:S9,M9=Tr.useState,E9=Tr.useEffect,I9=Tr.useLayoutEffect,A9=Tr.useDebugValue;function P9(e,t){var n=t(),r=M9({inst:{value:n,getSnapshot:t}}),s=r[0].inst,a=r[1];return I9(function(){s.value=n,s.getSnapshot=t,Ui(s)&&a({inst:s})},[e,n,t]),E9(function(){return Ui(s)&&a({inst:s}),e(function(){Ui(s)&&a({inst:s})})},[e]),A9(n),n}function Ui(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!C9(e,n)}catch{return!0}}function _9(e,t){return t()}var $9=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?_9:P9;xv.useSyncExternalStore=Tr.useSyncExternalStore!==void 0?Tr.useSyncExternalStore:$9;bv.exports=xv;var yv=bv.exports;const D9=(e,t)=>{if(sr(t))return t;if(p9(t)&&sr(t.defaultValue))return t.defaultValue;if(typeof e=="function")return"";if(Array.isArray(e)){const n=e[e.length-1];return typeof n=="function"?"":n}return e},T9={t:D9,ready:!1},L9=()=>()=>{},Vt=(e,t={})=>{const{i18n:n}=t,{i18n:r,defaultNS:s}=ve(N9)||{},a=n||r||v9();a&&!a.reportNamespaces&&(a.reportNamespaces=new k9),a||Wl(a,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const i=H(()=>({...x9(),...a?.options?.react,...t}),[a,t]),{useSuspense:l,keyPrefix:c}=i,d=s||a?.options?.defaultNS,u=sr(d)?[d]:d||["translation"],p=H(()=>u,u);a?.reportNamespaces?.addUsedNamespaces?.(p);const h=te(0),m=U(A=>{if(!a)return L9;const{bindI18n:z,bindI18nStore:P}=i,B=()=>{h.current+=1,A()};return z&&a.on(z,B),P&&a.store.on(P,B),()=>{z&&z.split(" ").forEach(R=>a.off(R,B)),P&&P.split(" ").forEach(R=>a.store.off(R,B))}},[a,i]),g=te(),b=U(()=>{if(!a)return T9;const A=!!(a.isInitialized||a.initializedStoreOnce)&&p.every(D=>u9(D,a,i)),z=t.lng||a.language,P=h.current,B=g.current;if(B&&B.ready===A&&B.lng===z&&B.keyPrefix===c&&B.revision===P)return B;const M={t:a.getFixedT(z,i.nsMode==="fallback"?p:p[0],c),ready:A,lng:z,keyPrefix:c,revision:P};return g.current=M,M},[a,p,c,i,t.lng]),[x,y]=_(0),{t:w,ready:v}=yv.useSyncExternalStore(m,b,b);Y(()=>{if(a&&!v&&!l){const A=()=>y(z=>z+1);t.lng?lf(a,t.lng,p,A):Yl(a,p,A)}},[a,t.lng,p,v,l,x]);const N=a||{},k=te(null),C=te(),E=A=>{const z=Object.getOwnPropertyDescriptors(A);z.__original&&delete z.__original;const P=Object.create(Object.getPrototypeOf(A),z);if(!Object.prototype.hasOwnProperty.call(P,"__original"))try{Object.defineProperty(P,"__original",{value:A,writable:!1,enumerable:!1,configurable:!1})}catch{}return P},I=H(()=>{const A=N,z=A?.language;let P=A;A&&(k.current&&k.current.__original===A?C.current!==z?(P=E(A),k.current=P,C.current=z):P=k.current:(P=E(A),k.current=P,C.current=z));const B=!v&&!l?(...M)=>(Wl(a,"USE_T_BEFORE_READY","useTranslation: t was called before ready. When using useSuspense: false, make sure to check the ready flag before using t."),w(...M)):w,R=[B,P,v];return R.t=B,R.i18n=P,R.ready=v,R},[w,N,v,N.resolvedLanguage,N.language,N.languages]);if(a&&l&&!v)throw new Promise(A=>{const z=()=>A();t.lng?lf(a,t.lng,p,z):Yl(a,p,z)});return I},cf={info:rr,success:Kd,warning:it,error:nr},R9={info:"text-blue-400",success:"text-green-400",warning:"text-amber-400",error:"text-red-400"},df={active:"border-l-blue-400","in-progress":"border-l-amber-400",completed:"border-l-green-400",failed:"border-l-red-400",dismissed:"border-l-foreground-subtle/30"};function O9(e){const t=Math.floor((Date.now()-e)/1e3);if(t<60)return"just now";const n=Math.floor(t/60);if(n<60)return`${String(n)}m ago`;const r=Math.floor(n/60);if(r<24)return`${String(r)}h ago`;const s=Math.floor(r/24);return`${String(s)}d ago`}function uf({alert:e,onMarkRead:t,onDismiss:n}){const r=e.severity in cf?e.severity:"info",s=e.status in df?e.status:"active",a=cf[r],i=R9[r],l=df[s];return f("div",{className:`flex items-start gap-2.5 px-3 py-2.5 border-l-2 ${l} ${e.read?"opacity-60":""} hover:bg-surface-hover transition-colors`,children:[o(a,{className:`h-3.5 w-3.5 shrink-0 mt-0.5 ${i}`}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:`text-[11px] font-semibold ${e.read?"text-foreground-subtle":"text-foreground"}`,children:e.title}),!e.read&&o("span",{className:"h-1.5 w-1.5 rounded-full bg-primary shrink-0"})]}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5 line-clamp-2",children:e.message}),e.status==="in-progress"&&e.progress!==void 0&&f("div",{className:"mt-1.5 flex items-center gap-2",children:[o("div",{className:"flex-1 h-1 bg-surface-hover rounded-full overflow-hidden",children:o("div",{className:"h-full bg-primary rounded-full transition-all duration-300",style:{width:`${String(Math.min(100,Math.max(0,e.progress)))}%`}})}),f("span",{className:"text-[9px] text-foreground-subtle font-mono shrink-0",children:[String(Math.round(e.progress)),"%"]})]}),o("div",{className:"text-[9px] text-foreground-subtle/60 mt-1",children:O9(e.updatedAt)})]}),f("div",{className:"flex items-center gap-0.5 shrink-0",children:[!e.read&&o("button",{type:"button",onClick:c=>{c.stopPropagation(),t(e.id)},className:"p-1 rounded hover:bg-surface-hover transition-colors",title:"Mark as read",children:o(_t,{className:"h-3 w-3 text-foreground-subtle"})}),e.status!=="in-progress"&&o("button",{type:"button",onClick:c=>{c.stopPropagation(),n(e.id)},className:"p-1 rounded hover:bg-surface-hover transition-colors",title:"Dismiss",children:o(Fe,{className:"h-3 w-3 text-foreground-subtle"})})]})]})}function pf({variant:e="icon",compact:t=!1}={}){const[n,r]=_(!1),[s,a]=_(!1),i=te(null),l=te(null),c=ke(),{data:d=0}=Ab(void 0,{staleTime:1e4,refetchInterval:3e4}),{data:u=[],isLoading:p}=Ib({limit:50},{enabled:n,staleTime:5e3}),h=s?u:u.filter(A=>!A.read),m=u.filter(A=>A.read).length,g=()=>{c.invalidateQueries({queryKey:[["alerts"]]})},b=Pb({onSuccess:g}),x=_b({onSuccess:g}),y=$b({onSuccess:g});gt("alert.created",()=>{c.invalidateQueries({queryKey:[["alerts"]]})}),gt("alert.updated",()=>{c.invalidateQueries({queryKey:[["alerts"]]})}),Y(()=>{if(!n)return;const A=z=>{const P=z.target;i.current&&!i.current.contains(P)&&l.current&&!l.current.contains(P)&&r(!1)};return document.addEventListener("mousedown",A),()=>document.removeEventListener("mousedown",A)},[n]);const w=U(A=>{b.mutate({alertId:A})},[b]),v=U(A=>{A&&y.mutate({alertId:A})},[y]),N=U(()=>{x.mutate(void 0),r(!1)},[x]),k=h.filter(A=>A.status==="in-progress"),C=h.filter(A=>A.status!=="in-progress"),[E,I]=_({});return Y(()=>{if(n&&l.current){const A=l.current.getBoundingClientRect();I({position:"fixed",left:A.left,bottom:window.innerHeight-A.top+4,zIndex:9999})}},[n]),f("div",{children:[e==="sidebar"?f("button",{ref:l,type:"button",onClick:()=>r(!n),className:`flex w-full items-center gap-2.5 rounded-md ${t?"justify-center px-0 py-2":"px-2.5 py-1.5"} text-[12px] text-foreground-subtle hover:bg-surface-hover hover:text-foreground transition-colors`,title:t?`Alerts${d>0?` (${d})`:""}`:void 0,children:[f("span",{className:"relative inline-flex shrink-0",children:[o(at,{className:"h-3.5 w-3.5"}),t&&d>0&&o("span",{className:"absolute -top-1 -right-1 h-2 w-2 rounded-full bg-primary"})]}),!t&&o("span",{className:"flex-1 text-left",children:"Alerts"}),!t&&d>0&&o("span",{className:"flex items-center justify-center h-4 min-w-4 px-1 rounded-full bg-primary text-primary-foreground text-[9px] font-bold leading-none",children:d>99?"99+":String(d)})]}):f("button",{ref:l,type:"button",onClick:()=>r(!n),className:"relative p-1.5 rounded-md hover:bg-surface-hover text-foreground-subtle hover:text-foreground transition-colors","aria-label":"Alerts",children:[o(at,{className:"h-4.5 w-4.5"}),d>0&&o("span",{className:"absolute -top-0.5 -right-0.5 flex items-center justify-center h-4 min-w-4 px-0.5 rounded-full bg-primary text-primary-foreground text-[9px] font-bold leading-none",children:d>99?"99+":String(d)})]}),n&&qo(f("div",{ref:i,style:E,className:"w-80 max-h-[28rem] bg-surface border border-border rounded-lg shadow-xl flex flex-col overflow-hidden",children:[f("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border shrink-0",children:[o("span",{className:"text-[12px] font-semibold text-foreground",children:"Alerts"}),f("div",{className:"flex items-center gap-2",children:[m>0&&f("label",{className:"flex items-center gap-1 text-[10px] text-foreground-subtle cursor-pointer select-none",children:[o("input",{type:"checkbox",checked:s,onChange:A=>a(A.target.checked),className:"h-3 w-3 rounded border-border accent-primary cursor-pointer"}),"Show read"]}),d>0&&f("button",{type:"button",onClick:N,className:"flex items-center gap-1 text-[10px] text-primary hover:text-primary/80 transition-colors",children:[o(LR,{className:"h-3 w-3"}),"Mark all read"]})]})]}),f("div",{className:"flex-1 overflow-y-auto",children:[p&&o("div",{className:"flex items-center justify-center py-8",children:o(Se,{className:"h-4 w-4 animate-spin text-foreground-subtle"})}),!p&&h.length===0&&f("div",{className:"flex flex-col items-center justify-center py-8 text-foreground-subtle",children:[o(at,{className:"h-6 w-6 mb-2 opacity-40"}),o("span",{className:"text-[11px]",children:u.length>0?"No unread alerts":"No alerts"}),u.length>0&&!s&&f("button",{type:"button",onClick:()=>a(!0),className:"text-[10px] text-primary mt-1 hover:underline",children:["Show ",m," read alert",m!==1?"s":""]})]}),k.length>0&&f("div",{className:"border-b border-border",children:[o("div",{className:"px-3 py-1.5 bg-surface-hover/50",children:o("span",{className:"text-[9px] font-semibold uppercase tracking-widest text-foreground-subtle/60",children:"In Progress"})}),k.map(A=>o(uf,{alert:A,onMarkRead:w,onDismiss:v},A.id))]}),C.map(A=>o(uf,{alert:A,onMarkRead:w,onDismiss:v},A.id))]})]}),document.body)]})}function vv(e){return e.map(t=>({id:t.page.id,addonId:t.addonId,label:t.page.label,icon:t.page.icon,path:t.page.path,remoteName:t.page.remoteName,bundle:t.page.bundle,bundleUrl:t.bundleUrl}))}const ff=new Map,Ss=new Map,hf=new Set;function B9(e){return!e||typeof e!="object"?!1:typeof e.default=="function"}async function z9(e,t){const n=ff.get(e);if(n)return n;const r=Ss.get(e);if(r)return r;hf.has(e)||(Ec(),_r.registerRemotes([{name:e,entry:t,type:"module"}],{force:!1}),hf.add(e));const s=_r.loadRemote(`${e}/page`).then(a=>{if(!B9(a))throw new Error(`Addon page remote ${e} (${t}) does not expose a default React component on './page'`);return ff.set(e,a.default),Ss.delete(e),a.default}).catch(a=>{throw Ss.delete(e),a});return Ss.set(e,s),s}function F9(){const{pagePath:e}=zd(),t=Te(),{data:n}=nd(void 0,{staleTime:6e4}),r=H(()=>n?vv(n):void 0,[n]),s=r?.find(d=>d.path===`/addon/${e}`),[a,i]=_(null),[l,c]=_(null);return Y(()=>{if(!s)return;c(null),i(null);let d=!1;return z9(s.remoteName,s.bundleUrl).then(u=>{d||i(()=>u)}).catch(u=>{if(d)return;const p=u instanceof Error?u.message:String(u);c(`Failed to load addon page: ${p}`)}),()=>{d=!0}},[s]),r?s?l?o("div",{className:"flex items-center justify-center h-full text-red-400 text-sm",children:l}):a?o(a,{trpc:t.trpcClient,theme:{isDark:document.documentElement.classList.contains("dark")},navigate:d=>{window.location.href=d}}):o("div",{className:"flex items-center justify-center h-full",children:o("div",{className:"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full"})}):o("div",{className:"flex items-center justify-center h-full text-foreground-subtle",children:"Addon page not found"}):o("div",{className:"flex items-center justify-center h-full",children:o("div",{className:"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full"})})}const j9={dark:Z0,light:RO,system:U6},V9={gauge:K0,puzzle:la,bot:MR,cpu:bt,terminal:ov,box:Ka,wrench:YO,activity:Xo,plug:_o};function H9(){const e=vt(),t=rt(),{user:n,logout:r}=nn(),s=Hr(),{t:a}=Vt(),i=hr(),l=Mg(),c=cR(),d=c!=="connected",u=c==="connecting",[p,h]=_(!1),[m,g]=_(()=>typeof window>"u"?!1:window.localStorage.getItem("camstack:sidebar-collapsed")==="1");Y(()=>{typeof window>"u"||window.localStorage.setItem("camstack:sidebar-collapsed",m?"1":"0")},[m]);const[b,x]=_(()=>{if(typeof window>"u")return new Set;try{const $=window.localStorage.getItem("camstack:sidebar-collapsed-groups");if(!$)return new Set;const q=JSON.parse($);return Array.isArray(q)?new Set(q.filter(G=>typeof G=="string")):new Set}catch{return new Set}});Y(()=>{typeof window>"u"||window.localStorage.setItem("camstack:sidebar-collapsed-groups",JSON.stringify([...b]))},[b]),Y(()=>{l&&window.localStorage.getItem("camstack:sidebar-collapsed")===null&&g(!0)},[l]);const{data:y=[]}=od({nodeId:"hub"},{staleTime:3e4,refetchInterval:3e4}),w=y.length,v=ke(),N=te(Date.now()),k=3e4,C=2e3,{data:E}=nd(void 0,{staleTime:0,refetchOnMount:"always",refetchInterval:$=>{const q=$.state.data;return q&&q.length>0||Date.now()-N.current>=k?!1:C}}),I=H(()=>E&&n?.isAdmin?vv(E):[],[E,n?.isAdmin]);gt("addon.page-ready",()=>{v.invalidateQueries({queryKey:[["addonPages","listPages"]]})});const A=()=>{r(),t("/login")},z=$=>!!(e.pathname===$||e.pathname.startsWith($+"/")),B=["/pipeline","/timeline"].some($=>e.pathname===$||e.pathname.startsWith($+"/")),R=n?.isAdmin===!0,M=[{label:a("nav.devices","Devices"),icon:Dr,path:"/devices"},{label:a("nav.integrations"),icon:_o,path:"/integrations"},{label:a("nav.timeline","Timeline"),icon:WR,path:"/timeline"},{label:a("nav.pipeline","Pipeline"),icon:f6,path:"/pipeline"}].filter(Boolean),T=[{label:a("system.identity","Identity & Access"),icon:Yd,path:"/system/identity",adminOnly:!0},{label:a("system.network","Network"),icon:_n,path:"/system/network",adminOnly:!0},{label:a("system.integrations","Integrations"),icon:_o,path:"/system/integrations",adminOnly:!0},{label:a("system.data","Data"),icon:Q0,path:"/system/data",adminOnly:!0},{label:a("system.cluster","Cluster"),icon:$n,path:"/system/cluster",adminOnly:!0},{label:a("system.addons"),icon:la,path:"/system/addons",adminOnly:!0},{label:a("system.addonSettings","Addon Settings"),icon:Jt,path:"/system/settings",adminOnly:!0},{label:a("system.logs","Logs"),icon:at,path:"/system/logs",adminOnly:!0}].filter($=>!$.adminOnly||R),L=s?.mode??"system",O={dark:a("theme.dark"),light:a("theme.light"),system:a("theme.system")},F=m&&!i,j=($,q="md")=>`flex w-full items-center gap-2.5 rounded-md ${F?"justify-center px-0 py-2":"px-2.5 py-1.5"} ${q==="lg"?"text-[13px] font-medium":"text-[12px]"} transition-all ${$?q==="lg"?"bg-primary/12 text-primary shadow-sm shadow-primary/5":"bg-primary/12 text-primary":"text-foreground-subtle hover:bg-surface-hover hover:text-foreground"}`,V=f(me,{children:[f("div",{className:`flex h-14 items-center border-b border-border ${F?"justify-center px-1":"pl-3 pr-4 gap-2"}`,children:[!F&&o("img",{src:s?.resolvedMode==="light"?"/brand/logo-horizontal-light.svg":"/brand/logo-horizontal-dark.svg",alt:"CamStack Admin",className:"h-9 flex-1 min-w-0"}),!i&&o("button",{onClick:()=>g($=>!$),className:`p-1.5 rounded-md hover:bg-surface-hover text-foreground-subtle transition-colors flex-shrink-0 ${F?"":"mr-2"}`,"aria-label":m?"Expand sidebar":"Collapse sidebar",title:m?"Expand sidebar":"Collapse sidebar",children:m?o(wt,{className:"h-4 w-4"}):o(Gd,{className:"h-4 w-4"})})]}),f("nav",{className:`flex-1 overflow-y-auto py-3 ${F?"px-1.5":"px-2"} space-y-0.5`,children:[(()=>{const $=z("/dashboard");return f("button",{"data-testid":"nav-dashboard",onClick:()=>{t("/dashboard"),h(!1)},className:j($,"lg"),title:F?a("nav.dashboard"):void 0,children:[o(Y0,{className:`h-4 w-4 shrink-0 ${$?"text-primary":""}`}),!F&&a("nav.dashboard")]})})(),!F&&o("div",{className:"pt-4 pb-1.5 px-2.5",children:o("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/60",children:a("nav.camerasSection","Cameras")})}),F&&o("div",{className:"pt-3 mb-1 mx-2 border-t border-border/60"}),M.map($=>{const q=$.icon,G=z($.path),Z=`nav-${$.path.replace(/^\//,"").replace(/\//g,"-")}`;return f("button",{"data-testid":Z,onClick:()=>{t($.path),h(!1)},className:j(G),title:F?$.label:void 0,children:[o(q,{className:`h-3.5 w-3.5 shrink-0 ${G?"text-primary":""}`}),!F&&$.label]},$.path)}),!F&&o("div",{className:"pt-4 pb-1.5 px-2.5",children:o("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/60",children:a("system.title")})}),F&&o("div",{className:"pt-3 mb-1 mx-2 border-t border-border/60"}),T.map($=>{const q=$.icon,G=z($.path),Z=$.path==="/system/addons",oe=`nav-${$.path.replace(/^\//,"").replace(/\//g,"-")}`;return f("button",{"data-testid":oe,onClick:()=>{t($.path),h(!1)},className:j(G),title:F?$.label:void 0,children:[o(q,{className:`h-3.5 w-3.5 shrink-0 ${G?"text-primary":""}`}),!F&&f(me,{children:[o("span",{className:"flex-1 text-left",children:$.label}),Z&&w>0&&o("span",{className:"ml-auto rounded-full bg-primary px-1.5 py-0.5 text-[9px] font-bold text-primary-foreground leading-none",children:w})]}),F&&Z&&w>0&&o("span",{className:"absolute mt-[-14px] ml-3 h-2 w-2 rounded-full bg-primary"})]},$.path)}),I&&I.length>0&&!F&&o("div",{className:"pt-4 pb-1.5 px-2.5",children:o("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-foreground-subtle/60",children:a("nav.addonPages","Addon Pages")})}),F&&I&&I.length>0&&o("div",{className:"pt-3 mb-1 mx-2 border-t border-border/60"}),I?.map($=>{const q=z($.path),G=V9[$.icon]??la;return f("button",{onClick:()=>{t($.path),h(!1)},className:j(q),title:F?$.label:void 0,children:[o(G,{className:`h-3.5 w-3.5 shrink-0 ${q?"text-primary":""}`}),!F&&$.label]},$.id)})]}),f("div",{className:`border-t border-border ${F?"p-1.5":"p-2"} space-y-0.5`,children:[f("button",{onClick:()=>s?.toggleMode(),className:j(!1),title:F?O[L]:void 0,children:[(()=>{const $=j9[L];return o($,{className:"h-3.5 w-3.5 shrink-0"})})(),!F&&o("span",{children:O[L]})]}),o(pf,{variant:"sidebar",compact:F}),f("button",{type:"button",onClick:()=>t("/system/my-access"),className:j(z("/system/my-access")),title:F?a("system.myAccess","My access"):void 0,children:[o(mn,{className:"h-3.5 w-3.5 shrink-0"}),!F&&o("span",{className:"truncate",children:a("system.myAccess","My access")})]}),f("button",{onClick:A,className:j(!1).replace("hover:text-foreground","hover:text-danger"),title:F?n?.username??"Logout":void 0,children:[o(Zd,{className:"h-3.5 w-3.5 shrink-0"}),!F&&o("span",{className:"truncate",children:n?.username??"User"})]})]})]});return f("div",{className:"flex h-screen bg-background text-foreground",children:[!i&&o("aside",{className:`flex flex-col border-r border-border bg-surface/80 backdrop-blur-sm shrink-0 transition-[width] duration-150 ease-out ${F?"w-12":"w-48"}`,children:V}),i&&o(Vc,{open:p,onClose:()=>h(!1),width:"w-64",children:V}),f("div",{className:"flex flex-1 flex-col min-w-0",children:[d&&f("div",{className:"flex items-center justify-center gap-2 bg-danger/90 px-3 py-2 text-[12px] font-medium text-white shrink-0",children:[o(av,{className:"h-3.5 w-3.5"}),o("span",{children:u?a("connection.reconnecting","Reconnecting…"):a("connection.disconnected","Server unreachable — reconnecting…")}),o(Se,{className:"h-3.5 w-3.5 animate-spin"})]}),i&&f("header",{className:"flex items-center h-12 border-b border-border px-3 shrink-0 bg-surface/80 backdrop-blur-sm",children:[o("button",{onClick:()=>h(!0),className:"p-1.5 -ml-1.5 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors","aria-label":"Open menu",children:o(F6,{className:"h-5 w-5"})}),o("div",{className:"flex-1 flex justify-center",children:o("img",{src:s?.resolvedMode==="light"?"/brand/logo-horizontal-light.svg":"/brand/logo-horizontal-dark.svg",alt:"CamStack",className:"h-7"})}),o(pf,{})]}),f("main",{className:`relative flex-1 min-h-0 bg-background ${B?"overflow-hidden":"overflow-auto"}`,children:[d&&o("div",{className:"absolute inset-0 z-40 bg-background/60 backdrop-blur-[2px]"}),o(wL,{})]})]})]})}function q9(){const{login:e,verifyTotp:t}=nn(),n=Hr(),r=rt(),[s,a]=_(""),[i,l]=_(""),[c,d]=_(!1),[u,p]=_(""),[h,m]=_(!1),[g,b]=_("credentials"),[x,y]=_(""),[w,v]=_(""),N=async E=>{E.preventDefault(),p(""),m(!0);try{const I=await e(s,i);if(I.kind==="totp-required"){y(I.challengeToken),b("totp");return}r(i==="changeme"?"/change-password":"/dashboard",{replace:!0})}catch(I){p(I instanceof Error?I.message:"Login failed")}finally{m(!1)}},k=async E=>{E.preventDefault(),p(""),m(!0);try{await t(x,w.trim()),r("/dashboard",{replace:!0})}catch(I){p(I instanceof Error?I.message:"TOTP verification failed"),v("")}finally{m(!1)}},C=()=>{b("credentials"),y(""),v(""),p("")};return o("div",{className:"flex min-h-screen items-center justify-center bg-background p-4",children:f("div",{className:"w-full max-w-sm",children:[o("div",{className:"flex justify-center mb-8",children:o("img",{src:n?.resolvedMode==="light"?"/brand/logo-horizontal-light.svg":"/brand/logo-horizontal-dark.svg",alt:"CamStack Admin",className:"h-12"})}),g==="credentials"?f("form",{onSubmit:N,className:"space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",children:[u&&o("div",{className:"rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger",children:u}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-xs font-medium text-foreground-subtle",children:"Username"}),o("input",{"data-testid":"login-username",type:"text",placeholder:"Username",value:s,onChange:E=>a(E.target.value),className:"w-full rounded-lg border border-border bg-background px-3 py-2.5 text-sm text-foreground placeholder:text-foreground-disabled focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none transition-all",autoFocus:!0})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-xs font-medium text-foreground-subtle",children:"Password"}),f("div",{className:"relative",children:[o("input",{"data-testid":"login-password",type:c?"text":"password",placeholder:"Password",value:i,onChange:E=>l(E.target.value),className:"w-full rounded-lg border border-border bg-background px-3 py-2.5 pr-10 text-sm text-foreground placeholder:text-foreground-disabled focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none transition-all"}),o("button",{type:"button",onClick:()=>d(!c),className:"absolute right-2.5 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground transition-colors",tabIndex:-1,children:c?o(G0,{className:"h-4 w-4"}):o(es,{className:"h-4 w-4"})})]})]}),o("button",{"data-testid":"login-submit",type:"submit",disabled:h||!s||!i,className:"w-full rounded-lg bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground shadow-md shadow-primary/20 hover:shadow-lg hover:shadow-primary/30 disabled:opacity-50 disabled:shadow-none transition-all",children:h?f("span",{className:"flex items-center justify-center gap-2",children:[o("span",{className:"h-4 w-4 animate-spin rounded-full border-2 border-primary-foreground/30 border-t-primary-foreground"}),"Logging in..."]}):"Log in"})]}):f("form",{onSubmit:k,className:"space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",children:[f("div",{className:"flex items-center gap-2 pb-1 border-b border-border",children:[o(An,{className:"h-4 w-4 text-primary"}),o("div",{className:"text-sm font-medium text-foreground",children:"Two-factor authentication"})]}),f("p",{className:"text-xs text-foreground-subtle",children:["Enter the 6-digit code from your authenticator app to finish signing in as"," ",o("span",{className:"font-mono text-foreground",children:s}),"."]}),u&&o("div",{className:"rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger",children:u}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-xs font-medium text-foreground-subtle",children:"Authentication code"}),o("input",{"data-testid":"login-totp",type:"text",inputMode:"numeric",autoComplete:"one-time-code",placeholder:"123456",value:w,onChange:E=>v(E.target.value.replace(/\D/g,"").slice(0,6)),className:"w-full rounded-lg border border-border bg-background px-3 py-3 text-center text-2xl font-mono tracking-widest text-foreground placeholder:text-foreground-disabled focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none transition-all",autoFocus:!0})]}),o("button",{"data-testid":"login-totp-submit",type:"submit",disabled:h||w.length!==6,className:"w-full rounded-lg bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground shadow-md shadow-primary/20 hover:shadow-lg hover:shadow-primary/30 disabled:opacity-50 disabled:shadow-none transition-all",children:h?f("span",{className:"flex items-center justify-center gap-2",children:[o("span",{className:"h-4 w-4 animate-spin rounded-full border-2 border-primary-foreground/30 border-t-primary-foreground"}),"Verifying..."]}):"Verify and sign in"}),f("button",{type:"button",onClick:C,className:"w-full flex items-center justify-center gap-1.5 text-xs text-foreground-subtle hover:text-foreground transition-colors",children:[o(Qd,{className:"h-3 w-3"}),"Back to username + password"]})]}),g==="credentials"&&o(U9,{}),o("p",{className:"mt-6 text-center text-[10px] text-foreground-subtle/50",children:"CamStack v0.1.0"})]})})}function U9(){const t=(S.auth.listProviders.useQuery().data??[]).filter(n=>n.flowType==="redirect");return t.length===0?null:f("div",{className:"mt-6 space-y-3",children:[f("div",{className:"flex items-center gap-3",children:[o("div",{className:"h-px flex-1 bg-border"}),o("span",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"Or continue with"}),o("div",{className:"h-px flex-1 bg-border"})]}),o("div",{className:"space-y-2",children:t.map(n=>f("a",{href:`/addon/${encodeURIComponent(n.id)}/start`,className:"flex items-center justify-center gap-2 w-full rounded-lg border border-border bg-surface px-4 py-2.5 text-sm font-medium text-foreground hover:bg-surface-hover transition-colors",children:[o(mn,{className:"h-4 w-4 text-primary"}),n.name]},n.id))})]})}const mf=8;function Q9(){const{user:e,mustChangePassword:t,clearMustChangePassword:n,logout:r}=nn(),s=Hr(),a=rt(),[i,l]=_(""),[c,d]=_(""),[u,p]=_(!1),[h,m]=_(""),g=wd({onSuccess:()=>{n(),a("/dashboard",{replace:!0})},onError:x=>{m(x instanceof Error?x.message:"Could not change password")}}),b=async x=>{if(x.preventDefault(),m(""),!e){m("Not signed in");return}if(i.length<mf){m(`Password must be at least ${mf} characters`);return}if(i!==c){m("The two passwords do not match");return}if(i==="changeme"){m("Choose a password different from the seed default");return}g.mutate({id:e.id,newPassword:i})};return o("div",{className:"flex min-h-screen items-center justify-center bg-background p-4",children:f("div",{className:"w-full max-w-sm",children:[o("div",{className:"flex justify-center mb-8",children:o("img",{src:s?.resolvedMode==="light"?"/brand/logo-horizontal-light.svg":"/brand/logo-horizontal-dark.svg",alt:"CamStack Admin",className:"h-12"})}),f("form",{onSubmit:b,className:"space-y-4 rounded-xl border border-border bg-surface p-6 shadow-xl shadow-black/10",children:[f("div",{className:"space-y-1",children:[o("h1",{className:"text-sm font-semibold text-foreground",children:"Set a new password"}),o("p",{className:"text-xs text-foreground-subtle",children:t?"You must rotate the seed password before continuing.":"Choose a new password for your account."})]}),h&&o("div",{className:"rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger",children:h}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-xs font-medium text-foreground-subtle",children:"New password"}),f("div",{className:"relative",children:[o("input",{"data-testid":"change-password-new",type:u?"text":"password",value:i,onChange:x=>l(x.target.value),className:"w-full rounded-lg border border-border bg-background px-3 py-2.5 pr-10 text-sm text-foreground placeholder:text-foreground-disabled focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none transition-all",autoFocus:!0}),o("button",{type:"button",onClick:()=>p(!u),className:"absolute right-2.5 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground transition-colors",tabIndex:-1,children:u?o(G0,{className:"h-4 w-4"}):o(es,{className:"h-4 w-4"})})]})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-xs font-medium text-foreground-subtle",children:"Confirm new password"}),o("input",{"data-testid":"change-password-confirm",type:u?"text":"password",value:c,onChange:x=>d(x.target.value),className:"w-full rounded-lg border border-border bg-background px-3 py-2.5 text-sm text-foreground placeholder:text-foreground-disabled focus:border-primary focus:ring-1 focus:ring-primary/30 outline-none transition-all"})]}),o("button",{"data-testid":"change-password-submit",type:"submit",disabled:g.isPending||!i||!c,className:"w-full rounded-lg bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground shadow-md shadow-primary/20 hover:shadow-lg hover:shadow-primary/30 disabled:opacity-50 disabled:shadow-none transition-all",children:g.isPending?"Saving…":"Save and continue"}),t&&o("button",{type:"button",onClick:()=>{r(),a("/login",{replace:!0})},className:"w-full text-xs text-foreground-subtle hover:text-foreground transition-colors",children:"Sign out instead"})]})]})})}function G9(){const e=rt();return f("div",{className:"flex flex-col items-center justify-center text-foreground py-16 px-4",children:[o("div",{className:"flex h-16 w-16 items-center justify-center rounded-2xl bg-danger/10 mb-4",children:o(CO,{className:"h-8 w-8 text-danger"})}),o("h1",{className:"text-xl font-bold",children:"Access Denied"}),o("p",{className:"mt-2 text-sm text-foreground-subtle",children:"You don't have permission to access this page."}),o("button",{onClick:()=>e("/dashboard"),className:"mt-6 rounded-lg bg-primary px-5 py-2.5 text-sm font-medium text-primary-foreground shadow-md shadow-primary/20 hover:shadow-lg transition-all",children:"Go to Dashboard"})]})}const wv="camstack:dashboard-layout",Qi={version:1,widgets:[]};function K9(){try{const e=localStorage.getItem(wv);if(!e)return Qi;const t=JSON.parse(e);return t&&t.version===1&&Array.isArray(t.widgets)?{version:1,widgets:t.widgets}:Qi}catch{return Qi}}function W9(e){try{localStorage.setItem(wv,JSON.stringify(e))}catch{}}function Y9(){const e=typeof crypto<"u"?crypto:void 0;return e?.randomUUID?e.randomUUID():`widget-${Date.now().toString(36)}-${Math.floor(Math.random()*1e6).toString(36)}`}function Z9(){const[e,t]=_(K9),[n,r]=_(!1),s=Uy(),a=H(()=>s.filter(d=>d.hosts.includes("dashboard")),[s]),i=U(d=>{t(d),W9(d)},[]),l=U(d=>{i({version:1,widgets:[...e.widgets,d]})},[e,i]),c=U(d=>{i({version:1,widgets:e.widgets.filter(u=>u.instanceId!==d)})},[e,i]);return f("div",{className:"p-4",children:[f("div",{className:"flex items-center justify-between mb-4",children:[o("h1",{className:"text-lg font-semibold text-foreground",children:"Dashboard"}),f("button",{onClick:()=>r(!0),className:"flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",children:[o(Et,{className:"h-3.5 w-3.5"}),"Add widget"]})]}),e.widgets.length===0?o(X9,{onAdd:()=>r(!0)}):o("div",{className:"grid grid-cols-12 gap-3 auto-rows-[minmax(80px,_auto)]",children:e.widgets.map(d=>o(J9,{entry:d,onRemove:()=>c(d.instanceId)},d.instanceId))}),n&&o(t7,{widgets:a,onClose:()=>r(!1),onAdd:d=>{l(d),r(!1)}})]})}function X9({onAdd:e}){return f("div",{className:"flex flex-col items-center justify-center py-24 text-foreground-subtle",children:[o("div",{className:"flex h-16 w-16 items-center justify-center rounded-2xl bg-surface border border-border mb-4",children:o(Y0,{className:"h-8 w-8 text-foreground-subtle/40"})}),o("p",{className:"text-sm font-medium text-foreground/70",children:"Your dashboard is empty"}),o("p",{className:"text-xs text-foreground-subtle mt-1 mb-4",children:"Add widgets to monitor your cameras and system"}),f("button",{onClick:e,className:"flex items-center gap-1.5 rounded-lg bg-primary px-4 py-2 text-xs font-semibold text-primary-foreground shadow-md shadow-primary/20 hover:shadow-lg transition-all",children:[o(Et,{className:"h-3.5 w-3.5"}),"Add your first widget"]})]})}function J9({entry:e,onRemove:t}){const n=e7(e.columns),r=Math.max(1,Math.min(12,e.rows));return f("div",{className:"relative group rounded-lg border border-border bg-surface overflow-hidden flex flex-col",style:{gridColumn:`span ${n} / span ${n}`,gridRow:`span ${r} / span ${r}`},children:[o("button",{type:"button",onClick:t,title:"Remove widget",className:"absolute right-1.5 top-1.5 z-10 inline-flex h-5 w-5 items-center justify-center rounded-md border border-border/60 bg-surface/80 text-foreground-subtle opacity-0 group-hover:opacity-100 hover:bg-danger/10 hover:text-danger hover:border-danger/40 transition-all",children:o(Fe,{className:"h-3 w-3"})}),o("div",{className:"flex-1 min-h-0 overflow-auto p-2",children:o(ft,{widgetId:e.widgetId,host:"dashboard",instanceId:e.instanceId,config:e.config,deviceId:e.deviceId,size:e.size,columns:e.columns,rows:e.rows})})]})}function e7(e){return!Number.isFinite(e)||e<1?6:Math.min(12,Math.floor(e))}function t7({widgets:e,onClose:t,onAdd:n}){const[r,s]=_(null);return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-2xl rounded-xl border border-border bg-surface p-5 shadow-2xl shadow-black/20",onClick:a=>a.stopPropagation(),children:[f("div",{className:"flex items-center justify-between mb-4",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:r?`Configure: ${r.label}`:"Add widget"}),o("button",{onClick:t,className:"p-1 rounded-md hover:bg-surface-hover text-foreground-subtle hover:text-foreground transition-colors",children:o(Fe,{className:"h-4 w-4"})})]}),r===null?o(n7,{widgets:e,onSelect:s}):o(r7,{widget:r,onCancel:()=>s(null),onAdd:n})]})})}function n7({widgets:e,onSelect:t}){return e.length===0?o("div",{className:"text-center py-8 text-xs text-foreground-subtle italic",children:"No dashboard-host widgets registered. Make sure the contributing addons are enabled and have rebuilt their widget bundles."}):o("div",{className:"grid grid-cols-2 gap-2 max-h-96 overflow-auto",children:e.map(n=>f("button",{onClick:()=>t(n),className:"flex flex-col rounded-lg border border-border p-3 text-left hover:bg-surface-hover hover:border-primary/30 transition-all group",children:[o("span",{className:"text-xs font-medium text-foreground block",children:n.label}),o("span",{className:"text-[10px] text-foreground-subtle truncate",title:n.widgetId,children:n.widgetId}),n.description&&o("span",{className:"text-[10px] text-foreground-subtle mt-1 line-clamp-2",children:n.description})]},n.widgetId))})}function r7({widget:e,onCancel:t,onAdd:n}){const[r,s]=_(e.defaultSize),[a,i]=_(e.defaultColumns),[l,c]=_(e.defaultRows),[d,u]=_(null),{data:p}=Bn({},{enabled:e.requires.deviceContext,staleTime:3e4}),h=!e.requires.deviceContext||d!==null&&d>0,m=()=>{if(!h)return;const g={instanceId:Y9(),widgetId:e.widgetId,size:r,columns:a,rows:l,...e.requires.deviceContext&&d!==null?{deviceId:d}:{}};n(g)};return f("div",{className:"space-y-3",children:[f("div",{children:[o("label",{className:"block text-[11px] font-medium text-foreground-subtle mb-1",children:"Size"}),o("div",{className:"flex items-center gap-1",children:e.allowedSizes.map(g=>o("button",{onClick:()=>s(g),className:`px-3 py-1 rounded-md text-[11px] font-medium border transition-colors ${r===g?"bg-primary/10 text-primary border-primary/30":"border-border text-foreground-subtle hover:bg-surface-hover hover:text-foreground"}`,children:g.toUpperCase()},g))})]}),f("div",{className:"grid grid-cols-2 gap-3",children:[o(gf,{label:"Columns (1-12)",value:a,min:1,max:12,onChange:i}),o(gf,{label:"Rows (1-12)",value:l,min:1,max:12,onChange:c})]}),e.requires.deviceContext&&f("div",{children:[o("label",{className:"block text-[11px] font-medium text-foreground-subtle mb-1",children:"Device"}),f("select",{value:d??"",onChange:g=>u(g.target.value===""?null:Number(g.target.value)),className:"w-full rounded-md border border-border bg-surface px-2 py-1.5 text-foreground text-xs focus:border-primary outline-none",children:[o("option",{value:"",children:"— select a device —"}),(p??[]).map(g=>f("option",{value:g.id,children:[g.name??g.stableId," (#",g.id,")"]},g.id))]})]}),f("div",{className:"flex items-center justify-end gap-2 pt-2 border-t border-border",children:[o("button",{onClick:t,className:"px-3 py-1.5 rounded-md text-xs font-medium border border-border text-foreground-subtle hover:bg-surface-hover hover:text-foreground transition-colors",children:"Back"}),o("button",{disabled:!h,onClick:m,className:"px-3 py-1.5 rounded-md text-xs font-medium bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:"Add to dashboard"})]})]})}function gf({label:e,value:t,min:n,max:r,onChange:s}){return f("div",{children:[o("label",{className:"block text-[11px] font-medium text-foreground-subtle mb-1",children:e}),o("input",{type:"number",min:n,max:r,value:t,onChange:a=>{const i=Number(a.target.value);Number.isFinite(i)&&s(Math.max(n,Math.min(r,Math.floor(i))))},className:"w-full rounded-md border border-border bg-surface px-2 py-1.5 text-foreground text-xs focus:border-primary outline-none"})]})}function o7(){return o(Z9,{})}function tt({icon:e,title:t,subtitle:n,actions:r,children:s}){const a=!!t||n!=null||r!=null;return f("div",{className:"p-4 space-y-4",children:[a&&f("div",{className:"flex items-center justify-between gap-4",children:[f("div",{className:"min-w-0",children:[t&&f("h1",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[e&&o(e,{className:"h-4 w-4 text-foreground-subtle"}),t]}),n&&o("p",{className:"text-xs text-foreground-subtle mt-0.5",children:n})]}),r&&o("div",{className:"shrink-0 flex items-center gap-2",children:r})]}),s]})}const bf=["camera","hub","nvr","light","siren","switch","sensor","thermostat","button","generic"];function s7(){const{t:e}=Vt(),t=rt(),n=Te();St(["deviceManager"],["device.registered","device.unregistered","device.online","device.offline","device.disabled","device.enabled"]),St(["integrations"],["integration.enabled","integration.disabled","integration.deleted","provider.started","provider.stopped","addon.installed","addon.uninstalled","addon.started","addon.stopped"]);const{data:r}=Bn({},{staleTime:3e4}),{data:s}=pd(void 0,{staleTime:3e4}),a=H(()=>r??[],[r]),{activeDevices:i,orphanDevices:l}=H(()=>{const m=new Set((s??[]).map(k=>k.addonId)),g=k=>typeof k.addonId=="string"&&k.addonId.length>0&&!m.has(k.addonId),b=new Set;for(const k of a)g(k)&&b.add(k.id);const x=new Set(b),y=new Map;for(const k of a)y.set(k.id,k);const w=(k,C=0)=>{if(C>32)return!1;if(b.has(k.id))return!0;if(k.parentDeviceId==null)return!1;const E=y.get(k.parentDeviceId);return E?w(E,C+1):!1};for(const k of a)w(k)&&x.add(k.id);const v=[],N=[];for(const k of a)x.has(k.id)?N.push(k):v.push(k);return{activeDevices:v,orphanDevices:N}},[a,s]),c=H(()=>{const m=new Map;for(const g of a)m.set(g.id,{id:g.id,name:g.name??g.stableId??`#${String(g.id)}`});return m},[a]),d=U(m=>c.get(m)??null,[c]),u=H(()=>(s??[]).map(m=>({id:m.addonId,name:m.name??m.addonId,icon:o(gn,{type:m.addonId,size:"sm"})})),[s]),p=U(m=>o(gn,{type:m,size:"sm"}),[]),h=U(m=>t(`/devices/${String(m)}`),[t]);return f(tt,{icon:Dr,title:e("nav.devices","Devices"),children:[o(Ao,{devices:i,trpc:n.trpcClient,filters:{types:bf,addons:u},resolveIntegrationIcon:p,resolveParent:d,onNavigate:h}),l.length>0&&f("div",{className:"mt-6 space-y-2",children:[f("div",{className:"flex items-baseline gap-2",children:[o(it,{className:"h-3.5 w-3.5 text-warning shrink-0"}),o("h2",{className:"text-sm font-semibold text-foreground",children:"Orphan devices"}),f("span",{className:"text-[10px] text-foreground-subtle",children:[l.length," device",l.length===1?"":"s"," pointing at integrations no longer registered"]})]}),f("div",{className:"rounded-lg border border-warning/30 bg-warning/5 p-2",children:[o("p",{className:"text-[11px] text-foreground-subtle px-2 pb-2",children:"These devices reference an addonId that has no matching integration. Delete them, or re-install the missing integration to bring them back online. The provider scope (`addonId`) shown beside each row is what's failing to resolve."}),o(Ao,{devices:l,trpc:n.trpcClient,filters:{types:bf,addons:u},urlScope:"nested",lsKey:"devices:orphan",resolveIntegrationIcon:p,resolveParent:d,onNavigate:h})]})]})]})}function a7({onSelect:e,onClose:t,pendingAddonId:n=null}){const{t:r}=Vt(),s=rt(),{data:a,isLoading:i}=px();if(i)return o("div",{className:"space-y-2 p-2",children:[1,2,3].map(c=>o("div",{className:"h-14 rounded-lg bg-surface animate-pulse"},c))});const l=n!==null;return f("div",{className:"space-y-2",children:[(a??[]).map(c=>{const d=c.instanceMode==="unique"&&c.existingInstances.length>0,u=n===c.addonId,p=l;return f("button",{disabled:p,onClick:()=>{if(!p)if(d){const h=c.existingInstances[0].id;t(),s(`/integrations/${h}`)}else e(c.addonId,c.instanceMode,c.discoveryMode,c.name)},className:"flex w-full items-center gap-3 rounded-lg border border-border bg-surface p-3 text-left hover:border-foreground-subtle/30 transition-colors disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:border-border",children:[c.iconUrl?o("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg flex-shrink-0",style:{backgroundColor:`${c.color}15`},children:o("img",{src:c.iconUrl,alt:"",className:"h-5 w-5"})}):o("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg flex-shrink-0",style:{backgroundColor:`${c.color}15`},children:o("span",{className:"text-sm",style:{color:c.color},children:"◉"})}),f("div",{className:"flex-1 min-w-0",children:[o("p",{className:"text-xs font-semibold text-foreground",children:c.name}),c.description&&o("p",{className:"text-[10px] text-foreground-subtle mt-0.5 truncate",children:c.description})]}),u?o(Se,{className:"h-4 w-4 animate-spin text-primary flex-shrink-0"}):d?f("span",{className:"flex items-center gap-1 text-[10px] font-medium text-foreground-subtle",children:[o(Jt,{className:"h-3 w-3"}),r("integrations.manage")]}):o(wt,{className:"h-4 w-4 text-foreground-subtle flex-shrink-0"})]},c.addonId)}),(a??[]).length===0&&o("div",{className:"py-8 text-center text-xs text-foreground-subtle",children:r("integrations.noProviders")})]})}function i7(e){return/^[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)+$/.test(e)}function xf(e,t){if(e!==void 0)return t&&i7(e)?t(e):e}function l7({section:e,values:t,onChange:n,disabled:r,translationFn:s,onTestField:a,probeResults:i,onAction:l}){const[c,d]=_(e.defaultCollapsed??!1),u=e.style==="accordion";if(e.fields.reduce((b,x)=>b+(Nd(x,t,e.fields)?1:0),0)===0)return null;const h=e.columns??2,m=h===1?"grid-cols-1":h===3?"grid-cols-1 @[420px]:grid-cols-2 @[680px]:grid-cols-3":h===4?"grid-cols-1 @[420px]:grid-cols-2 @[900px]:grid-cols-4":"grid-cols-1 @[480px]:grid-cols-2",g=!e.title&&!e.description;return f("div",{className:"@container rounded-lg border border-border bg-surface p-3",style:{containerType:"inline-size"},children:[!g&&f("div",{className:["flex items-center justify-between mb-2",u?"cursor-pointer":""].join(" "),onClick:u?()=>d(b=>!b):void 0,children:[f("div",{children:[e.title&&o("h3",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wider",children:xf(e.title,s)}),e.description&&o("p",{className:"text-[10px] text-foreground-subtle mt-0.5",children:xf(e.description,s)})]}),u&&o("span",{className:"text-foreground-subtle text-xs ml-2",children:c?"▸":"▾"})]}),!c&&o("div",{className:`grid ${m} gap-x-3 gap-y-2.5`,children:e.fields.map(b=>o(gr,{field:b,values:t,onChange:n,disabled:r,translationFn:s,onTestField:a,externalProbe:i?.[b.key],allFields:e.fields,onAction:l},b.key))})]})}function Dn({schema:e,values:t,onChange:n,disabled:r,translationFn:s,onTestField:a,probeResults:i,onClearProbe:l,onAction:c}){const d=(u,p)=>{n({...t,[u]:p}),l?.(u)};return o("div",{className:"space-y-4",children:e.sections.map((u,p)=>o(l7,{section:u,values:t,onChange:d,disabled:r,translationFn:s,onTestField:a,probeResults:i,onAction:c},`${u.id}-${p}`))})}function c7({addonId:e,configSchema:t,onSave:n,onBack:r}){const{t:s}=Vt(),[a,i]=_(""),[l,c]=_({}),[d,u]=_(null),p=fx({onSuccess:h=>u(h),onError:h=>u({success:!1,error:String(h)})});return f("div",{className:"space-y-4",children:[f("div",{children:[o("label",{className:"block text-[11px] font-medium text-foreground mb-1",children:s("integrations.integrationName")}),o("input",{type:"text",value:a,onChange:h=>i(h.target.value),placeholder:s("integrations.integrationNamePlaceholder"),className:"w-full rounded-lg border border-border bg-surface px-3 py-2 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:border-primary/50"})]}),t&&o(Dn,{schema:t,values:l,onChange:c}),d&&o("div",{className:`rounded-lg border px-3 py-2 text-xs ${d.success?"border-success/30 bg-success/5 text-success":"border-danger/30 bg-danger/5 text-danger"}`,children:d.success?s("integrations.connectionSuccess"):`${s("integrations.errorPrefix")} ${d.error}`}),f("div",{className:"flex items-center justify-between pt-2",children:[o("button",{onClick:r,className:"rounded-lg border border-border px-3 py-1.5 text-xs text-foreground-subtle hover:text-foreground transition-colors",children:s("integrations.back")}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>p.mutate({addonId:e,settings:l}),disabled:p.isPending,className:"rounded-lg border border-border px-3 py-1.5 text-xs text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",children:p.isPending?s("integrations.testing"):s("integrations.testConnection")}),o("button",{onClick:()=>n({name:a,config:l}),disabled:!a.trim(),className:"rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground shadow-sm disabled:opacity-50",children:s("integrations.forward")})]})]})]})}function d7({providerId:e,onImport:t,onSkip:n}){const{t:r}=Vt(),[s,a]=_(new Set),i=dd(),l=i.data,c=i.isPending||!i.data&&!i.isError;Y(()=>{e&&(i.isPending||i.data||i.mutate({addonId:e}))},[e,i]);function d(p){a(h=>{const m=new Set(h);return m.has(p)?m.delete(p):m.add(p),m})}if(c)return f("div",{className:"flex flex-col items-center py-12",children:[o("div",{className:"h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent"}),o("p",{className:"mt-3 text-xs text-foreground-subtle",children:r("integrations.searchingDevices")})]});const u=l??[];return f("div",{className:"space-y-4",children:[o("p",{className:"text-xs text-foreground-subtle",children:u.length>0?r("integrations.foundDevices",{count:u.length}):r("integrations.noDevicesFound")}),u.length>0&&o("div",{className:"space-y-1.5 max-h-64 overflow-y-auto",children:u.map(p=>{const h=p.stableId,m=p.suggestedName??h,g=s.has(h);return f("button",{onClick:()=>d(h),className:`flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-colors ${g?"border-primary/40 bg-primary/5":"border-border bg-surface hover:border-foreground-subtle/30"}`,children:[o("div",{className:`flex h-5 w-5 items-center justify-center rounded border flex-shrink-0 ${g?"border-primary bg-primary":"border-border"}`,children:g&&o(_t,{className:"h-3 w-3 text-primary-foreground"})}),o(Dr,{className:"h-3.5 w-3.5 text-foreground-subtle flex-shrink-0"}),o("span",{className:"text-xs font-medium text-foreground truncate",children:m})]},h)})}),f("div",{className:"flex items-center justify-between pt-2",children:[o("button",{onClick:n,className:"rounded-lg border border-border px-3 py-1.5 text-xs text-foreground-subtle hover:text-foreground transition-colors",children:r("integrations.skip")}),u.length>0&&f("button",{onClick:()=>t(Array.from(s)),disabled:s.size===0,className:"rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground shadow-sm disabled:opacity-50",children:[r("integrations.importSelected")," (",s.size,")"]})]})]})}function u7(e){const t=n=>{if(n.type==="separator"||n.type==="info"||n.type==="button")return n;if(n.type==="group")return{...n,fields:n.fields.map(i=>t(i))};const r=n,{value:s,...a}=r;return a};return{...e.tabs?{tabs:e.tabs}:{},sections:e.sections.map(n=>({...n,fields:n.fields.map(t)}))}}function p7({open:e,onClose:t}){const{t:n}=Vt(),r=rt(),s=ke(),[a,i]=_("picker"),[l,c]=_(null),[d,u]=_(null),[p,h]=_("manual"),{data:m}=sd({addonId:l??"",nodeId:"hub"},{enabled:l!=null}),g=H(()=>m?u7(m):null,[m]),b=cx({onSuccess:()=>s.invalidateQueries({queryKey:[["integrations"]]})}),x=dd(),y=x.data;Y(()=>{a!=="discovery"||!d||!l||x.isPending||x.data||x.mutate({addonId:l})},[a,d,l,x]);const w=ox({onSuccess:()=>s.invalidateQueries({queryKey:[["deviceManager"]]})});async function v(R,M,D,T){if(!b.isPending){if(c(R),h(D),M==="unique"){try{const L=await b.mutateAsync({addonId:R,name:T,settings:{}});t(),E(),r(`/integrations/${L.id}`)}catch{}return}i("config")}}async function N(R){if(l)try{const M=await b.mutateAsync({addonId:l,name:R.name,settings:R.config});u(M.id),p==="auto"||p==="both"?i("discovery"):C(M.id)}catch{}}async function k(R){if(l){for(const M of R){const D=y?.find(T=>T.stableId===M);D&&await w.mutateAsync({addonId:l,candidate:D})}C()}}function C(R){const M=R??d??l;t(),E(),M&&r(`/integrations/${M}`)}function E(){i("picker"),c(null),u(null),h("manual")}function I(){t(),E()}if(!e)return null;const A={picker:n("integrations.newIntegration"),config:n("integrations.configureIntegration"),discovery:n("integrations.importDevices")},z=b.isPending,P=z?l:null,B=b.error;return f("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[o("div",{className:"absolute inset-0 bg-black/60",onClick:z?void 0:I}),f("div",{className:"relative z-10 w-full max-w-lg rounded-xl border border-border bg-background shadow-2xl",children:[f("div",{className:"flex items-center justify-between border-b border-border px-5 py-4",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:A[a]}),o("button",{onClick:I,disabled:z,className:"rounded-md p-1 text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"relative px-5 py-4",children:[B&&!z&&o("div",{className:"mb-3 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:B instanceof Error?B.message:String(B)}),a==="picker"&&o(a7,{onSelect:v,onClose:I,pendingAddonId:P}),a==="config"&&l&&o(c7,{addonId:l,configSchema:g??null,onSave:N,onBack:()=>i("picker")}),a==="discovery"&&d&&o(d7,{providerId:d,onImport:k,onSkip:C}),z&&f("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-2 bg-background/85 backdrop-blur-sm",children:[o(Se,{className:"h-6 w-6 animate-spin text-primary"}),o("p",{className:"text-xs font-medium text-foreground",children:n("integrations.creating",{defaultValue:"Creating integration…"})}),o("p",{className:"text-[10px] text-foreground-subtle",children:n("integrations.creatingHint",{defaultValue:"Waiting for the addon to restart and register"})})]})]})]})]})}const yf={running:{bg:"bg-success/10",text:"text-success",dot:"bg-success",label:"Running"},stopped:{bg:"bg-foreground-subtle/10",text:"text-foreground-subtle",dot:"bg-foreground-subtle",label:"Stopped"},error:{bg:"bg-danger/10",text:"text-danger",dot:"bg-danger",label:"Error"},online:{bg:"bg-success/10",text:"text-success",dot:"bg-success",label:"Online"},offline:{bg:"bg-foreground-subtle/10",text:"text-foreground-subtle",dot:"bg-foreground-subtle",label:"Offline"},idle:{bg:"bg-info/10",text:"text-info",dot:"bg-info",label:"Idle"},disabled:{bg:"bg-warning/10",text:"text-warning",dot:"bg-warning",label:"Disabled"},enabled:{bg:"bg-success/10",text:"text-success",dot:"bg-success",label:"Enabled"}};function ti({status:e}){const t=yf[e]??yf.stopped;return f("span",{className:`inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-medium ${t.bg} ${t.text}`,children:[o("span",{className:`h-1.5 w-1.5 rounded-full ${t.dot}`}),t.label]})}const Gi="px-3 py-2 text-left text-[10px] font-semibold uppercase tracking-wider text-foreground-subtle";function f7({integrations:e,expandedAddonId:t,onToggleExpand:n,onOpenSettings:r,renderExpanded:s}){const a=U(i=>n(i),[n]);return o("div",{className:"overflow-hidden rounded-lg border border-border bg-surface",children:f("table",{className:"w-full table-fixed text-xs",children:[o("thead",{className:"bg-surface-hover/40",children:f("tr",{children:[o("th",{className:K(Gi,"w-[60%]"),children:"Integration"}),o("th",{className:K(Gi,"w-[15%]"),children:"Devices"}),o("th",{className:K(Gi,"w-[25%]"),children:"Status"})]})}),o("tbody",{children:e.map(i=>{const l=t===i.addonId;return o(h7,{integration:i,isExpanded:l,onClick:a,onOpenSettings:r,renderExpanded:s},i.id)})})]})})}function h7({integration:e,isExpanded:t,onClick:n,onOpenSettings:r,renderExpanded:s}){const a=U(c=>{c.stopPropagation(),r(e.id)},[e.id,r]),i=U(()=>{n(e.addonId)},[e.addonId,n]),l=U(c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),i())},[i]);return f(me,{children:[f("tr",{role:"button",tabIndex:0,"aria-expanded":t,className:K("cursor-pointer border-t border-border transition-colors hover:bg-surface-hover","focus:outline-none focus-visible:ring-1 focus-visible:ring-primary/40",t&&"bg-surface-hover/60"),onClick:i,onKeyDown:l,children:[o("td",{className:"px-3 py-2.5",children:f("div",{className:"flex items-center gap-2.5",children:[t?o(lt,{className:"h-3.5 w-3.5 flex-shrink-0 text-foreground-subtle"}):o(wt,{className:"h-3.5 w-3.5 flex-shrink-0 text-foreground-subtle"}),o(gn,{type:e.addonId,size:"sm"}),f("div",{className:"flex min-w-0 flex-col",children:[o("span",{className:"truncate text-xs font-semibold text-foreground",children:e.name}),o("span",{className:"truncate text-[10px] text-foreground-subtle",children:e.addonId})]})]})}),f("td",{className:"px-3 py-2.5 text-[11px] text-foreground-subtle",children:[e.deviceCount," device",e.deviceCount!==1?"s":""]}),o("td",{className:"px-3 py-2.5",children:f("div",{className:"flex items-center justify-between gap-2",children:[o(ti,{status:e.status}),f("button",{type:"button",onClick:a,className:"flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium text-foreground-subtle transition-colors hover:bg-primary/10 hover:text-primary",title:"Open integration settings",children:[o(Jt,{className:"h-3 w-3"}),"Settings"]})]})})]}),t&&o("tr",{className:"border-t border-border bg-surface",children:o("td",{colSpan:3,className:"px-3 py-3",children:s(e.addonId)})})]})}function m7(e){if(!e.enabled)return"disabled";switch(e.processState){case"running":return"running";case"stopped":case"crashed":case"unknown":default:return"stopped"}}const Cs="expand";function g7(){const{t:e}=Vt(),t=rt(),n=Te(),[r]=Ga(),[s,a]=_(!1),i=U(()=>a(!0),[]),l=U(()=>a(!1),[]);St(["integrations"],["integration.enabled","integration.disabled","integration.deleted","provider.started","provider.stopped","addon.installed","addon.uninstalled","addon.started","addon.stopped","addon.updated"]),St(["deviceManager"],["device.registered","device.unregistered","device.online","device.offline","device.disabled","device.enabled"]);const{data:c,isLoading:d,refetch:u}=pd(void 0,{staleTime:3e4}),{data:p,isLoading:h,refetch:m}=Bn({},{staleTime:3e4}),g=H(()=>p??[],[p]),b=H(()=>c??[],[c]),x=H(()=>{const R=new Map;for(const M of g)R.set(M.id,{id:M.id,name:M.name??M.stableId??`#${String(M.id)}`});return R},[g]),y=H(()=>{const R=new Map;for(const M of g){if(M.parentDeviceId!==null&&M.parentDeviceId!==void 0&&!!M.role)continue;const T=M.addonId??"";T&&R.set(T,(R.get(T)??0)+1)}return R},[g]),w=H(()=>b.map(R=>({id:R.id,addonId:R.addonId,name:R.name,enabled:R.enabled,status:m7(R),deviceCount:y.get(R.addonId)??0})),[b,y]),v=r.get(Cs),N=U(R=>{const M=new URLSearchParams(window.location.search);M.get(Cs)===R?M.delete(Cs):M.set(Cs,R);const T=M.toString(),L=`${window.location.pathname}${T?`?${T}`:""}${window.location.hash}`;window.history.replaceState(window.history.state,"",L),window.dispatchEvent(new PopStateEvent("popstate"))},[]),k=U(R=>t(`/integrations/${R}`),[t]),C=U(R=>x.get(R)??null,[x]),E=U(R=>o(gn,{type:R,size:"sm"}),[]),I=U(R=>t(`/devices/${String(R)}`),[t]),A=U(R=>o(Ao,{devices:g,trpc:n.trpcClient,forceAddon:R,urlScope:"nested",lsKey:`integrations:nested:${R}`,resolveIntegrationIcon:E,resolveParent:C,onNavigate:I}),[g,n.trpcClient,E,C,I]),z=U(()=>{u(),m()},[u,m]),P=d||h,B=b.length>0;return f(tt,{icon:_o,title:e("nav.integrations","Integrations"),actions:f(me,{children:[o("button",{onClick:z,disabled:P,className:"flex items-center gap-1 rounded-lg border border-border bg-surface px-2.5 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",title:"Refresh",children:o(ct,{className:K("h-3.5 w-3.5",P&&"animate-spin")})}),f("button",{onClick:i,className:"flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground shadow-sm",children:[o(Et,{className:"h-3.5 w-3.5"}),"New Integration"]})]}),children:[P&&o("div",{className:"space-y-2",children:[1,2,3].map(R=>o("div",{className:"h-12 rounded-lg border border-border bg-surface animate-pulse"},R))}),!P&&!B&&f("div",{className:"flex flex-col items-center py-20 text-foreground-subtle",children:[o("p",{className:"text-sm",children:"No integrations configured."}),o("p",{className:"text-xs mt-1",children:'Click "New Integration" to connect cameras and devices.'})]}),!P&&B&&o(f7,{integrations:w,expandedAddonId:v,onToggleExpand:N,onOpenSettings:k,renderExpanded:A}),o(p7,{open:s,onClose:l})]})}function Nv(e){const t=[];for(const n of e)n.type==="probe"&&t.push(n.key),n.type==="group"&&"fields"in n&&t.push(...Nv(n.fields));return t}function b7(e,t,n){const[r,s]=_("idle"),[a,i]=_({}),l=H(()=>{const p=[];for(const h of e.sections)p.push(...Nv(h.fields));return p},[e]),c=l.length>0&&n!==void 0,d=U(p=>{i(h=>{if(!h[p])return h;const m={...h};return delete m[p],m})},[]),u=U(async()=>{if(!n)return;const p=l.filter(b=>{const x=t[b];return x!=null&&String(x).trim()!==""});if(p.length===0)return;s("testing");const h={};for(const b of p)h[b]={status:"probing"};i(h);const m=await Promise.allSettled(p.map(async b=>{try{const x=await n(b,t[b]);return{key:b,result:x}}catch(x){const w={status:"error",error:x instanceof Error?x.message:String(x)};return{key:b,result:w}}})),g={};for(const b of m)if(b.status==="fulfilled"){const{key:x,result:y}=b.value;g[x]={status:y.status==="ok"?"ok":"error",result:y}}i(g),s("idle")},[n,l,t]);return{testAllStatus:r,hasProbeFields:c,probeResults:a,handleTestAll:u,clearProbeResult:d}}function kv(e){const t=[];for(const n of e)"required"in n&&n.required===!0&&"key"in n&&n.key&&t.push(n.key),n.type==="group"&&"fields"in n&&t.push(...kv(n.fields));return t}function Ki(e){return e==null?!0:typeof e=="string"?e.trim()==="":!1}function Xl(e,t={}){for(const n of e){if(n.type==="group"&&"fields"in n){Xl(n.fields,t);continue}"key"in n&&n.key&&"default"in n&&n.default!==void 0&&(t[n.key]=n.default)}return t}function vf(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`probe-${crypto.randomUUID()}`:`probe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function x7({open:e,integrationId:t,addonId:n,onClose:r}){const{t:s}=Vt(),a=ke(),[i,l]=_({}),[c,d]=_(!1),[u,p]=_(null),[h,m]=_(vf),g=sx({addonId:n,type:pt.Camera},{enabled:e}),b=g.data??null;Y(()=>{if(e){const M=b?Xl(b.sections.flatMap(D=>D.fields)):{};l(M),m(vf()),d(!1),p(null)}},[e,t,b]);const x=H(()=>({...i,_probeRequestId:h}),[i,h]),y=ax({onSuccess:()=>{a.invalidateQueries({queryKey:[["deviceManager"]]})}}),w=ud(),v=U(async(M,D)=>{d(!0);const T=await w.mutateAsync({addonId:n,type:pt.Camera,key:M,value:D,formValues:x});return T.status==="ok"&&T.suggestedValues&&l(L=>{let O=!1;const F={...L};for(const[j,V]of Object.entries(T.suggestedValues??{}))Ki(L[j])&&!Ki(V)&&(F[j]=V,O=!0);return O?F:L}),T},[w,n,x]),{testAllStatus:N,hasProbeFields:k,probeResults:C,handleTestAll:E,clearProbeResult:I}=b7(b??{sections:[]},i,v);async function A(M){p(null);try{if(await y.mutateAsync({addonId:n,type:pt.Camera,config:i}),M){const D=b?Xl(b.sections.flatMap(T=>T.fields)):{};l(D)}else r()}catch(D){p(D instanceof Error?D.message:String(D))}}if(!e)return null;const P=kv((b?.sections??[]).flatMap(M=>M.fields)).filter(M=>Ki(i[M])),B=P.length===0,R=!g.isLoading&&(g.isError||b===null);return f("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[o("div",{className:"absolute inset-0 bg-black/60",onClick:r}),f("div",{className:"relative z-10 flex w-full max-w-2xl flex-col max-h-[90vh] rounded-xl border border-border bg-background shadow-2xl",children:[f("div",{className:"flex items-center justify-between border-b border-border px-5 py-4 shrink-0",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:s("integrations.addDevice")}),o("button",{onClick:r,className:"rounded-md p-1 text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:o(Fe,{className:"h-4 w-4"})})]}),o("div",{className:"flex-1 min-h-0 overflow-y-auto px-5 py-4 space-y-3",children:g.isLoading?o("div",{className:"flex items-center justify-center py-8",children:o(Se,{className:"h-5 w-5 animate-spin text-primary"})}):R?f("div",{className:"flex items-start gap-3 rounded-lg border border-destructive/40 bg-destructive/10 px-4 py-3",children:[o(it,{className:"h-4 w-4 text-destructive mt-0.5 shrink-0"}),f("div",{className:"space-y-1",children:[o("p",{className:"text-xs font-medium text-destructive",children:"Provider unavailable"}),f("p",{className:"text-xs text-foreground-subtle",children:["The addon ",o("span",{className:"font-mono",children:n})," is not ready or does not support manual device creation. Check that the integration is online and try again."]})]})]}):o(Dn,{schema:b,values:i,onChange:l,onTestField:v,probeResults:C,onClearProbe:I})}),!R&&!g.isLoading&&f("div",{className:"border-t border-border bg-surface/50 shrink-0",children:[f("button",{type:"button",onClick:()=>d(M=>!M),className:"flex w-full items-center justify-between px-5 py-2 text-[11px] text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:[f("span",{className:"flex items-center gap-2",children:[o(at,{className:"h-3.5 w-3.5"}),"Test logs",o("span",{className:"font-mono text-[9px] opacity-60",children:h.slice(0,14)})]}),o(lt,{className:`h-3.5 w-3.5 transition-transform ${c?"rotate-180":""}`})]}),c&&o("div",{className:"border-t border-border max-h-64 overflow-hidden",children:o(tn,{addonId:n,requestId:h,limit:50,maxHeight:"max-h-64",showFilters:!1,showScope:!1,className:"border-0 rounded-none"})})]}),!R&&!g.isLoading&&(u||P.length>0)&&o("div",{className:"border-t border-destructive/30 bg-destructive/5 px-5 py-2 shrink-0",children:f("div",{className:"flex items-start gap-2",children:[o(it,{className:"h-3.5 w-3.5 text-destructive mt-0.5 shrink-0"}),o("p",{className:"text-[11px] text-destructive",children:u||`Required: ${P.join(", ")}`})]})}),f("div",{className:"flex items-center justify-between border-t border-border px-5 py-3 shrink-0",children:[f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:r,className:"rounded-lg border border-border px-3 py-1.5 text-xs text-foreground-subtle hover:text-foreground transition-colors",children:s("integrations.cancel")}),!R&&k&&f("button",{type:"button",onClick:E,disabled:N==="testing",className:"inline-flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",children:[N==="testing"?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(or,{className:"h-3.5 w-3.5"}),"Test All"]})]}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>A(!0),disabled:R||!B||y.isPending,className:"rounded-lg border border-border px-3 py-1.5 text-xs text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",children:s("integrations.saveAndNew")}),o("button",{onClick:()=>A(!1),disabled:R||!B||y.isPending,className:"rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground shadow-sm disabled:opacity-50",children:y.isPending?s("integrations.saving"):s("integrations.save")})]})]})]})]})}function y7(){const{t:e}=Vt(),{integrationId:t}=zd(),n=ke(),r=rt(),s=Te(),[a,i]=_(!1),[l,c]=_(!1),[d,u]=_(!1),[p,h]=_(!1),{data:m,isLoading:g}=ix({id:t??""},{enabled:!!t}),{data:b}=sd({addonId:m?.addonId??"",nodeId:"hub"},{enabled:!!m?.addonId}),x=b!=null&&Array.isArray(b.sections)&&b.sections.some(B=>B.fields.length>0),{data:y}=Bn({},{refetchInterval:5e3}),w=[["integrations","get"],{input:{id:t??""},type:"query"}],v=dx({onMutate:async B=>{await n.cancelQueries({queryKey:w});const R=n.getQueryData(w);return R!=null&&n.setQueryData(w,{...R,enabled:B.enabled}),{previous:R}},onError:(B,R,M)=>{const D=M;D?.previous!=null&&n.setQueryData(w,D.previous)},onSettled:()=>{n.invalidateQueries({queryKey:[["integrations"]]}),n.invalidateQueries({queryKey:[["deviceManager"]]})}}),N=ux({onSuccess:()=>{n.invalidateQueries({queryKey:[["integrations"]]}),n.invalidateQueries({queryKey:[["deviceManager"]]}),u(!1),r("/integrations")}}),k=Ko({onSuccess:()=>{n.invalidateQueries({queryKey:[["integrations"]]}),n.invalidateQueries({queryKey:[["deviceManager"]]})}}),C=H(()=>y??[],[y]),E=H(()=>{const B=new Map;for(const R of C)B.set(R.id,{id:R.id,name:R.name??R.stableId??`#${String(R.id)}`});return B},[C]),I=U(B=>E.get(B)??null,[E]),A=U(B=>o(gn,{type:B,size:"sm"}),[]),z=U(B=>r(`/devices/${String(B)}`),[r]),P=H(()=>{const B=m?.addonId;if(!B)return 0;let R=0;for(const M of C)M.addonId!==B||M.parentDeviceId!==null&&M.parentDeviceId!==void 0&&M.role||(R+=1);return R},[C,m?.addonId]);return g?f("div",{className:"p-4",children:[o("div",{className:"h-16 rounded-lg bg-surface animate-pulse mb-4"}),o("div",{className:"h-40 rounded-lg bg-surface animate-pulse"})]}):m?f("div",{className:"p-4 space-y-4",children:[o(Hc,{items:[{label:"Integrations",onClick:()=>r("/integrations")},{label:m.name}]}),f("div",{className:"flex items-center justify-between",children:[f("div",{className:"flex items-center gap-3",children:[o("img",{src:`/api/addon-assets/${m.addonId}/assets/icon.svg`,alt:"",className:"h-8 w-8 rounded-lg",onError:B=>{B.target.style.display="none"}}),f("div",{children:[o("h1",{className:"text-lg font-semibold text-foreground",children:m.name}),f("p",{className:"text-[11px] text-foreground-subtle mt-0.5",children:[m.addonId," · ",P," ",e("integrations.devices")]})]})]}),f("div",{className:"flex items-center gap-3",children:[f("div",{className:`inline-flex items-center gap-2 rounded-lg border px-3 py-1.5 transition-colors ${v.isPending?"opacity-60":""} ${m.enabled?"border-success/30 bg-success/5":"border-border bg-surface"}`,title:e("integrations.toggleHint",{defaultValue:"Click to toggle"}),children:[o(Oc,{checked:m.enabled,onCheckedChange:B=>v.mutate({id:t,enabled:B}),disabled:v.isPending,"aria-label":m.enabled?"Disable integration":"Enable integration"}),o("span",{className:`text-[11px] font-medium ${m.enabled?"text-success":"text-foreground-subtle"}`,children:m.enabled?"Enabled":"Disabled"}),v.isPending&&o(Se,{className:"h-3 w-3 animate-spin text-foreground-subtle"})]}),x&&f("button",{onClick:()=>c(!0),className:"flex items-center gap-1.5 rounded-lg border border-border bg-surface px-3 py-1.5 text-[11px] text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:[o(Jt,{className:"h-3 w-3"}),e("integrations.config")]}),f("button",{onClick:()=>h(!0),className:"flex items-center gap-1.5 rounded-lg border border-border bg-surface px-3 py-1.5 text-[11px] text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",title:e("integrations.logs",{defaultValue:"View logs"}),children:[o(at,{className:"h-3 w-3"}),e("integrations.logs",{defaultValue:"Logs"})]}),o(Ad,{label:"Restart",icon:ct,title:`Restart "${m.name}"?`,description:`Restarting the addon will briefly disconnect every device backed by it (${P} active). Streams will reconnect automatically.`,confirmLabel:"Restart",triggerVariant:"outline",confirmVariant:"danger",disabled:k.isPending,action:()=>k.mutateAsync({addonId:m.addonId})}),f("button",{onClick:()=>u(!0),className:"flex items-center gap-1.5 rounded-lg border border-danger bg-danger/10 px-3 py-1.5 text-[11px] font-medium text-danger hover:bg-danger hover:text-background transition-colors",title:e("integrations.delete",{defaultValue:"Delete integration"}),children:[o(Ze,{className:"h-3 w-3"}),e("integrations.delete",{defaultValue:"Delete"})]})]})]}),o(Ao,{devices:C,trpc:s.trpcClient,defaultView:"cards",forceAddon:m.addonId,urlScope:"root",lsKey:`integration-detail:${m.addonId}`,resolveIntegrationIcon:A,resolveParent:I,onNavigate:z}),o("button",{onClick:()=>i(!0),className:"fixed bottom-6 right-6 flex h-12 w-12 items-center justify-center rounded-full bg-primary shadow-lg shadow-primary/30 hover:shadow-primary/40 transition-shadow",title:e("integrations.addDevice"),children:o(Et,{className:"h-5 w-5 text-primary-foreground"})}),a&&t&&o(x7,{open:a,integrationId:t,addonId:m.addonId,onClose:()=>i(!1)}),l&&o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:()=>c(!1),children:f("div",{className:"rounded-xl border border-border bg-surface p-6 shadow-xl w-80",onClick:B=>B.stopPropagation(),children:[o("h2",{className:"text-sm font-semibold text-foreground mb-2",children:e("integrations.providerConfig")}),o("p",{className:"text-[11px] text-foreground-subtle",children:e("integrations.configComingSoon")}),o("button",{onClick:()=>c(!1),className:"mt-4 w-full rounded-lg bg-primary px-3 py-1.5 text-[11px] text-primary-foreground hover:bg-primary/90 transition-colors",children:"Close"})]})}),p&&o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-6",onClick:()=>h(!1),children:f("div",{className:"flex flex-col rounded-xl border border-border bg-surface shadow-xl w-full max-w-5xl h-[80vh]",onClick:B=>B.stopPropagation(),children:[f("div",{className:"flex items-center justify-between border-b border-border px-4 py-2.5",children:[f("div",{className:"flex items-center gap-2 min-w-0",children:[o(at,{className:"h-4 w-4 text-primary shrink-0"}),o("h2",{className:"text-sm font-semibold text-foreground truncate",children:m.name}),f("span",{className:"text-[10px] text-foreground-subtle font-mono truncate",children:[m.addonId,t?` · ${t}`:""]})]}),o("button",{onClick:()=>h(!1),className:"flex h-7 w-7 items-center justify-center rounded text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors","aria-label":"Close logs",children:o(Fe,{className:"h-4 w-4"})})]}),o("div",{className:"flex-1 min-h-0 overflow-hidden",children:o(tn,{addonId:m.addonId,limit:200,maxHeight:"max-h-full",showScope:!1,className:"h-full border-0 rounded-none"})})]})}),d&&o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60",onClick:()=>!N.isPending&&u(!1),children:f("div",{className:"rounded-xl border border-border bg-background p-5 shadow-2xl w-96 space-y-3",onClick:B=>B.stopPropagation(),children:[f("div",{className:"flex items-start gap-3",children:[o("div",{className:"flex h-9 w-9 items-center justify-center rounded-lg bg-danger/10 shrink-0",children:o(it,{className:"h-4 w-4 text-danger"})}),f("div",{className:"min-w-0",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e("integrations.deleteTitle",{defaultValue:"Delete integration?"})}),o("p",{className:"mt-1 text-[11px] text-foreground-subtle",children:e("integrations.deleteWarning",{defaultValue:'This removes the integration "{{name}}" and its {{count}} device(s). The addon will restart. This cannot be undone.',name:m.name,count:P})})]})]}),N.error&&o("div",{className:"rounded-lg border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger",children:N.error instanceof Error?N.error.message:String(N.error)}),f("div",{className:"flex items-center justify-end gap-2 pt-1",children:[o("button",{onClick:()=>u(!1),disabled:N.isPending,className:"rounded-lg border border-border px-3 py-1.5 text-[11px] text-foreground-subtle hover:text-foreground transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:e("integrations.cancel",{defaultValue:"Cancel"})}),o("button",{onClick:()=>N.mutate({id:t}),disabled:N.isPending,className:"inline-flex items-center gap-1.5 rounded-lg bg-danger px-3 py-1.5 text-[11px] font-medium text-background hover:bg-danger/90 transition-colors disabled:opacity-60 disabled:cursor-not-allowed",children:N.isPending?f(me,{children:[o(Se,{className:"h-3 w-3 animate-spin"}),e("integrations.deleting",{defaultValue:"Deleting…"})]}):f(me,{children:[o(Ze,{className:"h-3 w-3"}),e("integrations.confirmDelete",{defaultValue:"Delete integration"})]})})]})]})})]}):f("div",{className:"flex flex-col items-center justify-center py-20 px-6 text-center gap-4",children:[o("div",{className:"flex h-12 w-12 items-center justify-center rounded-full bg-foreground-subtle/10",children:o(gO,{className:"h-6 w-6 text-foreground-subtle"})}),f("div",{className:"space-y-1 max-w-sm",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e("integrations.integrationNotFound",{defaultValue:"Integration not found"})}),o("p",{className:"text-[11px] text-foreground-subtle",children:e("integrations.integrationNotFoundHint",{defaultValue:'The integration "{{id}}" does not exist. It may have been deleted, or the URL may be wrong.',id:t??""})})]}),f("button",{onClick:()=>r("/integrations"),className:"inline-flex items-center gap-1.5 rounded-lg border border-border bg-surface px-3 py-1.5 text-[11px] font-medium text-foreground hover:bg-surface-hover transition-colors",children:[o(Qd,{className:"h-3 w-3"}),e("integrations.backToList",{defaultValue:"Back to integrations"})]})]})}function v7({label:e,color:t,title:n,style:r}){return f("div",{className:"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 z-10 group cursor-pointer",style:r,title:n,children:[o("div",{className:"h-2.5 w-2.5 rounded-full border-2 border-background shadow-sm transition-transform group-hover:scale-150",style:{backgroundColor:t}}),n&&o("div",{className:"absolute bottom-full left-1/2 -translate-x-1/2 mb-1.5 hidden group-hover:block z-20 pointer-events-none",children:f("div",{className:"bg-surface border border-border rounded px-2 py-1 text-[10px] text-foreground whitespace-nowrap shadow-lg",children:[o("span",{className:"inline-block h-1.5 w-1.5 rounded-full mr-1 align-middle",style:{backgroundColor:t}}),e]})})]})}const Wi=36e5;function w7(e){return String(e).padStart(2,"0")}function N7(e){const t=new Date(e);return`${w7(t.getHours())}:00`}function k7({startMs:e,endMs:t,segments:n,events:r,playheadMs:s,onSeek:a}){const i=te(null),l=t-e,c=U(m=>Math.max(0,Math.min(100,(m-e)/l*100)),[e,l]);function d(m){if(!i.current)return;const g=i.current.getBoundingClientRect(),b=Math.max(0,Math.min(1,(m.clientX-g.left)/g.width));a(Math.round(e+b*l))}const u=[],p=Math.floor(e/Wi),h=Math.ceil(t/Wi);for(let m=p;m<=h;m++){const g=m*Wi;g<e||g>t||u.push({percent:c(g),label:N7(g)})}return f("div",{className:"select-none",children:[o("div",{className:"relative h-5 mb-1",children:u.map(({percent:m,label:g})=>o("span",{className:"absolute -translate-x-1/2 text-[10px] text-foreground-subtle",style:{left:`${m}%`},children:g},g))}),f("div",{ref:i,className:"relative h-8 rounded bg-surface-hover cursor-pointer overflow-hidden border border-border",onClick:d,onPointerMove:m=>{m.buttons===1&&d(m)},children:[n.map((m,g)=>{const b=c(m.startMs),x=c(m.endMs)-b;return o("div",{className:"absolute top-1 bottom-1 rounded-sm bg-success/60",style:{left:`${b}%`,width:`${Math.max(x,.1)}%`}},g)}),r.map(m=>o(v7,{label:m.label,color:m.color,title:`${m.label} — ${new Date(m.timestampMs).toLocaleTimeString()}`,style:{left:`${c(m.timestampMs)}%`}},m.id)),o("div",{className:"absolute top-0 bottom-0 w-0.5 bg-danger z-20 pointer-events-none",style:{left:`${c(s)}%`},children:o("div",{className:"absolute -top-0.5 left-1/2 -translate-x-1/2 w-2.5 h-2.5 bg-danger rotate-45"})})]})]})}const wf={person:"#f59e0b",vehicle:"#3b82f6",car:"#3b82f6",face:"#a855f7",plate:"#ec4899",animal:"#10b981",motion:"#ef4444",unknown:"#6b7280"};function Jl(e){return wf[e.toLowerCase()]??wf.unknown}function S7(e){const t=new Date(e);return t.setHours(0,0,0,0),t.getTime()}function C7(e){return new Date(e).toISOString().slice(0,10)}function M7(e){return new Date(e+"T00:00:00").getTime()}function E7(e){return[{startMs:e+0*36e5,endMs:e+4*36e5},{startMs:e+6*36e5,endMs:e+10*36e5},{startMs:e+12*36e5,endMs:e+16*36e5},{startMs:e+18*36e5,endMs:e+23*36e5}]}function I7(e){const t=["person","vehicle","face","motion"];return Array.from({length:24},(n,r)=>({id:`placeholder-${r}`,timestampMs:e+Math.floor(Math.random()*24*36e5),label:t[r%t.length],color:Jl(t[r%t.length])})).sort((n,r)=>n.timestampMs-r.timestampMs)}function A7(){const{t:e}=Vt(),t=S7(new Date),[n,r]=_(t),[s,a]=_(null),[i,l]=_(t+12*36e5),c=n,d=n+24*36e5,{data:u,isLoading:p}=Bn({},{staleTime:3e4}),h=u??[],m=H(()=>h.filter(N=>{const k=N.type.toLowerCase();return k==="camera"||k.includes("camera")||N.features.some(C=>C.toLowerCase().includes("video")||C.toLowerCase().includes("stream"))}).map(N=>({id:N.id,name:N.name??N.stableId})),[h]),g=s??m[0]?.id??null,{data:b}=Ln({queryKey:["events",g,c],queryFn:()=>Promise.resolve(null),enabled:!!g,staleTime:6e4}),x=H(()=>{const v=Array.isArray(b)?b:(()=>{const k=Tu(b)?.events;return Array.isArray(k)?k:[]})();return v.length===0?g?I7(c):[]:v.flatMap((N,k)=>{const C=Tu(N);if(!C)return[];const E=String(C.class??C.type??C.label??"unknown").toLowerCase(),I=typeof C.timestamp=="number"?C.timestamp:c;return[{id:String(C.id??k),timestampMs:I,label:E,color:Jl(E)}]})},[b,g,c]),y=H(()=>g?E7(c):[],[g,c]);function w(v){r(N=>N+v*24*36e5),l(N=>N+v*24*36e5)}return f("div",{className:"flex flex-col h-full p-4 gap-4 overflow-hidden",children:[f("div",{className:"flex items-center justify-between gap-4 shrink-0",children:[o("h1",{className:"text-lg font-semibold text-foreground",children:e("nav.timeline","Timeline")}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>w(-1),className:"p-1 rounded hover:bg-surface-hover text-foreground-subtle hover:text-foreground transition-colors",children:o(Gd,{className:"h-4 w-4"})}),f("div",{className:"relative flex items-center",children:[o(H0,{className:"absolute left-2 h-3.5 w-3.5 text-foreground-subtle pointer-events-none"}),o("input",{type:"date",value:C7(n),onChange:v=>{if(v.target.value){const N=M7(v.target.value);r(N),l(N+12*36e5)}},className:"rounded-lg border border-border bg-surface pl-7 pr-3 py-1.5 text-xs text-foreground focus:outline-none focus:border-primary/50"})]}),o("button",{onClick:()=>w(1),className:"p-1 rounded hover:bg-surface-hover text-foreground-subtle hover:text-foreground transition-colors",disabled:n>=t,children:o(wt,{className:"h-4 w-4"})})]})]}),f("div",{className:"flex gap-1.5 shrink-0 overflow-x-auto pb-1",children:[p&&o("div",{className:"h-8 w-48 rounded-lg bg-surface animate-pulse"}),!p&&m.length===0&&o("span",{className:"text-xs text-foreground-subtle",children:"No cameras found"}),m.map(v=>{const N=v.id===g;return o("button",{onClick:()=>a(v.id),className:`shrink-0 rounded-lg px-3 py-1.5 text-[12px] font-medium transition-all border ${N?"bg-primary/12 text-primary border-primary/30":"bg-surface text-foreground-subtle border-border hover:bg-surface-hover hover:text-foreground"}`,children:v.name},v.id)})]}),f("div",{className:"relative w-full aspect-video rounded-xl border border-border bg-black shrink-0 overflow-hidden max-h-[45vh]",children:[f("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-3 text-foreground-subtle",children:[o(yo,{className:"h-12 w-12 opacity-20"}),o("p",{className:"text-sm opacity-50",children:g?`${m.find(v=>v.id===g)?.name??g} — seek to play`:"Select a camera"})]}),o("div",{className:"absolute top-3 left-3 rounded bg-black/60 px-2 py-1 text-[11px] text-white font-mono",children:new Date(i).toLocaleTimeString()})]}),f("div",{className:"rounded-xl border border-border bg-surface px-4 pt-3 pb-4 shrink-0",children:[f("div",{className:"flex flex-wrap items-center gap-4 mb-3",children:[o("span",{className:"text-[10px] font-semibold text-foreground-subtle uppercase tracking-wider",children:"Timeline"}),f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"inline-block h-2 w-4 rounded-sm bg-success/60"}),o("span",{className:"text-[10px] text-foreground-subtle",children:"Recording"})]}),Array.from(new Set(x.map(v=>v.label))).slice(0,5).map(v=>f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"inline-block h-2.5 w-2.5 rounded-full",style:{backgroundColor:Jl(v)}}),o("span",{className:"text-[10px] text-foreground-subtle capitalize",children:v})]},v))]}),g?o(k7,{startMs:c,endMs:d,segments:y,events:x,playheadMs:i,onSeek:l}):o("div",{className:"h-8 rounded bg-surface-hover flex items-center justify-center text-xs text-foreground-subtle",children:"Select a camera to view timeline"})]})]})}function P7({selectedNodeId:e,onSelect:t,refreshToken:n}){const{data:r}=zn(void 0,{staleTime:3e4}),{data:s}=za(void 0,{staleTime:3e4}),a=new Map;for(const d of s??[])a.set(d.agentNodeId,(a.get(d.agentNodeId)??0)+1);const i=r??[],l=i.filter(d=>d.isOnline).length,c=i.filter(d=>!d.isOnline).length;return f("div",{className:"flex flex-col h-full",children:[f("button",{type:"button",onClick:()=>t(No),className:`flex items-center gap-3 px-4 py-3 border-b border-border text-left transition-colors ${e===No?"bg-primary/10 text-primary":"text-foreground hover:bg-surface-hover"}`,children:[o(_n,{className:"h-4 w-4 flex-shrink-0"}),f("div",{className:"min-w-0 flex-1",children:[o("div",{className:"text-xs font-semibold truncate",children:"Cluster"}),o("div",{className:"text-[10px] text-foreground-subtle",children:"Balancer + failover + assignments"})]})]}),o("div",{className:"flex-1 overflow-y-auto",children:i.map(d=>{const u=e===d.id,p=a.get(d.id)??0,h=d.isHub?hn:bt;return f("button",{type:"button",onClick:()=>t(d.id),className:`flex items-center gap-3 w-full px-4 py-3 border-b border-border text-left transition-colors ${u?"bg-primary/10 text-primary":"text-foreground hover:bg-surface-hover"}`,children:[o(h,{className:"h-4 w-4 flex-shrink-0"}),f("div",{className:"min-w-0 flex-1",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-xs font-semibold truncate",children:d.name}),d.isHub&&o("span",{className:"text-[9px] uppercase tracking-wider text-foreground-subtle border border-border rounded px-1 py-0.5",children:"hub"}),!d.isOnline&&o("span",{className:"h-1.5 w-1.5 rounded-full bg-destructive flex-shrink-0"}),d.isOnline&&o("span",{className:"h-1.5 w-1.5 rounded-full bg-success flex-shrink-0"})]}),f("div",{className:"text-[10px] text-foreground-subtle flex items-center gap-2 mt-0.5",children:[f("span",{children:[d.cpuCores," cores"]}),o("span",{children:"•"}),f("span",{children:[Math.round(d.memoryMB/1024)," GB"]}),p>0&&f(me,{children:[o("span",{children:"•"}),f("span",{className:"inline-flex items-center gap-0.5 text-foreground",children:[o(sv,{className:"h-2.5 w-2.5"}),p]})]})]})]})]},d.id)})}),f("div",{className:"px-4 py-2 border-t border-border text-[10px] text-foreground-subtle flex items-center justify-between",children:[f("span",{children:[l," online"]}),c>0&&f("span",{className:"text-destructive",children:[c," offline"]})]})]})}function _7({nodeId:e,refreshToken:t}){const{data:n}=zn(void 0,{staleTime:3e4}),r=n?.find(i=>i.id===e),a=Gr("pipeline.runner-load-snapshot",i=>i.nodeId===e)?.load??null;return r?f("div",{className:"px-6 py-4 border-b border-border",children:[f("div",{className:"flex items-center gap-2 mb-1",children:[o("h2",{className:"text-base font-semibold text-foreground",children:r.name}),r.isOnline?o("span",{className:"text-[10px] px-2 py-0.5 rounded-full bg-success/10 text-success",children:"online"}):o("span",{className:"text-[10px] px-2 py-0.5 rounded-full bg-destructive/10 text-destructive",children:"offline"}),r.isHub&&o("span",{className:"text-[9px] uppercase tracking-wider text-foreground-subtle border border-border rounded px-1 py-0.5",children:"hub"})]}),f("div",{className:"text-[11px] text-foreground-subtle flex items-center gap-2 flex-wrap",children:[o("span",{children:r.cpuModel??"CPU"}),o("span",{children:"•"}),f("span",{children:[r.cpuCores," cores"]}),o("span",{children:"•"}),f("span",{children:[Math.round(r.memoryMB/1024)," GB"]}),a&&f(me,{children:[o("span",{children:"•"}),f("span",{children:[a.attachedCameras," cameras (",a.activeCameras," active)"]}),o("span",{children:"•"}),f("span",{children:[a.avgInferenceTimeMs.toFixed(0),"ms avg inference"]}),o("span",{children:"•"}),f("span",{children:["queue ",a.queueDepthTotal]}),a.hardware.hasGpu&&f(me,{children:[o("span",{children:"•"}),o("span",{className:"text-success",children:"GPU"})]})]})]})]}):o("div",{className:"px-6 py-4 border-b border-border",children:f("div",{className:"text-xs text-foreground-subtle",children:["Node not found: ",e]})})}function Sv({refreshToken:e,nodeId:t}){const[n,r]=_(new Map),{nodes:s}=Kr();gt("pipeline.camera-metrics-snapshot",p=>{const h=p.data;typeof h?.deviceId=="number"&&r(m=>{const g=new Map(m);return g.set(h.deviceId,h),g})});const{data:a}=oy(void 0,{staleTime:5e3}),i=H(()=>{const p=new Map;for(const h of a??[])p.set(h.nodeId,h.deviceCount);return p},[a]),l=H(()=>{const p=new Map,h=Date.now()-3e4;for(const m of n.values()){if(m.timestamp<h)continue;const g=m.nodeId??"hub",b=p.get(g)??{attachedCameras:0,activeCameras:0,totalFps:0,totalInferenceWeighted:0,queueDepth:0};b.attachedCameras++,m.metrics.phase==="active"&&b.activeCameras++,b.totalFps+=m.metrics.actualFps,b.totalInferenceWeighted+=m.metrics.avgInferenceTimeMs,b.queueDepth+=m.metrics.queueDepth,p.set(g,b)}return p},[n]),c=H(()=>{const p=new Map;for(const h of s)p.set(h.id,h.shortName);return p},[s]),d=H(()=>{let p=0,h=0,m=0,g=0,b=0;for(const y of l.values())p+=y.attachedCameras,h+=y.activeCameras,m+=y.totalFps,g+=y.totalInferenceWeighted,b+=y.queueDepth;const x=p>0?g/p:0;return{totalAgents:s.length,onlineAgents:s.filter(y=>y.isOnline).length,attachedCameras:p,activeCameras:h,avgInferenceTimeMs:x,queueDepth:b,totalFps:m}},[l,s]);if(t){const p=l.get(t);return f("div",{className:"@container/liveload",children:[o("h3",{className:"text-sm font-semibold text-foreground mb-2",children:"Live load"}),f("div",{className:"grid grid-cols-2 @md/liveload:grid-cols-3 @3xl/liveload:grid-cols-5 gap-2 mb-3",children:[o(Ut,{label:"FPS",value:p?p.totalFps.toFixed(1):"—"}),o(Ut,{label:"Cameras",value:p?`${p.activeCameras}/${p.attachedCameras}`:"—"}),o(Ut,{label:"Avg infer ms",value:p&&p.attachedCameras>0?(p.totalInferenceWeighted/p.attachedCameras).toFixed(0):"—"}),o(Ut,{label:"Queue",value:p?String(p.queueDepth):"—"}),o(Ut,{label:"Audio",value:String(i.get(t)??"—")})]})]})}const u=[...l.entries()].sort(([p],[h])=>p==="hub"?-1:h==="hub"?1:p.localeCompare(h));return f("div",{className:"@container/liveload",children:[o("h3",{className:"text-sm font-semibold text-foreground mb-2",children:"Live load"}),f("div",{className:"grid grid-cols-2 @md/liveload:grid-cols-3 @3xl/liveload:grid-cols-5 gap-2 sm:gap-3 mb-3",children:[o(Ut,{label:"Total agents",value:`${d.onlineAgents}/${d.totalAgents}`}),o(Ut,{label:"Cameras",value:`${d.activeCameras}/${d.attachedCameras}`}),o(Ut,{label:"Total FPS",value:d.totalFps.toFixed(1)}),o(Ut,{label:"Avg inference ms",value:d.avgInferenceTimeMs.toFixed(0)}),o(Ut,{label:"Queue depth",value:String(d.queueDepth)})]}),o("div",{className:"rounded-lg border border-border overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[480px]",children:[o("thead",{className:"bg-surface",children:f("tr",{className:"text-foreground-subtle text-[10px] uppercase tracking-wider",children:[o("th",{className:"text-left px-3 py-2",children:"Agent"}),o("th",{className:"text-right px-3 py-2",children:"FPS"}),o("th",{className:"text-right px-3 py-2",children:"Cameras"}),o("th",{className:"text-right px-3 py-2",children:"Inference ms"}),o("th",{className:"text-right px-3 py-2",children:"Queue"}),o("th",{className:"text-right px-3 py-2",children:"Audio"})]})}),f("tbody",{children:[u.map(([p,h])=>f("tr",{className:"border-t border-border",children:[o("td",{className:"px-3 py-2 text-foreground font-medium",children:c.get(p)??p}),o("td",{className:"px-3 py-2 text-right text-foreground",children:h.totalFps.toFixed(1)}),o("td",{className:"px-3 py-2 text-right text-foreground",children:h.attachedCameras}),o("td",{className:"px-3 py-2 text-right text-foreground",children:h.attachedCameras>0?(h.totalInferenceWeighted/h.attachedCameras).toFixed(0):"—"}),o("td",{className:"px-3 py-2 text-right text-foreground",children:h.queueDepth}),o("td",{className:"px-3 py-2 text-right text-foreground",children:i.get(p)??"—"})]},p)),u.length===0&&o("tr",{children:o("td",{colSpan:6,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:"No camera metrics received yet"})})]})]})})]})}function Ut({label:e,value:t}){return f("div",{className:"rounded-lg border border-border bg-surface/60 p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle mb-1",children:e}),o("div",{className:"text-lg font-semibold text-foreground",children:t})]})}function Cv(e){return Bn({addonId:e})}function $7(e){return er({deviceId:e},{enabled:Number.isFinite(e)})}const D7=3e4,T7=2e3;function Mv(e){const t=te(0);return t.current===0&&(t.current=Date.now()),Yb({parentDeviceId:e},{enabled:Number.isFinite(e),staleTime:0,refetchOnMount:"always",refetchInterval:n=>{const r=n.state.data;return r&&r.length>0||Date.now()-t.current>=D7?!1:T7}})}const Yi={active:!1,pinned:!1,nodeId:null,reason:""},Zi=["pipeline.camera-assigned","pipeline.camera-unassigned","pipeline.camera-updated","agent.online","agent.offline"],L7={pipeline:bt,decoder:yo,audio:Gl},Nf={pipeline:"Pipeline",decoder:"Decoder",audio:"Audio"};function Ev({mode:e,nodeId:t,compact:n=!1}){if(e==="agent"&&!t)throw new Error('CameraAssignmentsTable: nodeId is required when mode === "agent"');const r=ke(),[s,a]=_(null),[i,l]=_(null),[c,d]=_(new Map);St(["pipelineOrchestrator","getPipelineAssignments"],Zi),St(["pipelineOrchestrator","getDecoderAssignments"],Zi),St(["pipelineOrchestrator","getAudioAssignments"],Zi);const{data:u}=za(void 0,{staleTime:3e4}),{data:p}=ty(void 0,{staleTime:3e4}),{data:h}=sy(void 0,{staleTime:3e4}),{nodes:m}=Kr(),{data:g}=Cv();gt("pipeline.camera-metrics-snapshot",P=>{const B=P.data;typeof B.deviceId=="number"&&d(R=>{const M=new Map(R);return M.set(B.deviceId,B),M})}),Y(()=>{if(c.size===0)return;const P=setInterval(()=>{d(B=>{const R=Date.now()-1e4;let M=!1;const D=new Map(B);for(const[T,L]of B)L.timestamp<R&&(D.delete(T),M=!0);return M?D:B})},5e3);return()=>clearInterval(P)},[c.size]);const b=H(()=>{const P=new Map;for(const B of g??[])P.set(B.id,B.name);return P},[g]),x=H(()=>{const P=new Map,B=M=>{const D=P.get(M);if(D)return D;const T={deviceId:M,deviceName:b.get(M)??`Device ${M}`,pipeline:Yi,decoder:Yi,audio:Yi};return P.set(M,T),T};for(const M of u??[]){const D=B(M.deviceId);P.set(M.deviceId,{...D,pipeline:{active:e==="cluster"?!0:M.agentNodeId===t,pinned:M.pinned,nodeId:M.agentNodeId,reason:M.reason??""}})}for(const M of p??[]){const D=B(M.deviceId);P.set(M.deviceId,{...D,decoder:{active:e==="cluster"?!0:M.decoderNodeId===t,pinned:M.pinned,nodeId:M.decoderNodeId,reason:M.reason??""}})}for(const M of h??[]){const D=B(M.deviceId);P.set(M.deviceId,{...D,audio:{active:e==="cluster"?!0:M.nodeId===t,pinned:M.pinned,nodeId:M.nodeId,reason:"capacity"}})}let R=[...P.values()];return e==="agent"&&(R=R.filter(M=>M.pipeline.active||M.decoder.active||M.audio.active)),R.sort((M,D)=>M.deviceId-D.deviceId),R},[u,p,h,b,e,t]),y=H(()=>(m??[]).filter(P=>P.isOnline).map(P=>({id:P.id,name:P.name})),[m]),w=()=>{r.invalidateQueries({queryKey:[["pipelineOrchestrator","getPipelineAssignments"]]}),r.invalidateQueries({queryKey:[["pipelineOrchestrator","getDecoderAssignments"]]}),r.invalidateQueries({queryKey:[["pipelineOrchestrator","getAudioAssignments"]]})},v=Gx({onSuccess:w}),N=Kx({onSuccess:w}),k=Jx({onSuccess:w}),C=ey({onSuccess:w}),E=ny({onSuccess:w}),I=ry({onSuccess:w}),A=(P,B,R)=>{B==="pipeline"?v.mutate({deviceId:P,agentNodeId:R}):B==="decoder"?k.mutate({deviceId:P,nodeId:R}):E.mutate({deviceId:P,nodeId:R}),a(null)},z=(P,B)=>{B==="pipeline"?N.mutate({deviceId:P}):B==="decoder"?C.mutate({deviceId:P}):I.mutate({deviceId:P}),a(null)};return o("div",{className:"rounded-lg border border-border overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{className:"bg-surface",children:f("tr",{className:"text-foreground-subtle text-[10px] uppercase tracking-wider",children:[!n&&o("th",{className:"w-6"}),o("th",{className:"text-left px-3 py-2 align-middle",children:"Camera"}),o("th",{className:"text-left px-3 py-2 align-middle",children:"Pipeline"}),o("th",{className:"text-left px-3 py-2 align-middle",children:"Decoder"}),o("th",{className:"text-left px-3 py-2 align-middle",children:"Audio"}),o("th",{className:"text-left px-3 py-2 align-middle",children:"Status"})]})}),f("tbody",{children:[x.map(P=>{const B=c.get(P.deviceId),R=i===P.deviceId;return f(Ge.Fragment,{children:[f("tr",{className:"border-t border-border align-middle relative",children:[!n&&o("td",{className:"px-2 py-2 align-middle",children:o("button",{type:"button",onClick:()=>l(R?null:P.deviceId),className:"p-1 rounded hover:bg-surface-hover text-foreground-subtle","aria-label":R?"Collapse broker details":"Expand broker details",children:R?o(lt,{className:"h-3.5 w-3.5"}):o(wt,{className:"h-3.5 w-3.5"})})}),f("td",{className:"px-3 py-2 align-middle",children:[o("div",{className:"text-foreground font-medium leading-tight",children:P.deviceName}),f("div",{className:"text-[10px] text-foreground-subtle leading-tight",children:["#",P.deviceId]})]}),o(Xi,{role:"pipeline",state:P.pipeline,mode:e,deviceId:P.deviceId,onlineNodes:y,isMenuOpen:s?.deviceId===P.deviceId&&s.role==="pipeline",onToggleMenu:()=>a(s?.deviceId===P.deviceId&&s.role==="pipeline"?null:{deviceId:P.deviceId,role:"pipeline"}),onCloseMenu:()=>a(null),onMove:M=>A(P.deviceId,"pipeline",M),onUnpin:()=>z(P.deviceId,"pipeline")}),o(Xi,{role:"decoder",state:P.decoder,mode:e,deviceId:P.deviceId,onlineNodes:y,isMenuOpen:s?.deviceId===P.deviceId&&s.role==="decoder",onToggleMenu:()=>a(s?.deviceId===P.deviceId&&s.role==="decoder"?null:{deviceId:P.deviceId,role:"decoder"}),onCloseMenu:()=>a(null),onMove:M=>A(P.deviceId,"decoder",M),onUnpin:()=>z(P.deviceId,"decoder")}),o(Xi,{role:"audio",state:P.audio,mode:e,deviceId:P.deviceId,onlineNodes:y,isMenuOpen:s?.deviceId===P.deviceId&&s.role==="audio",onToggleMenu:()=>a(s?.deviceId===P.deviceId&&s.role==="audio"?null:{deviceId:P.deviceId,role:"audio"}),onCloseMenu:()=>a(null),onMove:M=>A(P.deviceId,"audio",M),onUnpin:()=>z(P.deviceId,"audio")}),o("td",{className:"px-3 py-2 align-middle",children:o(B7,{snap:B})})]}),R&&!n&&f("tr",{className:"bg-surface/50",children:[o("td",{}),o("td",{colSpan:5,className:"px-3 py-2",children:o(ft,{widgetId:"stream-broker/stream-broker-panel",host:"device-tab",deviceId:P.deviceId,instanceId:`pipeline-row/${P.deviceId}`,config:{variant:"compact",title:"Stream brokers & clients"}})})]})]},P.deviceId)}),x.length===0&&o("tr",{children:o("td",{colSpan:n?5:6,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:e==="agent"?"No cameras assigned to this node":"No cameras currently assigned"})})]})]})})}function Xi({role:e,state:t,mode:n,onlineNodes:r,isMenuOpen:s,onToggleMenu:a,onCloseMenu:i,onMove:l,onUnpin:c}){const d=L7[e],u=r.filter(m=>m.id!==(t.nodeId??"")),h=(t.active||n==="cluster")&&(u.length>0||t.pinned);return f("td",{className:"px-3 py-2 align-middle relative",children:[f("div",{className:"flex items-center gap-2",children:[n==="agent"?o(R7,{state:t,Icon:d}):o(O7,{state:t,Icon:d}),o("div",{className:"ml-auto",children:h&&o("button",{type:"button",onClick:a,className:"p-1 rounded hover:bg-surface-hover","aria-label":`${Nf[e]} actions`,children:o(r6,{className:"h-3 w-3 text-foreground-subtle"})})})]}),s&&h&&o(z7,{title:Nf[e],targets:u,pinned:t.pinned,onMove:l,onUnpin:c,onClose:i})]})}function R7({state:e,Icon:t}){const n=e.active?rv:ts;return f("div",{className:"flex items-center gap-1.5",children:[o(n,{className:`h-3.5 w-3.5 ${e.active?"text-success":"text-foreground-subtle/50"}`}),o(t,{className:`h-3 w-3 ${e.active?"text-foreground-subtle":"text-foreground-subtle/40"}`}),e.pinned&&o(J0,{className:"h-2.5 w-2.5 text-amber-400"})]})}function O7({state:e,Icon:t}){return!e.active||!e.nodeId?f("div",{className:"flex items-center gap-1.5 text-foreground-subtle/60",children:[o(t,{className:"h-3 w-3"}),o("span",{className:"text-[10px] italic",children:"—"})]}):f("div",{className:"flex items-center gap-1.5 min-w-0",children:[o(t,{className:"h-3 w-3 text-foreground-subtle shrink-0"}),f("div",{className:"flex flex-col leading-tight min-w-0",children:[o("span",{className:"font-mono text-[11px] text-foreground truncate",children:e.nodeId}),o("span",{className:"flex items-center gap-1 text-[10px]",children:e.pinned?f("span",{className:"inline-flex items-center gap-0.5 text-amber-400",children:[o(J0,{className:"h-2.5 w-2.5"})," manual"]}):f("span",{className:"text-foreground-subtle truncate",children:["auto · ",e.reason||"capacity"]})})]})]})}function B7({snap:e}){if(!e)return o("span",{className:"text-[10px] text-foreground-subtle italic",children:"—"});const{phase:t,actualFps:n,avgInferenceTimeMs:r,queueDepth:s,configuredFps:a}=e.metrics,i=ur(t);return f("div",{className:"flex flex-col gap-0.5 font-mono text-[10px] tabular-nums leading-tight",children:[f("span",{className:`inline-flex items-center gap-1 ${i.textColor}`,children:[o(Ed,{phase:t,className:"h-2.5 w-2.5"}),o("span",{className:"font-semibold uppercase tracking-wider",children:i.label})]}),f("span",{className:"text-foreground-subtle",children:[o("span",{className:"text-foreground",children:n.toFixed(1)}),f("span",{children:["/",a.toFixed(0)," fps"]})]}),f("span",{className:"text-foreground-subtle",children:[o("span",{className:"text-foreground",children:r.toFixed(0)}),o("span",{children:" ms"}),s>0&&f("span",{className:"text-warning ml-1",children:["q",s]})]})]})}function z7({title:e,targets:t,pinned:n,onMove:r,onUnpin:s,onClose:a}){const i=te(null);return Y(()=>{const l=c=>{i.current?.contains(c.target)||a()};return window.addEventListener("mousedown",l),()=>window.removeEventListener("mousedown",l)},[a]),f("div",{ref:i,className:"absolute right-2 top-full mt-1 w-48 rounded-lg border border-border bg-surface shadow-lg z-20 text-left",children:[o("div",{className:"px-3 py-1 text-[9px] uppercase tracking-wider text-foreground-subtle border-b border-border",children:e}),t.length>0&&o("div",{className:"py-1",children:t.map(l=>f("button",{type:"button",onClick:()=>r(l.id),className:"block w-full text-left px-3 py-1 text-[11px] text-foreground hover:bg-surface-hover",children:["Move to ",l.name]},l.id))}),n&&f("button",{type:"button",onClick:s,className:"block w-full text-left px-3 py-1.5 text-[11px] text-destructive hover:bg-destructive/10 border-t border-border",children:["Unpin ",e.toLowerCase()]}),t.length===0&&!n&&o("div",{className:"px-3 py-1.5 text-[10px] text-foreground-subtle italic",children:"Already auto · no other nodes online"})]})}function F7({nodeId:e,refreshToken:t}){return f("div",{className:"space-y-6",children:[o(Sv,{refreshToken:t,nodeId:e}),f("div",{children:[o("h3",{className:"text-sm font-semibold text-foreground mb-1",children:"Cameras on this node"}),f("p",{className:"text-[11px] text-foreground-subtle",children:["Checkboxes mark the roles currently running on ",e,". Use the kebab to move a role to another node or unpin it; live KPIs come from the runner snapshot stream."]})]}),o(Ev,{mode:"agent",nodeId:e,compact:!0})]})}function j7(e,t){const n=Math.max(0,t-e),r=Math.floor(e/1e3),s=Math.floor(n/1e3);return`${r}s idle · ${s}s left`}function V7({nodeId:e,refreshToken:t}){const n=ke(),r=Qx({onSettled:()=>{n.invalidateQueries({queryKey:["pipelineExecutor","listLoadedEngines"]})}}),{data:s}=Ux({nodeId:e},{staleTime:5e3}),i=Gr("pipeline.engine-metrics-snapshot",h=>h.nodeId===e)?.engines??s??null,l=i===null;St(["pipelineRunner","getLocalCameras"],["pipeline.camera-assigned","pipeline.camera-unassigned"]);const{data:c}=hy({nodeId:e},{staleTime:3e4}),{values:d}=Kc("pipeline.camera-metrics-snapshot",h=>h.deviceId,h=>h.nodeId===e),u=H(()=>d.filter(h=>h.metrics.phase==="active").length,[d]),p=h=>{const m=c??[];m.length>0&&!window.confirm(`${m.length} camera(s) are dispatching through this engine. Killing it forces a respawn on the next frame. Continue?`)||r.mutate({nodeId:e,engine:h,force:m.length>0})};return f("div",{className:"space-y-6",children:[f("div",{children:[o("h3",{className:"text-sm font-semibold text-foreground mb-1",children:"Inference engines on this node"}),f("p",{className:"text-[11px] text-foreground-subtle",children:[(i??[]).length," engine(s) resident in RAM. ",(c??[]).length," camera(s) attached, ",u," actively dispatching frames. Refreshes every 5s."]})]}),o("div",{className:"rounded-lg border border-border overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{className:"bg-surface",children:f("tr",{className:"text-foreground-subtle text-[10px] uppercase tracking-wider",children:[o("th",{className:"text-left px-3 py-2 whitespace-nowrap",children:"Kind"}),o("th",{className:"text-left px-3 py-2 whitespace-nowrap",children:"Runtime / Backend / Device"}),o("th",{className:"text-left px-3 py-2",children:"Models"}),o("th",{className:"text-right px-3 py-2 whitespace-nowrap",children:"Pool PID"}),o("th",{className:"text-right px-3 py-2 whitespace-nowrap",children:"Auto-kill"}),o("th",{className:"text-right px-3 py-2 whitespace-nowrap",children:"In use"}),o("th",{className:"w-20"})]})}),f("tbody",{children:[l&&o("tr",{children:o("td",{colSpan:7,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:"Loading…"})}),!l&&(i??[]).map(h=>{const m=h.kind==="warm-override";return f("tr",{className:`border-t border-border ${m?"bg-amber-500/5":""}`,children:[o("td",{className:"px-3 py-2",children:f("span",{className:`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-[10px] font-medium ${m?"bg-amber-500/15 text-amber-400":"bg-success/15 text-success"}`,children:[m?o(c6,{className:"h-3 w-3"}):o(bt,{className:"h-3 w-3"}),m?"warm":"runtime"]})}),o("td",{className:"px-3 py-2",children:f("span",{className:"inline-flex items-center gap-1 text-[11px] text-sky-400",children:[o(Jd,{className:"h-3 w-3"}),h.engine.runtime,"/",h.engine.backend,h.engine.device?`/${h.engine.device}`:"",h.engine.format?` · ${h.engine.format}`:""]})}),o("td",{className:"px-3 py-2",children:h.modelsLoaded.length===0?o("span",{className:"text-foreground-subtle text-[11px]",children:"—"}):o("div",{className:"flex flex-wrap gap-1",children:h.modelsLoaded.map(g=>o("span",{className:"inline-block rounded bg-surface px-1.5 py-0.5 text-[10px] font-mono text-foreground-subtle",children:g},g))})}),o("td",{className:"px-3 py-2 text-right font-mono text-foreground",children:h.poolPid??"—"}),o("td",{className:"px-3 py-2 text-right text-[11px]",children:h.idleMs!==null&&h.idleTtlMs!==null?o("span",{className:"text-foreground-subtle",children:j7(h.idleMs,h.idleTtlMs)}):o("span",{className:"text-foreground-subtle/50",children:"never"})}),o("td",{className:"px-3 py-2 text-right text-foreground",children:m?"—":(c??[]).length}),o("td",{className:"px-3 py-2 text-right",children:f("button",{type:"button",disabled:r.isPending,onClick:()=>p(h.engine),className:"inline-flex items-center gap-1 px-2 py-1 rounded border border-destructive/30 text-destructive text-[11px] hover:bg-destructive/10 disabled:opacity-50",children:[o(Ze,{className:"h-3 w-3"}),"Kill"]})})]},h.engineKey)}),!l&&(i??[]).length===0&&o("tr",{children:o("td",{colSpan:7,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:"No engines resident — the factory spins up on the first pipeline run."})})]})]})}),f("div",{className:"text-[10px] text-foreground-subtle leading-relaxed",children:[o("strong",{className:"text-foreground",children:"runtime"}),": main camera-serving engine; never auto-killed while cameras attached. ",o("strong",{className:"text-foreground",children:"warm"}),": benchmark/test override held in cache for fast re-use; auto-disposed after the idle TTL."]}),r.isError&&f("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-[11px] text-destructive",children:["Kill failed: ",r.error instanceof Error?r.error.message:"unknown"]})]})}function It(e){if(!Number.isFinite(e)||e<0)return"—";if(e<1024)return`${Math.round(e)} B`;const t=["KB","MB","GB","TB","PB"];let n=e/1024,r="KB";for(const a of t){if(r=a,n<1024)break;n/=1024}return`${n>=100?Math.round(n).toString():n.toFixed(1)} ${r}`}function Iv(e){return It(e*1024*1024)}const H7=new Set(y2);function kf(e){return H7.has(e)}function Ji(e,t,n){return`${e}/${t}/${n}`}function ec(e){return{coreml:"CoreML",openvino:"OpenVINO",onnx:"ONNX"}[e.format]??e.format.toUpperCase()}function Sf(e){return{coreml:"Apple Neural Engine / GPU — .mlpackage",openvino:"Intel CPU / GPU / NPU — .xml",onnx:"CPU, CUDA, Node.js — .onnx"}[e.format]??`.${e.format}`}function qn(e){return e.format}function q7(e,t){let n=0,r=0,s=0;for(const a of e)for(const i of a.addons)for(const l of i.models){const c=l.formats[t];c&&(n++,c.downloaded&&(r++,s+=c.sizeMB))}return{total:n,downloaded:r,downloadedSizeMB:s}}function U7({addonId:e,model:t,format:n,isActive:r,progress:s,errorMsg:a,onDownload:i,onDelete:l}){const c=t.formats[n];return c?f("div",{className:"flex items-center gap-3 px-4 py-3 border-b border-border/50 last:border-b-0 hover:bg-surface-hover/30 transition-colors",children:[o("div",{className:`h-2 w-2 rounded-full shrink-0 ${c.downloaded?"bg-success":"bg-foreground-subtle/30"}`}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-medium text-foreground",children:t.name}),f("span",{className:"text-[10px] text-foreground-subtle font-mono",children:["(",t.id,")"]})]}),s&&s.progress>=0&&s.progress<100&&f("div",{className:"mt-1.5 flex items-center gap-2 max-w-xs",children:[o("div",{className:"flex-1 h-1 bg-surface-hover rounded-full overflow-hidden",children:o("div",{className:"bg-primary h-full rounded-full transition-all duration-300",style:{width:`${s.progress}%`}})}),f("span",{className:"text-[9px] text-primary font-mono tabular-nums shrink-0",children:[Math.round(s.progress),"%"]})]})]}),o("span",{className:"text-xs text-foreground-subtle tabular-nums shrink-0",children:Iv(c.sizeMB)}),a&&f("span",{className:"flex items-center gap-1 text-[10px] text-danger max-w-[160px] truncate shrink-0",title:a,children:[o(nr,{className:"h-3 w-3 shrink-0"}),a]}),c.downloaded?f("button",{onClick:l,disabled:r,className:"inline-flex items-center gap-1.5 px-3 py-1.5 text-[11px] font-medium rounded-md border border-danger/30 text-danger hover:bg-danger/10 disabled:opacity-50 transition-colors shrink-0",children:[r?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),r?"Deleting...":"Delete"]}):f("button",{onClick:i,disabled:r,className:"inline-flex items-center gap-1.5 px-3 py-1.5 text-[11px] font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors shrink-0",children:[r?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xt,{className:"h-3 w-3"}),r?"Downloading...":"Download"]})]}):null}function Q7({engines:e,activeEngine:t,viewEngine:n,onSelect:r}){const[s,a]=_(!1);return f("div",{className:"relative",children:[f("button",{type:"button",onClick:()=>a(!s),className:"flex items-center gap-2 rounded-lg border border-border bg-surface px-4 py-2.5 w-full text-left hover:bg-surface-hover transition-colors",children:[o(bt,{className:"h-4 w-4 text-primary shrink-0"}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-medium text-foreground",children:ec(n)}),qn(n)===qn(t)&&o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-success/10 text-success font-medium",children:"Active"})]}),o("div",{className:"text-[10px] text-foreground-subtle",children:Sf(n)})]}),o(lt,{className:`h-4 w-4 text-foreground-subtle transition-transform ${s?"rotate-180":""}`})]}),s&&o("div",{className:"absolute top-full left-0 right-0 mt-1 rounded-lg border border-border bg-surface shadow-lg z-50 overflow-hidden",children:e.map(i=>{const l=qn(i)===qn(n),c=qn(i)===qn(t);return f("button",{type:"button",onClick:()=>{r(i),a(!1)},className:`flex items-center gap-3 px-4 py-2.5 w-full text-left transition-colors ${l?"bg-primary/5":"hover:bg-surface-hover"}`,children:[o(bt,{className:`h-4 w-4 shrink-0 ${l?"text-primary":"text-foreground-subtle"}`}),f("div",{className:"flex-1",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:`text-sm font-medium ${l?"text-primary":"text-foreground"}`,children:ec(i)}),c&&o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-success/10 text-success font-medium",children:"Active"})]}),o("div",{className:"text-[10px] text-foreground-subtle",children:Sf(i)})]}),l&&o(Kd,{className:"h-4 w-4 text-primary shrink-0"})]},qn(i))})})]})}function G7({embedded:e=!1,nodeId:t}={}){const n=ke(),r=t??"hub",[s,a]=_(null),[i,l]=_(new Set),[c,d]=_(new Map),[u,p]=_(new Map),[h,m]=_(""),{data:g=[]}=Fx({nodeId:r},{staleTime:6e4}),x=g.filter((O,F,j)=>j.findIndex(V=>V.format===O.format)===F),{data:y}=jx({nodeId:r},{staleTime:3e4}),w=y,{data:v,isLoading:N}=Wo({nodeId:r},{staleTime:1e4}),k=Hx(),C=qx();gt("model.download.progress",O=>{const F=O.data,j=typeof F.modelId=="string"?F.modelId:void 0,V=typeof F.progress=="number"?F.progress:void 0,$=typeof F.totalMB=="number"?F.totalMB:0;j===void 0||V===void 0||(d(q=>{const G=new Map(q);return V===100||V===-1?G.delete(j):G.set(j,{modelId:j,progress:V,totalMB:$}),G}),V===100&&n.invalidateQueries({queryKey:[["pipelineExecutor","getSchema"]]}))});const E=w??{runtime:"node",backend:"cpu",format:"onnx"},I=x.find(O=>O.format===s)??E,A=I.format,z=v?.slots??[],P=z.map(O=>({...O,addons:O.addons.map(F=>({...F,models:F.models.filter(j=>j.formats[A]!==void 0)})).filter(F=>F.models.length>0)})).filter(O=>O.addons.length>0),B=q7(P,A),R=U(async(O,F,j)=>{if(!kf(j))return;const V=Ji(O,F,j);l($=>new Set([...$,V])),p($=>{const q=new Map($);return q.delete(V),q});try{await k.mutateAsync({addonId:O,modelId:F,format:j,nodeId:r}),n.invalidateQueries({queryKey:[["pipelineExecutor","getSchema"]]})}catch($){p(q=>new Map([...q,[V,$ instanceof Error?$.message:"Download failed"]]))}finally{l($=>{const q=new Set($);return q.delete(V),q})}},[k,n,r]),M=U(async(O,F,j)=>{if(!kf(j))return;const V=Ji(O,F,j);l($=>new Set([...$,V])),p($=>{const q=new Map($);return q.delete(V),q});try{await C.mutateAsync({addonId:O,modelId:F,format:j,nodeId:r}),n.invalidateQueries({queryKey:[["pipelineExecutor","getSchema"]]})}catch($){p(q=>new Map([...q,[V,$ instanceof Error?$.message:"Delete failed"]]))}finally{l($=>{const q=new Set($);return q.delete(V),q})}},[C,n,r]),D=U(O=>{a(O.format)},[]),T=h.trim()?P.map(O=>({...O,addons:O.addons.map(F=>({...F,models:F.models.filter(j=>j.name.toLowerCase().includes(h.toLowerCase())||j.id.toLowerCase().includes(h.toLowerCase())||F.name.toLowerCase().includes(h.toLowerCase()))})).filter(F=>F.models.length>0)})).filter(O=>O.addons.length>0):P,L=f(me,{children:[N&&o("div",{className:"flex items-center justify-center py-16",children:o(Se,{className:"h-5 w-5 animate-spin text-foreground-subtle"})}),!N&&z.length===0&&f("div",{className:"flex flex-col items-center justify-center py-16 text-foreground-subtle",children:[o(ia,{className:"h-8 w-8 mb-3 opacity-30"}),o("span",{className:"text-sm",children:"No pipeline steps available"}),o("span",{className:"text-xs mt-1",children:"Configure the detection pipeline to see available models."})]}),!N&&z.length>0&&f(me,{children:[o(Q7,{engines:x,activeEngine:E,viewEngine:I,onSelect:D}),f("div",{className:"flex items-center gap-4 text-xs text-foreground-subtle",children:[f("span",{children:[o("span",{className:"font-semibold text-foreground tabular-nums",children:B.total}),o("span",{className:"ml-1",children:"compatible models"})]}),o("span",{className:"text-border",children:"|"}),f("span",{children:[o("span",{className:"font-semibold text-success tabular-nums",children:B.downloaded}),o("span",{className:"ml-1",children:"downloaded"})]}),o("span",{className:"text-border",children:"|"}),f("span",{className:"tabular-nums",children:[Iv(B.downloadedSizeMB),o("span",{className:"ml-1",children:"on disk"})]})]}),B.total>5&&f("div",{className:"relative",children:[o(nv,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-foreground-subtle"}),o("input",{type:"text",value:h,onChange:O=>m(O.target.value),placeholder:"Search models...",className:"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-border bg-surface text-foreground placeholder:text-foreground-subtle/50 focus:outline-none focus:ring-1 focus:ring-primary"})]}),T.map(O=>{const F=O.addons.reduce((V,$)=>V+$.models.length,0),j=O.addons.reduce((V,$)=>V+$.models.filter(q=>q.formats[A]?.downloaded).length,0);return f("div",{children:[f("div",{className:"flex items-center gap-2 mb-2",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:O.label}),o("div",{className:"flex-1 h-px bg-border"}),f("span",{className:"text-[10px] text-foreground-subtle tabular-nums",children:[j,"/",F]})]}),o("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:O.addons.map(V=>V.models.map($=>{const q=Ji(V.id,$.id,A);return o(U7,{addonId:V.id,model:$,format:A,isActive:i.has(q),progress:c.get($.id),errorMsg:u.get(q),onDownload:()=>R(V.id,$.id,A),onDelete:()=>M(V.id,$.id,A)},`${V.id}/${$.id}`)}))})]},O.id)}),T.length===0&&o("div",{className:"text-center py-8 text-sm text-foreground-subtle",children:h.trim()?f(me,{children:["No models matching “",h,"”"]}):f(me,{children:["No models available for ",ec(I)," format"]})})]})]});return e?o("div",{className:"space-y-4",children:L}):o(tt,{children:L})}function K7({nodeId:e,refreshToken:t}){return o(G7,{embedded:!0,nodeId:e})}function Av({nodeId:e,title:t}){const{data:n}=Cv(),{data:r}=za(void 0,{staleTime:3e4}),s=H(()=>{const d=new Map;for(const u of n??[])d.set(u.id,u.name);return d},[n]),a=H(()=>{if(!e)return null;const d=new Set;for(const u of r??[])u.agentNodeId===e&&d.add(u.deviceId);return d},[e,r]),[i,l]=_(new Map);gt("pipeline.camera-metrics-snapshot",d=>{const u=d.data;typeof u.deviceId=="number"&&(e&&u.nodeId!==e||l(p=>{const h=new Map(p);return h.set(u.deviceId,u),h}))}),Y(()=>{if(i.size===0)return;const d=setInterval(()=>{l(u=>{const p=Date.now()-1e4;let h=!1;const m=new Map(u);for(const[g,b]of u)b.timestamp<p&&(m.delete(g),h=!0);return h?m:u})},5e3);return()=>clearInterval(d)},[i.size]);const c=H(()=>{const d=[];for(const u of i.values())a&&!a.has(u.deviceId)||d.push(u);return d.sort((u,p)=>u.deviceId-p.deviceId),d},[i,a]);return c.length===0?f("div",{className:"rounded-md border border-border bg-surface px-3 py-2 text-[11px] text-foreground-subtle italic",children:[t??"Cameras",": no live snapshots yet"]}):f("div",{className:"rounded-md border border-border bg-surface px-3 py-2",children:[f("div",{className:"flex items-center gap-2 mb-1.5",children:[o("span",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:t??"Cameras"}),o("span",{className:"text-[10px] text-foreground-subtle",children:c.length})]}),o("div",{className:"flex flex-wrap gap-1.5",children:c.map(d=>{const u=s.get(d.deviceId)??`#${d.deviceId}`,p=ur(d.metrics.phase);return f("div",{title:`${u} · ${p.label} · ${d.metrics.actualFps.toFixed(1)} fps · ${d.metrics.avgInferenceTimeMs.toFixed(0)}ms infer · q=${d.metrics.queueDepth}`,className:`inline-flex items-center gap-1 rounded border px-1.5 py-0.5 text-[10px] ${p.badgeClass}`,children:[o(Ed,{phase:d.metrics.phase,className:"h-2.5 w-2.5"}),o("span",{className:"font-medium text-foreground/90 max-w-[120px] truncate",children:u}),o("span",{className:"font-mono tabular-nums",children:d.metrics.actualFps.toFixed(1)}),o("span",{className:"opacity-60",children:"fps"})]},d.deviceId)})})]})}function el(e,t){if(!e)return null;for(const n of e.slots)for(const r of n.addons)if(r.id===t)return r;return null}function W7({nodeId:e,refreshToken:t}){const n=ke(),[r,s]=_(null),[a,i]=_(null),l=Wo({nodeId:e},{refetchOnMount:"always"}),c=hd({agentNodeId:e},{refetchOnMount:"always"}),d=md({onSuccess:()=>{n.invalidateQueries({queryKey:[["addonSettings"]]}),n.invalidateQueries({queryKey:[["pipelineOrchestrator"]]}),n.invalidateQueries({queryKey:[["pipelineExecutor"]]})}}),u=l.data??null,p=c.data,h=u?.selectedEngine.format??"coreml",m=H(()=>u?Ta(u):[],[u]),g=H(()=>[{agentNodeId:e,engineLabel:h}],[e,h]),b=(C,E)=>{const I=p?.addonDefaults[C];return el(u,C)?.models.some(P=>!!P.formats[h])?I?I.enabled?{kind:"enabled",modelId:I.modelId}:{kind:"disabled"}:{kind:"na"}:{kind:"na"}},x=r&&u?el(u,r.addonId):null,y=C=>{const E=p?.addonDefaults[C]??null;s({addonId:C,agentNodeId:e}),i(E)},w=(C,E)=>{if(!p)return;const I=p.addonDefaults[C],A=el(u,C);if(!I&&!A)return;const z={enabled:E,modelId:I?.modelId??A?.defaultModelId??"",settings:I?.settings??{}};d.mutate({agentNodeId:e,defaults:{...p.addonDefaults,[C]:z}})},v=()=>{s(null),i(null)},N=()=>{!a||!r||!p||d.mutate({agentNodeId:e,defaults:{...p.addonDefaults,[r.addonId]:a}},{onSuccess:v})};if(l.isLoading||c.isLoading)return o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading pipeline…"});if(l.error)return f("div",{className:"text-xs text-red-400",children:["Failed to load catalog: ",String(l.error)]});if(!u)return o("div",{className:"text-xs text-foreground-subtle",children:"Catalog unavailable for this node (runner offline?)."});const k=r!==null&&x!==null&&a!==null;return f("div",{className:"relative h-full w-full space-y-3",children:[o(Av,{nodeId:e}),o("div",{className:k?"pr-[360px]":"",children:m.length>0?o(Uc,{tree:m,agents:g,getCellState:b,onCellClick:y,selectedCell:r,onToggleEnabled:w}):o("div",{className:"text-xs text-foreground-subtle",children:"Catalog empty."})}),o(qc,{open:k,onClose:v,title:x?.name??"",subtitle:r?`${r.agentNodeId} · ${h}`:"",footer:f(me,{children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:v,children:"Cancel"}),o("button",{type:"button",disabled:!a||!r||d.isPending,className:"px-3 py-1 text-xs bg-primary text-primary-foreground rounded disabled:opacity-50",onClick:N,children:d.isPending?"Saving…":"Save"})]}),children:x&&a&&r&&o(Ra,{mode:"agent",addon:x,agentDefault:a,agentNodeId:r.agentNodeId,engineFormat:h,onChangeAgentConfig:C=>i(C)})})]})}function Pv({pendingCount:e,onSave:t,onDiscard:n,saving:r=!1,saveLabel:s="Save",discardLabel:a="Discard"}){return e<=0?null:f("div",{className:"sticky bottom-0 -mb-3 flex items-center justify-between gap-3 rounded-lg border border-primary/40 bg-primary/5 px-3 py-2 shadow-sm z-10",children:[f("span",{className:"text-xs text-foreground",children:[e," unsaved change",e===1?"":"s"]}),f("div",{className:"flex items-center gap-2",children:[o("button",{type:"button",onClick:n,disabled:r,className:"inline-flex items-center rounded-md border border-border px-2.5 py-1 text-xs text-foreground-subtle hover:bg-surface-hover disabled:opacity-50",children:a}),o("button",{type:"button",onClick:t,disabled:r,className:"inline-flex items-center rounded-md bg-primary px-3 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:r?"Saving…":s})]})]})}function _v({tabs:e,activeId:t,onChange:n,countByTab:r,pendingByTab:s}){return e.length===0?null:o("div",{className:"flex flex-wrap items-center gap-1 border-b border-border shrink-0",children:e.map(a=>{const i=a.id===t,l=r?.get(a.id)??0,c=s?.get(a.id)??0;return f("button",{type:"button",onClick:()=>n(a.id),className:`relative px-3 py-1.5 text-xs font-medium rounded-t-md transition-colors -mb-px border-b-2 whitespace-nowrap ${i?"text-primary border-primary bg-primary/5":"text-foreground-subtle border-transparent hover:text-foreground hover:bg-surface-hover"}`,children:[a.label,l>0&&f("span",{className:"ml-1.5 text-[10px] opacity-60",children:["(",l,")"]}),c>0&&o("span",{className:"ml-1.5 inline-flex h-1.5 w-1.5 rounded-full bg-primary"})]},a.id)})})}function Y7(e,t){for(const n of e)for(const r of n.fields){if(!("key"in r)||r.key!==t)continue;if(r.type==="button"||r.type==="separator"||r.type==="info")return!0;const s=r.immediate;return s===!0?!0:s===!1?!1:n.immediate===!0}return!1}function $v({schema:e,serverValues:t,onImmediateSave:n,onDeferredSave:r}){const[s,a]=_({}),[i,l]=_(!1),c=te(null),d=e?.sections??[],u=Object.keys(s).length>0,p=H(()=>({...t,...s}),[t,s]);Y(()=>{if(u){l(!0);return}c.current&&clearTimeout(c.current),c.current=setTimeout(()=>l(!1),500)},[u]);const h=U(()=>{l(!0),c.current&&clearTimeout(c.current),c.current=setTimeout(()=>l(!1),2e3)},[]),m=U(y=>{h();const w={},v={},N={...t,...s};for(const[k,C]of Object.entries(y))N[k]!==C&&(Y7(d,k)?w[k]=C:v[k]=C);Object.keys(w).length>0&&n(w),a(k=>{const C={...k};for(const E of Object.keys(w))delete C[E];for(const[E,I]of Object.entries(v))C[E]=I;return C})},[h,t,s,d,n]),g=U(y=>{const w={},v={};for(const[N,k]of Object.entries(s))y.includes(N)?w[N]=k:v[N]=k;a(v),Object.keys(w).length>0&&r(w)},[s,r]),b=U(y=>{a(w=>{const v={...w};for(const N of y)delete v[N];return v})},[]),x=U(()=>{a({})},[]);return{values:p,pendingKeys:Object.keys(s),hasPendingEdits:u,editingPaused:i,handleChange:m,handleSave:g,handleDiscard:b,resetAll:x}}const Z7=Ue(function({addonId:t,schema:n,serverValues:r,onImmediateSave:s,onStateChange:a,onAction:i,disabled:l},c){const d=$v({schema:n,serverValues:r,onImmediateSave:U(b=>s(t,b),[t,s]),onDeferredSave:U(()=>{},[])});c2(c,()=>({flush:()=>{const b={};for(const x of d.pendingKeys)b[x]=d.values[x];return d.handleDiscard(d.pendingKeys),b},discard:()=>d.resetAll()}),[d]);const u=d.pendingKeys,p=u.join("|"),h=H(()=>u.map(b=>`${b}=${JSON.stringify(d.values[b])}`).join(","),[u,d.values]),m=te(a);Y(()=>{m.current=a},[a]),Y(()=>{const b={};for(const x of u)b[x]=d.values[x];m.current({addonId:t,pendingKeys:u,pendingValues:b})},[t,p,h]);const g=H(()=>{if(i)return(b,x,y)=>i(t,b,x,y)},[t,i]);return o(Dn,{schema:n,values:d.values,onChange:d.handleChange,disabled:l,onAction:g})});function Dv(e,t){if(e.type==="separator"||e.type==="info"||e.type==="button")return e;if(e.type==="group"){const a=e.fields.map(i=>Dv(i,t));return{...e,fields:a}}const n=e;t[e.key]=n.value;const{value:r,...s}=n;return s}function X7(e,t){return{...e,fields:e.fields.map(n=>Dv(n,t))}}function J7(e){const t={};return{schema:{...e.tabs?{tabs:e.tabs}:{},sections:e.sections.map(r=>X7(r,t))},values:t}}function to({nodeId:e,addonIds:t,level:n,deviceId:r,sectionIds:s,sectionTab:a,extraTabs:i,title:l,description:c}){const d=ke(),u=Te().trpcClient,p=Cb(),h=Mb(),m=Vx(),g=Vb(),b=Db(),x=!!(i&&i.length>0),[y,w]=_(null);if(n==="device"&&!r)throw new Error('NodeAddonsSettingsPanel: deviceId is required when level === "device"');const v=e??"hub",N=p2({queries:t.map(J=>({queryKey:[["addonSettings",n==="global"?"getGlobalSettings":"getDeviceSettings"],{addonId:J,nodeId:v,deviceId:r??null}],queryFn:async()=>{if(n==="global"){const ee=await u.addonSettings.getGlobalSettings.query({addonId:J,nodeId:v});return{addonId:J,result:ee}}const W=await u.addonSettings.getDeviceSettings.query({addonId:J,deviceId:r,nodeId:v});return{addonId:J,result:W}},staleTime:3e4}))}),k=N.some(J=>J.isLoading),C=N.map(J=>{if(!J.data)return"-";if(J.data.result===null)return`${J.data.addonId}:n`;const W=[];for(const ee of J.data.result.sections){W.push(`s:${ee.id}:${ee.tab??"general"}`);for(const ae of ee.fields){if(!("key"in ae))continue;const fe="options"in ae&&Array.isArray(ae.options)?ae.options.map(le=>le.value).join(","):"",ge=ae.value,Q=ge===void 0?"":typeof ge=="string"?ge:JSON.stringify(ge);W.push(`f:${ae.key}:${fe}:${Q}`)}}return`${J.data.addonId}:${W.join("|")}`}).join("||"),E=H(()=>{const J=new Set;for(const W of N){const ee=W.data?.result?.sections;if(ee)for(const ae of ee)J.add(ae.tab??"general")}return[...J]},[C+"::"+N.map(J=>(J.data?.result?.sections??[]).map(W=>W.tab??"general").join(",")).join("::")]),I=H(()=>new Map((i??[]).map(J=>[J.id,J])),[i]),A=H(()=>{if(!x)return[];const J=[...new Set([...E,...(i??[]).map(ee=>ee.id)])],W=ee=>{const ae=I.get(ee);if(ae?.order!==void 0)return ae.order;const fe=Nl[ee];return fe?fe.order:50};return J.sort((ee,ae)=>{const fe=W(ee),ge=W(ae);return fe!==ge?fe-ge:ee.localeCompare(ae)})},[x,E,i,I]),z=H(()=>{const J=new Map;for(const W of E){const ee=Nl[W];J.set(W,ee?.label??W.charAt(0).toUpperCase()+W.slice(1))}for(const W of i??[])J.set(W.id,W.label);return J},[E,i]),P=x?y&&A.includes(y)?y:A[0]??null:null,B=P!==null&&I.has(P),R=x?P&&!B?P:void 0:a,{data:M}=wn(void 0,{staleTime:6e4}),D=H(()=>{const J=new Map;for(const W of M??[]){const ee=W.manifest?.id;if(!ee)continue;const ae=W.manifest?.name??W.manifest?.packageDisplayName??ee;J.set(ee,ae)}return J},[M]),T=H(()=>{const J=s?new Set(s):null,W=[];for(const ee of N){if(!ee.data||ee.data.result===null)continue;const{schema:ae,values:fe}=J7(ee.data.result),ge=ae.sections.filter(ue=>J?J.has(ue.id):!0);if(ge.length===0)continue;const Q={...ee.data.result,sections:ee.data.result.sections.filter(ue=>J?J.has(ue.id):!0)},le={...ae,sections:ge};W.push({addonId:ee.data.addonId,schemaWithValues:Q,schema:le,serverValues:fe})}return W},[C,s]),[L,O]=_(new Map),F=U(J=>{O(W=>{const ee=new Map(W);return ee.set(J.addonId,J),ee})},[]),j=te(new Map),V=U(J=>W=>{W?j.current.set(J,W):j.current.delete(J)},[]),$=U(async(J,W)=>{n==="global"?await p.mutateAsync({addonId:J,nodeId:v,patch:W}):await h.mutateAsync({addonId:J,deviceId:r,nodeId:v,patch:W}),d.invalidateQueries({queryKey:[["addonSettings"]]})},[p,h,v,n,r,d]),q=U(async(J,W,ee,ae)=>{const fe=v;try{switch(W){case"reprobe-engine":await m.mutateAsync({nodeId:fe}),d.invalidateQueries({queryKey:[["addonSettings"]]});return;case"reprobe-hwaccel":await g.mutateAsync({nodeId:fe}),d.invalidateQueries({queryKey:[["addonSettings"]]});return;case"reprobe-audio-engine":await b.mutateAsync({nodeId:fe}),d.invalidateQueries({queryKey:[["addonSettings"]]});return;default:{const ge=await u.addons.custom.mutate({addonId:J,action:W,input:ae});return d.invalidateQueries({queryKey:[["addonSettings"]]}),ge}}}catch(ge){throw console.error("[NodeAddonsSettingsPanel] action failed",{addonId:J,action:W,err:ge}),ge}},[m,g,b,v,d,u]),G=U((J,W)=>{$(J,W)},[$]),Z=Kn({mutationFn:async()=>{const J=[];for(const ee of T){const ae=L.get(ee.addonId);!ae||ae.pendingKeys.length===0||J.push({addonId:ee.addonId,patch:ae.pendingValues})}return J.length===0?{saved:[]}:{saved:await Promise.all(J.map(async({addonId:ee,patch:ae})=>(n==="global"?await p.mutateAsync({addonId:ee,nodeId:v,patch:ae}):await h.mutateAsync({addonId:ee,deviceId:r,nodeId:v,patch:ae}),ee)))}},onSuccess:({saved:J})=>{for(const W of J)j.current.get(W)?.discard();d.invalidateQueries({queryKey:[["addonSettings"]]})}}),oe=U(()=>{for(const J of j.current.values())J.discard()},[]),ne=H(()=>{let J=0;for(const W of T){const ee=L.get(W.addonId);ee&&(J+=ee.pendingKeys.length)}return J},[T,L]),X=H(()=>{const J=new Map;for(const W of T){const ee=L.get(W.addonId);if(!ee||ee.pendingKeys.length===0)continue;const ae=new Set(ee.pendingKeys);for(const fe of W.schema.sections){const ge=fe.tab??"general";for(const Q of fe.fields)"key"in Q&&ae.has(Q.key)&&J.set(ge,(J.get(ge)??0)+1)}}return J},[T,L]);if(k)return o("div",{className:"h-24 rounded-lg border border-border bg-surface animate-pulse"});const re=P&&B?I.get(P):void 0;if(!x&&T.length===0)return f("div",{className:"text-[11px] text-foreground-subtle italic",children:["No addons in ",t.length>0?`[${t.join(", ")}]`:"the current selection"," ","expose ",n,"-level settings on this node."]});const be=Z.isPending;return f("div",{className:"space-y-4",children:[(l||c)&&f("div",{className:"border-b border-border pb-2",children:[l&&o("h2",{className:"text-sm font-semibold text-foreground",children:l}),c&&o("p",{className:"text-[11px] text-foreground-subtle mt-0.5",children:c})]}),x&&o(_v,{tabs:A.map(J=>({id:J,label:z.get(J)??J})),activeId:P,onChange:w,pendingByTab:X}),Z.isError&&f("div",{className:"rounded-md border border-red-500/40 bg-red-500/10 px-3 py-2 text-[11px] text-red-400",children:["Save failed: ",String(Z.error?.message??Z.error)]}),re?re.content:(()=>{const J=R?T.reduce((ae,fe)=>ae+fe.schemaWithValues.sections.filter(ge=>(ge.tab??"general")===R).length,0):0,W=R!==null&&J<=1,ee=T.map(ae=>({...ae,renderedWithValues:{...ae.schemaWithValues,sections:ae.schemaWithValues.sections.filter(fe=>R?(fe.tab??"general")===R:!0).map(fe=>W?{...fe,title:"",description:void 0}:fe)}})).filter(ae=>ae.renderedWithValues.sections.length>0).sort((ae,fe)=>{const ge=ue=>{let de=Number.POSITIVE_INFINITY;for(const ce of ue)typeof ce.order=="number"&&ce.order<de&&(de=ce.order);return de},Q=ge(ae.renderedWithValues.sections),le=ge(fe.renderedWithValues.sections);return Q!==le?Q-le:0});return ee.length===0?o("div",{className:"text-[11px] text-foreground-subtle italic",children:"Nothing to configure here for this node."}):o(eB,{entries:ee,paneStates:L,displayNames:D,disabled:be,setPaneRef:V,onPaneStateChange:F,onImmediateSave:G,onAction:q,inline:x||!!a})})(),!k&&o(Pv,{pendingCount:ne,onSave:()=>Z.mutate(),onDiscard:oe,saving:be})]})}function eB({entries:e,paneStates:t,displayNames:n,disabled:r,setPaneRef:s,onPaneStateChange:a,onImmediateSave:i,onAction:l,inline:c}){const d=H(()=>[...e].sort((x,y)=>{if(x.addonId==="system-config")return-1;if(y.addonId==="system-config")return 1;const w=n.get(x.addonId)??x.addonId,v=n.get(y.addonId)??y.addonId;return w.localeCompare(v)}),[e,n]),u=d[0]?.addonId??"",[p,h]=_(u);Y(()=>{d.length!==0&&(d.find(x=>x.addonId===p)||h(d[0].addonId))},[d,p]);const m=d.find(x=>x.addonId===p)??d[0];if(!m)return null;const g=H(()=>l?(x,y,w,v)=>l(x,y,w,v):void 0,[l]),b=x=>o(Z7,{ref:s(x.addonId),addonId:x.addonId,schema:x.renderedWithValues,serverValues:x.serverValues,onImmediateSave:i,onStateChange:a,onAction:g,disabled:r},x.addonId);return d.length===1||c?o("div",{className:"flex flex-col gap-4",children:d.map(b)}):f("div",{className:"flex flex-col gap-3",children:[o("div",{className:"flex flex-wrap items-center gap-1 border-b border-border shrink-0",children:d.map(x=>{const y=n.get(x.addonId)??x.addonId,w=x.addonId===m.addonId,v=(t.get(x.addonId)?.pendingKeys.length??0)>0;return f("button",{type:"button",onClick:()=>h(x.addonId),className:`relative px-3 py-1.5 text-xs font-medium rounded-t-md transition-colors -mb-px border-b-2 whitespace-nowrap ${w?"text-primary border-primary bg-primary/5":"text-foreground-subtle border-transparent hover:text-foreground hover:bg-surface-hover"}`,children:[y,v&&o("span",{className:"ml-1.5 inline-flex h-1.5 w-1.5 rounded-full bg-amber-400"})]},x.addonId)})}),o("div",{className:"space-y-2",children:d.map(x=>o("div",{style:x.addonId===m.addonId?void 0:{display:"none"},children:b(x)},x.addonId))})]})}const tB=["detection-pipeline","decoder-nodeav","audio-analyzer","pipeline-runner"];function nB({nodeId:e,refreshToken:t}){return f("div",{className:"flex flex-col h-full",children:[o(_7,{nodeId:e,refreshToken:t}),o("div",{className:"flex-1 min-h-0 overflow-y-auto p-6",children:o(to,{nodeId:e,addonIds:tB,level:"global",extraTabs:[{id:"assignments",label:"Assignments",order:-10,content:o(F7,{nodeId:e,refreshToken:t})},{id:"tree",label:"Pipeline",order:39,content:o(W7,{nodeId:e,refreshToken:t})},{id:"engines",label:"Warm instances",order:180,content:o(V7,{nodeId:e,refreshToken:t})},{id:"models",label:"Models",order:200,content:o(K7,{nodeId:e,refreshToken:t})}]})})]})}function rB({refreshToken:e}){const t=ke(),n=Wx({onSuccess:()=>{t.invalidateQueries({queryKey:[["pipelineOrchestrator","getPipelineAssignments"]]}),t.invalidateQueries({queryKey:[["pipelineOrchestrator","getDecoderAssignments"]]}),t.invalidateQueries({queryKey:[["pipelineOrchestrator","getAudioAssignments"]]})}});return f("div",{className:"space-y-6",children:[o(Sv,{refreshToken:e}),f("div",{className:"flex flex-col gap-3 @md/clustertab:flex-row @md/clustertab:items-center @md/clustertab:justify-between",children:[f("div",{className:"min-w-0",children:[o("h3",{className:"text-sm font-semibold text-foreground mb-1",children:"Placement matrix"}),o("p",{className:"text-[11px] text-foreground-subtle",children:"Pipeline · decoder · audio assignments per camera. Click the kebab to pin / unpin / move any role; expand the chevron for the per-camera broker drill-down."})]}),f("button",{type:"button",onClick:()=>n.mutate(void 0),disabled:n.isPending,className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-white hover:bg-primary/90 disabled:opacity-50 shrink-0 self-start @md/clustertab:self-auto whitespace-nowrap",children:[o(Jd,{className:"h-3.5 w-3.5"}),n.isPending?"Rebalancing…":"Rebalance pipelines"]})]}),o(Ev,{mode:"cluster"})]})}const oB=["pipeline-orchestrator"];function sB({refreshToken:e}){return o("div",{className:"space-y-4 max-w-3xl",children:o(to,{nodeId:"hub",addonIds:oB,level:"global",title:"Cluster settings",description:"Cluster-wide orchestration knobs: enabled nodes, load balancer thresholds, and failover policy. Per-camera pipelines live in Device Overrides; live cluster load is on the Assignments tab."})})}function aB({refreshToken:e}){const t=ke(),{data:n,isLoading:r}=uy(),[s,a]=_(null),[i,l]=_(""),[c,d]=_(""),u=()=>{t.invalidateQueries({queryKey:[["pipelineOrchestrator","listTemplates"]]})},p=py({onSuccess:()=>{a(null),u()}}),h=fy({onSuccess:u}),m=y=>{a(y.id),l(y.name),d(y.description??"")},g=()=>{a(null),l(""),d("")},b=()=>{if(!s)return;const y=c.trim();p.mutate({id:s,name:i.trim()||"Untitled",...y?{description:y}:{}})};if(r)return o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading templates…"});const x=[...n??[]].sort((y,w)=>y.name.localeCompare(w.name));return o("div",{className:"space-y-6 max-w-4xl",children:f("section",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"border-b border-border px-4 py-3 flex items-center justify-between",children:[f("div",{children:[o("h3",{className:"text-sm font-semibold text-foreground",children:"Templates"}),o("p",{className:"text-[11px] text-foreground-subtle mt-0.5",children:"Curated pipeline presets operators can apply to any camera. Apply-time is a copy — future edits to a template don't retroactively change cameras that were seeded from it. Save a template from the device Pipeline tab."})]}),f("div",{className:"text-[11px] text-foreground-subtle",children:[x.length," template",x.length===1?"":"s"]})]}),x.length===0?f("div",{className:"px-4 py-8 text-xs text-foreground-subtle flex flex-col items-center gap-2",children:[o(Et,{className:"h-6 w-6 opacity-40"}),o("div",{children:'No templates yet. Create one from a device Pipeline tab ("Save as template").'})]}):o("ul",{className:"divide-y divide-border",children:x.map(y=>{const w=s===y.id;return o("li",{className:"px-4 py-3 text-xs",children:f("div",{className:"flex items-start gap-3",children:[o("div",{className:"flex-1 min-w-0",children:w?f("div",{className:"space-y-2",children:[o("input",{className:"w-full rounded border border-border bg-surface-hover px-2 py-1 text-xs text-foreground focus:outline-none focus:border-primary",value:i,onChange:v=>l(v.target.value),placeholder:"Template name",autoFocus:!0}),o("input",{className:"w-full rounded border border-border bg-surface-hover px-2 py-1 text-[11px] text-foreground focus:outline-none focus:border-primary",value:c,onChange:v=>d(v.target.value),placeholder:"Description (optional)"})]}):f(me,{children:[o("div",{className:"font-medium text-foreground",children:y.name}),y.description&&o("div",{className:"text-foreground-subtle mt-0.5",children:y.description}),f("div",{className:"mt-1 font-mono text-[10px] text-foreground-subtle",children:["engine ",y.config.engine.runtime,"/",y.config.engine.backend," · ",y.config.steps.length," step(s)",y.config.audio?.enabled?" · audio":"",f("span",{className:"ml-2",children:["updated ",new Date(y.updatedAt).toLocaleString()]})]})]})}),o("div",{className:"flex items-center gap-1 shrink-0",children:w?f(me,{children:[f("button",{type:"button",onClick:b,disabled:p.isPending,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] font-medium bg-primary text-white hover:bg-primary/90 disabled:opacity-50",children:[o(_t,{className:"h-3 w-3"}),"Save"]}),f("button",{type:"button",onClick:g,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover",children:[o(Fe,{className:"h-3 w-3"}),"Cancel"]})]}):f(me,{children:[o("button",{type:"button",onClick:()=>m(y),title:"Rename",className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] text-foreground-subtle hover:text-foreground hover:bg-surface-hover",children:o(eo,{className:"h-3 w-3"})}),o("button",{type:"button",onClick:()=>{confirm(`Delete template "${y.name}"?`)&&h.mutate({id:y.id})},disabled:h.isPending,title:"Delete",className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] text-foreground-subtle hover:text-red-400 hover:bg-surface-hover disabled:opacity-50",children:o(Ze,{className:"h-3 w-3"})})]})})]})},y.id)})})]})})}function Cf(e,t){if(!e)return null;for(const n of e.slots)for(const r of n.addons)if(r.id===t)return r;return null}function iB({nodeId:e,refreshToken:t}){const n=ke(),r=Te().trpcClient,[s,a]=_(null),[i,l]=_(null),c=Yr(void 0,{refetchOnMount:"always"});St(["nodes","topology"],["agent.online","agent.offline","agent.unregistered","addon.installed","addon.uninstalled","addon.updated"]);const d=zn(void 0,{staleTime:3e4,refetchOnMount:"always"}),u=H(()=>{const A=new Set;for(const z of d.data??[])z.isOnline&&A.add(z.id);return A},[d.data]),p=Wo({nodeId:e},{refetchOnMount:"always"}),h=H(()=>(c.data??[]).filter(A=>u.has(A.nodeId)).map(A=>A.nodeId),[c.data,u]),m=Ln({enabled:h.length>0,queryKey:[["pipelineExecutor","getSchema"],"schema-by-agent",h.join(","),t],queryFn:async()=>{const A={};for(const z of h)try{const P=await r.pipelineExecutor.getSchema.query({nodeId:z});A[z]=P.selectedEngine.format}catch{A[z]="coreml"}return A}}),g=md({onSuccess:()=>{n.invalidateQueries({queryKey:[["pipelineOrchestrator"]]}),n.invalidateQueries({queryKey:[["pipelineExecutor"]]}),n.invalidateQueries({queryKey:[["addonSettings"]]})}}),b=H(()=>p.data?Ta(p.data):[],[p.data]),x=H(()=>{const A=c.data??[],z=u;return(z.size===0?[]:A.filter(B=>z.has(B.nodeId))).map(B=>{const R=m.data?.[B.nodeId];return{agentNodeId:B.nodeId,engineLabel:R??"(engine unknown)"}})},[c.data,m.data,u]),y=(A,z)=>{const B=c.data?.find(T=>T.nodeId===z)?.settings.addonDefaults[A],R=m.data?.[z];return Cf(p.data??null,A)?.models.some(T=>R!==void 0&&!!T.formats[R])?B?B.enabled?{kind:"enabled",modelId:B.modelId}:{kind:"disabled"}:{kind:"na"}:{kind:"na"}},w=s?c.data?.find(A=>A.nodeId===s.agentNodeId)??null:null,v=s&&p.data?Cf(p.data,s.addonId):null,N=s?m.data?.[s.agentNodeId]??"coreml":"coreml",k=()=>{a(null),l(null)},C=(A,z)=>{const B=c.data?.find(R=>R.nodeId===z)?.settings.addonDefaults[A]??null;a({addonId:A,agentNodeId:z}),l(B)},E=()=>{!i||!s||!w||g.mutate({agentNodeId:s.agentNodeId,defaults:{...w.settings.addonDefaults,[s.addonId]:i}},{onSuccess:k})};if(c.isLoading||p.isLoading)return o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading agents…"});if(!p.data)return f("div",{className:"text-xs text-foreground-subtle",children:["Catalog unavailable for ",e,"."]});const I=s!==null&&v!==null&&i!==null;return f("div",{className:"relative h-full w-full space-y-3",children:[o(Av,{title:"Cluster cameras"}),o("div",{className:I?"pr-[360px]":"",children:b.length>0&&x.length>0?o(Uc,{tree:b,agents:x,getCellState:y,onCellClick:C,selectedCell:s}):o("div",{className:"text-xs text-foreground-subtle",children:"No agents or catalog empty."})}),o(qc,{open:I,onClose:k,title:v?.name??"",subtitle:s?`${s.agentNodeId} · ${N}`:"",footer:f(me,{children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:k,children:"Cancel"}),o("button",{type:"button",disabled:!i||!s||g.isPending,className:"px-3 py-1 text-xs bg-primary text-primary-foreground rounded disabled:opacity-50",onClick:E,children:g.isPending?"Saving…":"Save"})]}),children:v&&i&&s&&o(Ra,{mode:"agent",addon:v,agentDefault:i,agentNodeId:s.agentNodeId,engineFormat:N,onChangeAgentConfig:A=>l(A)})})]})}const lB=[{id:"assignments",label:"Assignments"},{id:"pipeline",label:"Pipeline"},{id:"settings",label:"Settings"},{id:"templates",label:"Templates"}];function cB({refreshToken:e}){const[t,n]=_("assignments"),{data:r}=zn(void 0,{staleTime:3e4}),s=r?.find(a=>a.isHub&&a.isOnline)?.id??r?.find(a=>a.isOnline)?.id??null;return f("div",{className:"flex flex-col h-full",children:[f("div",{className:"px-6 py-4 border-b border-border",children:[o("h2",{className:"text-base font-semibold text-foreground",children:"Cluster Orchestration"}),o("div",{className:"text-[11px] text-foreground-subtle mt-1",children:"Assignments with live load, cluster-wide settings, pipeline template library, per-camera pipeline overrides."})]}),o("div",{className:"flex items-center gap-1 px-6 border-b border-border",children:lB.map(a=>o("button",{type:"button",onClick:()=>n(a.id),className:`px-3 py-2 text-xs font-medium border-b-2 transition-colors ${t===a.id?"border-primary text-primary":"border-transparent text-foreground-subtle hover:text-foreground"}`,children:a.label},a.id))}),f("div",{className:"flex-1 min-h-0 overflow-y-auto p-4 sm:p-6 @container/clustertab",children:[t==="assignments"&&o(rB,{refreshToken:e}),t==="pipeline"&&(s?o(iB,{nodeId:s,refreshToken:e}):o("div",{className:"text-xs text-foreground-subtle",children:"No online node available — schema unreachable."})),t==="settings"&&o(sB,{refreshToken:e}),t==="templates"&&o(aB,{refreshToken:e})]})]})}const No="__cluster__";function dB(){const[e,t]=Ga(),n=e.get("node")??No,[r,s]=_(0);return Y(()=>{e.get("node")||t({node:No},{replace:!0})},[e,t]),f("div",{className:"flex flex-col h-full overflow-hidden",children:[o("div",{className:"flex items-center justify-end gap-4 px-4 py-3 border-b border-border shrink-0",children:f("button",{type:"button",onClick:()=>s(i=>i+1),title:"Refresh",className:"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-[11px] font-medium border border-border text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:[o(ct,{className:"h-3.5 w-3.5"}),"Refresh"]})}),f("div",{className:"flex-1 flex flex-col md:flex-row overflow-hidden min-h-0",children:[o("aside",{className:"w-full md:w-72 shrink-0 border-b md:border-b-0 md:border-r border-border overflow-y-auto",children:o(P7,{selectedNodeId:n,onSelect:i=>{t({node:i},{replace:!0})},refreshToken:r})}),o("section",{className:"flex-1 min-h-0 overflow-hidden",children:n===No?o(cB,{refreshToken:r}):o(nB,{nodeId:n,refreshToken:r})})]})]})}const uB="device-export",tl="export",pB="Export";function tc(e){return e.type==="separator"||e.type==="info"||e.type==="object-array"||e.type==="widget"||e.type==="addon-action-button"?!1:e.type==="group"?e.fields.some(tc):e.type==="sub-tabs"?e.tabs.some(t=>t.fields.some(tc)):e.writerCapName===uB}function Do(e){return e.fields.some(tc)}function fB(e){const[t,n]=_("idle"),[r,s]=_(null),a=te(null),i=te(null),l=te(null),c=te(!0),d=hx(),u=mx(),p=gx(),h=U(()=>{if(a.current){try{a.current.close()}catch{}a.current=null}if(i.current){for(const b of i.current.getTracks())try{b.stop()}catch{}i.current=null}l.current=null},[]),m=U(async()=>{if(t==="idle")return;n("stopping");const b=l.current;if(b&&e!==null)try{await Promise.race([p.mutateAsync({deviceId:e,sessionId:b}),new Promise((y,w)=>setTimeout(()=>w(new Error("server stopSession timeout")),2e3))])}catch(y){console.warn("[intercom] server stopSession failed (continuing teardown)",y)}h(),c.current&&(n("idle"),s(null))},[t,e,p,h]),g=U(async()=>{if(e===null||t!=="idle"&&t!=="error")return;s(null);let b=null,x=null,y=null;try{n("requesting-mic"),b=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1}),i.current=b,n("starting");const w=await d.mutateAsync({deviceId:e});y=w.sessionId,l.current=y,n("connecting"),x=new RTCPeerConnection,a.current=x,x.oniceconnectionstatechange=()=>{if(!c.current)return;const k=x.iceConnectionState;k==="connected"||k==="completed"?n("talking"):(k==="failed"||k==="closed"||k==="disconnected")&&c.current&&(s(k==="failed"?"WebRTC connection failed":null),m())};for(const k of b.getAudioTracks())x.addTrack(k,b);await x.setRemoteDescription({type:"offer",sdp:w.sdpOffer});const v=await x.createAnswer();await x.setLocalDescription(v);const N=x.localDescription?.sdp??v.sdp??"";await u.mutateAsync({deviceId:e,sessionId:y,sdpAnswer:N})}catch(w){const v=w instanceof Error?w.message:String(w);if(console.warn("[intercom] start failed",w),x)try{x.close()}catch{}if(b)for(const N of b.getTracks())try{N.stop()}catch{}if(a.current=null,i.current=null,y!==null)try{await p.mutateAsync({deviceId:e,sessionId:y})}catch{}l.current=null,c.current&&(s(v),n("error"))}},[e,t,d,u,p,m]);return Y(()=>(c.current=!0,()=>{c.current=!1;const b=l.current;if(b!==null&&e!==null&&p.mutate({deviceId:e,sessionId:b}),a.current){try{a.current.close()}catch{}a.current=null}if(i.current){for(const x of i.current.getTracks())try{x.stop()}catch{}i.current=null}l.current=null}),[e]),{state:t,error:r,start:g,stop:m,isTalking:t==="talking"}}let hB=0;function ut(){return++hB}function nl(e){switch(e.type){case"system":return"system";case"device":return`#${e.deviceId}`;case"provider":return e.providerId;case"addon":return e.addonId}}function mB(e){return["","Commands"," help Show this help"," examples Show usage examples for the current scope"," context Show every available variable + full API surface"," clear Clear terminal (also Ctrl+L)","","Shortcuts"," Enter Execute expression"," Arrow Up/Down Navigate command history"," Ctrl+L Clear terminal","",`Try: ${{system:" sm.summary() // fleet overview",device:" device.state.battery.value?.sleeping // sync read",provider:" devices.map(d => d.name)",addon:" manifest.version"}[e.type]}`,"","Top-level objects: sm (SystemMirror), DeviceType, Math, JSON, Date, …"]}function gB(e){switch(e.type){case"device":return["","── State (sync, zero round-trip) ─────────────────────────"," device.state.battery.value"," device.state.battery.value?.percentage"," device.state.motion.value?.detected","","── Actions (async, through wrapper chain) ────────────────"," await device.snapshot.getSnapshot({})"," await device.ptz.move({ direction: 'left', steps: 1 })"," await device.switch.setState({ on: true })","","── Wait for condition ───────────────────────────────────"," await sm.waitForState(deviceId, 'battery', s => !s.sleeping, 30_000)","","── Subscribe to changes ─────────────────────────────────"," const off = device.state.battery.subscribe(s => console.log(s))","","── Quick info ───────────────────────────────────────────"," info.name device name"," info.addonId owning addon"," sm.dump(deviceId) full debug dump"];case"system":return["","── Lookups ──────────────────────────────────────────────"," sm.getDeviceById(8)"," sm.getDeviceByName('Sala da pranzo')"," sm.getDevicesByAddon('reolink')"," sm.getDevicesByType(DeviceType.Camera)","","── Filters (typed query) ────────────────────────────────"," sm.query({ addonId: 'reolink', online: true })"," sm.query({ caps: ['battery', 'snapshot'] })"," sm.query({ name: /^Cam-/ })","","── Cross-device ─────────────────────────────────────────"," sm.whereState('battery', s => s.percentage < 20).length"," sm.mapState('battery', s => s.percentage)"," sm.countByCap('snapshot')","","── Batch action ─────────────────────────────────────────"," await sm.invokeCap('snapshot', 'getSnapshot', {}, { parallelism: 4 })","","── Listen ───────────────────────────────────────────────"," sm.listenCap('motion', (id, s) => console.log(id, s))"," sm.onDeviceAdded((id, info) => console.log('+', info.name))","","── Diagnostics ──────────────────────────────────────────"," sm.summary()"," sm.dump(8)"];case"provider":return[""," devices.map(d => d.name)"," await getIntegration()"," sm.getDevicesByAddon('<this-addon-id>').length"];case"addon":return[""," manifest.name"," manifest.version"," declaration"]}}function bB(e){const t=["",`Scope: ${e.type}`,""];switch(e.type){case"system":return[...t,"Primary API — sm (SystemMirror):"," sm.getDeviceById(id) DeviceProxy | null (sync)"," sm.getDeviceByName(name) DeviceProxy | null"," sm.getDeviceByStableId(sid) DeviceProxy | null"," sm.getAllDevices() readonly DeviceProxy[]"," sm.getDeviceInfo(id) DeviceInfo | null"," sm.summary() fleet stats","","Filters — sm.query({...}):"," sm.query({ addonId: 'reolink', online: true })"," sm.query({ caps: ['battery', 'snapshot'] }) // ALL caps required"," sm.query({ anyCap: ['ptz', 'motion'] }) // ANY cap"," sm.query({ name: { contains: 'sala' } }) // case-insensitive"," sm.query({ name: /^Cam-\\d+$/ })"," sm.query({ type: DeviceType.Camera })"," sm.query({ parentDeviceId: 8 }) // accessories of cam 8"," sm.query({ where: (info, dev) => dev.state.battery.value?.sleeping })","","State queries:"," sm.whereState('battery', s => s.percentage < 20)"," sm.mapState('battery', s => s.percentage)"," sm.findState('motion', s => s.detected)"," sm.countByCap('snapshot')","","Listeners (return unsubscribe fn):"," sm.listen((id, cap, slice) => …) // every state change"," sm.listenCap('motion', (id, slice) => …)"," sm.listenDevice(8, (id, cap, slice) => …)"," sm.onDeviceAdded((id, info) => …)"," sm.onDeviceRemoved((id, info) => …)","","Wait primitives:"," await sm.waitForState(8, 'battery', s => !s.sleeping, 30_000)"," await sm.waitForDevice(99, 30_000)","","Batch:"," await sm.invokeCap('snapshot', 'getSnapshot', {}, { parallelism: 4 })"," await sm.forEachCap('reboot', d => d.reboot.reboot({}))","","Diagnostics:"," sm.dump(8) debug dump (one device)"," sm.dump() full fleet dump"," sm.summary() breakdown by cap/addon/type","","Legacy: deviceRegistry, addonRegistry, eventBus, devices(), addons()"];case"device":return[...t,"Pre-bound variables:"," device DeviceProxy for this device (sync state + async methods)"," deviceId number"," info DeviceInfo metadata (name, addonId, type, online, …)"," sm SystemMirror (full cluster view)"," rawDevice legacy IDevice instance (escape hatch)","","Reactive state (sync, zero round-trip):"," device.state.battery.value BatteryStatus | undefined"," device.state.battery.value?.sleeping"," device.state.battery.value?.percentage"," device.state.motion.value?.detected"," device.state.switch.value?.on"," device.state.brightness.value?.percentage"," device.state.doorbell.value?.lastPressedAt","","Cap actions (async, through wrapper chain):"," await device.snapshot.getSnapshot({})"," await device.snapshot.getSnapshot({ streamId: 'high' })"," await device.ptz.move({ direction: 'left', steps: 1 })"," await device.ptz.goToPreset({ presetId: 'home' })"," await device.switch.setState({ on: true })"," await device.brightness.setBrightness({ percentage: 60 })"," await device.reboot.reboot({})","","Subscribe to slice changes:"," const off = device.state.battery.subscribe(s => console.log(s))"," // off() to unsubscribe","","Wait for a state condition:"," await sm.waitForState(deviceId, 'battery', s => !s.sleeping, 30_000)","","Diagnostics:"," info.name device name"," info.addonId which addon owns it"," info.online transport health"," sm.dump(deviceId) full debug dump (binding + state + info)"];case"provider":return[...t,"Pre-bound variables:"," devices Devices belonging to this provider (raw IDevice[])"," getIntegration() Integration metadata","","For typed device access use the SystemMirror:"," await getSystemMirror()"," sm.getDevicesByAddon('this-addon-id')"];case"addon":return[...t,"Pre-bound variables:"," manifest { name, version, ... }"," declaration addon declaration"," source addon source location","","Examples:"," manifest.name"," manifest.version"]}}function xB({scope:e,greeting:t,className:n}){const r=Te(),[s,a]=_(()=>{const v=[];return t&&v.push({id:ut(),kind:"info",text:t}),v.push({id:ut(),kind:"info",text:`scope: ${nl(e)} — type help or context for available commands`}),v}),[i,l]=_(""),[c,d]=_([]),[u,p]=_(-1),h=te(null),m=te(null);Y(()=>{const v=m.current;v&&(v.scrollTop=v.scrollHeight)},[s]);const g=U(()=>{h.current?.focus()},[]),b=Kn({mutationFn:v=>r.trpcClient.repl.execute.mutate({code:v,scope:e}),onSuccess:v=>{const N=v??{},k=typeof N.output=="string"?N.output:v==null?"undefined":typeof v=="string"?v:JSON.stringify(v,null,2),C=N.type==="error";a(E=>[...E,{id:ut(),kind:C?"error":"result",text:k}])},onError:v=>{const N=v instanceof Error?v.message:String(v);a(k=>[...k,{id:ut(),kind:"error",text:N}])}});function x(v){const N=v.trim();if(N){if(N==="clear"){a([{id:ut(),kind:"info",text:`scope: ${nl(e)}`}]),l("");return}if(N==="help"){a(k=>[...k,{id:ut(),kind:"input",text:`> ${N}`},...mB(e).map(C=>({id:ut(),kind:"info",text:C}))]),l("");return}if(N==="context"){a(k=>[...k,{id:ut(),kind:"input",text:`> ${N}`},...bB(e).map(C=>({id:ut(),kind:"info",text:C}))]),l("");return}if(N==="examples"){a(k=>[...k,{id:ut(),kind:"input",text:`> ${N}`},...gB(e).map(C=>({id:ut(),kind:"info",text:C}))]),l("");return}d(k=>[...k,N]),p(-1),a(k=>[...k,{id:ut(),kind:"input",text:`> ${N}`}]),l(""),b.mutate(N)}}function y(v){if(v.key==="Enter"){v.preventDefault(),x(i);return}if(v.key==="ArrowUp"){if(v.preventDefault(),c.length===0)return;const N=u===-1?c.length-1:Math.max(0,u-1);p(N),l(c[N]??"");return}if(v.key==="ArrowDown"){if(v.preventDefault(),u===-1)return;const N=u+1;N>=c.length?(p(-1),l("")):(p(N),l(c[N]??""));return}v.ctrlKey&&v.key==="l"&&(v.preventDefault(),a([{id:ut(),kind:"info",text:`scope: ${nl(e)}`}]))}const w={input:"text-zinc-300",result:"text-emerald-300",error:"text-red-300",info:"text-zinc-400"};return f("div",{className:`flex flex-col bg-[#0c0a09] rounded-lg border border-border overflow-hidden font-mono text-xs ${n??""}`,onClick:g,children:[f("div",{ref:m,className:"flex-1 overflow-y-auto p-3 space-y-1 min-h-[120px]",children:[s.map(v=>o("pre",{className:`whitespace-pre-wrap break-words leading-relaxed ${w[v.kind]}`,children:v.text},v.id)),b.isPending&&o("span",{className:"text-zinc-500 animate-pulse",children:"…thinking"})]}),f("div",{className:"flex items-center gap-2 border-t border-zinc-800 px-3 py-2 bg-[#0c0a09]",children:[o("span",{className:"text-emerald-400 flex-shrink-0 select-none font-bold",children:">"}),o("input",{ref:h,value:i,onChange:v=>l(v.target.value),onKeyDown:y,disabled:b.isPending,placeholder:"device.state.battery.value",autoFocus:!0,className:"flex-1 bg-transparent text-zinc-100 placeholder:text-zinc-600 focus:outline-none caret-emerald-400 disabled:opacity-50",spellCheck:!1,autoComplete:"off",autoCorrect:"off",autoCapitalize:"off"})]})]})}function yB(e){const t=ke(),n=e!==null&&Number.isFinite(e),r=my({deviceId:e??0},{enabled:n,refetchInterval:5e3,retry:1}),s=gy({onSuccess:()=>{t.invalidateQueries({queryKey:[["ptzAutotrack"]]})}}),a=by({onSuccess:()=>{t.invalidateQueries({queryKey:[["ptzAutotrack"]]})}}),i=U(async d=>{e!==null&&await s.mutateAsync({deviceId:e,enabled:d})},[e,s]),l=U(async d=>{e!==null&&await a.mutateAsync({deviceId:e,settings:d})},[e,a]),c=r.error?r.error.message:s.error?s.error.message:a.error?a.error.message:null;return{status:r.data??null,isLoading:r.isLoading,isPending:s.isPending||a.isPending,error:c,setEnabled:i,setSettings:l}}function vB({deviceId:e}){const{status:t,isLoading:n,isPending:r,error:s,setEnabled:a,setSettings:i}=yB(Number.isFinite(e)?e:null),[l,c]=_({targetType:"",stopDelaySeconds:30,disappearDelaySeconds:15}),[d,u]=_(!1);return Y(()=>{if(d)return;const p=t?.currentSettings;p&&c({targetType:p.targetType,stopDelaySeconds:p.stopDelaySeconds,disappearDelaySeconds:p.disappearDelaySeconds})},[t,d]),n&&!t?f("div",{className:"flex items-center gap-2 px-3 py-2 text-[10.5px] text-foreground-subtle",children:[o(Se,{className:"h-3 w-3 animate-spin"}),"Loading autotrack…"]}):f("div",{className:"border-t border-border/40 mt-2 pt-2 px-1 space-y-2",children:[f("div",{className:"flex items-center justify-between px-2",children:[f("div",{className:"flex items-center gap-1.5 text-[10.5px] font-semibold text-foreground",children:[o(JR,{className:"h-3 w-3 text-primary"}),"Autotracking"]}),f("button",{type:"button",onClick:()=>{a(!(t?.enabled??!1))},disabled:r,className:`flex items-center gap-1.5 rounded-md px-2 py-1 text-[10px] font-medium transition-colors ${t?.enabled?"bg-success/15 text-success hover:bg-success/25":"bg-surface-elevated/40 text-foreground-subtle hover:bg-surface-hover hover:text-foreground"} disabled:opacity-50`,"aria-pressed":t?.enabled??!1,children:[o("span",{className:`h-1.5 w-1.5 rounded-full ${t?.enabled?"bg-success":"bg-foreground-subtle/40"}`}),t?.enabled?"Enabled":"Disabled"]})]}),s&&f("div",{className:"flex items-start gap-1.5 rounded-md border border-danger/30 bg-danger/5 px-2 py-1.5 text-[10px] text-danger",children:[o(nr,{className:"h-3 w-3 flex-shrink-0 mt-0.5"}),o("span",{className:"leading-snug break-words",children:s})]}),f("div",{className:"grid grid-cols-2 gap-2 px-2",children:[(t?.supportedTargetTypes?.length??0)>0&&f("label",{className:"col-span-2 flex flex-col gap-1",children:[o("span",{className:"text-[10px] font-medium text-foreground-subtle",children:"Target type"}),o("select",{value:l.targetType,onFocus:()=>u(!0),onChange:p=>c(h=>({...h,targetType:p.target.value})),onBlur:()=>{u(!1);const p=t?.currentSettings?.targetType??"";l.targetType!==p&&i({targetType:l.targetType})},disabled:r,className:"rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50",children:(t?.supportedTargetTypes??[]).map(p=>o("option",{value:p.value,children:p.label},p.value))})]}),f("label",{className:"flex flex-col gap-1",children:[o("span",{className:"text-[10px] font-medium text-foreground-subtle",children:"Stop delay (s)"}),o("input",{type:"number",min:0,max:300,value:l.stopDelaySeconds,onFocus:()=>u(!0),onChange:p=>c(h=>({...h,stopDelaySeconds:Number(p.target.value)||0})),onBlur:()=>{u(!1);const p=t?.currentSettings?.stopDelaySeconds??30;l.stopDelaySeconds!==p&&i({stopDelaySeconds:l.stopDelaySeconds})},disabled:r,className:"rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50"})]}),f("label",{className:"flex flex-col gap-1",children:[o("span",{className:"text-[10px] font-medium text-foreground-subtle",children:"Disappear delay (s)"}),o("input",{type:"number",min:0,max:300,value:l.disappearDelaySeconds,onFocus:()=>u(!0),onChange:p=>c(h=>({...h,disappearDelaySeconds:Number(p.target.value)||0})),onBlur:()=>{u(!1);const p=t?.currentSettings?.disappearDelaySeconds??15;l.disappearDelaySeconds!==p&&i({disappearDelaySeconds:l.disappearDelaySeconds})},disabled:r,className:"rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground focus:border-primary focus:outline-none disabled:opacity-50"})]})]}),o("p",{className:"px-2 text-[9.5px] text-foreground-subtle leading-snug italic",children:"Settings save on blur. Vendor support varies — Reolink honours all three; Hikvision honours target type + stop delay only (disappear delay is accepted but ignored at firmware push)."})]})}function wB({deviceId:e,intercomAvailable:t=!1}){const n=Te(),r=typeof window<"u"?window.location.origin:"",s=Number.isFinite(e),a=iv(s?e:null),{streams:i,pipelineMetrics:l,createSession:c,sendAnswer:d,closeSession:u}=Td(n.trpcClient,s?e:null),p=Zc(n.trpcClient,s?e:null),h=fB(s&&t?e:null),m=h.state==="requesting-mic"||h.state==="starting"||h.state==="connecting"||h.state==="stopping",g=h.isTalking||m,b=()=>{h.state==="idle"||h.state==="error"?h.start():h.state!=="stopping"&&h.stop()},x=e0(),y=x.length>0?o(me,{children:x.map(w=>o("div",{className:"absolute inset-0",children:w.node},w.id))}):null;return o(Cd,{serverUrl:r,createSession:c,sendAnswer:d,closeSession:u,streams:i,pipelineMetrics:l,phase:a.phase,detections:a,defaultShowDetections:!0,defaultShowMotion:!0,showPlayStop:!0,snapshotSrc:p.src,snapshotLoading:p.loading,onRefreshSnapshot:p.refresh,intercomAvailable:t,intercomShown:g,onIntercomToggle:b,extraOverlay:y,chromeless:!0,className:"h-full"})}function NB({deviceId:e}){return Number.isFinite(e)?o("div",{className:"flex flex-col h-full",children:o(tn,{deviceId:e,limit:50,maxHeight:"max-h-full",showScope:!1,showFilters:!1})}):f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]})}function kB({deviceId:e}){if(!Number.isFinite(e))return f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]});const t=[`CamStack REPL — device #${e}`,""," device.state.battery.value sync state read"," await device.snapshot.getSnapshot({}) cap action",""," type 'examples' for more, 'context' for the full API"].join(`
|
|
1142
|
-
`);return o(xB,{scope:{type:"device",deviceId:e},greeting:t,className:"h-full border-0 rounded-none"})}function SB({deviceId:e}){const t=Te(),n=Number.isFinite(e),r=Ld(t.trpcClient,n?e:0,{enabled:n}),{data:s}=$7(n?e:0);if(!n)return f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]});const a=(s?.features??[]).includes(Wn.PtzAutotrack);return f("div",{className:"flex flex-col h-full overflow-y-auto",children:[o(Pd,{controls:r,mode:"panel"}),a&&o(vB,{deviceId:e})]})}function CB({deviceId:e}){return Number.isFinite(e)?o("div",{className:"flex flex-col h-full overflow-y-auto",children:o(br,{deviceId:e,limit:50,maxHeight:"max-h-full"})}):f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]})}function MB({deviceId:e}){return Number.isFinite(e)?o("div",{className:"flex flex-col h-full overflow-y-auto",children:o(Id,{deviceId:e,limit:50,maxHeight:"max-h-full"})}):f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]})}function EB({parentDeviceId:e}){const{t}=Vt(),n=rt(),r=Te(),{data:s,isLoading:a,isError:i}=Mv(e);if(a)return o("div",{className:"rounded-lg border border-border bg-surface p-3",children:o("p",{className:"text-[10px] text-foreground-subtle",children:t("common.loading",{defaultValue:"Loading…"})})});if(i)return o("div",{className:"rounded-lg border border-border bg-surface p-3",children:o("p",{className:"text-[10px] text-warning",children:t("integrations.childrenLoadError",{defaultValue:"Failed to load children"})})});const l=s??[];if(l.length===0)return null;const c=l.some(p=>!!p.role),d=l.some(p=>!p.role),u=c&&!d?t("device.accessories",{defaultValue:"Accessories"}):!c&&d?t("device.adoptedDevices",{defaultValue:"Adopted devices"}):t("device.children",{defaultValue:"Children"});return f("div",{className:"rounded-lg border border-border bg-surface p-3",children:[o("div",{className:"text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle mb-1.5",children:u}),o("div",{className:"space-y-1",children:l.map(p=>o(Io,{trpc:r.trpcClient,device:p,variant:"minimal",onNavigate:h=>n(`/devices/${String(h)}`)},p.id))})]})}function rl(e){return e<1e3?`${e.toFixed(0)} kbps`:`${(e/1e3).toFixed(1)} Mbps`}function IB({device:e}){const t=rt(),n=typeof e.id=="number"?e.id:null,r=String(e.type??""),s=r===pt.Camera,a=r===pt.Hub,i=e.features??[],{data:l}=fd({deviceId:n??0},{enabled:n!==null&&s,refetchInterval:5e3}),c=l?.streams??{},d=Object.entries(c),u=i.includes(Wn.DoorbellButton),p=Rd(u?{deviceId:n??void 0,historyLimit:10}:void 0),h=p.latest?Date.now()-p.latest.timestamp<3e4:!1;return f("div",{className:"space-y-5",children:[a&&n!==null&&o(x0,{deviceId:n,onOpenChild:m=>t(`/devices/${m}`)}),s&&n!==null&&o(ft,{widgetId:"pipeline-orchestrator/pipeline-quick-stats",host:"device-tab",deviceId:n}),u&&o(_d,{history:p.history,latestIsFresh:h}),s&&n!==null&&o(ft,{widgetId:"stream-broker/stream-broker-panel",host:"device-tab",deviceId:n}),s&&d.length>0&&f("div",{className:"@container rounded-lg border border-border bg-surface overflow-hidden",style:{containerType:"inline-size"},children:[o("div",{className:"border-b border-border px-4 py-2",children:o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:"Stream Network"})}),o("div",{className:"divide-y divide-border",children:d.map(([m,g])=>f("div",{className:"px-4 py-2.5",children:[f("div",{className:"flex items-center gap-2 mb-2",children:[o(or,{className:"h-3 w-3 text-foreground-subtle"}),o("span",{className:"text-[11px] font-medium text-foreground",children:m})]}),f("div",{className:"grid grid-cols-2 @[640px]:grid-cols-4 gap-2",children:[o(Ms,{label:"Nominal",value:rl(g.nominalBitrateKbps??0)}),o(Ms,{label:"Observed",value:rl(g.observedBitrateKbps??0)}),o(Ms,{label:"Peak",value:rl(g.peakBitrateKbps??0)}),o(Ms,{label:"Packet Loss",value:`${(g.packetLossPercent??0).toFixed(2)}%`,warning:(g.packetLossPercent??0)>1})]})]},m))})]}),o(cv,{})]})}function Ms({label:e,value:t,warning:n}){return f("div",{children:[o("p",{className:"text-[10px] text-foreground-subtle",children:e}),o("p",{className:`text-xs font-medium ${n?"text-warning":"text-foreground"}`,children:t})]})}function AB({schema:e,values:t,pendingKeys:n,onChange:r,onAction:s,onSave:a,onDiscard:i,disabled:l}){const c=e.tabs??[],d=H(()=>{const k=new Map;for(const C of e.sections){const E=C.tab??"general",I=k.get(E)??[];I.push(C),k.set(E,I)}return k},[e.sections]),u=new Set(c.map(k=>k.id)),p=[...c,...[...d.keys()].filter(k=>!u.has(k)).map(k=>({id:k,label:k,icon:"wrench",order:100}))],h=p[0]?.id??"general",[m,g]=_(h),b=d.get(m)??[],y={sections:b.length<=1?b.length===1?[{...b[0],title:""}]:b:b.every(C=>!C.title)?[{...b[0],title:"",fields:b.flatMap(C=>C.fields)}]:b},w=o(Pv,{pendingCount:n.length,onSave:()=>a(n),onDiscard:()=>i(n),saving:l});if(p.length<=1)return f("div",{className:"flex flex-col gap-3",children:[o(Dn,{schema:e,values:t,onChange:r,onAction:s,disabled:l}),w]});const v=new Map,N=new Map;for(const[k,C]of d){v.set(k,C.length);const E=new Set,I=z=>{for(const P of z)if("key"in P&&typeof P.key=="string"&&E.add(P.key),P.type==="group")I(P.fields);else if(P.type==="sub-tabs")for(const B of P.tabs)I(B.fields)};for(const z of C)I(z.fields);const A=n.filter(z=>E.has(z)).length;A>0&&N.set(k,A)}return f("div",{className:"flex flex-col gap-3",children:[o(_v,{tabs:p.map(k=>({id:k.id,label:k.label})),activeId:m,onChange:g,countByTab:v,pendingByTab:N}),o(Dn,{schema:y,values:t,onChange:r,onAction:s,disabled:l}),w]})}function PB(e,t){return t&&t==="admin"?e:!0}function _B(e){if(!e)return null;const n={sections:[...e.sections].sort((r,s)=>{const a=r.tab??"general",i=s.tab??"general";return a!==i?a.localeCompare(i):Do(r)&&Do(s)?r.id.localeCompare(s.id):(r.order??0)-(s.order??0)})};return e.tabs?{...n,tabs:e.tabs}:n}function Tv(e){return e.type==="separator"||e.type==="info"||e.type==="button"||e.type==="widget"||e.type==="addon-action-button"}function Lv(e){return e.key}function $B(e){if(!Tv(e))return e.value}function Rv(e){return Tv(e)?null:e}function pa(e,t){for(const n of e)if(t(n),n.type==="group")pa(n.fields,t);else if(n.type==="sub-tabs")for(const r of n.tabs)pa(r.fields,t)}function DB(e){if(!e)return{};const t={};for(const n of e.sections)pa(n.fields,r=>{const s=Lv(r);s!==null&&(t[s]=$B(r))});return t}function Mf(e,t){if(!e)return null;let n=null;for(const r of e.sections)if(pa(r.fields,s=>{if(n!==null||Lv(s)!==t)return;const a=Rv(s);a&&a.writerCapName&&a.writerAddonId&&(n={capName:a.writerCapName,addonId:a.writerAddonId})}),n!==null)break;return n}function TB(e){return{...e,fields:e.fields.map(Ov)}}function Ov(e){return e.type==="separator"||e.type==="info"||e.type==="button"||e.type==="object-array"?e:{...e,readonlyField:!0}}function LB(e,t){return e&&{...e,sections:e.sections.map(n=>({...n,fields:n.fields.map(r=>{const s=Rv(r);return s?PB(t,s.minRole)?r:Ov(r):r})}))}}function nc({deviceId:e,sectionFilter:t}){const n=ke(),{user:r}=nn(),s=r?.isAdmin===!0,a=te(!1),{data:i,isLoading:l}=cd({deviceId:e},{refetchInterval:()=>a.current?!1:2500,staleTime:6e4,enabled:Number.isFinite(e)}),{data:c}=er({deviceId:e},{staleTime:6e4,enabled:Number.isFinite(e)}),d=i?.settings??null,u=i?.live??null,p=H(()=>{if(!d&&!u)return null;const B=d?.sections??[],R=(u?.sections??[]).map(TB),M=[...B,...R],D=t?M.filter(t):M.filter(F=>F.location!=="top-tab"&&!Do(F));if(D.length===0)return null;const T=new Set;for(const F of D)T.add(F.tab??"general");const O=[...d?.tabs??[],...(u?.tabs??[]).filter(F=>!(d?.tabs??[]).some(j=>j.id===F.id))].filter(F=>T.has(F.id));return O.length>0?{tabs:O,sections:D}:{sections:D}},[d,u,t]),h=H(()=>_B(p),[p]),m=H(()=>LB(h,s),[h,s]),g=H(()=>DB(m),[m]),b=Iy(),x=ud(),y=rx({onSuccess:()=>{n.invalidateQueries({queryKey:[["deviceManager","getDeviceAggregate"]]})}}),w={isPending:y.isPending,mutate:B=>{y.mutate({deviceId:e,changes:[...B]})}},v=U(B=>{const R=Object.entries(B).map(([M,D])=>{const T=Mf(m,M);return T?{writerCapName:T.capName,writerAddonId:T.addonId,key:M,value:D}:null}).filter(M=>M!==null);R.length>0&&w.mutate(R)},[m,w]),N=U(B=>{const R=Object.entries(B).map(([M,D])=>{const T=Mf(m,M);return T?{writerCapName:T.capName,writerAddonId:T.addonId,key:M,value:D}:null}).filter(M=>M!==null);R.length>0&&w.mutate(R)},[m,w]),k=$v({schema:m,serverValues:g,onImmediateSave:v,onDeferredSave:N}),{values:C,pendingKeys:E,handleChange:I,handleSave:A,handleDiscard:z}=k;if(a.current=k.editingPaused,l)return f("div",{className:"flex items-center justify-center py-12 text-foreground-subtle",children:[o(Se,{className:"h-4 w-4 animate-spin mr-2"}),o("span",{className:"text-xs",children:"Loading device aggregate…"})]});if(!m||m.sections.length===0)return o("div",{className:"text-xs text-foreground-subtle italic py-4 text-center",children:"No aggregate contributions for this device."});async function P(B,R,M){if(B==="regenerate-rtsp-token"){const D=["rtspUrl:","regenerateToken:"].find(O=>R.startsWith(O));if(!D)throw new Error(`regenerate-rtsp-token: unrecognised key "${R}" (expected "rtspUrl:<streamId>" or "regenerateToken:<streamId>")`);const T=R.slice(D.length);if(!T)throw new Error(`regenerate-rtsp-token: key "${R}" has no streamId after prefix`);const L=`${e}/${T}`;await b.mutateAsync({brokerId:L}),n.invalidateQueries({queryKey:[["deviceManager","getDeviceAggregate"]]});return}if(B==="test-probe"){if(!c)return{status:"error",error:"Device metadata not loaded yet"};try{return await x.mutateAsync({addonId:c.addonId,type:c.type,key:R,value:M})}catch(D){return{status:"error",error:D instanceof Error?D.message:String(D)}}}if(B==="refresh-driver-data"){await y.mutateAsync({deviceId:e,changes:[{writerCapName:"device-manager",writerAddonId:"device-manager",key:R,value:Date.now()}]});return}throw new Error(`[device-aggregate] unknown action "${B}"`)}return o(AB,{schema:m,values:C,pendingKeys:E,onChange:I,onAction:P,onSave:A,onDiscard:z,disabled:w.isPending})}function RB({deviceId:e}){return o(nc,{deviceId:e})}const Bv=6e4,rc=60*Bv,Ef=24*rc;function ni(e){if(e==null||e<=0)return"—";const t=Date.now()-e;return t<0||t<3e4?"just now":t<rc?`${String(Math.floor(t/Bv))}m ago`:t<Ef?`${String(Math.floor(t/rc))}h ago`:`${String(Math.floor(t/Ef))}d ago`}function OB(e,t=new Date){const n=new Date(e);return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()}function zv({dev:e,busy:t,setBusy:n}){const r=e?.motionTrigger,s=pn(e?.state.motionTrigger),[a,i]=_(!1);if(!r)return null;const l=s?.enabled===!0,c=s!==void 0,d=async()=>{if(t||!c)return;const p=!l;n(!0),i(!0);try{await r.setMotionTrigger({enabled:p})}finally{n(!1),i(!1)}};return f("button",{type:"button",onClick:()=>{d()},disabled:t||!c,title:c?l?"Disable trigger on motion":"Enable trigger on motion":"Awaiting state…","aria-pressed":l,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${l?"border-primary/50 bg-primary/15 text-primary":"border-border bg-surface text-foreground-subtle hover:text-foreground"}`,children:[o(Xo,{className:"h-3 w-3"}),o("span",{children:a?l?"Disabling…":"Enabling…":c?l?"On motion: on":"On motion: off":"On motion: …"})]})}function Fv({deviceId:e,deviceName:t,useSiren:n=!1}){const r=Te(),s=At(r.trpcClient,e),a=pn(s?.state.switch),[i,l]=_(!1),c=a?.on??!1,d=a?.lastChangedAt??null,u=a!==void 0,p=n?Jo:ev,h=async()=>{if(!(i||!u||!s?.switch)){l(!0);try{await s.switch.setState({on:!c})}finally{l(!1)}}};return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("button",{type:"button",onClick:()=>{h()},disabled:i||!u||!s?.switch,title:u?c?`Turn off ${t}`:`Turn on ${t}`:"Awaiting state…","aria-pressed":c,className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all disabled:cursor-not-allowed disabled:opacity-50 ${c?"border-success bg-success/20 text-success shadow-lg shadow-success/20":"border-border bg-surface text-foreground-subtle hover:border-foreground-subtle hover:text-foreground"}`,children:o(p,{className:"h-10 w-10"})}),o(zv,{dev:s,busy:i,setBusy:l}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${c?"text-success":"text-foreground-subtle"}`,children:u?c?"On":"Off":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:u?`Changed ${ni(d)}`:"Awaiting state…"})]})]})}function BB({deviceId:e,deviceName:t}){const n=Te(),r=At(n.trpcClient,e),s=pn(r?.state.switch),a=pn(r?.state.brightness),i=s?.on??!1,l=s?.lastChangedAt??null,c=s!==void 0,d=a!==void 0,u=r?.brightness!==void 0,[p,h]=_(!1),[m,g]=_(a?.percentage??0);Y(()=>{a?.percentage!==void 0&&g(a.percentage)},[a?.percentage]);const b=async()=>{if(!(p||!c||!r?.switch)){h(!0);try{await r.switch.setState({on:!i})}finally{h(!1)}}},x=async()=>{if(!(p||!d||!r?.brightness)){h(!0);try{await r.brightness.setBrightness({percentage:m})}finally{h(!1)}}};return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("button",{type:"button",onClick:()=>{b()},disabled:p||!c||!r?.switch,title:c?i?`Turn off ${t}`:`Turn on ${t}`:"Awaiting state…","aria-pressed":i,className:`flex h-20 w-20 items-center justify-center rounded-full border-2 transition-all disabled:cursor-not-allowed disabled:opacity-50 ${i?"border-warning bg-warning/20 text-warning shadow-lg shadow-warning/30":"border-border bg-surface text-foreground-subtle hover:border-foreground-subtle hover:text-foreground"}`,children:o(I6,{className:"h-9 w-9"})}),u?f("div",{className:"flex w-full max-w-xs flex-col items-center gap-1",children:[o("input",{type:"range",min:0,max:100,step:1,value:m,disabled:p||!i||!d,onChange:y=>g(Number(y.currentTarget.value)),onPointerUp:()=>{x()},onKeyUp:y=>{y.key==="Enter"&&x()},"aria-label":"Brightness",className:"w-full accent-warning disabled:cursor-not-allowed disabled:opacity-50"}),o("div",{className:"text-[10px] text-foreground-subtle tabular-nums",children:d?`${String(m)}%`:"Brightness unavailable"})]}):null,o(zv,{dev:r,busy:p,setBusy:h}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${i?"text-warning":"text-foreground-subtle"}`,children:c?i?"On":"Off":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:c?`Changed ${ni(l)}`:"Awaiting state…"})]})]})}function zB({deviceId:e}){const t=Te(),n=At(t.trpcClient,e),r=pn(n?.state.motion),s=r?.detected??!1,a=r?.lastDetectedAt??null,i=r!==void 0;return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("div",{className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all ${s?"border-danger bg-danger/20 text-danger shadow-lg shadow-danger/30 animate-pulse":"border-border bg-surface text-foreground-subtle"}`,"aria-live":"polite",title:s?"Motion detected":"Idle",children:s?o(iO,{className:"h-10 w-10"}):o(Xo,{className:"h-10 w-10"})}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${s?"text-danger":"text-foreground-subtle"}`,children:i?s?"Triggered":"Idle":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:i?`Last trip ${ni(a)}`:"Awaiting state…"})]})]})}function FB({deviceId:e}){const t=Te(),n=At(t.trpcClient,e),r=pn(n?.state.doorbell),s=r?.lastPressedAt??null,a=r!==void 0,i=s!==null&&Date.now()-s<6e4,[l,c]=_(0),[d,u]=_(null);return Y(()=>{s===null||s===d||(u(s),OB(s)&&c(p=>p+1))},[s,d]),f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("div",{className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all ${i?"border-primary bg-primary/20 text-primary shadow-lg shadow-primary/30 animate-pulse":"border-border bg-surface text-foreground-subtle"}`,"aria-live":"polite",title:i?"Just pressed":"Idle",children:o(Jo,{className:"h-10 w-10"})}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${i?"text-primary":"text-foreground-subtle"}`,children:a?`Last press ${ni(s)}`:"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5 tabular-nums",children:a?`${String(l)} ring${l===1?"":"s"} today`:"Awaiting state…"})]})]})}function jB({deviceName:e,deviceType:t,provider:n,isOnline:r,features:s}){return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-border bg-surface p-6 text-center",children:[o(gn,{type:n,size:"lg"}),f("div",{children:[o("div",{className:"text-sm font-semibold text-foreground",children:e}),o("div",{className:"text-[10px] text-foreground-subtle uppercase tracking-wider mt-0.5",children:t})]}),f("div",{className:"flex items-center gap-2 flex-wrap justify-center",children:[o(ti,{status:r?"online":"offline"}),s.length>0&&o(Ja,{capabilities:s})]}),o("div",{className:"text-[10px] text-foreground-subtle italic max-w-xs mt-1",children:"No live view for this device type. Use the Config tab or the shortcut row to interact."})]})}function VB({deviceId:e}){const t=ke(),n=Hb({deviceId:e},{refetchInterval:1e4,retry:!1}),r=qb({onSuccess:()=>{t.invalidateQueries({queryKey:[["deviceDiscovery","listDiscovered"]]}),t.invalidateQueries({queryKey:[["deviceDiscovery","getStatus"]]})}}),s=H(()=>HB(n.data??[]),[n.data]);return f("div",{className:"flex h-full w-full flex-col gap-3 p-3 sm:p-4",children:[f("div",{className:"flex flex-wrap items-stretch gap-2 sm:gap-3",children:[o(ol,{label:"Discovered",value:s.total,icon:o($n,{className:"h-3.5 w-3.5"})}),o(ol,{label:"Adopted",value:s.adopted,accent:"success"}),o(ol,{label:"Available",value:s.available,accent:s.available>0?"primary":void 0}),f("button",{type:"button",onClick:()=>{r.mutateAsync({deviceId:e}).catch(()=>{})},disabled:r.isPending,className:"inline-flex items-center justify-center gap-1.5 rounded-lg border border-border px-3 py-2 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50 self-stretch shrink-0",children:[r.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(ct,{className:"h-3.5 w-3.5"}),o("span",{className:"hidden sm:inline",children:"Discover"})]})]}),f("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-foreground-subtle border-t border-border-subtle pt-2",children:[o(Es,{icon:o(or,{className:"h-3 w-3 text-emerald-500"}),label:`${s.online} online`}),o(Es,{icon:o(Z0,{className:"h-3 w-3 text-amber-500"}),label:`${s.sleeping} sleeping`}),o(Es,{icon:o(av,{className:"h-3 w-3 text-destructive"}),label:`${s.offline} offline`}),s.unknown>0?o(Es,{icon:o(GR,{className:"h-3 w-3 text-foreground-subtle"}),label:`${s.unknown} unknown`}):null]})]})}function HB(e){const t={total:e.length,adopted:0,available:0,online:0,sleeping:0,offline:0,unknown:0};for(const n of e)n.alreadyAdopted?t.adopted+=1:t.available+=1,t[n.status]+=1;return t}function ol({label:e,value:t,icon:n,accent:r}){return f("div",{className:`flex flex-1 basis-[140px] min-w-0 flex-col gap-1 rounded-lg border px-2 py-1.5 sm:px-3 sm:py-2 ${r==="success"?"bg-emerald-500/10 border-emerald-500/30 text-emerald-500":r==="primary"?"bg-primary/10 border-primary/30 text-primary":"bg-surface-hover border-border text-foreground"}`,children:[f("div",{className:"flex items-center gap-1.5 text-[10px] uppercase tracking-wider opacity-70 truncate",children:[n,o("span",{className:"truncate",children:e})]}),o("div",{className:"text-xl sm:text-2xl font-semibold tabular-nums leading-none",children:t})]})}function Es({icon:e,label:t}){return f("span",{className:"inline-flex items-center gap-1",children:[e,o("span",{children:t})]})}const qB=e=>o(Fv,{...e,useSiren:!0}),UB={[pt.Switch]:Fv,[pt.Siren]:qB,[pt.Light]:BB,[pt.Sensor]:zB,[pt.Button]:FB,[pt.Hub]:VB};function QB(e){const t=UB[e.deviceType]??jB;return o(t,{...e})}function eu(e){if(e<60)return`${Math.round(e)}s`;const t=Math.floor(e/60),n=Math.round(e%60);if(t<60)return n>0?`${t}m ${n}s`:`${t}m`;const r=Math.floor(t/60),s=t%60;return s>0?`${r}h ${s}m`:`${r}h`}function fa(e){return new Date(e).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function ha(e){return e.toISOString().slice(0,10)}function GB(e,t){return ha(e)===ha(t)}function fo(e){const t=new Date(e);return t.setHours(0,0,0,0),t}function KB(e){const t=new Date(e);return t.setHours(23,59,59,999),t}function Tt({className:e=""}){return o("div",{className:`animate-pulse rounded bg-foreground-subtle/10 ${e}`})}function Un(){return f("div",{className:"flex items-center gap-3 px-4 py-3",children:[o(Tt,{className:"h-4 w-4"}),o(Tt,{className:"h-3 w-24"}),o(Tt,{className:"h-3 w-16 ml-auto"})]})}function io({children:e,actions:t}){return f("div",{className:"border-b border-border px-4 py-2.5 flex items-center justify-between",children:[o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:e}),t]})}function If({icon:e,label:t,value:n}){return f("div",{className:"flex items-center gap-2",children:[o(e,{className:"h-3.5 w-3.5 text-foreground-subtle flex-shrink-0"}),f("div",{className:"min-w-0",children:[o("p",{className:"text-[10px] text-foreground-subtle leading-tight",children:t}),o("p",{className:"text-xs font-medium text-foreground leading-tight",children:n})]})]})}function WB({segments:e,selectedDate:t}){const n=fo(t).getTime(),r=1440*60*1e3,s=Array.from({length:25},(a,i)=>i);return f("div",{className:"space-y-1",children:[o("div",{className:"flex justify-between px-0.5",children:s.filter(a=>a%3===0).map(a=>o("span",{className:"text-[9px] text-foreground-subtle font-mono",children:String(a).padStart(2,"0")},a))}),f("div",{className:"relative h-6 rounded bg-background border border-border overflow-hidden",children:[e.map(a=>{const i=new Date(a.startTime).getTime()-n,l=new Date(a.endTime).getTime()-n,c=Math.max(0,i/r*100),d=Math.min(100-c,(l-i)/r*100);return d<=0?null:o("div",{className:"absolute top-0 bottom-0 bg-primary/60 hover:bg-primary/80 transition-colors",style:{left:`${c}%`,width:`${Math.max(d,.3)}%`},title:`${fa(a.startTime)} - ${fa(a.endTime)} (${eu(a.duration)})`},a.id)}),s.slice(1,-1).map(a=>o("div",{className:"absolute top-0 bottom-0 w-px bg-border/50",style:{left:`${a/24*100}%`}},a))]})]})}function YB({segment:e,selected:t,onToggle:n,onPlay:r,onDownload:s,onDelete:a}){return f("div",{className:`flex items-center gap-3 px-4 py-2 border-b border-border last:border-b-0 hover:bg-background/50 transition-colors ${t?"bg-primary/5":""}`,children:[o("button",{onClick:n,className:"flex-shrink-0 text-foreground-subtle hover:text-foreground",children:t?o(rv,{className:"h-4 w-4 text-primary"}):o(ts,{className:"h-4 w-4"})}),f("div",{className:"flex-1 min-w-0",children:[f("p",{className:"text-xs font-mono text-foreground",children:[fa(e.startTime)," - ",fa(e.endTime)]}),f("p",{className:"text-[10px] text-foreground-subtle",children:[eu(e.duration),e.sizeBytes!=null&&` · ${It(e.sizeBytes)}`]})]}),f("div",{className:"flex items-center gap-1 flex-shrink-0",children:[o("button",{onClick:r,title:"Play",className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Ya,{className:"h-3.5 w-3.5"})}),o("button",{onClick:s,title:"Download",className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Xt,{className:"h-3.5 w-3.5"})}),o("button",{onClick:a,title:"Delete",className:"p-1 rounded hover:bg-danger/10 text-foreground-subtle hover:text-danger transition-colors",children:o(Ze,{className:"h-3.5 w-3.5"})})]})]})}function ZB({deviceId:e}){const t=ke(),[n,r]=_(()=>fo(new Date)),[s,a]=_(new Set),i=Sy({deviceId:e},{refetchInterval:5e3}),l=wy({deviceId:e}),c=l.data?.streams[0]?.streamId??"stream0",d=Ny({deviceId:e,streamId:c,startTime:fo(n).getTime(),endTime:KB(n).getTime()}),u=ky({deviceId:e,streamId:c},{refetchInterval:3e4}),p=Cy({deviceId:e,dataCategory:"recording:main"}),h=U(()=>{t.invalidateQueries({queryKey:["recordingEngine","getPolicyStatus"]}),t.invalidateQueries({queryKey:["recordingEngine","getSegments"]}),t.invalidateQueries({queryKey:["recordingEngine","getStorageUsage"]})},[t]),m=yy({onSuccess:h}),g={isPending:m.isPending,error:m.error,mutate:()=>{const T=l.data,L=T?{mode:T.mode,streams:T.streams,enabled:!0,preBufferSec:T.preBufferSec,postBufferSec:T.postBufferSec,scheduleRules:T.scheduleRules}:{mode:"continuous",streams:[{streamId:c,mode:"always"}],enabled:!0,preBufferSec:10,postBufferSec:5};m.mutate({deviceId:e,policy:L})}},b=vy({onSuccess:h}),x=i.data??void 0,y=l.data??void 0,w=d.data??[],v=u.data,N=p.data??void 0,k=(x?.enabled??!1)&&(x?.activeStreams??0)>0,C=g.isPending||b.isPending,E=GB(n,new Date),I=H(()=>[...w].sort((T,L)=>new Date(L.startTime).getTime()-new Date(T.startTime).getTime()),[w]),A=H(()=>w.reduce((T,L)=>T+(L.duration??0),0),[w]),z=H(()=>w.reduce((T,L)=>T+(L.sizeBytes??0),0),[w]);function P(){k?b.mutate({deviceId:e}):g.mutate()}function B(){r(T=>{const L=new Date(T);return L.setDate(L.getDate()-1),fo(L)}),a(new Set)}function R(){E||(r(T=>{const L=new Date(T);return L.setDate(L.getDate()+1),fo(L)}),a(new Set))}function M(T){a(L=>{const O=new Set(L);return O.has(T)?O.delete(T):O.add(T),O})}function D(){s.size===I.length?a(new Set):a(new Set(I.map(T=>T.id)))}return i.isLoading&&l.isLoading?f("div",{className:"space-y-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Recording Status"}),f("div",{className:"px-4 py-4 space-y-3",children:[o(Tt,{className:"h-10 w-full"}),o(Tt,{className:"h-4 w-48"})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Segments"}),f("div",{className:"divide-y divide-border",children:[o(Un,{}),o(Un,{}),o(Un,{})]})]})]}):f("div",{className:"space-y-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Recording Status"}),f("div",{className:"px-4 py-4 flex items-center justify-between gap-4",children:[f("div",{className:"flex items-center gap-3 min-w-0",children:[o("div",{className:`flex items-center justify-center rounded-full p-2 flex-shrink-0 ${k?"bg-danger/10":"bg-foreground-subtle/10"}`,children:o(U0,{className:`h-5 w-5 ${k?"text-danger animate-pulse":"text-foreground-subtle"}`})}),f("div",{className:"min-w-0",children:[o("p",{className:`text-sm font-medium ${k?"text-danger":"text-foreground-subtle"}`,children:k?"Recording":"Not Recording"}),o("p",{className:"text-[11px] text-foreground-subtle mt-0.5 truncate",children:k&&x?`${x.mode} – ${x.activeStreams} stream(s)`:"No active recording session"})]})]}),o("button",{onClick:P,disabled:C,className:`inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors flex-shrink-0 disabled:opacity-50 ${k?"bg-danger/10 text-danger hover:bg-danger/20":"bg-primary text-primary-foreground hover:bg-primary/90"}`,children:k?f(me,{children:[o(ts,{className:"h-3.5 w-3.5"}),C?"Stopping...":"Stop Recording"]}):f(me,{children:[o(Ya,{className:"h-3.5 w-3.5"}),C?"Starting...":"Start Recording"]})})]}),k&&x&&f("div",{className:"border-t border-border px-4 py-2 flex items-center gap-2 text-[11px] text-foreground-subtle",children:[o(yo,{className:"h-3.5 w-3.5 text-primary flex-shrink-0"}),f("span",{children:[x.activeStreams," active stream",x.activeStreams!==1?"s":""," · mode: ",x.mode]})]})]}),f("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:f("span",{className:"flex items-center gap-1.5",children:[o(Jt,{className:"h-3.5 w-3.5"}),"Settings"]})}),l.isLoading?f("div",{className:"px-4 py-3 space-y-2",children:[o(Tt,{className:"h-3 w-32"}),o(Tt,{className:"h-3 w-40"}),o(Tt,{className:"h-3 w-28"})]}):f("div",{className:"divide-y divide-border",children:[o(lo,{label:"Stream",value:c}),o(lo,{label:"Pre-buffer",value:y?`${y.preBufferSec}s`:"N/A"}),o(lo,{label:"Mode",value:y?.mode??"continuous"}),o(lo,{label:"Retention",value:N?.retentionDays!=null?`${N.retentionDays} days`:"N/A"}),N?.retentionGb!=null&&o(lo,{label:"Max Storage",value:`${N.retentionGb} GB`})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:f("span",{className:"flex items-center gap-1.5",children:[o(ia,{className:"h-3.5 w-3.5"}),"Storage"]})}),u.isLoading?f("div",{className:"px-4 py-3 space-y-2",children:[o(Tt,{className:"h-3 w-28"}),o(Tt,{className:"h-3 w-36"}),o(Tt,{className:"h-3 w-24"})]}):u.error?f("div",{className:"px-4 py-4 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4"}),"Failed to load storage info"]}):f("div",{className:"px-4 py-3 grid grid-cols-2 gap-3",children:[o(If,{icon:ia,label:"Total",value:v?.totalBytes!=null?It(v.totalBytes):"N/A"}),o(If,{icon:yo,label:"Segments",value:v?.segmentCount!=null?String(v.segmentCount):"N/A"})]})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"border-b border-border px-4 py-2.5 flex items-center justify-between",children:[o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:"Segment Browser"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:B,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Gd,{className:"h-4 w-4"})}),f("div",{className:"flex items-center gap-1.5 text-xs text-foreground font-medium",children:[o(H0,{className:"h-3.5 w-3.5 text-foreground-subtle"}),E?"Today":ha(n)]}),o("button",{onClick:R,disabled:E,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors disabled:opacity-30 disabled:cursor-not-allowed",children:o(wt,{className:"h-4 w-4"})})]})]}),f("div",{className:"px-4 py-3 border-b border-border",children:[o(WB,{segments:w,selectedDate:n}),f("div",{className:"flex items-center gap-4 mt-2 text-[10px] text-foreground-subtle",children:[f("span",{children:[w.length," segment",w.length!==1?"s":""]}),A>0&&f("span",{children:[eu(A)," recorded"]}),z>0&&o("span",{children:It(z)})]})]}),I.length>0&&f("div",{className:"border-b border-border px-4 py-2 flex items-center justify-between",children:[o("button",{onClick:D,className:"text-[11px] text-foreground-subtle hover:text-foreground transition-colors",children:s.size===I.length?"Deselect All":"Select All"}),s.size>0&&f("div",{className:"flex items-center gap-2",children:[f("span",{className:"text-[10px] text-foreground-subtle",children:[s.size," selected"]}),f("button",{className:"inline-flex items-center gap-1 rounded px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",title:"Download selected",children:[o(Xt,{className:"h-3 w-3"}),"Download"]}),f("button",{className:"inline-flex items-center gap-1 rounded px-2 py-0.5 text-[10px] font-medium bg-danger/10 text-danger hover:bg-danger/20 transition-colors",title:"Delete selected",children:[o(Ze,{className:"h-3 w-3"}),"Delete"]})]})]}),d.isLoading?f("div",{className:"divide-y divide-border",children:[o(Un,{}),o(Un,{}),o(Un,{}),o(Un,{})]}):I.length===0?f("div",{className:"flex flex-col items-center justify-center py-12 text-foreground-subtle",children:[o(yo,{className:"h-8 w-8 mb-3 opacity-30"}),o("p",{className:"text-sm",children:"No recorded segments"}),o("p",{className:"text-xs mt-1 opacity-70",children:E?"Recorded clips will appear here as they are created":`No recordings found for ${ha(n)}`})]}):o("div",{className:"max-h-[400px] overflow-y-auto",children:I.map(T=>o(YB,{segment:T,selected:s.has(T.id),onToggle:()=>M(T.id),onPlay:()=>{},onDownload:()=>{},onDelete:()=>{}},T.id))})]}),i.error&&f("div",{className:"rounded-lg border border-danger/30 bg-danger/5 px-4 py-3 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4 flex-shrink-0"}),"Failed to load recording status. Will retry automatically."]}),(g.error||b.error)&&f("div",{className:"rounded-lg border border-danger/30 bg-danger/5 px-4 py-3 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4 flex-shrink-0"}),g.error?`Failed to start recording: ${g.error instanceof Error?g.error.message:"Unknown error"}`:`Failed to stop recording: ${b.error instanceof Error?b.error.message:"Unknown error"}`]})]})}function lo({label:e,value:t}){return f("div",{className:"flex items-center justify-between px-4 py-2.5",children:[o("span",{className:"text-xs text-foreground-subtle",children:e}),o("span",{className:"text-xs font-medium text-foreground",children:t})]})}function XB({deviceId:e}){const t=ke(),n=Number.isFinite(e),{data:r}=er({deviceId:e},{enabled:n}),s=typeof r?.type=="string"?r.type:"camera";St(["deviceManager","getBindings"],["capability.binding-changed"]);const{data:a,isLoading:i,isError:l,error:c}=ex({deviceId:e},{staleTime:3e4,enabled:n}),{data:d}=nx({deviceType:s},{staleTime:3e4,enabled:!!s}),u=tx({onSuccess:()=>{t.invalidateQueries({queryKey:[["deviceManager","getBindings"]]})}});if(i)return o("div",{className:"p-4",children:o("div",{className:"h-20 rounded-lg border border-border bg-surface animate-pulse"})});if(l)return f("div",{className:"p-4 text-xs text-red-400",children:["Failed to load bindings: ",c instanceof Error?c.message:String(c)]});const p=new Map,h={};for(const b of d??[])h[b.capName]=b.wrappers;for(const b of a?.entries??[])p.set(b.capName,{...b,wrappers:h[b.capName]??[]});for(const b of d??[])p.has(b.capName)||p.set(b.capName,{capName:b.capName,kind:"unbound",providerAddonId:"",providerNodeId:"",nativeAddonId:"",wrappers:b.wrappers});const m=[...p.values()].sort((b,x)=>b.capName.localeCompare(x.capName));if(m.length===0)return f("div",{className:"flex flex-col items-center justify-center gap-2 p-8 text-foreground-subtle",children:[o(Wa,{className:"h-8 w-8 opacity-40"}),o("p",{className:"text-xs",children:"No capability providers applicable to this device yet."}),o("p",{className:"text-[10px] opacity-60",children:"Native providers show up here as soon as the owning addon registers them."})]});const g=m.filter(b=>b.kind!=="unbound").length;return f("div",{className:"flex flex-col gap-3 p-1",children:[f("div",{className:"text-[11px] text-foreground-subtle",children:[o("span",{className:"font-medium text-foreground",children:g})," ","of ",m.length," capabilit",m.length===1?"y":"ies"," bound — rows marked ",o("em",{children:"unbound"})," have a wrapper available you can activate."]}),o("div",{className:"overflow-hidden rounded-lg border border-border bg-surface",children:f("table",{className:"w-full border-collapse text-[11px]",children:[o("thead",{children:f("tr",{className:"bg-surface-hover/50 text-left text-[10px] uppercase tracking-wide text-foreground-subtle",children:[o("th",{className:"px-3 py-2 font-medium",children:"Capability"}),o("th",{className:"px-3 py-2 font-medium",children:"Kind"}),o("th",{className:"px-3 py-2 font-medium",children:"Active Provider"}),o("th",{className:"px-3 py-2 font-medium",children:"Node"}),o("th",{className:"px-3 py-2 font-medium",children:"Native"}),o("th",{className:"px-3 py-2 font-medium",children:"Wrapper"})]})}),o("tbody",{children:m.map(b=>{const x=b.kind==="wrapped"?b.providerAddonId:null;return f("tr",{className:"border-t border-border align-middle",children:[o("td",{className:"px-3 py-2 font-mono text-foreground",children:b.capName}),o("td",{className:"px-3 py-2",children:o(JB,{kind:b.kind})}),o("td",{className:"px-3 py-2 font-mono text-foreground-subtle",children:b.providerAddonId||o("span",{className:"opacity-40",children:"—"})}),o("td",{className:"px-3 py-2",children:b.providerNodeId?o(ez,{nodeId:b.providerNodeId}):o("span",{className:"text-[10px] opacity-40",children:"—"})}),o("td",{className:"px-3 py-2 font-mono text-foreground-subtle",children:b.nativeAddonId||o("span",{className:"opacity-40",children:"—"})}),o("td",{className:"px-3 py-2",children:o(tz,{wrappers:b.wrappers,activeWrapperId:x,disabled:u.isPending,onPick:y=>{const w=x===y;u.mutate({deviceId:e,capName:b.capName,wrapperAddonId:y,active:!w})}})})]},b.capName)})})]})})]})}function JB({kind:e}){return e==="native"?f("span",{className:"inline-flex items-center gap-1 rounded-md border border-success/30 text-success bg-success/5 px-1.5 py-0.5 text-[10px] font-medium",children:[o(hn,{className:"h-3 w-3"}),"native"]}):e==="wrapped"?f("span",{className:"inline-flex items-center gap-1 rounded-md border border-primary/30 text-primary bg-primary/5 px-1.5 py-0.5 text-[10px] font-medium",children:[o(C6,{className:"h-3 w-3"}),"wrapped"]}):f("span",{className:"inline-flex items-center gap-1 rounded-md border border-border text-foreground-subtle/70 px-1.5 py-0.5 text-[10px] font-medium",children:[o(H6,{className:"h-3 w-3"}),"unbound"]})}function ez({nodeId:e}){return o("span",{className:`inline-flex items-center rounded-md border border-border px-1.5 py-0.5 font-mono text-[10px] ${e==="hub"?"text-foreground-subtle":"text-foreground"}`,children:e})}function tz({wrappers:e,activeWrapperId:t,disabled:n,onPick:r}){return e.length===0?o("span",{className:"text-[10px] opacity-40",children:"none available"}):o("div",{className:"flex flex-wrap gap-1",children:e.map(s=>{const a=s===t;return f("button",{disabled:n,onClick:()=>r(s),title:a?"Click to deactivate (revert to native)":`Activate wrapper ${s}`,className:`inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 font-mono text-[10px] transition-colors disabled:opacity-50 ${a?"border-primary/40 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[a?o(_t,{className:"h-3 w-3"}):o(tv,{className:"h-3 w-3"}),s]},s)})})}function nz(e,t){if(!e)return null;for(const n of e.slots)for(const r of n.addons)if(r.id===t)return r;return null}function rz(e,t,n){const r=e?.stepOverridesByAgent?.[t]?.[n];if(r)return r.enabled===!1?"off":(r.enabled===!0,"on");const s=e?.stepToggles?.[n];return s===!1?"off":s===!0?"on":"inherit"}function oz({agents:e,currentAgent:t,onPick:n}){const[r,s]=_(!1);return f("div",{className:"relative",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:()=>s(a=>!a),children:"Mirror from ▾"}),r&&o("div",{className:"absolute top-full left-0 mt-1 min-w-[140px] bg-surface border border-border rounded shadow-lg z-10",children:e.filter(a=>a!==t).map(a=>o("button",{type:"button",className:"w-full text-left px-3 py-1.5 text-xs hover:bg-muted",onClick:()=>{s(!1),n(a)},children:a},a))})]})}function sz({deviceId:e,refreshToken:t}){const n=ke(),[r,s]=_(null),[a,i]=_(null),[l,c]=_(null),[d,u]=_(null),p=gd({deviceId:e}),h=Yr(),m=Fa({deviceId:e}),g=Yx(),b=H(()=>{const D=m.data?.agentNodeId;if(D)return D;const T=g.data?.find(L=>L.online)?.nodeId;return T||"hub"},[m.data?.agentNodeId,g.data]),x=a??b,y=Wo({nodeId:x??""},{enabled:!!x}),w=ly({onSuccess:()=>{n.invalidateQueries({queryKey:[["pipelineOrchestrator","getCameraSettings"]]}),c(null)}}),v=H(()=>y.data?Ta(y.data):[],[y.data]),N=H(()=>{const D=p.data??null,T={};for(const L of h.data??[])for(const O of Object.keys(L.settings.addonDefaults)){const F=T[O]??[];F.push({agentNodeId:L.nodeId,state:rz(D,L.nodeId,O)}),T[O]=F}return T},[p.data,h.data]),k=r?nz(y.data??null,r):null,C=x?h.data?.find(D=>D.nodeId===x)??null:null,E=r&&C?C.settings.addonDefaults[r]??null:null,I=r&&x?p.data?.stepOverridesByAgent?.[x]?.[r]??null:null,A=y.data?.selectedEngine.format??"coreml",z=D=>{i(D),c(null),u(null)},P=D=>{s(D),c(null),u(null)},B=D=>{if(!x||!r||!y.data||!h.data)return;const T=h.data.find(F=>F.nodeId===D),L=h.data.find(F=>F.nodeId===x);if(!T||!L)return;const[O]=Vm({source:{nodeId:T.nodeId,engine:{format:A},defaults:T.settings.addonDefaults},target:{nodeId:L.nodeId,engine:{format:A},defaults:L.settings.addonDefaults},catalog:y.data,addonIds:[r]});if(!O){u("no mirror result");return}if(O.outcome==="skip"){u(`skipped: ${O.reason??"no candidate"}`);return}c(O.patch),u(`${O.outcome} from ${D}`)},R=()=>{!x||!r||w.mutate({deviceId:e,agentNodeId:x,addonId:r,patch:l})},M=()=>{!x||!r||w.mutate({deviceId:e,agentNodeId:x,addonId:r,patch:null})};return h.isLoading||y.isLoading?o("div",{className:"text-xs text-foreground-subtle animate-pulse p-4",children:"Loading pipeline…"}):y.data?o("div",{className:"@container h-full",style:{containerType:"inline-size"},children:f("div",{className:"flex flex-col @[720px]:flex-row h-full",children:[o("aside",{className:"w-full @[720px]:w-[300px] @[720px]:flex-shrink-0 border-b @[720px]:border-b-0 @[720px]:border-r border-border overflow-y-auto max-h-[40vh] @[720px]:max-h-none",children:o(Lg,{tree:v,selectedAddonId:r,onSelect:P,agentDots:N})}),o("section",{className:"flex-1 min-w-0 p-4 overflow-y-auto",children:!r||!k?o("div",{className:"text-sm text-foreground-subtle",children:"Select a step on the left to configure it for this camera."}):f("div",{className:"space-y-4",children:[f("div",{children:[o("div",{className:"text-[10px] uppercase tracking-widest text-foreground-subtle",children:"Selected step"}),o("div",{className:"text-base font-semibold",children:k.name})]}),f("div",{className:"flex items-end gap-3 flex-wrap",children:[f("div",{children:[o("div",{className:"text-[10px] uppercase tracking-widest text-foreground-subtle mb-1",children:"Agent"}),o("div",{className:"flex rounded border border-border overflow-hidden",children:(h.data??[]).map(D=>o("button",{type:"button",onClick:()=>z(D.nodeId),className:`px-3 py-1 text-xs ${x===D.nodeId?"bg-primary text-primary-foreground":"bg-surface hover:bg-muted"}`,children:D.nodeId},D.nodeId))})]}),o(oz,{agents:(h.data??[]).map(D=>D.nodeId),currentAgent:x,onPick:B}),d&&o("div",{className:"text-[10px] text-foreground-subtle",children:d})]}),E&&o(Ra,{mode:"device",addon:k,agentDefault:E,agentNodeId:x??"",currentPatch:l??I,engineFormat:A,onChangePatch:c}),f("div",{className:"flex items-center justify-between gap-2 pt-4 border-t border-border",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted text-foreground-subtle",disabled:!I||w.isPending,onClick:M,children:"Clear override"}),f("div",{className:"flex items-center gap-2",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:()=>c(null),children:"Reset draft"}),o("button",{type:"button",className:"px-3 py-1 text-xs bg-primary text-primary-foreground rounded disabled:opacity-50",disabled:!x||!r||w.isPending,onClick:R,children:w.isPending?"Saving…":"Save"})]})]})]})})]})}):o("div",{className:"text-xs text-foreground-subtle p-4",children:"Catalog unavailable."})}const az=[{id:"overview",label:"Overview",cameraOnly:!1},{id:"config",label:"Config",cameraOnly:!1},{id:"pipeline",label:"Pipeline",cameraOnly:!0},{id:"bindings",label:"Bindings",cameraOnly:!0},{id:"recording",label:"Recording",cameraOnly:!0}];function iz(e){const t=e===pt.Camera;return az.filter(n=>t||!n.cameraOnly).map(({id:n,label:r})=>({id:n,label:r}))}const lz=[{id:"logs",icon:at,label:"Logs"},{id:"repl",icon:ov,label:"REPL"},{id:"events",icon:Jo,label:"Events"},{id:"state",icon:Q0,label:"State"},{id:"ptz",icon:K6,label:"PTZ",featureGate:Wn.PanTiltZoom}];function cz(){const e=zd(),t=Number(e.deviceId),n=Number.isFinite(t),r=rt(),s=ke(),a=nt(),i=Te(),[l,c]=_("overview"),[d,u]=_("logs"),p="device-detail.left-col-width-px",[h,m]=_(()=>{if(typeof window>"u")return null;const de=window.localStorage.getItem(p),ce=de?Number(de):NaN;return Number.isFinite(ce)&&ce>0?ce:null}),g=te(h);g.current=h;function b(de){de.preventDefault();const ce=de.clientX,Ce=de.currentTarget.previousElementSibling?.getBoundingClientRect().width??h??0,pe=280,$e=Math.max(pe+50,Math.floor(window.innerWidth*.7)),Ae=dt=>{const yr=Math.max(pe,Math.min($e,Ce+(dt.clientX-ce)));m(yr)},Xe=()=>{document.removeEventListener("mousemove",Ae),document.removeEventListener("mouseup",Xe);const dt=g.current;if(dt!==null)try{window.localStorage.setItem(p,String(Math.round(dt)))}catch{}document.body.style.userSelect="",document.body.style.cursor=""};document.body.style.userSelect="none",document.body.style.cursor="col-resize",document.addEventListener("mousemove",Ae),document.addEventListener("mouseup",Xe)}const{data:x,isLoading:y,isError:w}=er({deviceId:t},{enabled:n,refetchInterval:5e3,retry:1}),{data:v}=cd({deviceId:t},{enabled:n,staleTime:3e4}),N=H(()=>{const de=v?.settings?.sections??[],ce=v?.live?.sections??[],Ce=[...de,...ce],pe=new Set;for(const Ae of Ce)Ae.location==="top-tab"&&Ae.tab&&pe.add(Ae.tab);return Ce.some(Do)&&pe.add(tl),[...pe].map(Ae=>{if(Ae===tl)return{id:Ae,label:pB,isAddonContrib:!0};const Xe=Nl[Ae];return{id:Ae,label:Xe?.label??Ae,isAddonContrib:!0}})},[v]),k=x,C=String(k?.name??e.deviceId??"Device"),E=k?.online===!0,I=E?"online":"offline",A=String(k?.addonId??"rtsp"),z=k?.features??[],P=k?.type,B=P===pt.Camera,R=typeof k?.parentDeviceId=="number"?k.parentDeviceId:null,{data:M}=er({deviceId:R??0},{enabled:R!==null,staleTime:3e4}),D=hr(),T=H(()=>[...iz(P),...N],[P,N]),{data:L}=Mv(n?t:0),O=(L??[]).length>0,F=H(()=>lz.filter(({featureGate:de})=>!de||z.includes(de)),[z]),{data:j}=lx({addonId:A},{enabled:!!A&&A!=="rtsp"}),V=Jb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]}),r(j?.id?`/integrations/${j.id}`:"/integrations")}}),$=Zb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),q=Xb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),G=xy(),Z=Ko({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),oe=z.includes(Wn.Rebootable),ne=z.includes(Wn.BatteryOperated),X=Yc(i.trpcClient,ne&&n?t:null),[re,be]=_(!1),J=At(i.trpcClient,n?t:null),W=async()=>{if(!(re||!J)){be(!0);try{await J.snapshot?.invalidateCache({});const de=await J.snapshot?.getSnapshot({});if(!de)return;const ce=`data:${de.contentType};base64,${de.base64}`,Ce=de.contentType.includes("png")?"png":"jpg",pe=C.replace(/[^a-zA-Z0-9_.-]+/g,"_"),$e=new Date().toISOString().replace(/[:.]/g,"-"),Ae=document.createElement("a");Ae.href=ce,Ae.download=`${pe}-${$e}.${Ce}`,document.body.appendChild(Ae),Ae.click(),document.body.removeChild(Ae)}finally{be(!1)}}},ee=$.isPending||q.isPending,{data:ae}=Fa({deviceId:t},{enabled:n,refetchInterval:1e4}),fe=ae?.agentNodeId??null,Q=typeof fe=="string"&&fe.length>0&&!fe.startsWith("addon:")?fe:void 0,{data:le}=bd({deviceId:t,...Q?{nodeId:Q}:{}},{enabled:n,refetchInterval:3e3,retry:!1});function ue(){if(!n)return null;switch(l){case"overview":return o(IB,{device:k??{}});case"config":return o(RB,{deviceId:t});case"pipeline":return o(sz,{deviceId:t,refreshToken:0});case"bindings":return o(XB,{deviceId:t});case"recording":return o(ZB,{deviceId:t});default:{const de=l;return N.some(Ce=>Ce.id===de)?de===tl?o(nc,{deviceId:t,sectionFilter:Do}):o(nc,{deviceId:t,sectionFilter:Ce=>Ce.location==="top-tab"&&Ce.tab===de}):null}}}return n?y?f("div",{className:"flex flex-col h-full",children:[f("div",{className:"border-b border-border bg-surface px-6 py-4",children:[o("div",{className:"h-4 w-48 rounded bg-surface-hover animate-pulse mb-3"}),o("div",{className:"h-8 w-64 rounded bg-surface-hover animate-pulse"})]}),o("div",{className:"flex-1 p-6",children:o("div",{className:"h-40 rounded-lg border border-border bg-surface animate-pulse"})})]}):w||!x?f("div",{className:"flex flex-col items-center justify-center h-full gap-3 text-foreground-subtle",children:[o("p",{className:"text-lg font-semibold text-foreground",children:"Device not found"}),f("p",{className:"text-xs",children:["No device with ID ",f("code",{className:"font-mono bg-surface px-1.5 py-0.5 rounded text-[11px]",children:["#",t]})]}),o("button",{onClick:()=>r("/integrations"),className:"mt-2 rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",children:"Back to Integrations"})]}):f("div",{className:"absolute inset-0 flex flex-col overflow-hidden",children:[f("div",{className:"border-b border-border bg-surface px-6 py-3 flex-shrink-0",children:[o("div",{className:"mb-2",children:o(Hc,{items:[{label:"Integrations",onClick:()=>r("/integrations")},{label:j?.name??A,onClick:()=>j?.id&&r(`/integrations/${j.id}`)},{label:C}]})}),f("div",{className:"flex items-center gap-2 sm:gap-3",children:[o(gn,{type:A,size:"lg"}),f("div",{className:"min-w-0 flex-1",children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("h1",{className:"text-sm sm:text-base font-semibold text-foreground truncate",children:C}),o(ti,{status:I}),ne&&o(Xc,{status:X,variant:"full"})]}),R!==null&&M&&f("button",{type:"button",onClick:()=>r(`/devices/${R}`),className:"text-[10px] text-foreground-subtle hover:text-primary transition-colors mt-0.5 inline-flex items-center gap-1",title:`Open parent device ${M.name}`,children:[o("span",{children:"↑"}),o("span",{className:"truncate",children:String(M.name??`Device #${R}`)})]}),o("div",{className:"hidden md:flex items-center gap-3 mt-0.5 text-[10px] text-foreground-subtle",children:z.length>0&&o(Ja,{capabilities:z})})]}),le&&o("div",{className:"hidden lg:flex",children:o(dz,{metrics:le})}),f("div",{className:"flex items-center gap-1 shrink-0",children:[f("button",{onClick:async()=>{await a({title:`Disable "${C}"?`,message:"The device will stop processing streams and events. You can re-enable it later.",confirmLabel:"Disable",variant:"danger"})&&q.mutate({deviceId:t})},disabled:ee,title:"Disable device",className:"inline-flex items-center gap-1.5 rounded-lg px-2 sm:px-2.5 py-1.5 text-[11px] font-medium border transition-colors disabled:opacity-50 border-success/30 text-success hover:bg-success/10",children:[o(ev,{className:"h-3.5 w-3.5"}),o("span",{className:"hidden sm:inline",children:ee?"Updating…":"Enabled"})]}),o("div",{className:"hidden sm:block h-5 w-px bg-border mx-1"}),o(y0,{triggerClassName:"ml-1",items:[{id:"snapshot",label:"Take snapshot",description:"Fetch a fresh frame and download it.",icon:Dr,disabled:re,onClick:()=>{W()}},{id:"reboot",label:"Reboot device",description:"Camera goes offline for ~30 seconds.",icon:kt,hidden:!oe,disabled:G.isPending,danger:!0,onClick:async()=>{await a({title:`Reboot "${C}"?`,message:"The camera will go offline for around 30 seconds while the firmware reboots.",confirmLabel:"Reboot",variant:"danger"})&&G.mutate({deviceId:t})}},{id:"restart-addon",label:"Restart addon",description:`Bounces every device served by ${j?.name??A}.`,icon:ct,disabled:Z.isPending,danger:!0,onClick:async()=>{await a({title:`Restart "${j?.name??A}"?`,message:`Restarting the addon will briefly disconnect every device served by it (not just "${C}"). Streams will reconnect automatically.`,confirmLabel:"Restart",variant:"danger"})&&Z.mutate({addonId:A})}},{id:"delete",label:"Delete device",description:"Remove the device and all its settings.",icon:Ze,separatorBefore:!0,disabled:V.isPending,danger:!0,onClick:async()=>{await a({title:`Delete "${C}"?`,message:"This will remove the device and all its settings. This action cannot be undone.",confirmLabel:"Delete",variant:"danger"})&&V.mutate({deviceId:t})}}]})]})]})]}),o(cb,{deviceId:t,device:k??void 0,children:o(Jy,{children:o(w0,{children:f("main",{className:D?"flex-1 overflow-y-auto flex flex-col":"flex-1 min-h-0 overflow-hidden flex flex-row",children:[f("div",{className:D?"flex flex-col bg-surface":`${h===null?"w-1/2 lg:w-1/3":""} flex-shrink-0 flex flex-col bg-surface min-h-0 overflow-hidden`,style:!D&&h!==null?{width:`${String(h)}px`}:void 0,children:[o("div",{className:`flex-shrink-0 border-b border-border-subtle ${B?"aspect-video bg-black":"bg-surface"}`,children:B?o(wB,{deviceId:t,intercomAvailable:z.includes(Wn.TwoWayAudio)}):o(QB,{deviceId:t,deviceName:C,deviceType:P??"unknown",provider:A,isOnline:E,features:z})}),f("div",{className:D?"flex flex-col border-b border-border":"flex-1 min-h-0 flex flex-col overflow-hidden",children:[o("div",{className:"flex-shrink-0 border-b border-border-subtle px-2 py-1.5",children:o("div",{className:"flex gap-1 overflow-x-auto -mx-1 px-1 pb-0.5",children:F.map(({id:de,label:ce,icon:Ce})=>f("button",{onClick:()=>u(de),title:ce,className:`flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium transition-colors flex-shrink-0 ${d===de?"bg-primary/15 text-primary":"text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[o(Ce,{className:"h-3 w-3"}),ce]},de))})}),f("div",{className:D?"h-72 overflow-hidden":"flex-1 min-h-0 overflow-hidden",children:[d==="logs"&&o(NB,{deviceId:t}),d==="repl"&&o(kB,{deviceId:t}),d==="events"&&o(CB,{deviceId:t}),d==="state"&&o(MB,{deviceId:t}),d==="ptz"&&o(SB,{deviceId:t})]})]})]}),!D&&o("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",onMouseDown:b,className:"flex-shrink-0 w-1 cursor-col-resize bg-border hover:bg-primary/40 transition-colors group relative z-10",children:o("span",{className:"absolute inset-y-0 -left-1 -right-1"})}),f("div",{className:D?"flex flex-col":"flex-1 min-w-0 min-h-0 flex flex-col overflow-hidden",children:[o("div",{className:"flex-shrink-0 border-b border-border bg-surface px-4",children:o("div",{className:"flex flex-wrap items-center gap-0",children:T.map(de=>{const ce=l===de.id;return f("button",{onClick:()=>c(de.id),className:`relative flex-shrink-0 px-3 py-2 text-xs font-medium transition-colors ${ce?"text-primary":"text-foreground-subtle hover:text-foreground"}`,children:[de.label,ce&&o("span",{className:"absolute bottom-0 left-0 right-0 h-0.5 rounded-full bg-primary"})]},de.id)})})}),f("div",{className:D?"p-3 flex flex-col gap-3":"flex-1 min-h-0 overflow-y-auto p-4 flex flex-col gap-3",children:[l==="overview"&&O&&o(EB,{parentDeviceId:t}),ue()]})]})]})})})})]}):f("div",{className:"flex flex-col items-center justify-center h-full gap-3 text-foreground-subtle",children:[o("p",{className:"text-lg font-semibold text-foreground",children:"Invalid device id"}),f("p",{className:"text-xs",children:["The URL segment ",o("code",{className:"font-mono bg-surface px-1.5 py-0.5 rounded text-[11px]",children:e.deviceId})," is not a number."]}),o("button",{onClick:()=>r("/integrations"),className:"mt-2 rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",children:"Back to Integrations"})]})}function dz({metrics:e}){const t=e.phase??"idle",n=ur(t);return f("div",{className:"flex items-center gap-3 flex-shrink-0",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:`h-1.5 w-1.5 rounded-full ${n.dotClass}`}),o("span",{className:`text-[10px] font-medium ${n.textColor}`,children:n.label})]}),o("div",{className:"h-3 w-px bg-border"}),f("div",{className:"flex items-center gap-1 text-[10px] text-foreground-subtle",children:[o(Xo,{className:"h-3 w-3"}),o("span",{className:"text-foreground tabular-nums",children:(e.actualFps??0).toFixed(1)}),o("span",{children:"fps"})]}),f("div",{className:"flex items-center gap-1 text-[10px] text-foreground-subtle",children:[o(bt,{className:"h-3 w-3"}),o("span",{className:"text-foreground tabular-nums",children:(e.avgInferenceTimeMs??0).toFixed(0)}),o("span",{children:"ms"})]}),(e.queueDepth??0)>0&&f("span",{className:"text-[10px] text-warning tabular-nums",children:["q:",e.queueDepth]})]})}function jv({packageName:e,currentVersion:t,installSource:n,onInstall:r,onClose:s}){const a=n==="upload"||n==="local",{data:i,isLoading:l}=yb({name:e},{staleTime:5*6e4});return f("div",{className:"fixed z-50 w-72 rounded-lg border border-border bg-surface shadow-xl overflow-hidden",style:{top:"auto",bottom:"auto"},ref:c=>{if(!c)return;const d=c.parentElement?.getBoundingClientRect();if(!d)return;const u=window.innerHeight-d.bottom,p=d.top;u<280&&p>u?(c.style.bottom=`${window.innerHeight-d.top+4}px`,c.style.top="auto"):(c.style.top=`${d.bottom+4}px`,c.style.bottom="auto"),c.style.right=`${window.innerWidth-d.right}px`},onClick:c=>c.stopPropagation(),children:[f("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border",children:[o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle font-medium",children:"Versions"}),o("button",{type:"button",onClick:s,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-3 w-3"})})]}),a&&f("div",{className:"flex items-start gap-2 px-3 py-2 border-b border-border bg-cyan-500/10 text-[10px]",children:[o(Xa,{className:"h-3 w-3 mt-0.5 text-cyan-500 shrink-0"}),f("div",{className:"text-cyan-700 dark:text-cyan-200",children:[f("span",{className:"font-semibold",children:[n==="upload"?"Uploaded copy":"Local copy"," in place."]})," ","Re-install ",o("span",{className:"font-mono",children:t})," from npm to track upstream releases again."]})]}),l&&f("div",{className:"flex items-center justify-center gap-2 py-6 text-[10px] text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Loading versions..."]}),i&&o("div",{className:"max-h-64 overflow-auto divide-y divide-border",children:i.map(c=>{const d=c.version===t,u=/-(alpha|beta|rc|dev|canary|next)/i.test(c.version);return f("div",{className:`flex items-center gap-2 px-3 py-2 text-[11px] ${d?"bg-primary/5":"hover:bg-surface-hover"} transition-colors`,children:[o("span",{className:`font-mono flex-1 ${d?"text-primary font-semibold":u?"text-amber-400":"text-foreground"}`,children:c.version}),c.distTags.map(p=>o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${p==="latest"?"bg-emerald-500/15 text-emerald-400":p==="beta"?"bg-amber-500/15 text-amber-400":"bg-gray-500/15 text-gray-400"}`,children:p},p)),c.deprecated&&o("span",{className:"text-[9px] text-red-400 line-through",children:"deprecated"}),o("span",{className:"text-[9px] text-foreground-subtle shrink-0",children:new Date(c.publishedAt).toLocaleDateString()}),d&&!a?o(_t,{className:"h-3 w-3 text-primary shrink-0"}):o("button",{type:"button",onClick:()=>r(c.version),className:"shrink-0 rounded p-0.5 hover:bg-primary/20 text-foreground-subtle hover:text-primary transition-colors",title:d?`Re-install ${c.version} from npm`:`Install ${c.version}`,children:o(Xt,{className:"h-3 w-3"})})]},c.version)})}),i&&i.length===0&&o("div",{className:"py-4 text-center text-[10px] text-foreground-subtle",children:"No versions found"})]})}const uz="device-export";function pz(e){return e.capabilities.some(t=>(typeof t=="string"?t:t.name)===uz)}function fz({isBundle:e,installSource:t,addonId:n,iconPath:r,color:s}){const[a,i]=_(!1),l=s?{backgroundColor:`${s.startsWith("#")?s:`#${s}`}26`}:void 0,c=e?"bg-indigo-500/20 text-indigo-700 dark:text-indigo-300":"bg-purple-500/20 text-purple-700 dark:text-purple-300",d=n&&r?`/api/addon-assets/${n}/${r}`:null,u=!!d&&!a;return f("div",{className:"relative flex-shrink-0",children:[o("div",{className:`h-9 w-9 rounded-lg flex items-center justify-center ${l?"":c}`,style:l,children:u?o("img",{src:d,alt:n,className:"h-5 w-5",onError:()=>i(!0)}):e?o(X0,{className:"h-4 w-4"}):o(la,{className:"h-4 w-4"})}),t==="local"&&o("span",{className:"absolute -top-1.5 -left-1.5 text-[7px] font-bold leading-none bg-orange-500 text-white px-1 py-0.5 rounded -rotate-12 shadow-sm",children:"DEV"}),t==="npm"&&o("span",{className:"absolute -top-1 -left-1 w-4 h-4 rounded bg-[#cb3837] flex items-center justify-center -rotate-12 shadow-sm",children:o("svg",{viewBox:"0 0 780 250",className:"w-[11px] h-[11px]",children:o("path",{fill:"#fff",d:"M240 250h100V50h100v200h340V0H0v250z"})})}),t==="upload"&&o("span",{className:"absolute -top-1.5 -left-1.5 flex items-center justify-center h-4 w-4 rounded bg-cyan-500 -rotate-12 shadow-sm",children:o(Xa,{className:"h-2.5 w-2.5 text-white"})})]})}function hz({addonId:e}){const t=ke(),{data:n="inherit"}=Nb({addonId:e},{staleTime:3e4}),r=kb({onSuccess:()=>{t.invalidateQueries({queryKey:[["addons","getAddonAutoUpdate"]]})}});return o("div",{className:"flex rounded-lg border border-border overflow-hidden text-[10px] font-medium",children:["inherit","off","latest","beta"].map(s=>o("button",{type:"button",onClick:a=>{a.stopPropagation(),r.mutate({addonId:e,channel:s})},disabled:r.isPending,className:`px-2.5 py-1 transition-colors capitalize ${n===s?s==="inherit"?"bg-gray-700/50 text-gray-700 dark:text-gray-300":s==="off"?"bg-gray-700 text-gray-700 dark:text-gray-300":s==="latest"?"bg-blue-500/20 text-blue-400":"bg-amber-500/20 text-amber-400":"bg-transparent text-foreground-subtle hover:bg-surface-hover"} ${s!=="inherit"?"border-l border-border":""}`,children:s},s))})}function oc({addon:e,agents:t=[],clusterStatus:n,hideVersion:r,availableUpdate:s,onUpdate:a,isUpdating:i,bundle:l}){const[c,d]=_(!1),[u,p]=_(!1),[h,m]=_(!1),[g,b]=_(!1),[x,y]=_(!1),[w,v]=_("logs"),N=ke(),k=nt(),{manifest:C}=e,E=e.installedOn??[],I=!l&&!C.protected&&C.removable!==!1,A=!!l,z=l?.displayName??C.name,P=l?.packageName??C.packageName,B=l?.version??C.packageVersion??C.version,R=l?.installSource??e.installSource,M=l?l.bundle?.description??l.addons[0]?.manifest.description:C.description;!l&&(C.components&&C.components.length>0||t.length>=2);const D=db({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["addonPages"]]}),N.invalidateQueries({queryKey:[["capabilities"]]})}}),T=Ko({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]})}}),L=rd({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["addonPages"]]}),N.invalidateQueries({queryKey:[["capabilities"]]}),N.invalidateQueries({queryKey:[["integrations"]]})}}),O=vb({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["alerts"]]})}}),F=e.health,j=F?.phase==="failed"&&!F.inGracePeriod,V=j&&F?.nextRetryAt&&!F.retrying;return f("div",{className:`rounded-lg border bg-surface overflow-hidden ${j?"border-red-500/50":"border-border"}`,children:[j&&F&&f("div",{className:"bg-danger/10 border-b border-danger/30 px-4 py-2.5 flex items-start gap-2.5",children:[o(Z6,{className:"h-4 w-4 text-danger shrink-0 mt-0.5"}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"text-xs font-semibold text-danger",children:["Failed to load (attempt #",F.retryCount,")"]}),o("div",{className:"text-[11px] text-foreground mt-0.5 break-words font-mono",children:F.lastError?.message??"Unknown error"}),V&&F.nextRetryAt&&f("div",{className:"text-[10px] text-foreground-subtle mt-1",children:["Auto-retry at ",new Date(F.nextRetryAt).toLocaleTimeString()]})]}),f("button",{type:"button",disabled:O.isPending||F.retrying,onClick:$=>{$.stopPropagation(),O.mutate({packageName:P})},className:"inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-semibold border border-red-400/40 bg-red-400/10 text-red-700 dark:text-red-300 hover:bg-red-400/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0",title:"Reset retry counter and force immediate reload",children:[o(ct,{className:`h-3 w-3 ${O.isPending||F.retrying?"animate-spin":""}`}),"Retry now"]})]}),f("div",{className:"flex items-start gap-3 px-4 py-3",children:[o(fz,{isBundle:A||!!C.components&&C.components.length>1,installSource:R,addonId:A?l.addons[0]?.manifest.id:C.id,iconPath:A?l.bundle?.icon??l.addons[0]?.manifest.icon:C.icon,color:A?l.addons[0]?.manifest.color:C.color}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-semibold text-foreground truncate",children:z}),f("span",{className:"text-[10px] text-foreground-subtle font-mono shrink-0",children:["(",P,")"]}),A&&f("span",{className:"text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1",children:[o(X0,{className:"h-3 w-3"}),l.addons.length]})]}),M&&o("p",{className:"text-[10px] text-foreground-subtle mt-0.5 line-clamp-1",children:M}),!A&&e.process&&f("div",{className:"flex items-center gap-1.5 mt-1",children:[o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.mode==="forked"?"bg-blue-500/15 text-blue-400":"bg-gray-500/15 text-gray-400"}`,children:e.process.mode==="forked"?"forked":"in-process"}),e.process.pid!=null&&f("span",{className:"text-[9px] font-mono text-foreground-subtle",children:["PID ",e.process.pid]}),o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.state==="running"?"bg-emerald-500/15 text-emerald-400":e.process.state==="crashed"?"bg-red-500/15 text-red-400":"bg-gray-500/15 text-gray-400"}`,children:e.process.state})]})]}),!r&&f("div",{className:"relative inline-flex items-center gap-1.5 shrink-0 pt-0.5",children:[i?f("span",{className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-blue-500/30 bg-blue-500/10 text-blue-400",children:[o(Se,{className:"h-3 w-3 animate-spin"}),"Updating to ",s,"…"]}):s&&a?f("button",{type:"button",onClick:$=>{$.stopPropagation(),a()},className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-semibold border border-primary/40 bg-primary/10 text-primary hover:bg-primary/20 transition-colors animate-pulse",title:`Update to ${s}`,children:[o(Xt,{className:"h-3 w-3"}),s]}):null,f("button",{type:"button",onClick:$=>{$.stopPropagation(),m(q=>!q)},className:["inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border transition-colors",R==="local"?"border-orange-500/30 bg-orange-500/10 text-orange-400 hover:bg-orange-500/20":s?"border-amber-500/30 bg-amber-500/10 text-amber-400 hover:bg-amber-500/20":"border-emerald-500/30 bg-emerald-500/10 text-emerald-400 hover:bg-emerald-500/20"].join(" "),title:s?`Current ${B} — newer ${s} available`:"View all versions",children:[B,o(lt,{className:"h-3 w-3 opacity-50"})]}),h&&o(jv,{packageName:P,currentVersion:B,...R?{installSource:R}:{},onInstall:$=>{m(!1),L.mutate({packageName:P,version:$})},onClose:()=>m(!1)})]})]}),!A&&f("div",{className:"flex items-center gap-1 px-4 py-1.5 border-t border-border/50 bg-surface-hover/20",children:[f("button",{type:"button",onClick:$=>{$.stopPropagation(),T.mutate({addonId:C.id})},disabled:T.isPending,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-blue-400 hover:border-blue-500/30 hover:bg-blue-500/10 disabled:opacity-50 transition-colors",children:[o(ct,{className:`h-3 w-3 ${T.isPending?"animate-spin":""}`}),"Restart"]}),f("button",{type:"button",onClick:$=>{$.stopPropagation(),b(q=>!q)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${g?"border-primary/30 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10"}`,children:[o(at,{className:"h-3 w-3"}),"Logs"]}),!A&&f("button",{type:"button",onClick:$=>{$.stopPropagation(),y(!0)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${x?"border-primary/30 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10"}`,children:[o(Jt,{className:"h-3 w-3"}),"Settings"]}),o("div",{className:"flex-1"}),I&&f("button",{type:"button",onClick:async $=>{$.stopPropagation(),await k({title:`Uninstall ${C.name}?`,message:"This will remove the addon package and all its data. This action cannot be undone.",confirmLabel:"Uninstall",variant:"danger"})&&D.mutate({packageName:C.packageName})},disabled:D.isPending,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-red-400 hover:border-red-500/30 hover:bg-red-500/10 disabled:opacity-50 transition-colors",children:[o(Ze,{className:"h-3 w-3"}),D.isPending?"Removing...":"Uninstall"]})]}),n&&n.nodes.length>1&&!A&&f("div",{className:"border-t border-border px-4 py-2 bg-muted/10",children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle mb-1.5",children:"Cluster Deployment"}),o("div",{className:"space-y-1",children:n.nodes.map($=>f("div",{className:"flex items-center gap-2 text-[10px]",children:[o("div",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${$.status==="offline"?"bg-muted-foreground/30":$.synced?"bg-success":"bg-amber-500"}`}),o("span",{className:"font-medium text-foreground min-w-[60px]",children:$.name}),o("span",{className:"font-mono text-foreground-subtle",children:$.version}),!$.synced&&$.status!=="offline"&&o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-400 border border-amber-500/20",children:"outdated"}),$.status==="offline"&&o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-muted text-muted-foreground",children:"offline"}),$.synced&&$.status!=="offline"&&o("span",{className:"text-[9px] text-success",children:"synced"})]},$.nodeId))})]}),g&&!A&&f("div",{className:"border-t border-border",children:[f("div",{className:"flex items-center px-4 py-1 bg-surface-hover/20 border-b border-border/50",children:[f("div",{className:"flex rounded border border-border overflow-hidden text-[9px]",children:[o("button",{type:"button",onClick:()=>v("logs"),className:`px-2 py-0.5 transition-colors ${w==="logs"?"bg-primary/10 text-primary":"text-foreground-subtle hover:bg-surface-hover"}`,children:"Logs"}),o("button",{type:"button",onClick:()=>v("events"),className:`px-2 py-0.5 border-l border-border transition-colors ${w==="events"?"bg-primary/10 text-primary":"text-foreground-subtle hover:bg-surface-hover"}`,children:"Events"})]}),o("div",{className:"flex-1"}),o("button",{type:"button",onClick:$=>{$.stopPropagation(),b(!1)},className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-3.5 w-3.5"})})]}),w==="logs"&&o(tn,{addonId:C.id,maxHeight:"max-h-64",showFilters:!1}),w==="events"&&o(br,{addonId:C.id,category:"addon.*",maxHeight:"max-h-64"})]}),A&&f(me,{children:[o("button",{type:"button",onClick:()=>d($=>!$),className:"w-full flex items-center justify-center border-t border-border py-1 hover:bg-surface-hover/50 transition-colors",children:c?o(jR,{className:"h-3.5 w-3.5 text-foreground-subtle"}):o(lt,{className:"h-3.5 w-3.5 text-foreground-subtle"})}),c&&o("div",{className:"border-t border-border px-3 py-2 space-y-2",children:l.addons.map($=>o(oc,{addon:$,agents:t,hideVersion:!0},$.manifest.id))})]}),x&&!A&&o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4",onClick:()=>y(!1),children:f("div",{className:"w-full max-w-lg max-h-[80vh] rounded-xl border border-border bg-surface shadow-2xl flex flex-col overflow-hidden",onClick:$=>$.stopPropagation(),children:[f("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border flex-shrink-0",children:[f("div",{className:"flex items-center gap-2",children:[o(Jt,{className:"h-4 w-4 text-primary"}),f("h2",{className:"text-sm font-semibold text-foreground",children:[z," Settings"]})]}),o("button",{onClick:()=>y(!1),className:"text-foreground-subtle hover:text-foreground transition-colors p-1 rounded",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"flex-1 overflow-y-auto px-5 py-4 space-y-4",children:[o(to,{nodeId:"hub",addonIds:[C.id],level:"global"}),pz(C)&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Device export"}),o(Md,{addonId:C.id})]}),R==="npm"&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Auto-Update"}),o(hz,{addonId:C.id})]}),C.components&&C.components.length>0&&f("div",{children:[f("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:["Components (",C.components.length,")"]}),o("div",{className:"flex flex-wrap gap-1",children:C.components.map($=>o("span",{className:"text-[10px] rounded bg-background border border-border px-1.5 py-0.5 text-foreground-subtle font-mono",children:$},$))})]}),t.length>=2&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Installed on"}),f("div",{className:"flex items-center gap-1.5 flex-wrap",children:[E.length===0&&o("span",{className:"text-[10px] text-foreground-subtle",children:"Hub (local)"}),E.map($=>o("span",{className:"rounded-full bg-surface-hover border border-border px-2 py-0.5 text-[10px] text-foreground-subtle",children:$},$)),f("div",{className:"relative",children:[f("button",{type:"button",onClick:$=>{$.stopPropagation(),p(q=>!q)},className:"inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2 py-0.5 text-[10px] text-foreground-subtle hover:text-foreground hover:border-primary transition-colors",title:"Install on more agents",children:[o(Et,{className:"h-3 w-3"}),"Add agent"]}),u&&f("div",{className:"absolute left-0 top-full mt-1 z-10 min-w-[160px] rounded-md border border-border bg-surface shadow-lg overflow-hidden",children:[t.filter($=>!$.isHub&&!E.includes($.name)).map($=>o("button",{type:"button",onClick:q=>{q.stopPropagation(),p(!1)},className:"w-full text-left px-3 py-1.5 text-[10px] text-foreground hover:bg-surface-hover transition-colors",children:$.name},$.id)),t.filter($=>!$.isHub&&!E.includes($.name)).length===0&&o("div",{className:"px-3 py-1.5 text-[10px] text-foreground-subtle",children:"No available agents"})]})]})]})]})]}),o("div",{className:"flex items-center justify-end px-5 py-3 border-t border-border flex-shrink-0",children:o("button",{type:"button",onClick:()=>y(!1),className:"rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:"Close"})})]})})]})}const mz=".tgz,.tar.gz,.zip";function gz({onUploadSuccess:e}){const[t,n]=_(!1),r=te(null),s=U(async i=>{n(!0);const l=new FormData;l.append("file",i);const c=localStorage.getItem("camstack_admin_token")??"";try{(await(await fetch("/api/addons/upload",{method:"POST",headers:{Authorization:`Bearer ${c}`},body:l})).json()).success&&e()}finally{n(!1)}},[e]),a=U(i=>{const l=i.target.files?.[0];l&&s(l),i.target.value=""},[s]);return f(me,{children:[o("input",{ref:r,type:"file",accept:mz,onChange:a,className:"hidden"}),f("button",{type:"button",onClick:()=>r.current?.click(),disabled:t,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",children:[t?o(Se,{className:"w-3.5 h-3.5 animate-spin"}):o(Xa,{className:"w-3.5 h-3.5"}),t?"Uploading...":"Upload"]})]})}function bz(){const{data:e,isLoading:t,isError:n}=gb(void 0,{staleTime:6e4}),[r,s]=_(null),[a,i]=_(null),l=xb({onError:d=>{i(d instanceof Error?d.message:String(d))},onSuccess:()=>{s(null)}});if(t)return o(sl,{children:o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading system packages…"})});if(n)return o(sl,{children:o("div",{className:"text-xs text-danger",children:"Failed to load system packages"})});const c=e??[];return c.length===0?o(me,{}):f(me,{children:[o(sl,{collapsible:!0,defaultCollapsed:!0,children:o("div",{className:"space-y-1.5",children:c.map(d=>o(xz,{row:d,onUpdate:u=>s({packageName:d.packageName,fromVersion:d.currentVersion,toVersion:u})},d.packageName))})}),r!==null&&o(yz,{pending:r,onCancel:()=>{s(null),i(null)},onConfirm:()=>{i(null),l.mutate({packageName:r.packageName,version:r.toVersion})},isPending:l.isPending,error:a})]})}function sl({children:e,collapsible:t=!1,defaultCollapsed:n=!1}){const[r,s]=_(n),a=!t||!r,i=f("div",{className:"flex items-center gap-2",children:[t&&(r?o(wt,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"}):o(lt,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"})),o(it,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"}),o("span",{className:"text-[11px] font-medium text-amber-800",children:"System packages"}),o("span",{className:"text-[10px] text-foreground-subtle",children:"Updating these will restart the hub (~10s)."})]});return f("div",{className:"rounded-md border border-amber-500/30 bg-amber-500/5 p-3 space-y-2",children:[t?o("button",{type:"button",onClick:()=>s(l=>!l),"aria-expanded":!r,className:"flex w-full items-center text-left",children:i}):i,a&&e]})}function xz({row:e,onUpdate:t}){const[n,r]=_(!1),s=e.hasUpdate&&e.latestVersion!==null;return f("div",{className:"flex items-center justify-between gap-3 px-2 py-1.5 rounded bg-surface/50 border border-border",children:[f("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[o("span",{className:"font-mono text-[11px] text-foreground truncate",children:e.packageName}),e.description!==void 0&&o("span",{className:"text-[10px] text-foreground-subtle truncate",title:e.description,children:e.description})]}),f("div",{className:"flex items-center gap-2 shrink-0",children:[s&&f("button",{type:"button",onClick:()=>t(e.latestVersion),className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] rounded bg-amber-500/15 text-amber-800 hover:bg-amber-500/25 border border-amber-500/30 font-medium transition-colors",title:`Update to ${e.latestVersion}`,children:[o(Xt,{className:"w-3 h-3"}),"v",e.latestVersion]}),f("button",{type:"button",onClick:()=>r(a=>!a),className:["inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-mono font-medium border transition-colors",s?"border-amber-500/30 bg-amber-500/10 text-amber-800 hover:bg-amber-500/20":"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 hover:bg-emerald-500/20"].join(" "),title:"View all versions",children:["v",e.currentVersion,o(lt,{className:"w-3 h-3 opacity-50"})]}),n&&o(jv,{packageName:e.packageName,currentVersion:e.currentVersion,onInstall:a=>{r(!1),t(a)},onClose:()=>r(!1)})]})]})}function yz({pending:e,onCancel:t,onConfirm:n,isPending:r,error:s}){return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60",children:f("div",{className:"bg-surface border border-border rounded-md shadow-xl p-5 max-w-md w-full mx-4 space-y-3",children:[f("div",{className:"flex items-center gap-2",children:[o(it,{className:"w-4 h-4 text-amber-700"}),o("h3",{className:"text-sm font-medium text-foreground",children:"Update system package?"})]}),f("div",{className:"space-y-2 text-[11px] text-foreground-subtle",children:[f("div",{children:[o("span",{className:"font-mono text-foreground",children:e.packageName}),o("span",{className:"mx-1",children:"·"}),f("span",{className:"font-mono",children:["v",e.fromVersion]}),o("span",{className:"mx-1",children:"→"}),f("span",{className:"font-mono text-amber-700",children:["v",e.toVersion]})]}),o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 p-2 text-amber-800",children:"The hub will restart immediately after the install. Any in-flight requests will be dropped. The reconnect typically takes ~10 seconds."}),s!==null&&o("div",{className:"rounded border border-danger/40 bg-danger/10 p-2 text-danger",children:s})]}),f("div",{className:"flex justify-end gap-2 pt-1",children:[o("button",{type:"button",onClick:t,disabled:r,className:"px-3 py-1.5 text-[11px] rounded bg-surface hover:bg-surface-hover border border-border disabled:opacity-50",children:"Cancel"}),f("button",{type:"button",onClick:n,disabled:r,className:"inline-flex items-center gap-1.5 px-3 py-1.5 text-[11px] rounded bg-amber-500/20 text-amber-800 hover:bg-amber-500/30 border border-amber-500/40 font-medium disabled:opacity-50",children:[r?o(Se,{className:"w-3 h-3 animate-spin"}):o(Xt,{className:"w-3 h-3"}),"Update & restart"]})]})]})})}function vz(e,t){const n=e??"hub-only";return n==="any-node"?!0:n==="hub-only"?t:!t}function wz(e){const t=e;if(!t?.manifest)return null;const n={...t.manifest,name:t.manifest.name??t.manifest.id,version:t.manifest.version??"0.0.0",capabilities:t.manifest.capabilities??[]},r=t.process,s=r?{pid:r.pid,mode:r.mode==="forked"?"forked":"in-process",state:r.state??"unknown"}:void 0,a=t.health,i=t.declaration?.execution,l=t.manifest.execution,c=i?.placement??l?.placement;return{manifest:n,enabled:!0,source:t.source,installSource:t.installSource,installedOn:[],...s?{process:s}:{},hasBackup:t.hasBackup,...a?{health:a}:{},...c?{placement:c}:{}}}function Nz(e){const t=new Map,n=[];for(const s of e){const a=s.manifest.packageName;if(!a){n.push(s);continue}const i=t.get(a);if(i)i.addons.push(s);else{const l=s.manifest.bundle,c={packageName:a,displayName:l?.displayName??s.manifest.packageDisplayName??s.manifest.name,version:s.manifest.packageVersion,addons:[s],...s.installSource!==void 0?{installSource:s.installSource}:{},...l!==void 0?{bundle:l}:{}};t.set(a,c)}}const r=[];for(const s of t.values())s.bundle!==void 0||s.addons.length>=2?r.push({bundle:s,representative:s.addons[0]}):r.push(s.addons[0]);return r.push(...n),r}function sn(e){return"bundle"in e}function kz({addons:e,clusterStatus:t,selectedNode:n,onRefresh:r,isRefreshing:s}){const a=ke(),[i,l]=_(""),c=d2(i),[d,u]=_(!1),p=te(null);Y(()=>{if(!d)return;const $=q=>{p.current&&!p.current.contains(q.target)&&u(!1)};return document.addEventListener("mousedown",$),()=>document.removeEventListener("mousedown",$)},[d]);const{data:h}=od({nodeId:n.id},{staleTime:5*6e4}),m=H(()=>{const $=new Map;for(const q of h??[])$.set(q.name,q.latestVersion);return $},[h]),[g,b]=_(null),[x,y]=_(null),w=Rl({onMutate:$=>{b($.name),y(null)},onSuccess:($,q)=>{b(null);const G=$;if(G&&G.success===!1){y({name:q.name,message:G.error??"Update failed (no error message returned by server)"});return}a.invalidateQueries({queryKey:[["addons"]]}),a.invalidateQueries({queryKey:[["addons","listUpdates"]]})},onError:($,q)=>{b(null),y({name:q.name,message:$ instanceof Error?$.message:String($)})}}),{data:v}=wb(void 0,{staleTime:3e4}),N=Sb({onSuccess:()=>{a.invalidateQueries({queryKey:[["addons","getAutoUpdateSettings"]]})}}),{data:k,isFetching:C}=pb({query:c||void 0},{enabled:d,staleTime:6e4}),E=Rl(),I=async()=>{const $=h??[];for(const q of $)await E.mutateAsync({name:q.name,version:q.latestVersion,nodeId:n.id});a.invalidateQueries({queryKey:[["addons"]]})},A=rd({onSuccess:()=>{a.invalidateQueries({queryKey:[["addons"]]}),a.invalidateQueries({queryKey:[["addonPages"]]}),a.invalidateQueries({queryKey:[["capabilities"]]}),a.invalidateQueries({queryKey:[["integrations"]]})}}),[z,P]=_("type"),[B,R]=_(()=>typeof window>"u"?"grouped":window.localStorage.getItem("camstack.addons.viewMode")==="flat"?"flat":"grouped"),M=$=>{R($),typeof window<"u"&&window.localStorage.setItem("camstack.addons.viewMode",$)},[D,T]=Ga(),L=D.get("capability"),O=H(()=>{let $=n.isHub?e:e.filter(q=>vz(q.placement,n.isHub));return L&&($=$.filter(q=>(q.manifest.capabilities??[]).some(Z=>(typeof Z=="string"?Z:Z.name)===L))),$},[e,n.isHub,L]),F=()=>{const $=new URLSearchParams(D);$.delete("capability"),T($,{replace:!0})},j=B==="flat"?O:Nz(O),V=H(()=>{const $=[...j];switch(z){case"type":$.sort((q,G)=>{const Z=sn(q)?0:1,oe=sn(G)?0:1;if(Z!==oe)return Z-oe;const ne=sn(q)?q.bundle.displayName:q.manifest.name,X=sn(G)?G.bundle.displayName:G.manifest.name;return ne.localeCompare(X)});break;case"name":$.sort((q,G)=>{const Z=sn(q)?q.bundle.displayName:q.manifest.name,oe=sn(G)?G.bundle.displayName:G.manifest.name;return Z.localeCompare(oe)});break;case"source":$.sort((q,G)=>{const Z=sn(q)?q.bundle.installSource??"":q.installSource??"",oe=sn(G)?G.bundle.installSource??"":G.installSource??"";return Z.localeCompare(oe)});break}return $},[j,z]);return f("div",{className:"space-y-4",children:[x&&o("div",{className:"rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-[11px]",children:f("div",{className:"flex items-start justify-between gap-3",children:[f("div",{className:"space-y-0.5",children:[f("div",{className:"font-medium text-danger",children:["Failed to update ",x.name]}),o("div",{className:"text-foreground-subtle font-mono",children:x.message})]}),o("button",{type:"button",onClick:()=>y(null),className:"text-foreground-subtle hover:text-foreground text-[10px]",children:"dismiss"})]})}),f("div",{className:"flex items-center gap-2 flex-wrap",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-[10px] text-foreground-subtle",children:"Sort:"}),f("select",{value:z,onChange:$=>P($.target.value),className:"rounded-md border border-border bg-surface px-2 py-1.5 text-[11px] text-foreground focus:outline-none focus:border-primary/50",children:[o("option",{value:"type",children:"Bundles first"}),o("option",{value:"name",children:"Name"}),o("option",{value:"source",children:"Install source"})]})]}),f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-[10px] text-foreground-subtle",children:"View:"}),o("div",{className:"flex rounded-md border border-border overflow-hidden text-[10px] font-medium",children:["grouped","flat"].map($=>o("button",{type:"button",onClick:()=>M($),className:`px-2.5 py-1.5 transition-colors capitalize ${B===$?"bg-primary/10 text-primary":"bg-transparent text-foreground-subtle hover:bg-surface-hover"}`,title:$==="grouped"?"Group multi-addon packages into a bundle card":"Show every addon as its own card",children:$},$))})]}),n.isHub&&f("div",{className:"flex items-center gap-1.5",children:[o(ct,{className:"h-3 w-3 text-foreground-subtle"}),o("span",{className:"text-[10px] text-foreground-subtle",children:"Auto-Update:"}),o("div",{className:"flex rounded-md border border-border overflow-hidden text-[10px] font-medium",children:["off","latest","beta"].map($=>o("button",{type:"button",onClick:()=>N.mutate({channel:$}),disabled:N.isPending,className:`px-2.5 py-1.5 transition-colors capitalize ${v?.channel===$?$==="off"?"bg-gray-700 text-gray-200":$==="latest"?"bg-blue-500/20 text-blue-400":"bg-amber-500/20 text-amber-400":"bg-transparent text-foreground-subtle hover:bg-surface-hover"} ${$!=="off"?"border-l border-border":""}`,children:$},$))})]}),(h?.length??0)>0&&f("button",{type:"button",onClick:()=>void I(),disabled:E.isPending,className:"flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 border border-blue-500/30 disabled:opacity-50 transition-colors font-medium",children:[o(Xt,{className:`w-3 h-3 ${E.isPending?"animate-bounce":""}`}),"Update All (",h.length,")"]}),f("button",{type:"button",onClick:r,disabled:s,className:"flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",children:[o(ct,{className:`w-3 h-3 ${s?"animate-spin":""}`}),"Refresh"]})]}),f("div",{className:"flex items-center gap-3",children:[f("div",{className:"relative flex-1 min-w-[200px]",ref:p,children:[o(nv,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-foreground-subtle"}),o("input",{type:"text",value:i,onChange:$=>{l($.target.value),u(!0)},onFocus:()=>u(!0),placeholder:"Search addons on npm...",className:"w-full rounded-lg border border-border bg-background pl-9 pr-3 py-2 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"}),C&&o(Se,{className:"absolute right-2.5 top-1/2 -translate-y-1/2 h-3 w-3 text-foreground-subtle animate-spin"}),d&&k&&k.length>0&&f("div",{className:"absolute left-0 right-0 top-full mt-1 z-40 rounded-lg border border-border bg-surface shadow-xl overflow-hidden",children:[k.length>0&&f("div",{className:"px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border",children:["npm results (",k.length,")"]}),k&&k.length>0&&o("div",{className:"max-h-72 overflow-auto divide-y divide-border",children:k.map($=>f("div",{className:"flex items-center gap-3 px-3 py-2 hover:bg-surface-hover transition-colors",children:[o("div",{className:"w-6 h-6 rounded-md bg-primary/10 flex items-center justify-center text-primary text-[9px] font-bold shrink-0",children:$.name.replace("@camstack/addon-","").charAt(0).toUpperCase()}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-[11px] font-semibold truncate",children:$.name}),f("span",{className:"text-[10px] text-foreground-subtle",children:["v",$.version]})]}),$.description&&o("div",{className:"text-[10px] text-foreground-subtle truncate",children:$.description})]}),$.installed?f("span",{className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md border border-emerald-500/30 bg-emerald-500/10 text-emerald-400 shrink-0",children:[o(_t,{className:"h-3 w-3"}),$.installedVersion??"Installed"]}):f("button",{type:"button",onClick:()=>A.mutate({packageName:$.name}),disabled:A.isPending,className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors shrink-0",children:[A.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xt,{className:"h-3 w-3"}),"Install"]})]},$.name))})]})]}),o(gz,{onUploadSuccess:()=>{a.invalidateQueries({queryKey:[["addons"]]}),r()}})]}),L&&f("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-primary/10 border border-primary/30 text-sm",children:[o("span",{className:"text-foreground-subtle",children:"Filtering by capability:"}),o("span",{className:"font-mono text-primary font-semibold",children:L}),o("button",{type:"button",onClick:F,className:"ml-auto text-xs text-foreground-subtle hover:text-foreground underline",children:"Clear"})]}),O.length===0&&o("div",{className:"text-xs text-foreground-subtle",children:e.length===0?"No addons installed":L?`No installed addons declare the "${L}" capability. Browse the npm catalog above to find a compatible addon.`:`No addons compatible with ${n.name} (placement filter active)`}),o("div",{className:"space-y-2",children:V.map($=>{if(sn($)){const Z=$.bundle.packageName,oe=m.get(Z);return o(oc,{addon:$.representative,clusterStatus:t?.[$.representative.manifest.id],bundle:$.bundle,availableUpdate:oe,isUpdating:g===Z,onUpdate:oe?()=>w.mutate({name:Z,version:oe,nodeId:n.id}):void 0},Z)}const q=$.manifest.packageName,G=m.get(q);return o(oc,{addon:$,clusterStatus:t?.[$.manifest.id],availableUpdate:G,isUpdating:g===q,onUpdate:G?()=>w.mutate({name:$.manifest.packageName,version:G,nodeId:n.id}):void 0},$.manifest.id)})})]})}function Sz(){const e=ke(),{data:t,isLoading:n,isError:r}=wn(),{data:s}=Ox(void 0,{staleTime:15e3}),{data:a}=zn(void 0,{staleTime:3e4,refetchInterval:1e4}),i=H(()=>{const x=new Map;x.set("hub",{id:"hub",name:"Hub",isHub:!0});for(const y of a??[]){const w=String(y.id??"");w&&x.set(w,{id:w,name:String(y.name??w),isHub:!!y.isHub})}return[...x.values()]},[a]),[l,c]=_("hub"),d=i.find(x=>x.id===l)??i[0],u=fb(),p=ub(),h=u.isPending||p.isPending,m=async()=>{await u.mutateAsync({nodeId:l}),await p.mutateAsync(),e.invalidateQueries({queryKey:[["addons"]]})},g=te(u);g.current=u,Y(()=>{g.current.mutate({nodeId:"hub"})},[]);const b=(t??[]).map(wz).filter(x=>x!==null);return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o(Bg,{selectedNodeId:l,onSelect:c}),f("div",{className:"flex items-center gap-3 flex-wrap",children:[!n&&!r&&f("span",{className:"text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium",children:[b.length," installed"]}),f("button",{type:"button",onClick:()=>void m(),disabled:h,className:"inline-flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",title:"Re-fetch addons + check npm for new versions",children:[o(ct,{className:`w-3 h-3 ${h?"animate-spin":""}`}),"Check for updates"]})]})]}),!d.isHub&&f("div",{className:"rounded-md border border-warning/30 bg-warning/5 px-3 py-2 text-[11px] text-foreground-subtle",children:["Showing only addons compatible with"," ",o("span",{className:"font-medium text-foreground",children:d.name})," ","— agents only run ",o("code",{className:"font-mono",children:"agent-only"})," and"," ",o("code",{className:"font-mono",children:"any-node"})," addons. Install / uninstall is hub-driven; agents auto-sync from the hub."]}),n&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading…"}),r&&o("div",{className:"text-xs text-danger",children:"Failed to load addons"}),d.isHub&&o(bz,{}),!n&&!r&&o(kz,{addons:b,clusterStatus:s,selectedNode:d,onRefresh:()=>void m(),isRefreshing:h})]})}function Cz({value:e,size:t=192}){const[n,r]=_(null),[s,a]=_(null);if(Y(()=>{let d=!1;return E2(()=>import("./browser-BXdiCFWD.js").then(u=>u.b),[]).then(async u=>{if(d)return;const p=u.create;if(typeof p!="function"){a("qrcode.create() unavailable in installed version");return}try{const h=p(e,{errorCorrectionLevel:"M"});d||r(h)}catch(h){d||a(h instanceof Error?h.message:"QR generation failed")}}).catch(()=>{d||a("qrcode library not installed")}),()=>{d=!0}},[e]),s)return o("div",{className:"flex items-center justify-center text-[10px] text-foreground-subtle text-center p-4",style:{width:t,height:t},children:"QR rendering unavailable — use the secret below."});if(!n)return o("div",{className:"flex items-center justify-center text-[10px] text-foreground-subtle animate-pulse",style:{width:t,height:t},children:"Generating…"});const i=n.modules.size,l=t/i,c=[];for(let d=0;d<i;d++)for(let u=0;u<i;u++)n.modules.data[d*i+u]&&c.push(o("rect",{x:u*l,y:d*l,width:l,height:l,fill:"currentColor"},`${u}-${d}`));return f("svg",{width:t,height:t,viewBox:`0 0 ${t} ${t}`,className:"text-black",children:[o("rect",{x:0,y:0,width:t,height:t,fill:"white"}),c]})}const Mz={view:{icon:es,cls:"bg-foreground-subtle/15 text-foreground-subtle"},create:{icon:eo,cls:"bg-primary/15 text-primary"},delete:{icon:Ze,cls:"bg-danger/15 text-danger"}};function Ez(){const{user:e,logout:t}=nn();if(!e)return o(tt,{children:o("div",{className:"text-xs text-foreground-subtle",children:"Not signed in."})});const n=e.isAdmin,r=e.scopes??[];return f(tt,{children:[f("div",{className:"rounded-lg border border-border bg-surface px-4 py-3 flex items-center gap-3",children:[o("div",{className:"flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 text-primary font-semibold text-base",children:e.username.slice(0,1).toUpperCase()}),f("div",{className:"flex-1 min-w-0",children:[o("div",{className:"text-sm font-semibold text-foreground truncate",children:e.username}),f("div",{className:"text-[11px] text-foreground-subtle",children:[n?"Administrator":"User"," · session id ",f("span",{className:"font-mono",children:[e.id.slice(0,8),"…"]})]})]})]}),n&&f("div",{className:"rounded-lg border border-primary/30 bg-primary/5 px-4 py-3 text-xs text-foreground flex items-start gap-2.5",children:[o(rr,{className:"h-4 w-4 text-primary mt-0.5 shrink-0"}),f("div",{children:[o("div",{className:"font-semibold text-foreground",children:"Unrestricted access"}),o("p",{className:"text-foreground-subtle mt-0.5",children:"Admin sessions bypass the per-call scope check. Every protected endpoint is reachable regardless of the list below."})]})]}),o(Iz,{}),o(Az,{username:e.username}),r.length>0&&f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2 border-b border-border",children:[o("div",{className:"text-xs font-semibold text-foreground",children:"Granted scopes"}),o("div",{className:"text-[10px] text-foreground-subtle",children:"Baked into your session token at login; sign out + back in to refresh after changes."})]}),f("div",{className:"grid grid-cols-[100px_1fr_240px] gap-3 px-4 py-2 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border",children:[o("div",{children:"Type"}),o("div",{children:"Target"}),o("div",{children:"Access"})]}),o("ul",{className:"divide-y divide-border",children:r.map((s,a)=>f("li",{className:"grid grid-cols-[100px_1fr_240px] gap-3 px-4 py-2.5 items-center text-xs",children:[o("span",{className:"font-mono text-foreground-subtle",children:s.type}),o("span",{className:"font-mono text-foreground",children:s.type==="device"?s.targets.join(", "):s.target}),o("div",{className:"flex items-center gap-1",children:["view","create","delete"].map(i=>{const l=s.access.includes(i),{icon:c,cls:d}=Mz[i];return f("span",{className:`inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] font-medium ${l?d:"bg-transparent text-foreground-subtle/40 line-through"}`,title:l?`Can ${i}`:`Cannot ${i}`,children:[o(c,{className:"h-3 w-3"}),i]},i)})})]},a))})]}),o("div",{className:"flex justify-end",children:f("button",{onClick:t,className:"inline-flex items-center gap-1.5 rounded border border-border px-2.5 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground transition-colors",children:[o(Zd,{className:"h-3 w-3"}),"Sign out"]})})]})}function Iz(){const e=Te(),[t,n]=_(""),[r,s]=_(""),[a,i]=_(""),[l,c]=_(null),d=Kn({mutationFn:m=>e.changeOwnPassword(m),onSuccess:()=>{c({kind:"success",msg:"Password updated."}),n(""),s(""),i("")},onError:m=>{c({kind:"error",msg:m instanceof Error?m.message:"Update failed"})}}),u=r.length>0&&a.length>0&&r!==a,p=r.length>0&&r.length<8,h=t.length>=1&&r.length>=8&&r===a;return f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2.5 border-b border-border flex items-center gap-2",children:[o(W0,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("div",{className:"text-xs font-semibold text-foreground",children:"Change password"})]}),f("div",{className:"p-4 space-y-3",children:[o(al,{label:"Current password",value:t,onChange:n,autoComplete:"current-password"}),o(al,{label:"New password",value:r,onChange:s,autoComplete:"new-password",hint:"At least 8 characters."}),o(al,{label:"Confirm new password",value:a,onChange:i,autoComplete:"new-password"}),(u||p)&&o("div",{className:"text-[11px] text-danger",children:u?"Passwords do not match.":"New password must be at least 8 characters."}),l&&f("div",{className:`text-[11px] flex items-center gap-1 ${l.kind==="success"?"text-emerald-500":"text-danger"}`,children:[l.kind==="success"?o(xo,{className:"h-3 w-3"}):o(nr,{className:"h-3 w-3"}),l.msg]}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{c(null),d.mutate({currentPassword:t,newPassword:r})},disabled:!h||d.isPending,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[d.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Yd,{className:"h-3 w-3"}),"Update password"]})})]})]})}function al({label:e,value:t,onChange:n,autoComplete:r,hint:s}){return f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:e}),o("input",{type:"password",value:t,onChange:a=>n(a.target.value),autoComplete:r,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"}),s&&o("div",{className:"text-[10px] text-foreground-subtle",children:s})]})}function Az({username:e}){const t=Te(),n=Ln({queryKey:["auth","getOwnTotpStatus"],queryFn:()=>t.getOwnTotpStatus()}),r=n.data,[s,a]=_(null),[i,l]=_(""),[c,d]=_(null),[u,p]=_(!1),h=Kn({mutationFn:()=>t.setupOwnTotp(),onSuccess:y=>{a({secret:y.secret,otpauthUrl:y.otpauthUrl}),l(""),d(null)},onError:y=>d(y instanceof Error?y.message:"Setup failed")}),m=Kn({mutationFn:y=>t.confirmOwnTotp(y),onSuccess:()=>{a(null),l(""),d(null),n.refetch()},onError:y=>d(y instanceof Error?y.message:"Confirmation failed — code did not match")}),g=Kn({mutationFn:()=>t.disableOwnTotp(),onSuccess:()=>{d(null),n.refetch()},onError:y=>d(y instanceof Error?y.message:"Disable failed")});Y(()=>{if(!u)return;const y=setTimeout(()=>p(!1),1500);return()=>clearTimeout(y)},[u]);const b=H(()=>n.isLoading?"loading":s?"setup_in_progress":r?.enabled?"enrolled":"not_enrolled",[n.isLoading,r?.enabled,s]),x=()=>{s&&navigator.clipboard.writeText(s.secret).then(()=>p(!0))};return f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2.5 border-b border-border flex items-center gap-2",children:[o(An,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("div",{className:"text-xs font-semibold text-foreground",children:"Two-factor authentication"})]}),f("div",{className:"p-4 space-y-3",children:[b==="loading"&&f("div",{className:"flex items-center gap-2 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Checking status…"]}),b==="not_enrolled"&&f(me,{children:[o("div",{className:"text-xs text-foreground-subtle",children:"2FA isn't active on your account. Enable it to require a 6-digit code from your authenticator app at every login."}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{d(null),h.mutate()},disabled:h.isPending,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[h.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(An,{className:"h-3 w-3"}),"Enable 2FA"]})})]}),b==="setup_in_progress"&&s&&f(me,{children:[f("div",{className:"text-[11px] text-foreground-subtle",children:["Scan the QR code (or enter the secret manually) into your authenticator app for ",o("span",{className:"font-mono",children:e}),", then enter the 6-digit code below to confirm."]}),f("div",{className:"flex flex-col items-center gap-3",children:[o("div",{className:"rounded-lg border border-border bg-white p-3",children:o(Cz,{value:s.otpauthUrl,size:180})}),f("div",{className:"w-full",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle mb-1",children:"Secret (manual entry)"}),f("div",{className:"flex items-center gap-2 rounded border border-border bg-surface-hover/30 px-2 py-1.5",children:[o("code",{className:"text-[11px] font-mono text-foreground break-all flex-1",children:s.secret}),f("button",{onClick:x,className:"inline-flex items-center gap-1 text-[10px] text-foreground-subtle hover:text-foreground",children:[u?o(xo,{className:"h-3 w-3 text-emerald-500"}):o(aa,{className:"h-3 w-3"}),u?"Copied":"Copy"]})]})]})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"6-digit code"}),o("input",{type:"text",inputMode:"numeric",autoComplete:"one-time-code",placeholder:"123456",value:i,onChange:y=>l(y.target.value.replace(/\D/g,"").slice(0,6)),className:"w-full rounded-md border border-border bg-surface px-3 py-2 text-center text-lg font-mono tracking-widest text-foreground focus:outline-none focus:ring-2 focus:ring-primary"})]}),c&&f("div",{className:"text-[11px] text-danger flex items-center gap-1",children:[o(nr,{className:"h-3 w-3"}),c]}),f("div",{className:"flex justify-end gap-2",children:[o("button",{onClick:()=>{a(null),d(null),l("")},className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:()=>{d(null),m.mutate({code:i})},disabled:m.isPending||i.length!==6,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[m.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(xo,{className:"h-3 w-3"}),"Confirm"]})]})]}),b==="enrolled"&&r&&f(me,{children:[f("div",{className:"rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5 flex items-start gap-2.5",children:[o(xo,{className:"h-4 w-4 mt-0.5 text-emerald-500 shrink-0"}),f("div",{className:"text-xs text-foreground space-y-0.5",children:[o("div",{className:"font-medium",children:"2FA is active"}),f("div",{className:"text-foreground-subtle",children:["Enrolled on ",r.confirmedAt?new Date(r.confirmedAt).toLocaleString():"—"]})]})]}),c&&f("div",{className:"text-[11px] text-danger flex items-center gap-1",children:[o(nr,{className:"h-3 w-3"}),c]}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{d(null),g.mutate()},disabled:g.isPending,className:"rounded bg-danger px-3 py-1.5 text-xs font-medium text-white hover:bg-danger/90 disabled:opacity-50 inline-flex items-center gap-1",children:[g.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(An,{className:"h-3 w-3"}),"Disable 2FA"]})})]})]})]})}function Pz(){return o(tt,{children:o("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:o(tn,{limit:500,maxHeight:"max-h-[calc(100vh-250px)]",showScope:!0,showFilters:!0})})})}function ri({tabs:e,defaultTab:t}){const[n,r]=Ga(),s=n.get("tab"),a=t??e[0]?.id??"",i=e.some(d=>d.id===s)?s:a,l=e.find(d=>d.id===i)??e[0],c=d=>{const u=new URLSearchParams(n);u.set("tab",d),r(u,{replace:!0})};return f("div",{className:"space-y-3",children:[o("div",{className:"flex border-b border-border",children:e.map(d=>{const u=d.icon,p=d.id===i;return f("button",{onClick:()=>c(d.id),className:`flex items-center gap-1.5 px-3 py-2 text-xs font-medium border-b-2 transition-colors ${p?"border-primary text-primary":"border-transparent text-foreground-subtle hover:text-foreground"}`,children:[u&&o(u,{className:"h-3.5 w-3.5"}),d.label]},d.id)})}),o("div",{children:l?.content})]})}function _z({userId:e,username:t,onClose:n}){const r=ke(),s=nt(),a=Fy({userId:e}),i=a.data,l=()=>r.invalidateQueries({queryKey:[["userManagement","getTotpStatus"]]}),c=zy({onSuccess:()=>{l(),n()}}),d=a.isLoading?"loading":i?.enabled?"enrolled":"not_enrolled",u=async()=>{await s({title:"Remove 2FA",message:`Remove two-factor authentication for "${t}"? They'll be able to log in with just their password until they re-enroll from their own profile page.`,confirmLabel:"Remove",variant:"danger"})&&c.mutate({userId:e})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm p-4",children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl overflow-hidden",children:[f("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[f("div",{className:"flex items-center gap-2",children:[o(An,{className:"h-4 w-4 text-primary"}),f("div",{children:[o("div",{className:"text-sm font-medium text-foreground",children:"Two-factor authentication"}),f("div",{className:"text-[11px] text-foreground-subtle",children:["User: ",o("span",{className:"font-mono",children:t})]})]})]}),o("button",{onClick:n,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-4",children:[d==="loading"&&f("div",{className:"flex items-center gap-2 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Checking status…"]}),d==="not_enrolled"&&f("div",{className:"rounded-md border border-border bg-surface-hover/30 px-3 py-2.5 flex items-start gap-2.5 text-xs text-foreground-subtle",children:[o(rr,{className:"h-4 w-4 mt-0.5 shrink-0"}),f("div",{children:[o("div",{className:"font-medium text-foreground",children:"2FA not enrolled"}),o("p",{className:"mt-0.5",children:"Only the user themselves can enable 2FA, from their own profile page."})]})]}),d==="enrolled"&&i&&f(me,{children:[f("div",{className:"rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5 flex items-start gap-2.5",children:[o(xo,{className:"h-4 w-4 mt-0.5 text-emerald-500 shrink-0"}),f("div",{className:"text-xs text-foreground space-y-0.5",children:[o("div",{className:"font-medium",children:"2FA is active"}),f("div",{className:"text-foreground-subtle",children:["Enrolled on ",i.confirmedAt?new Date(i.confirmedAt).toLocaleString():"—"]})]})]}),o("div",{className:"text-[11px] text-foreground-subtle",children:"Removing here clears the server-side secret. Use this only when the user has lost access — they'll have to re-enroll from their profile page afterwards."}),f("div",{className:"flex justify-end gap-2",children:[o(Be,{onClick:n,variant:"secondary",children:"Close"}),f("button",{onClick:u,disabled:c.isPending,className:"rounded bg-danger px-3 py-1.5 text-xs font-medium text-white hover:bg-danger/90 disabled:opacity-50 inline-flex items-center gap-1",children:[c.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Fe,{className:"h-3 w-3"}),"Remove 2FA"]})]})]})]})]})})}function $z(){const e=ke(),{user:t}=nn(),[n,r]=_(!1),[s,a]=_(""),[i,l]=_(""),[c,d]=_(!1),[u,p]=_(null),{data:h,isLoading:m,isError:g}=vd(),b=nt(),x=()=>e.invalidateQueries({queryKey:[["userManagement","listUsers"]]}),y=Py({onSuccess:()=>{x(),r(!1),a(""),l(""),d(!1),p(null)},onError:D=>{p(D instanceof Error?D.message:"Failed to create user")}}),w=$y({onSuccess:x}),v=_y({onSuccess:x}),N=wd({onSuccess:x}),k=Dy({onSuccess:()=>{x(),E(null)}}),[C,E]=_(null),[I,A]=_(null),z=h??[];async function P(D){await b({title:"Delete user",message:`Permanently delete user "${D.username}"? This cannot be undone — any active sessions will be revoked on next request.`,confirmLabel:"Delete",variant:"danger"})&&w.mutate({id:D.id})}async function B(D){const T=window.prompt(`New password for "${D.username}":`);if(!T)return;if(T.length<8){window.alert("Password must be at least 8 characters.");return}await b({title:"Reset password",message:`Reset the password for "${D.username}"? They will need to use the new password on their next login.`,confirmLabel:"Reset"})&&N.mutate({id:D.id,newPassword:T})}function R(D,T){T!==D.isAdmin&&v.mutate({id:D.id,isAdmin:T})}function M(D){return D?new Date(typeof D=="number"?D:String(D)).toLocaleDateString("en-GB",{day:"2-digit",month:"short",year:"numeric"}):"—"}return f(tt,{children:[o("div",{className:"flex items-center justify-end",children:f("button",{onClick:()=>r(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground shadow-sm hover:bg-primary/90",children:[o(Et,{className:"h-3.5 w-3.5"}),"Create User"]})}),n&&f("div",{className:"rounded-lg border border-border bg-surface p-4 space-y-3",children:[f("div",{className:"flex items-center justify-between",children:[o("span",{className:"text-xs font-medium text-foreground",children:"New User"}),o("button",{onClick:()=>r(!1),className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"grid grid-cols-3 gap-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Username"}),o("input",{type:"text",value:s,onChange:D=>a(D.target.value),placeholder:"john",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Password"}),o("input",{type:"password",value:i,onChange:D=>l(D.target.value),placeholder:"••••••••",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Admin"}),f("label",{className:"flex items-center gap-2 rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground cursor-pointer",children:[o("input",{type:"checkbox",checked:c,onChange:D=>d(D.target.checked),className:"rounded border-border focus:ring-primary"}),o("span",{className:"text-foreground-subtle",children:"Unrestricted access"})]})]})]}),u&&o("p",{className:"text-[10px] text-danger",children:u}),f("div",{className:"flex justify-end gap-2",children:[o("button",{onClick:()=>r(!1),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),o("button",{onClick:()=>y.mutate({username:s,password:i,isAdmin:c}),disabled:y.isPending||!s||!i,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:y.isPending?"Creating...":"Create"})]})]}),m&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading..."}),g&&o("div",{className:"text-xs text-danger",children:"Failed to load"}),!m&&!g&&z.length===0&&o("div",{className:"text-xs text-foreground-subtle",children:"No data"}),(()=>{const D=L=>w.isPending&&w.variables?.id===L.id||v.isPending&&v.variables?.id===L.id||N.isPending&&N.variables?.id===L.id;return o(Da,{columns:[{key:"username",header:"Username",render:L=>L.username},{key:"isAdmin",header:"Admin",render:L=>f("label",{className:"inline-flex items-center gap-1.5 text-xs cursor-pointer",children:[o("input",{type:"checkbox",checked:L.isAdmin,onChange:O=>R(L,O.target.checked),disabled:D(L),className:"rounded border-border focus:ring-primary disabled:opacity-50"}),o("span",{className:L.isAdmin?"text-primary font-medium":"text-foreground-subtle",children:L.isAdmin?"Admin":"Regular"})]})},{key:"scopes",header:"Scopes",render:L=>{if(L.isAdmin)return o("span",{className:"text-[10px] text-foreground-subtle italic",children:"unscoped"});const O=L.scopes??[];return f("button",{onClick:()=>E(L),className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground",title:"Edit scope grants",children:[o(mn,{className:"h-3 w-3"}),O.length===0?"no access":`${O.length} grant${O.length===1?"":"s"}`]})}},{key:"createdAt",header:"Created",render:L=>o("span",{className:"text-foreground-subtle",children:M(L.createdAt)})},{key:"actions",header:"Actions",align:"right",render:L=>{const O=D(L),F=L.id!==t?.id&&L.totpEnabled;return f("div",{className:"flex items-center justify-end gap-1",children:[F&&f("button",{onClick:()=>A(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground disabled:opacity-50",title:"Remove two-factor authentication",children:[o(An,{className:"h-3 w-3"}),"Remove 2FA"]}),f("button",{onClick:()=>B(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground disabled:opacity-50",title:"Reset password",children:[o(k6,{className:"h-3 w-3"}),"Reset password"]}),f("button",{onClick:()=>P(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",title:"Delete user",children:[O?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Delete"]})]})}}],rows:z,rowKey:L=>L.id,minWidthPx:560})})(),I&&o(_z,{userId:I.id,username:I.username,onClose:()=>A(null)}),C&&o(Dz,{user:C,onClose:()=>E(null),onSubmit:D=>k.mutate({userId:C.id,scopes:D}),submitting:k.isPending})]})}function Dz(e){const{user:t}=nn(),n=t?.isAdmin===!0;return o(Tz,{...e,callerScopes:n?null:t?.scopes??[]})}function Tz({user:e,onClose:t,onSubmit:n,submitting:r,callerScopes:s}){const a=H(()=>(e.scopes??[]).map(d=>({...d,access:[...d.access]})),[e.scopes]),[i,l]=_(a),c=Dd(i);return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:f("div",{className:"w-full max-w-2xl rounded-lg border border-border bg-surface shadow-xl",children:[f("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[f("div",{children:[f("div",{className:"text-sm font-semibold text-foreground",children:["Edit scopes — ",e.username]}),o("div",{className:"text-[10px] text-foreground-subtle",children:e.isAdmin?"Admin users bypass the scope check; this list is ignored.":"Pick which capabilities this user can call, and which access flavours within each."})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"px-4 py-4",children:[o($d,{value:i,onChange:l,clampToParent:s,emptyHint:f(me,{children:["No scopes granted. ",o("span",{className:"font-medium text-foreground",children:e.username})," cannot call any protected endpoint until a scope is added."]})}),c&&o("p",{className:"mt-2 text-[10px] text-danger",children:c})]}),f("div",{className:"flex items-center justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),o("button",{onClick:()=>n(i),disabled:r||c!==null,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:r?o(Se,{className:"h-3 w-3 animate-spin"}):"Save scopes"})]})]})})}const Lz="bg-primary/10 text-primary",Rz="bg-foreground-subtle/10 text-foreground-subtle";function ko(e){if(!e)return"—";const t=new Date(e);return Number.isNaN(t.getTime())?"—":t.toLocaleString()}function Oz(e){return e?e==="*"?"*":e.join(", "):""}function Bz(){const e=ke(),t=nt(),{data:n,isLoading:r}=Ty(),{data:s}=vd(),a=H(()=>n??[],[n]),i=H(()=>s??[],[s]),l=()=>e.invalidateQueries({queryKey:[["userManagement","listApiKeys"]]}),c=()=>e.invalidateQueries({queryKey:[["userManagement","listScopedTokens"]]}),[d,u]=_(!1),[p,h]=_(null),m=Ly({onSuccess:l}),g=Ry({onSuccess:({token:w,record:v})=>{c(),u(!1),h({token:w,label:v.name})}}),b=Oy({onSuccess:c}),x=async(w,v)=>{await t({title:`Revoke "${v}"?`,message:"Any client using this token will lose access immediately. This cannot be undone.",confirmLabel:"Revoke",variant:"danger"})&&m.mutate({id:w})},y=async(w,v)=>{await t({title:`Revoke "${v}"?`,message:"The scoped token will be invalid on its next use.",confirmLabel:"Revoke",variant:"danger"})&&b.mutate({id:w})};return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o("p",{className:"text-xs text-foreground-subtle max-w-2xl",children:"Issue scoped tokens to grant a user a narrow surface — a specific addon, integration, or capability. Every token MUST be scoped: revoking it has predictable blast radius."}),f("button",{onClick:()=>u(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",disabled:i.length===0,title:i.length===0?"Create a user first":"Issue a scoped token",children:[o(mn,{className:"h-3.5 w-3.5"}),"New token"]})]}),f(Af,{title:"Scoped tokens",subtitle:"Grouped per user",children:[i.length===0&&o(Fz,{text:"No users yet — scoped tokens are issued on behalf of an existing user."}),i.map(w=>o(jz,{userId:w.id,username:w.username,onRevoke:(v,N)=>{y(v,N)},revokePending:b.isPending,revokeId:b.variables?.id},w.id))]}),a.length>0&&o(Af,{title:"Legacy API keys",subtitle:`${a.length} pre-existing — revoke only`,children:o(Vv,{headers:["Label","Admin","Prefix","Allowed providers","Created","Last used",""],rows:a.map(w=>{const v=!!w.isAdmin,N=m.isPending&&m.variables?.id===w.id;return f("tr",{className:"hover:bg-primary/5",children:[o("td",{className:"px-3 py-2 text-foreground border-b border-border font-medium",children:w.label}),o("td",{className:"px-3 py-2 text-foreground border-b border-border",children:o("span",{className:`inline-block rounded px-2 py-0.5 text-[10px] uppercase tracking-wide ${v?Lz:Rz}`,children:v?"admin":"regular"})}),f("td",{className:"px-3 py-2 text-foreground border-b border-border font-mono text-[11px]",children:[w.tokenPrefix,"…"]}),o("td",{className:"px-3 py-2 text-foreground border-b border-border text-foreground-subtle",children:Oz(w.allowedProviders)||"all"}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(w.createdAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(w.lastUsedAt)}),o("td",{className:"px-3 py-2 border-b border-border text-right",children:f("button",{onClick:()=>{x(w.id,w.label)},disabled:N,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",title:"Revoke",children:[N?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Revoke"]})})]},w.id)})})}),r&&o(zz,{}),d&&o(Vz,{users:i.map(w=>({id:w.id,username:w.username})),onClose:()=>u(!1),onSubmit:w=>g.mutate({userId:w.userId,name:w.name,scopes:w.scopes,...w.expiresAt!==void 0?{expiresAt:w.expiresAt}:{}}),submitting:g.isPending}),p&&o(Hz,{token:p.token,label:p.label,onClose:()=>h(null)})]})}function Af({title:e,subtitle:t,children:n}){return f("div",{className:"space-y-2",children:[f("div",{className:"flex items-baseline justify-between",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e}),t&&o("span",{className:"text-[10px] text-foreground-subtle",children:t})]}),n]})}function zz(){return o("div",{className:"space-y-2",children:[1,2].map(e=>o("div",{className:"h-10 rounded border border-border bg-surface animate-pulse"},e))})}function Fz({text:e}){return o("div",{className:"rounded border border-dashed border-border bg-surface px-3 py-4 text-xs text-foreground-subtle text-center",children:e})}function Vv({headers:e,rows:t}){return o("div",{className:"rounded-lg border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{children:o("tr",{children:e.map((n,r)=>o("th",{className:`px-3 py-2 text-foreground-subtle font-medium bg-surface border-b border-border whitespace-nowrap ${r===e.length-1?"text-right":"text-left"}`,children:n},r))})}),o("tbody",{children:t})]})})}function jz({userId:e,username:t,onRevoke:n,revokePending:r,revokeId:s}){const{data:a,isLoading:i}=By({userId:e}),l=a??[];return i||l.length===0?null:f("div",{className:"space-y-1.5",children:[o("div",{className:"text-[11px] font-medium text-foreground",children:t}),o(Vv,{headers:["Name","Prefix","Scopes","Expires","Last used","Created",""],rows:l.map(c=>{const d=r&&s===c.id;return f("tr",{className:"hover:bg-primary/5",children:[o("td",{className:"px-3 py-2 text-foreground border-b border-border font-medium",children:c.name}),f("td",{className:"px-3 py-2 text-foreground border-b border-border font-mono text-[11px]",children:[c.tokenPrefix,"…"]}),o("td",{className:"px-3 py-2 text-foreground border-b border-border",children:o("div",{className:"flex flex-wrap gap-1",children:c.scopes.map((u,p)=>f("span",{className:"inline-block rounded bg-foreground-subtle/10 px-1.5 py-0.5 text-[10px] font-mono",children:[u.type,":",u.type==="device"?`[${u.targets.join(",")}]`:u.target]},p))})}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.expiresAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.lastUsedAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.createdAt)}),o("td",{className:"px-3 py-2 border-b border-border text-right",children:f("button",{onClick:()=>n(c.id,c.name),disabled:d,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",children:[d?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Revoke"]})})]},c.id)})})]})}function Vz({users:e,onClose:t,onSubmit:n,submitting:r}){const{user:s}=nn(),i=s?.isAdmin===!0?null:s?.scopes??[],[l,c]=_(e[0]?.id??""),[d,u]=_(""),[p,h]=_([{type:"capability",target:"",access:["view","create"]}]),[m,g]=_(""),b=Dd(p),x=l!==""&&d.trim().length>0&&p.length>0&&b===null&&!r,y=()=>{const w=parseInt(m,10),v=Number.isFinite(w)&&w>0?Date.now()+w*864e5:void 0;n({userId:l,name:d.trim(),scopes:p,expiresAt:v})};return f(Hv,{title:"Create scoped token",onClose:t,children:[f("div",{className:"space-y-3",children:[o(Is,{label:"On behalf of user",children:o("select",{value:l,onChange:w=>c(w.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary",children:e.map(w=>o("option",{value:w.id,children:w.username},w.id))})}),o(Is,{label:"Name",children:o("input",{value:d,onChange:w=>u(w.target.value),placeholder:"cloudflare-tunnel-route",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary"})}),f(Is,{label:"Scopes",hint:"Each scope picks a (cap or addon) target + one or more access flavours. The token can access ONLY what's listed.",children:[o($d,{value:p,onChange:h,clampToParent:i}),b&&o("p",{className:"mt-1 text-[10px] text-danger",children:b})]}),o(Is,{label:"Expires in (days)",hint:"Leave blank for non-expiring.",children:o("input",{type:"number",min:1,value:m,onChange:w=>g(w.target.value),placeholder:"30",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary"})})]}),f(qv,{children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:y,disabled:!x,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[r?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(mn,{className:"h-3.5 w-3.5"}),"Issue token"]})]})]})}function Hz({token:e,label:t,onClose:n}){const[r,s]=_(!1),a=async()=>{try{await navigator.clipboard.writeText(e),s(!0)}catch{}};return f(Hv,{title:`Token: ${t}`,onClose:n,children:[f("div",{className:"space-y-3",children:[o("div",{className:"rounded border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning",children:"Copy this token now. Once you close this dialog the secret cannot be displayed again."}),o("div",{className:"rounded border border-border bg-background p-2 font-mono text-[11px] break-all select-all",children:e})]}),f(qv,{children:[f("button",{onClick:()=>{a()},className:"inline-flex items-center gap-1.5 rounded bg-surface border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-primary/5 hover:border-primary/30",children:[r?o(_t,{className:"h-3.5 w-3.5 text-primary"}):o(aa,{className:"h-3.5 w-3.5"}),r?"Copied":"Copy"]}),o("button",{onClick:n,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:"Done"})]})]})}function Hv({title:e,onClose:t,children:n}){return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:r=>r.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),o("div",{className:"p-4",children:n})]})})}function qv({children:e}){return o("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:e})}function Is({label:e,hint:t,children:n}){return f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:e}),n,t&&o("p",{className:"text-[10px] text-foreground-subtle",children:t})]})}function qz({addonId:e,fallback:t,tileClassName:n,iconPath:r="assets/icon.svg"}){const[s,a]=_(!1),i=`/api/addon-assets/${e}/${r}`;return o("div",{className:`h-10 w-10 rounded-lg flex items-center justify-center shrink-0 ${n}`,children:s?o(t,{className:"h-5 w-5"}):o("img",{src:i,alt:e,className:"h-6 w-6",onError:()=>a(!0)})})}function Uz({addonId:e,defaultActivity:t,showActivity:n=!0,maxHeight:r="max-h-64",defaultTab:s}){const a=t??(s==="events"?"events":"logs"),[i,l]=_(a);return f("div",{className:"flex flex-col gap-4",children:[o(to,{nodeId:"hub",addonIds:[e],level:"global"}),n&&f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border bg-surface-hover/20",children:[o("span",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",children:"Activity"}),f("div",{className:"flex items-center gap-1",children:[o(Pf,{kind:"logs",active:i==="logs",onClick:()=>l("logs")}),o(Pf,{kind:"events",active:i==="events",onClick:()=>l("events")})]})]}),i==="logs"?o(tn,{addonId:e,maxHeight:r,showFilters:!1}):o(br,{addonId:e,category:"addon.*",maxHeight:r})]})]})}function Pf({kind:e,active:t,onClick:n}){return f("button",{onClick:n,className:`inline-flex items-center gap-1 rounded px-2 py-0.5 text-[11px] font-medium transition-colors ${t?"bg-primary/10 text-primary":"text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[o(e==="logs"?at:Jo,{className:"h-3 w-3"}),e==="logs"?"Logs":"Events"]})}function ns(e){const{title:t,subtitle:n,pageIcon:r,itemIcon:s,capability:a,installButtonLabel:i="Add addon",items:l,isLoading:c,emptyTitle:d="No addons installed for this capability",emptyDescription:u,itemIconColor:p,renderStatusBadges:h,renderPrimaryAction:m,itemError:g,renderExpandedPanel:b,workspaceMaxHeight:x="max-h-72",trailing:y,showChrome:w=!1}=e,v=l.length>1,[N,k]=_(()=>l[0]?.addonId??null);Y(()=>{N&&(l.some(I=>I.addonId===N)||k(l[0]?.addonId??null))},[l,N]);const C=I=>k(A=>A===I?null:I),E=`/system/addons?capability=${encodeURIComponent(a)}`;return o(tt,{icon:w?r:void 0,title:w?t:void 0,subtitle:w?n:void 0,actions:w?o(sa,{to:E,children:f(Be,{variant:"primary",size:"sm",children:[o(Et,{className:"h-3.5 w-3.5 mr-1"}),i]})}):void 0,children:c?o(un,{children:o("div",{className:"p-6 text-sm text-foreground-subtle",children:"Loading…"})}):l.length===0?o(un,{children:o(Wc,{title:d,description:u??`Install an addon that declares the "${a}" capability to get started.`,action:w?o(sa,{to:E,children:f(Be,{variant:"primary",size:"sm",children:[o(Et,{className:"h-3.5 w-3.5 mr-1"}),i]})}):void 0})}):f("div",{className:"flex flex-col gap-4",children:[l.map(I=>{const A=!v||N===I.addonId,z=p?.(I)??(I.isActive?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"),P=g?.(I)??null;return f(un,{children:[f("div",{className:`flex items-center gap-3 p-4 ${A?"border-b border-border":""}`,children:[v&&o("button",{type:"button",onClick:()=>C(I.addonId),"aria-label":A?"Collapse":"Expand",className:"shrink-0 p-1 rounded hover:bg-foreground-subtle/10 transition-colors",children:o(lt,{className:`h-4 w-4 text-foreground-subtle transition-transform ${A?"rotate-180":""}`})}),f("button",{type:"button",onClick:()=>v&&C(I.addonId),className:`flex items-center gap-4 flex-1 min-w-0 text-left ${v?"hover:opacity-80 transition-opacity":""}`,disabled:!v,children:[o(qz,{addonId:I.addonId,fallback:s,tileClassName:z}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("span",{className:"font-semibold text-foreground",children:I.displayName}),o(Qz,{isActive:I.isActive}),h?.(I)]}),f("div",{className:"text-xs text-foreground-subtle mt-1 font-mono",children:["@camstack/addon-",I.addonId]})]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[m?.(I),o(Gz,{capName:a,addonId:I.addonId,isActive:I.isActive}),o(Kz,{addonId:I.addonId,displayName:I.displayName})]})]}),A&&f("div",{className:"p-4 flex flex-col gap-3",children:[P!==null&&o(Oa,{message:P}),b?.(I),o(Uz,{addonId:I.addonId,maxHeight:x})]})]},I.addonId)}),y]})})}function Qz({isActive:e}){return o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${e?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:e?"Enabled":"Disabled"})}function Gz({capName:e,addonId:t,isActive:n}){const r=ke(),s=bb({onSuccess:()=>{r.invalidateQueries({queryKey:[["addons","listCapabilityProviders"]]})}}),a=s.isPending;return f(Be,{size:"sm",variant:n?"secondary":"primary",disabled:a,onClick:()=>s.mutate({capName:e,addonId:t,enabled:!n}),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):n?o(ts,{className:"h-3 w-3"}):o(Ya,{className:"h-3 w-3"}),n?"Disable":"Enable"]})}function Kz({addonId:e,displayName:t}){const n=ke(),r=Ko({onSuccess:()=>{n.invalidateQueries({queryKey:[["addons","listCapabilityProviders"]]})}});return o(Ad,{label:"Restart",icon:ct,size:"sm",title:`Restart "${t}"?`,description:"Restarting the addon bounces its subprocess — the provider will briefly drop and reconnect automatically.",confirmLabel:"Restart",triggerVariant:"ghost",confirmVariant:"danger",disabled:r.isPending,action:()=>r.mutateAsync({addonId:e})})}const _f=3e4;function Wz(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function Yz(e){return e==="local-auth"?{headline:"Username + password (local).",icon:w6,bullets:["Users live in the hub’s SQLite database — no IdP roundtrip.","TOTP / 2FA can be enrolled per-user from the Users page (added in v0.4).","API keys + scoped tokens are managed from the API Keys page."],setupSteps:["Add users from Users → New user (or seed via CAMSTACK_ADMIN_USER / CAMSTACK_ADMIN_PASS).","Hand out either passwords or scoped tokens — both validate through this provider."]}:e.startsWith("auth-oidc")?{headline:"OpenID Connect (Google, Microsoft, Okta, Keycloak, …).",icon:_n,bullets:["Three-leg redirect flow with PKCE S256 + nonce.","id_token is signature-verified against the IdP’s JWKS — no implicit trust.","First-time sign-ins are auto-provisioned with the configured Default Role."],setupSteps:["Register a web app at your IdP and copy the client_id + client_secret.","Set the redirect URI to `https://<this-hub>/addon/<addon-id>/callback`.","Paste issuer + credentials in the Settings panel below — saves on every change."]}:e.startsWith("auth-saml")?{headline:"SAML 2.0 — enterprise SSO (Azure AD, Okta, OneLogin).",icon:_n,bullets:["Heavier handshake than OIDC — exchange metadata XML with your IdP.","Group → role mapping via SAML assertions."]}:e.startsWith("auth-webauthn")||e.startsWith("auth-passkey")?{headline:"Passkeys / WebAuthn — passwordless second factor.",icon:An,bullets:["Enroll a YubiKey, Touch ID, or platform passkey per user.","Resistant to phishing — the browser binds the credential to your hub origin."]}:e.startsWith("auth-totp")||e.startsWith("auth-magic-link")?{headline:"TOTP / magic-link — second factor or passwordless sign-in.",icon:An,bullets:["Codes / links delivered out-of-band (RFC 6238 for TOTP).","Compatible with Google Authenticator, Aegis, 1Password, Bitwarden, etc."]}:{headline:"Authentication provider.",icon:mn,bullets:["Generic authentication provider. No additional hints registered."]}}function Zz(){const e=Go({capName:"auth-provider"},{refetchInterval:_f}),t=wn(void 0,{refetchInterval:_f}),n=H(()=>Wz(t.data??[]),[t.data]),r=H(()=>(e.data??[]).map(s=>({addonId:s.addonId,displayName:n.get(s.addonId)??s.addonId,isActive:s.isActive})),[e.data,n]);return o(ns,{title:"Authentication",subtitle:"Identity providers exposed to the admin UI. Multiple providers can run in parallel — operators pick which to enable. Disabling a provider only removes that external login method; local password login is unaffected. Each provider’s settings + live logs are inline below.",pageIcon:mn,itemIcon:mn,capability:"auth-provider",installButtonLabel:"Add provider",items:r,isLoading:e.isLoading,emptyTitle:"No authentication providers registered",emptyDescription:"Local auth should always be available — if this list is empty the local-auth builtin failed to register. Check the Addons page for load errors.",renderExpandedPanel:s=>o(Xz,{addonId:s.addonId})})}function Xz({addonId:e}){const t=Yz(e),n=t.icon;return f("div",{className:"rounded-lg border border-border bg-surface p-4 space-y-3",children:[f("div",{className:"flex items-start gap-2.5",children:[o(n,{className:"h-4 w-4 mt-0.5 text-primary shrink-0"}),o("div",{className:"text-xs text-foreground font-medium",children:t.headline})]}),o("ul",{className:"text-xs text-foreground-subtle space-y-1.5 pl-6 list-disc",children:t.bullets.map((r,s)=>o("li",{children:r},s))}),t.setupSteps&&t.setupSteps.length>0&&f("div",{className:"rounded-md border border-border bg-surface-hover/40 px-3 py-2.5 space-y-1.5",children:[f("div",{className:"flex items-center gap-1.5 text-[10px] font-semibold text-foreground-subtle uppercase tracking-wide",children:[o(SR,{className:"h-3 w-3"}),"Setup steps"]}),o("ol",{className:"text-xs text-foreground space-y-0.5 pl-4 list-decimal",children:t.setupSteps.map((r,s)=>o("li",{children:r},s))})]}),e==="local-auth"&&f("div",{className:"rounded-md border border-blue-500/30 bg-blue-500/5 px-3 py-2 flex items-start gap-2 text-[11px] text-foreground",children:[o(rr,{className:"h-3.5 w-3.5 mt-0.5 text-blue-500 shrink-0"}),f("span",{children:["TOTP / 2FA settings are exposed per-user from the"," ",o("a",{href:"/system/users",className:"underline text-primary",children:"Users"})," page (added in v0.4). Enable for each user via the Actions column → “Enable TOTP”."]})]})]})}function Jz(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"users",label:"Users",icon:qO,content:o($z,{})},{id:"api-keys",label:"Tokens",icon:W0,content:o(Bz,{})},{id:"authentication",label:"Authentication",icon:mn,content:o(Zz,{})}]})})}const sc=5e3,eF={connected:!1,endpoint:null};function tF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function nF(){const e=ke(),t=Go({capName:"network-access"},{refetchInterval:sc}),n=wn(void 0,{refetchInterval:sc}),r=H(()=>tF(n.data??[]),[n.data]),s=H(()=>(t.data??[]).map(m=>({addonId:m.addonId,displayName:r.get(m.addonId)??m.addonId,isActive:m.isActive})),[t.data,r]),[a,i]=_(null),[l,c]=_({}),d=(m,g)=>{e.invalidateQueries({queryKey:[["networkAccess"]]}),i(null),c(b=>{const x=g?.addonId;if(x===void 0||!(x in b))return b;const y={...b};return delete y[x],y})},u=(m,g)=>{i(null);const b=g?.addonId;if(b===void 0)return;const x=m instanceof Error?m.message:String(m);c(y=>({...y,[b]:x}))},p=Px({onSuccess:d,onError:u}),h=_x({onSuccess:d,onError:u});return o(ns,{title:"Remote Access",subtitle:"Public-facing tunnels that expose this hub to the internet (Cloudflare Tunnel, ngrok, …). Settings, Logs and Events are docked under every provider.",pageIcon:_n,itemIcon:_n,capability:"network-access",installButtonLabel:"Add tunnel",items:s,isLoading:t.isLoading,emptyTitle:"No remote-access providers installed",emptyDescription:"Install a tunnel addon (e.g. @camstack/addon-cloudflare-tunnel) to expose this hub publicly.",renderStatusBadges:m=>o(rF,{addonId:m.addonId}),itemError:m=>l[m.addonId]??null,renderPrimaryAction:m=>o(oF,{addonId:m.addonId,busyId:a,onStart:g=>{i(g),p.mutate({addonId:g})},onStop:g=>{i(g),h.mutate({addonId:g})}})})}function Uv(e){const{data:t}=$x({addonId:e},{refetchInterval:sc,retry:!1}),n=t?v2.safeParse(t):null;return n?.success?n.data:eF}function rF({addonId:e}){const t=Uv(e);return f(me,{children:[o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t.connected?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:t.connected?"Connected":"Disconnected"}),t.endpoint&&f("a",{href:t.endpoint.url,target:"_blank",rel:"noopener noreferrer",onClick:n=>n.stopPropagation(),className:"text-[10px] text-emerald-700 dark:text-emerald-300 hover:underline flex items-center gap-1",children:[o(Wd,{className:"h-3 w-3"}),t.endpoint.url]})]})}function oF({addonId:e,busyId:t,onStart:n,onStop:r}){const s=Uv(e),a=t===e;return s.connected?f(Be,{size:"sm",variant:"secondary",disabled:a,onClick:()=>r(e),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):o(ts,{className:"h-3 w-3"}),"Stop"]}):f(Be,{size:"sm",variant:"primary",disabled:a,onClick:()=>n(e),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ya,{className:"h-3 w-3"}),"Start"]})}const $f=3e4;function sF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function aF(e){const t=[];for(const n of e)typeof n.urls=="string"?t.push(n.urls):t.push(...n.urls);return t}function iF(){const e=Go({capName:"turn-provider"},{refetchInterval:$f}),t=wn(void 0,{refetchInterval:$f}),n=yd(),r=n.data??[],s=H(()=>sF(t.data??[]),[t.data]),a=H(()=>(e.data??[]).map(i=>({addonId:i.addonId,displayName:s.get(i.addonId)??i.addonId,isActive:i.isActive})),[e.data,s]);return o(ns,{title:"TURN Servers",subtitle:"ICE servers used for WebRTC NAT traversal. Multiple providers can coexist — the WebRTC layer concatenates servers from all enabled providers per session.",pageIcon:$n,itemIcon:$n,capability:"turn-provider",installButtonLabel:"Add provider",items:a,isLoading:e.isLoading,emptyTitle:"No TURN providers installed",emptyDescription:"Install a TURN addon (e.g. @camstack/addon-cloudflare-turn) to enable WebRTC behind restrictive NATs.",renderExpandedPanel:i=>o(lF,{addonId:i.addonId,enabled:i.isActive}),trailing:f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border flex items-center justify-between",children:[f("div",{children:[o("div",{className:"text-sm font-semibold",children:"Combined ICE server list"}),o("div",{className:"text-xs text-foreground-subtle",children:"What the WebRTC layer fetches per-session."})]}),o(Be,{size:"sm",variant:"secondary",onClick:()=>n.refetch(),disabled:n.isFetching,children:"Refresh"})]}),o("div",{className:"p-4",children:r.length===0?o("div",{className:"text-xs text-foreground-subtle",children:"No servers from enabled providers."}):o("div",{className:"flex flex-col gap-3",children:r.map((i,l)=>{const c=Array.isArray(i.urls)?i.urls:[i.urls];return f("div",{className:"rounded border border-border bg-surface",children:[(i.username||i.credential)&&f("div",{className:"px-3 py-1.5 border-b border-border text-[10px] font-mono text-foreground-subtle flex items-center gap-3",children:[i.username&&f("span",{children:[o("span",{className:"text-foreground-subtle",children:"user:"})," ",o("span",{className:"text-foreground",children:i.username})]}),i.credential&&f("span",{title:i.credential,children:[o("span",{className:"text-foreground-subtle",children:"credential:"})," ",o("span",{className:"text-foreground",children:`${i.credential.slice(0,8)}…${i.credential.slice(-4)}`})]})]}),o("ul",{className:"divide-y divide-border",children:c.map(d=>o("li",{className:"px-3 py-1.5 font-mono text-xs text-foreground break-all",children:d},d))})]},l)})})})]})})}function lF({addonId:e,enabled:t}){const n=yd({addonId:e},{enabled:t,retry:!1}),r=H(()=>aF(n.data??[]),[n.data]);return!t||r.length===0?null:f("div",{className:"rounded-lg border border-border bg-surface p-3",children:[f("div",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide mb-2",children:["Discovered ICE servers (",r.length,")"]}),o("div",{className:"flex flex-wrap gap-1",children:r.map(s=>o("span",{className:"inline-block rounded px-1.5 py-0.5 text-[10px] font-mono bg-foreground-subtle/10 text-foreground",children:s},s))})]})}const cF={lan:$n,wifi:or,docker:Wa,vpn:Yd,loopback:hn,other:hn},dF={lan:"LAN",wifi:"Wi-Fi",docker:"Docker",vpn:"VPN",loopback:"Loopback",other:"Other"},uF=["lan","wifi","vpn","docker","other","loopback"];function pF(e){const{interfaces:t,disabled:n,hideLoopback:r,ipv4Only:s,emptyMessage:a}=e,i=H(()=>t.filter(u=>!(r&&u.kind==="loopback"||s&&u.family!=="IPv4")),[t,r,s]),l=H(()=>{const u=new Map;for(const p of i){const h=u.get(p.kind)??[];h.push(p),u.set(p.kind,h)}return uF.filter(p=>u.has(p)).map(p=>({kind:p,items:u.get(p)}))},[i]),c=u=>e.mode==="single"?e.value===u:e.value.includes(u),d=u=>{if(n||u.kind==="loopback")return;if(e.mode==="single"){e.onChange(e.value===u.address?null:u.address);return}const p=new Set(e.value);p.has(u.address)?p.delete(u.address):p.add(u.address),e.onChange([...p])};return i.length===0?o("div",{className:"text-xs text-foreground-subtle italic",children:a??"No addresses available."}):o("div",{className:"flex flex-col gap-3",children:l.map(({kind:u,items:p})=>{const h=cF[u]??hn;return f("div",{className:"rounded-md border border-border overflow-hidden",children:[f("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-surface-hover/30 border-b border-border",children:[o(h,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("span",{className:"text-[11px] font-semibold uppercase tracking-wide text-foreground-subtle",children:dF[u]??u}),f("span",{className:"text-[10px] text-foreground-subtle",children:["· ",p.length]})]}),o("ul",{className:"divide-y divide-border",children:p.map(m=>{const g=c(m.address),b=m.kind==="loopback",x=!m.plausible&&!b;return f("li",{className:`flex items-center gap-3 px-3 py-2 ${b?"opacity-60 cursor-not-allowed":n?"opacity-60":x?"cursor-pointer hover:bg-surface-hover/30 bg-amber-500/[0.04]":"cursor-pointer hover:bg-surface-hover/30"}`,onClick:()=>d(m),children:[o("span",{className:`flex items-center justify-center h-4 w-4 rounded ${e.mode==="single"?"rounded-full":"rounded"} border ${g?"border-primary bg-primary text-primary-foreground":"border-border bg-surface"}`,children:g&&o(_t,{className:"h-3 w-3"})}),f("div",{className:`flex-1 min-w-0 ${x?"text-foreground-subtle":""}`,children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("span",{className:`font-mono text-xs font-semibold ${x?"text-foreground-subtle":"text-foreground"}`,children:m.name}),o("span",{className:"text-[10px] rounded px-1.5 py-0.5 bg-foreground-subtle/10 text-foreground-subtle font-mono",children:m.family}),m.preferred&&o("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-primary/15 text-primary",children:"Auto-preferred"}),b&&o("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-foreground-subtle/15 text-foreground-subtle",children:"Always included"}),x&&f("span",{className:"inline-flex items-center gap-1 text-[10px] rounded-full px-2 py-0.5 font-medium bg-amber-500/15 text-amber-700 dark:text-amber-300",title:m.plausibleReason||void 0,children:[o(it,{className:"h-2.5 w-2.5"}),"Unlikely usable"]})]}),f("div",{className:"text-xs text-foreground-subtle mt-0.5 font-mono break-all",children:[m.address,m.cidr&&m.cidr!==m.address?` (${m.cidr})`:""]})]})]},`${m.name}-${m.family}-${m.address}`)})})]},u)})})}const Df={"lan-ipv4":"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300","lan-ipv6":"bg-violet-500/15 text-violet-700 dark:text-violet-300",public:"bg-blue-500/15 text-blue-700 dark:text-blue-300",loopback:"bg-foreground-subtle/15 text-foreground-subtle"};function fF(){const e=ke(),t=Te(),n=bx(void 0,{refetchInterval:3e4}),r=yx(void 0),s=vx({onSuccess:()=>{e.invalidateQueries({queryKey:[["localNetwork"]]})}}),a=wx({onSuccess:C=>{p(C.addresses),e.invalidateQueries({queryKey:[["localNetwork"]]})}}),i=H(()=>n.data?.interfaces??[],[n.data]),l=typeof window<"u"?Number(window.location.port)||(window.location.protocol==="https:"?443:80):4e3,c=typeof window<"u"&&window.location.protocol==="https:"?"https":"http",d=xx({port:l,scheme:c},{refetchInterval:3e4}),[u,p]=_([]),[h,m]=_(!1);Y(()=>{!h&&r.data&&(p(r.data.addresses),m(!0))},[r.data,h]);const g=r.data?.addresses??[],b=H(()=>{if(u.length!==g.length)return!0;const C=[...u].sort(),E=[...g].sort();return C.some((I,A)=>I!==E[A])},[u,g]),x=()=>{s.mutate({addresses:[...u]})},y=()=>{p(g)},w=()=>{p([])},v=()=>{n.refetch(),d.refetch(),r.refetch()},N=async()=>{try{const C=await t.raceConnectionEndpoints({perCandidateTimeoutMs:1500});console.info("[network-addresses] race result",C)}catch(C){console.warn("[network-addresses] race failed",C)}},k=d.data?.endpoints??[];return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o("p",{className:"text-xs text-foreground-subtle max-w-2xl",children:"Pick the local addresses SDK clients should race for the fastest path to this hub. Empty selection (auto) lets every non-loopback / non-link-local interface participate."}),f("div",{className:"flex items-center gap-2 shrink-0",children:[f(Be,{size:"sm",variant:"secondary",onClick:v,disabled:n.isLoading,children:[o(ct,{className:`h-3 w-3 ${n.isLoading?"animate-spin":""}`}),"Refresh"]}),o(Be,{size:"sm",variant:"secondary",onClick:N,children:"Probe race"})]})]}),f("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border flex items-center justify-between",children:[f("div",{children:[o("div",{className:"text-sm font-semibold",children:"Allowed addresses"}),o("div",{className:"text-xs text-foreground-subtle",children:u.length===0?"Auto — every non-loopback / non-link-local interface participates.":`${u.length} pinned`})]}),f("div",{className:"flex items-center gap-1",children:[f(Be,{size:"sm",variant:"secondary",onClick:()=>a.mutate(void 0),disabled:a.isPending||s.isPending,title:"Re-run the auto-detection heuristic + overwrite the current allowlist with the best matches.",children:[o(_O,{className:"h-3 w-3"}),a.isPending?"Detecting…":"Best match"]}),f(Be,{size:"sm",variant:"secondary",onClick:w,disabled:u.length===0||s.isPending,children:[o(tv,{className:"h-3 w-3"}),"Clear"]}),b&&o(Be,{size:"sm",variant:"secondary",onClick:y,disabled:s.isPending,children:"Discard"}),f(Be,{size:"sm",variant:"primary",onClick:x,disabled:!b||s.isPending,children:[o(fO,{className:"h-3 w-3"}),s.isPending?"Saving…":"Save"]})]})]}),o("div",{className:"p-4",children:o(pF,{mode:"multiple",interfaces:i,value:u,onChange:p,disabled:s.isPending,emptyMessage:n.isLoading?"Loading interfaces…":"No interfaces detected."})})]}),f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border",children:[o("div",{className:"text-sm font-semibold",children:"Connection endpoints — priority order"}),o("div",{className:"text-xs text-foreground-subtle",children:"Live preview of the ranked candidate list the SDK would race against. Updates with each Save."})]}),o("div",{className:"p-4",children:k.length===0?o("div",{className:"text-xs text-foreground-subtle italic",children:d.isLoading?"Loading…":"No endpoints available."}):o("ul",{className:"space-y-1 text-xs",children:k.map(C=>f("li",{className:`flex items-center gap-2 flex-wrap ${C.plausible?"":"opacity-80"}`,children:[o("span",{className:"font-mono text-[10px] w-10 text-foreground-subtle",children:String(C.priority).padStart(4,"0")}),o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${Df[C.kind]??Df.loopback}`,children:C.kind}),C.interfaceKind!=="lan"&&C.interfaceKind!=="public"&&o("span",{className:"text-[10px] rounded px-1.5 py-0.5 bg-foreground-subtle/10 text-foreground-subtle font-medium uppercase",children:C.interfaceKind}),!C.plausible&&C.interfaceKind!=="loopback"&&f("span",{className:"inline-flex items-center gap-1 text-[10px] rounded-full px-2 py-0.5 font-medium bg-amber-500/15 text-amber-700 dark:text-amber-300",title:C.plausibleReason||void 0,children:[o(it,{className:"h-2.5 w-2.5"}),"Unlikely usable"]}),o("span",{className:`font-mono break-all ${C.plausible?"text-foreground":"text-foreground-subtle"}`,children:C.baseUrl}),f("span",{className:"text-foreground-subtle",children:["— ",C.label]})]},`${C.priority}-${C.baseUrl}`))})})]})]})]})}const hF={mesh:"bg-violet-500/15 text-violet-700 dark:text-violet-300",public:"bg-blue-500/15 text-blue-700 dark:text-blue-300"},ac=5e3,mF=3e4,gF={joined:!1,meshIp:"",magicDnsHostname:"",peerCount:0,endpoints:[],tenantName:"",magicDnsSuffix:"",userLogin:null,controlPlaneUrl:"",keyExpiry:null};function bF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function xF(){const e=Go({capName:"mesh-network"},{refetchInterval:ac}),t=wn(void 0,{refetchInterval:ac}),n=H(()=>bF(t.data??[]),[t.data]),r=H(()=>(e.data??[]).map(s=>({addonId:s.addonId,displayName:n.get(s.addonId)??s.addonId,isActive:s.isActive})),[e.data,n]);return o(ns,{title:"Mesh Networks",subtitle:"Private VPN meshes that connect CamStack to your other devices (Tailscale, Headscale, …). Each provider can also expose this hub publicly via its ingress (Tailscale Funnel).",pageIcon:Wa,itemIcon:$n,capability:"mesh-network",installButtonLabel:"Add mesh",items:r,isLoading:e.isLoading,emptyTitle:"No mesh-network providers installed",emptyDescription:"Install a mesh addon (e.g. @camstack/addon-tailscale-client) to join this hub into a private VPN mesh.",renderStatusBadges:s=>o(yF,{addonId:s.addonId}),renderPrimaryAction:s=>o(vF,{addonId:s.addonId}),renderExpandedPanel:s=>o(wF,{addonId:s.addonId})})}function tu(e){const{data:t,isLoading:n}=Nx({addonId:e},{refetchInterval:ac,retry:!1}),r=t?pm.safeParse(t):null;return{status:r?.success?r.data:gF,isLoading:n}}function yF({addonId:e}){const{status:t}=tu(e);return f(me,{children:[o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t.joined?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:t.joined?"Joined":"Not joined"}),t.joined&&f("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-foreground-subtle/15 text-foreground-subtle",children:[t.peerCount," peer",t.peerCount===1?"":"s"]})]})}function vF({addonId:e}){const t=ke(),[n,r]=_(!1),[s,a]=_(null),i=Te(),{status:l}=tu(e),c=U(()=>{t.invalidateQueries({queryKey:[["meshNetwork"]]})},[t]),d=kx(),u=Sx({onSuccess:c}),p=Cx({onSuccess:c}),h=U(async()=>{r(!0);const g={cancelled:!1};a(g);try{const b=await d.mutateAsync({addonId:e});if(g.cancelled)return;b.loginUrl&&window.open(b.loginUrl,"_blank","noopener,noreferrer");const x=Date.now(),y=10*6e4;for(;!g.cancelled&&(await MF(2e3),!g.cancelled);){const w=await i.trpcClient.meshNetwork.getStatus.query({addonId:e}).catch(()=>null),v=w?pm.safeParse(w):null;if(v?.success&&v.data.joined){c();break}if(Date.now()-x>y)break}}finally{r(!1),a(null)}},[e,c,d,i]),m=U(()=>{s&&(s.cancelled=!0),r(!1),a(null)},[s]);return o(me,{children:l.joined?f(me,{children:[f(Be,{size:"sm",variant:"secondary",disabled:u.isPending,onClick:()=>u.mutate({addonId:e}),children:[u.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Zd,{className:"h-3 w-3"}),"Disconnect"]}),f(Be,{size:"sm",variant:"ghost",disabled:p.isPending,onClick:()=>p.mutate({addonId:e}),children:[p.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Hp,{className:"h-3 w-3"}),"Log out"]})]}):n?f(Be,{size:"sm",variant:"ghost",onClick:m,children:[o(Fe,{className:"h-3 w-3 mr-1"})," Cancel"]}):f(me,{children:[f(Be,{size:"sm",variant:"primary",onClick:()=>void h(),children:[o($6,{className:"h-3 w-3"}),"Connect"]}),f(Be,{size:"sm",variant:"ghost",disabled:p.isPending,onClick:()=>p.mutate({addonId:e}),children:[p.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Hp,{className:"h-3 w-3"}),"Log out"]})]})})}function wF({addonId:e}){const{status:t}=tu(e),n=Mx({addonId:e},{refetchInterval:mF,retry:!1});return f("div",{className:"rounded-lg border border-border bg-surface",children:[f("div",{className:"p-4 space-y-4",children:[t.error&&o(Oa,{message:t.error}),o(NF,{status:t}),t.endpoints.length>0&&f("div",{className:"space-y-1.5",children:[o("div",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",children:"Endpoints"}),t.endpoints.map(r=>f("div",{className:"flex items-center gap-2 text-xs flex-wrap",children:[f("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${hF[r.scope]??"bg-foreground-subtle/15 text-foreground-subtle"}`,children:[r.scope==="public"?o(_n,{className:"inline h-2.5 w-2.5 mr-0.5"}):null,r.label]}),f("a",{href:r.url,target:"_blank",rel:"noopener noreferrer",onClick:s=>s.stopPropagation(),className:"text-emerald-700 dark:text-emerald-300 hover:underline break-all flex items-center gap-1",children:[o(Wd,{className:"h-3 w-3 shrink-0"}),r.url]})]},r.id))]})]}),o("div",{className:"border-t border-border",children:o(SF,{peers:n.data?.peers??[],loading:n.isLoading})})]})}function NF({status:e}){const t=[{label:"Tenant",value:e.tenantName||"—"},{label:"User",value:e.userLogin??"—"},{label:"Control plane",value:e.controlPlaneUrl||"—"},{label:"Mesh IP",value:e.meshIp||"—",mono:!0},{label:"MagicDNS",value:e.magicDnsHostname||"—",mono:!0},{label:"DNS suffix",value:e.magicDnsSuffix||"—",mono:!0},{label:"Peers",value:String(e.peerCount)},{label:"Key expiry",value:e.keyExpiry?kF(e.keyExpiry):"—"}];return o("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-1.5",children:t.map(n=>f("div",{className:"flex items-baseline justify-between gap-3 text-xs",children:[o("span",{className:"text-foreground-subtle shrink-0",children:n.label}),o("span",{className:`text-foreground truncate ${n.mono?"font-mono":""}`,children:n.value})]},n.label))})}function kF(e){const t=e-Date.now();if(t<0)return`Expired ${Qv(e)}`;const n=Math.floor(t/864e5);if(n>60)return new Date(e).toLocaleDateString();if(n>1)return`in ${n} days`;const r=Math.floor(t/36e5);return r>1?`in ${r}h`:`in ${Math.max(1,Math.floor(t/6e4))} min`}function SF({peers:e,loading:t}){const n=H(()=>e.map(a=>({...a,_id:a.id})),[e]),r=U(a=>{a&&navigator.clipboard?.writeText(a)},[]),s=H(()=>[{key:"hostname",header:"Hostname",render:a=>f("div",{className:"flex flex-col",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"font-medium text-foreground",children:a.hostname||"(unknown)"}),a.isSelf&&o(zt,{variant:"info",children:"self"}),a.exitNodeOption&&o(zt,{variant:"warning",children:"exit-node"})]}),a.userLogin&&o("div",{className:"text-[10px] text-foreground-subtle truncate",children:a.userLogin})]})},{key:"magicDns",header:"MagicDNS",render:a=>a.magicDns?f("div",{className:"flex items-center gap-1",children:[o("span",{className:"font-mono text-xs truncate",children:a.magicDns}),o("button",{onClick:()=>r(a.magicDns),className:"p-0.5 hover:bg-foreground-subtle/10 rounded","aria-label":"Copy MagicDNS",children:o(aa,{className:"h-3 w-3 text-foreground-subtle"})})]}):o("span",{className:"text-foreground-subtle",children:"—"})},{key:"addresses",header:"IP",render:a=>{const i=a.addresses[0]??"";return i?f("div",{className:"flex items-center gap-1",children:[o("span",{className:"font-mono text-xs",children:i}),o("button",{onClick:()=>r(i),className:"p-0.5 hover:bg-foreground-subtle/10 rounded","aria-label":"Copy IP",children:o(aa,{className:"h-3 w-3 text-foreground-subtle"})})]}):o("span",{className:"text-foreground-subtle",children:"—"})}},{key:"connection",header:"Connection",render:a=>f("div",{className:"flex items-center gap-1.5",children:[o(zt,{variant:CF(a.connection),children:a.connection}),a.relay&&o("span",{className:"text-[10px] text-foreground-subtle font-mono",children:a.relay})]})},{key:"routes",header:"Routes",render:a=>a.advertisedRoutes.length>0?o("span",{className:"text-[10px] font-mono text-foreground-subtle truncate",children:a.advertisedRoutes.join(", ")}):o("span",{className:"text-foreground-subtle",children:"—"})},{key:"tx",header:"TX / RX",render:a=>f("span",{className:"text-[10px] text-foreground-subtle font-mono",children:["↑ ",Tf(a.txBytes)," · ↓ ",Tf(a.rxBytes)]})},{key:"lastSeen",header:"Last seen",render:a=>o("span",{className:"text-[10px] text-foreground-subtle",children:a.lastSeenMs>0?Qv(a.lastSeenMs):"—"})}],[r]);return t&&e.length===0?f("div",{className:"p-4 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3 w-3 animate-spin inline mr-1"})," Loading peers…"]}):e.length===0?o("div",{className:"p-4 text-xs text-foreground-subtle",children:"No peers visible — your tailnet may be empty or the host is not joined."}):o("div",{className:"p-4",children:o(Da,{columns:s,rows:n,rowKey:a=>a._id,minWidthPx:820})})}function CF(e){return e==="direct"?"success":e==="relay"?"warning":"info"}function Tf(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:e<1024*1024*1024?`${(e/1024/1024).toFixed(1)}MB`:`${(e/1024/1024/1024).toFixed(2)}GB`}function Qv(e){const t=Date.now()-e;return t<6e4?"just now":t<36e5?`${Math.round(t/6e4)}m ago`:t<864e5?`${Math.round(t/36e5)}h ago`:`${Math.round(t/864e5)}d ago`}function MF(e){return new Promise(t=>setTimeout(t,e))}function EF(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"addresses",label:"Network Addresses",icon:hn,content:o(fF,{})},{id:"remote-access",label:"Remote Access",icon:_n,content:o(nF,{})},{id:"mesh",label:"Mesh Networks",icon:Wa,content:o(xF,{})},{id:"turn",label:"TURN Servers",icon:$n,content:o(iF,{})}]})})}const IF=[{kind:"device-export",tabId:"device-export",title:"Device export",subtitle:"Outbound exporters that publish CamStack devices to other ecosystems (HomeAssistant, HomeKit, Alexa, …).",icon:wO,emptyTitle:"No device-export providers installed",emptyDescription:"Install an export addon (e.g. @camstack/addon-export-ha-mqtt) to surface your CamStack devices in HomeAssistant, HomeKit, …",addLabel:"Add export"},{kind:"email",tabId:"email",title:"Email providers",subtitle:"Outbound email relays used for magic-link login, notifications, and alerts (SMTP today, future SendGrid, …).",icon:L6,emptyTitle:"No email providers installed",emptyDescription:"Install an email-provider addon (e.g. @camstack/addon-smtp) so the hub can deliver magic-link logins and notifications.",addLabel:"Add email provider"},{kind:"broker",tabId:"broker",title:"Brokers",subtitle:"Message brokers consumed by exporters and downstream automations (MQTT today, future Kafka, …).",icon:Za,emptyTitle:"No brokers installed",emptyDescription:"Install a broker addon (e.g. @camstack/addon-mqtt-broker) to publish device events for downstream automations.",addLabel:"Add broker"}];function AF(e){if(typeof e=="string")return e;if(e&&typeof e=="object"){const t=e.name;if(typeof t=="string")return t}return null}function PF(e){const t=e,n=t?.manifest;if(!n?.id)return null;const r=[];for(const i of n.capabilities??[]){const l=AF(i);l!==null&&r.push(l)}const s=n.packageDisplayName??n.name??n.id,a=t?.process?.state??null;return{addonId:n.id,displayName:s,isActive:a==="running",packageName:n.packageName??`@camstack/addon-${n.id}`,capNames:r,processState:a}}function _F(e,t){const n=new Set(t);return e.filter(r=>r.capNames.some(s=>n.has(s)))}function $F(e){for(const[t,n]of Object.entries(hm))if(n===e)return t;return null}function DF(e){return e==="running"?{label:"Running",className:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300"}:e==="crashed"||e==="failed"?{label:e==="failed"?"Failed":"Crashed",className:"bg-danger/15 text-danger"}:e==="stopped"||e==="disabled"?{label:"Stopped",className:"bg-foreground-subtle/15 text-foreground-subtle"}:{label:e??"Unknown",className:"bg-foreground-subtle/15 text-foreground-subtle"}}function nu({label:e,className:t}){return o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t}`,children:e})}function TF({addonId:e}){const{data:t,isLoading:n}=Ax({addonId:e},{refetchInterval:1e4,retry:!1});if(n||!t)return null;const r=w2.safeParse(t);if(!r.success)return null;const s=r.data,a=`${s.brokerCount} broker${s.brokerCount===1?"":"s"}${s.embeddedRunning?" • embedded up":""}`;return o(nu,{label:a,className:"bg-primary/10 text-primary"})}function LF({addonId:e}){const{data:t,isLoading:n}=ld({addonId:e},{refetchInterval:1e4,retry:!1});if(n||!t)return null;const r=um.safeParse(t);if(!r.success)return null;const s=r.data,a=s.linkState==="linked"?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":s.linkState==="error"?"bg-danger/15 text-danger":"bg-foreground-subtle/15 text-foreground-subtle",i=`${s.linkState} • ${s.exposedDeviceCount} exposed`;return o(nu,{label:i,className:a})}function RF({kind:e,addonId:t}){return e==="broker"?o(TF,{addonId:t}):e==="device-export"?o(LF,{addonId:t}):null}function OF({descriptor:e,rows:t,isLoading:n}){const r=$F(e.kind),s=e.kind==="device-export";return o(ns,{title:e.title,subtitle:e.subtitle,pageIcon:e.icon,itemIcon:e.icon,capability:r??e.kind,installButtonLabel:e.addLabel,items:t,isLoading:n,emptyTitle:e.emptyTitle,emptyDescription:e.emptyDescription,renderStatusBadges:a=>{const i=DF(a.processState);return f(me,{children:[o(nu,{label:i.label,className:i.className}),o(RF,{kind:e.kind,addonId:a.addonId})]})},renderExpandedPanel:s?a=>o(Md,{addonId:a.addonId}):void 0,showChrome:!0})}function BF(){const e=wn(void 0,{refetchInterval:1e4}),t=(e.data??[]).map(PF).filter(r=>r!==null),n=IF.map(r=>{const s=Object.entries(hm).filter(([,a])=>a===r.kind).map(([a])=>a);return{id:r.tabId,label:r.title,icon:r.icon,content:o(OF,{descriptor:r,rows:_F(t,s),isLoading:e.isLoading})}});return o(tt,{icon:_o,title:"Integrations",subtitle:"External systems this hub talks to — device exporters, email relays, and message brokers. Settings, Logs and Events are docked under every provider.",children:o(ri,{tabs:n})})}function zF(e){const t=e.basePath;if(typeof t=="string"&&t.length>0)return t;const n=Object.keys(e);return n.length===0?"":n.join(", ")}function FF({location:e,onEdit:t,onDelete:n,onSetDefault:r}){const s=zF(e.config);return f("div",{className:"flex items-center gap-3 px-3 py-2 border-t border-border first:border-t-0 hover:bg-primary/5",children:[f("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[o("div",{className:"w-[88px] shrink-0",children:e.isDefault?f("span",{className:"inline-flex items-center gap-0.5 rounded bg-primary/10 border border-primary/20 px-1.5 py-0.5 text-[10px] font-semibold text-primary uppercase tracking-wide",title:"Default location for this type",children:[o(zi,{className:"h-2.5 w-2.5 fill-primary"}),"Default"]}):f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-0.5 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 hover:border-primary/30 uppercase tracking-wide",title:"Promote to default for this type",children:[o(zi,{className:"h-2.5 w-2.5"}),"Set default"]})}),o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono",children:e.providerId}),e.isSystem&&o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5",title:"System-managed location — cannot be deleted; edit config to relocate",children:"system"}),f("div",{className:"min-w-0",children:[o("div",{className:"text-xs font-medium text-foreground truncate",children:e.displayName}),s&&o("div",{className:"text-[10px] text-foreground-subtle truncate font-mono",children:s})]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[!e.isDefault&&f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10",title:"Set as default for this type",children:[o(zi,{className:"h-3 w-3"}),"Set default"]}),f("button",{onClick:()=>t(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10",children:[o(eo,{className:"h-3 w-3"}),"Edit"]}),!e.isSystem&&zs[e.type]!=="singleton"&&o("button",{onClick:()=>n(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10",title:"Delete location",children:o(Ze,{className:"h-3 w-3"})})]})]})}function jF({type:e,displayName:t,description:n,locations:r,onAdd:s,onEdit:a,onDelete:i,onSetDefault:l}){const c=H(()=>{const d=[...r];return d.sort((u,p)=>u.isDefault!==p.isDefault?u.isDefault?-1:1:u.displayName.localeCompare(p.displayName)),d},[r]);return f("div",{className:"rounded-lg border border-border bg-surface",children:[f("div",{className:"flex items-start justify-between border-b border-border px-3 py-2",children:[f("div",{className:"space-y-0.5",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-semibold text-foreground capitalize",children:t}),o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono",children:e})]}),n&&o("p",{className:"text-[11px] text-foreground-subtle",children:n}),zs[e]==="singleton"&&o("p",{className:"text-[10px] text-foreground-subtle italic",children:"Singleton — one location per type. Edit the existing entry; it can't be split."})]}),zs[e]==="multi"&&f("button",{onClick:()=>s(e),className:"inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3 w-3"}),"Add"]})]}),c.length===0?o("div",{className:"px-3 py-4 text-center text-[11px] text-foreground-subtle italic",children:zs[e]==="multi"?'No location registered. Click "Add" to register one.':"No location registered yet — should be auto-seeded at next boot."}):o("div",{children:c.map(d=>o(FF,{location:d,onEdit:a,onDelete:i,onSetDefault:l},d.id))})]})}function VF(e){const t=e.trim().toLowerCase();return t.length===0?"":t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Lf(e,t){const n=VF(t),r=n.length>0?n:"default";return`${e}:${r}`}function Gv({initialType:e,onClose:t,onCreated:n}){const r=ke(),s=Te().trpcClient,[a,i]=_("picker"),[l,c]=_(e),[d,u]=_(null),[p,h]=_({}),[m,g]=_(""),[b,x]=_(null),[y,w]=_(!1),[v,N]=_(null),[k,C]=_(!1),E=xd(),I=H(()=>{const D=E.data;return Array.isArray(D)?D.filter(L=>L.supportedLocationTypes.includes(l)):[]},[E.data,l]),A=E.isLoading,z=ja({onSuccess:()=>{r.invalidateQueries({queryKey:[["storage","listLocations"]]}),n()}}),P=H(()=>b!==null&&b.length>0?b:Lf(l,m),[l,m,b]),B=async()=>{if(d){C(!0),N(null);try{const L=await(O=>s.storage.testConfig.query(O))({providerId:d.providerId,config:p});N(L)}catch(D){N({ok:!1,error:D instanceof Error?D.message:String(D)})}finally{C(!1)}}},R=()=>{d&&z.mutate({id:P,type:l,displayName:m.trim(),providerId:d.providerId,config:p,isDefault:y})},M={picker:"Add Location — Pick provider",config:`Add Location — ${d?.displayName??""}`,naming:"Add Location — Name & defaults"};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:D=>D.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:M[a]}),f("p",{className:"text-xs text-foreground-subtle",children:["Type: ",o("span",{className:"font-mono",children:l})]})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),a==="picker"&&f("div",{className:"p-4 space-y-2",children:[A&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading providers…"}),!A&&I.length===0&&f("div",{className:"rounded border border-border bg-background px-3 py-4 text-center text-xs text-foreground-subtle",children:['No storage-provider supports type "',l,'". Install a compatible addon (e.g. ',o("code",{className:"font-mono",children:"remote-storage"}),") to enable it."]}),I.map(D=>f("button",{onClick:()=>{u(D),i("config")},className:"flex w-full items-center gap-3 rounded-lg border border-border bg-background p-3 text-left hover:border-primary/40 hover:bg-primary/5 transition-colors",children:[f("div",{className:"flex-1 min-w-0",children:[o("p",{className:"text-xs font-semibold text-foreground",children:D.displayName}),o("p",{className:"text-[10px] text-foreground-subtle font-mono mt-0.5 truncate",children:D.providerId})]}),o(wt,{className:"h-4 w-4 text-foreground-subtle flex-shrink-0"})]},D.providerId))]}),a==="config"&&d&&f("div",{className:"p-4 space-y-3 max-h-[60vh] overflow-y-auto",children:[o(Dn,{schema:d.configSchema,values:p,onChange:h}),v&&o("div",{className:`rounded border px-3 py-2 text-[11px] ${v.ok?"border-success/30 bg-success/5 text-success":"border-danger/30 bg-danger/5 text-danger"}`,children:v.ok?"Connection OK.":`Test failed: ${v.error??"unknown error"}`}),f("div",{className:"flex items-center justify-between pt-1",children:[o("button",{onClick:()=>i("picker"),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Back"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{B()},disabled:k,className:"rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50",children:k?"Testing…":"Test connection"}),o("button",{onClick:()=>i("naming"),className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:"Next"})]})]})]}),a==="naming"&&d&&f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Display name"}),o("input",{type:"text",value:m,onChange:D=>g(D.target.value),placeholder:`${l} on ${d.displayName}`,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[f("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:["Id ",o("span",{className:"lowercase tracking-normal text-foreground-subtle",children:"— auto-derived; override if needed"})]}),o("input",{type:"text",value:P,onChange:D=>x(D.target.value),placeholder:Lf(l,m),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground font-mono focus:outline-none focus:ring-1 focus:ring-primary"}),f("p",{className:"text-[10px] text-foreground-subtle",children:["Format: ",o("code",{className:"font-mono",children:"<type>:<slug>"}),". Lowercase letters, digits, and hyphens only."]})]}),f("label",{className:"flex items-start gap-2 rounded border border-border bg-background px-3 py-2 cursor-pointer hover:bg-primary/5",children:[o("input",{type:"checkbox",checked:y,onChange:D=>w(D.target.checked),className:"accent-primary mt-0.5"}),f("div",{className:"space-y-0.5",children:[f("div",{className:"text-xs font-medium text-foreground",children:['Mark as default for type "',l,'"']}),f("div",{className:"text-[10px] text-foreground-subtle",children:["Setting this as default will demote the current default for this type. References like"," ",f("code",{className:"font-mono",children:['"',l,'"']})," resolve to whichever location is the default."]})]})]}),z.isError&&o("div",{className:"rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]",children:z.error instanceof Error?z.error.message:String(z.error)}),f("div",{className:"flex items-center justify-between pt-1",children:[o("button",{onClick:()=>i("config"),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Back"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{c(e),u(null),h({}),g(""),x(null),w(!1),N(null),i("picker")},className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Reset"}),f("button",{onClick:R,disabled:z.isPending||m.trim().length===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[z.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):null,z.isPending?"Saving…":"Save"]})]})]})]})]})})}function HF({location:e,onClose:t,onSaved:n}){const r=ke(),s=Te().trpcClient,[a,i]=_({...e.config}),[l,c]=_(e.displayName),[d,u]=_(null),[p,h]=_(!1),m=xd(),g=H(()=>{const w=m.data;return Array.isArray(w)?w.find(N=>N.providerId===e.providerId)??null:null},[m.data,e.providerId]),b=ja({onSuccess:()=>{r.invalidateQueries({queryKey:[["storage","listLocations"]]}),n()}}),x=async()=>{h(!0),u(null);try{const v=await(N=>s.storage.testConfig.query(N))({providerId:e.providerId,config:a});u(v)}catch(w){u({ok:!1,error:w instanceof Error?w.message:String(w)})}finally{h(!1)}},y=()=>{b.mutate({id:e.id,type:e.type,providerId:e.providerId,isDefault:e.isDefault,displayName:l.trim(),config:a})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:w=>w.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[f("h2",{className:"text-sm font-semibold text-foreground",children:["Edit ",e.displayName]}),f("p",{className:"text-xs text-foreground-subtle",children:[o("span",{className:"font-mono",children:e.id})," · ",g?.displayName??e.providerId]})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-3 max-h-[60vh] overflow-y-auto",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Display name"}),o("input",{type:"text",value:l,onChange:w=>c(w.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})]}),g&&o(Dn,{schema:g.configSchema,values:a,onChange:i}),!g&&!m.isLoading&&f("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300",children:["Provider ",o("code",{className:"font-mono",children:e.providerId})," is no longer registered. Field schema unavailable; raw config is preserved on save."]}),d&&o("div",{className:`rounded border px-3 py-2 text-[11px] ${d.ok?"border-success/30 bg-success/5 text-success":"border-danger/30 bg-danger/5 text-danger"}`,children:d.ok?"Connection OK.":`Test failed: ${d.error??"unknown error"}`}),b.isError&&o("div",{className:"rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]",children:b.error instanceof Error?b.error.message:String(b.error)})]}),f("div",{className:"flex items-center justify-between gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{x()},disabled:p||!g,className:"rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50",children:p?"Testing…":"Test connection"}),f("button",{onClick:y,disabled:b.isPending||l.trim().length===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[b.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):null,b.isPending?"Saving…":"Save"]})]})]})]})})}const qF={data:"Data",media:"Media",recordings:"Recordings","recordings-high":"Recordings (High)","recordings-low":"Recordings (Low)","recordings-clips":"Recordings (Clips)","event-images":"Event Images",models:"Models","addons-data":"Addons Data",cache:"Cache",logs:"Logs",backups:"Backups"},UF={backups:"Snapshot archives. Default landing for `backup-orchestrator`.",recordings:"Continuous recordings (combined high + low + clips when no slot is specified).","recordings-high":"High-quality continuous recordings.","recordings-low":"Low-quality continuous recordings.","recordings-clips":"Event clips (motion / detection triggers).","event-images":"Detection snapshots, thumbnails, and crops.",models:"ML model files. Read by inference-engine addons.",logs:"Long-term log archives."};function QF(){const e=ke(),t=nt(),{data:n,isLoading:r,isError:s}=My({}),[a,i]=_(null),[l,c]=_(null),d=Ey({onSuccess:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]})}}),u=ja({onSuccess:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]})}}),p=g=>{g.isDefault||u.mutate({id:g.id,type:g.type,providerId:g.providerId,displayName:g.displayName,config:g.config,isDefault:!0})},h=async g=>{if(g.isDefault){await t({title:"Cannot delete default location",message:`"${g.displayName}" is the default for type "${g.type}". Mark another location as default first, then delete this one.`,confirmLabel:"OK",variant:"warning"});return}await t({title:`Delete location "${g.displayName}"?`,message:"This removes the location record. Files on disk are not deleted; the underlying directory or remote path stays untouched.",confirmLabel:"Delete",variant:"danger"})&&d.mutate({id:g.id})},m=H(()=>{const g=new Map;for(const b of Lu)g.set(b,[]);for(const b of n??[]){const x=g.get(b.type);x?x.push(b):g.set(b.type,[b])}return g},[n]);return f(tt,{children:[r&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading locations…"}),s&&o("div",{className:"text-xs text-danger",children:"Failed to load storage locations."}),!r&&!s&&o("div",{className:"space-y-3",children:Lu.map(g=>o(jF,{type:g,displayName:qF[g],description:UF[g],locations:m.get(g)??[],onAdd:b=>i(b),onEdit:b=>c(b),onDelete:b=>{h(b)},onSetDefault:b=>p(b)},g))}),a!==null&&o(Gv,{initialType:a,onClose:()=>i(null),onCreated:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]}),i(null)}}),l!==null&&o(HF,{location:l,onClose:()=>c(null),onSaved:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]}),c(null)}})]})}const GF=[["backup","listDestinations"]],KF=["backup","listArchives"];function WF({destinationId:e,restoreSupported:t,onOpenRestoreWizard:n}){const r=ke(),s=nt(),{data:a,isLoading:i,isError:l}=id({destinationId:e}),c=a??[],d=Bb({onSuccess:()=>{r.invalidateQueries({queryKey:[[...KF]]}),r.invalidateQueries({queryKey:GF})}}),u=U(async b=>{await s({title:"Delete this archive?",message:`Permanently deletes "${b.label??b.id}" and frees ${It(b.sizeBytes)}.`,confirmLabel:"Delete",variant:"danger"})&&d.mutate({destinationId:e,backupId:b.id})},[s,e,d]),[p,h]=_(null),m=U(async b=>{h(b.id);try{const x=localStorage.getItem("camstack_admin_token"),y={};x&&(y.Authorization=`Bearer ${x}`);const w=await fetch(YF(e,b.id),{headers:y});if(!w.ok)throw new Error(`download failed: ${w.status} ${w.statusText}`);const v=await w.blob(),N=URL.createObjectURL(v),k=document.createElement("a");k.href=N,k.download=`${b.label??b.id}.tar.gz`,document.body.appendChild(k),k.click(),k.remove(),URL.revokeObjectURL(N)}finally{h(null)}},[e]),g=H(()=>[...c].sort((b,x)=>x.createdAt-b.createdAt),[c]);return i?o("div",{className:"text-xs text-foreground-subtle animate-pulse py-2",children:"Loading archives…"}):l?o("div",{className:"text-xs text-danger py-2",children:"Failed to read manifest for this destination"}):g.length===0?o("div",{className:"text-xs text-foreground-subtle italic py-2",children:"No archives at this destination yet."}):o("div",{className:"rounded border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{children:f("tr",{className:"text-foreground-subtle bg-background/30",children:[o("th",{className:"text-left px-3 py-1.5 font-medium",children:"When"}),o("th",{className:"text-left px-3 py-1.5 font-medium",children:"Label"}),o("th",{className:"text-left px-3 py-1.5 font-medium",children:"Includes"}),o("th",{className:"text-right px-3 py-1.5 font-medium",children:"Size"}),o("th",{className:"text-right px-3 py-1.5 font-medium w-52",children:"Actions"})]})}),o("tbody",{children:g.map(b=>f("tr",{className:"border-t border-border hover:bg-primary/5",children:[o("td",{className:"px-3 py-1.5 text-foreground tabular-nums",children:ZF(b.createdAt)}),o("td",{className:"px-3 py-1.5 text-foreground",children:b.label??o("span",{className:"text-foreground-subtle italic",children:"—"})}),o("td",{className:"px-3 py-1.5 text-foreground-subtle",children:b.locations.join(", ")}),o("td",{className:"px-3 py-1.5 text-foreground text-right tabular-nums",children:It(b.sizeBytes)}),o("td",{className:"px-3 py-1.5",children:f("div",{className:"flex items-center justify-end gap-1",children:[f("button",{onClick:()=>{m(b)},disabled:p===b.id,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 disabled:opacity-50",title:"Download archive",children:[p===b.id?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xt,{className:"h-3 w-3"}),"Download"]}),t&&n&&f("button",{onClick:()=>n({destinationId:e,archiveId:b.id}),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-primary hover:bg-primary/10",title:"Restore from this archive",children:[o(kt,{className:"h-3 w-3"}),"Restore"]}),o("button",{onClick:()=>{u(b)},disabled:d.isPending,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10 disabled:opacity-50",title:"Delete archive",children:d.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"})})]})})]},b.id))})]})})}function YF(e,t){return`/api/backup/download/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}function ZF(e){return new Date(e).toLocaleString(void 0,{day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit"})}const Kv=[{id:"manual",label:"Manual only",cron:""},{id:"hourly",label:"Every hour",cron:"0 * * * *",description:"On the hour"},{id:"every-3h",label:"Every 3 hours",cron:"0 */3 * * *",description:"00:00, 03:00, 06:00, 09:00 …"},{id:"every-6h",label:"Every 6 hours",cron:"0 */6 * * *",description:"00:00, 06:00, 12:00, 18:00"},{id:"daily-3am",label:"Daily at 03:00",cron:"0 3 * * *",description:"Every night at 3 AM"},{id:"weekly-sun",label:"Weekly Sunday 03:00",cron:"0 3 * * 0",description:"Sunday morning at 3 AM"}];function XF(e){const t=e.trim();for(const n of Kv)if(n.cron===t)return n.id;return"custom"}function JF({value:e,onChange:t,previewCount:n=5,disabled:r=!1}){const s=XF(e),[a,i]=_(s==="custom");Y(()=>{s!=="custom"&&i(!1)},[s]);const l=nj(e,250),c=Fb({cron:l,count:n},{enabled:l.trim().length>0}),d=c.data??null,u=h=>{i(!1),t(h.cron)},p=a||s==="custom";return f("div",{className:"space-y-3",children:[f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Schedule preset"}),f("div",{className:"flex flex-wrap gap-1.5",children:[Kv.map(h=>{const m=!a&&s===h.id;return o("button",{type:"button",onClick:()=>u(h),disabled:r,className:"rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 "+(m?"border-primary bg-primary/10 text-primary":"border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground"),title:h.description??h.label,children:h.label},h.id)}),o("button",{type:"button",onClick:()=>{i(!0),e.trim().length===0&&t("0 3 * * *")},disabled:r,className:"rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 "+(p?"border-primary bg-primary/10 text-primary":"border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground"),children:"Custom…"})]})]}),p&&f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Cron expression (5-field POSIX)"}),o("input",{type:"text",value:e,onChange:h=>t(h.target.value),disabled:r,placeholder:"0 3 * * *",spellCheck:!1,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs font-mono text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"}),f("p",{className:"text-[10px] text-foreground-subtle",children:["Format: ",o("span",{className:"font-mono",children:"minute hour day-of-month month day-of-week"})," · all times server-local"]})]}),o(ej,{cron:l,preview:d,loading:c.isFetching})]})}function ej({cron:e,preview:t,loading:n}){return n&&t===null?f("div",{className:"flex items-center gap-2 rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle",children:[o(Se,{className:"h-3 w-3 animate-spin"}),"Validating…"]}):t===null?null:t.ok?t.nextRuns.length===0?o("div",{className:"rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle",children:"No future runs match this expression."}):f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Next runs"}),o("ul",{className:"rounded border border-border bg-background/40 divide-y divide-border",children:t.nextRuns.map((r,s)=>f("li",{className:"flex items-center justify-between px-3 py-1.5 text-[11px]",children:[o("span",{className:"text-foreground tabular-nums",children:new Date(r).toLocaleString()}),o("span",{className:"text-foreground-subtle text-[10px] tabular-nums",children:tj(r)})]},`${r}-${s}`))})]}):o("div",{className:"rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger",children:t.error??"Invalid cron expression"})}function tj(e){const t=e-Date.now();if(t<=0)return"now";const n=Math.floor(t/1e3);if(n<60)return`in ${n}s`;const r=Math.floor(n/60);if(r<60)return`in ${r}m`;const s=Math.floor(r/60);return s<24?`in ${s}h`:`in ${Math.floor(s/24)}d`}function nj(e,t){const[n,r]=_(e),s=H(()=>e,[e]);return Y(()=>{const a=setTimeout(()=>r(s),t);return()=>clearTimeout(a)},[s,t]),n}const rj=[["backup","listDestinations"]];function oj({onCreateAt:e,onOpenRestoreWizard:t}){const{data:n,isLoading:r,isError:s}=ad(),a=n??[],[i,l]=_(null),c=u=>{l(p=>p===u?null:u)},d=cj();return r?o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading destinations…"}):s?o("div",{className:"text-xs text-danger",children:"Failed to load destinations"}):a.length===0?o("div",{className:"rounded-lg border border-border bg-surface px-4 py-8 text-center",children:o("p",{className:"text-xs text-foreground-subtle",children:"No `backups`-typed storage locations registered. Add one in Settings → Storage to begin."})}):o("div",{className:"rounded-lg border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[720px]",children:[o("thead",{children:f("tr",{className:"text-foreground-subtle border-b border-border bg-background/40",children:[o("th",{className:"text-left px-3 py-2 font-medium w-6"}),o("th",{className:"text-left px-3 py-2 font-medium",children:"Destination"}),o("th",{className:"text-left px-3 py-2 font-medium w-20",children:"Enabled"}),o("th",{className:"text-left px-3 py-2 font-medium w-28",children:"Retention"}),o("th",{className:"text-left px-3 py-2 font-medium w-56",children:"Schedule"}),o("th",{className:"text-left px-3 py-2 font-medium w-44",children:"Last success"}),o("th",{className:"text-right px-3 py-2 font-medium w-44",children:"Actions"})]})}),o("tbody",{children:a.map(u=>{const p=d.get(u.id);return o(sj,{row:u,isOpen:i===u.id,onToggle:()=>c(u.id),onCreateAt:e,liveLastSuccessAt:p?.at,liveLastSuccessSizeBytes:p?.sizeBytes,...t?{onOpenRestoreWizard:t}:{}},u.id)})})]})})}function sj({row:e,isOpen:t,onToggle:n,onCreateAt:r,onOpenRestoreWizard:s,liveLastSuccessAt:a,liveLastSuccessSizeBytes:i}){const l=ke(),c=zb({onSuccess:()=>{l.invalidateQueries({queryKey:rj})}}),[d,u]=_(String(e.retentionCount));Y(()=>{u(String(e.retentionCount))},[e.retentionCount]);const[p,h]=_(!1),m=U(x=>{c.mutate({locationId:e.id,enabled:x,retentionCount:e.retentionCount,...e.label!==void 0?{label:e.label}:{},...e.cron!==void 0?{cron:e.cron}:{}})},[c,e.id,e.retentionCount,e.label,e.cron]),g=U(()=>{const x=Number.parseInt(d,10);if(Number.isNaN(x)||x<1){u(String(e.retentionCount));return}x!==e.retentionCount&&c.mutate({locationId:e.id,enabled:e.enabled,retentionCount:x,...e.label!==void 0?{label:e.label}:{},...e.cron!==void 0?{cron:e.cron}:{}})},[c,d,e.id,e.enabled,e.retentionCount,e.label,e.cron]),b=U(x=>{c.mutate({locationId:e.id,enabled:e.enabled,retentionCount:e.retentionCount,...e.label!==void 0?{label:e.label}:{},cron:x},{onSuccess:()=>{h(!1)}})},[c,e.id,e.enabled,e.retentionCount,e.label]);return f(me,{children:[f("tr",{className:"border-t border-border first:border-t-0 hover:bg-primary/5",children:[o("td",{className:"px-2 py-2",children:o("button",{onClick:n,className:"inline-flex items-center justify-center rounded p-1 text-foreground-subtle hover:bg-primary/10 hover:text-foreground",title:t?"Hide archives":"Show archives",children:t?o(lt,{className:"h-3.5 w-3.5"}):o(wt,{className:"h-3.5 w-3.5"})})}),o("td",{className:"px-3 py-2",children:f("button",{onClick:n,className:"text-left hover:underline focus:outline-none",title:"View archives",children:[o("div",{className:"text-foreground font-medium",children:e.displayName}),f("div",{className:"flex items-center gap-1.5 mt-0.5",children:[o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5",children:e.kind}),o("span",{className:"text-[10px] text-foreground-subtle font-mono",children:e.id})]})]})}),o("td",{className:"px-3 py-2",children:o("label",{className:"inline-flex items-center cursor-pointer",children:o("input",{type:"checkbox",className:"accent-primary",checked:e.enabled,disabled:c.isPending,onChange:x=>m(x.target.checked)})})}),o("td",{className:"px-3 py-2",children:o("input",{type:"number",min:1,max:1e3,value:d,disabled:c.isPending,onChange:x=>u(x.target.value),onBlur:g,onKeyDown:x=>{x.key==="Enter"&&x.target.blur(),x.key==="Escape"&&u(String(e.retentionCount))},className:"w-16 rounded border border-border bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})}),o("td",{className:"px-3 py-2",children:o(aj,{cron:e.cron,nextRunAt:e.nextRunAt,onEdit:()=>h(!0),disabled:c.isPending})}),o("td",{className:"px-3 py-2 text-foreground-subtle",children:(()=>{const x=dj(a,e.lastSuccessAt),y=x===a?i:e.lastSuccessSizeBytes;return x!==void 0?o(uj,{at:x,sizeBytes:y}):o("span",{className:"italic",children:"Never"})})()}),o("td",{className:"px-3 py-2",children:o("div",{className:"flex items-center justify-end gap-1.5",children:e.triggerSupported&&f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3 w-3"}),"Create here"]})})})]}),t&&o("tr",{className:"border-t border-border bg-background/30",children:o("td",{colSpan:7,className:"px-4 py-3",children:o(WF,{destinationId:e.id,restoreSupported:e.restoreSupported,...s?{onOpenRestoreWizard:s}:{}})})}),p&&o(lj,{destinationName:e.displayName,currentCron:e.cron??"",onSave:b,onClose:()=>h(!1),saving:c.isPending,saveError:c.error instanceof Error?c.error.message:null})]})}function aj({cron:e,nextRunAt:t,onEdit:n,disabled:r}){const s=typeof e=="string"&&e.trim().length>0;return f("button",{type:"button",onClick:n,disabled:r,className:"group flex flex-col items-start gap-0.5 text-left rounded px-1.5 py-1 -mx-1.5 hover:bg-primary/5 disabled:opacity-50",title:"Edit schedule",children:[f("div",{className:"flex items-center gap-1.5",children:[o(PR,{className:"h-3 w-3 text-foreground-subtle group-hover:text-foreground"}),o("span",{className:s?"font-mono text-foreground":"italic text-foreground-subtle",children:s?e:"Manual"})]}),s&&t!==void 0&&f("span",{className:"text-[10px] text-foreground-subtle tabular-nums",children:["next ",ij(t)]})]})}function ij(e){const t=e-Date.now();if(t<=0)return"imminent";const n=Math.floor(t/1e3);if(n<60)return`in ${n}s`;const r=Math.floor(n/60);if(r<60)return`in ${r}m`;const s=Math.floor(r/60);return s<24?`in ${s}h`:`in ${Math.floor(s/24)}d`}function lj({destinationName:e,currentCron:t,onSave:n,onClose:r,saving:s,saveError:a}){const[i,l]=_(t);return o("tr",{children:o("td",{colSpan:7,className:"p-0",children:o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:r,children:f("div",{className:"w-full max-w-lg rounded-xl border border-border bg-surface shadow-2xl",onClick:c=>c.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Schedule"}),f("p",{className:"text-xs text-foreground-subtle",children:["→ ",e]})]}),o("button",{onClick:r,className:"text-foreground-subtle hover:text-foreground",title:"Close",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4",children:[o(JF,{value:i,onChange:l,disabled:s}),a!==null&&o("div",{className:"mt-3 rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger",children:a})]}),f("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:r,disabled:s,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground disabled:opacity-50",children:"Cancel"}),o("button",{onClick:()=>n(i.trim()),disabled:s||i.trim()===t.trim(),className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:s?"Saving…":"Save"})]})]})})})})}function cj(){const{map:e}=Kc(Ne.BackupCompleted,t=>t.destinationId);return H(()=>{const t=new Map;for(const[n,r]of e)t.set(n,{at:Date.now(),sizeBytes:r.sizeMB*1024*1024});return t},[e])}function dj(e,t){return e===void 0?t:t===void 0||e>t?e:t}function uj({at:e,sizeBytes:t}){const n=pj(e),r=H(()=>new Date(e).toLocaleString(),[e]);return f("span",{title:r,className:"text-foreground tabular-nums",children:[n,t!==void 0&&f("span",{className:"ml-1 text-foreground-subtle",children:["· ",It(t)]})]})}function pj(e){const[,t]=_(0);return Y(()=>{const n=setInterval(()=>t(r=>r+1),3e4);return()=>clearInterval(n)},[]),fj(e)}function fj(e){const t=Math.max(0,Date.now()-e),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;const r=Math.floor(n/60);if(r<60)return`${r}m ago`;const s=Math.floor(r/60);if(s<24)return`${s}h ago`;const a=Math.floor(s/24);if(a<30)return`${a}d ago`;const i=Math.floor(a/30);return i<12?`${i}mo ago`:`${Math.floor(a/365)}y ago`}const hj=[["backup","list"]];function mj({initialDestinationId:e,initialArchiveId:t,onClose:n,onScheduled:r}){const s=ke(),[a,i]=_(e&&t?2:1),[l,c]=_(e),[d,u]=_(t),[p,h]=_(new Set),{data:m}=ad(),g=m??[],{data:b,isLoading:x}=id({destinationId:l??""},{enabled:!!l}),y=b??[];Y(()=>{if(l!==void 0)return;const z=g.filter(P=>P.restoreSupported);z.length===1&&c(z[0].id)},[l,g]);const{data:w}=Rb({destinationId:l??"",backupId:d??""},{enabled:!!l&&!!d}),v=H(()=>w?.locations??[],[w]);Y(()=>{v.length!==0&&h(z=>z.size===0?new Set(v):z)},[v]);const N=Ob({onSuccess:()=>{s.invalidateQueries({queryKey:hj}),r(),n()}}),k=z=>{h(P=>{const B=new Set(P);return B.has(z)?B.delete(z):B.add(z),B})},C=!!l&&!!d,E=p.size>0,I=C&&E&&!N.isPending,A=()=>{!l||!d||N.mutate({destinationId:l,backupId:d,locations:[...p]})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:n,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:z=>z.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Restore Backup"}),f("p",{className:"text-xs text-foreground-subtle",children:["Step ",a," of 3 — ",a===1?"pick source":a===2?"pick locations":"confirm"]})]}),o("button",{onClick:n,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),a===1&&o(gj,{destinations:g,destinationId:l,onPickDestination:z=>{c(z),u(void 0),h(new Set)},archives:y,archivesLoading:x,archiveId:d,onPickArchive:u}),a===2&&o(bj,{locations:v,picked:p,onToggle:k}),a===3&&o(xj,{destinationName:g.find(z=>z.id===l)?.displayName??l??"",archive:y.find(z=>z.id===d),picked:[...p]}),f("div",{className:"flex justify-between gap-2 border-t border-border px-4 py-3",children:[o("div",{children:a>1&&f("button",{onClick:()=>i(z=>z===3?2:1),className:"inline-flex items-center gap-1 rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:[o(Qd,{className:"h-3 w-3"}),"Back"]})}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:n,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),a<3?f("button",{disabled:a===1&&!C||a===2&&!E,onClick:()=>i(z=>z===1?2:3),className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:["Next",o(yR,{className:"h-3 w-3"})]}):f("button",{onClick:A,disabled:!I,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[N.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(kt,{className:"h-3.5 w-3.5"}),"Schedule Restore"]})]})]})]})})}function gj({destinations:e,destinationId:t,onPickDestination:n,archives:r,archivesLoading:s,archiveId:a,onPickArchive:i}){const l=e.filter(c=>c.restoreSupported);return f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Destination"}),f("select",{value:t??"",onChange:c=>n(c.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary",children:[o("option",{value:"",disabled:!0,children:"Select destination…"}),l.map(c=>f("option",{value:c.id,children:[c.displayName," (",c.kind,")"]},c.id))]})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Archive"}),!t&&o("div",{className:"text-xs text-foreground-subtle italic",children:"Pick a destination first."}),t&&s&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Reading archives…"}),t&&!s&&r.length===0&&o("div",{className:"text-xs text-foreground-subtle italic",children:"No archives available at this destination."}),t&&r.length>0&&o("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:r.map(c=>{const d=a===c.id;return f("label",{className:`flex items-center justify-between px-3 py-2 text-xs cursor-pointer ${d?"bg-primary/10":"hover:bg-primary/5"}`,children:[f("div",{className:"flex items-center gap-2",children:[o("input",{type:"radio",name:"archive",checked:d,onChange:()=>i(c.id),className:"accent-primary"}),f("div",{children:[o("div",{className:"font-medium text-foreground",children:c.label??c.id}),o("div",{className:"text-[10px] text-foreground-subtle",children:new Date(c.createdAt).toLocaleString()})]})]}),o("span",{className:"text-[10px] text-foreground-subtle tabular-nums",children:It(c.sizeBytes)})]},c.id)})})]})]})}function bj({locations:e,picked:t,onToggle:n}){return e.length===0?o("div",{className:"p-4",children:o("div",{className:"text-xs text-foreground-subtle",children:"Loading archive manifest… If this persists, the archive may predate manifests — restoring will apply everything in the tarball."})}):f("div",{className:"p-4 space-y-3",children:[o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300",children:"Selected entries will overwrite live data on the next server restart. Unchecked entries stay current."}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Apply"}),o("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:e.map(r=>f("label",{className:"flex items-center gap-2 px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer",children:[o("input",{type:"checkbox",checked:t.has(r),onChange:()=>n(r),className:"accent-primary"}),o("span",{className:"font-mono text-foreground",children:r}),o("span",{className:"ml-auto text-[10px] text-foreground-subtle",children:vj(r)})]},r))})]})]})}function xj({destinationName:e,archive:t,picked:n}){return f("div",{className:"p-4 space-y-3 text-xs",children:[o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-amber-700 dark:text-amber-300",children:"Restore is applied at next server boot. Active connections will drop when you restart."}),f("dl",{className:"space-y-1.5",children:[o(As,{term:"Destination",value:e}),o(As,{term:"Archive",value:t?.label??t?.id??"—"}),t&&o(As,{term:"Created",value:`${new Date(t.createdAt).toLocaleString()} · ${It(t.sizeBytes)}`}),o(As,{term:"Locations",value:n.length>0?n.join(", "):"— (full archive)"})]})]})}function As({term:e,value:t}){return f("div",{className:"flex justify-between gap-3",children:[o("dt",{className:"text-foreground-subtle",children:e}),o("dd",{className:"text-foreground font-mono text-right truncate",children:t})]})}const yj={db:"Database",addons:"Addon configs","addons-data":"Addon data",tls:"TLS certificates",cache:"Cache",data:"Top-level data"};function vj(e){return yj[e]??""}const wj=[["backup","list"]],Nj=[["backup","listLocations"]];function kj(){const e=ke(),t=nt(),{data:n}=Lb(),r=Tb({onSuccess:()=>{e.invalidateQueries({queryKey:wj}),e.invalidateQueries({queryKey:[["backup","listDestinations"]]}),e.invalidateQueries({queryKey:[["backup","listArchives"]]})}}),s=hb(),[a,i]=_(null),[l,c]=_(null),[d,u]=_(!1),[p,h]=_(!1),[m,g]=_(!1),b=async()=>{await t({title:"Restart server now?",message:"Active connections will drop and the apply-backup hook will run before boot.",confirmLabel:"Restart",variant:"warning"})&&s.mutate({confirm:!0})};return f(tt,{children:[f("div",{className:"flex items-center justify-end gap-2 flex-wrap",children:[f("button",{onClick:()=>u(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-surface border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-primary/5 hover:border-primary/30",children:[o(kt,{className:"h-3.5 w-3.5"}),"Restore…"]}),f("button",{onClick:()=>g(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3.5 w-3.5"}),"Add destination"]})]}),p&&o("div",{className:"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2.5 text-xs text-amber-700 dark:text-amber-300",children:f("div",{className:"flex items-center justify-between gap-3",children:[f("div",{className:"flex items-center gap-2",children:[o(kt,{className:"h-3.5 w-3.5"}),o("span",{children:"Restore scheduled. Restart the server to apply."})]}),f("button",{onClick:()=>{b()},disabled:s.isPending,className:"inline-flex items-center gap-1.5 rounded bg-amber-500/20 px-2 py-1 font-medium text-amber-800 dark:text-amber-200 hover:bg-amber-500/30 disabled:opacity-50",children:[s.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(kt,{className:"h-3.5 w-3.5"}),"Restart Now"]})]})}),o(oj,{onCreateAt:x=>i(x),onOpenRestoreWizard:x=>c(x)}),a&&o(Sj,{destination:a,locations:n??[],onClose:()=>i(null),onSubmit:(x,y)=>{r.mutate({destinations:[a.id],locations:x,label:y||void 0},{onSuccess:()=>{i(null),e.invalidateQueries({queryKey:Nj})}})},submitting:r.isPending}),(l||d)&&o(mj,{...l?{initialDestinationId:l.destinationId,initialArchiveId:l.archiveId}:{},onClose:()=>{c(null),u(!1)},onScheduled:()=>h(!0)}),m&&o(Gv,{initialType:"backups",onClose:()=>g(!1),onCreated:()=>{g(!1),e.invalidateQueries({queryKey:[["backup","listDestinations"]]})}})]})}function Sj({destination:e,locations:t,onClose:n,onSubmit:r,submitting:s}){const a=t.filter(p=>p.present),[i,l]=_(""),[c,d]=_(()=>new Set(a.map(p=>p.name))),u=p=>{d(h=>{const m=new Set(h);return m.has(p)?m.delete(p):m.add(p),m})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:n,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:p=>p.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Create Backup"}),f("p",{className:"text-xs text-foreground-subtle",children:["→ ",e.displayName]})]}),o("button",{onClick:n,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Label (optional)"}),o("input",{type:"text",value:i,onChange:p=>l(p.target.value),placeholder:"pre-upgrade",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Include"}),f("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:[a.length===0&&o("div",{className:"px-3 py-2 text-xs text-foreground-subtle italic",children:"Nothing to back up."}),a.map(p=>f("label",{className:"flex items-center justify-between px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer",children:[f("div",{className:"flex items-center gap-2",children:[o("input",{type:"checkbox",checked:c.has(p.name),onChange:()=>u(p.name),className:"accent-primary"}),o("span",{className:"font-mono text-foreground",children:p.name})]}),f("div",{className:"text-[10px] text-foreground-subtle tabular-nums",children:[It(p.sizeBytes)," · ",p.fileCount," files"]})]},p.name))]})]})]}),f("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:n,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:()=>r(Array.from(c),i.trim()),disabled:s||c.size===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[s?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(V0,{className:"h-3.5 w-3.5"}),s?"Creating…":"Create"]})]})]})})}function Cj(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"storage",label:"Storage",icon:ia,content:o(QF,{})},{id:"backup",label:"Backup",icon:V0,content:o(kj,{})}]})})}function Mj(){const{data:e,isLoading:t}=zn(void 0,{staleTime:3e4}),n=(e??[]).find(s=>s.isHub&&s.isOnline),r=n?.addons.map(s=>s.id)??[];return o(tt,{children:t?o("div",{className:"text-muted-foreground text-sm py-12 text-center",children:"Loading hub topology…"}):n?r.length===0?o("div",{className:"text-muted-foreground text-sm py-12 text-center",children:"No addons installed on the hub yet."}):o(to,{nodeId:n.id,addonIds:r,level:"global"}):f("div",{className:"flex flex-col items-center justify-center text-muted-foreground text-sm gap-2 py-12",children:[o(Jt,{className:"h-8 w-8 opacity-30"}),o("p",{children:"No online hub node found."}),o("p",{className:"text-xs",children:"Settings will appear once the hub is reachable."})]})})}function Ej(e){const t=new FormData;return t.append("file",e.file,e.file.name),t.append("nodeId",e.nodeId),e.addonId&&t.append("addonId",e.addonId),new Promise((n,r)=>{const s=new XMLHttpRequest;s.open("POST","/api/addons/upload"),e.token&&s.setRequestHeader("Authorization",`Bearer ${e.token}`),s.upload.addEventListener("progress",a=>{a.lengthComputable&&e.onProgress(Math.round(a.loaded/a.total*100))}),s.addEventListener("load",()=>{let a;try{a=JSON.parse(s.responseText)}catch{r(new Error(`HTTP ${s.status}`));return}s.status>=200&&s.status<300?n(a):r(new Error(a.error??`HTTP ${s.status}`))}),s.addEventListener("error",()=>r(new Error("Network error during upload"))),s.addEventListener("abort",()=>r(new Error("Upload aborted"))),s.send(t)})}function Ij({nodeId:e,addons:t,isHub:n}){const r=ke(),s=nt(),[a,i]=_(null),[l,c]=_(null),[d,u]=_(!1),[p,h]=_(null),[m,g]=_(0),b=te(null),x=Ba(),y=Dx(),w=Bx({nodeId:e}),v=w.data??[],N=new Map(t.map(P=>[P.id,P.capabilities])),k=v.length>0?v.map(P=>({id:P.id,status:P.status,capabilities:N.get(P.id)??[],version:P.version,packageName:P.packageName})):t.map(P=>({id:P.id,status:P.status,capabilities:P.capabilities,version:void 0,packageName:void 0})),C=()=>{r.invalidateQueries({queryKey:[["nodes","topology"]]}),w.refetch()},E=async P=>{i(P);try{await x.mutateAsync({nodeId:e,addonId:P}),C()}catch(B){console.error("Failed to restart addon:",B)}finally{i(null)}},I=async P=>{if(await s({title:"Uninstall addon",message:`Remove "${P}" from ${e}? The addon directory will be deleted on disk.`,confirmLabel:"Uninstall",variant:"danger"})){c(P);try{await y.mutateAsync({nodeId:e,addonId:P}),C()}catch(R){console.error("Failed to uninstall addon:",R)}finally{c(null)}}},z=f("div",{className:"flex items-center gap-2 mb-2",children:[o("input",{ref:b,type:"file",accept:".tgz,.tar.gz",className:"hidden",onChange:async P=>{const B=P.target.files?.[0];if(B){P.target.value="",h(null),u(!0),g(0);try{const R=localStorage.getItem("camstack_admin_token");await Ej({file:B,nodeId:e,token:R,onProgress:g}),C()}catch(R){h(R instanceof Error?R.message:String(R))}finally{u(!1),g(0)}}}}),f("button",{onClick:()=>b.current?.click(),disabled:d,className:"inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1 text-[11px] font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",children:[d?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xa,{className:"h-3 w-3"}),d?`Uploading… ${m}%`:"Upload addon (.tgz)"]}),d&&o("div",{className:"flex-1 h-1 rounded-full bg-muted overflow-hidden max-w-[140px]",children:o("div",{className:"h-full bg-primary transition-all",style:{width:`${m}%`}})}),p&&o("span",{className:"text-[10px] text-destructive",children:p})]});return k.length===0?f("div",{children:[z,o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:w.isLoading?"Loading addons…":"No addons on this node"})]}):f("div",{children:[z,f("table",{className:"w-full text-xs",children:[o("thead",{children:f("tr",{className:"text-muted-foreground text-left",children:[o("th",{className:"py-2 font-medium",children:"Addon"}),o("th",{className:"py-2 font-medium",children:"Version"}),o("th",{className:"py-2 font-medium",children:"Capabilities"}),o("th",{className:"py-2 font-medium",children:"Status"}),o("th",{className:"py-2 font-medium w-16"})]})}),o("tbody",{children:k.map(P=>f("tr",{className:"border-t border-border/50",children:[f("td",{className:"py-2 font-medium",children:[o("div",{children:P.id}),P.packageName&&o("div",{className:"text-[9px] text-muted-foreground",children:P.packageName})]}),o("td",{className:"py-2 text-muted-foreground",children:P.version??"—"}),o("td",{className:"py-2",children:o("div",{className:"flex flex-wrap gap-1",children:P.capabilities.length>0?P.capabilities.map(B=>o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-blue-500/10 text-blue-400",children:B},B)):o("span",{className:"text-muted-foreground",children:"—"})})}),o("td",{className:"py-2",children:o("span",{className:`text-[10px] px-1.5 py-0.5 rounded-full ${P.status==="running"?"bg-success/10 text-success":P.status==="error"?"bg-destructive/10 text-destructive":"bg-muted text-muted-foreground"}`,children:P.status})}),o("td",{className:"py-2",children:f("div",{className:"flex items-center gap-1 justify-end",children:[o("button",{onClick:()=>E(P.id),disabled:a===P.id||l===P.id,className:"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:`Restart ${P.id}`,children:o(kt,{className:`h-3 w-3 ${a===P.id?"animate-spin":""}`})}),o("button",{onClick:()=>I(P.id),disabled:a===P.id||l===P.id,className:"p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-50",title:`Uninstall ${P.id}`,children:l===P.id?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"})})]})})]},P.id))})]})]})}function Aj(e){if(e<60)return`${e}s`;const t=Math.floor(e/60);if(t<60)return`${t}m`;const n=Math.floor(t/60);return n<24?`${n}h ${t%60}m`:`${Math.floor(n/24)}d ${n%24}h`}function Pj({state:e}){return o("span",{className:`text-[10px] px-1.5 py-0.5 rounded-full ${e==="running"?"bg-success/10 text-success":e==="crashed"?"bg-destructive/10 text-destructive":"bg-muted text-muted-foreground"}`,children:e})}const _j=["trace","debug","info","warn","error"];function $j({proc:e,nodeId:t,defaultExpanded:n,activePanel:r,onTogglePanel:s}){const a=e.services??[],i=a.length===1,[l,c]=_(i||n),[d,u]=_(null),[p,h]=_("info"),m=e.name.includes("(core)"),g=Ba(),b=Tx(),x=zx(),y=async N=>{u(N);try{await g.mutateAsync({nodeId:t,addonId:N})}catch(k){console.error("Failed to restart addon:",k)}finally{u(null)}},w=async()=>{u(e.name);try{await b.mutateAsync({nodeId:t,processName:e.name})}catch(N){console.error("Failed to restart process:",N)}finally{u(null)}},v=async N=>{const k=`${t}/${e.name}`;try{await x.mutateAsync({nodeId:k,level:N}),h(N)}catch(C){console.error("Failed to set log level:",C)}};return f("div",{className:"border border-border/50 rounded-lg overflow-hidden",children:[f("div",{role:i?void 0:"button",tabIndex:i?void 0:0,onClick:i?void 0:()=>c(!l),onKeyDown:i?void 0:N=>{(N.key==="Enter"||N.key===" ")&&c(!l)},className:`flex items-center gap-2 w-full px-3 py-2 bg-muted/20 transition-colors text-left select-none ${i?"":"hover:bg-muted/40 cursor-pointer"}`,children:[i?o("span",{className:"h-3 w-3 shrink-0"}):l?o(lt,{className:"h-3 w-3 text-muted-foreground shrink-0"}):o(wt,{className:"h-3 w-3 text-muted-foreground shrink-0"}),m?o(hn,{className:"h-3.5 w-3.5 text-primary shrink-0"}):o(Ka,{className:"h-3.5 w-3.5 text-amber-500 shrink-0"}),o("span",{className:"text-xs font-semibold flex-1",children:e.name}),f("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:["PID ",e.pid]}),o(Pj,{state:e.state}),f("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:[e.cpuPercent,"% CPU"]}),o("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:It(e.memoryRss)}),o("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:Aj(e.uptimeSeconds)}),!m&&f("div",{className:"flex items-center gap-1",onClick:N=>N.stopPropagation(),children:[f(bg,{children:[o(xg,{className:"text-[9px] px-1.5 py-0.5 rounded border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors font-mono",title:"Set log level",children:p}),o(yg,{align:"end",className:"min-w-[70px] py-0.5",children:_j.map(N=>o(vg,{onClick:()=>v(N),className:`h-auto px-2 py-1 text-[10px] font-mono ${N===p?"text-primary font-semibold":""}`,children:N},N))})]}),o("button",{onClick:w,disabled:d===e.name,className:"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:"Restart process",children:o(kt,{className:`h-3 w-3 ${d===e.name?"animate-spin":""}`})})]})]}),l&&a.length>0&&o("div",{className:"divide-y divide-border/30",children:a.map(N=>f("div",{children:[f("div",{className:"flex items-center gap-2 px-3 py-1.5 pl-9 hover:bg-muted/10 transition-colors",children:[o("div",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${N.status==="running"?"bg-success":"bg-muted-foreground/30"}`}),o("span",{className:"text-xs font-medium flex-1 min-w-0 truncate",children:N.addonId}),N.capabilities.length>0&&f("div",{className:"flex gap-1 flex-shrink-0",children:[N.capabilities.slice(0,3).map(k=>o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-blue-500/10 text-blue-400 truncate max-w-[80px]",children:k},k)),N.capabilities.length>3&&f("span",{className:"text-[9px] text-muted-foreground",children:["+",N.capabilities.length-3]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[o("button",{onClick:()=>s(N.addonId,"logs"),className:`p-0.5 rounded transition-colors ${r?.addonId===N.addonId&&r.type==="logs"?"bg-primary/10 text-primary":"hover:bg-muted text-muted-foreground hover:text-foreground"}`,title:`Show logs for ${N.addonId}`,children:o(at,{className:"h-3 w-3"})}),o("button",{onClick:()=>s(N.addonId,"events"),className:`p-0.5 rounded transition-colors ${r?.addonId===N.addonId&&r.type==="events"?"bg-primary/10 text-primary":"hover:bg-muted text-muted-foreground hover:text-foreground"}`,title:`Show events for ${N.addonId}`,children:o(Za,{className:"h-3 w-3"})}),o("button",{onClick:()=>y(N.addonId),disabled:d===N.addonId,className:"p-0.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:`Restart ${N.addonId}`,children:o(kt,{className:`h-3 w-3 ${d===N.addonId?"animate-spin":""}`})})]})]}),r?.addonId===N.addonId&&r.type==="logs"&&o("div",{className:"border-t border-border/40 bg-muted/5",children:o(tn,{addonId:N.addonId,agentId:t,maxHeight:"max-h-48",showFilters:!1,onClose:()=>s(N.addonId,"logs")})}),r?.addonId===N.addonId&&r.type==="events"&&o("div",{className:"border-t border-border/40 bg-muted/5",children:o(br,{addonId:N.addonId,category:"addon.*",maxHeight:"max-h-48",onClose:()=>s(N.addonId,"events")})})]},N.addonId))}),l&&a.length===0&&o("div",{className:"px-3 py-2 pl-9 text-[10px] text-muted-foreground",children:"No services"})]})}function Dj({nodeId:e,processes:t}){const[n,r]=_(null),s=(a,i)=>{r(l=>l?.addonId===a&&l.type===i?null:{addonId:a,type:i})};return t.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No processes on this node"}):o("div",{className:"space-y-2 py-1",children:t.map((a,i)=>o($j,{proc:a,nodeId:e,defaultExpanded:i===0,activePanel:n,onTogglePanel:s},a.name))})}function Tj(e){return e<60?`${e}s`:e<3600?`${Math.floor(e/60)}m ${e%60}s`:e<86400?`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`:`${Math.floor(e/86400)}d ${Math.floor(e%86400/3600)}h`}function Lj(e,t=80){return e.length<=t?e:`…${e.slice(e.length-t+1)}`}function Rj({nodeId:e}){const t=ke(),n=nt(),[r,s]=_("all"),a=Gr("metrics.node-processes-snapshot",k=>k.nodeId===e),{data:i}=Ex({nodeId:e},{staleTime:6e4}),l=a?.processes??i,c=H(()=>l?[...l]:[],[l]),d=H(()=>r==="ghost"?c.filter(k=>k.classification==="ghost"):c,[c,r]),u=H(()=>{const k=c.filter(E=>E.classification==="ghost"),C=new Map;for(const E of k)C.has(E.ppid)||C.set(E.ppid,[]),C.get(E.ppid).push(E);return[...C.entries()].filter(([,E])=>E.length>1).map(([E,I])=>({ppid:E,children:I})).sort((E,I)=>I.children.length-E.children.length)},[c]),p=Ix({onSettled:()=>{t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]})}}),h=H(()=>{const k=new Map;for(const C of c)k.set(C.pid,C.classification);return k},[c]),m=async(k,C)=>{if(k.classification==="root"||k.classification==="system")return;const E=k.classification==="ghost"?"ghost":k.addonId??"process",I=C?"SIGKILL":"SIGTERM";await n({title:`Send ${I}?`,message:`Target pid ${k.pid} (${E}) on node ${e}.`,confirmLabel:`Send ${I}`,variant:"danger"})&&p.mutate({nodeId:e,pid:k.pid,force:C})},g=async(k,C)=>{try{await p.mutateAsync({nodeId:e,pid:k,force:C})}catch{}},b=async k=>{const C=h.get(k.ppid);if(C==="root"||C==="system"){await n({title:"Cannot kill protected ancestor",message:C==="root"?`pid ${k.ppid} is the current node supervisor. Restart the node via the cluster page instead.`:`pid ${k.ppid} is a system ancestor (concurrently / vite / npm wrapper). Killing it would tear down the dev tree.`,confirmLabel:"OK",cancelLabel:"Close",variant:"warning"});return}await n({title:`Kill ghost parent + ${k.children.length} child(ren)?`,message:`SIGKILL parent pid ${k.ppid} and SIGTERM ${k.children.length} ghost child(ren) on node ${e}.`,confirmLabel:"Kill all",variant:"danger"})&&(await Promise.all([g(k.ppid,!0),...k.children.map(I=>g(I.pid,!1))]),t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}))},x=async()=>{const k=c.filter(E=>E.classification==="ghost");k.length===0||!await n({title:`Kill all ${k.length} ghost process(es)?`,message:`SIGKILL ${k.length} ghost process(es) on node ${e}. This is irreversible.`,confirmLabel:"Kill all",variant:"danger"})||(await Promise.all(k.map(E=>g(E.pid,!0))),t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}))},y=c.filter(k=>k.classification==="ghost").length,w=c.filter(k=>k.classification==="managed").length,v=c.filter(k=>k.classification==="root").length,N=c.filter(k=>k.classification==="system").length;return f("div",{className:"space-y-4",children:[f("div",{className:"flex items-start justify-between gap-4",children:[f("p",{className:"text-[11px] text-foreground-subtle",children:["ps"," scan + kernel `$process.list` cross-reference. Ghosts = camstack-shaped commands with no managed binding (usually orphaned to ppid=1). Refreshes every 10s."]}),f("button",{type:"button",onClick:()=>t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}),className:"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[11px] text-foreground hover:bg-surface-hover",children:[o(ct,{className:"h-3 w-3"})," Refresh"]})]}),f("div",{className:"grid grid-cols-4 gap-3",children:[f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"Root"}),o("div",{className:"text-xl font-semibold text-foreground",children:v})]}),f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"Managed"}),o("div",{className:"text-xl font-semibold text-foreground",children:w})]}),f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"System"}),o("div",{className:"text-xl font-semibold text-foreground",children:N})]}),f("div",{className:`rounded-lg border p-3 ${y>0?"border-destructive/40 bg-destructive/5":"border-border"}`,children:[f("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle flex items-center gap-1",children:[y>0&&o(vs,{className:"h-3 w-3 text-destructive"})," Ghosts"]}),o("div",{className:`text-xl font-semibold ${y>0?"text-destructive":"text-foreground"}`,children:y})]})]}),u.length>0&&f("div",{className:"rounded-lg border border-amber-500/40 bg-amber-500/5 p-3",children:[f("div",{className:"flex items-center gap-1 text-[11px] font-semibold text-amber-400 mb-2",children:[o(it,{className:"h-3 w-3"})," Recurring ghost parents (",u.length,")"]}),o("div",{className:"space-y-1.5",children:u.map(k=>f("div",{className:"text-[11px] text-foreground flex items-center justify-between gap-2",children:[f("div",{className:"flex items-center gap-2",children:[f("span",{className:"font-mono text-foreground-subtle",children:["ppid ",k.ppid]}),f("span",{children:["→ ",k.children.length," ghost(s)"]})]}),f("button",{type:"button",disabled:p.isPending,onClick:()=>{b(k)},className:"inline-flex items-center gap-1 rounded border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-[10px] text-amber-400 hover:bg-amber-500/20 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill parent + ",k.children.length]})]},k.ppid))})]}),f("div",{className:"flex items-center justify-between gap-2 text-[11px]",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-foreground-subtle",children:"Filter:"}),f("button",{type:"button",className:`px-2 py-0.5 rounded ${r==="all"?"bg-primary text-primary-foreground":"border border-border text-foreground hover:bg-surface-hover"}`,onClick:()=>s("all"),children:["All (",c.length,")"]}),f("button",{type:"button",className:`px-2 py-0.5 rounded ${r==="ghost"?"bg-destructive text-destructive-foreground":"border border-border text-foreground hover:bg-surface-hover"}`,onClick:()=>s("ghost"),children:["Ghost only (",y,")"]})]}),y>0&&f("button",{type:"button",disabled:p.isPending,onClick:()=>{x()},className:"inline-flex items-center gap-1 rounded border border-destructive/40 bg-destructive/10 px-2 py-1 text-[11px] font-medium text-destructive hover:bg-destructive/20 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill all ",y," ghost(s)"]})]}),o("div",{className:"rounded-lg border border-border overflow-hidden",children:f("table",{className:"w-full text-xs",children:[o("thead",{className:"bg-surface",children:f("tr",{className:"text-foreground-subtle text-[10px] uppercase tracking-wider",children:[o("th",{className:"text-left px-3 py-2",children:"Class"}),o("th",{className:"text-right px-3 py-2",children:"PID"}),o("th",{className:"text-right px-3 py-2",children:"PPID"}),o("th",{className:"text-left px-3 py-2",children:"Addon"}),o("th",{className:"text-left px-3 py-2",children:"Command"}),o("th",{className:"text-right px-3 py-2",children:"CPU%"}),o("th",{className:"text-right px-3 py-2",children:"RSS"}),o("th",{className:"text-right px-3 py-2",children:"Uptime"}),o("th",{className:"w-44"})]})}),f("tbody",{children:[d.length===0&&o("tr",{children:o("td",{colSpan:9,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:r==="ghost"?"No ghost processes detected.":"Scanning…"})}),d.map(k=>f("tr",{className:`border-t border-border ${k.classification==="ghost"?"bg-destructive/5":""}`,children:[o("td",{className:"px-3 py-2",children:o("span",{className:`inline-block rounded-full px-1.5 py-0.5 text-[10px] font-medium ${k.classification==="ghost"?"bg-destructive/20 text-destructive":k.classification==="root"?"bg-sky-500/20 text-sky-400":k.classification==="system"?"bg-foreground-subtle/20 text-foreground-subtle":"bg-success/20 text-success"}`,children:k.classification})}),o("td",{className:"px-3 py-2 text-right font-mono text-foreground",children:k.pid}),f("td",{className:"px-3 py-2 text-right font-mono text-foreground-subtle",children:[k.ppid,k.orphaned?" ⚠":""]}),o("td",{className:"px-3 py-2 text-foreground-subtle text-[11px]",children:k.addonId??"—"}),o("td",{className:"px-3 py-2 font-mono text-[10px] text-foreground-subtle break-all",children:Lj(k.command)}),o("td",{className:"px-3 py-2 text-right text-foreground",children:k.cpuPercent.toFixed(1)}),o("td",{className:"px-3 py-2 text-right text-foreground",children:It(k.memoryRssBytes)}),o("td",{className:"px-3 py-2 text-right text-foreground-subtle",children:Tj(k.uptimeSec)}),o("td",{className:"px-3 py-2 text-right",children:f("div",{className:"inline-flex gap-1",children:[f("button",{type:"button",disabled:p.isPending||k.classification==="root"||k.classification==="system",onClick:()=>{m(k,!1)},title:"SIGTERM",className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded border border-border text-[10px] text-foreground hover:bg-surface-hover disabled:opacity-30",children:[o(Ze,{className:"h-3 w-3"})," Term"]}),f("button",{type:"button",disabled:p.isPending||k.classification==="root"||k.classification==="system",onClick:()=>{m(k,!0)},title:"SIGKILL",className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded border border-destructive/30 text-[10px] text-destructive hover:bg-destructive/10 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill"]})]})})]},k.pid))]})]})}),p.isError&&f("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-[11px] text-destructive",children:["Kill failed: ",p.error instanceof Error?p.error.message:"unknown"]})]})}function Oj({nodeId:e,addonIds:t}){return t.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No addons on this node"}):o("div",{className:"w-full py-2",children:o(to,{nodeId:e,addonIds:t,level:"global"})})}function Bj({nodeId:e,addons:t}){const n=ke(),{data:r,isLoading:s}=Zx({nodeId:e}),a=H(()=>{const l=new Map;for(const c of t)for(const d of c.capabilities){const u=l.get(d)??[];u.push(c.id),l.set(d,u)}return[...l.entries()].sort(([c],[d])=>c.localeCompare(d)).map(([c,d])=>({capName:c,providers:d}))},[t]),i=Xx({onSuccess:()=>{n.invalidateQueries({queryKey:[["pipelineOrchestrator","getCapabilityBindings"]]})}});return a.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No capabilities on this node"}):f("table",{className:"w-full text-xs",children:[o("thead",{children:f("tr",{className:"text-muted-foreground text-left",children:[o("th",{className:"py-2 font-medium w-1/2",children:"Capability"}),o("th",{className:"py-2 font-medium",children:"Bound provider"})]})}),o("tbody",{children:a.map(({capName:l,providers:c})=>{const u=r?.[l]??c[0]??"",p=c.length===1;return f("tr",{className:"border-t border-border/50",children:[o("td",{className:"py-2 font-medium",children:l}),o("td",{className:"py-2",children:o("select",{value:u,onChange:h=>i.mutate({nodeId:e,capName:l,addonId:h.target.value}),disabled:p||i.isPending||s,className:"w-full rounded-md border border-border bg-surface px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-60",title:p?"Only one provider installed — choice becomes available once a second addon registers this capability":void 0,children:c.map(h=>o("option",{value:h,children:h},h))})})]},l)})})]})}function zj(e){if(e==null)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/86400),r=Math.floor(t%86400/3600),s=Math.floor(t%3600/60);return n>0?`${n}d ${r}h ${s}m`:r>0?`${r}h ${s}m`:`${s}m`}function Fj(e){const[t,n]=_(!1),[r,s]=_(e.name),a=ke(),i=Rx({onSuccess:()=>{a.invalidateQueries({queryKey:[["nodes","topology"]]})}}),l=(e.localIps??[]).filter(p=>!p.includes(":")),c=(e.localIps??[]).filter(p=>p.includes(":")),d=async()=>{if(!r.trim()||r===e.name){n(!1);return}try{await i.mutateAsync({nodeId:e.nodeId,name:r.trim()}),n(!1)}catch(p){console.error("Rename failed:",p)}},u=[["Node ID",o("span",{className:"font-mono text-xs",children:e.nodeId})],["Display Name",t?f("div",{className:"flex items-center gap-1.5",children:[o("input",{type:"text",className:"flex-1 px-2 py-0.5 text-xs border border-border rounded bg-background focus:outline-none focus:ring-1 focus:ring-primary",value:r,onChange:p=>s(p.target.value),onKeyDown:p=>{p.key==="Enter"&&d(),p.key==="Escape"&&n(!1)},disabled:i.isPending,autoFocus:!0}),o("button",{onClick:()=>void d(),disabled:i.isPending,className:"p-0.5 text-success hover:bg-success/10 rounded",title:"Save",children:o(_t,{className:"h-3.5 w-3.5"})}),o("button",{onClick:()=>n(!1),className:"p-0.5 text-muted-foreground hover:bg-muted rounded",title:"Cancel",children:o(Fe,{className:"h-3.5 w-3.5"})})]}):f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-xs",children:e.name}),!e.isHub&&o("button",{onClick:()=>{s(e.name),n(!0)},className:"p-0.5 text-muted-foreground hover:text-primary rounded",title:"Rename",children:o(eo,{className:"h-3 w-3"})})]})],["Hostname",o("span",{className:"text-xs",children:e.hostname})],["Role",e.isHub?o("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-primary/10 text-primary font-medium",children:"Hub"}):o("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground font-medium",children:"Agent"})],["Platform",f("span",{className:"text-xs",children:[e.platform," / ",e.arch]})],["CPU",f("span",{className:"text-xs",children:[e.cpuModel??"—"," (",e.cpuCores," cores)"]})],["Memory",o("span",{className:"text-xs",children:e.memoryMB>0?`${(e.memoryMB/1024).toFixed(1)} GB`:"—"})],["Uptime",o("span",{className:"text-xs",children:zj(e.uptime)})],["Engines",e.engines.length>0?o("div",{className:"flex flex-wrap gap-1",children:e.engines.map(p=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:p},p))}):o("span",{className:"text-xs text-muted-foreground",children:"—"})]];return l.length>0&&u.push(["IPv4",o("div",{className:"flex flex-wrap gap-1.5",children:l.map((p,h)=>o("span",{className:"font-mono text-xs px-1.5 py-0.5 rounded bg-muted",children:p},`${p}-${h}`))})]),c.length>0&&u.push(["IPv6",o("div",{className:"flex flex-wrap gap-1.5",children:c.map((p,h)=>o("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-muted truncate max-w-[280px]",title:p,children:p},`${p}-${h}`))})]),o("div",{className:"py-2",children:o("table",{className:"w-full text-sm",children:o("tbody",{children:u.map(([p,h],m)=>f("tr",{className:m%2===0?"bg-muted/20":"",children:[o("td",{className:"py-1.5 px-2 text-xs font-medium text-muted-foreground w-28 align-top whitespace-nowrap",children:p}),o("td",{className:"py-1.5 px-2",children:h})]},p))})})})}function jj({node:e}){const[t,n]=_("info"),r=e.processes??[],s=e.addons.map(a=>a.id);return e.isOnline?f("div",{className:"border border-border rounded-xl overflow-hidden",children:[f("div",{className:"flex items-center gap-3 px-4 py-3 bg-muted/30 border-b border-border",children:[o("div",{className:"w-2.5 h-2.5 rounded-full bg-success"}),o("span",{className:"text-sm font-semibold",children:e.name}),f("span",{className:"text-xs text-muted-foreground",children:[e.cpuModel??e.platform," · ",e.memoryMB>0?`${Math.round(e.memoryMB/1024)}GB`:""," · ",e.arch]}),e.engines.map(a=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:a},a)),f("div",{className:"ml-auto flex gap-3 text-xs text-muted-foreground",children:[f("span",{className:"flex items-center gap-1",children:[o(bt,{className:"h-3 w-3"})," ",e.cpuPercent,"%"]}),f("span",{className:"flex items-center gap-1",children:[o(Xd,{className:"h-3 w-3"})," ",e.memoryPercent,"%"]})]})]}),o("div",{className:"flex border-b border-border px-4",children:["info","addons","forks","processes","settings","capabilities"].map(a=>o("button",{onClick:()=>n(a),className:`px-3 py-2 text-xs font-medium border-b-2 transition-colors ${t===a?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground"}`,children:a==="info"?"Info":a==="addons"?`Addons (${e.addons.length})`:a==="forks"?`Forks (${r.length})`:a==="processes"?"Processes":a==="settings"?"Settings":"Capabilities"},a))}),f("div",{className:"px-4 py-2",children:[t==="info"&&o(Fj,{nodeId:e.id,name:e.name,hostname:e.hostname,platform:e.platform,arch:e.arch,cpuModel:e.cpuModel,cpuCores:e.cpuCores,memoryMB:e.memoryMB,engines:e.engines,isHub:e.isHub,uptime:e.uptime,localIps:e.localIps}),t==="addons"&&o(Ij,{nodeId:e.id,addons:e.addons,isHub:e.isHub}),t==="forks"&&o(Dj,{nodeId:e.id,processes:r}),t==="processes"&&o(Rj,{nodeId:e.id}),t==="settings"&&o(Oj,{nodeId:e.id,addonIds:s}),t==="capabilities"&&o(Bj,{nodeId:e.id,addons:e.addons})]})]}):f("div",{className:"border border-border rounded-xl overflow-hidden opacity-60",children:[f("div",{className:"flex items-center gap-3 px-4 py-3 bg-muted/30",children:[o("div",{className:"w-2.5 h-2.5 rounded-full bg-destructive"}),o("span",{className:"text-sm font-semibold",children:e.name}),f("span",{className:"text-xs text-muted-foreground",children:[e.cpuModel??e.platform," · ",e.memoryMB>0?`${Math.round(e.memoryMB/1024)}GB`:""," · ",e.arch]}),e.engines.map(a=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:a},a)),o("span",{className:"ml-auto text-xs px-2 py-0.5 rounded-full bg-destructive/10 text-destructive",children:"offline"})]}),f("div",{className:"px-4 py-3 text-xs text-muted-foreground",children:[e.addons.length," addon",e.addons.length!==1?"s":""," assigned — will resume when node reconnects"]})]})}function Vj({nodes:e}){const t=[...e].sort((n,r)=>n.isHub?-1:r.isHub?1:n.isOnline&&!r.isOnline?-1:!n.isOnline&&r.isOnline?1:n.name.localeCompare(r.name));return o("div",{className:"flex flex-col gap-4",children:t.map(n=>o(jj,{node:n},n.id))})}function We(e){if(typeof e=="string"||typeof e=="number")return""+e;let t="";if(Array.isArray(e))for(let n=0,r;n<e.length;n++)(r=We(e[n]))!==""&&(t+=(t&&" ")+r);else for(let n in e)e[n]&&(t+=(t&&" ")+n);return t}var Hj={value:()=>{}};function oi(){for(var e=0,t=arguments.length,n={},r;e<t;++e){if(!(r=arguments[e]+"")||r in n||/[\s.]/.test(r))throw new Error("illegal type: "+r);n[r]=[]}return new Qs(n)}function Qs(e){this._=e}function qj(e,t){return e.trim().split(/^|\s+/).map(function(n){var r="",s=n.indexOf(".");if(s>=0&&(r=n.slice(s+1),n=n.slice(0,s)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}Qs.prototype=oi.prototype={constructor:Qs,on:function(e,t){var n=this._,r=qj(e+"",n),s,a=-1,i=r.length;if(arguments.length<2){for(;++a<i;)if((s=(e=r[a]).type)&&(s=Uj(n[s],e.name)))return s;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++a<i;)if(s=(e=r[a]).type)n[s]=Rf(n[s],e.name,t);else if(t==null)for(s in n)n[s]=Rf(n[s],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new Qs(e)},call:function(e,t){if((s=arguments.length-2)>0)for(var n=new Array(s),r=0,s,a;r<s;++r)n[r]=arguments[r+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(a=this._[e],r=0,s=a.length;r<s;++r)a[r].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var r=this._[e],s=0,a=r.length;s<a;++s)r[s].value.apply(t,n)}};function Uj(e,t){for(var n=0,r=e.length,s;n<r;++n)if((s=e[n]).name===t)return s.value}function Rf(e,t,n){for(var r=0,s=e.length;r<s;++r)if(e[r].name===t){e[r]=Hj,e=e.slice(0,r).concat(e.slice(r+1));break}return n!=null&&e.push({name:t,value:n}),e}var ic="http://www.w3.org/1999/xhtml";const Of={svg:"http://www.w3.org/2000/svg",xhtml:ic,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function si(e){var t=e+="",n=t.indexOf(":");return n>=0&&(t=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),Of.hasOwnProperty(t)?{space:Of[t],local:e}:e}function Qj(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===ic&&t.documentElement.namespaceURI===ic?t.createElement(e):t.createElementNS(n,e)}}function Gj(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Wv(e){var t=si(e);return(t.local?Gj:Qj)(t)}function Kj(){}function ru(e){return e==null?Kj:function(){return this.querySelector(e)}}function Wj(e){typeof e!="function"&&(e=ru(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=new Array(i),c,d,u=0;u<i;++u)(c=a[u])&&(d=e.call(c,c.__data__,u,a))&&("__data__"in c&&(d.__data__=c.__data__),l[u]=d);return new xt(r,this._parents)}function Yj(e){return e==null?[]:Array.isArray(e)?e:Array.from(e)}function Zj(){return[]}function Yv(e){return e==null?Zj:function(){return this.querySelectorAll(e)}}function Xj(e){return function(){return Yj(e.apply(this,arguments))}}function Jj(e){typeof e=="function"?e=Xj(e):e=Yv(e);for(var t=this._groups,n=t.length,r=[],s=[],a=0;a<n;++a)for(var i=t[a],l=i.length,c,d=0;d<l;++d)(c=i[d])&&(r.push(e.call(c,c.__data__,d,i)),s.push(c));return new xt(r,s)}function Zv(e){return function(){return this.matches(e)}}function Xv(e){return function(t){return t.matches(e)}}var eV=Array.prototype.find;function tV(e){return function(){return eV.call(this.children,e)}}function nV(){return this.firstElementChild}function rV(e){return this.select(e==null?nV:tV(typeof e=="function"?e:Xv(e)))}var oV=Array.prototype.filter;function sV(){return Array.from(this.children)}function aV(e){return function(){return oV.call(this.children,e)}}function iV(e){return this.selectAll(e==null?sV:aV(typeof e=="function"?e:Xv(e)))}function lV(e){typeof e!="function"&&(e=Zv(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=[],c,d=0;d<i;++d)(c=a[d])&&e.call(c,c.__data__,d,a)&&l.push(c);return new xt(r,this._parents)}function Jv(e){return new Array(e.length)}function cV(){return new xt(this._enter||this._groups.map(Jv),this._parents)}function ma(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}ma.prototype={constructor:ma,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};function dV(e){return function(){return e}}function uV(e,t,n,r,s,a){for(var i=0,l,c=t.length,d=a.length;i<d;++i)(l=t[i])?(l.__data__=a[i],r[i]=l):n[i]=new ma(e,a[i]);for(;i<c;++i)(l=t[i])&&(s[i]=l)}function pV(e,t,n,r,s,a,i){var l,c,d=new Map,u=t.length,p=a.length,h=new Array(u),m;for(l=0;l<u;++l)(c=t[l])&&(h[l]=m=i.call(c,c.__data__,l,t)+"",d.has(m)?s[l]=c:d.set(m,c));for(l=0;l<p;++l)m=i.call(e,a[l],l,a)+"",(c=d.get(m))?(r[l]=c,c.__data__=a[l],d.delete(m)):n[l]=new ma(e,a[l]);for(l=0;l<u;++l)(c=t[l])&&d.get(h[l])===c&&(s[l]=c)}function fV(e){return e.__data__}function hV(e,t){if(!arguments.length)return Array.from(this,fV);var n=t?pV:uV,r=this._parents,s=this._groups;typeof e!="function"&&(e=dV(e));for(var a=s.length,i=new Array(a),l=new Array(a),c=new Array(a),d=0;d<a;++d){var u=r[d],p=s[d],h=p.length,m=mV(e.call(u,u&&u.__data__,d,r)),g=m.length,b=l[d]=new Array(g),x=i[d]=new Array(g),y=c[d]=new Array(h);n(u,p,b,x,y,m,t);for(var w=0,v=0,N,k;w<g;++w)if(N=b[w]){for(w>=v&&(v=w+1);!(k=x[v])&&++v<g;);N._next=k||null}}return i=new xt(i,r),i._enter=l,i._exit=c,i}function mV(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function gV(){return new xt(this._exit||this._groups.map(Jv),this._parents)}function bV(e,t,n){var r=this.enter(),s=this,a=this.exit();return typeof e=="function"?(r=e(r),r&&(r=r.selection())):r=r.append(e+""),t!=null&&(s=t(s),s&&(s=s.selection())),n==null?a.remove():n(a),r&&s?r.merge(s).order():s}function xV(e){for(var t=e.selection?e.selection():e,n=this._groups,r=t._groups,s=n.length,a=r.length,i=Math.min(s,a),l=new Array(s),c=0;c<i;++c)for(var d=n[c],u=r[c],p=d.length,h=l[c]=new Array(p),m,g=0;g<p;++g)(m=d[g]||u[g])&&(h[g]=m);for(;c<s;++c)l[c]=n[c];return new xt(l,this._parents)}function yV(){for(var e=this._groups,t=-1,n=e.length;++t<n;)for(var r=e[t],s=r.length-1,a=r[s],i;--s>=0;)(i=r[s])&&(a&&i.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(i,a),a=i);return this}function vV(e){e||(e=wV);function t(p,h){return p&&h?e(p.__data__,h.__data__):!p-!h}for(var n=this._groups,r=n.length,s=new Array(r),a=0;a<r;++a){for(var i=n[a],l=i.length,c=s[a]=new Array(l),d,u=0;u<l;++u)(d=i[u])&&(c[u]=d);c.sort(t)}return new xt(s,this._parents).order()}function wV(e,t){return e<t?-1:e>t?1:e>=t?0:NaN}function NV(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function kV(){return Array.from(this)}function SV(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],s=0,a=r.length;s<a;++s){var i=r[s];if(i)return i}return null}function CV(){let e=0;for(const t of this)++e;return e}function MV(){return!this.node()}function EV(e){for(var t=this._groups,n=0,r=t.length;n<r;++n)for(var s=t[n],a=0,i=s.length,l;a<i;++a)(l=s[a])&&e.call(l,l.__data__,a,s);return this}function IV(e){return function(){this.removeAttribute(e)}}function AV(e){return function(){this.removeAttributeNS(e.space,e.local)}}function PV(e,t){return function(){this.setAttribute(e,t)}}function _V(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function $V(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttribute(e):this.setAttribute(e,n)}}function DV(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function TV(e,t){var n=si(e);if(arguments.length<2){var r=this.node();return n.local?r.getAttributeNS(n.space,n.local):r.getAttribute(n)}return this.each((t==null?n.local?AV:IV:typeof t=="function"?n.local?DV:$V:n.local?_V:PV)(n,t))}function e1(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function LV(e){return function(){this.style.removeProperty(e)}}function RV(e,t,n){return function(){this.style.setProperty(e,t,n)}}function OV(e,t,n){return function(){var r=t.apply(this,arguments);r==null?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function BV(e,t,n){return arguments.length>1?this.each((t==null?LV:typeof t=="function"?OV:RV)(e,t,n??"")):Lr(this.node(),e)}function Lr(e,t){return e.style.getPropertyValue(t)||e1(e).getComputedStyle(e,null).getPropertyValue(t)}function zV(e){return function(){delete this[e]}}function FV(e,t){return function(){this[e]=t}}function jV(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function VV(e,t){return arguments.length>1?this.each((t==null?zV:typeof t=="function"?jV:FV)(e,t)):this.node()[e]}function t1(e){return e.trim().split(/^|\s+/)}function ou(e){return e.classList||new n1(e)}function n1(e){this._node=e,this._names=t1(e.getAttribute("class")||"")}n1.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function r1(e,t){for(var n=ou(e),r=-1,s=t.length;++r<s;)n.add(t[r])}function o1(e,t){for(var n=ou(e),r=-1,s=t.length;++r<s;)n.remove(t[r])}function HV(e){return function(){r1(this,e)}}function qV(e){return function(){o1(this,e)}}function UV(e,t){return function(){(t.apply(this,arguments)?r1:o1)(this,e)}}function QV(e,t){var n=t1(e+"");if(arguments.length<2){for(var r=ou(this.node()),s=-1,a=n.length;++s<a;)if(!r.contains(n[s]))return!1;return!0}return this.each((typeof t=="function"?UV:t?HV:qV)(n,t))}function GV(){this.textContent=""}function KV(e){return function(){this.textContent=e}}function WV(e){return function(){var t=e.apply(this,arguments);this.textContent=t??""}}function YV(e){return arguments.length?this.each(e==null?GV:(typeof e=="function"?WV:KV)(e)):this.node().textContent}function ZV(){this.innerHTML=""}function XV(e){return function(){this.innerHTML=e}}function JV(e){return function(){var t=e.apply(this,arguments);this.innerHTML=t??""}}function eH(e){return arguments.length?this.each(e==null?ZV:(typeof e=="function"?JV:XV)(e)):this.node().innerHTML}function tH(){this.nextSibling&&this.parentNode.appendChild(this)}function nH(){return this.each(tH)}function rH(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function oH(){return this.each(rH)}function sH(e){var t=typeof e=="function"?e:Wv(e);return this.select(function(){return this.appendChild(t.apply(this,arguments))})}function aH(){return null}function iH(e,t){var n=typeof e=="function"?e:Wv(e),r=t==null?aH:typeof t=="function"?t:ru(t);return this.select(function(){return this.insertBefore(n.apply(this,arguments),r.apply(this,arguments)||null)})}function lH(){var e=this.parentNode;e&&e.removeChild(this)}function cH(){return this.each(lH)}function dH(){var e=this.cloneNode(!1),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function uH(){var e=this.cloneNode(!0),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function pH(e){return this.select(e?uH:dH)}function fH(e){return arguments.length?this.property("__data__",e):this.node().__data__}function hH(e){return function(t){e.call(this,t,this.__data__)}}function mH(e){return e.trim().split(/^|\s+/).map(function(t){var n="",r=t.indexOf(".");return r>=0&&(n=t.slice(r+1),t=t.slice(0,r)),{type:t,name:n}})}function gH(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,s=t.length,a;n<s;++n)a=t[n],(!e.type||a.type===e.type)&&a.name===e.name?this.removeEventListener(a.type,a.listener,a.options):t[++r]=a;++r?t.length=r:delete this.__on}}}function bH(e,t,n){return function(){var r=this.__on,s,a=hH(t);if(r){for(var i=0,l=r.length;i<l;++i)if((s=r[i]).type===e.type&&s.name===e.name){this.removeEventListener(s.type,s.listener,s.options),this.addEventListener(s.type,s.listener=a,s.options=n),s.value=t;return}}this.addEventListener(e.type,a,n),s={type:e.type,name:e.name,value:t,listener:a,options:n},r?r.push(s):this.__on=[s]}}function xH(e,t,n){var r=mH(e+""),s,a=r.length,i;if(arguments.length<2){var l=this.node().__on;if(l){for(var c=0,d=l.length,u;c<d;++c)for(s=0,u=l[c];s<a;++s)if((i=r[s]).type===u.type&&i.name===u.name)return u.value}return}for(l=t?bH:gH,s=0;s<a;++s)this.each(l(r[s],t,n));return this}function s1(e,t,n){var r=e1(e),s=r.CustomEvent;typeof s=="function"?s=new s(t,n):(s=r.document.createEvent("Event"),n?(s.initEvent(t,n.bubbles,n.cancelable),s.detail=n.detail):s.initEvent(t,!1,!1)),e.dispatchEvent(s)}function yH(e,t){return function(){return s1(this,e,t)}}function vH(e,t){return function(){return s1(this,e,t.apply(this,arguments))}}function wH(e,t){return this.each((typeof t=="function"?vH:yH)(e,t))}function*NH(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],s=0,a=r.length,i;s<a;++s)(i=r[s])&&(yield i)}var a1=[null];function xt(e,t){this._groups=e,this._parents=t}function rs(){return new xt([[document.documentElement]],a1)}function kH(){return this}xt.prototype=rs.prototype={constructor:xt,select:Wj,selectAll:Jj,selectChild:rV,selectChildren:iV,filter:lV,data:hV,enter:cV,exit:gV,join:bV,merge:xV,selection:kH,order:yV,sort:vV,call:NV,nodes:kV,node:SV,size:CV,empty:MV,each:EV,attr:TV,style:BV,property:VV,classed:QV,text:YV,html:eH,raise:nH,lower:oH,append:sH,insert:iH,remove:cH,clone:pH,datum:fH,on:xH,dispatch:wH,[Symbol.iterator]:NH};function ht(e){return typeof e=="string"?new xt([[document.querySelector(e)]],[document.documentElement]):new xt([[e]],a1)}function SH(e){let t;for(;t=e.sourceEvent;)e=t;return e}function Lt(e,t){if(e=SH(e),t===void 0&&(t=e.currentTarget),t){var n=t.ownerSVGElement||t;if(n.createSVGPoint){var r=n.createSVGPoint();return r.x=e.clientX,r.y=e.clientY,r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}if(t.getBoundingClientRect){var s=t.getBoundingClientRect();return[e.clientX-s.left-t.clientLeft,e.clientY-s.top-t.clientTop]}}return[e.pageX,e.pageY]}const CH={passive:!1},To={capture:!0,passive:!1};function il(e){e.stopImmediatePropagation()}function Ar(e){e.preventDefault(),e.stopImmediatePropagation()}function i1(e){var t=e.document.documentElement,n=ht(e).on("dragstart.drag",Ar,To);"onselectstart"in t?n.on("selectstart.drag",Ar,To):(t.__noselect=t.style.MozUserSelect,t.style.MozUserSelect="none")}function l1(e,t){var n=e.document.documentElement,r=ht(e).on("dragstart.drag",null);t&&(r.on("click.drag",Ar,To),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in n?r.on("selectstart.drag",null):(n.style.MozUserSelect=n.__noselect,delete n.__noselect)}const Ps=e=>()=>e;function lc(e,{sourceEvent:t,subject:n,target:r,identifier:s,active:a,x:i,y:l,dx:c,dy:d,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:s,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:i,enumerable:!0,configurable:!0},y:{value:l,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:d,enumerable:!0,configurable:!0},_:{value:u}})}lc.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function MH(e){return!e.ctrlKey&&!e.button}function EH(){return this.parentNode}function IH(e,t){return t??{x:e.x,y:e.y}}function AH(){return navigator.maxTouchPoints||"ontouchstart"in this}function c1(){var e=MH,t=EH,n=IH,r=AH,s={},a=oi("start","drag","end"),i=0,l,c,d,u,p=0;function h(N){N.on("mousedown.drag",m).filter(r).on("touchstart.drag",x).on("touchmove.drag",y,CH).on("touchend.drag touchcancel.drag",w).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function m(N,k){if(!(u||!e.call(this,N,k))){var C=v(this,t.call(this,N,k),N,k,"mouse");C&&(ht(N.view).on("mousemove.drag",g,To).on("mouseup.drag",b,To),i1(N.view),il(N),d=!1,l=N.clientX,c=N.clientY,C("start",N))}}function g(N){if(Ar(N),!d){var k=N.clientX-l,C=N.clientY-c;d=k*k+C*C>p}s.mouse("drag",N)}function b(N){ht(N.view).on("mousemove.drag mouseup.drag",null),l1(N.view,d),Ar(N),s.mouse("end",N)}function x(N,k){if(e.call(this,N,k)){var C=N.changedTouches,E=t.call(this,N,k),I=C.length,A,z;for(A=0;A<I;++A)(z=v(this,E,N,k,C[A].identifier,C[A]))&&(il(N),z("start",N,C[A]))}}function y(N){var k=N.changedTouches,C=k.length,E,I;for(E=0;E<C;++E)(I=s[k[E].identifier])&&(Ar(N),I("drag",N,k[E]))}function w(N){var k=N.changedTouches,C=k.length,E,I;for(u&&clearTimeout(u),u=setTimeout(function(){u=null},500),E=0;E<C;++E)(I=s[k[E].identifier])&&(il(N),I("end",N,k[E]))}function v(N,k,C,E,I,A){var z=a.copy(),P=Lt(A||C,k),B,R,M;if((M=n.call(N,new lc("beforestart",{sourceEvent:C,target:h,identifier:I,active:i,x:P[0],y:P[1],dx:0,dy:0,dispatch:z}),E))!=null)return B=M.x-P[0]||0,R=M.y-P[1]||0,function D(T,L,O){var F=P,j;switch(T){case"start":s[I]=D,j=i++;break;case"end":delete s[I],--i;case"drag":P=Lt(O||L,k),j=i;break}z.call(T,N,new lc(T,{sourceEvent:L,subject:M,target:h,identifier:I,active:j,x:P[0]+B,y:P[1]+R,dx:P[0]-F[0],dy:P[1]-F[1],dispatch:z}),E)}}return h.filter=function(N){return arguments.length?(e=typeof N=="function"?N:Ps(!!N),h):e},h.container=function(N){return arguments.length?(t=typeof N=="function"?N:Ps(N),h):t},h.subject=function(N){return arguments.length?(n=typeof N=="function"?N:Ps(N),h):n},h.touchable=function(N){return arguments.length?(r=typeof N=="function"?N:Ps(!!N),h):r},h.on=function(){var N=a.on.apply(a,arguments);return N===a?h:N},h.clickDistance=function(N){return arguments.length?(p=(N=+N)*N,h):Math.sqrt(p)},h}function su(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function d1(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function os(){}var Lo=.7,ga=1/Lo,Pr="\\s*([+-]?\\d+)\\s*",Ro="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Yt="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",PH=/^#([0-9a-f]{3,8})$/,_H=new RegExp(`^rgb\\(${Pr},${Pr},${Pr}\\)$`),$H=new RegExp(`^rgb\\(${Yt},${Yt},${Yt}\\)$`),DH=new RegExp(`^rgba\\(${Pr},${Pr},${Pr},${Ro}\\)$`),TH=new RegExp(`^rgba\\(${Yt},${Yt},${Yt},${Ro}\\)$`),LH=new RegExp(`^hsl\\(${Ro},${Yt},${Yt}\\)$`),RH=new RegExp(`^hsla\\(${Ro},${Yt},${Yt},${Ro}\\)$`),Bf={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};su(os,ar,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:zf,formatHex:zf,formatHex8:OH,formatHsl:BH,formatRgb:Ff,toString:Ff});function zf(){return this.rgb().formatHex()}function OH(){return this.rgb().formatHex8()}function BH(){return u1(this).formatHsl()}function Ff(){return this.rgb().formatRgb()}function ar(e){var t,n;return e=(e+"").trim().toLowerCase(),(t=PH.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?jf(t):n===3?new st(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?_s(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?_s(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=_H.exec(e))?new st(t[1],t[2],t[3],1):(t=$H.exec(e))?new st(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=DH.exec(e))?_s(t[1],t[2],t[3],t[4]):(t=TH.exec(e))?_s(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=LH.exec(e))?qf(t[1],t[2]/100,t[3]/100,1):(t=RH.exec(e))?qf(t[1],t[2]/100,t[3]/100,t[4]):Bf.hasOwnProperty(e)?jf(Bf[e]):e==="transparent"?new st(NaN,NaN,NaN,0):null}function jf(e){return new st(e>>16&255,e>>8&255,e&255,1)}function _s(e,t,n,r){return r<=0&&(e=t=n=NaN),new st(e,t,n,r)}function zH(e){return e instanceof os||(e=ar(e)),e?(e=e.rgb(),new st(e.r,e.g,e.b,e.opacity)):new st}function cc(e,t,n,r){return arguments.length===1?zH(e):new st(e,t,n,r??1)}function st(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}su(st,cc,d1(os,{brighter(e){return e=e==null?ga:Math.pow(ga,e),new st(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Lo:Math.pow(Lo,e),new st(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new st(Zn(this.r),Zn(this.g),Zn(this.b),ba(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Vf,formatHex:Vf,formatHex8:FH,formatRgb:Hf,toString:Hf}));function Vf(){return`#${Gn(this.r)}${Gn(this.g)}${Gn(this.b)}`}function FH(){return`#${Gn(this.r)}${Gn(this.g)}${Gn(this.b)}${Gn((isNaN(this.opacity)?1:this.opacity)*255)}`}function Hf(){const e=ba(this.opacity);return`${e===1?"rgb(":"rgba("}${Zn(this.r)}, ${Zn(this.g)}, ${Zn(this.b)}${e===1?")":`, ${e})`}`}function ba(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Zn(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Gn(e){return e=Zn(e),(e<16?"0":"")+e.toString(16)}function qf(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Rt(e,t,n,r)}function u1(e){if(e instanceof Rt)return new Rt(e.h,e.s,e.l,e.opacity);if(e instanceof os||(e=ar(e)),!e)return new Rt;if(e instanceof Rt)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,s=Math.min(t,n,r),a=Math.max(t,n,r),i=NaN,l=a-s,c=(a+s)/2;return l?(t===a?i=(n-r)/l+(n<r)*6:n===a?i=(r-t)/l+2:i=(t-n)/l+4,l/=c<.5?a+s:2-a-s,i*=60):l=c>0&&c<1?0:i,new Rt(i,l,c,e.opacity)}function jH(e,t,n,r){return arguments.length===1?u1(e):new Rt(e,t,n,r??1)}function Rt(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}su(Rt,jH,d1(os,{brighter(e){return e=e==null?ga:Math.pow(ga,e),new Rt(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Lo:Math.pow(Lo,e),new Rt(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,s=2*n-r;return new st(ll(e>=240?e-240:e+120,s,r),ll(e,s,r),ll(e<120?e+240:e-120,s,r),this.opacity)},clamp(){return new Rt(Uf(this.h),$s(this.s),$s(this.l),ba(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=ba(this.opacity);return`${e===1?"hsl(":"hsla("}${Uf(this.h)}, ${$s(this.s)*100}%, ${$s(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Uf(e){return e=(e||0)%360,e<0?e+360:e}function $s(e){return Math.max(0,Math.min(1,e||0))}function ll(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const au=e=>()=>e;function VH(e,t){return function(n){return e+n*t}}function HH(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function qH(e){return(e=+e)==1?p1:function(t,n){return n-t?HH(t,n,e):au(isNaN(t)?n:t)}}function p1(e,t){var n=t-e;return n?VH(e,n):au(isNaN(e)?t:e)}const xa=(function e(t){var n=qH(t);function r(s,a){var i=n((s=cc(s)).r,(a=cc(a)).r),l=n(s.g,a.g),c=n(s.b,a.b),d=p1(s.opacity,a.opacity);return function(u){return s.r=i(u),s.g=l(u),s.b=c(u),s.opacity=d(u),s+""}}return r.gamma=e,r})(1);function UH(e,t){t||(t=[]);var n=e?Math.min(t.length,e.length):0,r=t.slice(),s;return function(a){for(s=0;s<n;++s)r[s]=e[s]*(1-a)+t[s]*a;return r}}function QH(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function GH(e,t){var n=t?t.length:0,r=e?Math.min(n,e.length):0,s=new Array(r),a=new Array(n),i;for(i=0;i<r;++i)s[i]=So(e[i],t[i]);for(;i<n;++i)a[i]=t[i];return function(l){for(i=0;i<r;++i)a[i]=s[i](l);return a}}function KH(e,t){var n=new Date;return e=+e,t=+t,function(r){return n.setTime(e*(1-r)+t*r),n}}function Qt(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}function WH(e,t){var n={},r={},s;(e===null||typeof e!="object")&&(e={}),(t===null||typeof t!="object")&&(t={});for(s in t)s in e?n[s]=So(e[s],t[s]):r[s]=t[s];return function(a){for(s in n)r[s]=n[s](a);return r}}var dc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,cl=new RegExp(dc.source,"g");function YH(e){return function(){return e}}function ZH(e){return function(t){return e(t)+""}}function f1(e,t){var n=dc.lastIndex=cl.lastIndex=0,r,s,a,i=-1,l=[],c=[];for(e=e+"",t=t+"";(r=dc.exec(e))&&(s=cl.exec(t));)(a=s.index)>n&&(a=t.slice(n,a),l[i]?l[i]+=a:l[++i]=a),(r=r[0])===(s=s[0])?l[i]?l[i]+=s:l[++i]=s:(l[++i]=null,c.push({i,x:Qt(r,s)})),n=cl.lastIndex;return n<t.length&&(a=t.slice(n),l[i]?l[i]+=a:l[++i]=a),l.length<2?c[0]?ZH(c[0].x):YH(t):(t=c.length,function(d){for(var u=0,p;u<t;++u)l[(p=c[u]).i]=p.x(d);return l.join("")})}function So(e,t){var n=typeof t,r;return t==null||n==="boolean"?au(t):(n==="number"?Qt:n==="string"?(r=ar(t))?(t=r,xa):f1:t instanceof ar?xa:t instanceof Date?KH:QH(t)?UH:Array.isArray(t)?GH:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?WH:Qt)(e,t)}var Qf=180/Math.PI,uc={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function h1(e,t,n,r,s,a){var i,l,c;return(i=Math.sqrt(e*e+t*t))&&(e/=i,t/=i),(c=e*n+t*r)&&(n-=e*c,r-=t*c),(l=Math.sqrt(n*n+r*r))&&(n/=l,r/=l,c/=l),e*r<t*n&&(e=-e,t=-t,c=-c,i=-i),{translateX:s,translateY:a,rotate:Math.atan2(t,e)*Qf,skewX:Math.atan(c)*Qf,scaleX:i,scaleY:l}}var Ds;function XH(e){const t=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(e+"");return t.isIdentity?uc:h1(t.a,t.b,t.c,t.d,t.e,t.f)}function JH(e){return e==null||(Ds||(Ds=document.createElementNS("http://www.w3.org/2000/svg","g")),Ds.setAttribute("transform",e),!(e=Ds.transform.baseVal.consolidate()))?uc:(e=e.matrix,h1(e.a,e.b,e.c,e.d,e.e,e.f))}function m1(e,t,n,r){function s(d){return d.length?d.pop()+" ":""}function a(d,u,p,h,m,g){if(d!==p||u!==h){var b=m.push("translate(",null,t,null,n);g.push({i:b-4,x:Qt(d,p)},{i:b-2,x:Qt(u,h)})}else(p||h)&&m.push("translate("+p+t+h+n)}function i(d,u,p,h){d!==u?(d-u>180?u+=360:u-d>180&&(d+=360),h.push({i:p.push(s(p)+"rotate(",null,r)-2,x:Qt(d,u)})):u&&p.push(s(p)+"rotate("+u+r)}function l(d,u,p,h){d!==u?h.push({i:p.push(s(p)+"skewX(",null,r)-2,x:Qt(d,u)}):u&&p.push(s(p)+"skewX("+u+r)}function c(d,u,p,h,m,g){if(d!==p||u!==h){var b=m.push(s(m)+"scale(",null,",",null,")");g.push({i:b-4,x:Qt(d,p)},{i:b-2,x:Qt(u,h)})}else(p!==1||h!==1)&&m.push(s(m)+"scale("+p+","+h+")")}return function(d,u){var p=[],h=[];return d=e(d),u=e(u),a(d.translateX,d.translateY,u.translateX,u.translateY,p,h),i(d.rotate,u.rotate,p,h),l(d.skewX,u.skewX,p,h),c(d.scaleX,d.scaleY,u.scaleX,u.scaleY,p,h),d=u=null,function(m){for(var g=-1,b=h.length,x;++g<b;)p[(x=h[g]).i]=x.x(m);return p.join("")}}}var eq=m1(XH,"px, ","px)","deg)"),tq=m1(JH,", ",")",")"),nq=1e-12;function Gf(e){return((e=Math.exp(e))+1/e)/2}function rq(e){return((e=Math.exp(e))-1/e)/2}function oq(e){return((e=Math.exp(2*e))-1)/(e+1)}const Gs=(function e(t,n,r){function s(a,i){var l=a[0],c=a[1],d=a[2],u=i[0],p=i[1],h=i[2],m=u-l,g=p-c,b=m*m+g*g,x,y;if(b<nq)y=Math.log(h/d)/t,x=function(E){return[l+E*m,c+E*g,d*Math.exp(t*E*y)]};else{var w=Math.sqrt(b),v=(h*h-d*d+r*b)/(2*d*n*w),N=(h*h-d*d-r*b)/(2*h*n*w),k=Math.log(Math.sqrt(v*v+1)-v),C=Math.log(Math.sqrt(N*N+1)-N);y=(C-k)/t,x=function(E){var I=E*y,A=Gf(k),z=d/(n*w)*(A*oq(t*I+k)-rq(k));return[l+z*m,c+z*g,d*A/Gf(t*I+k)]}}return x.duration=y*1e3*t/Math.SQRT2,x}return s.rho=function(a){var i=Math.max(.001,+a),l=i*i,c=l*l;return e(i,l,c)},s})(Math.SQRT2,2,4);var Rr=0,ho=0,co=0,g1=1e3,ya,mo,va=0,ir=0,ai=0,Oo=typeof performance=="object"&&performance.now?performance:Date,b1=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function iu(){return ir||(b1(sq),ir=Oo.now()+ai)}function sq(){ir=0}function wa(){this._call=this._time=this._next=null}wa.prototype=x1.prototype={constructor:wa,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?iu():+n)+(t==null?0:+t),!this._next&&mo!==this&&(mo?mo._next=this:ya=this,mo=this),this._call=e,this._time=n,pc()},stop:function(){this._call&&(this._call=null,this._time=1/0,pc())}};function x1(e,t,n){var r=new wa;return r.restart(e,t,n),r}function aq(){iu(),++Rr;for(var e=ya,t;e;)(t=ir-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Rr}function Kf(){ir=(va=Oo.now())+ai,Rr=ho=0;try{aq()}finally{Rr=0,lq(),ir=0}}function iq(){var e=Oo.now(),t=e-va;t>g1&&(ai-=t,va=e)}function lq(){for(var e,t=ya,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:ya=n);mo=e,pc(r)}function pc(e){if(!Rr){ho&&(ho=clearTimeout(ho));var t=e-ir;t>24?(e<1/0&&(ho=setTimeout(Kf,e-Oo.now()-ai)),co&&(co=clearInterval(co))):(co||(va=Oo.now(),co=setInterval(iq,g1)),Rr=1,b1(Kf))}}function Wf(e,t,n){var r=new wa;return t=t==null?0:+t,r.restart(s=>{r.stop(),e(s+t)},t,n),r}var cq=oi("start","end","cancel","interrupt"),dq=[],y1=0,Yf=1,fc=2,Ks=3,Zf=4,hc=5,Ws=6;function ii(e,t,n,r,s,a){var i=e.__transition;if(!i)e.__transition={};else if(n in i)return;uq(e,n,{name:t,index:r,group:s,on:cq,tween:dq,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:y1})}function lu(e,t){var n=Ht(e,t);if(n.state>y1)throw new Error("too late; already scheduled");return n}function rn(e,t){var n=Ht(e,t);if(n.state>Ks)throw new Error("too late; already running");return n}function Ht(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function uq(e,t,n){var r=e.__transition,s;r[t]=n,n.timer=x1(a,0,n.time);function a(d){n.state=Yf,n.timer.restart(i,n.delay,n.time),n.delay<=d&&i(d-n.delay)}function i(d){var u,p,h,m;if(n.state!==Yf)return c();for(u in r)if(m=r[u],m.name===n.name){if(m.state===Ks)return Wf(i);m.state===Zf?(m.state=Ws,m.timer.stop(),m.on.call("interrupt",e,e.__data__,m.index,m.group),delete r[u]):+u<t&&(m.state=Ws,m.timer.stop(),m.on.call("cancel",e,e.__data__,m.index,m.group),delete r[u])}if(Wf(function(){n.state===Ks&&(n.state=Zf,n.timer.restart(l,n.delay,n.time),l(d))}),n.state=fc,n.on.call("start",e,e.__data__,n.index,n.group),n.state===fc){for(n.state=Ks,s=new Array(h=n.tween.length),u=0,p=-1;u<h;++u)(m=n.tween[u].value.call(e,e.__data__,n.index,n.group))&&(s[++p]=m);s.length=p+1}}function l(d){for(var u=d<n.duration?n.ease.call(null,d/n.duration):(n.timer.restart(c),n.state=hc,1),p=-1,h=s.length;++p<h;)s[p].call(e,u);n.state===hc&&(n.on.call("end",e,e.__data__,n.index,n.group),c())}function c(){n.state=Ws,n.timer.stop(),delete r[t];for(var d in r)return;delete e.__transition}}function Ys(e,t){var n=e.__transition,r,s,a=!0,i;if(n){t=t==null?null:t+"";for(i in n){if((r=n[i]).name!==t){a=!1;continue}s=r.state>fc&&r.state<hc,r.state=Ws,r.timer.stop(),r.on.call(s?"interrupt":"cancel",e,e.__data__,r.index,r.group),delete n[i]}a&&delete e.__transition}}function pq(e){return this.each(function(){Ys(this,e)})}function fq(e,t){var n,r;return function(){var s=rn(this,e),a=s.tween;if(a!==n){r=n=a;for(var i=0,l=r.length;i<l;++i)if(r[i].name===t){r=r.slice(),r.splice(i,1);break}}s.tween=r}}function hq(e,t,n){var r,s;if(typeof n!="function")throw new Error;return function(){var a=rn(this,e),i=a.tween;if(i!==r){s=(r=i).slice();for(var l={name:t,value:n},c=0,d=s.length;c<d;++c)if(s[c].name===t){s[c]=l;break}c===d&&s.push(l)}a.tween=s}}function mq(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r=Ht(this.node(),n).tween,s=0,a=r.length,i;s<a;++s)if((i=r[s]).name===e)return i.value;return null}return this.each((t==null?fq:hq)(n,e,t))}function cu(e,t,n){var r=e._id;return e.each(function(){var s=rn(this,r);(s.value||(s.value={}))[t]=n.apply(this,arguments)}),function(s){return Ht(s,r).value[t]}}function v1(e,t){var n;return(typeof t=="number"?Qt:t instanceof ar?xa:(n=ar(t))?(t=n,xa):f1)(e,t)}function gq(e){return function(){this.removeAttribute(e)}}function bq(e){return function(){this.removeAttributeNS(e.space,e.local)}}function xq(e,t,n){var r,s=n+"",a;return function(){var i=this.getAttribute(e);return i===s?null:i===r?a:a=t(r=i,n)}}function yq(e,t,n){var r,s=n+"",a;return function(){var i=this.getAttributeNS(e.space,e.local);return i===s?null:i===r?a:a=t(r=i,n)}}function vq(e,t,n){var r,s,a;return function(){var i,l=n(this),c;return l==null?void this.removeAttribute(e):(i=this.getAttribute(e),c=l+"",i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l)))}}function wq(e,t,n){var r,s,a;return function(){var i,l=n(this),c;return l==null?void this.removeAttributeNS(e.space,e.local):(i=this.getAttributeNS(e.space,e.local),c=l+"",i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l)))}}function Nq(e,t){var n=si(e),r=n==="transform"?tq:v1;return this.attrTween(e,typeof t=="function"?(n.local?wq:vq)(n,r,cu(this,"attr."+e,t)):t==null?(n.local?bq:gq)(n):(n.local?yq:xq)(n,r,t))}function kq(e,t){return function(n){this.setAttribute(e,t.call(this,n))}}function Sq(e,t){return function(n){this.setAttributeNS(e.space,e.local,t.call(this,n))}}function Cq(e,t){var n,r;function s(){var a=t.apply(this,arguments);return a!==r&&(n=(r=a)&&Sq(e,a)),n}return s._value=t,s}function Mq(e,t){var n,r;function s(){var a=t.apply(this,arguments);return a!==r&&(n=(r=a)&&kq(e,a)),n}return s._value=t,s}function Eq(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(t==null)return this.tween(n,null);if(typeof t!="function")throw new Error;var r=si(e);return this.tween(n,(r.local?Cq:Mq)(r,t))}function Iq(e,t){return function(){lu(this,e).delay=+t.apply(this,arguments)}}function Aq(e,t){return t=+t,function(){lu(this,e).delay=t}}function Pq(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?Iq:Aq)(t,e)):Ht(this.node(),t).delay}function _q(e,t){return function(){rn(this,e).duration=+t.apply(this,arguments)}}function $q(e,t){return t=+t,function(){rn(this,e).duration=t}}function Dq(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?_q:$q)(t,e)):Ht(this.node(),t).duration}function Tq(e,t){if(typeof t!="function")throw new Error;return function(){rn(this,e).ease=t}}function Lq(e){var t=this._id;return arguments.length?this.each(Tq(t,e)):Ht(this.node(),t).ease}function Rq(e,t){return function(){var n=t.apply(this,arguments);if(typeof n!="function")throw new Error;rn(this,e).ease=n}}function Oq(e){if(typeof e!="function")throw new Error;return this.each(Rq(this._id,e))}function Bq(e){typeof e!="function"&&(e=Zv(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=[],c,d=0;d<i;++d)(c=a[d])&&e.call(c,c.__data__,d,a)&&l.push(c);return new bn(r,this._parents,this._name,this._id)}function zq(e){if(e._id!==this._id)throw new Error;for(var t=this._groups,n=e._groups,r=t.length,s=n.length,a=Math.min(r,s),i=new Array(r),l=0;l<a;++l)for(var c=t[l],d=n[l],u=c.length,p=i[l]=new Array(u),h,m=0;m<u;++m)(h=c[m]||d[m])&&(p[m]=h);for(;l<r;++l)i[l]=t[l];return new bn(i,this._parents,this._name,this._id)}function Fq(e){return(e+"").trim().split(/^|\s+/).every(function(t){var n=t.indexOf(".");return n>=0&&(t=t.slice(0,n)),!t||t==="start"})}function jq(e,t,n){var r,s,a=Fq(t)?lu:rn;return function(){var i=a(this,e),l=i.on;l!==r&&(s=(r=l).copy()).on(t,n),i.on=s}}function Vq(e,t){var n=this._id;return arguments.length<2?Ht(this.node(),n).on.on(e):this.each(jq(n,e,t))}function Hq(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function qq(){return this.on("end.remove",Hq(this._id))}function Uq(e){var t=this._name,n=this._id;typeof e!="function"&&(e=ru(e));for(var r=this._groups,s=r.length,a=new Array(s),i=0;i<s;++i)for(var l=r[i],c=l.length,d=a[i]=new Array(c),u,p,h=0;h<c;++h)(u=l[h])&&(p=e.call(u,u.__data__,h,l))&&("__data__"in u&&(p.__data__=u.__data__),d[h]=p,ii(d[h],t,n,h,d,Ht(u,n)));return new bn(a,this._parents,t,n)}function Qq(e){var t=this._name,n=this._id;typeof e!="function"&&(e=Yv(e));for(var r=this._groups,s=r.length,a=[],i=[],l=0;l<s;++l)for(var c=r[l],d=c.length,u,p=0;p<d;++p)if(u=c[p]){for(var h=e.call(u,u.__data__,p,c),m,g=Ht(u,n),b=0,x=h.length;b<x;++b)(m=h[b])&&ii(m,t,n,b,h,g);a.push(h),i.push(u)}return new bn(a,i,t,n)}var Gq=rs.prototype.constructor;function Kq(){return new Gq(this._groups,this._parents)}function Wq(e,t){var n,r,s;return function(){var a=Lr(this,e),i=(this.style.removeProperty(e),Lr(this,e));return a===i?null:a===n&&i===r?s:s=t(n=a,r=i)}}function w1(e){return function(){this.style.removeProperty(e)}}function Yq(e,t,n){var r,s=n+"",a;return function(){var i=Lr(this,e);return i===s?null:i===r?a:a=t(r=i,n)}}function Zq(e,t,n){var r,s,a;return function(){var i=Lr(this,e),l=n(this),c=l+"";return l==null&&(c=l=(this.style.removeProperty(e),Lr(this,e))),i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l))}}function Xq(e,t){var n,r,s,a="style."+t,i="end."+a,l;return function(){var c=rn(this,e),d=c.on,u=c.value[a]==null?l||(l=w1(t)):void 0;(d!==n||s!==u)&&(r=(n=d).copy()).on(i,s=u),c.on=r}}function Jq(e,t,n){var r=(e+="")=="transform"?eq:v1;return t==null?this.styleTween(e,Wq(e,r)).on("end.style."+e,w1(e)):typeof t=="function"?this.styleTween(e,Zq(e,r,cu(this,"style."+e,t))).each(Xq(this._id,e)):this.styleTween(e,Yq(e,r,t),n).on("end.style."+e,null)}function eU(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}function tU(e,t,n){var r,s;function a(){var i=t.apply(this,arguments);return i!==s&&(r=(s=i)&&eU(e,i,n)),r}return a._value=t,a}function nU(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(t==null)return this.tween(r,null);if(typeof t!="function")throw new Error;return this.tween(r,tU(e,t,n??""))}function rU(e){return function(){this.textContent=e}}function oU(e){return function(){var t=e(this);this.textContent=t??""}}function sU(e){return this.tween("text",typeof e=="function"?oU(cu(this,"text",e)):rU(e==null?"":e+""))}function aU(e){return function(t){this.textContent=e.call(this,t)}}function iU(e){var t,n;function r(){var s=e.apply(this,arguments);return s!==n&&(t=(n=s)&&aU(s)),t}return r._value=e,r}function lU(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(e==null)return this.tween(t,null);if(typeof e!="function")throw new Error;return this.tween(t,iU(e))}function cU(){for(var e=this._name,t=this._id,n=N1(),r=this._groups,s=r.length,a=0;a<s;++a)for(var i=r[a],l=i.length,c,d=0;d<l;++d)if(c=i[d]){var u=Ht(c,t);ii(c,e,n,d,i,{time:u.time+u.delay+u.duration,delay:0,duration:u.duration,ease:u.ease})}return new bn(r,this._parents,e,n)}function dU(){var e,t,n=this,r=n._id,s=n.size();return new Promise(function(a,i){var l={value:i},c={value:function(){--s===0&&a()}};n.each(function(){var d=rn(this,r),u=d.on;u!==e&&(t=(e=u).copy(),t._.cancel.push(l),t._.interrupt.push(l),t._.end.push(c)),d.on=t}),s===0&&a()})}var uU=0;function bn(e,t,n,r){this._groups=e,this._parents=t,this._name=n,this._id=r}function N1(){return++uU}var an=rs.prototype;bn.prototype={constructor:bn,select:Uq,selectAll:Qq,selectChild:an.selectChild,selectChildren:an.selectChildren,filter:Bq,merge:zq,selection:Kq,transition:cU,call:an.call,nodes:an.nodes,node:an.node,size:an.size,empty:an.empty,each:an.each,on:Vq,attr:Nq,attrTween:Eq,style:Jq,styleTween:nU,text:sU,textTween:lU,remove:qq,tween:mq,delay:Pq,duration:Dq,ease:Lq,easeVarying:Oq,end:dU,[Symbol.iterator]:an[Symbol.iterator]};function pU(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}var fU={time:null,delay:0,duration:250,ease:pU};function hU(e,t){for(var n;!(n=e.__transition)||!(n=n[t]);)if(!(e=e.parentNode))throw new Error(`transition ${t} not found`);return n}function mU(e){var t,n;e instanceof bn?(t=e._id,e=e._name):(t=N1(),(n=fU).time=iu(),e=e==null?null:e+"");for(var r=this._groups,s=r.length,a=0;a<s;++a)for(var i=r[a],l=i.length,c,d=0;d<l;++d)(c=i[d])&&ii(c,e,t,d,i,n||hU(c,t));return new bn(r,this._parents,e,t)}rs.prototype.interrupt=pq;rs.prototype.transition=mU;const Ts=e=>()=>e;function gU(e,{sourceEvent:t,target:n,transform:r,dispatch:s}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:s}})}function dn(e,t,n){this.k=e,this.x=t,this.y=n}dn.prototype={constructor:dn,scale:function(e){return e===1?this:new dn(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new dn(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var li=new dn(1,0,0);k1.prototype=dn.prototype;function k1(e){for(;!e.__zoom;)if(!(e=e.parentNode))return li;return e.__zoom}function dl(e){e.stopImmediatePropagation()}function uo(e){e.preventDefault(),e.stopImmediatePropagation()}function bU(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function xU(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Xf(){return this.__zoom||li}function yU(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function vU(){return navigator.maxTouchPoints||"ontouchstart"in this}function wU(e,t,n){var r=e.invertX(t[0][0])-n[0][0],s=e.invertX(t[1][0])-n[1][0],a=e.invertY(t[0][1])-n[0][1],i=e.invertY(t[1][1])-n[1][1];return e.translate(s>r?(r+s)/2:Math.min(0,r)||Math.max(0,s),i>a?(a+i)/2:Math.min(0,a)||Math.max(0,i))}function S1(){var e=bU,t=xU,n=wU,r=yU,s=vU,a=[0,1/0],i=[[-1/0,-1/0],[1/0,1/0]],l=250,c=Gs,d=oi("start","zoom","end"),u,p,h,m=500,g=150,b=0,x=10;function y(M){M.property("__zoom",Xf).on("wheel.zoom",I,{passive:!1}).on("mousedown.zoom",A).on("dblclick.zoom",z).filter(s).on("touchstart.zoom",P).on("touchmove.zoom",B).on("touchend.zoom touchcancel.zoom",R).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}y.transform=function(M,D,T,L){var O=M.selection?M.selection():M;O.property("__zoom",Xf),M!==O?k(M,D,T,L):O.interrupt().each(function(){C(this,arguments).event(L).start().zoom(null,typeof D=="function"?D.apply(this,arguments):D).end()})},y.scaleBy=function(M,D,T,L){y.scaleTo(M,function(){var O=this.__zoom.k,F=typeof D=="function"?D.apply(this,arguments):D;return O*F},T,L)},y.scaleTo=function(M,D,T,L){y.transform(M,function(){var O=t.apply(this,arguments),F=this.__zoom,j=T==null?N(O):typeof T=="function"?T.apply(this,arguments):T,V=F.invert(j),$=typeof D=="function"?D.apply(this,arguments):D;return n(v(w(F,$),j,V),O,i)},T,L)},y.translateBy=function(M,D,T,L){y.transform(M,function(){return n(this.__zoom.translate(typeof D=="function"?D.apply(this,arguments):D,typeof T=="function"?T.apply(this,arguments):T),t.apply(this,arguments),i)},null,L)},y.translateTo=function(M,D,T,L,O){y.transform(M,function(){var F=t.apply(this,arguments),j=this.__zoom,V=L==null?N(F):typeof L=="function"?L.apply(this,arguments):L;return n(li.translate(V[0],V[1]).scale(j.k).translate(typeof D=="function"?-D.apply(this,arguments):-D,typeof T=="function"?-T.apply(this,arguments):-T),F,i)},L,O)};function w(M,D){return D=Math.max(a[0],Math.min(a[1],D)),D===M.k?M:new dn(D,M.x,M.y)}function v(M,D,T){var L=D[0]-T[0]*M.k,O=D[1]-T[1]*M.k;return L===M.x&&O===M.y?M:new dn(M.k,L,O)}function N(M){return[(+M[0][0]+ +M[1][0])/2,(+M[0][1]+ +M[1][1])/2]}function k(M,D,T,L){M.on("start.zoom",function(){C(this,arguments).event(L).start()}).on("interrupt.zoom end.zoom",function(){C(this,arguments).event(L).end()}).tween("zoom",function(){var O=this,F=arguments,j=C(O,F).event(L),V=t.apply(O,F),$=T==null?N(V):typeof T=="function"?T.apply(O,F):T,q=Math.max(V[1][0]-V[0][0],V[1][1]-V[0][1]),G=O.__zoom,Z=typeof D=="function"?D.apply(O,F):D,oe=c(G.invert($).concat(q/G.k),Z.invert($).concat(q/Z.k));return function(ne){if(ne===1)ne=Z;else{var X=oe(ne),re=q/X[2];ne=new dn(re,$[0]-X[0]*re,$[1]-X[1]*re)}j.zoom(null,ne)}})}function C(M,D,T){return!T&&M.__zooming||new E(M,D)}function E(M,D){this.that=M,this.args=D,this.active=0,this.sourceEvent=null,this.extent=t.apply(M,D),this.taps=0}E.prototype={event:function(M){return M&&(this.sourceEvent=M),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(M,D){return this.mouse&&M!=="mouse"&&(this.mouse[1]=D.invert(this.mouse[0])),this.touch0&&M!=="touch"&&(this.touch0[1]=D.invert(this.touch0[0])),this.touch1&&M!=="touch"&&(this.touch1[1]=D.invert(this.touch1[0])),this.that.__zoom=D,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(M){var D=ht(this.that).datum();d.call(M,this.that,new gU(M,{sourceEvent:this.sourceEvent,target:y,transform:this.that.__zoom,dispatch:d}),D)}};function I(M,...D){if(!e.apply(this,arguments))return;var T=C(this,D).event(M),L=this.__zoom,O=Math.max(a[0],Math.min(a[1],L.k*Math.pow(2,r.apply(this,arguments)))),F=Lt(M);if(T.wheel)(T.mouse[0][0]!==F[0]||T.mouse[0][1]!==F[1])&&(T.mouse[1]=L.invert(T.mouse[0]=F)),clearTimeout(T.wheel);else{if(L.k===O)return;T.mouse=[F,L.invert(F)],Ys(this),T.start()}uo(M),T.wheel=setTimeout(j,g),T.zoom("mouse",n(v(w(L,O),T.mouse[0],T.mouse[1]),T.extent,i));function j(){T.wheel=null,T.end()}}function A(M,...D){if(h||!e.apply(this,arguments))return;var T=M.currentTarget,L=C(this,D,!0).event(M),O=ht(M.view).on("mousemove.zoom",$,!0).on("mouseup.zoom",q,!0),F=Lt(M,T),j=M.clientX,V=M.clientY;i1(M.view),dl(M),L.mouse=[F,this.__zoom.invert(F)],Ys(this),L.start();function $(G){if(uo(G),!L.moved){var Z=G.clientX-j,oe=G.clientY-V;L.moved=Z*Z+oe*oe>b}L.event(G).zoom("mouse",n(v(L.that.__zoom,L.mouse[0]=Lt(G,T),L.mouse[1]),L.extent,i))}function q(G){O.on("mousemove.zoom mouseup.zoom",null),l1(G.view,L.moved),uo(G),L.event(G).end()}}function z(M,...D){if(e.apply(this,arguments)){var T=this.__zoom,L=Lt(M.changedTouches?M.changedTouches[0]:M,this),O=T.invert(L),F=T.k*(M.shiftKey?.5:2),j=n(v(w(T,F),L,O),t.apply(this,D),i);uo(M),l>0?ht(this).transition().duration(l).call(k,j,L,M):ht(this).call(y.transform,j,L,M)}}function P(M,...D){if(e.apply(this,arguments)){var T=M.touches,L=T.length,O=C(this,D,M.changedTouches.length===L).event(M),F,j,V,$;for(dl(M),j=0;j<L;++j)V=T[j],$=Lt(V,this),$=[$,this.__zoom.invert($),V.identifier],O.touch0?!O.touch1&&O.touch0[2]!==$[2]&&(O.touch1=$,O.taps=0):(O.touch0=$,F=!0,O.taps=1+!!u);u&&(u=clearTimeout(u)),F&&(O.taps<2&&(p=$[0],u=setTimeout(function(){u=null},m)),Ys(this),O.start())}}function B(M,...D){if(this.__zooming){var T=C(this,D).event(M),L=M.changedTouches,O=L.length,F,j,V,$;for(uo(M),F=0;F<O;++F)j=L[F],V=Lt(j,this),T.touch0&&T.touch0[2]===j.identifier?T.touch0[0]=V:T.touch1&&T.touch1[2]===j.identifier&&(T.touch1[0]=V);if(j=T.that.__zoom,T.touch1){var q=T.touch0[0],G=T.touch0[1],Z=T.touch1[0],oe=T.touch1[1],ne=(ne=Z[0]-q[0])*ne+(ne=Z[1]-q[1])*ne,X=(X=oe[0]-G[0])*X+(X=oe[1]-G[1])*X;j=w(j,Math.sqrt(ne/X)),V=[(q[0]+Z[0])/2,(q[1]+Z[1])/2],$=[(G[0]+oe[0])/2,(G[1]+oe[1])/2]}else if(T.touch0)V=T.touch0[0],$=T.touch0[1];else return;T.zoom("touch",n(v(j,V,$),T.extent,i))}}function R(M,...D){if(this.__zooming){var T=C(this,D).event(M),L=M.changedTouches,O=L.length,F,j;for(dl(M),h&&clearTimeout(h),h=setTimeout(function(){h=null},m),F=0;F<O;++F)j=L[F],T.touch0&&T.touch0[2]===j.identifier?delete T.touch0:T.touch1&&T.touch1[2]===j.identifier&&delete T.touch1;if(T.touch1&&!T.touch0&&(T.touch0=T.touch1,delete T.touch1),T.touch0)T.touch0[1]=this.__zoom.invert(T.touch0[0]);else if(T.end(),T.taps===2&&(j=Lt(j,this),Math.hypot(p[0]-j[0],p[1]-j[1])<x)){var V=ht(this).on("dblclick.zoom");V&&V.apply(this,arguments)}}}return y.wheelDelta=function(M){return arguments.length?(r=typeof M=="function"?M:Ts(+M),y):r},y.filter=function(M){return arguments.length?(e=typeof M=="function"?M:Ts(!!M),y):e},y.touchable=function(M){return arguments.length?(s=typeof M=="function"?M:Ts(!!M),y):s},y.extent=function(M){return arguments.length?(t=typeof M=="function"?M:Ts([[+M[0][0],+M[0][1]],[+M[1][0],+M[1][1]]]),y):t},y.scaleExtent=function(M){return arguments.length?(a[0]=+M[0],a[1]=+M[1],y):[a[0],a[1]]},y.translateExtent=function(M){return arguments.length?(i[0][0]=+M[0][0],i[1][0]=+M[1][0],i[0][1]=+M[0][1],i[1][1]=+M[1][1],y):[[i[0][0],i[0][1]],[i[1][0],i[1][1]]]},y.constrain=function(M){return arguments.length?(n=M,y):n},y.duration=function(M){return arguments.length?(l=+M,y):l},y.interpolate=function(M){return arguments.length?(c=M,y):c},y.on=function(){var M=d.on.apply(d,arguments);return M===d?y:M},y.clickDistance=function(M){return arguments.length?(b=(M=+M)*M,y):Math.sqrt(b)},y.tapDistance=function(M){return arguments.length?(x=+M,y):x},y}const en={error001:()=>"[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001",error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>"The React Flow parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,{id:t,sourceHandle:n,targetHandle:r})=>`Couldn't create edge for ${e} handle id: "${e==="source"?n:r}", edge id: ${t}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(e="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${e}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs."},Bo=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],C1=["Enter"," ","Escape"],M1={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:e,x:t,y:n})=>`Moved selected node ${e}. New position, x: ${t}, y: ${n}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var Or;(function(e){e.Strict="strict",e.Loose="loose"})(Or||(Or={}));var Xn;(function(e){e.Free="free",e.Vertical="vertical",e.Horizontal="horizontal"})(Xn||(Xn={}));var zo;(function(e){e.Partial="partial",e.Full="full"})(zo||(zo={}));const E1={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var En;(function(e){e.Bezier="default",e.Straight="straight",e.Step="step",e.SmoothStep="smoothstep",e.SimpleBezier="simplebezier"})(En||(En={}));var Na;(function(e){e.Arrow="arrow",e.ArrowClosed="arrowclosed"})(Na||(Na={}));var we;(function(e){e.Left="left",e.Top="top",e.Right="right",e.Bottom="bottom"})(we||(we={}));const Jf={[we.Left]:we.Right,[we.Right]:we.Left,[we.Top]:we.Bottom,[we.Bottom]:we.Top};function I1(e){return e===null?null:e?"valid":"invalid"}const A1=e=>"id"in e&&"source"in e&&"target"in e,NU=e=>"id"in e&&"position"in e&&!("source"in e)&&!("target"in e),du=e=>"id"in e&&"internals"in e&&!("source"in e)&&!("target"in e),ss=(e,t=[0,0])=>{const{width:n,height:r}=Nn(e),s=e.origin??t,a=n*s[0],i=r*s[1];return{x:e.position.x-a,y:e.position.y-i}},kU=(e,t={nodeOrigin:[0,0]})=>{if(e.length===0)return{x:0,y:0,width:0,height:0};const n=e.reduce((r,s)=>{const a=typeof s=="string";let i=!t.nodeLookup&&!a?s:void 0;t.nodeLookup&&(i=a?t.nodeLookup.get(s):du(s)?s:t.nodeLookup.get(s.id));const l=i?ka(i,t.nodeOrigin):{x:0,y:0,x2:0,y2:0};return ci(r,l)},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return di(n)},as=(e,t={})=>{let n={x:1/0,y:1/0,x2:-1/0,y2:-1/0},r=!1;return e.forEach(s=>{(t.filter===void 0||t.filter(s))&&(n=ci(n,ka(s)),r=!0)}),r?di(n):{x:0,y:0,width:0,height:0}},uu=(e,t,[n,r,s]=[0,0,1],a=!1,i=!1)=>{const l={...ls(t,[n,r,s]),width:t.width/s,height:t.height/s},c=[];for(const d of e.values()){const{measured:u,selectable:p=!0,hidden:h=!1}=d;if(i&&!p||h)continue;const m=u.width??d.width??d.initialWidth??null,g=u.height??d.height??d.initialHeight??null,b=Fo(l,zr(d)),x=(m??0)*(g??0),y=a&&b>0;(!d.internals.handleBounds||y||b>=x||d.dragging)&&c.push(d)}return c},SU=(e,t)=>{const n=new Set;return e.forEach(r=>{n.add(r.id)}),t.filter(r=>n.has(r.source)||n.has(r.target))};function CU(e,t){const n=new Map,r=t?.nodes?new Set(t.nodes.map(s=>s.id)):null;return e.forEach(s=>{s.measured.width&&s.measured.height&&(t?.includeHiddenNodes||!s.hidden)&&(!r||r.has(s.id))&&n.set(s.id,s)}),n}async function MU({nodes:e,width:t,height:n,panZoom:r,minZoom:s,maxZoom:a},i){if(e.size===0)return Promise.resolve(!0);const l=CU(e,i),c=as(l),d=pu(c,t,n,i?.minZoom??s,i?.maxZoom??a,i?.padding??.1);return await r.setViewport(d,{duration:i?.duration,ease:i?.ease,interpolate:i?.interpolate}),Promise.resolve(!0)}function P1({nodeId:e,nextPosition:t,nodeLookup:n,nodeOrigin:r=[0,0],nodeExtent:s,onError:a}){const i=n.get(e),l=i.parentId?n.get(i.parentId):void 0,{x:c,y:d}=l?l.internals.positionAbsolute:{x:0,y:0},u=i.origin??r;let p=i.extent||s;if(i.extent==="parent"&&!i.expandParent)if(!l)a?.("005",en.error005());else{const m=l.measured.width,g=l.measured.height;m&&g&&(p=[[c,d],[c+m,d+g]])}else l&&Fr(i.extent)&&(p=[[i.extent[0][0]+c,i.extent[0][1]+d],[i.extent[1][0]+c,i.extent[1][1]+d]]);const h=Fr(p)?lr(t,p,i.measured):t;return(i.measured.width===void 0||i.measured.height===void 0)&&a?.("015",en.error015()),{position:{x:h.x-c+(i.measured.width??0)*u[0],y:h.y-d+(i.measured.height??0)*u[1]},positionAbsolute:h}}async function EU({nodesToRemove:e=[],edgesToRemove:t=[],nodes:n,edges:r,onBeforeDelete:s}){const a=new Set(e.map(h=>h.id)),i=[];for(const h of n){if(h.deletable===!1)continue;const m=a.has(h.id),g=!m&&h.parentId&&i.find(b=>b.id===h.parentId);(m||g)&&i.push(h)}const l=new Set(t.map(h=>h.id)),c=r.filter(h=>h.deletable!==!1),u=SU(i,c);for(const h of c)l.has(h.id)&&!u.find(g=>g.id===h.id)&&u.push(h);if(!s)return{edges:u,nodes:i};const p=await s({nodes:i,edges:u});return typeof p=="boolean"?p?{edges:u,nodes:i}:{edges:[],nodes:[]}:p}const Br=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),lr=(e={x:0,y:0},t,n)=>({x:Br(e.x,t[0][0],t[1][0]-(n?.width??0)),y:Br(e.y,t[0][1],t[1][1]-(n?.height??0))});function _1(e,t,n){const{width:r,height:s}=Nn(n),{x:a,y:i}=n.internals.positionAbsolute;return lr(e,[[a,i],[a+r,i+s]],t)}const eh=(e,t,n)=>e<t?Br(Math.abs(e-t),1,t)/t:e>n?-Br(Math.abs(e-n),1,t)/t:0,$1=(e,t,n=15,r=40)=>{const s=eh(e.x,r,t.width-r)*n,a=eh(e.y,r,t.height-r)*n;return[s,a]},ci=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),mc=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),di=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),zr=(e,t=[0,0])=>{const{x:n,y:r}=du(e)?e.internals.positionAbsolute:ss(e,t);return{x:n,y:r,width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}},ka=(e,t=[0,0])=>{const{x:n,y:r}=du(e)?e.internals.positionAbsolute:ss(e,t);return{x:n,y:r,x2:n+(e.measured?.width??e.width??e.initialWidth??0),y2:r+(e.measured?.height??e.height??e.initialHeight??0)}},D1=(e,t)=>di(ci(mc(e),mc(t))),Fo=(e,t)=>{const n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},th=e=>Ot(e.width)&&Ot(e.height)&&Ot(e.x)&&Ot(e.y),Ot=e=>!isNaN(e)&&isFinite(e),IU=(e,t)=>{},is=(e,t=[1,1])=>({x:t[0]*Math.round(e.x/t[0]),y:t[1]*Math.round(e.y/t[1])}),ls=({x:e,y:t},[n,r,s],a=!1,i=[1,1])=>{const l={x:(e-n)/s,y:(t-r)/s};return a?is(l,i):l},Sa=({x:e,y:t},[n,r,s])=>({x:e*s+n,y:t*s+r});function vr(e,t){if(typeof e=="number")return Math.floor((t-t/(1+e))*.5);if(typeof e=="string"&&e.endsWith("px")){const n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(n)}if(typeof e=="string"&&e.endsWith("%")){const n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(t*n*.01)}return console.error(`[React Flow] The padding value "${e}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function AU(e,t,n){if(typeof e=="string"||typeof e=="number"){const r=vr(e,n),s=vr(e,t);return{top:r,right:s,bottom:r,left:s,x:s*2,y:r*2}}if(typeof e=="object"){const r=vr(e.top??e.y??0,n),s=vr(e.bottom??e.y??0,n),a=vr(e.left??e.x??0,t),i=vr(e.right??e.x??0,t);return{top:r,right:i,bottom:s,left:a,x:a+i,y:r+s}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function PU(e,t,n,r,s,a){const{x:i,y:l}=Sa(e,[t,n,r]),{x:c,y:d}=Sa({x:e.x+e.width,y:e.y+e.height},[t,n,r]),u=s-c,p=a-d;return{left:Math.floor(i),top:Math.floor(l),right:Math.floor(u),bottom:Math.floor(p)}}const pu=(e,t,n,r,s,a)=>{const i=AU(a,t,n),l=(t-i.x)/e.width,c=(n-i.y)/e.height,d=Math.min(l,c),u=Br(d,r,s),p=e.x+e.width/2,h=e.y+e.height/2,m=t/2-p*u,g=n/2-h*u,b=PU(e,m,g,u,t,n),x={left:Math.min(b.left-i.left,0),top:Math.min(b.top-i.top,0),right:Math.min(b.right-i.right,0),bottom:Math.min(b.bottom-i.bottom,0)};return{x:m-x.left+x.right,y:g-x.top+x.bottom,zoom:u}},jo=()=>typeof navigator<"u"&&navigator?.userAgent?.indexOf("Mac")>=0;function Fr(e){return e!=null&&e!=="parent"}function Nn(e){return{width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}}function T1(e){return(e.measured?.width??e.width??e.initialWidth)!==void 0&&(e.measured?.height??e.height??e.initialHeight)!==void 0}function L1(e,t={width:0,height:0},n,r,s){const a={...e},i=r.get(n);if(i){const l=i.origin||s;a.x+=i.internals.positionAbsolute.x-(t.width??0)*l[0],a.y+=i.internals.positionAbsolute.y-(t.height??0)*l[1]}return a}function nh(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}function _U(){let e,t;return{promise:new Promise((r,s)=>{e=r,t=s}),resolve:e,reject:t}}function $U(e){return{...M1,...e||{}}}function Co(e,{snapGrid:t=[0,0],snapToGrid:n=!1,transform:r,containerBounds:s}){const{x:a,y:i}=Bt(e),l=ls({x:a-(s?.left??0),y:i-(s?.top??0)},r),{x:c,y:d}=n?is(l,t):l;return{xSnapped:c,ySnapped:d,...l}}const fu=e=>({width:e.offsetWidth,height:e.offsetHeight}),R1=e=>e?.getRootNode?.()||window?.document,DU=["INPUT","SELECT","TEXTAREA"];function O1(e){const t=e.composedPath?.()?.[0]||e.target;return t?.nodeType!==1?!1:DU.includes(t.nodeName)||t.hasAttribute("contenteditable")||!!t.closest(".nokey")}const B1=e=>"clientX"in e,Bt=(e,t)=>{const n=B1(e),r=n?e.clientX:e.touches?.[0].clientX,s=n?e.clientY:e.touches?.[0].clientY;return{x:r-(t?.left??0),y:s-(t?.top??0)}},rh=(e,t,n,r,s)=>{const a=t.querySelectorAll(`.${e}`);return!a||!a.length?null:Array.from(a).map(i=>{const l=i.getBoundingClientRect();return{id:i.getAttribute("data-handleid"),type:e,nodeId:s,position:i.getAttribute("data-handlepos"),x:(l.left-n.left)/r,y:(l.top-n.top)/r,...fu(i)}})};function z1({sourceX:e,sourceY:t,targetX:n,targetY:r,sourceControlX:s,sourceControlY:a,targetControlX:i,targetControlY:l}){const c=e*.125+s*.375+i*.375+n*.125,d=t*.125+a*.375+l*.375+r*.125,u=Math.abs(c-e),p=Math.abs(d-t);return[c,d,u,p]}function Ls(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function oh({pos:e,x1:t,y1:n,x2:r,y2:s,c:a}){switch(e){case we.Left:return[t-Ls(t-r,a),n];case we.Right:return[t+Ls(r-t,a),n];case we.Top:return[t,n-Ls(n-s,a)];case we.Bottom:return[t,n+Ls(s-n,a)]}}function F1({sourceX:e,sourceY:t,sourcePosition:n=we.Bottom,targetX:r,targetY:s,targetPosition:a=we.Top,curvature:i=.25}){const[l,c]=oh({pos:n,x1:e,y1:t,x2:r,y2:s,c:i}),[d,u]=oh({pos:a,x1:r,y1:s,x2:e,y2:t,c:i}),[p,h,m,g]=z1({sourceX:e,sourceY:t,targetX:r,targetY:s,sourceControlX:l,sourceControlY:c,targetControlX:d,targetControlY:u});return[`M${e},${t} C${l},${c} ${d},${u} ${r},${s}`,p,h,m,g]}function j1({sourceX:e,sourceY:t,targetX:n,targetY:r}){const s=Math.abs(n-e)/2,a=n<e?n+s:n-s,i=Math.abs(r-t)/2,l=r<t?r+i:r-i;return[a,l,s,i]}function TU({sourceNode:e,targetNode:t,selected:n=!1,zIndex:r=0,elevateOnSelect:s=!1,zIndexMode:a="basic"}){if(a==="manual")return r;const i=s&&n?r+1e3:r,l=Math.max(e.parentId||s&&e.selected?e.internals.z:0,t.parentId||s&&t.selected?t.internals.z:0);return i+l}function LU({sourceNode:e,targetNode:t,width:n,height:r,transform:s}){const a=ci(ka(e),ka(t));a.x===a.x2&&(a.x2+=1),a.y===a.y2&&(a.y2+=1);const i={x:-s[0]/s[2],y:-s[1]/s[2],width:n/s[2],height:r/s[2]};return Fo(i,di(a))>0}const RU=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`xy-edge__${e}${t||""}-${n}${r||""}`,OU=(e,t)=>t.some(n=>n.source===e.source&&n.target===e.target&&(n.sourceHandle===e.sourceHandle||!n.sourceHandle&&!e.sourceHandle)&&(n.targetHandle===e.targetHandle||!n.targetHandle&&!e.targetHandle)),BU=(e,t,n={})=>{if(!e.source||!e.target)return t;const r=n.getEdgeId||RU;let s;return A1(e)?s={...e}:s={...e,id:r(e)},OU(s,t)?t:(s.sourceHandle===null&&delete s.sourceHandle,s.targetHandle===null&&delete s.targetHandle,t.concat(s))};function V1({sourceX:e,sourceY:t,targetX:n,targetY:r}){const[s,a,i,l]=j1({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,s,a,i,l]}const sh={[we.Left]:{x:-1,y:0},[we.Right]:{x:1,y:0},[we.Top]:{x:0,y:-1},[we.Bottom]:{x:0,y:1}},zU=({source:e,sourcePosition:t=we.Bottom,target:n})=>t===we.Left||t===we.Right?e.x<n.x?{x:1,y:0}:{x:-1,y:0}:e.y<n.y?{x:0,y:1}:{x:0,y:-1},ah=(e,t)=>Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));function FU({source:e,sourcePosition:t=we.Bottom,target:n,targetPosition:r=we.Top,center:s,offset:a,stepPosition:i}){const l=sh[t],c=sh[r],d={x:e.x+l.x*a,y:e.y+l.y*a},u={x:n.x+c.x*a,y:n.y+c.y*a},p=zU({source:d,sourcePosition:t,target:u}),h=p.x!==0?"x":"y",m=p[h];let g=[],b,x;const y={x:0,y:0},w={x:0,y:0},[,,v,N]=j1({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(l[h]*c[h]===-1){h==="x"?(b=s.x??d.x+(u.x-d.x)*i,x=s.y??(d.y+u.y)/2):(b=s.x??(d.x+u.x)/2,x=s.y??d.y+(u.y-d.y)*i);const I=[{x:b,y:d.y},{x:b,y:u.y}],A=[{x:d.x,y:x},{x:u.x,y:x}];l[h]===m?g=h==="x"?I:A:g=h==="x"?A:I}else{const I=[{x:d.x,y:u.y}],A=[{x:u.x,y:d.y}];if(h==="x"?g=l.x===m?A:I:g=l.y===m?I:A,t===r){const M=Math.abs(e[h]-n[h]);if(M<=a){const D=Math.min(a-1,a-M);l[h]===m?y[h]=(d[h]>e[h]?-1:1)*D:w[h]=(u[h]>n[h]?-1:1)*D}}if(t!==r){const M=h==="x"?"y":"x",D=l[h]===c[M],T=d[M]>u[M],L=d[M]<u[M];(l[h]===1&&(!D&&T||D&&L)||l[h]!==1&&(!D&&L||D&&T))&&(g=h==="x"?I:A)}const z={x:d.x+y.x,y:d.y+y.y},P={x:u.x+w.x,y:u.y+w.y},B=Math.max(Math.abs(z.x-g[0].x),Math.abs(P.x-g[0].x)),R=Math.max(Math.abs(z.y-g[0].y),Math.abs(P.y-g[0].y));B>=R?(b=(z.x+P.x)/2,x=g[0].y):(b=g[0].x,x=(z.y+P.y)/2)}const k={x:d.x+y.x,y:d.y+y.y},C={x:u.x+w.x,y:u.y+w.y};return[[e,...k.x!==g[0].x||k.y!==g[0].y?[k]:[],...g,...C.x!==g[g.length-1].x||C.y!==g[g.length-1].y?[C]:[],n],b,x,v,N]}function jU(e,t,n,r){const s=Math.min(ah(e,t)/2,ah(t,n)/2,r),{x:a,y:i}=t;if(e.x===a&&a===n.x||e.y===i&&i===n.y)return`L${a} ${i}`;if(e.y===i){const d=e.x<n.x?-1:1,u=e.y<n.y?1:-1;return`L ${a+s*d},${i}Q ${a},${i} ${a},${i+s*u}`}const l=e.x<n.x?1:-1,c=e.y<n.y?-1:1;return`L ${a},${i+s*c}Q ${a},${i} ${a+s*l},${i}`}function gc({sourceX:e,sourceY:t,sourcePosition:n=we.Bottom,targetX:r,targetY:s,targetPosition:a=we.Top,borderRadius:i=5,centerX:l,centerY:c,offset:d=20,stepPosition:u=.5}){const[p,h,m,g,b]=FU({source:{x:e,y:t},sourcePosition:n,target:{x:r,y:s},targetPosition:a,center:{x:l,y:c},offset:d,stepPosition:u});let x=`M${p[0].x} ${p[0].y}`;for(let y=1;y<p.length-1;y++)x+=jU(p[y-1],p[y],p[y+1],i);return x+=`L${p[p.length-1].x} ${p[p.length-1].y}`,[x,h,m,g,b]}function ih(e){return e&&!!(e.internals.handleBounds||e.handles?.length)&&!!(e.measured.width||e.width||e.initialWidth)}function VU(e){const{sourceNode:t,targetNode:n}=e;if(!ih(t)||!ih(n))return null;const r=t.internals.handleBounds||lh(t.handles),s=n.internals.handleBounds||lh(n.handles),a=ch(r?.source??[],e.sourceHandle),i=ch(e.connectionMode===Or.Strict?s?.target??[]:(s?.target??[]).concat(s?.source??[]),e.targetHandle);if(!a||!i)return e.onError?.("008",en.error008(a?"target":"source",{id:e.id,sourceHandle:e.sourceHandle,targetHandle:e.targetHandle})),null;const l=a?.position||we.Bottom,c=i?.position||we.Top,d=cr(t,a,l),u=cr(n,i,c);return{sourceX:d.x,sourceY:d.y,targetX:u.x,targetY:u.y,sourcePosition:l,targetPosition:c}}function lh(e){if(!e)return null;const t=[],n=[];for(const r of e)r.width=r.width??1,r.height=r.height??1,r.type==="source"?t.push(r):r.type==="target"&&n.push(r);return{source:t,target:n}}function cr(e,t,n=we.Left,r=!1){const s=(t?.x??0)+e.internals.positionAbsolute.x,a=(t?.y??0)+e.internals.positionAbsolute.y,{width:i,height:l}=t??Nn(e);if(r)return{x:s+i/2,y:a+l/2};switch(t?.position??n){case we.Top:return{x:s+i/2,y:a};case we.Right:return{x:s+i,y:a+l/2};case we.Bottom:return{x:s+i/2,y:a+l};case we.Left:return{x:s,y:a+l/2}}}function ch(e,t){return e&&(t?e.find(n=>n.id===t):e[0])||null}function bc(e,t){return e?typeof e=="string"?e:`${t?`${t}__`:""}${Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("&")}`:""}function HU(e,{id:t,defaultColor:n,defaultMarkerStart:r,defaultMarkerEnd:s}){const a=new Set;return e.reduce((i,l)=>([l.markerStart||r,l.markerEnd||s].forEach(c=>{if(c&&typeof c=="object"){const d=bc(c,t);a.has(d)||(i.push({id:d,color:c.color||n,...c}),a.add(d))}}),i),[]).sort((i,l)=>i.id.localeCompare(l.id))}const H1=1e3,qU=10,hu={nodeOrigin:[0,0],nodeExtent:Bo,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},UU={...hu,checkEquality:!0};function mu(e,t){const n={...e};for(const r in t)t[r]!==void 0&&(n[r]=t[r]);return n}function QU(e,t,n){const r=mu(hu,n);for(const s of e.values())if(s.parentId)bu(s,e,t,r);else{const a=ss(s,r.nodeOrigin),i=Fr(s.extent)?s.extent:r.nodeExtent,l=lr(a,i,Nn(s));s.internals.positionAbsolute=l}}function GU(e,t){if(!e.handles)return e.measured?t?.internals.handleBounds:void 0;const n=[],r=[];for(const s of e.handles){const a={id:s.id,width:s.width??1,height:s.height??1,nodeId:e.id,x:s.x,y:s.y,position:s.position,type:s.type};s.type==="source"?n.push(a):s.type==="target"&&r.push(a)}return{source:n,target:r}}function gu(e){return e==="manual"}function xc(e,t,n,r={}){const s=mu(UU,r),a={i:0},i=new Map(t),l=s?.elevateNodesOnSelect&&!gu(s.zIndexMode)?H1:0;let c=e.length>0,d=!1;t.clear(),n.clear();for(const u of e){let p=i.get(u.id);if(s.checkEquality&&u===p?.internals.userNode)t.set(u.id,p);else{const h=ss(u,s.nodeOrigin),m=Fr(u.extent)?u.extent:s.nodeExtent,g=lr(h,m,Nn(u));p={...s.defaults,...u,measured:{width:u.measured?.width,height:u.measured?.height},internals:{positionAbsolute:g,handleBounds:GU(u,p),z:q1(u,l,s.zIndexMode),userNode:u}},t.set(u.id,p)}(p.measured===void 0||p.measured.width===void 0||p.measured.height===void 0)&&!p.hidden&&(c=!1),u.parentId&&bu(p,t,n,r,a),d||=u.selected??!1}return{nodesInitialized:c,hasSelectedNodes:d}}function KU(e,t){if(!e.parentId)return;const n=t.get(e.parentId);n?n.set(e.id,e):t.set(e.parentId,new Map([[e.id,e]]))}function bu(e,t,n,r,s){const{elevateNodesOnSelect:a,nodeOrigin:i,nodeExtent:l,zIndexMode:c}=mu(hu,r),d=e.parentId,u=t.get(d);if(!u){console.warn(`Parent node ${d} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}KU(e,n),s&&!u.parentId&&u.internals.rootParentIndex===void 0&&c==="auto"&&(u.internals.rootParentIndex=++s.i,u.internals.z=u.internals.z+s.i*qU),s&&u.internals.rootParentIndex!==void 0&&(s.i=u.internals.rootParentIndex);const p=a&&!gu(c)?H1:0,{x:h,y:m,z:g}=WU(e,u,i,l,p,c),{positionAbsolute:b}=e.internals,x=h!==b.x||m!==b.y;(x||g!==e.internals.z)&&t.set(e.id,{...e,internals:{...e.internals,positionAbsolute:x?{x:h,y:m}:b,z:g}})}function q1(e,t,n){const r=Ot(e.zIndex)?e.zIndex:0;return gu(n)?r:r+(e.selected?t:0)}function WU(e,t,n,r,s,a){const{x:i,y:l}=t.internals.positionAbsolute,c=Nn(e),d=ss(e,n),u=Fr(e.extent)?lr(d,e.extent,c):d;let p=lr({x:i+u.x,y:l+u.y},r,c);e.extent==="parent"&&(p=_1(p,c,t));const h=q1(e,s,a),m=t.internals.z??0;return{x:p.x,y:p.y,z:m>=h?m+1:h}}function xu(e,t,n,r=[0,0]){const s=[],a=new Map;for(const i of e){const l=t.get(i.parentId);if(!l)continue;const c=a.get(i.parentId)?.expandedRect??zr(l),d=D1(c,i.rect);a.set(i.parentId,{expandedRect:d,parent:l})}return a.size>0&&a.forEach(({expandedRect:i,parent:l},c)=>{const d=l.internals.positionAbsolute,u=Nn(l),p=l.origin??r,h=i.x<d.x?Math.round(Math.abs(d.x-i.x)):0,m=i.y<d.y?Math.round(Math.abs(d.y-i.y)):0,g=Math.max(u.width,Math.round(i.width)),b=Math.max(u.height,Math.round(i.height)),x=(g-u.width)*p[0],y=(b-u.height)*p[1];(h>0||m>0||x||y)&&(s.push({id:c,type:"position",position:{x:l.position.x-h+x,y:l.position.y-m+y}}),n.get(c)?.forEach(w=>{e.some(v=>v.id===w.id)||s.push({id:w.id,type:"position",position:{x:w.position.x+h,y:w.position.y+m}})})),(u.width<i.width||u.height<i.height||h||m)&&s.push({id:c,type:"dimensions",setAttributes:!0,dimensions:{width:g+(h?p[0]*h-x:0),height:b+(m?p[1]*m-y:0)}})}),s}function YU(e,t,n,r,s,a,i){const l=r?.querySelector(".xyflow__viewport");let c=!1;if(!l)return{changes:[],updatedInternals:c};const d=[],u=window.getComputedStyle(l),{m22:p}=new window.DOMMatrixReadOnly(u.transform),h=[];for(const m of e.values()){const g=t.get(m.id);if(!g)continue;if(g.hidden){t.set(g.id,{...g,internals:{...g.internals,handleBounds:void 0}}),c=!0;continue}const b=fu(m.nodeElement),x=g.measured.width!==b.width||g.measured.height!==b.height;if(!!(b.width&&b.height&&(x||!g.internals.handleBounds||m.force))){const w=m.nodeElement.getBoundingClientRect(),v=Fr(g.extent)?g.extent:a;let{positionAbsolute:N}=g.internals;g.parentId&&g.extent==="parent"?N=_1(N,b,t.get(g.parentId)):v&&(N=lr(N,v,b));const k={...g,measured:b,internals:{...g.internals,positionAbsolute:N,handleBounds:{source:rh("source",m.nodeElement,w,p,g.id),target:rh("target",m.nodeElement,w,p,g.id)}}};t.set(g.id,k),g.parentId&&bu(k,t,n,{nodeOrigin:s,zIndexMode:i}),c=!0,x&&(d.push({id:g.id,type:"dimensions",dimensions:b}),g.expandParent&&g.parentId&&h.push({id:g.id,parentId:g.parentId,rect:zr(k,s)}))}}if(h.length>0){const m=xu(h,t,n,s);d.push(...m)}return{changes:d,updatedInternals:c}}async function ZU({delta:e,panZoom:t,transform:n,translateExtent:r,width:s,height:a}){if(!t||!e.x&&!e.y)return Promise.resolve(!1);const i=await t.setViewportConstrained({x:n[0]+e.x,y:n[1]+e.y,zoom:n[2]},[[0,0],[s,a]],r),l=!!i&&(i.x!==n[0]||i.y!==n[1]||i.k!==n[2]);return Promise.resolve(l)}function dh(e,t,n,r,s,a){let i=s;const l=r.get(i)||new Map;r.set(i,l.set(n,t)),i=`${s}-${e}`;const c=r.get(i)||new Map;if(r.set(i,c.set(n,t)),a){i=`${s}-${e}-${a}`;const d=r.get(i)||new Map;r.set(i,d.set(n,t))}}function U1(e,t,n){e.clear(),t.clear();for(const r of n){const{source:s,target:a,sourceHandle:i=null,targetHandle:l=null}=r,c={edgeId:r.id,source:s,target:a,sourceHandle:i,targetHandle:l},d=`${s}-${i}--${a}-${l}`,u=`${a}-${l}--${s}-${i}`;dh("source",c,u,e,s,i),dh("target",c,d,e,a,l),t.set(r.id,r)}}function Q1(e,t){if(!e.parentId)return!1;const n=t.get(e.parentId);return n?n.selected?!0:Q1(n,t):!1}function uh(e,t,n){let r=e;do{if(r?.matches?.(t))return!0;if(r===n)return!1;r=r?.parentElement}while(r);return!1}function XU(e,t,n,r){const s=new Map;for(const[a,i]of e)if((i.selected||i.id===r)&&(!i.parentId||!Q1(i,e))&&(i.draggable||t&&typeof i.draggable>"u")){const l=e.get(a);l&&s.set(a,{id:a,position:l.position||{x:0,y:0},distance:{x:n.x-l.internals.positionAbsolute.x,y:n.y-l.internals.positionAbsolute.y},extent:l.extent,parentId:l.parentId,origin:l.origin,expandParent:l.expandParent,internals:{positionAbsolute:l.internals.positionAbsolute||{x:0,y:0}},measured:{width:l.measured.width??0,height:l.measured.height??0}})}return s}function ul({nodeId:e,dragItems:t,nodeLookup:n,dragging:r=!0}){const s=[];for(const[i,l]of t){const c=n.get(i)?.internals.userNode;c&&s.push({...c,position:l.position,dragging:r})}if(!e)return[s[0],s];const a=n.get(e)?.internals.userNode;return[a?{...a,position:t.get(e)?.position||a.position,dragging:r}:s[0],s]}function JU({dragItems:e,snapGrid:t,x:n,y:r}){const s=e.values().next().value;if(!s)return null;const a={x:n-s.distance.x,y:r-s.distance.y},i=is(a,t);return{x:i.x-a.x,y:i.y-a.y}}function eQ({onNodeMouseDown:e,getStoreItems:t,onDragStart:n,onDrag:r,onDragStop:s}){let a={x:null,y:null},i=0,l=new Map,c=!1,d={x:0,y:0},u=null,p=!1,h=null,m=!1,g=!1,b=null;function x({noDragClassName:w,handleSelector:v,domNode:N,isSelectable:k,nodeId:C,nodeClickDistance:E=0}){h=ht(N);function I({x:B,y:R}){const{nodeLookup:M,nodeExtent:D,snapGrid:T,snapToGrid:L,nodeOrigin:O,onNodeDrag:F,onSelectionDrag:j,onError:V,updateNodePositions:$}=t();a={x:B,y:R};let q=!1;const G=l.size>1,Z=G&&D?mc(as(l)):null,oe=G&&L?JU({dragItems:l,snapGrid:T,x:B,y:R}):null;for(const[ne,X]of l){if(!M.has(ne))continue;let re={x:B-X.distance.x,y:R-X.distance.y};L&&(re=oe?{x:Math.round(re.x+oe.x),y:Math.round(re.y+oe.y)}:is(re,T));let be=null;if(G&&D&&!X.extent&&Z){const{positionAbsolute:ee}=X.internals,ae=ee.x-Z.x+D[0][0],fe=ee.x+X.measured.width-Z.x2+D[1][0],ge=ee.y-Z.y+D[0][1],Q=ee.y+X.measured.height-Z.y2+D[1][1];be=[[ae,ge],[fe,Q]]}const{position:J,positionAbsolute:W}=P1({nodeId:ne,nextPosition:re,nodeLookup:M,nodeExtent:be||D,nodeOrigin:O,onError:V});q=q||X.position.x!==J.x||X.position.y!==J.y,X.position=J,X.internals.positionAbsolute=W}if(g=g||q,!!q&&($(l,!0),b&&(r||F||!C&&j))){const[ne,X]=ul({nodeId:C,dragItems:l,nodeLookup:M});r?.(b,l,ne,X),F?.(b,ne,X),C||j?.(b,X)}}async function A(){if(!u)return;const{transform:B,panBy:R,autoPanSpeed:M,autoPanOnNodeDrag:D}=t();if(!D){c=!1,cancelAnimationFrame(i);return}const[T,L]=$1(d,u,M);(T!==0||L!==0)&&(a.x=(a.x??0)-T/B[2],a.y=(a.y??0)-L/B[2],await R({x:T,y:L})&&I(a)),i=requestAnimationFrame(A)}function z(B){const{nodeLookup:R,multiSelectionActive:M,nodesDraggable:D,transform:T,snapGrid:L,snapToGrid:O,selectNodesOnDrag:F,onNodeDragStart:j,onSelectionDragStart:V,unselectNodesAndEdges:$}=t();p=!0,(!F||!k)&&!M&&C&&(R.get(C)?.selected||$()),k&&F&&C&&e?.(C);const q=Co(B.sourceEvent,{transform:T,snapGrid:L,snapToGrid:O,containerBounds:u});if(a=q,l=XU(R,D,q,C),l.size>0&&(n||j||!C&&V)){const[G,Z]=ul({nodeId:C,dragItems:l,nodeLookup:R});n?.(B.sourceEvent,l,G,Z),j?.(B.sourceEvent,G,Z),C||V?.(B.sourceEvent,Z)}}const P=c1().clickDistance(E).on("start",B=>{const{domNode:R,nodeDragThreshold:M,transform:D,snapGrid:T,snapToGrid:L}=t();u=R?.getBoundingClientRect()||null,m=!1,g=!1,b=B.sourceEvent,M===0&&z(B),a=Co(B.sourceEvent,{transform:D,snapGrid:T,snapToGrid:L,containerBounds:u}),d=Bt(B.sourceEvent,u)}).on("drag",B=>{const{autoPanOnNodeDrag:R,transform:M,snapGrid:D,snapToGrid:T,nodeDragThreshold:L,nodeLookup:O}=t(),F=Co(B.sourceEvent,{transform:M,snapGrid:D,snapToGrid:T,containerBounds:u});if(b=B.sourceEvent,(B.sourceEvent.type==="touchmove"&&B.sourceEvent.touches.length>1||C&&!O.has(C))&&(m=!0),!m){if(!c&&R&&p&&(c=!0,A()),!p){const j=Bt(B.sourceEvent,u),V=j.x-d.x,$=j.y-d.y;Math.sqrt(V*V+$*$)>L&&z(B)}(a.x!==F.xSnapped||a.y!==F.ySnapped)&&l&&p&&(d=Bt(B.sourceEvent,u),I(F))}}).on("end",B=>{if(!(!p||m)&&(c=!1,p=!1,cancelAnimationFrame(i),l.size>0)){const{nodeLookup:R,updateNodePositions:M,onNodeDragStop:D,onSelectionDragStop:T}=t();if(g&&(M(l,!1),g=!1),s||D||!C&&T){const[L,O]=ul({nodeId:C,dragItems:l,nodeLookup:R,dragging:!1});s?.(B.sourceEvent,l,L,O),D?.(B.sourceEvent,L,O),C||T?.(B.sourceEvent,O)}}}).filter(B=>{const R=B.target;return!B.button&&(!w||!uh(R,`.${w}`,N))&&(!v||uh(R,v,N))});h.call(P)}function y(){h?.on(".drag",null)}return{update:x,destroy:y}}function tQ(e,t,n){const r=[],s={x:e.x-n,y:e.y-n,width:n*2,height:n*2};for(const a of t.values())Fo(s,zr(a))>0&&r.push(a);return r}const nQ=250;function rQ(e,t,n,r){let s=[],a=1/0;const i=tQ(e,n,t+nQ);for(const l of i){const c=[...l.internals.handleBounds?.source??[],...l.internals.handleBounds?.target??[]];for(const d of c){if(r.nodeId===d.nodeId&&r.type===d.type&&r.id===d.id)continue;const{x:u,y:p}=cr(l,d,d.position,!0),h=Math.sqrt(Math.pow(u-e.x,2)+Math.pow(p-e.y,2));h>t||(h<a?(s=[{...d,x:u,y:p}],a=h):h===a&&s.push({...d,x:u,y:p}))}}if(!s.length)return null;if(s.length>1){const l=r.type==="source"?"target":"source";return s.find(c=>c.type===l)??s[0]}return s[0]}function G1(e,t,n,r,s,a=!1){const i=r.get(e);if(!i)return null;const l=s==="strict"?i.internals.handleBounds?.[t]:[...i.internals.handleBounds?.source??[],...i.internals.handleBounds?.target??[]],c=(n?l?.find(d=>d.id===n):l?.[0])??null;return c&&a?{...c,...cr(i,c,c.position,!0)}:c}function K1(e,t){return e||(t?.classList.contains("target")?"target":t?.classList.contains("source")?"source":null)}function oQ(e,t){let n=null;return t?n=!0:e&&!t&&(n=!1),n}const W1=()=>!0;function sQ(e,{connectionMode:t,connectionRadius:n,handleId:r,nodeId:s,edgeUpdaterType:a,isTarget:i,domNode:l,nodeLookup:c,lib:d,autoPanOnConnect:u,flowId:p,panBy:h,cancelConnection:m,onConnectStart:g,onConnect:b,onConnectEnd:x,isValidConnection:y=W1,onReconnectEnd:w,updateConnection:v,getTransform:N,getFromHandle:k,autoPanSpeed:C,dragThreshold:E=1,handleDomNode:I}){const A=R1(e.target);let z=0,P;const{x:B,y:R}=Bt(e),M=K1(a,I),D=l?.getBoundingClientRect();let T=!1;if(!D||!M)return;const L=G1(s,M,r,c,t);if(!L)return;let O=Bt(e,D),F=!1,j=null,V=!1,$=null;function q(){if(!u||!D)return;const[J,W]=$1(O,D,C);h({x:J,y:W}),z=requestAnimationFrame(q)}const G={...L,nodeId:s,type:M,position:L.position},Z=c.get(s);let ne={inProgress:!0,isValid:null,from:cr(Z,G,we.Left,!0),fromHandle:G,fromPosition:G.position,fromNode:Z,to:O,toHandle:null,toPosition:Jf[G.position],toNode:null,pointer:O};function X(){T=!0,v(ne),g?.(e,{nodeId:s,handleId:r,handleType:M})}E===0&&X();function re(J){if(!T){const{x:Q,y:le}=Bt(J),ue=Q-B,de=le-R;if(!(ue*ue+de*de>E*E))return;X()}if(!k()||!G){be(J);return}const W=N();O=Bt(J,D),P=rQ(ls(O,W,!1,[1,1]),n,c,G),F||(q(),F=!0);const ee=Y1(J,{handle:P,connectionMode:t,fromNodeId:s,fromHandleId:r,fromType:i?"target":"source",isValidConnection:y,doc:A,lib:d,flowId:p,nodeLookup:c});$=ee.handleDomNode,j=ee.connection,V=oQ(!!P,ee.isValid);const ae=c.get(s),fe=ae?cr(ae,G,we.Left,!0):ne.from,ge={...ne,from:fe,isValid:V,to:ee.toHandle&&V?Sa({x:ee.toHandle.x,y:ee.toHandle.y},W):O,toHandle:ee.toHandle,toPosition:V&&ee.toHandle?ee.toHandle.position:Jf[G.position],toNode:ee.toHandle?c.get(ee.toHandle.nodeId):null,pointer:O};v(ge),ne=ge}function be(J){if(!("touches"in J&&J.touches.length>0)){if(T){(P||$)&&j&&V&&b?.(j);const{inProgress:W,...ee}=ne,ae={...ee,toPosition:ne.toHandle?ne.toPosition:null};x?.(J,ae),a&&w?.(J,ae)}m(),cancelAnimationFrame(z),F=!1,V=!1,j=null,$=null,A.removeEventListener("mousemove",re),A.removeEventListener("mouseup",be),A.removeEventListener("touchmove",re),A.removeEventListener("touchend",be)}}A.addEventListener("mousemove",re),A.addEventListener("mouseup",be),A.addEventListener("touchmove",re),A.addEventListener("touchend",be)}function Y1(e,{handle:t,connectionMode:n,fromNodeId:r,fromHandleId:s,fromType:a,doc:i,lib:l,flowId:c,isValidConnection:d=W1,nodeLookup:u}){const p=a==="target",h=t?i.querySelector(`.${l}-flow__handle[data-id="${c}-${t?.nodeId}-${t?.id}-${t?.type}"]`):null,{x:m,y:g}=Bt(e),b=i.elementFromPoint(m,g),x=b?.classList.contains(`${l}-flow__handle`)?b:h,y={handleDomNode:x,isValid:!1,connection:null,toHandle:null};if(x){const w=K1(void 0,x),v=x.getAttribute("data-nodeid"),N=x.getAttribute("data-handleid"),k=x.classList.contains("connectable"),C=x.classList.contains("connectableend");if(!v||!w)return y;const E={source:p?v:r,sourceHandle:p?N:s,target:p?r:v,targetHandle:p?s:N};y.connection=E;const A=k&&C&&(n===Or.Strict?p&&w==="source"||!p&&w==="target":v!==r||N!==s);y.isValid=A&&d(E),y.toHandle=G1(v,w,N,u,n,!0)}return y}const yc={onPointerDown:sQ,isValid:Y1};function aQ({domNode:e,panZoom:t,getTransform:n,getViewScale:r}){const s=ht(e);function a({translateExtent:l,width:c,height:d,zoomStep:u=1,pannable:p=!0,zoomable:h=!0,inversePan:m=!1}){const g=v=>{if(v.sourceEvent.type!=="wheel"||!t)return;const N=n(),k=v.sourceEvent.ctrlKey&&jo()?10:1,C=-v.sourceEvent.deltaY*(v.sourceEvent.deltaMode===1?.05:v.sourceEvent.deltaMode?1:.002)*u,E=N[2]*Math.pow(2,C*k);t.scaleTo(E)};let b=[0,0];const x=v=>{(v.sourceEvent.type==="mousedown"||v.sourceEvent.type==="touchstart")&&(b=[v.sourceEvent.clientX??v.sourceEvent.touches[0].clientX,v.sourceEvent.clientY??v.sourceEvent.touches[0].clientY])},y=v=>{const N=n();if(v.sourceEvent.type!=="mousemove"&&v.sourceEvent.type!=="touchmove"||!t)return;const k=[v.sourceEvent.clientX??v.sourceEvent.touches[0].clientX,v.sourceEvent.clientY??v.sourceEvent.touches[0].clientY],C=[k[0]-b[0],k[1]-b[1]];b=k;const E=r()*Math.max(N[2],Math.log(N[2]))*(m?-1:1),I={x:N[0]-C[0]*E,y:N[1]-C[1]*E},A=[[0,0],[c,d]];t.setViewportConstrained({x:I.x,y:I.y,zoom:N[2]},A,l)},w=S1().on("start",x).on("zoom",p?y:null).on("zoom.wheel",h?g:null);s.call(w,{})}function i(){s.on("zoom",null)}return{update:a,destroy:i,pointer:Lt}}const ui=e=>({x:e.x,y:e.y,zoom:e.k}),pl=({x:e,y:t,zoom:n})=>li.translate(e,t).scale(n),Cr=(e,t)=>e.target.closest(`.${t}`),Z1=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),iQ=e=>((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2,fl=(e,t=0,n=iQ,r=()=>{})=>{const s=typeof t=="number"&&t>0;return s||r(),s?e.transition().duration(t).ease(n).on("end",r):e},X1=e=>{const t=e.ctrlKey&&jo()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t};function lQ({zoomPanValues:e,noWheelClassName:t,d3Selection:n,d3Zoom:r,panOnScrollMode:s,panOnScrollSpeed:a,zoomOnPinch:i,onPanZoomStart:l,onPanZoom:c,onPanZoomEnd:d}){return u=>{if(Cr(u,t))return u.ctrlKey&&u.preventDefault(),!1;u.preventDefault(),u.stopImmediatePropagation();const p=n.property("__zoom").k||1;if(u.ctrlKey&&i){const x=Lt(u),y=X1(u),w=p*Math.pow(2,y);r.scaleTo(n,w,x,u);return}const h=u.deltaMode===1?20:1;let m=s===Xn.Vertical?0:u.deltaX*h,g=s===Xn.Horizontal?0:u.deltaY*h;!jo()&&u.shiftKey&&s!==Xn.Vertical&&(m=u.deltaY*h,g=0),r.translateBy(n,-(m/p)*a,-(g/p)*a,{internal:!0});const b=ui(n.property("__zoom"));clearTimeout(e.panScrollTimeout),e.isPanScrolling?(c?.(u,b),e.panScrollTimeout=setTimeout(()=>{d?.(u,b),e.isPanScrolling=!1},150)):(e.isPanScrolling=!0,l?.(u,b))}}function cQ({noWheelClassName:e,preventScrolling:t,d3ZoomHandler:n}){return function(r,s){const a=r.type==="wheel",i=!t&&a&&!r.ctrlKey,l=Cr(r,e);if(r.ctrlKey&&a&&l&&r.preventDefault(),i||l)return null;r.preventDefault(),n.call(this,r,s)}}function dQ({zoomPanValues:e,onDraggingChange:t,onPanZoomStart:n}){return r=>{if(r.sourceEvent?.internal)return;const s=ui(r.transform);e.mouseButton=r.sourceEvent?.button||0,e.isZoomingOrPanning=!0,e.prevViewport=s,r.sourceEvent?.type==="mousedown"&&t(!0),n&&n?.(r.sourceEvent,s)}}function uQ({zoomPanValues:e,panOnDrag:t,onPaneContextMenu:n,onTransformChange:r,onPanZoom:s}){return a=>{e.usedRightMouseButton=!!(n&&Z1(t,e.mouseButton??0)),a.sourceEvent?.sync||r([a.transform.x,a.transform.y,a.transform.k]),s&&!a.sourceEvent?.internal&&s?.(a.sourceEvent,ui(a.transform))}}function pQ({zoomPanValues:e,panOnDrag:t,panOnScroll:n,onDraggingChange:r,onPanZoomEnd:s,onPaneContextMenu:a}){return i=>{if(!i.sourceEvent?.internal&&(e.isZoomingOrPanning=!1,a&&Z1(t,e.mouseButton??0)&&!e.usedRightMouseButton&&i.sourceEvent&&a(i.sourceEvent),e.usedRightMouseButton=!1,r(!1),s)){const l=ui(i.transform);e.prevViewport=l,clearTimeout(e.timerId),e.timerId=setTimeout(()=>{s?.(i.sourceEvent,l)},n?150:0)}}}function fQ({zoomActivationKeyPressed:e,zoomOnScroll:t,zoomOnPinch:n,panOnDrag:r,panOnScroll:s,zoomOnDoubleClick:a,userSelectionActive:i,noWheelClassName:l,noPanClassName:c,lib:d,connectionInProgress:u}){return p=>{const h=e||t,m=n&&p.ctrlKey,g=p.type==="wheel";if(p.button===1&&p.type==="mousedown"&&(Cr(p,`${d}-flow__node`)||Cr(p,`${d}-flow__edge`)))return!0;if(!r&&!h&&!s&&!a&&!n||i||u&&!g||Cr(p,l)&&g||Cr(p,c)&&(!g||s&&g&&!e)||!n&&p.ctrlKey&&g)return!1;if(!n&&p.type==="touchstart"&&p.touches?.length>1)return p.preventDefault(),!1;if(!h&&!s&&!m&&g||!r&&(p.type==="mousedown"||p.type==="touchstart")||Array.isArray(r)&&!r.includes(p.button)&&p.type==="mousedown")return!1;const b=Array.isArray(r)&&r.includes(p.button)||!p.button||p.button<=1;return(!p.ctrlKey||g)&&b}}function hQ({domNode:e,minZoom:t,maxZoom:n,translateExtent:r,viewport:s,onPanZoom:a,onPanZoomStart:i,onPanZoomEnd:l,onDraggingChange:c}){const d={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},u=e.getBoundingClientRect(),p=S1().scaleExtent([t,n]).translateExtent(r),h=ht(e).call(p);w({x:s.x,y:s.y,zoom:Br(s.zoom,t,n)},[[0,0],[u.width,u.height]],r);const m=h.on("wheel.zoom"),g=h.on("dblclick.zoom");p.wheelDelta(X1);function b(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).transform(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function x({noWheelClassName:P,noPanClassName:B,onPaneContextMenu:R,userSelectionActive:M,panOnScroll:D,panOnDrag:T,panOnScrollMode:L,panOnScrollSpeed:O,preventScrolling:F,zoomOnPinch:j,zoomOnScroll:V,zoomOnDoubleClick:$,zoomActivationKeyPressed:q,lib:G,onTransformChange:Z,connectionInProgress:oe,paneClickDistance:ne,selectionOnDrag:X}){M&&!d.isZoomingOrPanning&&y();const re=D&&!q&&!M;p.clickDistance(X?1/0:!Ot(ne)||ne<0?0:ne);const be=re?lQ({zoomPanValues:d,noWheelClassName:P,d3Selection:h,d3Zoom:p,panOnScrollMode:L,panOnScrollSpeed:O,zoomOnPinch:j,onPanZoomStart:i,onPanZoom:a,onPanZoomEnd:l}):cQ({noWheelClassName:P,preventScrolling:F,d3ZoomHandler:m});if(h.on("wheel.zoom",be,{passive:!1}),!M){const W=dQ({zoomPanValues:d,onDraggingChange:c,onPanZoomStart:i});p.on("start",W);const ee=uQ({zoomPanValues:d,panOnDrag:T,onPaneContextMenu:!!R,onPanZoom:a,onTransformChange:Z});p.on("zoom",ee);const ae=pQ({zoomPanValues:d,panOnDrag:T,panOnScroll:D,onPaneContextMenu:R,onPanZoomEnd:l,onDraggingChange:c});p.on("end",ae)}const J=fQ({zoomActivationKeyPressed:q,panOnDrag:T,zoomOnScroll:V,panOnScroll:D,zoomOnDoubleClick:$,zoomOnPinch:j,userSelectionActive:M,noPanClassName:B,noWheelClassName:P,lib:G,connectionInProgress:oe});p.filter(J),$?h.on("dblclick.zoom",g):h.on("dblclick.zoom",null)}function y(){p.on("zoom",null)}async function w(P,B,R){const M=pl(P),D=p?.constrain()(M,B,R);return D&&await b(D),new Promise(T=>T(D))}async function v(P,B){const R=pl(P);return await b(R,B),new Promise(M=>M(R))}function N(P){if(h){const B=pl(P),R=h.property("__zoom");(R.k!==P.zoom||R.x!==P.x||R.y!==P.y)&&p?.transform(h,B,null,{sync:!0})}}function k(){const P=h?k1(h.node()):{x:0,y:0,k:1};return{x:P.x,y:P.y,zoom:P.k}}function C(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).scaleTo(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function E(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).scaleBy(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function I(P){p?.scaleExtent(P)}function A(P){p?.translateExtent(P)}function z(P){const B=!Ot(P)||P<0?0:P;p?.clickDistance(B)}return{update:x,destroy:y,setViewport:v,setViewportConstrained:w,getViewport:k,scaleTo:C,scaleBy:E,setScaleExtent:I,setTranslateExtent:A,syncViewport:N,setClickDistance:z}}var jr;(function(e){e.Line="line",e.Handle="handle"})(jr||(jr={}));function mQ({width:e,prevWidth:t,height:n,prevHeight:r,affectsX:s,affectsY:a}){const i=e-t,l=n-r,c=[i>0?1:i<0?-1:0,l>0?1:l<0?-1:0];return i&&s&&(c[0]=c[0]*-1),l&&a&&(c[1]=c[1]*-1),c}function ph(e){const t=e.includes("right")||e.includes("left"),n=e.includes("bottom")||e.includes("top"),r=e.includes("left"),s=e.includes("top");return{isHorizontal:t,isVertical:n,affectsX:r,affectsY:s}}function Cn(e,t){return Math.max(0,t-e)}function Mn(e,t){return Math.max(0,e-t)}function Rs(e,t,n){return Math.max(0,t-e,e-n)}function fh(e,t){return e?!t:t}function gQ(e,t,n,r,s,a,i,l){let{affectsX:c,affectsY:d}=t;const{isHorizontal:u,isVertical:p}=t,h=u&&p,{xSnapped:m,ySnapped:g}=n,{minWidth:b,maxWidth:x,minHeight:y,maxHeight:w}=r,{x:v,y:N,width:k,height:C,aspectRatio:E}=e;let I=Math.floor(u?m-e.pointerX:0),A=Math.floor(p?g-e.pointerY:0);const z=k+(c?-I:I),P=C+(d?-A:A),B=-a[0]*k,R=-a[1]*C;let M=Rs(z,b,x),D=Rs(P,y,w);if(i){let O=0,F=0;c&&I<0?O=Cn(v+I+B,i[0][0]):!c&&I>0&&(O=Mn(v+z+B,i[1][0])),d&&A<0?F=Cn(N+A+R,i[0][1]):!d&&A>0&&(F=Mn(N+P+R,i[1][1])),M=Math.max(M,O),D=Math.max(D,F)}if(l){let O=0,F=0;c&&I>0?O=Mn(v+I,l[0][0]):!c&&I<0&&(O=Cn(v+z,l[1][0])),d&&A>0?F=Mn(N+A,l[0][1]):!d&&A<0&&(F=Cn(N+P,l[1][1])),M=Math.max(M,O),D=Math.max(D,F)}if(s){if(u){const O=Rs(z/E,y,w)*E;if(M=Math.max(M,O),i){let F=0;!c&&!d||c&&!d&&h?F=Mn(N+R+z/E,i[1][1])*E:F=Cn(N+R+(c?I:-I)/E,i[0][1])*E,M=Math.max(M,F)}if(l){let F=0;!c&&!d||c&&!d&&h?F=Cn(N+z/E,l[1][1])*E:F=Mn(N+(c?I:-I)/E,l[0][1])*E,M=Math.max(M,F)}}if(p){const O=Rs(P*E,b,x)/E;if(D=Math.max(D,O),i){let F=0;!c&&!d||d&&!c&&h?F=Mn(v+P*E+B,i[1][0])/E:F=Cn(v+(d?A:-A)*E+B,i[0][0])/E,D=Math.max(D,F)}if(l){let F=0;!c&&!d||d&&!c&&h?F=Cn(v+P*E,l[1][0])/E:F=Mn(v+(d?A:-A)*E,l[0][0])/E,D=Math.max(D,F)}}}A=A+(A<0?D:-D),I=I+(I<0?M:-M),s&&(h?z>P*E?A=(fh(c,d)?-I:I)/E:I=(fh(c,d)?-A:A)*E:u?(A=I/E,d=c):(I=A*E,c=d));const T=c?v+I:v,L=d?N+A:N;return{width:k+(c?-I:I),height:C+(d?-A:A),x:a[0]*I*(c?-1:1)+T,y:a[1]*A*(d?-1:1)+L}}const J1={width:0,height:0,x:0,y:0},bQ={...J1,pointerX:0,pointerY:0,aspectRatio:1};function xQ(e){return[[0,0],[e.measured.width,e.measured.height]]}function yQ(e,t,n){const r=t.position.x+e.position.x,s=t.position.y+e.position.y,a=e.measured.width??0,i=e.measured.height??0,l=n[0]*a,c=n[1]*i;return[[r-l,s-c],[r+a-l,s+i-c]]}function vQ({domNode:e,nodeId:t,getStoreItems:n,onChange:r,onEnd:s}){const a=ht(e);let i={controlDirection:ph("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function l({controlPosition:d,boundaries:u,keepAspectRatio:p,resizeDirection:h,onResizeStart:m,onResize:g,onResizeEnd:b,shouldResize:x}){let y={...J1},w={...bQ};i={boundaries:u,resizeDirection:h,keepAspectRatio:p,controlDirection:ph(d)};let v,N=null,k=[],C,E,I,A=!1;const z=c1().on("start",P=>{const{nodeLookup:B,transform:R,snapGrid:M,snapToGrid:D,nodeOrigin:T,paneDomNode:L}=n();if(v=B.get(t),!v)return;N=L?.getBoundingClientRect()??null;const{xSnapped:O,ySnapped:F}=Co(P.sourceEvent,{transform:R,snapGrid:M,snapToGrid:D,containerBounds:N});y={width:v.measured.width??0,height:v.measured.height??0,x:v.position.x??0,y:v.position.y??0},w={...y,pointerX:O,pointerY:F,aspectRatio:y.width/y.height},C=void 0,v.parentId&&(v.extent==="parent"||v.expandParent)&&(C=B.get(v.parentId),E=C&&v.extent==="parent"?xQ(C):void 0),k=[],I=void 0;for(const[j,V]of B)if(V.parentId===t&&(k.push({id:j,position:{...V.position},extent:V.extent}),V.extent==="parent"||V.expandParent)){const $=yQ(V,v,V.origin??T);I?I=[[Math.min($[0][0],I[0][0]),Math.min($[0][1],I[0][1])],[Math.max($[1][0],I[1][0]),Math.max($[1][1],I[1][1])]]:I=$}m?.(P,{...y})}).on("drag",P=>{const{transform:B,snapGrid:R,snapToGrid:M,nodeOrigin:D}=n(),T=Co(P.sourceEvent,{transform:B,snapGrid:R,snapToGrid:M,containerBounds:N}),L=[];if(!v)return;const{x:O,y:F,width:j,height:V}=y,$={},q=v.origin??D,{width:G,height:Z,x:oe,y:ne}=gQ(w,i.controlDirection,T,i.boundaries,i.keepAspectRatio,q,E,I),X=G!==j,re=Z!==V,be=oe!==O&&X,J=ne!==F&&re;if(!be&&!J&&!X&&!re)return;if((be||J||q[0]===1||q[1]===1)&&($.x=be?oe:y.x,$.y=J?ne:y.y,y.x=$.x,y.y=$.y,k.length>0)){const fe=oe-O,ge=ne-F;for(const Q of k)Q.position={x:Q.position.x-fe+q[0]*(G-j),y:Q.position.y-ge+q[1]*(Z-V)},L.push(Q)}if((X||re)&&($.width=X&&(!i.resizeDirection||i.resizeDirection==="horizontal")?G:y.width,$.height=re&&(!i.resizeDirection||i.resizeDirection==="vertical")?Z:y.height,y.width=$.width,y.height=$.height),C&&v.expandParent){const fe=q[0]*($.width??0);$.x&&$.x<fe&&(y.x=fe,w.x=w.x-($.x-fe));const ge=q[1]*($.height??0);$.y&&$.y<ge&&(y.y=ge,w.y=w.y-($.y-ge))}const W=mQ({width:y.width,prevWidth:j,height:y.height,prevHeight:V,affectsX:i.controlDirection.affectsX,affectsY:i.controlDirection.affectsY}),ee={...y,direction:W};x?.(P,ee)!==!1&&(A=!0,g?.(P,ee),r($,L))}).on("end",P=>{A&&(b?.(P,{...y}),s?.({...y}),A=!1)});a.call(z)}function c(){a.on(".drag",null)}return{update:l,destroy:c}}var ew={exports:{}},tw={};/**
|
|
1142
|
+
`);return o(xB,{scope:{type:"device",deviceId:e},greeting:t,className:"h-full border-0 rounded-none"})}function SB({deviceId:e}){const t=Te(),n=Number.isFinite(e),r=Ld(t.trpcClient,n?e:0,{enabled:n}),{data:s}=$7(n?e:0);if(!n)return f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]});const a=(s?.features??[]).includes(Wn.PtzAutotrack);return f("div",{className:"flex flex-col h-full overflow-y-auto",children:[o(Pd,{controls:r,mode:"panel"}),a&&o(vB,{deviceId:e})]})}function CB({deviceId:e}){return Number.isFinite(e)?o("div",{className:"flex flex-col h-full overflow-y-auto",children:o(br,{deviceId:e,limit:50,maxHeight:"max-h-full"})}):f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]})}function MB({deviceId:e}){return Number.isFinite(e)?o("div",{className:"flex flex-col h-full overflow-y-auto",children:o(Id,{deviceId:e,limit:50,maxHeight:"max-h-full"})}):f("div",{className:"flex items-center justify-center h-full text-[11px] text-foreground-subtle italic",children:["Device #",e," not loaded."]})}function EB({parentDeviceId:e}){const{t}=Vt(),n=rt(),r=Te(),{data:s,isLoading:a,isError:i}=Mv(e);if(a)return o("div",{className:"rounded-lg border border-border bg-surface p-3",children:o("p",{className:"text-[10px] text-foreground-subtle",children:t("common.loading",{defaultValue:"Loading…"})})});if(i)return o("div",{className:"rounded-lg border border-border bg-surface p-3",children:o("p",{className:"text-[10px] text-warning",children:t("integrations.childrenLoadError",{defaultValue:"Failed to load children"})})});const l=s??[];if(l.length===0)return null;const c=l.some(p=>!!p.role),d=l.some(p=>!p.role),u=c&&!d?t("device.accessories",{defaultValue:"Accessories"}):!c&&d?t("device.adoptedDevices",{defaultValue:"Adopted devices"}):t("device.children",{defaultValue:"Children"});return f("div",{className:"rounded-lg border border-border bg-surface p-3",children:[o("div",{className:"text-[10px] font-semibold uppercase tracking-wide text-foreground-subtle mb-1.5",children:u}),o("div",{className:"space-y-1",children:l.map(p=>o(Io,{trpc:r.trpcClient,device:p,variant:"minimal",onNavigate:h=>n(`/devices/${String(h)}`)},p.id))})]})}function rl(e){return e<1e3?`${e.toFixed(0)} kbps`:`${(e/1e3).toFixed(1)} Mbps`}function IB({device:e}){const t=rt(),n=typeof e.id=="number"?e.id:null,r=String(e.type??""),s=r===pt.Camera,a=r===pt.Hub,i=e.features??[],{data:l}=fd({deviceId:n??0},{enabled:n!==null&&s,refetchInterval:5e3}),c=l?.streams??{},d=Object.entries(c),u=i.includes(Wn.DoorbellButton),p=Rd(u?{deviceId:n??void 0,historyLimit:10}:void 0),h=p.latest?Date.now()-p.latest.timestamp<3e4:!1;return f("div",{className:"space-y-5",children:[a&&n!==null&&o(x0,{deviceId:n,onOpenChild:m=>t(`/devices/${m}`)}),s&&n!==null&&o(ft,{widgetId:"pipeline-orchestrator/pipeline-quick-stats",host:"device-tab",deviceId:n}),u&&o(_d,{history:p.history,latestIsFresh:h}),s&&n!==null&&o(ft,{widgetId:"stream-broker/stream-broker-panel",host:"device-tab",deviceId:n}),s&&d.length>0&&f("div",{className:"@container rounded-lg border border-border bg-surface overflow-hidden",style:{containerType:"inline-size"},children:[o("div",{className:"border-b border-border px-4 py-2",children:o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:"Stream Network"})}),o("div",{className:"divide-y divide-border",children:d.map(([m,g])=>f("div",{className:"px-4 py-2.5",children:[f("div",{className:"flex items-center gap-2 mb-2",children:[o(or,{className:"h-3 w-3 text-foreground-subtle"}),o("span",{className:"text-[11px] font-medium text-foreground",children:m})]}),f("div",{className:"grid grid-cols-2 @[640px]:grid-cols-4 gap-2",children:[o(Ms,{label:"Nominal",value:rl(g.nominalBitrateKbps??0)}),o(Ms,{label:"Observed",value:rl(g.observedBitrateKbps??0)}),o(Ms,{label:"Peak",value:rl(g.peakBitrateKbps??0)}),o(Ms,{label:"Packet Loss",value:`${(g.packetLossPercent??0).toFixed(2)}%`,warning:(g.packetLossPercent??0)>1})]})]},m))})]}),o(cv,{})]})}function Ms({label:e,value:t,warning:n}){return f("div",{children:[o("p",{className:"text-[10px] text-foreground-subtle",children:e}),o("p",{className:`text-xs font-medium ${n?"text-warning":"text-foreground"}`,children:t})]})}function AB({schema:e,values:t,pendingKeys:n,onChange:r,onAction:s,onSave:a,onDiscard:i,disabled:l}){const c=e.tabs??[],d=H(()=>{const k=new Map;for(const C of e.sections){const E=C.tab??"general",I=k.get(E)??[];I.push(C),k.set(E,I)}return k},[e.sections]),u=new Set(c.map(k=>k.id)),p=[...c,...[...d.keys()].filter(k=>!u.has(k)).map(k=>({id:k,label:k,icon:"wrench",order:100}))],h=p[0]?.id??"general",[m,g]=_(h),b=d.get(m)??[],y={sections:b.length<=1?b.length===1?[{...b[0],title:""}]:b:b.every(C=>!C.title)?[{...b[0],title:"",fields:b.flatMap(C=>C.fields)}]:b},w=o(Pv,{pendingCount:n.length,onSave:()=>a(n),onDiscard:()=>i(n),saving:l});if(p.length<=1)return f("div",{className:"flex flex-col gap-3",children:[o(Dn,{schema:e,values:t,onChange:r,onAction:s,disabled:l}),w]});const v=new Map,N=new Map;for(const[k,C]of d){v.set(k,C.length);const E=new Set,I=z=>{for(const P of z)if("key"in P&&typeof P.key=="string"&&E.add(P.key),P.type==="group")I(P.fields);else if(P.type==="sub-tabs")for(const B of P.tabs)I(B.fields)};for(const z of C)I(z.fields);const A=n.filter(z=>E.has(z)).length;A>0&&N.set(k,A)}return f("div",{className:"flex flex-col gap-3",children:[o(_v,{tabs:p.map(k=>({id:k.id,label:k.label})),activeId:m,onChange:g,countByTab:v,pendingByTab:N}),o(Dn,{schema:y,values:t,onChange:r,onAction:s,disabled:l}),w]})}function PB(e,t){return t&&t==="admin"?e:!0}function _B(e){if(!e)return null;const n={sections:[...e.sections].sort((r,s)=>{const a=r.tab??"general",i=s.tab??"general";return a!==i?a.localeCompare(i):Do(r)&&Do(s)?r.id.localeCompare(s.id):(r.order??0)-(s.order??0)})};return e.tabs?{...n,tabs:e.tabs}:n}function Tv(e){return e.type==="separator"||e.type==="info"||e.type==="button"||e.type==="widget"||e.type==="addon-action-button"}function Lv(e){return e.key}function $B(e){if(!Tv(e))return e.value}function Rv(e){return Tv(e)?null:e}function pa(e,t){for(const n of e)if(t(n),n.type==="group")pa(n.fields,t);else if(n.type==="sub-tabs")for(const r of n.tabs)pa(r.fields,t)}function DB(e){if(!e)return{};const t={};for(const n of e.sections)pa(n.fields,r=>{const s=Lv(r);s!==null&&(t[s]=$B(r))});return t}function Mf(e,t){if(!e)return null;let n=null;for(const r of e.sections)if(pa(r.fields,s=>{if(n!==null||Lv(s)!==t)return;const a=Rv(s);a&&a.writerCapName&&a.writerAddonId&&(n={capName:a.writerCapName,addonId:a.writerAddonId})}),n!==null)break;return n}function TB(e){return{...e,fields:e.fields.map(Ov)}}function Ov(e){return e.type==="separator"||e.type==="info"||e.type==="button"||e.type==="object-array"?e:{...e,readonlyField:!0}}function LB(e,t){return e&&{...e,sections:e.sections.map(n=>({...n,fields:n.fields.map(r=>{const s=Rv(r);return s?PB(t,s.minRole)?r:Ov(r):r})}))}}function nc({deviceId:e,sectionFilter:t}){const n=ke(),{user:r}=nn(),s=r?.isAdmin===!0,a=te(!1),{data:i,isLoading:l}=cd({deviceId:e},{refetchInterval:()=>a.current?!1:2500,staleTime:6e4,enabled:Number.isFinite(e)}),{data:c}=er({deviceId:e},{staleTime:6e4,enabled:Number.isFinite(e)}),d=i?.settings??null,u=i?.live??null,p=H(()=>{if(!d&&!u)return null;const B=d?.sections??[],R=(u?.sections??[]).map(TB),M=[...B,...R],D=t?M.filter(t):M.filter(F=>F.location!=="top-tab"&&!Do(F));if(D.length===0)return null;const T=new Set;for(const F of D)T.add(F.tab??"general");const O=[...d?.tabs??[],...(u?.tabs??[]).filter(F=>!(d?.tabs??[]).some(j=>j.id===F.id))].filter(F=>T.has(F.id));return O.length>0?{tabs:O,sections:D}:{sections:D}},[d,u,t]),h=H(()=>_B(p),[p]),m=H(()=>LB(h,s),[h,s]),g=H(()=>DB(m),[m]),b=Iy(),x=ud(),y=rx({onSuccess:()=>{n.invalidateQueries({queryKey:[["deviceManager","getDeviceAggregate"]]})}}),w={isPending:y.isPending,mutate:B=>{y.mutate({deviceId:e,changes:[...B]})}},v=U(B=>{const R=Object.entries(B).map(([M,D])=>{const T=Mf(m,M);return T?{writerCapName:T.capName,writerAddonId:T.addonId,key:M,value:D}:null}).filter(M=>M!==null);R.length>0&&w.mutate(R)},[m,w]),N=U(B=>{const R=Object.entries(B).map(([M,D])=>{const T=Mf(m,M);return T?{writerCapName:T.capName,writerAddonId:T.addonId,key:M,value:D}:null}).filter(M=>M!==null);R.length>0&&w.mutate(R)},[m,w]),k=$v({schema:m,serverValues:g,onImmediateSave:v,onDeferredSave:N}),{values:C,pendingKeys:E,handleChange:I,handleSave:A,handleDiscard:z}=k;if(a.current=k.editingPaused,l)return f("div",{className:"flex items-center justify-center py-12 text-foreground-subtle",children:[o(Se,{className:"h-4 w-4 animate-spin mr-2"}),o("span",{className:"text-xs",children:"Loading device aggregate…"})]});if(!m||m.sections.length===0)return o("div",{className:"text-xs text-foreground-subtle italic py-4 text-center",children:"No aggregate contributions for this device."});async function P(B,R,M){if(B==="regenerate-rtsp-token"){const D=["rtspUrl:","regenerateToken:"].find(O=>R.startsWith(O));if(!D)throw new Error(`regenerate-rtsp-token: unrecognised key "${R}" (expected "rtspUrl:<streamId>" or "regenerateToken:<streamId>")`);const T=R.slice(D.length);if(!T)throw new Error(`regenerate-rtsp-token: key "${R}" has no streamId after prefix`);const L=`${e}/${T}`;await b.mutateAsync({brokerId:L}),n.invalidateQueries({queryKey:[["deviceManager","getDeviceAggregate"]]});return}if(B==="test-probe"){if(!c)return{status:"error",error:"Device metadata not loaded yet"};try{return await x.mutateAsync({addonId:c.addonId,type:c.type,key:R,value:M})}catch(D){return{status:"error",error:D instanceof Error?D.message:String(D)}}}if(B==="refresh-driver-data"){await y.mutateAsync({deviceId:e,changes:[{writerCapName:"device-manager",writerAddonId:"device-manager",key:R,value:Date.now()}]});return}throw new Error(`[device-aggregate] unknown action "${B}"`)}return o(AB,{schema:m,values:C,pendingKeys:E,onChange:I,onAction:P,onSave:A,onDiscard:z,disabled:w.isPending})}function RB({deviceId:e}){return o(nc,{deviceId:e})}const Bv=6e4,rc=60*Bv,Ef=24*rc;function ni(e){if(e==null||e<=0)return"—";const t=Date.now()-e;return t<0||t<3e4?"just now":t<rc?`${String(Math.floor(t/Bv))}m ago`:t<Ef?`${String(Math.floor(t/rc))}h ago`:`${String(Math.floor(t/Ef))}d ago`}function OB(e,t=new Date){const n=new Date(e);return n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate()}function zv({dev:e,busy:t,setBusy:n}){const r=e?.motionTrigger,s=pn(e?.state.motionTrigger),[a,i]=_(!1);if(!r)return null;const l=s?.enabled===!0,c=s!==void 0,d=async()=>{if(t||!c)return;const p=!l;n(!0),i(!0);try{await r.setMotionTrigger({enabled:p})}finally{n(!1),i(!1)}};return f("button",{type:"button",onClick:()=>{d()},disabled:t||!c,title:c?l?"Disable trigger on motion":"Enable trigger on motion":"Awaiting state…","aria-pressed":l,className:`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${l?"border-primary/50 bg-primary/15 text-primary":"border-border bg-surface text-foreground-subtle hover:text-foreground"}`,children:[o(Xo,{className:"h-3 w-3"}),o("span",{children:a?l?"Disabling…":"Enabling…":c?l?"On motion: on":"On motion: off":"On motion: …"})]})}function Fv({deviceId:e,deviceName:t,useSiren:n=!1}){const r=Te(),s=At(r.trpcClient,e),a=pn(s?.state.switch),[i,l]=_(!1),c=a?.on??!1,d=a?.lastChangedAt??null,u=a!==void 0,p=n?Jo:ev,h=async()=>{if(!(i||!u||!s?.switch)){l(!0);try{await s.switch.setState({on:!c})}finally{l(!1)}}};return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("button",{type:"button",onClick:()=>{h()},disabled:i||!u||!s?.switch,title:u?c?`Turn off ${t}`:`Turn on ${t}`:"Awaiting state…","aria-pressed":c,className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all disabled:cursor-not-allowed disabled:opacity-50 ${c?"border-success bg-success/20 text-success shadow-lg shadow-success/20":"border-border bg-surface text-foreground-subtle hover:border-foreground-subtle hover:text-foreground"}`,children:o(p,{className:"h-10 w-10"})}),o(zv,{dev:s,busy:i,setBusy:l}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${c?"text-success":"text-foreground-subtle"}`,children:u?c?"On":"Off":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:u?`Changed ${ni(d)}`:"Awaiting state…"})]})]})}function BB({deviceId:e,deviceName:t}){const n=Te(),r=At(n.trpcClient,e),s=pn(r?.state.switch),a=pn(r?.state.brightness),i=s?.on??!1,l=s?.lastChangedAt??null,c=s!==void 0,d=a!==void 0,u=r?.brightness!==void 0,[p,h]=_(!1),[m,g]=_(a?.percentage??0);Y(()=>{a?.percentage!==void 0&&g(a.percentage)},[a?.percentage]);const b=async()=>{if(!(p||!c||!r?.switch)){h(!0);try{await r.switch.setState({on:!i})}finally{h(!1)}}},x=async()=>{if(!(p||!d||!r?.brightness)){h(!0);try{await r.brightness.setBrightness({percentage:m})}finally{h(!1)}}};return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("button",{type:"button",onClick:()=>{b()},disabled:p||!c||!r?.switch,title:c?i?`Turn off ${t}`:`Turn on ${t}`:"Awaiting state…","aria-pressed":i,className:`flex h-20 w-20 items-center justify-center rounded-full border-2 transition-all disabled:cursor-not-allowed disabled:opacity-50 ${i?"border-warning bg-warning/20 text-warning shadow-lg shadow-warning/30":"border-border bg-surface text-foreground-subtle hover:border-foreground-subtle hover:text-foreground"}`,children:o(I6,{className:"h-9 w-9"})}),u?f("div",{className:"flex w-full max-w-xs flex-col items-center gap-1",children:[o("input",{type:"range",min:0,max:100,step:1,value:m,disabled:p||!i||!d,onChange:y=>g(Number(y.currentTarget.value)),onPointerUp:()=>{x()},onKeyUp:y=>{y.key==="Enter"&&x()},"aria-label":"Brightness",className:"w-full accent-warning disabled:cursor-not-allowed disabled:opacity-50"}),o("div",{className:"text-[10px] text-foreground-subtle tabular-nums",children:d?`${String(m)}%`:"Brightness unavailable"})]}):null,o(zv,{dev:r,busy:p,setBusy:h}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${i?"text-warning":"text-foreground-subtle"}`,children:c?i?"On":"Off":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:c?`Changed ${ni(l)}`:"Awaiting state…"})]})]})}function zB({deviceId:e}){const t=Te(),n=At(t.trpcClient,e),r=pn(n?.state.motion),s=r?.detected??!1,a=r?.lastDetectedAt??null,i=r!==void 0;return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("div",{className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all ${s?"border-danger bg-danger/20 text-danger shadow-lg shadow-danger/30 animate-pulse":"border-border bg-surface text-foreground-subtle"}`,"aria-live":"polite",title:s?"Motion detected":"Idle",children:s?o(iO,{className:"h-10 w-10"}):o(Xo,{className:"h-10 w-10"})}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${s?"text-danger":"text-foreground-subtle"}`,children:i?s?"Triggered":"Idle":"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5",children:i?`Last trip ${ni(a)}`:"Awaiting state…"})]})]})}function FB({deviceId:e}){const t=Te(),n=At(t.trpcClient,e),r=pn(n?.state.doorbell),s=r?.lastPressedAt??null,a=r!==void 0,i=s!==null&&Date.now()-s<6e4,[l,c]=_(0),[d,u]=_(null);return Y(()=>{s===null||s===d||(u(s),OB(s)&&c(p=>p+1))},[s,d]),f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 p-4",children:[o("div",{className:`flex h-24 w-24 items-center justify-center rounded-full border-2 transition-all ${i?"border-primary bg-primary/20 text-primary shadow-lg shadow-primary/30 animate-pulse":"border-border bg-surface text-foreground-subtle"}`,"aria-live":"polite",title:i?"Just pressed":"Idle",children:o(Jo,{className:"h-10 w-10"})}),f("div",{className:"text-center",children:[o("div",{className:`text-sm font-semibold ${i?"text-primary":"text-foreground-subtle"}`,children:a?`Last press ${ni(s)}`:"Unknown"}),o("div",{className:"text-[10px] text-foreground-subtle mt-0.5 tabular-nums",children:a?`${String(l)} ring${l===1?"":"s"} today`:"Awaiting state…"})]})]})}function jB({deviceName:e,deviceType:t,provider:n,isOnline:r,features:s}){return f("div",{className:"flex h-full w-full flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-border bg-surface p-6 text-center",children:[o(gn,{type:n,size:"lg"}),f("div",{children:[o("div",{className:"text-sm font-semibold text-foreground",children:e}),o("div",{className:"text-[10px] text-foreground-subtle uppercase tracking-wider mt-0.5",children:t})]}),f("div",{className:"flex items-center gap-2 flex-wrap justify-center",children:[o(ti,{status:r?"online":"offline"}),s.length>0&&o(Ja,{capabilities:s})]}),o("div",{className:"text-[10px] text-foreground-subtle italic max-w-xs mt-1",children:"No live view for this device type. Use the Config tab or the shortcut row to interact."})]})}function VB({deviceId:e}){const t=ke(),n=Hb({deviceId:e},{refetchInterval:1e4,retry:!1}),r=qb({onSuccess:()=>{t.invalidateQueries({queryKey:[["deviceDiscovery","listDiscovered"]]}),t.invalidateQueries({queryKey:[["deviceDiscovery","getStatus"]]})}}),s=H(()=>HB(n.data??[]),[n.data]);return f("div",{className:"flex h-full w-full flex-col gap-3 p-3 sm:p-4",children:[f("div",{className:"flex flex-wrap items-stretch gap-2 sm:gap-3",children:[o(ol,{label:"Discovered",value:s.total,icon:o($n,{className:"h-3.5 w-3.5"})}),o(ol,{label:"Adopted",value:s.adopted,accent:"success"}),o(ol,{label:"Available",value:s.available,accent:s.available>0?"primary":void 0}),f("button",{type:"button",onClick:()=>{r.mutateAsync({deviceId:e}).catch(()=>{})},disabled:r.isPending,className:"inline-flex items-center justify-center gap-1.5 rounded-lg border border-border px-3 py-2 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50 self-stretch shrink-0",children:[r.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(ct,{className:"h-3.5 w-3.5"}),o("span",{className:"hidden sm:inline",children:"Discover"})]})]}),f("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-foreground-subtle border-t border-border-subtle pt-2",children:[o(Es,{icon:o(or,{className:"h-3 w-3 text-emerald-500"}),label:`${s.online} online`}),o(Es,{icon:o(Z0,{className:"h-3 w-3 text-amber-500"}),label:`${s.sleeping} sleeping`}),o(Es,{icon:o(av,{className:"h-3 w-3 text-destructive"}),label:`${s.offline} offline`}),s.unknown>0?o(Es,{icon:o(GR,{className:"h-3 w-3 text-foreground-subtle"}),label:`${s.unknown} unknown`}):null]})]})}function HB(e){const t={total:e.length,adopted:0,available:0,online:0,sleeping:0,offline:0,unknown:0};for(const n of e)n.alreadyAdopted?t.adopted+=1:t.available+=1,t[n.status]+=1;return t}function ol({label:e,value:t,icon:n,accent:r}){return f("div",{className:`flex flex-1 basis-[140px] min-w-0 flex-col gap-1 rounded-lg border px-2 py-1.5 sm:px-3 sm:py-2 ${r==="success"?"bg-emerald-500/10 border-emerald-500/30 text-emerald-500":r==="primary"?"bg-primary/10 border-primary/30 text-primary":"bg-surface-hover border-border text-foreground"}`,children:[f("div",{className:"flex items-center gap-1.5 text-[10px] uppercase tracking-wider opacity-70 truncate",children:[n,o("span",{className:"truncate",children:e})]}),o("div",{className:"text-xl sm:text-2xl font-semibold tabular-nums leading-none",children:t})]})}function Es({icon:e,label:t}){return f("span",{className:"inline-flex items-center gap-1",children:[e,o("span",{children:t})]})}const qB=e=>o(Fv,{...e,useSiren:!0}),UB={[pt.Switch]:Fv,[pt.Siren]:qB,[pt.Light]:BB,[pt.Sensor]:zB,[pt.Button]:FB,[pt.Hub]:VB};function QB(e){const t=UB[e.deviceType]??jB;return o(t,{...e})}function eu(e){if(e<60)return`${Math.round(e)}s`;const t=Math.floor(e/60),n=Math.round(e%60);if(t<60)return n>0?`${t}m ${n}s`:`${t}m`;const r=Math.floor(t/60),s=t%60;return s>0?`${r}h ${s}m`:`${r}h`}function fa(e){return new Date(e).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function ha(e){return e.toISOString().slice(0,10)}function GB(e,t){return ha(e)===ha(t)}function fo(e){const t=new Date(e);return t.setHours(0,0,0,0),t}function KB(e){const t=new Date(e);return t.setHours(23,59,59,999),t}function Tt({className:e=""}){return o("div",{className:`animate-pulse rounded bg-foreground-subtle/10 ${e}`})}function Un(){return f("div",{className:"flex items-center gap-3 px-4 py-3",children:[o(Tt,{className:"h-4 w-4"}),o(Tt,{className:"h-3 w-24"}),o(Tt,{className:"h-3 w-16 ml-auto"})]})}function io({children:e,actions:t}){return f("div",{className:"border-b border-border px-4 py-2.5 flex items-center justify-between",children:[o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:e}),t]})}function If({icon:e,label:t,value:n}){return f("div",{className:"flex items-center gap-2",children:[o(e,{className:"h-3.5 w-3.5 text-foreground-subtle flex-shrink-0"}),f("div",{className:"min-w-0",children:[o("p",{className:"text-[10px] text-foreground-subtle leading-tight",children:t}),o("p",{className:"text-xs font-medium text-foreground leading-tight",children:n})]})]})}function WB({segments:e,selectedDate:t}){const n=fo(t).getTime(),r=1440*60*1e3,s=Array.from({length:25},(a,i)=>i);return f("div",{className:"space-y-1",children:[o("div",{className:"flex justify-between px-0.5",children:s.filter(a=>a%3===0).map(a=>o("span",{className:"text-[9px] text-foreground-subtle font-mono",children:String(a).padStart(2,"0")},a))}),f("div",{className:"relative h-6 rounded bg-background border border-border overflow-hidden",children:[e.map(a=>{const i=new Date(a.startTime).getTime()-n,l=new Date(a.endTime).getTime()-n,c=Math.max(0,i/r*100),d=Math.min(100-c,(l-i)/r*100);return d<=0?null:o("div",{className:"absolute top-0 bottom-0 bg-primary/60 hover:bg-primary/80 transition-colors",style:{left:`${c}%`,width:`${Math.max(d,.3)}%`},title:`${fa(a.startTime)} - ${fa(a.endTime)} (${eu(a.duration)})`},a.id)}),s.slice(1,-1).map(a=>o("div",{className:"absolute top-0 bottom-0 w-px bg-border/50",style:{left:`${a/24*100}%`}},a))]})]})}function YB({segment:e,selected:t,onToggle:n,onPlay:r,onDownload:s,onDelete:a}){return f("div",{className:`flex items-center gap-3 px-4 py-2 border-b border-border last:border-b-0 hover:bg-background/50 transition-colors ${t?"bg-primary/5":""}`,children:[o("button",{onClick:n,className:"flex-shrink-0 text-foreground-subtle hover:text-foreground",children:t?o(rv,{className:"h-4 w-4 text-primary"}):o(ts,{className:"h-4 w-4"})}),f("div",{className:"flex-1 min-w-0",children:[f("p",{className:"text-xs font-mono text-foreground",children:[fa(e.startTime)," - ",fa(e.endTime)]}),f("p",{className:"text-[10px] text-foreground-subtle",children:[eu(e.duration),e.sizeBytes!=null&&` · ${It(e.sizeBytes)}`]})]}),f("div",{className:"flex items-center gap-1 flex-shrink-0",children:[o("button",{onClick:r,title:"Play",className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Ya,{className:"h-3.5 w-3.5"})}),o("button",{onClick:s,title:"Download",className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Xt,{className:"h-3.5 w-3.5"})}),o("button",{onClick:a,title:"Delete",className:"p-1 rounded hover:bg-danger/10 text-foreground-subtle hover:text-danger transition-colors",children:o(Ze,{className:"h-3.5 w-3.5"})})]})]})}function ZB({deviceId:e}){const t=ke(),[n,r]=_(()=>fo(new Date)),[s,a]=_(new Set),i=Sy({deviceId:e},{refetchInterval:5e3}),l=wy({deviceId:e}),c=l.data?.streams[0]?.streamId??"stream0",d=Ny({deviceId:e,streamId:c,startTime:fo(n).getTime(),endTime:KB(n).getTime()}),u=ky({deviceId:e,streamId:c},{refetchInterval:3e4}),p=Cy({deviceId:e,dataCategory:"recording:main"}),h=U(()=>{t.invalidateQueries({queryKey:["recordingEngine","getPolicyStatus"]}),t.invalidateQueries({queryKey:["recordingEngine","getSegments"]}),t.invalidateQueries({queryKey:["recordingEngine","getStorageUsage"]})},[t]),m=yy({onSuccess:h}),g={isPending:m.isPending,error:m.error,mutate:()=>{const T=l.data,L=T?{mode:T.mode,streams:T.streams,enabled:!0,preBufferSec:T.preBufferSec,postBufferSec:T.postBufferSec,scheduleRules:T.scheduleRules}:{mode:"continuous",streams:[{streamId:c,mode:"always"}],enabled:!0,preBufferSec:10,postBufferSec:5};m.mutate({deviceId:e,policy:L})}},b=vy({onSuccess:h}),x=i.data??void 0,y=l.data??void 0,w=d.data??[],v=u.data,N=p.data??void 0,k=(x?.enabled??!1)&&(x?.activeStreams??0)>0,C=g.isPending||b.isPending,E=GB(n,new Date),I=H(()=>[...w].sort((T,L)=>new Date(L.startTime).getTime()-new Date(T.startTime).getTime()),[w]),A=H(()=>w.reduce((T,L)=>T+(L.duration??0),0),[w]),z=H(()=>w.reduce((T,L)=>T+(L.sizeBytes??0),0),[w]);function P(){k?b.mutate({deviceId:e}):g.mutate()}function B(){r(T=>{const L=new Date(T);return L.setDate(L.getDate()-1),fo(L)}),a(new Set)}function R(){E||(r(T=>{const L=new Date(T);return L.setDate(L.getDate()+1),fo(L)}),a(new Set))}function M(T){a(L=>{const O=new Set(L);return O.has(T)?O.delete(T):O.add(T),O})}function D(){s.size===I.length?a(new Set):a(new Set(I.map(T=>T.id)))}return i.isLoading&&l.isLoading?f("div",{className:"space-y-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Recording Status"}),f("div",{className:"px-4 py-4 space-y-3",children:[o(Tt,{className:"h-10 w-full"}),o(Tt,{className:"h-4 w-48"})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Segments"}),f("div",{className:"divide-y divide-border",children:[o(Un,{}),o(Un,{}),o(Un,{})]})]})]}):f("div",{className:"space-y-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:"Recording Status"}),f("div",{className:"px-4 py-4 flex items-center justify-between gap-4",children:[f("div",{className:"flex items-center gap-3 min-w-0",children:[o("div",{className:`flex items-center justify-center rounded-full p-2 flex-shrink-0 ${k?"bg-danger/10":"bg-foreground-subtle/10"}`,children:o(U0,{className:`h-5 w-5 ${k?"text-danger animate-pulse":"text-foreground-subtle"}`})}),f("div",{className:"min-w-0",children:[o("p",{className:`text-sm font-medium ${k?"text-danger":"text-foreground-subtle"}`,children:k?"Recording":"Not Recording"}),o("p",{className:"text-[11px] text-foreground-subtle mt-0.5 truncate",children:k&&x?`${x.mode} – ${x.activeStreams} stream(s)`:"No active recording session"})]})]}),o("button",{onClick:P,disabled:C,className:`inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors flex-shrink-0 disabled:opacity-50 ${k?"bg-danger/10 text-danger hover:bg-danger/20":"bg-primary text-primary-foreground hover:bg-primary/90"}`,children:k?f(me,{children:[o(ts,{className:"h-3.5 w-3.5"}),C?"Stopping...":"Stop Recording"]}):f(me,{children:[o(Ya,{className:"h-3.5 w-3.5"}),C?"Starting...":"Start Recording"]})})]}),k&&x&&f("div",{className:"border-t border-border px-4 py-2 flex items-center gap-2 text-[11px] text-foreground-subtle",children:[o(yo,{className:"h-3.5 w-3.5 text-primary flex-shrink-0"}),f("span",{children:[x.activeStreams," active stream",x.activeStreams!==1?"s":""," · mode: ",x.mode]})]})]}),f("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:f("span",{className:"flex items-center gap-1.5",children:[o(Jt,{className:"h-3.5 w-3.5"}),"Settings"]})}),l.isLoading?f("div",{className:"px-4 py-3 space-y-2",children:[o(Tt,{className:"h-3 w-32"}),o(Tt,{className:"h-3 w-40"}),o(Tt,{className:"h-3 w-28"})]}):f("div",{className:"divide-y divide-border",children:[o(lo,{label:"Stream",value:c}),o(lo,{label:"Pre-buffer",value:y?`${y.preBufferSec}s`:"N/A"}),o(lo,{label:"Mode",value:y?.mode??"continuous"}),o(lo,{label:"Retention",value:N?.retentionDays!=null?`${N.retentionDays} days`:"N/A"}),N?.retentionGb!=null&&o(lo,{label:"Max Storage",value:`${N.retentionGb} GB`})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[o(io,{children:f("span",{className:"flex items-center gap-1.5",children:[o(ia,{className:"h-3.5 w-3.5"}),"Storage"]})}),u.isLoading?f("div",{className:"px-4 py-3 space-y-2",children:[o(Tt,{className:"h-3 w-28"}),o(Tt,{className:"h-3 w-36"}),o(Tt,{className:"h-3 w-24"})]}):u.error?f("div",{className:"px-4 py-4 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4"}),"Failed to load storage info"]}):f("div",{className:"px-4 py-3 grid grid-cols-2 gap-3",children:[o(If,{icon:ia,label:"Total",value:v?.totalBytes!=null?It(v.totalBytes):"N/A"}),o(If,{icon:yo,label:"Segments",value:v?.segmentCount!=null?String(v.segmentCount):"N/A"})]})]})]}),f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"border-b border-border px-4 py-2.5 flex items-center justify-between",children:[o("h2",{className:"text-xs font-semibold text-foreground uppercase tracking-wider",children:"Segment Browser"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:B,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",children:o(Gd,{className:"h-4 w-4"})}),f("div",{className:"flex items-center gap-1.5 text-xs text-foreground font-medium",children:[o(H0,{className:"h-3.5 w-3.5 text-foreground-subtle"}),E?"Today":ha(n)]}),o("button",{onClick:R,disabled:E,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors disabled:opacity-30 disabled:cursor-not-allowed",children:o(wt,{className:"h-4 w-4"})})]})]}),f("div",{className:"px-4 py-3 border-b border-border",children:[o(WB,{segments:w,selectedDate:n}),f("div",{className:"flex items-center gap-4 mt-2 text-[10px] text-foreground-subtle",children:[f("span",{children:[w.length," segment",w.length!==1?"s":""]}),A>0&&f("span",{children:[eu(A)," recorded"]}),z>0&&o("span",{children:It(z)})]})]}),I.length>0&&f("div",{className:"border-b border-border px-4 py-2 flex items-center justify-between",children:[o("button",{onClick:D,className:"text-[11px] text-foreground-subtle hover:text-foreground transition-colors",children:s.size===I.length?"Deselect All":"Select All"}),s.size>0&&f("div",{className:"flex items-center gap-2",children:[f("span",{className:"text-[10px] text-foreground-subtle",children:[s.size," selected"]}),f("button",{className:"inline-flex items-center gap-1 rounded px-2 py-0.5 text-[10px] font-medium bg-foreground-subtle/10 text-foreground-subtle hover:text-foreground transition-colors",title:"Download selected",children:[o(Xt,{className:"h-3 w-3"}),"Download"]}),f("button",{className:"inline-flex items-center gap-1 rounded px-2 py-0.5 text-[10px] font-medium bg-danger/10 text-danger hover:bg-danger/20 transition-colors",title:"Delete selected",children:[o(Ze,{className:"h-3 w-3"}),"Delete"]})]})]}),d.isLoading?f("div",{className:"divide-y divide-border",children:[o(Un,{}),o(Un,{}),o(Un,{}),o(Un,{})]}):I.length===0?f("div",{className:"flex flex-col items-center justify-center py-12 text-foreground-subtle",children:[o(yo,{className:"h-8 w-8 mb-3 opacity-30"}),o("p",{className:"text-sm",children:"No recorded segments"}),o("p",{className:"text-xs mt-1 opacity-70",children:E?"Recorded clips will appear here as they are created":`No recordings found for ${ha(n)}`})]}):o("div",{className:"max-h-[400px] overflow-y-auto",children:I.map(T=>o(YB,{segment:T,selected:s.has(T.id),onToggle:()=>M(T.id),onPlay:()=>{},onDownload:()=>{},onDelete:()=>{}},T.id))})]}),i.error&&f("div",{className:"rounded-lg border border-danger/30 bg-danger/5 px-4 py-3 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4 flex-shrink-0"}),"Failed to load recording status. Will retry automatically."]}),(g.error||b.error)&&f("div",{className:"rounded-lg border border-danger/30 bg-danger/5 px-4 py-3 flex items-center gap-2 text-xs text-danger",children:[o(it,{className:"h-4 w-4 flex-shrink-0"}),g.error?`Failed to start recording: ${g.error instanceof Error?g.error.message:"Unknown error"}`:`Failed to stop recording: ${b.error instanceof Error?b.error.message:"Unknown error"}`]})]})}function lo({label:e,value:t}){return f("div",{className:"flex items-center justify-between px-4 py-2.5",children:[o("span",{className:"text-xs text-foreground-subtle",children:e}),o("span",{className:"text-xs font-medium text-foreground",children:t})]})}function XB({deviceId:e}){const t=ke(),n=Number.isFinite(e),{data:r}=er({deviceId:e},{enabled:n}),s=typeof r?.type=="string"?r.type:"camera";St(["deviceManager","getBindings"],["capability.binding-changed"]);const{data:a,isLoading:i,isError:l,error:c}=ex({deviceId:e},{staleTime:3e4,enabled:n}),{data:d}=nx({deviceType:s},{staleTime:3e4,enabled:!!s}),u=tx({onSuccess:()=>{t.invalidateQueries({queryKey:[["deviceManager","getBindings"]]})}});if(i)return o("div",{className:"p-4",children:o("div",{className:"h-20 rounded-lg border border-border bg-surface animate-pulse"})});if(l)return f("div",{className:"p-4 text-xs text-red-400",children:["Failed to load bindings: ",c instanceof Error?c.message:String(c)]});const p=new Map,h={};for(const b of d??[])h[b.capName]=b.wrappers;for(const b of a?.entries??[])p.set(b.capName,{...b,wrappers:h[b.capName]??[]});for(const b of d??[])p.has(b.capName)||p.set(b.capName,{capName:b.capName,kind:"unbound",providerAddonId:"",providerNodeId:"",nativeAddonId:"",wrappers:b.wrappers});const m=[...p.values()].sort((b,x)=>b.capName.localeCompare(x.capName));if(m.length===0)return f("div",{className:"flex flex-col items-center justify-center gap-2 p-8 text-foreground-subtle",children:[o(Wa,{className:"h-8 w-8 opacity-40"}),o("p",{className:"text-xs",children:"No capability providers applicable to this device yet."}),o("p",{className:"text-[10px] opacity-60",children:"Native providers show up here as soon as the owning addon registers them."})]});const g=m.filter(b=>b.kind!=="unbound").length;return f("div",{className:"flex flex-col gap-3 p-1",children:[f("div",{className:"text-[11px] text-foreground-subtle",children:[o("span",{className:"font-medium text-foreground",children:g})," ","of ",m.length," capabilit",m.length===1?"y":"ies"," bound — rows marked ",o("em",{children:"unbound"})," have a wrapper available you can activate."]}),o("div",{className:"overflow-hidden rounded-lg border border-border bg-surface",children:f("table",{className:"w-full border-collapse text-[11px]",children:[o("thead",{children:f("tr",{className:"bg-surface-hover/50 text-left text-[10px] uppercase tracking-wide text-foreground-subtle",children:[o("th",{className:"px-3 py-2 font-medium",children:"Capability"}),o("th",{className:"px-3 py-2 font-medium",children:"Kind"}),o("th",{className:"px-3 py-2 font-medium",children:"Active Provider"}),o("th",{className:"px-3 py-2 font-medium",children:"Node"}),o("th",{className:"px-3 py-2 font-medium",children:"Native"}),o("th",{className:"px-3 py-2 font-medium",children:"Wrapper"})]})}),o("tbody",{children:m.map(b=>{const x=b.kind==="wrapped"?b.providerAddonId:null;return f("tr",{className:"border-t border-border align-middle",children:[o("td",{className:"px-3 py-2 font-mono text-foreground",children:b.capName}),o("td",{className:"px-3 py-2",children:o(JB,{kind:b.kind})}),o("td",{className:"px-3 py-2 font-mono text-foreground-subtle",children:b.providerAddonId||o("span",{className:"opacity-40",children:"—"})}),o("td",{className:"px-3 py-2",children:b.providerNodeId?o(ez,{nodeId:b.providerNodeId}):o("span",{className:"text-[10px] opacity-40",children:"—"})}),o("td",{className:"px-3 py-2 font-mono text-foreground-subtle",children:b.nativeAddonId||o("span",{className:"opacity-40",children:"—"})}),o("td",{className:"px-3 py-2",children:o(tz,{wrappers:b.wrappers,activeWrapperId:x,disabled:u.isPending,onPick:y=>{const w=x===y;u.mutate({deviceId:e,capName:b.capName,wrapperAddonId:y,active:!w})}})})]},b.capName)})})]})})]})}function JB({kind:e}){return e==="native"?f("span",{className:"inline-flex items-center gap-1 rounded-md border border-success/30 text-success bg-success/5 px-1.5 py-0.5 text-[10px] font-medium",children:[o(hn,{className:"h-3 w-3"}),"native"]}):e==="wrapped"?f("span",{className:"inline-flex items-center gap-1 rounded-md border border-primary/30 text-primary bg-primary/5 px-1.5 py-0.5 text-[10px] font-medium",children:[o(C6,{className:"h-3 w-3"}),"wrapped"]}):f("span",{className:"inline-flex items-center gap-1 rounded-md border border-border text-foreground-subtle/70 px-1.5 py-0.5 text-[10px] font-medium",children:[o(H6,{className:"h-3 w-3"}),"unbound"]})}function ez({nodeId:e}){return o("span",{className:`inline-flex items-center rounded-md border border-border px-1.5 py-0.5 font-mono text-[10px] ${e==="hub"?"text-foreground-subtle":"text-foreground"}`,children:e})}function tz({wrappers:e,activeWrapperId:t,disabled:n,onPick:r}){return e.length===0?o("span",{className:"text-[10px] opacity-40",children:"none available"}):o("div",{className:"flex flex-wrap gap-1",children:e.map(s=>{const a=s===t;return f("button",{disabled:n,onClick:()=>r(s),title:a?"Click to deactivate (revert to native)":`Activate wrapper ${s}`,className:`inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 font-mono text-[10px] transition-colors disabled:opacity-50 ${a?"border-primary/40 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[a?o(_t,{className:"h-3 w-3"}):o(tv,{className:"h-3 w-3"}),s]},s)})})}function nz(e,t){if(!e)return null;for(const n of e.slots)for(const r of n.addons)if(r.id===t)return r;return null}function rz(e,t,n){const r=e?.stepOverridesByAgent?.[t]?.[n];if(r)return r.enabled===!1?"off":(r.enabled===!0,"on");const s=e?.stepToggles?.[n];return s===!1?"off":s===!0?"on":"inherit"}function oz({agents:e,currentAgent:t,onPick:n}){const[r,s]=_(!1);return f("div",{className:"relative",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:()=>s(a=>!a),children:"Mirror from ▾"}),r&&o("div",{className:"absolute top-full left-0 mt-1 min-w-[140px] bg-surface border border-border rounded shadow-lg z-10",children:e.filter(a=>a!==t).map(a=>o("button",{type:"button",className:"w-full text-left px-3 py-1.5 text-xs hover:bg-muted",onClick:()=>{s(!1),n(a)},children:a},a))})]})}function sz({deviceId:e,refreshToken:t}){const n=ke(),[r,s]=_(null),[a,i]=_(null),[l,c]=_(null),[d,u]=_(null),p=gd({deviceId:e}),h=Yr(),m=Fa({deviceId:e}),g=Yx(),b=H(()=>{const D=m.data?.agentNodeId;if(D)return D;const T=g.data?.find(L=>L.online)?.nodeId;return T||"hub"},[m.data?.agentNodeId,g.data]),x=a??b,y=Wo({nodeId:x??""},{enabled:!!x}),w=ly({onSuccess:()=>{n.invalidateQueries({queryKey:[["pipelineOrchestrator","getCameraSettings"]]}),c(null)}}),v=H(()=>y.data?Ta(y.data):[],[y.data]),N=H(()=>{const D=p.data??null,T={};for(const L of h.data??[])for(const O of Object.keys(L.settings.addonDefaults)){const F=T[O]??[];F.push({agentNodeId:L.nodeId,state:rz(D,L.nodeId,O)}),T[O]=F}return T},[p.data,h.data]),k=r?nz(y.data??null,r):null,C=x?h.data?.find(D=>D.nodeId===x)??null:null,E=r&&C?C.settings.addonDefaults[r]??null:null,I=r&&x?p.data?.stepOverridesByAgent?.[x]?.[r]??null:null,A=y.data?.selectedEngine.format??"coreml",z=D=>{i(D),c(null),u(null)},P=D=>{s(D),c(null),u(null)},B=D=>{if(!x||!r||!y.data||!h.data)return;const T=h.data.find(F=>F.nodeId===D),L=h.data.find(F=>F.nodeId===x);if(!T||!L)return;const[O]=Vm({source:{nodeId:T.nodeId,engine:{format:A},defaults:T.settings.addonDefaults},target:{nodeId:L.nodeId,engine:{format:A},defaults:L.settings.addonDefaults},catalog:y.data,addonIds:[r]});if(!O){u("no mirror result");return}if(O.outcome==="skip"){u(`skipped: ${O.reason??"no candidate"}`);return}c(O.patch),u(`${O.outcome} from ${D}`)},R=()=>{!x||!r||w.mutate({deviceId:e,agentNodeId:x,addonId:r,patch:l})},M=()=>{!x||!r||w.mutate({deviceId:e,agentNodeId:x,addonId:r,patch:null})};return h.isLoading||y.isLoading?o("div",{className:"text-xs text-foreground-subtle animate-pulse p-4",children:"Loading pipeline…"}):y.data?o("div",{className:"@container h-full",style:{containerType:"inline-size"},children:f("div",{className:"flex flex-col @[720px]:flex-row h-full",children:[o("aside",{className:"w-full @[720px]:w-[300px] @[720px]:flex-shrink-0 border-b @[720px]:border-b-0 @[720px]:border-r border-border overflow-y-auto max-h-[40vh] @[720px]:max-h-none",children:o(Lg,{tree:v,selectedAddonId:r,onSelect:P,agentDots:N})}),o("section",{className:"flex-1 min-w-0 p-4 overflow-y-auto",children:!r||!k?o("div",{className:"text-sm text-foreground-subtle",children:"Select a step on the left to configure it for this camera."}):f("div",{className:"space-y-4",children:[f("div",{children:[o("div",{className:"text-[10px] uppercase tracking-widest text-foreground-subtle",children:"Selected step"}),o("div",{className:"text-base font-semibold",children:k.name})]}),f("div",{className:"flex items-end gap-3 flex-wrap",children:[f("div",{children:[o("div",{className:"text-[10px] uppercase tracking-widest text-foreground-subtle mb-1",children:"Agent"}),o("div",{className:"flex rounded border border-border overflow-hidden",children:(h.data??[]).map(D=>o("button",{type:"button",onClick:()=>z(D.nodeId),className:`px-3 py-1 text-xs ${x===D.nodeId?"bg-primary text-primary-foreground":"bg-surface hover:bg-muted"}`,children:D.nodeId},D.nodeId))})]}),o(oz,{agents:(h.data??[]).map(D=>D.nodeId),currentAgent:x,onPick:B}),d&&o("div",{className:"text-[10px] text-foreground-subtle",children:d})]}),E&&o(Ra,{mode:"device",addon:k,agentDefault:E,agentNodeId:x??"",currentPatch:l??I,engineFormat:A,onChangePatch:c}),f("div",{className:"flex items-center justify-between gap-2 pt-4 border-t border-border",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted text-foreground-subtle",disabled:!I||w.isPending,onClick:M,children:"Clear override"}),f("div",{className:"flex items-center gap-2",children:[o("button",{type:"button",className:"px-3 py-1 text-xs border border-border rounded bg-surface hover:bg-muted",onClick:()=>c(null),children:"Reset draft"}),o("button",{type:"button",className:"px-3 py-1 text-xs bg-primary text-primary-foreground rounded disabled:opacity-50",disabled:!x||!r||w.isPending,onClick:R,children:w.isPending?"Saving…":"Save"})]})]})]})})]})}):o("div",{className:"text-xs text-foreground-subtle p-4",children:"Catalog unavailable."})}const az=[{id:"overview",label:"Overview",cameraOnly:!1},{id:"config",label:"Config",cameraOnly:!1},{id:"pipeline",label:"Pipeline",cameraOnly:!0},{id:"bindings",label:"Bindings",cameraOnly:!0},{id:"recording",label:"Recording",cameraOnly:!0}];function iz(e){const t=e===pt.Camera;return az.filter(n=>t||!n.cameraOnly).map(({id:n,label:r})=>({id:n,label:r}))}const lz=[{id:"logs",icon:at,label:"Logs"},{id:"repl",icon:ov,label:"REPL"},{id:"events",icon:Jo,label:"Events"},{id:"state",icon:Q0,label:"State"},{id:"ptz",icon:K6,label:"PTZ",featureGate:Wn.PanTiltZoom}];function cz(){const e=zd(),t=Number(e.deviceId),n=Number.isFinite(t),r=rt(),s=ke(),a=nt(),i=Te(),[l,c]=_("overview"),[d,u]=_("logs"),p="device-detail.left-col-width-px",[h,m]=_(()=>{if(typeof window>"u")return null;const de=window.localStorage.getItem(p),ce=de?Number(de):NaN;return Number.isFinite(ce)&&ce>0?ce:null}),g=te(h);g.current=h;function b(de){de.preventDefault();const ce=de.clientX,Ce=de.currentTarget.previousElementSibling?.getBoundingClientRect().width??h??0,pe=280,$e=Math.max(pe+50,Math.floor(window.innerWidth*.7)),Ae=dt=>{const yr=Math.max(pe,Math.min($e,Ce+(dt.clientX-ce)));m(yr)},Xe=()=>{document.removeEventListener("mousemove",Ae),document.removeEventListener("mouseup",Xe);const dt=g.current;if(dt!==null)try{window.localStorage.setItem(p,String(Math.round(dt)))}catch{}document.body.style.userSelect="",document.body.style.cursor=""};document.body.style.userSelect="none",document.body.style.cursor="col-resize",document.addEventListener("mousemove",Ae),document.addEventListener("mouseup",Xe)}const{data:x,isLoading:y,isError:w}=er({deviceId:t},{enabled:n,refetchInterval:5e3,retry:1}),{data:v}=cd({deviceId:t},{enabled:n,staleTime:3e4}),N=H(()=>{const de=v?.settings?.sections??[],ce=v?.live?.sections??[],Ce=[...de,...ce],pe=new Set;for(const Ae of Ce)Ae.location==="top-tab"&&Ae.tab&&pe.add(Ae.tab);return Ce.some(Do)&&pe.add(tl),[...pe].map(Ae=>{if(Ae===tl)return{id:Ae,label:pB,isAddonContrib:!0};const Xe=Nl[Ae];return{id:Ae,label:Xe?.label??Ae,isAddonContrib:!0}})},[v]),k=x,C=String(k?.name??e.deviceId??"Device"),E=k?.online===!0,I=E?"online":"offline",A=String(k?.addonId??"rtsp"),z=k?.features??[],P=k?.type,B=P===pt.Camera,R=typeof k?.parentDeviceId=="number"?k.parentDeviceId:null,{data:M}=er({deviceId:R??0},{enabled:R!==null,staleTime:3e4}),D=hr(),T=H(()=>[...iz(P),...N],[P,N]),{data:L}=Mv(n?t:0),O=(L??[]).length>0,F=H(()=>lz.filter(({featureGate:de})=>!de||z.includes(de)),[z]),{data:j}=lx({addonId:A},{enabled:!!A&&A!=="rtsp"}),V=Jb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]}),r(j?.id?`/integrations/${j.id}`:"/integrations")}}),$=Zb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),q=Xb({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),G=xy(),Z=Ko({onSuccess:()=>{s.invalidateQueries({queryKey:[["deviceManager"]]})}}),oe=z.includes(Wn.Rebootable),ne=z.includes(Wn.BatteryOperated),X=Yc(i.trpcClient,ne&&n?t:null),[re,be]=_(!1),J=At(i.trpcClient,n?t:null),W=async()=>{if(!(re||!J)){be(!0);try{await J.snapshot?.invalidateCache({});const de=await J.snapshot?.getSnapshot({});if(!de)return;const ce=`data:${de.contentType};base64,${de.base64}`,Ce=de.contentType.includes("png")?"png":"jpg",pe=C.replace(/[^a-zA-Z0-9_.-]+/g,"_"),$e=new Date().toISOString().replace(/[:.]/g,"-"),Ae=document.createElement("a");Ae.href=ce,Ae.download=`${pe}-${$e}.${Ce}`,document.body.appendChild(Ae),Ae.click(),document.body.removeChild(Ae)}finally{be(!1)}}},ee=$.isPending||q.isPending,{data:ae}=Fa({deviceId:t},{enabled:n,refetchInterval:1e4}),fe=ae?.agentNodeId??null,Q=typeof fe=="string"&&fe.length>0&&!fe.startsWith("addon:")?fe:void 0,{data:le}=bd({deviceId:t,...Q?{nodeId:Q}:{}},{enabled:n,refetchInterval:3e3,retry:!1});function ue(){if(!n)return null;switch(l){case"overview":return o(IB,{device:k??{}});case"config":return o(RB,{deviceId:t});case"pipeline":return o(sz,{deviceId:t,refreshToken:0});case"bindings":return o(XB,{deviceId:t});case"recording":return o(ZB,{deviceId:t});default:{const de=l;return N.some(Ce=>Ce.id===de)?de===tl?o(nc,{deviceId:t,sectionFilter:Do}):o(nc,{deviceId:t,sectionFilter:Ce=>Ce.location==="top-tab"&&Ce.tab===de}):null}}}return n?y?f("div",{className:"flex flex-col h-full",children:[f("div",{className:"border-b border-border bg-surface px-6 py-4",children:[o("div",{className:"h-4 w-48 rounded bg-surface-hover animate-pulse mb-3"}),o("div",{className:"h-8 w-64 rounded bg-surface-hover animate-pulse"})]}),o("div",{className:"flex-1 p-6",children:o("div",{className:"h-40 rounded-lg border border-border bg-surface animate-pulse"})})]}):w||!x?f("div",{className:"flex flex-col items-center justify-center h-full gap-3 text-foreground-subtle",children:[o("p",{className:"text-lg font-semibold text-foreground",children:"Device not found"}),f("p",{className:"text-xs",children:["No device with ID ",f("code",{className:"font-mono bg-surface px-1.5 py-0.5 rounded text-[11px]",children:["#",t]})]}),o("button",{onClick:()=>r("/integrations"),className:"mt-2 rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",children:"Back to Integrations"})]}):f("div",{className:"absolute inset-0 flex flex-col overflow-hidden",children:[f("div",{className:"border-b border-border bg-surface px-6 py-3 flex-shrink-0",children:[o("div",{className:"mb-2",children:o(Hc,{items:[{label:"Integrations",onClick:()=>r("/integrations")},{label:j?.name??A,onClick:()=>j?.id&&r(`/integrations/${j.id}`)},{label:C}]})}),f("div",{className:"flex items-center gap-2 sm:gap-3",children:[o(gn,{type:A,size:"lg"}),f("div",{className:"min-w-0 flex-1",children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("h1",{className:"text-sm sm:text-base font-semibold text-foreground truncate",children:C}),o(ti,{status:I}),ne&&o(Xc,{status:X,variant:"full"})]}),R!==null&&M&&f("button",{type:"button",onClick:()=>r(`/devices/${R}`),className:"text-[10px] text-foreground-subtle hover:text-primary transition-colors mt-0.5 inline-flex items-center gap-1",title:`Open parent device ${M.name}`,children:[o("span",{children:"↑"}),o("span",{className:"truncate",children:String(M.name??`Device #${R}`)})]}),o("div",{className:"hidden md:flex items-center gap-3 mt-0.5 text-[10px] text-foreground-subtle",children:z.length>0&&o(Ja,{capabilities:z})})]}),le&&o("div",{className:"hidden lg:flex",children:o(dz,{metrics:le})}),f("div",{className:"flex items-center gap-1 shrink-0",children:[f("button",{onClick:async()=>{await a({title:`Disable "${C}"?`,message:"The device will stop processing streams and events. You can re-enable it later.",confirmLabel:"Disable",variant:"danger"})&&q.mutate({deviceId:t})},disabled:ee,title:"Disable device",className:"inline-flex items-center gap-1.5 rounded-lg px-2 sm:px-2.5 py-1.5 text-[11px] font-medium border transition-colors disabled:opacity-50 border-success/30 text-success hover:bg-success/10",children:[o(ev,{className:"h-3.5 w-3.5"}),o("span",{className:"hidden sm:inline",children:ee?"Updating…":"Enabled"})]}),o("div",{className:"hidden sm:block h-5 w-px bg-border mx-1"}),o(y0,{triggerClassName:"ml-1",items:[{id:"snapshot",label:"Take snapshot",description:"Fetch a fresh frame and download it.",icon:Dr,disabled:re,onClick:()=>{W()}},{id:"reboot",label:"Reboot device",description:"Camera goes offline for ~30 seconds.",icon:kt,hidden:!oe,disabled:G.isPending,danger:!0,onClick:async()=>{await a({title:`Reboot "${C}"?`,message:"The camera will go offline for around 30 seconds while the firmware reboots.",confirmLabel:"Reboot",variant:"danger"})&&G.mutate({deviceId:t})}},{id:"restart-addon",label:"Restart addon",description:`Bounces every device served by ${j?.name??A}.`,icon:ct,disabled:Z.isPending,danger:!0,onClick:async()=>{await a({title:`Restart "${j?.name??A}"?`,message:`Restarting the addon will briefly disconnect every device served by it (not just "${C}"). Streams will reconnect automatically.`,confirmLabel:"Restart",variant:"danger"})&&Z.mutate({addonId:A})}},{id:"delete",label:"Delete device",description:"Remove the device and all its settings.",icon:Ze,separatorBefore:!0,disabled:V.isPending,danger:!0,onClick:async()=>{await a({title:`Delete "${C}"?`,message:"This will remove the device and all its settings. This action cannot be undone.",confirmLabel:"Delete",variant:"danger"})&&V.mutate({deviceId:t})}}]})]})]})]}),o(cb,{deviceId:t,device:k??void 0,children:o(Jy,{children:o(w0,{children:f("main",{className:D?"flex-1 overflow-y-auto flex flex-col":"flex-1 min-h-0 overflow-hidden flex flex-row",children:[f("div",{className:D?"flex flex-col bg-surface":`${h===null?"w-1/2 lg:w-1/3":""} flex-shrink-0 flex flex-col bg-surface min-h-0 overflow-hidden`,style:!D&&h!==null?{width:`${String(h)}px`}:void 0,children:[o("div",{className:`flex-shrink-0 border-b border-border-subtle ${B?"aspect-video bg-black":"bg-surface"}`,children:B?o(wB,{deviceId:t,intercomAvailable:z.includes(Wn.TwoWayAudio)}):o(QB,{deviceId:t,deviceName:C,deviceType:P??"unknown",provider:A,isOnline:E,features:z})}),f("div",{className:D?"flex flex-col border-b border-border":"flex-1 min-h-0 flex flex-col overflow-hidden",children:[o("div",{className:"flex-shrink-0 border-b border-border-subtle px-2 py-1.5",children:o("div",{className:"flex gap-1 overflow-x-auto -mx-1 px-1 pb-0.5",children:F.map(({id:de,label:ce,icon:Ce})=>f("button",{onClick:()=>u(de),title:ce,className:`flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium transition-colors flex-shrink-0 ${d===de?"bg-primary/15 text-primary":"text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[o(Ce,{className:"h-3 w-3"}),ce]},de))})}),f("div",{className:D?"h-72 overflow-hidden":"flex-1 min-h-0 overflow-hidden",children:[d==="logs"&&o(NB,{deviceId:t}),d==="repl"&&o(kB,{deviceId:t}),d==="events"&&o(CB,{deviceId:t}),d==="state"&&o(MB,{deviceId:t}),d==="ptz"&&o(SB,{deviceId:t})]})]})]}),!D&&o("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",onMouseDown:b,className:"flex-shrink-0 w-1 cursor-col-resize bg-border hover:bg-primary/40 transition-colors group relative z-10",children:o("span",{className:"absolute inset-y-0 -left-1 -right-1"})}),f("div",{className:D?"flex flex-col":"flex-1 min-w-0 min-h-0 flex flex-col overflow-hidden",children:[o("div",{className:"flex-shrink-0 border-b border-border bg-surface px-4",children:o("div",{className:"flex flex-wrap items-center gap-0",children:T.map(de=>{const ce=l===de.id;return f("button",{onClick:()=>c(de.id),className:`relative flex-shrink-0 px-3 py-2 text-xs font-medium transition-colors ${ce?"text-primary":"text-foreground-subtle hover:text-foreground"}`,children:[de.label,ce&&o("span",{className:"absolute bottom-0 left-0 right-0 h-0.5 rounded-full bg-primary"})]},de.id)})})}),f("div",{className:D?"p-3 flex flex-col gap-3":"flex-1 min-h-0 overflow-y-auto p-4 flex flex-col gap-3",children:[l==="overview"&&O&&o(EB,{parentDeviceId:t}),ue()]})]})]})})})})]}):f("div",{className:"flex flex-col items-center justify-center h-full gap-3 text-foreground-subtle",children:[o("p",{className:"text-lg font-semibold text-foreground",children:"Invalid device id"}),f("p",{className:"text-xs",children:["The URL segment ",o("code",{className:"font-mono bg-surface px-1.5 py-0.5 rounded text-[11px]",children:e.deviceId})," is not a number."]}),o("button",{onClick:()=>r("/integrations"),className:"mt-2 rounded-lg bg-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",children:"Back to Integrations"})]})}function dz({metrics:e}){const t=e.phase??"idle",n=ur(t);return f("div",{className:"flex items-center gap-3 flex-shrink-0",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:`h-1.5 w-1.5 rounded-full ${n.dotClass}`}),o("span",{className:`text-[10px] font-medium ${n.textColor}`,children:n.label})]}),o("div",{className:"h-3 w-px bg-border"}),f("div",{className:"flex items-center gap-1 text-[10px] text-foreground-subtle",children:[o(Xo,{className:"h-3 w-3"}),o("span",{className:"text-foreground tabular-nums",children:(e.actualFps??0).toFixed(1)}),o("span",{children:"fps"})]}),f("div",{className:"flex items-center gap-1 text-[10px] text-foreground-subtle",children:[o(bt,{className:"h-3 w-3"}),o("span",{className:"text-foreground tabular-nums",children:(e.avgInferenceTimeMs??0).toFixed(0)}),o("span",{children:"ms"})]}),(e.queueDepth??0)>0&&f("span",{className:"text-[10px] text-warning tabular-nums",children:["q:",e.queueDepth]})]})}function jv({packageName:e,currentVersion:t,installSource:n,onInstall:r,onClose:s}){const a=n==="upload"||n==="local",{data:i,isLoading:l}=yb({name:e},{staleTime:5*6e4});return f("div",{className:"fixed z-50 w-72 rounded-lg border border-border bg-surface shadow-xl overflow-hidden",style:{top:"auto",bottom:"auto"},ref:c=>{if(!c)return;const d=c.parentElement?.getBoundingClientRect();if(!d)return;const u=window.innerHeight-d.bottom,p=d.top;u<280&&p>u?(c.style.bottom=`${window.innerHeight-d.top+4}px`,c.style.top="auto"):(c.style.top=`${d.bottom+4}px`,c.style.bottom="auto"),c.style.right=`${window.innerWidth-d.right}px`},onClick:c=>c.stopPropagation(),children:[f("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border",children:[o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle font-medium",children:"Versions"}),o("button",{type:"button",onClick:s,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-3 w-3"})})]}),a&&f("div",{className:"flex items-start gap-2 px-3 py-2 border-b border-border bg-cyan-500/10 text-[10px]",children:[o(Xa,{className:"h-3 w-3 mt-0.5 text-cyan-500 shrink-0"}),f("div",{className:"text-cyan-700 dark:text-cyan-200",children:[f("span",{className:"font-semibold",children:[n==="upload"?"Uploaded copy":"Local copy"," in place."]})," ","Re-install ",o("span",{className:"font-mono",children:t})," from npm to track upstream releases again."]})]}),l&&f("div",{className:"flex items-center justify-center gap-2 py-6 text-[10px] text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Loading versions..."]}),i&&o("div",{className:"max-h-64 overflow-auto divide-y divide-border",children:i.map(c=>{const d=c.version===t,u=/-(alpha|beta|rc|dev|canary|next)/i.test(c.version);return f("div",{className:`flex items-center gap-2 px-3 py-2 text-[11px] ${d?"bg-primary/5":"hover:bg-surface-hover"} transition-colors`,children:[o("span",{className:`font-mono flex-1 ${d?"text-primary font-semibold":u?"text-amber-400":"text-foreground"}`,children:c.version}),c.distTags.map(p=>o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${p==="latest"?"bg-emerald-500/15 text-emerald-400":p==="beta"?"bg-amber-500/15 text-amber-400":"bg-gray-500/15 text-gray-400"}`,children:p},p)),c.deprecated&&o("span",{className:"text-[9px] text-red-400 line-through",children:"deprecated"}),o("span",{className:"text-[9px] text-foreground-subtle shrink-0",children:new Date(c.publishedAt).toLocaleDateString()}),d&&!a?o(_t,{className:"h-3 w-3 text-primary shrink-0"}):o("button",{type:"button",onClick:()=>r(c.version),className:"shrink-0 rounded p-0.5 hover:bg-primary/20 text-foreground-subtle hover:text-primary transition-colors",title:d?`Re-install ${c.version} from npm`:`Install ${c.version}`,children:o(Xt,{className:"h-3 w-3"})})]},c.version)})}),i&&i.length===0&&o("div",{className:"py-4 text-center text-[10px] text-foreground-subtle",children:"No versions found"})]})}const uz="device-export";function pz(e){return e.capabilities.some(t=>(typeof t=="string"?t:t.name)===uz)}function fz({isBundle:e,installSource:t,addonId:n,iconPath:r,color:s}){const[a,i]=_(!1),l=s?{backgroundColor:`${s.startsWith("#")?s:`#${s}`}26`}:void 0,c=e?"bg-indigo-500/20 text-indigo-700 dark:text-indigo-300":"bg-purple-500/20 text-purple-700 dark:text-purple-300",d=n&&r?`/api/addon-assets/${n}/${r}`:null,u=!!d&&!a;return f("div",{className:"relative flex-shrink-0",children:[o("div",{className:`h-9 w-9 rounded-lg flex items-center justify-center ${l?"":c}`,style:l,children:u?o("img",{src:d,alt:n,className:"h-5 w-5",onError:()=>i(!0)}):e?o(X0,{className:"h-4 w-4"}):o(la,{className:"h-4 w-4"})}),t==="local"&&o("span",{className:"absolute -top-1.5 -left-1.5 text-[7px] font-bold leading-none bg-orange-500 text-white px-1 py-0.5 rounded -rotate-12 shadow-sm",children:"DEV"}),t==="npm"&&o("span",{className:"absolute -top-1 -left-1 w-4 h-4 rounded bg-[#cb3837] flex items-center justify-center -rotate-12 shadow-sm",children:o("svg",{viewBox:"0 0 780 250",className:"w-[11px] h-[11px]",children:o("path",{fill:"#fff",d:"M240 250h100V50h100v200h340V0H0v250z"})})}),t==="upload"&&o("span",{className:"absolute -top-1.5 -left-1.5 flex items-center justify-center h-4 w-4 rounded bg-cyan-500 -rotate-12 shadow-sm",children:o(Xa,{className:"h-2.5 w-2.5 text-white"})})]})}function hz({addonId:e}){const t=ke(),{data:n="inherit"}=Nb({addonId:e},{staleTime:3e4}),r=kb({onSuccess:()=>{t.invalidateQueries({queryKey:[["addons","getAddonAutoUpdate"]]})}});return o("div",{className:"flex rounded-lg border border-border overflow-hidden text-[10px] font-medium",children:["inherit","off","latest","beta"].map(s=>o("button",{type:"button",onClick:a=>{a.stopPropagation(),r.mutate({addonId:e,channel:s})},disabled:r.isPending,className:`px-2.5 py-1 transition-colors capitalize ${n===s?s==="inherit"?"bg-gray-700/50 text-gray-700 dark:text-gray-300":s==="off"?"bg-gray-700 text-gray-700 dark:text-gray-300":s==="latest"?"bg-blue-500/20 text-blue-400":"bg-amber-500/20 text-amber-400":"bg-transparent text-foreground-subtle hover:bg-surface-hover"} ${s!=="inherit"?"border-l border-border":""}`,children:s},s))})}function oc({addon:e,agents:t=[],clusterStatus:n,hideVersion:r,availableUpdate:s,onUpdate:a,isUpdating:i,bundle:l}){const[c,d]=_(!1),[u,p]=_(!1),[h,m]=_(!1),[g,b]=_(!1),[x,y]=_(!1),[w,v]=_("logs"),N=ke(),k=nt(),{manifest:C}=e,E=e.installedOn??[],I=!l&&!C.protected&&C.removable!==!1,A=!!l,z=l?.displayName??C.name,P=l?.packageName??C.packageName,B=l?.version??C.packageVersion??C.version,R=l?.installSource??e.installSource,M=l?l.bundle?.description??l.addons[0]?.manifest.description:C.description;!l&&(C.components&&C.components.length>0||t.length>=2);const D=db({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["addonPages"]]}),N.invalidateQueries({queryKey:[["capabilities"]]})}}),T=Ko({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]})}}),L=rd({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["addonPages"]]}),N.invalidateQueries({queryKey:[["capabilities"]]}),N.invalidateQueries({queryKey:[["integrations"]]})}}),O=vb({onSuccess:()=>{N.invalidateQueries({queryKey:[["addons"]]}),N.invalidateQueries({queryKey:[["alerts"]]})}}),F=e.health,j=F?.phase==="failed"&&!F.inGracePeriod,V=j&&F?.nextRetryAt&&!F.retrying;return f("div",{className:`rounded-lg border bg-surface overflow-hidden ${j?"border-red-500/50":"border-border"}`,children:[j&&F&&f("div",{className:"bg-danger/10 border-b border-danger/30 px-4 py-2.5 flex items-start gap-2.5",children:[o(Z6,{className:"h-4 w-4 text-danger shrink-0 mt-0.5"}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"text-xs font-semibold text-danger",children:["Failed to load (attempt #",F.retryCount,")"]}),o("div",{className:"text-[11px] text-foreground mt-0.5 break-words font-mono",children:F.lastError?.message??"Unknown error"}),V&&F.nextRetryAt&&f("div",{className:"text-[10px] text-foreground-subtle mt-1",children:["Auto-retry at ",new Date(F.nextRetryAt).toLocaleTimeString()]})]}),f("button",{type:"button",disabled:O.isPending||F.retrying,onClick:$=>{$.stopPropagation(),O.mutate({packageName:P})},className:"inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-semibold border border-red-400/40 bg-red-400/10 text-red-700 dark:text-red-300 hover:bg-red-400/20 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0",title:"Reset retry counter and force immediate reload",children:[o(ct,{className:`h-3 w-3 ${O.isPending||F.retrying?"animate-spin":""}`}),"Retry now"]})]}),f("div",{className:"flex items-start gap-3 px-4 py-3",children:[o(fz,{isBundle:A||!!C.components&&C.components.length>1,installSource:R,addonId:A?l.addons[0]?.manifest.id:C.id,iconPath:A?l.bundle?.icon??l.addons[0]?.manifest.icon:C.icon,color:A?l.addons[0]?.manifest.color:C.color}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-semibold text-foreground truncate",children:z}),f("span",{className:"text-[10px] text-foreground-subtle font-mono shrink-0",children:["(",P,")"]}),A&&f("span",{className:"text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium shrink-0 inline-flex items-center gap-1",children:[o(X0,{className:"h-3 w-3"}),l.addons.length]})]}),M&&o("p",{className:"text-[10px] text-foreground-subtle mt-0.5 line-clamp-1",children:M}),!A&&e.process&&f("div",{className:"flex items-center gap-1.5 mt-1",children:[o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.mode==="forked"?"bg-blue-500/15 text-blue-400":"bg-gray-500/15 text-gray-400"}`,children:e.process.mode==="forked"?"forked":"in-process"}),e.process.pid!=null&&f("span",{className:"text-[9px] font-mono text-foreground-subtle",children:["PID ",e.process.pid]}),o("span",{className:`text-[9px] rounded-full px-1.5 py-0.5 font-medium ${e.process.state==="running"?"bg-emerald-500/15 text-emerald-400":e.process.state==="crashed"?"bg-red-500/15 text-red-400":"bg-gray-500/15 text-gray-400"}`,children:e.process.state})]})]}),!r&&f("div",{className:"relative inline-flex items-center gap-1.5 shrink-0 pt-0.5",children:[i?f("span",{className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-blue-500/30 bg-blue-500/10 text-blue-400",children:[o(Se,{className:"h-3 w-3 animate-spin"}),"Updating to ",s,"…"]}):s&&a?f("button",{type:"button",onClick:$=>{$.stopPropagation(),a()},className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-semibold border border-primary/40 bg-primary/10 text-primary hover:bg-primary/20 transition-colors animate-pulse",title:`Update to ${s}`,children:[o(Xt,{className:"h-3 w-3"}),s]}):null,f("button",{type:"button",onClick:$=>{$.stopPropagation(),m(q=>!q)},className:["inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-bold font-mono border transition-colors",R==="local"?"border-orange-500/30 bg-orange-500/10 text-orange-400 hover:bg-orange-500/20":s?"border-amber-500/30 bg-amber-500/10 text-amber-400 hover:bg-amber-500/20":"border-emerald-500/30 bg-emerald-500/10 text-emerald-400 hover:bg-emerald-500/20"].join(" "),title:s?`Current ${B} — newer ${s} available`:"View all versions",children:[B,o(lt,{className:"h-3 w-3 opacity-50"})]}),h&&o(jv,{packageName:P,currentVersion:B,...R?{installSource:R}:{},onInstall:$=>{m(!1),L.mutate({packageName:P,version:$})},onClose:()=>m(!1)})]})]}),!A&&f("div",{className:"flex items-center gap-1 px-4 py-1.5 border-t border-border/50 bg-surface-hover/20",children:[f("button",{type:"button",onClick:$=>{$.stopPropagation(),T.mutate({addonId:C.id})},disabled:T.isPending,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-blue-400 hover:border-blue-500/30 hover:bg-blue-500/10 disabled:opacity-50 transition-colors",children:[o(ct,{className:`h-3 w-3 ${T.isPending?"animate-spin":""}`}),"Restart"]}),f("button",{type:"button",onClick:$=>{$.stopPropagation(),b(q=>!q)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${g?"border-primary/30 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10"}`,children:[o(at,{className:"h-3 w-3"}),"Logs"]}),!A&&f("button",{type:"button",onClick:$=>{$.stopPropagation(),y(!0)},className:`inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border transition-colors ${x?"border-primary/30 bg-primary/10 text-primary":"border-border text-foreground-subtle hover:text-foreground hover:border-primary/30 hover:bg-primary/10"}`,children:[o(Jt,{className:"h-3 w-3"}),"Settings"]}),o("div",{className:"flex-1"}),I&&f("button",{type:"button",onClick:async $=>{$.stopPropagation(),await k({title:`Uninstall ${C.name}?`,message:"This will remove the addon package and all its data. This action cannot be undone.",confirmLabel:"Uninstall",variant:"danger"})&&D.mutate({packageName:C.packageName})},disabled:D.isPending,className:"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-medium border border-border text-foreground-subtle hover:text-red-400 hover:border-red-500/30 hover:bg-red-500/10 disabled:opacity-50 transition-colors",children:[o(Ze,{className:"h-3 w-3"}),D.isPending?"Removing...":"Uninstall"]})]}),n&&n.nodes.length>1&&!A&&f("div",{className:"border-t border-border px-4 py-2 bg-muted/10",children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle mb-1.5",children:"Cluster Deployment"}),o("div",{className:"space-y-1",children:n.nodes.map($=>f("div",{className:"flex items-center gap-2 text-[10px]",children:[o("div",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${$.status==="offline"?"bg-muted-foreground/30":$.synced?"bg-success":"bg-amber-500"}`}),o("span",{className:"font-medium text-foreground min-w-[60px]",children:$.name}),o("span",{className:"font-mono text-foreground-subtle",children:$.version}),!$.synced&&$.status!=="offline"&&o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-400 border border-amber-500/20",children:"outdated"}),$.status==="offline"&&o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-muted text-muted-foreground",children:"offline"}),$.synced&&$.status!=="offline"&&o("span",{className:"text-[9px] text-success",children:"synced"})]},$.nodeId))})]}),g&&!A&&f("div",{className:"border-t border-border",children:[f("div",{className:"flex items-center px-4 py-1 bg-surface-hover/20 border-b border-border/50",children:[f("div",{className:"flex rounded border border-border overflow-hidden text-[9px]",children:[o("button",{type:"button",onClick:()=>v("logs"),className:`px-2 py-0.5 transition-colors ${w==="logs"?"bg-primary/10 text-primary":"text-foreground-subtle hover:bg-surface-hover"}`,children:"Logs"}),o("button",{type:"button",onClick:()=>v("events"),className:`px-2 py-0.5 border-l border-border transition-colors ${w==="events"?"bg-primary/10 text-primary":"text-foreground-subtle hover:bg-surface-hover"}`,children:"Events"})]}),o("div",{className:"flex-1"}),o("button",{type:"button",onClick:$=>{$.stopPropagation(),b(!1)},className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-3.5 w-3.5"})})]}),w==="logs"&&o(tn,{addonId:C.id,maxHeight:"max-h-64",showFilters:!1}),w==="events"&&o(br,{addonId:C.id,category:"addon.*",maxHeight:"max-h-64"})]}),A&&f(me,{children:[o("button",{type:"button",onClick:()=>d($=>!$),className:"w-full flex items-center justify-center border-t border-border py-1 hover:bg-surface-hover/50 transition-colors",children:c?o(jR,{className:"h-3.5 w-3.5 text-foreground-subtle"}):o(lt,{className:"h-3.5 w-3.5 text-foreground-subtle"})}),c&&o("div",{className:"border-t border-border px-3 py-2 space-y-2",children:l.addons.map($=>o(oc,{addon:$,agents:t,hideVersion:!0},$.manifest.id))})]}),x&&!A&&o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-4",onClick:()=>y(!1),children:f("div",{className:"w-full max-w-lg max-h-[80vh] rounded-xl border border-border bg-surface shadow-2xl flex flex-col overflow-hidden",onClick:$=>$.stopPropagation(),children:[f("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border flex-shrink-0",children:[f("div",{className:"flex items-center gap-2",children:[o(Jt,{className:"h-4 w-4 text-primary"}),f("h2",{className:"text-sm font-semibold text-foreground",children:[z," Settings"]})]}),o("button",{onClick:()=>y(!1),className:"text-foreground-subtle hover:text-foreground transition-colors p-1 rounded",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"flex-1 overflow-y-auto px-5 py-4 space-y-4",children:[o(to,{nodeId:"hub",addonIds:[C.id],level:"global"}),pz(C)&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Device export"}),o(Md,{addonId:C.id})]}),R==="npm"&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Auto-Update"}),o(hz,{addonId:C.id})]}),C.components&&C.components.length>0&&f("div",{children:[f("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:["Components (",C.components.length,")"]}),o("div",{className:"flex flex-wrap gap-1",children:C.components.map($=>o("span",{className:"text-[10px] rounded bg-background border border-border px-1.5 py-0.5 text-foreground-subtle font-mono",children:$},$))})]}),t.length>=2&&f("div",{children:[o("div",{className:"text-[10px] font-medium text-foreground-subtle uppercase tracking-wide mb-2",children:"Installed on"}),f("div",{className:"flex items-center gap-1.5 flex-wrap",children:[E.length===0&&o("span",{className:"text-[10px] text-foreground-subtle",children:"Hub (local)"}),E.map($=>o("span",{className:"rounded-full bg-surface-hover border border-border px-2 py-0.5 text-[10px] text-foreground-subtle",children:$},$)),f("div",{className:"relative",children:[f("button",{type:"button",onClick:$=>{$.stopPropagation(),p(q=>!q)},className:"inline-flex items-center gap-1 rounded-full border border-dashed border-border px-2 py-0.5 text-[10px] text-foreground-subtle hover:text-foreground hover:border-primary transition-colors",title:"Install on more agents",children:[o(Et,{className:"h-3 w-3"}),"Add agent"]}),u&&f("div",{className:"absolute left-0 top-full mt-1 z-10 min-w-[160px] rounded-md border border-border bg-surface shadow-lg overflow-hidden",children:[t.filter($=>!$.isHub&&!E.includes($.name)).map($=>o("button",{type:"button",onClick:q=>{q.stopPropagation(),p(!1)},className:"w-full text-left px-3 py-1.5 text-[10px] text-foreground hover:bg-surface-hover transition-colors",children:$.name},$.id)),t.filter($=>!$.isHub&&!E.includes($.name)).length===0&&o("div",{className:"px-3 py-1.5 text-[10px] text-foreground-subtle",children:"No available agents"})]})]})]})]})]}),o("div",{className:"flex items-center justify-end px-5 py-3 border-t border-border flex-shrink-0",children:o("button",{type:"button",onClick:()=>y(!1),className:"rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors",children:"Close"})})]})})]})}const mz=".tgz,.tar.gz,.zip";function gz({onUploadSuccess:e}){const[t,n]=_(!1),r=te(null),s=U(async i=>{n(!0);const l=new FormData;l.append("file",i);const c=localStorage.getItem("camstack_admin_token")??"";try{(await(await fetch("/api/addons/upload",{method:"POST",headers:{Authorization:`Bearer ${c}`},body:l})).json()).success&&e()}finally{n(!1)}},[e]),a=U(i=>{const l=i.target.files?.[0];l&&s(l),i.target.value=""},[s]);return f(me,{children:[o("input",{ref:r,type:"file",accept:mz,onChange:a,className:"hidden"}),f("button",{type:"button",onClick:()=>r.current?.click(),disabled:t,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",children:[t?o(Se,{className:"w-3.5 h-3.5 animate-spin"}):o(Xa,{className:"w-3.5 h-3.5"}),t?"Uploading...":"Upload"]})]})}function bz(){const{data:e,isLoading:t,isError:n}=gb(void 0,{staleTime:6e4}),[r,s]=_(null),[a,i]=_(null),l=xb({onError:d=>{i(d instanceof Error?d.message:String(d))},onSuccess:()=>{s(null)}});if(t)return o(sl,{children:o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading system packages…"})});if(n)return o(sl,{children:o("div",{className:"text-xs text-danger",children:"Failed to load system packages"})});const c=e??[];return c.length===0?o(me,{}):f(me,{children:[o(sl,{collapsible:!0,defaultCollapsed:!0,children:o("div",{className:"space-y-1.5",children:c.map(d=>o(xz,{row:d,onUpdate:u=>s({packageName:d.packageName,fromVersion:d.currentVersion,toVersion:u})},d.packageName))})}),r!==null&&o(yz,{pending:r,onCancel:()=>{s(null),i(null)},onConfirm:()=>{i(null),l.mutate({packageName:r.packageName,version:r.toVersion})},isPending:l.isPending,error:a})]})}function sl({children:e,collapsible:t=!1,defaultCollapsed:n=!1}){const[r,s]=_(n),a=!t||!r,i=f("div",{className:"flex items-center gap-2",children:[t&&(r?o(wt,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"}):o(lt,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"})),o(it,{className:"w-3.5 h-3.5 text-amber-700 shrink-0"}),o("span",{className:"text-[11px] font-medium text-amber-800",children:"System packages"}),o("span",{className:"text-[10px] text-foreground-subtle",children:"Updating these will restart the hub (~10s)."})]});return f("div",{className:"rounded-md border border-amber-500/30 bg-amber-500/5 p-3 space-y-2",children:[t?o("button",{type:"button",onClick:()=>s(l=>!l),"aria-expanded":!r,className:"flex w-full items-center text-left",children:i}):i,a&&e]})}function xz({row:e,onUpdate:t}){const[n,r]=_(!1),s=e.hasUpdate&&e.latestVersion!==null;return f("div",{className:"flex items-center justify-between gap-3 px-2 py-1.5 rounded bg-surface/50 border border-border",children:[f("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[o("span",{className:"font-mono text-[11px] text-foreground truncate",children:e.packageName}),e.description!==void 0&&o("span",{className:"text-[10px] text-foreground-subtle truncate",title:e.description,children:e.description})]}),f("div",{className:"flex items-center gap-2 shrink-0",children:[s&&f("button",{type:"button",onClick:()=>t(e.latestVersion),className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] rounded bg-amber-500/15 text-amber-800 hover:bg-amber-500/25 border border-amber-500/30 font-medium transition-colors",title:`Update to ${e.latestVersion}`,children:[o(Xt,{className:"w-3 h-3"}),"v",e.latestVersion]}),f("button",{type:"button",onClick:()=>r(a=>!a),className:["inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-mono font-medium border transition-colors",s?"border-amber-500/30 bg-amber-500/10 text-amber-800 hover:bg-amber-500/20":"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 hover:bg-emerald-500/20"].join(" "),title:"View all versions",children:["v",e.currentVersion,o(lt,{className:"w-3 h-3 opacity-50"})]}),n&&o(jv,{packageName:e.packageName,currentVersion:e.currentVersion,onInstall:a=>{r(!1),t(a)},onClose:()=>r(!1)})]})]})}function yz({pending:e,onCancel:t,onConfirm:n,isPending:r,error:s}){return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60",children:f("div",{className:"bg-surface border border-border rounded-md shadow-xl p-5 max-w-md w-full mx-4 space-y-3",children:[f("div",{className:"flex items-center gap-2",children:[o(it,{className:"w-4 h-4 text-amber-700"}),o("h3",{className:"text-sm font-medium text-foreground",children:"Update system package?"})]}),f("div",{className:"space-y-2 text-[11px] text-foreground-subtle",children:[f("div",{children:[o("span",{className:"font-mono text-foreground",children:e.packageName}),o("span",{className:"mx-1",children:"·"}),f("span",{className:"font-mono",children:["v",e.fromVersion]}),o("span",{className:"mx-1",children:"→"}),f("span",{className:"font-mono text-amber-700",children:["v",e.toVersion]})]}),o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 p-2 text-amber-800",children:"The hub will restart immediately after the install. Any in-flight requests will be dropped. The reconnect typically takes ~10 seconds."}),s!==null&&o("div",{className:"rounded border border-danger/40 bg-danger/10 p-2 text-danger",children:s})]}),f("div",{className:"flex justify-end gap-2 pt-1",children:[o("button",{type:"button",onClick:t,disabled:r,className:"px-3 py-1.5 text-[11px] rounded bg-surface hover:bg-surface-hover border border-border disabled:opacity-50",children:"Cancel"}),f("button",{type:"button",onClick:n,disabled:r,className:"inline-flex items-center gap-1.5 px-3 py-1.5 text-[11px] rounded bg-amber-500/20 text-amber-800 hover:bg-amber-500/30 border border-amber-500/40 font-medium disabled:opacity-50",children:[r?o(Se,{className:"w-3 h-3 animate-spin"}):o(Xt,{className:"w-3 h-3"}),"Update & restart"]})]})]})})}function vz(e,t){const n=e??"hub-only";return n==="any-node"?!0:n==="hub-only"?t:!t}function wz(e){const t=e;if(!t?.manifest)return null;const n={...t.manifest,name:t.manifest.name??t.manifest.id,version:t.manifest.version??"0.0.0",capabilities:t.manifest.capabilities??[]},r=t.process,s=r?{pid:r.pid,mode:r.mode==="forked"?"forked":"in-process",state:r.state??"unknown"}:void 0,a=t.health,i=t.declaration?.execution,l=t.manifest.execution,c=i?.placement??l?.placement;return{manifest:n,enabled:!0,source:t.source,installSource:t.installSource,installedOn:[],...s?{process:s}:{},hasBackup:t.hasBackup,...a?{health:a}:{},...c?{placement:c}:{}}}function Nz(e){const t=new Map,n=[];for(const s of e){const a=s.manifest.packageName;if(!a){n.push(s);continue}const i=t.get(a);if(i)i.addons.push(s);else{const l=s.manifest.bundle,c={packageName:a,displayName:l?.displayName??s.manifest.packageDisplayName??s.manifest.name,version:s.manifest.packageVersion,addons:[s],...s.installSource!==void 0?{installSource:s.installSource}:{},...l!==void 0?{bundle:l}:{}};t.set(a,c)}}const r=[];for(const s of t.values())s.bundle!==void 0||s.addons.length>=2?r.push({bundle:s,representative:s.addons[0]}):r.push(s.addons[0]);return r.push(...n),r}function sn(e){return"bundle"in e}function kz({addons:e,clusterStatus:t,selectedNode:n,onRefresh:r,isRefreshing:s}){const a=ke(),[i,l]=_(""),c=d2(i),[d,u]=_(!1),p=te(null);Y(()=>{if(!d)return;const $=q=>{p.current&&!p.current.contains(q.target)&&u(!1)};return document.addEventListener("mousedown",$),()=>document.removeEventListener("mousedown",$)},[d]);const{data:h}=od({nodeId:n.id},{staleTime:5*6e4}),m=H(()=>{const $=new Map;for(const q of h??[])$.set(q.name,q.latestVersion);return $},[h]),[g,b]=_(null),[x,y]=_(null),w=Rl({onMutate:$=>{b($.name),y(null)},onSuccess:($,q)=>{b(null);const G=$;if(G&&G.success===!1){y({name:q.name,message:G.error??"Update failed (no error message returned by server)"});return}a.invalidateQueries({queryKey:[["addons"]]}),a.invalidateQueries({queryKey:[["addons","listUpdates"]]})},onError:($,q)=>{b(null),y({name:q.name,message:$ instanceof Error?$.message:String($)})}}),{data:v}=wb(void 0,{staleTime:3e4}),N=Sb({onSuccess:()=>{a.invalidateQueries({queryKey:[["addons","getAutoUpdateSettings"]]})}}),{data:k,isFetching:C}=pb({query:c||void 0},{enabled:d,staleTime:6e4}),E=Rl(),I=async()=>{const $=h??[];for(const q of $)await E.mutateAsync({name:q.name,version:q.latestVersion,nodeId:n.id});a.invalidateQueries({queryKey:[["addons"]]})},A=rd({onSuccess:()=>{a.invalidateQueries({queryKey:[["addons"]]}),a.invalidateQueries({queryKey:[["addonPages"]]}),a.invalidateQueries({queryKey:[["capabilities"]]}),a.invalidateQueries({queryKey:[["integrations"]]})}}),[z,P]=_("type"),[B,R]=_(()=>typeof window>"u"?"grouped":window.localStorage.getItem("camstack.addons.viewMode")==="flat"?"flat":"grouped"),M=$=>{R($),typeof window<"u"&&window.localStorage.setItem("camstack.addons.viewMode",$)},[D,T]=Ga(),L=D.get("capability"),O=H(()=>{let $=n.isHub?e:e.filter(q=>vz(q.placement,n.isHub));return L&&($=$.filter(q=>(q.manifest.capabilities??[]).some(Z=>(typeof Z=="string"?Z:Z.name)===L))),$},[e,n.isHub,L]),F=()=>{const $=new URLSearchParams(D);$.delete("capability"),T($,{replace:!0})},j=B==="flat"?O:Nz(O),V=H(()=>{const $=[...j];switch(z){case"type":$.sort((q,G)=>{const Z=sn(q)?0:1,oe=sn(G)?0:1;if(Z!==oe)return Z-oe;const ne=sn(q)?q.bundle.displayName:q.manifest.name,X=sn(G)?G.bundle.displayName:G.manifest.name;return ne.localeCompare(X)});break;case"name":$.sort((q,G)=>{const Z=sn(q)?q.bundle.displayName:q.manifest.name,oe=sn(G)?G.bundle.displayName:G.manifest.name;return Z.localeCompare(oe)});break;case"source":$.sort((q,G)=>{const Z=sn(q)?q.bundle.installSource??"":q.installSource??"",oe=sn(G)?G.bundle.installSource??"":G.installSource??"";return Z.localeCompare(oe)});break}return $},[j,z]);return f("div",{className:"space-y-4",children:[x&&o("div",{className:"rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-[11px]",children:f("div",{className:"flex items-start justify-between gap-3",children:[f("div",{className:"space-y-0.5",children:[f("div",{className:"font-medium text-danger",children:["Failed to update ",x.name]}),o("div",{className:"text-foreground-subtle font-mono",children:x.message})]}),o("button",{type:"button",onClick:()=>y(null),className:"text-foreground-subtle hover:text-foreground text-[10px]",children:"dismiss"})]})}),f("div",{className:"flex items-center gap-2 flex-wrap",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-[10px] text-foreground-subtle",children:"Sort:"}),f("select",{value:z,onChange:$=>P($.target.value),className:"rounded-md border border-border bg-surface px-2 py-1.5 text-[11px] text-foreground focus:outline-none focus:border-primary/50",children:[o("option",{value:"type",children:"Bundles first"}),o("option",{value:"name",children:"Name"}),o("option",{value:"source",children:"Install source"})]})]}),f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-[10px] text-foreground-subtle",children:"View:"}),o("div",{className:"flex rounded-md border border-border overflow-hidden text-[10px] font-medium",children:["grouped","flat"].map($=>o("button",{type:"button",onClick:()=>M($),className:`px-2.5 py-1.5 transition-colors capitalize ${B===$?"bg-primary/10 text-primary":"bg-transparent text-foreground-subtle hover:bg-surface-hover"}`,title:$==="grouped"?"Group multi-addon packages into a bundle card":"Show every addon as its own card",children:$},$))})]}),n.isHub&&f("div",{className:"flex items-center gap-1.5",children:[o(ct,{className:"h-3 w-3 text-foreground-subtle"}),o("span",{className:"text-[10px] text-foreground-subtle",children:"Auto-Update:"}),o("div",{className:"flex rounded-md border border-border overflow-hidden text-[10px] font-medium",children:["off","latest","beta"].map($=>o("button",{type:"button",onClick:()=>N.mutate({channel:$}),disabled:N.isPending,className:`px-2.5 py-1.5 transition-colors capitalize ${v?.channel===$?$==="off"?"bg-gray-700 text-gray-200":$==="latest"?"bg-blue-500/20 text-blue-400":"bg-amber-500/20 text-amber-400":"bg-transparent text-foreground-subtle hover:bg-surface-hover"} ${$!=="off"?"border-l border-border":""}`,children:$},$))})]}),(h?.length??0)>0&&f("button",{type:"button",onClick:()=>void I(),disabled:E.isPending,className:"flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 border border-blue-500/30 disabled:opacity-50 transition-colors font-medium",children:[o(Xt,{className:`w-3 h-3 ${E.isPending?"animate-bounce":""}`}),"Update All (",h.length,")"]}),f("button",{type:"button",onClick:r,disabled:s,className:"flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",children:[o(ct,{className:`w-3 h-3 ${s?"animate-spin":""}`}),"Refresh"]})]}),f("div",{className:"flex items-center gap-3",children:[f("div",{className:"relative flex-1 min-w-[200px]",ref:p,children:[o(nv,{className:"absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-foreground-subtle"}),o("input",{type:"text",value:i,onChange:$=>{l($.target.value),u(!0)},onFocus:()=>u(!0),placeholder:"Search addons on npm...",className:"w-full rounded-lg border border-border bg-background pl-9 pr-3 py-2 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"}),C&&o(Se,{className:"absolute right-2.5 top-1/2 -translate-y-1/2 h-3 w-3 text-foreground-subtle animate-spin"}),d&&k&&k.length>0&&f("div",{className:"absolute left-0 right-0 top-full mt-1 z-40 rounded-lg border border-border bg-surface shadow-xl overflow-hidden",children:[k.length>0&&f("div",{className:"px-3 py-1.5 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border",children:["npm results (",k.length,")"]}),k&&k.length>0&&o("div",{className:"max-h-72 overflow-auto divide-y divide-border",children:k.map($=>f("div",{className:"flex items-center gap-3 px-3 py-2 hover:bg-surface-hover transition-colors",children:[o("div",{className:"w-6 h-6 rounded-md bg-primary/10 flex items-center justify-center text-primary text-[9px] font-bold shrink-0",children:$.name.replace("@camstack/addon-","").charAt(0).toUpperCase()}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-[11px] font-semibold truncate",children:$.name}),f("span",{className:"text-[10px] text-foreground-subtle",children:["v",$.version]})]}),$.description&&o("div",{className:"text-[10px] text-foreground-subtle truncate",children:$.description})]}),$.installed?f("span",{className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md border border-emerald-500/30 bg-emerald-500/10 text-emerald-400 shrink-0",children:[o(_t,{className:"h-3 w-3"}),$.installedVersion??"Installed"]}):f("button",{type:"button",onClick:()=>A.mutate({packageName:$.name}),disabled:A.isPending,className:"inline-flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors shrink-0",children:[A.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xt,{className:"h-3 w-3"}),"Install"]})]},$.name))})]})]}),o(gz,{onUploadSuccess:()=>{a.invalidateQueries({queryKey:[["addons"]]}),r()}})]}),L&&f("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-primary/10 border border-primary/30 text-sm",children:[o("span",{className:"text-foreground-subtle",children:"Filtering by capability:"}),o("span",{className:"font-mono text-primary font-semibold",children:L}),o("button",{type:"button",onClick:F,className:"ml-auto text-xs text-foreground-subtle hover:text-foreground underline",children:"Clear"})]}),O.length===0&&o("div",{className:"text-xs text-foreground-subtle",children:e.length===0?"No addons installed":L?`No installed addons declare the "${L}" capability. Browse the npm catalog above to find a compatible addon.`:`No addons compatible with ${n.name} (placement filter active)`}),o("div",{className:"space-y-2",children:V.map($=>{if(sn($)){const Z=$.bundle.packageName,oe=m.get(Z);return o(oc,{addon:$.representative,clusterStatus:t?.[$.representative.manifest.id],bundle:$.bundle,availableUpdate:oe,isUpdating:g===Z,onUpdate:oe?()=>w.mutate({name:Z,version:oe,nodeId:n.id}):void 0},Z)}const q=$.manifest.packageName,G=m.get(q);return o(oc,{addon:$,clusterStatus:t?.[$.manifest.id],availableUpdate:G,isUpdating:g===q,onUpdate:G?()=>w.mutate({name:$.manifest.packageName,version:G,nodeId:n.id}):void 0},$.manifest.id)})})]})}function Sz(){const e=ke(),{data:t,isLoading:n,isError:r}=wn(),{data:s}=Ox(void 0,{staleTime:15e3}),{data:a}=zn(void 0,{staleTime:3e4,refetchInterval:1e4}),i=H(()=>{const x=new Map;x.set("hub",{id:"hub",name:"Hub",isHub:!0});for(const y of a??[]){const w=String(y.id??"");w&&x.set(w,{id:w,name:String(y.name??w),isHub:!!y.isHub})}return[...x.values()]},[a]),[l,c]=_("hub"),d=i.find(x=>x.id===l)??i[0],u=fb(),p=ub(),h=u.isPending||p.isPending,m=async()=>{await u.mutateAsync({nodeId:l}),await p.mutateAsync(),e.invalidateQueries({queryKey:[["addons"]]})},g=te(u);g.current=u,Y(()=>{g.current.mutate({nodeId:"hub"})},[]);const b=(t??[]).map(wz).filter(x=>x!==null);return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o(Bg,{selectedNodeId:l,onSelect:c}),f("div",{className:"flex items-center gap-3 flex-wrap",children:[!n&&!r&&f("span",{className:"text-[10px] rounded-full bg-primary/10 text-primary px-2 py-0.5 font-medium",children:[b.length," installed"]}),f("button",{type:"button",onClick:()=>void m(),disabled:h,className:"inline-flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] rounded-md bg-surface hover:bg-surface-hover border border-border disabled:opacity-50 transition-colors",title:"Re-fetch addons + check npm for new versions",children:[o(ct,{className:`w-3 h-3 ${h?"animate-spin":""}`}),"Check for updates"]})]})]}),!d.isHub&&f("div",{className:"rounded-md border border-warning/30 bg-warning/5 px-3 py-2 text-[11px] text-foreground-subtle",children:["Showing only addons compatible with"," ",o("span",{className:"font-medium text-foreground",children:d.name})," ","— agents only run ",o("code",{className:"font-mono",children:"agent-only"})," and"," ",o("code",{className:"font-mono",children:"any-node"})," addons. Install / uninstall is hub-driven; agents auto-sync from the hub."]}),n&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading…"}),r&&o("div",{className:"text-xs text-danger",children:"Failed to load addons"}),d.isHub&&o(bz,{}),!n&&!r&&o(kz,{addons:b,clusterStatus:s,selectedNode:d,onRefresh:()=>void m(),isRefreshing:h})]})}function Cz({value:e,size:t=192}){const[n,r]=_(null),[s,a]=_(null);if(Y(()=>{let d=!1;return E2(()=>import("./browser-BXdiCFWD.js").then(u=>u.b),[]).then(async u=>{if(d)return;const p=u.create;if(typeof p!="function"){a("qrcode.create() unavailable in installed version");return}try{const h=p(e,{errorCorrectionLevel:"M"});d||r(h)}catch(h){d||a(h instanceof Error?h.message:"QR generation failed")}}).catch(()=>{d||a("qrcode library not installed")}),()=>{d=!0}},[e]),s)return o("div",{className:"flex items-center justify-center text-[10px] text-foreground-subtle text-center p-4",style:{width:t,height:t},children:"QR rendering unavailable — use the secret below."});if(!n)return o("div",{className:"flex items-center justify-center text-[10px] text-foreground-subtle animate-pulse",style:{width:t,height:t},children:"Generating…"});const i=n.modules.size,l=t/i,c=[];for(let d=0;d<i;d++)for(let u=0;u<i;u++)n.modules.data[d*i+u]&&c.push(o("rect",{x:u*l,y:d*l,width:l,height:l,fill:"currentColor"},`${u}-${d}`));return f("svg",{width:t,height:t,viewBox:`0 0 ${t} ${t}`,className:"text-black",children:[o("rect",{x:0,y:0,width:t,height:t,fill:"white"}),c]})}const Mz={view:{icon:es,cls:"bg-foreground-subtle/15 text-foreground-subtle"},create:{icon:eo,cls:"bg-primary/15 text-primary"},delete:{icon:Ze,cls:"bg-danger/15 text-danger"}};function Ez(){const{user:e,logout:t}=nn();if(!e)return o(tt,{children:o("div",{className:"text-xs text-foreground-subtle",children:"Not signed in."})});const n=e.isAdmin,r=e.scopes??[];return f(tt,{children:[f("div",{className:"rounded-lg border border-border bg-surface px-4 py-3 flex items-center gap-3",children:[o("div",{className:"flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 text-primary font-semibold text-base",children:e.username.slice(0,1).toUpperCase()}),f("div",{className:"flex-1 min-w-0",children:[o("div",{className:"text-sm font-semibold text-foreground truncate",children:e.username}),f("div",{className:"text-[11px] text-foreground-subtle",children:[n?"Administrator":"User"," · session id ",f("span",{className:"font-mono",children:[e.id.slice(0,8),"…"]})]})]})]}),n&&f("div",{className:"rounded-lg border border-primary/30 bg-primary/5 px-4 py-3 text-xs text-foreground flex items-start gap-2.5",children:[o(rr,{className:"h-4 w-4 text-primary mt-0.5 shrink-0"}),f("div",{children:[o("div",{className:"font-semibold text-foreground",children:"Unrestricted access"}),o("p",{className:"text-foreground-subtle mt-0.5",children:"Admin sessions bypass the per-call scope check. Every protected endpoint is reachable regardless of the list below."})]})]}),o(Iz,{}),o(Az,{username:e.username}),r.length>0&&f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2 border-b border-border",children:[o("div",{className:"text-xs font-semibold text-foreground",children:"Granted scopes"}),o("div",{className:"text-[10px] text-foreground-subtle",children:"Baked into your session token at login; sign out + back in to refresh after changes."})]}),f("div",{className:"grid grid-cols-[100px_1fr_240px] gap-3 px-4 py-2 text-[10px] uppercase tracking-wide text-foreground-subtle border-b border-border",children:[o("div",{children:"Type"}),o("div",{children:"Target"}),o("div",{children:"Access"})]}),o("ul",{className:"divide-y divide-border",children:r.map((s,a)=>f("li",{className:"grid grid-cols-[100px_1fr_240px] gap-3 px-4 py-2.5 items-center text-xs",children:[o("span",{className:"font-mono text-foreground-subtle",children:s.type}),o("span",{className:"font-mono text-foreground",children:s.type==="device"?s.targets.join(", "):s.target}),o("div",{className:"flex items-center gap-1",children:["view","create","delete"].map(i=>{const l=s.access.includes(i),{icon:c,cls:d}=Mz[i];return f("span",{className:`inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] font-medium ${l?d:"bg-transparent text-foreground-subtle/40 line-through"}`,title:l?`Can ${i}`:`Cannot ${i}`,children:[o(c,{className:"h-3 w-3"}),i]},i)})})]},a))})]}),o("div",{className:"flex justify-end",children:f("button",{onClick:t,className:"inline-flex items-center gap-1.5 rounded border border-border px-2.5 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground transition-colors",children:[o(Zd,{className:"h-3 w-3"}),"Sign out"]})})]})}function Iz(){const e=Te(),[t,n]=_(""),[r,s]=_(""),[a,i]=_(""),[l,c]=_(null),d=Kn({mutationFn:m=>e.changeOwnPassword(m),onSuccess:()=>{c({kind:"success",msg:"Password updated."}),n(""),s(""),i("")},onError:m=>{c({kind:"error",msg:m instanceof Error?m.message:"Update failed"})}}),u=r.length>0&&a.length>0&&r!==a,p=r.length>0&&r.length<8,h=t.length>=1&&r.length>=8&&r===a;return f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2.5 border-b border-border flex items-center gap-2",children:[o(W0,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("div",{className:"text-xs font-semibold text-foreground",children:"Change password"})]}),f("div",{className:"p-4 space-y-3",children:[o(al,{label:"Current password",value:t,onChange:n,autoComplete:"current-password"}),o(al,{label:"New password",value:r,onChange:s,autoComplete:"new-password",hint:"At least 8 characters."}),o(al,{label:"Confirm new password",value:a,onChange:i,autoComplete:"new-password"}),(u||p)&&o("div",{className:"text-[11px] text-danger",children:u?"Passwords do not match.":"New password must be at least 8 characters."}),l&&f("div",{className:`text-[11px] flex items-center gap-1 ${l.kind==="success"?"text-emerald-500":"text-danger"}`,children:[l.kind==="success"?o(xo,{className:"h-3 w-3"}):o(nr,{className:"h-3 w-3"}),l.msg]}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{c(null),d.mutate({currentPassword:t,newPassword:r})},disabled:!h||d.isPending,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[d.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Yd,{className:"h-3 w-3"}),"Update password"]})})]})]})}function al({label:e,value:t,onChange:n,autoComplete:r,hint:s}){return f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:e}),o("input",{type:"password",value:t,onChange:a=>n(a.target.value),autoComplete:r,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"}),s&&o("div",{className:"text-[10px] text-foreground-subtle",children:s})]})}function Az({username:e}){const t=Te(),n=Ln({queryKey:["auth","getOwnTotpStatus"],queryFn:()=>t.getOwnTotpStatus()}),r=n.data,[s,a]=_(null),[i,l]=_(""),[c,d]=_(null),[u,p]=_(!1),h=Kn({mutationFn:()=>t.setupOwnTotp(),onSuccess:y=>{a({secret:y.secret,otpauthUrl:y.otpauthUrl}),l(""),d(null)},onError:y=>d(y instanceof Error?y.message:"Setup failed")}),m=Kn({mutationFn:y=>t.confirmOwnTotp(y),onSuccess:()=>{a(null),l(""),d(null),n.refetch()},onError:y=>d(y instanceof Error?y.message:"Confirmation failed — code did not match")}),g=Kn({mutationFn:()=>t.disableOwnTotp(),onSuccess:()=>{d(null),n.refetch()},onError:y=>d(y instanceof Error?y.message:"Disable failed")});Y(()=>{if(!u)return;const y=setTimeout(()=>p(!1),1500);return()=>clearTimeout(y)},[u]);const b=H(()=>n.isLoading?"loading":s?"setup_in_progress":r?.enabled?"enrolled":"not_enrolled",[n.isLoading,r?.enabled,s]),x=()=>{s&&navigator.clipboard.writeText(s.secret).then(()=>p(!0))};return f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"px-4 py-2.5 border-b border-border flex items-center gap-2",children:[o(An,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("div",{className:"text-xs font-semibold text-foreground",children:"Two-factor authentication"})]}),f("div",{className:"p-4 space-y-3",children:[b==="loading"&&f("div",{className:"flex items-center gap-2 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Checking status…"]}),b==="not_enrolled"&&f(me,{children:[o("div",{className:"text-xs text-foreground-subtle",children:"2FA isn't active on your account. Enable it to require a 6-digit code from your authenticator app at every login."}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{d(null),h.mutate()},disabled:h.isPending,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[h.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(An,{className:"h-3 w-3"}),"Enable 2FA"]})})]}),b==="setup_in_progress"&&s&&f(me,{children:[f("div",{className:"text-[11px] text-foreground-subtle",children:["Scan the QR code (or enter the secret manually) into your authenticator app for ",o("span",{className:"font-mono",children:e}),", then enter the 6-digit code below to confirm."]}),f("div",{className:"flex flex-col items-center gap-3",children:[o("div",{className:"rounded-lg border border-border bg-white p-3",children:o(Cz,{value:s.otpauthUrl,size:180})}),f("div",{className:"w-full",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle mb-1",children:"Secret (manual entry)"}),f("div",{className:"flex items-center gap-2 rounded border border-border bg-surface-hover/30 px-2 py-1.5",children:[o("code",{className:"text-[11px] font-mono text-foreground break-all flex-1",children:s.secret}),f("button",{onClick:x,className:"inline-flex items-center gap-1 text-[10px] text-foreground-subtle hover:text-foreground",children:[u?o(xo,{className:"h-3 w-3 text-emerald-500"}):o(aa,{className:"h-3 w-3"}),u?"Copied":"Copy"]})]})]})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"6-digit code"}),o("input",{type:"text",inputMode:"numeric",autoComplete:"one-time-code",placeholder:"123456",value:i,onChange:y=>l(y.target.value.replace(/\D/g,"").slice(0,6)),className:"w-full rounded-md border border-border bg-surface px-3 py-2 text-center text-lg font-mono tracking-widest text-foreground focus:outline-none focus:ring-2 focus:ring-primary"})]}),c&&f("div",{className:"text-[11px] text-danger flex items-center gap-1",children:[o(nr,{className:"h-3 w-3"}),c]}),f("div",{className:"flex justify-end gap-2",children:[o("button",{onClick:()=>{a(null),d(null),l("")},className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:()=>{d(null),m.mutate({code:i})},disabled:m.isPending||i.length!==6,className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[m.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(xo,{className:"h-3 w-3"}),"Confirm"]})]})]}),b==="enrolled"&&r&&f(me,{children:[f("div",{className:"rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5 flex items-start gap-2.5",children:[o(xo,{className:"h-4 w-4 mt-0.5 text-emerald-500 shrink-0"}),f("div",{className:"text-xs text-foreground space-y-0.5",children:[o("div",{className:"font-medium",children:"2FA is active"}),f("div",{className:"text-foreground-subtle",children:["Enrolled on ",r.confirmedAt?new Date(r.confirmedAt).toLocaleString():"—"]})]})]}),c&&f("div",{className:"text-[11px] text-danger flex items-center gap-1",children:[o(nr,{className:"h-3 w-3"}),c]}),o("div",{className:"flex justify-end",children:f("button",{onClick:()=>{d(null),g.mutate()},disabled:g.isPending,className:"rounded bg-danger px-3 py-1.5 text-xs font-medium text-white hover:bg-danger/90 disabled:opacity-50 inline-flex items-center gap-1",children:[g.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(An,{className:"h-3 w-3"}),"Disable 2FA"]})})]})]})]})}function Pz(){return o(tt,{children:o("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:o(tn,{limit:500,maxHeight:"max-h-[calc(100vh-250px)]",showScope:!0,showFilters:!0})})})}function ri({tabs:e,defaultTab:t}){const[n,r]=Ga(),s=n.get("tab"),a=t??e[0]?.id??"",i=e.some(d=>d.id===s)?s:a,l=e.find(d=>d.id===i)??e[0],c=d=>{const u=new URLSearchParams(n);u.set("tab",d),r(u,{replace:!0})};return f("div",{className:"space-y-3",children:[o("div",{className:"flex border-b border-border",children:e.map(d=>{const u=d.icon,p=d.id===i;return f("button",{onClick:()=>c(d.id),className:`flex items-center gap-1.5 px-3 py-2 text-xs font-medium border-b-2 transition-colors ${p?"border-primary text-primary":"border-transparent text-foreground-subtle hover:text-foreground"}`,children:[u&&o(u,{className:"h-3.5 w-3.5"}),d.label]},d.id)})}),o("div",{children:l?.content})]})}function _z({userId:e,username:t,onClose:n}){const r=ke(),s=nt(),a=Fy({userId:e}),i=a.data,l=()=>r.invalidateQueries({queryKey:[["userManagement","getTotpStatus"]]}),c=zy({onSuccess:()=>{l(),n()}}),d=a.isLoading?"loading":i?.enabled?"enrolled":"not_enrolled",u=async()=>{await s({title:"Remove 2FA",message:`Remove two-factor authentication for "${t}"? They'll be able to log in with just their password until they re-enroll from their own profile page.`,confirmLabel:"Remove",variant:"danger"})&&c.mutate({userId:e})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm p-4",children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl overflow-hidden",children:[f("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[f("div",{className:"flex items-center gap-2",children:[o(An,{className:"h-4 w-4 text-primary"}),f("div",{children:[o("div",{className:"text-sm font-medium text-foreground",children:"Two-factor authentication"}),f("div",{className:"text-[11px] text-foreground-subtle",children:["User: ",o("span",{className:"font-mono",children:t})]})]})]}),o("button",{onClick:n,className:"p-1 rounded hover:bg-foreground-subtle/10 text-foreground-subtle",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-4",children:[d==="loading"&&f("div",{className:"flex items-center gap-2 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3.5 w-3.5 animate-spin"}),"Checking status…"]}),d==="not_enrolled"&&f("div",{className:"rounded-md border border-border bg-surface-hover/30 px-3 py-2.5 flex items-start gap-2.5 text-xs text-foreground-subtle",children:[o(rr,{className:"h-4 w-4 mt-0.5 shrink-0"}),f("div",{children:[o("div",{className:"font-medium text-foreground",children:"2FA not enrolled"}),o("p",{className:"mt-0.5",children:"Only the user themselves can enable 2FA, from their own profile page."})]})]}),d==="enrolled"&&i&&f(me,{children:[f("div",{className:"rounded-md border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5 flex items-start gap-2.5",children:[o(xo,{className:"h-4 w-4 mt-0.5 text-emerald-500 shrink-0"}),f("div",{className:"text-xs text-foreground space-y-0.5",children:[o("div",{className:"font-medium",children:"2FA is active"}),f("div",{className:"text-foreground-subtle",children:["Enrolled on ",i.confirmedAt?new Date(i.confirmedAt).toLocaleString():"—"]})]})]}),o("div",{className:"text-[11px] text-foreground-subtle",children:"Removing here clears the server-side secret. Use this only when the user has lost access — they'll have to re-enroll from their profile page afterwards."}),f("div",{className:"flex justify-end gap-2",children:[o(Be,{onClick:n,variant:"secondary",children:"Close"}),f("button",{onClick:u,disabled:c.isPending,className:"rounded bg-danger px-3 py-1.5 text-xs font-medium text-white hover:bg-danger/90 disabled:opacity-50 inline-flex items-center gap-1",children:[c.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Fe,{className:"h-3 w-3"}),"Remove 2FA"]})]})]})]})]})})}function $z(){const e=ke(),{user:t}=nn(),[n,r]=_(!1),[s,a]=_(""),[i,l]=_(""),[c,d]=_(!1),[u,p]=_(null),{data:h,isLoading:m,isError:g}=vd(),b=nt(),x=()=>e.invalidateQueries({queryKey:[["userManagement","listUsers"]]}),y=Py({onSuccess:()=>{x(),r(!1),a(""),l(""),d(!1),p(null)},onError:D=>{p(D instanceof Error?D.message:"Failed to create user")}}),w=$y({onSuccess:x}),v=_y({onSuccess:x}),N=wd({onSuccess:x}),k=Dy({onSuccess:()=>{x(),E(null)}}),[C,E]=_(null),[I,A]=_(null),z=h??[];async function P(D){await b({title:"Delete user",message:`Permanently delete user "${D.username}"? This cannot be undone — any active sessions will be revoked on next request.`,confirmLabel:"Delete",variant:"danger"})&&w.mutate({id:D.id})}async function B(D){const T=window.prompt(`New password for "${D.username}":`);if(!T)return;if(T.length<8){window.alert("Password must be at least 8 characters.");return}await b({title:"Reset password",message:`Reset the password for "${D.username}"? They will need to use the new password on their next login.`,confirmLabel:"Reset"})&&N.mutate({id:D.id,newPassword:T})}function R(D,T){T!==D.isAdmin&&v.mutate({id:D.id,isAdmin:T})}function M(D){return D?new Date(typeof D=="number"?D:String(D)).toLocaleDateString("en-GB",{day:"2-digit",month:"short",year:"numeric"}):"—"}return f(tt,{children:[o("div",{className:"flex items-center justify-end",children:f("button",{onClick:()=>r(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground shadow-sm hover:bg-primary/90",children:[o(Et,{className:"h-3.5 w-3.5"}),"Create User"]})}),n&&f("div",{className:"rounded-lg border border-border bg-surface p-4 space-y-3",children:[f("div",{className:"flex items-center justify-between",children:[o("span",{className:"text-xs font-medium text-foreground",children:"New User"}),o("button",{onClick:()=>r(!1),className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"grid grid-cols-3 gap-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Username"}),o("input",{type:"text",value:s,onChange:D=>a(D.target.value),placeholder:"john",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Password"}),o("input",{type:"password",value:i,onChange:D=>l(D.target.value),placeholder:"••••••••",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Admin"}),f("label",{className:"flex items-center gap-2 rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground cursor-pointer",children:[o("input",{type:"checkbox",checked:c,onChange:D=>d(D.target.checked),className:"rounded border-border focus:ring-primary"}),o("span",{className:"text-foreground-subtle",children:"Unrestricted access"})]})]})]}),u&&o("p",{className:"text-[10px] text-danger",children:u}),f("div",{className:"flex justify-end gap-2",children:[o("button",{onClick:()=>r(!1),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),o("button",{onClick:()=>y.mutate({username:s,password:i,isAdmin:c}),disabled:y.isPending||!s||!i,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:y.isPending?"Creating...":"Create"})]})]}),m&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading..."}),g&&o("div",{className:"text-xs text-danger",children:"Failed to load"}),!m&&!g&&z.length===0&&o("div",{className:"text-xs text-foreground-subtle",children:"No data"}),(()=>{const D=L=>w.isPending&&w.variables?.id===L.id||v.isPending&&v.variables?.id===L.id||N.isPending&&N.variables?.id===L.id;return o(Da,{columns:[{key:"username",header:"Username",render:L=>L.username},{key:"isAdmin",header:"Admin",render:L=>f("label",{className:"inline-flex items-center gap-1.5 text-xs cursor-pointer",children:[o("input",{type:"checkbox",checked:L.isAdmin,onChange:O=>R(L,O.target.checked),disabled:D(L),className:"rounded border-border focus:ring-primary disabled:opacity-50"}),o("span",{className:L.isAdmin?"text-primary font-medium":"text-foreground-subtle",children:L.isAdmin?"Admin":"Regular"})]})},{key:"scopes",header:"Scopes",render:L=>{if(L.isAdmin)return o("span",{className:"text-[10px] text-foreground-subtle italic",children:"unscoped"});const O=L.scopes??[];return f("button",{onClick:()=>E(L),className:"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground",title:"Edit scope grants",children:[o(mn,{className:"h-3 w-3"}),O.length===0?"no access":`${O.length} grant${O.length===1?"":"s"}`]})}},{key:"createdAt",header:"Created",render:L=>o("span",{className:"text-foreground-subtle",children:M(L.createdAt)})},{key:"actions",header:"Actions",align:"right",render:L=>{const O=D(L),F=L.id!==t?.id&&L.totpEnabled;return f("div",{className:"flex items-center justify-end gap-1",children:[F&&f("button",{onClick:()=>A(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground disabled:opacity-50",title:"Remove two-factor authentication",children:[o(An,{className:"h-3 w-3"}),"Remove 2FA"]}),f("button",{onClick:()=>B(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-foreground-subtle hover:bg-foreground-subtle/10 hover:text-foreground disabled:opacity-50",title:"Reset password",children:[o(k6,{className:"h-3 w-3"}),"Reset password"]}),f("button",{onClick:()=>P(L),disabled:O,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",title:"Delete user",children:[O?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Delete"]})]})}}],rows:z,rowKey:L=>L.id,minWidthPx:560})})(),I&&o(_z,{userId:I.id,username:I.username,onClose:()=>A(null)}),C&&o(Dz,{user:C,onClose:()=>E(null),onSubmit:D=>k.mutate({userId:C.id,scopes:D}),submitting:k.isPending})]})}function Dz(e){const{user:t}=nn(),n=t?.isAdmin===!0;return o(Tz,{...e,callerScopes:n?null:t?.scopes??[]})}function Tz({user:e,onClose:t,onSubmit:n,submitting:r,callerScopes:s}){const a=H(()=>(e.scopes??[]).map(d=>({...d,access:[...d.access]})),[e.scopes]),[i,l]=_(a),c=Dd(i);return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:f("div",{className:"w-full max-w-2xl rounded-lg border border-border bg-surface shadow-xl",children:[f("div",{className:"flex items-center justify-between border-b border-border px-4 py-3",children:[f("div",{children:[f("div",{className:"text-sm font-semibold text-foreground",children:["Edit scopes — ",e.username]}),o("div",{className:"text-[10px] text-foreground-subtle",children:e.isAdmin?"Admin users bypass the scope check; this list is ignored.":"Pick which capabilities this user can call, and which access flavours within each."})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"px-4 py-4",children:[o($d,{value:i,onChange:l,clampToParent:s,emptyHint:f(me,{children:["No scopes granted. ",o("span",{className:"font-medium text-foreground",children:e.username})," cannot call any protected endpoint until a scope is added."]})}),c&&o("p",{className:"mt-2 text-[10px] text-danger",children:c})]}),f("div",{className:"flex items-center justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),o("button",{onClick:()=>n(i),disabled:r||c!==null,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:r?o(Se,{className:"h-3 w-3 animate-spin"}):"Save scopes"})]})]})})}const Lz="bg-primary/10 text-primary",Rz="bg-foreground-subtle/10 text-foreground-subtle";function ko(e){if(!e)return"—";const t=new Date(e);return Number.isNaN(t.getTime())?"—":t.toLocaleString()}function Oz(e){return e?e==="*"?"*":e.join(", "):""}function Bz(){const e=ke(),t=nt(),{data:n,isLoading:r}=Ty(),{data:s}=vd(),a=H(()=>n??[],[n]),i=H(()=>s??[],[s]),l=()=>e.invalidateQueries({queryKey:[["userManagement","listApiKeys"]]}),c=()=>e.invalidateQueries({queryKey:[["userManagement","listScopedTokens"]]}),[d,u]=_(!1),[p,h]=_(null),m=Ly({onSuccess:l}),g=Ry({onSuccess:({token:w,record:v})=>{c(),u(!1),h({token:w,label:v.name})}}),b=Oy({onSuccess:c}),x=async(w,v)=>{await t({title:`Revoke "${v}"?`,message:"Any client using this token will lose access immediately. This cannot be undone.",confirmLabel:"Revoke",variant:"danger"})&&m.mutate({id:w})},y=async(w,v)=>{await t({title:`Revoke "${v}"?`,message:"The scoped token will be invalid on its next use.",confirmLabel:"Revoke",variant:"danger"})&&b.mutate({id:w})};return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o("p",{className:"text-xs text-foreground-subtle max-w-2xl",children:"Issue scoped tokens to grant a user a narrow surface — a specific addon, integration, or capability. Every token MUST be scoped: revoking it has predictable blast radius."}),f("button",{onClick:()=>u(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",disabled:i.length===0,title:i.length===0?"Create a user first":"Issue a scoped token",children:[o(mn,{className:"h-3.5 w-3.5"}),"New token"]})]}),f(Af,{title:"Scoped tokens",subtitle:"Grouped per user",children:[i.length===0&&o(Fz,{text:"No users yet — scoped tokens are issued on behalf of an existing user."}),i.map(w=>o(jz,{userId:w.id,username:w.username,onRevoke:(v,N)=>{y(v,N)},revokePending:b.isPending,revokeId:b.variables?.id},w.id))]}),a.length>0&&o(Af,{title:"Legacy API keys",subtitle:`${a.length} pre-existing — revoke only`,children:o(Vv,{headers:["Label","Admin","Prefix","Allowed providers","Created","Last used",""],rows:a.map(w=>{const v=!!w.isAdmin,N=m.isPending&&m.variables?.id===w.id;return f("tr",{className:"hover:bg-primary/5",children:[o("td",{className:"px-3 py-2 text-foreground border-b border-border font-medium",children:w.label}),o("td",{className:"px-3 py-2 text-foreground border-b border-border",children:o("span",{className:`inline-block rounded px-2 py-0.5 text-[10px] uppercase tracking-wide ${v?Lz:Rz}`,children:v?"admin":"regular"})}),f("td",{className:"px-3 py-2 text-foreground border-b border-border font-mono text-[11px]",children:[w.tokenPrefix,"…"]}),o("td",{className:"px-3 py-2 text-foreground border-b border-border text-foreground-subtle",children:Oz(w.allowedProviders)||"all"}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(w.createdAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(w.lastUsedAt)}),o("td",{className:"px-3 py-2 border-b border-border text-right",children:f("button",{onClick:()=>{x(w.id,w.label)},disabled:N,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",title:"Revoke",children:[N?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Revoke"]})})]},w.id)})})}),r&&o(zz,{}),d&&o(Vz,{users:i.map(w=>({id:w.id,username:w.username})),onClose:()=>u(!1),onSubmit:w=>g.mutate({userId:w.userId,name:w.name,scopes:w.scopes,...w.expiresAt!==void 0?{expiresAt:w.expiresAt}:{}}),submitting:g.isPending}),p&&o(Hz,{token:p.token,label:p.label,onClose:()=>h(null)})]})}function Af({title:e,subtitle:t,children:n}){return f("div",{className:"space-y-2",children:[f("div",{className:"flex items-baseline justify-between",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e}),t&&o("span",{className:"text-[10px] text-foreground-subtle",children:t})]}),n]})}function zz(){return o("div",{className:"space-y-2",children:[1,2].map(e=>o("div",{className:"h-10 rounded border border-border bg-surface animate-pulse"},e))})}function Fz({text:e}){return o("div",{className:"rounded border border-dashed border-border bg-surface px-3 py-4 text-xs text-foreground-subtle text-center",children:e})}function Vv({headers:e,rows:t}){return o("div",{className:"rounded-lg border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{children:o("tr",{children:e.map((n,r)=>o("th",{className:`px-3 py-2 text-foreground-subtle font-medium bg-surface border-b border-border whitespace-nowrap ${r===e.length-1?"text-right":"text-left"}`,children:n},r))})}),o("tbody",{children:t})]})})}function jz({userId:e,username:t,onRevoke:n,revokePending:r,revokeId:s}){const{data:a,isLoading:i}=By({userId:e}),l=a??[];return i||l.length===0?null:f("div",{className:"space-y-1.5",children:[o("div",{className:"text-[11px] font-medium text-foreground",children:t}),o(Vv,{headers:["Name","Prefix","Scopes","Expires","Last used","Created",""],rows:l.map(c=>{const d=r&&s===c.id;return f("tr",{className:"hover:bg-primary/5",children:[o("td",{className:"px-3 py-2 text-foreground border-b border-border font-medium",children:c.name}),f("td",{className:"px-3 py-2 text-foreground border-b border-border font-mono text-[11px]",children:[c.tokenPrefix,"…"]}),o("td",{className:"px-3 py-2 text-foreground border-b border-border",children:o("div",{className:"flex flex-wrap gap-1",children:c.scopes.map((u,p)=>f("span",{className:"inline-block rounded bg-foreground-subtle/10 px-1.5 py-0.5 text-[10px] font-mono",children:[u.type,":",u.type==="device"?`[${u.targets.join(",")}]`:u.target]},p))})}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.expiresAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.lastUsedAt)}),o("td",{className:"px-3 py-2 text-foreground-subtle border-b border-border",children:ko(c.createdAt)}),o("td",{className:"px-3 py-2 border-b border-border text-right",children:f("button",{onClick:()=>n(c.id,c.name),disabled:d,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] text-danger hover:bg-danger/10 disabled:opacity-50",children:[d?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"}),"Revoke"]})})]},c.id)})})]})}function Vz({users:e,onClose:t,onSubmit:n,submitting:r}){const{user:s}=nn(),i=s?.isAdmin===!0?null:s?.scopes??[],[l,c]=_(e[0]?.id??""),[d,u]=_(""),[p,h]=_([{type:"capability",target:"",access:["view","create"]}]),[m,g]=_(""),b=Dd(p),x=l!==""&&d.trim().length>0&&p.length>0&&b===null&&!r,y=()=>{const w=parseInt(m,10),v=Number.isFinite(w)&&w>0?Date.now()+w*864e5:void 0;n({userId:l,name:d.trim(),scopes:p,expiresAt:v})};return f(Hv,{title:"Create scoped token",onClose:t,children:[f("div",{className:"space-y-3",children:[o(Is,{label:"On behalf of user",children:o("select",{value:l,onChange:w=>c(w.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary",children:e.map(w=>o("option",{value:w.id,children:w.username},w.id))})}),o(Is,{label:"Name",children:o("input",{value:d,onChange:w=>u(w.target.value),placeholder:"cloudflare-tunnel-route",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary"})}),f(Is,{label:"Scopes",hint:"Each scope picks a (cap or addon) target + one or more access flavours. The token can access ONLY what's listed.",children:[o($d,{value:p,onChange:h,clampToParent:i}),b&&o("p",{className:"mt-1 text-[10px] text-danger",children:b})]}),o(Is,{label:"Expires in (days)",hint:"Leave blank for non-expiring.",children:o("input",{type:"number",min:1,value:m,onChange:w=>g(w.target.value),placeholder:"30",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-primary"})})]}),f(qv,{children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:y,disabled:!x,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[r?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(mn,{className:"h-3.5 w-3.5"}),"Issue token"]})]})]})}function Hz({token:e,label:t,onClose:n}){const[r,s]=_(!1),a=async()=>{try{await navigator.clipboard.writeText(e),s(!0)}catch{}};return f(Hv,{title:`Token: ${t}`,onClose:n,children:[f("div",{className:"space-y-3",children:[o("div",{className:"rounded border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning",children:"Copy this token now. Once you close this dialog the secret cannot be displayed again."}),o("div",{className:"rounded border border-border bg-background p-2 font-mono text-[11px] break-all select-all",children:e})]}),f(qv,{children:[f("button",{onClick:()=>{a()},className:"inline-flex items-center gap-1.5 rounded bg-surface border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-primary/5 hover:border-primary/30",children:[r?o(_t,{className:"h-3.5 w-3.5 text-primary"}):o(aa,{className:"h-3.5 w-3.5"}),r?"Copied":"Copy"]}),o("button",{onClick:n,className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:"Done"})]})]})}function Hv({title:e,onClose:t,children:n}){return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:r=>r.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:e}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),o("div",{className:"p-4",children:n})]})})}function qv({children:e}){return o("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:e})}function Is({label:e,hint:t,children:n}){return f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:e}),n,t&&o("p",{className:"text-[10px] text-foreground-subtle",children:t})]})}function qz({addonId:e,fallback:t,tileClassName:n,iconPath:r="assets/icon.svg"}){const[s,a]=_(!1),i=`/api/addon-assets/${e}/${r}`;return o("div",{className:`h-10 w-10 rounded-lg flex items-center justify-center shrink-0 ${n}`,children:s?o(t,{className:"h-5 w-5"}):o("img",{src:i,alt:e,className:"h-7 w-7 rounded-md bg-white p-1 ring-1 ring-black/5",onError:()=>a(!0)})})}function Uz({addonId:e,defaultActivity:t,showActivity:n=!0,maxHeight:r="max-h-64",defaultTab:s}){const a=t??(s==="events"?"events":"logs"),[i,l]=_(a);return f("div",{className:"flex flex-col gap-4",children:[o(to,{nodeId:"hub",addonIds:[e],level:"global"}),n&&f("div",{className:"rounded-lg border border-border bg-surface overflow-hidden",children:[f("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border bg-surface-hover/20",children:[o("span",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",children:"Activity"}),f("div",{className:"flex items-center gap-1",children:[o(Pf,{kind:"logs",active:i==="logs",onClick:()=>l("logs")}),o(Pf,{kind:"events",active:i==="events",onClick:()=>l("events")})]})]}),i==="logs"?o(tn,{addonId:e,maxHeight:r,showFilters:!1}):o(br,{addonId:e,category:"addon.*",maxHeight:r})]})]})}function Pf({kind:e,active:t,onClick:n}){return f("button",{onClick:n,className:`inline-flex items-center gap-1 rounded px-2 py-0.5 text-[11px] font-medium transition-colors ${t?"bg-primary/10 text-primary":"text-foreground-subtle hover:text-foreground hover:bg-surface-hover"}`,children:[o(e==="logs"?at:Jo,{className:"h-3 w-3"}),e==="logs"?"Logs":"Events"]})}function ns(e){const{title:t,subtitle:n,pageIcon:r,itemIcon:s,capability:a,installButtonLabel:i="Add addon",items:l,isLoading:c,emptyTitle:d="No addons installed for this capability",emptyDescription:u,itemIconColor:p,renderStatusBadges:h,renderPrimaryAction:m,itemError:g,renderExpandedPanel:b,workspaceMaxHeight:x="max-h-72",trailing:y,showChrome:w=!1}=e,v=l.length>1,[N,k]=_(()=>l[0]?.addonId??null);Y(()=>{N&&(l.some(I=>I.addonId===N)||k(l[0]?.addonId??null))},[l,N]);const C=I=>k(A=>A===I?null:I),E=`/system/addons?capability=${encodeURIComponent(a)}`;return o(tt,{icon:w?r:void 0,title:w?t:void 0,subtitle:w?n:void 0,actions:w?o(sa,{to:E,children:f(Be,{variant:"primary",size:"sm",children:[o(Et,{className:"h-3.5 w-3.5 mr-1"}),i]})}):void 0,children:c?o(un,{children:o("div",{className:"p-6 text-sm text-foreground-subtle",children:"Loading…"})}):l.length===0?o(un,{children:o(Wc,{title:d,description:u??`Install an addon that declares the "${a}" capability to get started.`,action:w?o(sa,{to:E,children:f(Be,{variant:"primary",size:"sm",children:[o(Et,{className:"h-3.5 w-3.5 mr-1"}),i]})}):void 0})}):f("div",{className:"flex flex-col gap-4",children:[l.map(I=>{const A=!v||N===I.addonId,z=p?.(I)??(I.isActive?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"),P=g?.(I)??null;return f(un,{children:[f("div",{className:`flex items-center gap-3 p-4 ${A?"border-b border-border":""}`,children:[v&&o("button",{type:"button",onClick:()=>C(I.addonId),"aria-label":A?"Collapse":"Expand",className:"shrink-0 p-1 rounded hover:bg-foreground-subtle/10 transition-colors",children:o(lt,{className:`h-4 w-4 text-foreground-subtle transition-transform ${A?"rotate-180":""}`})}),f("button",{type:"button",onClick:()=>v&&C(I.addonId),className:`flex items-center gap-4 flex-1 min-w-0 text-left ${v?"hover:opacity-80 transition-opacity":""}`,disabled:!v,children:[o(qz,{addonId:I.addonId,fallback:s,tileClassName:z}),f("div",{className:"flex-1 min-w-0",children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("span",{className:"font-semibold text-foreground",children:I.displayName}),o(Qz,{isActive:I.isActive}),h?.(I)]}),f("div",{className:"text-xs text-foreground-subtle mt-1 font-mono",children:["@camstack/addon-",I.addonId]})]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[m?.(I),o(Gz,{capName:a,addonId:I.addonId,isActive:I.isActive}),o(Kz,{addonId:I.addonId,displayName:I.displayName})]})]}),A&&f("div",{className:"p-4 flex flex-col gap-3",children:[P!==null&&o(Oa,{message:P}),b?.(I),o(Uz,{addonId:I.addonId,maxHeight:x})]})]},I.addonId)}),y]})})}function Qz({isActive:e}){return o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${e?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:e?"Enabled":"Disabled"})}function Gz({capName:e,addonId:t,isActive:n}){const r=ke(),s=bb({onSuccess:()=>{r.invalidateQueries({queryKey:[["addons","listCapabilityProviders"]]})}}),a=s.isPending;return f(Be,{size:"sm",variant:n?"secondary":"primary",disabled:a,onClick:()=>s.mutate({capName:e,addonId:t,enabled:!n}),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):n?o(ts,{className:"h-3 w-3"}):o(Ya,{className:"h-3 w-3"}),n?"Disable":"Enable"]})}function Kz({addonId:e,displayName:t}){const n=ke(),r=Ko({onSuccess:()=>{n.invalidateQueries({queryKey:[["addons","listCapabilityProviders"]]})}});return o(Ad,{label:"Restart",icon:ct,size:"sm",title:`Restart "${t}"?`,description:"Restarting the addon bounces its subprocess — the provider will briefly drop and reconnect automatically.",confirmLabel:"Restart",triggerVariant:"ghost",confirmVariant:"danger",disabled:r.isPending,action:()=>r.mutateAsync({addonId:e})})}const _f=3e4;function Wz(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function Yz(e){return e==="local-auth"?{headline:"Username + password (local).",icon:w6,bullets:["Users live in the hub’s SQLite database — no IdP roundtrip.","TOTP / 2FA can be enrolled per-user from the Users page (added in v0.4).","API keys + scoped tokens are managed from the API Keys page."],setupSteps:["Add users from Users → New user (or seed via CAMSTACK_ADMIN_USER / CAMSTACK_ADMIN_PASS).","Hand out either passwords or scoped tokens — both validate through this provider."]}:e.startsWith("auth-oidc")?{headline:"OpenID Connect (Google, Microsoft, Okta, Keycloak, …).",icon:_n,bullets:["Three-leg redirect flow with PKCE S256 + nonce.","id_token is signature-verified against the IdP’s JWKS — no implicit trust.","First-time sign-ins are auto-provisioned with the configured Default Role."],setupSteps:["Register a web app at your IdP and copy the client_id + client_secret.","Set the redirect URI to `https://<this-hub>/addon/<addon-id>/callback`.","Paste issuer + credentials in the Settings panel below — saves on every change."]}:e.startsWith("auth-saml")?{headline:"SAML 2.0 — enterprise SSO (Azure AD, Okta, OneLogin).",icon:_n,bullets:["Heavier handshake than OIDC — exchange metadata XML with your IdP.","Group → role mapping via SAML assertions."]}:e.startsWith("auth-webauthn")||e.startsWith("auth-passkey")?{headline:"Passkeys / WebAuthn — passwordless second factor.",icon:An,bullets:["Enroll a YubiKey, Touch ID, or platform passkey per user.","Resistant to phishing — the browser binds the credential to your hub origin."]}:e.startsWith("auth-totp")||e.startsWith("auth-magic-link")?{headline:"TOTP / magic-link — second factor or passwordless sign-in.",icon:An,bullets:["Codes / links delivered out-of-band (RFC 6238 for TOTP).","Compatible with Google Authenticator, Aegis, 1Password, Bitwarden, etc."]}:{headline:"Authentication provider.",icon:mn,bullets:["Generic authentication provider. No additional hints registered."]}}function Zz(){const e=Go({capName:"auth-provider"},{refetchInterval:_f}),t=wn(void 0,{refetchInterval:_f}),n=H(()=>Wz(t.data??[]),[t.data]),r=H(()=>(e.data??[]).map(s=>({addonId:s.addonId,displayName:n.get(s.addonId)??s.addonId,isActive:s.isActive})),[e.data,n]);return o(ns,{title:"Authentication",subtitle:"Identity providers exposed to the admin UI. Multiple providers can run in parallel — operators pick which to enable. Disabling a provider only removes that external login method; local password login is unaffected. Each provider’s settings + live logs are inline below.",pageIcon:mn,itemIcon:mn,capability:"auth-provider",installButtonLabel:"Add provider",items:r,isLoading:e.isLoading,emptyTitle:"No authentication providers registered",emptyDescription:"Local auth should always be available — if this list is empty the local-auth builtin failed to register. Check the Addons page for load errors.",renderExpandedPanel:s=>o(Xz,{addonId:s.addonId})})}function Xz({addonId:e}){const t=Yz(e),n=t.icon;return f("div",{className:"rounded-lg border border-border bg-surface p-4 space-y-3",children:[f("div",{className:"flex items-start gap-2.5",children:[o(n,{className:"h-4 w-4 mt-0.5 text-primary shrink-0"}),o("div",{className:"text-xs text-foreground font-medium",children:t.headline})]}),o("ul",{className:"text-xs text-foreground-subtle space-y-1.5 pl-6 list-disc",children:t.bullets.map((r,s)=>o("li",{children:r},s))}),t.setupSteps&&t.setupSteps.length>0&&f("div",{className:"rounded-md border border-border bg-surface-hover/40 px-3 py-2.5 space-y-1.5",children:[f("div",{className:"flex items-center gap-1.5 text-[10px] font-semibold text-foreground-subtle uppercase tracking-wide",children:[o(SR,{className:"h-3 w-3"}),"Setup steps"]}),o("ol",{className:"text-xs text-foreground space-y-0.5 pl-4 list-decimal",children:t.setupSteps.map((r,s)=>o("li",{children:r},s))})]}),e==="local-auth"&&f("div",{className:"rounded-md border border-blue-500/30 bg-blue-500/5 px-3 py-2 flex items-start gap-2 text-[11px] text-foreground",children:[o(rr,{className:"h-3.5 w-3.5 mt-0.5 text-blue-500 shrink-0"}),f("span",{children:["TOTP / 2FA settings are exposed per-user from the"," ",o("a",{href:"/system/users",className:"underline text-primary",children:"Users"})," page (added in v0.4). Enable for each user via the Actions column → “Enable TOTP”."]})]})]})}function Jz(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"users",label:"Users",icon:qO,content:o($z,{})},{id:"api-keys",label:"Tokens",icon:W0,content:o(Bz,{})},{id:"authentication",label:"Authentication",icon:mn,content:o(Zz,{})}]})})}const sc=5e3,eF={connected:!1,endpoint:null};function tF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function nF(){const e=ke(),t=Go({capName:"network-access"},{refetchInterval:sc}),n=wn(void 0,{refetchInterval:sc}),r=H(()=>tF(n.data??[]),[n.data]),s=H(()=>(t.data??[]).map(m=>({addonId:m.addonId,displayName:r.get(m.addonId)??m.addonId,isActive:m.isActive})),[t.data,r]),[a,i]=_(null),[l,c]=_({}),d=(m,g)=>{e.invalidateQueries({queryKey:[["networkAccess"]]}),i(null),c(b=>{const x=g?.addonId;if(x===void 0||!(x in b))return b;const y={...b};return delete y[x],y})},u=(m,g)=>{i(null);const b=g?.addonId;if(b===void 0)return;const x=m instanceof Error?m.message:String(m);c(y=>({...y,[b]:x}))},p=Px({onSuccess:d,onError:u}),h=_x({onSuccess:d,onError:u});return o(ns,{title:"Remote Access",subtitle:"Public-facing tunnels that expose this hub to the internet (Cloudflare Tunnel, ngrok, …). Settings, Logs and Events are docked under every provider.",pageIcon:_n,itemIcon:_n,capability:"network-access",installButtonLabel:"Add tunnel",items:s,isLoading:t.isLoading,emptyTitle:"No remote-access providers installed",emptyDescription:"Install a tunnel addon (e.g. @camstack/addon-cloudflare-tunnel) to expose this hub publicly.",renderStatusBadges:m=>o(rF,{addonId:m.addonId}),itemError:m=>l[m.addonId]??null,renderPrimaryAction:m=>o(oF,{addonId:m.addonId,busyId:a,onStart:g=>{i(g),p.mutate({addonId:g})},onStop:g=>{i(g),h.mutate({addonId:g})}})})}function Uv(e){const{data:t}=$x({addonId:e},{refetchInterval:sc,retry:!1}),n=t?v2.safeParse(t):null;return n?.success?n.data:eF}function rF({addonId:e}){const t=Uv(e);return f(me,{children:[o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t.connected?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:t.connected?"Connected":"Disconnected"}),t.endpoint&&f("a",{href:t.endpoint.url,target:"_blank",rel:"noopener noreferrer",onClick:n=>n.stopPropagation(),className:"text-[10px] text-emerald-700 dark:text-emerald-300 hover:underline flex items-center gap-1",children:[o(Wd,{className:"h-3 w-3"}),t.endpoint.url]})]})}function oF({addonId:e,busyId:t,onStart:n,onStop:r}){const s=Uv(e),a=t===e;return s.connected?f(Be,{size:"sm",variant:"secondary",disabled:a,onClick:()=>r(e),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):o(ts,{className:"h-3 w-3"}),"Stop"]}):f(Be,{size:"sm",variant:"primary",disabled:a,onClick:()=>n(e),children:[a?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ya,{className:"h-3 w-3"}),"Start"]})}const $f=3e4;function sF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function aF(e){const t=[];for(const n of e)typeof n.urls=="string"?t.push(n.urls):t.push(...n.urls);return t}function iF(){const e=Go({capName:"turn-provider"},{refetchInterval:$f}),t=wn(void 0,{refetchInterval:$f}),n=yd(),r=n.data??[],s=H(()=>sF(t.data??[]),[t.data]),a=H(()=>(e.data??[]).map(i=>({addonId:i.addonId,displayName:s.get(i.addonId)??i.addonId,isActive:i.isActive})),[e.data,s]);return o(ns,{title:"TURN Servers",subtitle:"ICE servers used for WebRTC NAT traversal. Multiple providers can coexist — the WebRTC layer concatenates servers from all enabled providers per session.",pageIcon:$n,itemIcon:$n,capability:"turn-provider",installButtonLabel:"Add provider",items:a,isLoading:e.isLoading,emptyTitle:"No TURN providers installed",emptyDescription:"Install a TURN addon (e.g. @camstack/addon-cloudflare-turn) to enable WebRTC behind restrictive NATs.",renderExpandedPanel:i=>o(lF,{addonId:i.addonId,enabled:i.isActive}),trailing:f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border flex items-center justify-between",children:[f("div",{children:[o("div",{className:"text-sm font-semibold",children:"Combined ICE server list"}),o("div",{className:"text-xs text-foreground-subtle",children:"What the WebRTC layer fetches per-session."})]}),o(Be,{size:"sm",variant:"secondary",onClick:()=>n.refetch(),disabled:n.isFetching,children:"Refresh"})]}),o("div",{className:"p-4",children:r.length===0?o("div",{className:"text-xs text-foreground-subtle",children:"No servers from enabled providers."}):o("div",{className:"flex flex-col gap-3",children:r.map((i,l)=>{const c=Array.isArray(i.urls)?i.urls:[i.urls];return f("div",{className:"rounded border border-border bg-surface",children:[(i.username||i.credential)&&f("div",{className:"px-3 py-1.5 border-b border-border text-[10px] font-mono text-foreground-subtle flex items-center gap-3",children:[i.username&&f("span",{children:[o("span",{className:"text-foreground-subtle",children:"user:"})," ",o("span",{className:"text-foreground",children:i.username})]}),i.credential&&f("span",{title:i.credential,children:[o("span",{className:"text-foreground-subtle",children:"credential:"})," ",o("span",{className:"text-foreground",children:`${i.credential.slice(0,8)}…${i.credential.slice(-4)}`})]})]}),o("ul",{className:"divide-y divide-border",children:c.map(d=>o("li",{className:"px-3 py-1.5 font-mono text-xs text-foreground break-all",children:d},d))})]},l)})})})]})})}function lF({addonId:e,enabled:t}){const n=yd({addonId:e},{enabled:t,retry:!1}),r=H(()=>aF(n.data??[]),[n.data]);return!t||r.length===0?null:f("div",{className:"rounded-lg border border-border bg-surface p-3",children:[f("div",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide mb-2",children:["Discovered ICE servers (",r.length,")"]}),o("div",{className:"flex flex-wrap gap-1",children:r.map(s=>o("span",{className:"inline-block rounded px-1.5 py-0.5 text-[10px] font-mono bg-foreground-subtle/10 text-foreground",children:s},s))})]})}const cF={lan:$n,wifi:or,docker:Wa,vpn:Yd,loopback:hn,other:hn},dF={lan:"LAN",wifi:"Wi-Fi",docker:"Docker",vpn:"VPN",loopback:"Loopback",other:"Other"},uF=["lan","wifi","vpn","docker","other","loopback"];function pF(e){const{interfaces:t,disabled:n,hideLoopback:r,ipv4Only:s,emptyMessage:a}=e,i=H(()=>t.filter(u=>!(r&&u.kind==="loopback"||s&&u.family!=="IPv4")),[t,r,s]),l=H(()=>{const u=new Map;for(const p of i){const h=u.get(p.kind)??[];h.push(p),u.set(p.kind,h)}return uF.filter(p=>u.has(p)).map(p=>({kind:p,items:u.get(p)}))},[i]),c=u=>e.mode==="single"?e.value===u:e.value.includes(u),d=u=>{if(n||u.kind==="loopback")return;if(e.mode==="single"){e.onChange(e.value===u.address?null:u.address);return}const p=new Set(e.value);p.has(u.address)?p.delete(u.address):p.add(u.address),e.onChange([...p])};return i.length===0?o("div",{className:"text-xs text-foreground-subtle italic",children:a??"No addresses available."}):o("div",{className:"flex flex-col gap-3",children:l.map(({kind:u,items:p})=>{const h=cF[u]??hn;return f("div",{className:"rounded-md border border-border overflow-hidden",children:[f("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-surface-hover/30 border-b border-border",children:[o(h,{className:"h-3.5 w-3.5 text-foreground-subtle"}),o("span",{className:"text-[11px] font-semibold uppercase tracking-wide text-foreground-subtle",children:dF[u]??u}),f("span",{className:"text-[10px] text-foreground-subtle",children:["· ",p.length]})]}),o("ul",{className:"divide-y divide-border",children:p.map(m=>{const g=c(m.address),b=m.kind==="loopback",x=!m.plausible&&!b;return f("li",{className:`flex items-center gap-3 px-3 py-2 ${b?"opacity-60 cursor-not-allowed":n?"opacity-60":x?"cursor-pointer hover:bg-surface-hover/30 bg-amber-500/[0.04]":"cursor-pointer hover:bg-surface-hover/30"}`,onClick:()=>d(m),children:[o("span",{className:`flex items-center justify-center h-4 w-4 rounded ${e.mode==="single"?"rounded-full":"rounded"} border ${g?"border-primary bg-primary text-primary-foreground":"border-border bg-surface"}`,children:g&&o(_t,{className:"h-3 w-3"})}),f("div",{className:`flex-1 min-w-0 ${x?"text-foreground-subtle":""}`,children:[f("div",{className:"flex items-center gap-2 flex-wrap",children:[o("span",{className:`font-mono text-xs font-semibold ${x?"text-foreground-subtle":"text-foreground"}`,children:m.name}),o("span",{className:"text-[10px] rounded px-1.5 py-0.5 bg-foreground-subtle/10 text-foreground-subtle font-mono",children:m.family}),m.preferred&&o("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-primary/15 text-primary",children:"Auto-preferred"}),b&&o("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-foreground-subtle/15 text-foreground-subtle",children:"Always included"}),x&&f("span",{className:"inline-flex items-center gap-1 text-[10px] rounded-full px-2 py-0.5 font-medium bg-amber-500/15 text-amber-700 dark:text-amber-300",title:m.plausibleReason||void 0,children:[o(it,{className:"h-2.5 w-2.5"}),"Unlikely usable"]})]}),f("div",{className:"text-xs text-foreground-subtle mt-0.5 font-mono break-all",children:[m.address,m.cidr&&m.cidr!==m.address?` (${m.cidr})`:""]})]})]},`${m.name}-${m.family}-${m.address}`)})})]},u)})})}const Df={"lan-ipv4":"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300","lan-ipv6":"bg-violet-500/15 text-violet-700 dark:text-violet-300",public:"bg-blue-500/15 text-blue-700 dark:text-blue-300",loopback:"bg-foreground-subtle/15 text-foreground-subtle"};function fF(){const e=ke(),t=Te(),n=bx(void 0,{refetchInterval:3e4}),r=yx(void 0),s=vx({onSuccess:()=>{e.invalidateQueries({queryKey:[["localNetwork"]]})}}),a=wx({onSuccess:C=>{p(C.addresses),e.invalidateQueries({queryKey:[["localNetwork"]]})}}),i=H(()=>n.data?.interfaces??[],[n.data]),l=typeof window<"u"?Number(window.location.port)||(window.location.protocol==="https:"?443:80):4e3,c=typeof window<"u"&&window.location.protocol==="https:"?"https":"http",d=xx({port:l,scheme:c},{refetchInterval:3e4}),[u,p]=_([]),[h,m]=_(!1);Y(()=>{!h&&r.data&&(p(r.data.addresses),m(!0))},[r.data,h]);const g=r.data?.addresses??[],b=H(()=>{if(u.length!==g.length)return!0;const C=[...u].sort(),E=[...g].sort();return C.some((I,A)=>I!==E[A])},[u,g]),x=()=>{s.mutate({addresses:[...u]})},y=()=>{p(g)},w=()=>{p([])},v=()=>{n.refetch(),d.refetch(),r.refetch()},N=async()=>{try{const C=await t.raceConnectionEndpoints({perCandidateTimeoutMs:1500});console.info("[network-addresses] race result",C)}catch(C){console.warn("[network-addresses] race failed",C)}},k=d.data?.endpoints??[];return f(tt,{children:[f("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[o("p",{className:"text-xs text-foreground-subtle max-w-2xl",children:"Pick the local addresses SDK clients should race for the fastest path to this hub. Empty selection (auto) lets every non-loopback / non-link-local interface participate."}),f("div",{className:"flex items-center gap-2 shrink-0",children:[f(Be,{size:"sm",variant:"secondary",onClick:v,disabled:n.isLoading,children:[o(ct,{className:`h-3 w-3 ${n.isLoading?"animate-spin":""}`}),"Refresh"]}),o(Be,{size:"sm",variant:"secondary",onClick:N,children:"Probe race"})]})]}),f("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border flex items-center justify-between",children:[f("div",{children:[o("div",{className:"text-sm font-semibold",children:"Allowed addresses"}),o("div",{className:"text-xs text-foreground-subtle",children:u.length===0?"Auto — every non-loopback / non-link-local interface participates.":`${u.length} pinned`})]}),f("div",{className:"flex items-center gap-1",children:[f(Be,{size:"sm",variant:"secondary",onClick:()=>a.mutate(void 0),disabled:a.isPending||s.isPending,title:"Re-run the auto-detection heuristic + overwrite the current allowlist with the best matches.",children:[o(_O,{className:"h-3 w-3"}),a.isPending?"Detecting…":"Best match"]}),f(Be,{size:"sm",variant:"secondary",onClick:w,disabled:u.length===0||s.isPending,children:[o(tv,{className:"h-3 w-3"}),"Clear"]}),b&&o(Be,{size:"sm",variant:"secondary",onClick:y,disabled:s.isPending,children:"Discard"}),f(Be,{size:"sm",variant:"primary",onClick:x,disabled:!b||s.isPending,children:[o(fO,{className:"h-3 w-3"}),s.isPending?"Saving…":"Save"]})]})]}),o("div",{className:"p-4",children:o(pF,{mode:"multiple",interfaces:i,value:u,onChange:p,disabled:s.isPending,emptyMessage:n.isLoading?"Loading interfaces…":"No interfaces detected."})})]}),f(un,{children:[f("div",{className:"px-4 py-3 border-b border-border",children:[o("div",{className:"text-sm font-semibold",children:"Connection endpoints — priority order"}),o("div",{className:"text-xs text-foreground-subtle",children:"Live preview of the ranked candidate list the SDK would race against. Updates with each Save."})]}),o("div",{className:"p-4",children:k.length===0?o("div",{className:"text-xs text-foreground-subtle italic",children:d.isLoading?"Loading…":"No endpoints available."}):o("ul",{className:"space-y-1 text-xs",children:k.map(C=>f("li",{className:`flex items-center gap-2 flex-wrap ${C.plausible?"":"opacity-80"}`,children:[o("span",{className:"font-mono text-[10px] w-10 text-foreground-subtle",children:String(C.priority).padStart(4,"0")}),o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${Df[C.kind]??Df.loopback}`,children:C.kind}),C.interfaceKind!=="lan"&&C.interfaceKind!=="public"&&o("span",{className:"text-[10px] rounded px-1.5 py-0.5 bg-foreground-subtle/10 text-foreground-subtle font-medium uppercase",children:C.interfaceKind}),!C.plausible&&C.interfaceKind!=="loopback"&&f("span",{className:"inline-flex items-center gap-1 text-[10px] rounded-full px-2 py-0.5 font-medium bg-amber-500/15 text-amber-700 dark:text-amber-300",title:C.plausibleReason||void 0,children:[o(it,{className:"h-2.5 w-2.5"}),"Unlikely usable"]}),o("span",{className:`font-mono break-all ${C.plausible?"text-foreground":"text-foreground-subtle"}`,children:C.baseUrl}),f("span",{className:"text-foreground-subtle",children:["— ",C.label]})]},`${C.priority}-${C.baseUrl}`))})})]})]})]})}const hF={mesh:"bg-violet-500/15 text-violet-700 dark:text-violet-300",public:"bg-blue-500/15 text-blue-700 dark:text-blue-300"},ac=5e3,mF=3e4,gF={joined:!1,meshIp:"",magicDnsHostname:"",peerCount:0,endpoints:[],tenantName:"",magicDnsSuffix:"",userLogin:null,controlPlaneUrl:"",keyExpiry:null};function bF(e){const t=new Map;for(const n of e){const r=n?.manifest;r?.id&&t.set(r.id,r.packageDisplayName??r.name??r.id)}return t}function xF(){const e=Go({capName:"mesh-network"},{refetchInterval:ac}),t=wn(void 0,{refetchInterval:ac}),n=H(()=>bF(t.data??[]),[t.data]),r=H(()=>(e.data??[]).map(s=>({addonId:s.addonId,displayName:n.get(s.addonId)??s.addonId,isActive:s.isActive})),[e.data,n]);return o(ns,{title:"Mesh Networks",subtitle:"Private VPN meshes that connect CamStack to your other devices (Tailscale, Headscale, …). Each provider can also expose this hub publicly via its ingress (Tailscale Funnel).",pageIcon:Wa,itemIcon:$n,capability:"mesh-network",installButtonLabel:"Add mesh",items:r,isLoading:e.isLoading,emptyTitle:"No mesh-network providers installed",emptyDescription:"Install a mesh addon (e.g. @camstack/addon-tailscale-client) to join this hub into a private VPN mesh.",renderStatusBadges:s=>o(yF,{addonId:s.addonId}),renderPrimaryAction:s=>o(vF,{addonId:s.addonId}),renderExpandedPanel:s=>o(wF,{addonId:s.addonId})})}function tu(e){const{data:t,isLoading:n}=Nx({addonId:e},{refetchInterval:ac,retry:!1}),r=t?pm.safeParse(t):null;return{status:r?.success?r.data:gF,isLoading:n}}function yF({addonId:e}){const{status:t}=tu(e);return f(me,{children:[o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t.joined?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":"bg-foreground-subtle/15 text-foreground-subtle"}`,children:t.joined?"Joined":"Not joined"}),t.joined&&f("span",{className:"text-[10px] rounded-full px-2 py-0.5 font-medium bg-foreground-subtle/15 text-foreground-subtle",children:[t.peerCount," peer",t.peerCount===1?"":"s"]})]})}function vF({addonId:e}){const t=ke(),[n,r]=_(!1),[s,a]=_(null),i=Te(),{status:l}=tu(e),c=U(()=>{t.invalidateQueries({queryKey:[["meshNetwork"]]})},[t]),d=kx(),u=Sx({onSuccess:c}),p=Cx({onSuccess:c}),h=U(async()=>{r(!0);const g={cancelled:!1};a(g);try{const b=await d.mutateAsync({addonId:e});if(g.cancelled)return;b.loginUrl&&window.open(b.loginUrl,"_blank","noopener,noreferrer");const x=Date.now(),y=10*6e4;for(;!g.cancelled&&(await MF(2e3),!g.cancelled);){const w=await i.trpcClient.meshNetwork.getStatus.query({addonId:e}).catch(()=>null),v=w?pm.safeParse(w):null;if(v?.success&&v.data.joined){c();break}if(Date.now()-x>y)break}}finally{r(!1),a(null)}},[e,c,d,i]),m=U(()=>{s&&(s.cancelled=!0),r(!1),a(null)},[s]);return o(me,{children:l.joined?f(me,{children:[f(Be,{size:"sm",variant:"secondary",disabled:u.isPending,onClick:()=>u.mutate({addonId:e}),children:[u.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Zd,{className:"h-3 w-3"}),"Disconnect"]}),f(Be,{size:"sm",variant:"ghost",disabled:p.isPending,onClick:()=>p.mutate({addonId:e}),children:[p.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Hp,{className:"h-3 w-3"}),"Log out"]})]}):n?f(Be,{size:"sm",variant:"ghost",onClick:m,children:[o(Fe,{className:"h-3 w-3 mr-1"})," Cancel"]}):f(me,{children:[f(Be,{size:"sm",variant:"primary",onClick:()=>void h(),children:[o($6,{className:"h-3 w-3"}),"Connect"]}),f(Be,{size:"sm",variant:"ghost",disabled:p.isPending,onClick:()=>p.mutate({addonId:e}),children:[p.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Hp,{className:"h-3 w-3"}),"Log out"]})]})})}function wF({addonId:e}){const{status:t}=tu(e),n=Mx({addonId:e},{refetchInterval:mF,retry:!1});return f("div",{className:"rounded-lg border border-border bg-surface",children:[f("div",{className:"p-4 space-y-4",children:[t.error&&o(Oa,{message:t.error}),o(NF,{status:t}),t.endpoints.length>0&&f("div",{className:"space-y-1.5",children:[o("div",{className:"text-[11px] font-semibold text-foreground-subtle uppercase tracking-wide",children:"Endpoints"}),t.endpoints.map(r=>f("div",{className:"flex items-center gap-2 text-xs flex-wrap",children:[f("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${hF[r.scope]??"bg-foreground-subtle/15 text-foreground-subtle"}`,children:[r.scope==="public"?o(_n,{className:"inline h-2.5 w-2.5 mr-0.5"}):null,r.label]}),f("a",{href:r.url,target:"_blank",rel:"noopener noreferrer",onClick:s=>s.stopPropagation(),className:"text-emerald-700 dark:text-emerald-300 hover:underline break-all flex items-center gap-1",children:[o(Wd,{className:"h-3 w-3 shrink-0"}),r.url]})]},r.id))]})]}),o("div",{className:"border-t border-border",children:o(SF,{peers:n.data?.peers??[],loading:n.isLoading})})]})}function NF({status:e}){const t=[{label:"Tenant",value:e.tenantName||"—"},{label:"User",value:e.userLogin??"—"},{label:"Control plane",value:e.controlPlaneUrl||"—"},{label:"Mesh IP",value:e.meshIp||"—",mono:!0},{label:"MagicDNS",value:e.magicDnsHostname||"—",mono:!0},{label:"DNS suffix",value:e.magicDnsSuffix||"—",mono:!0},{label:"Peers",value:String(e.peerCount)},{label:"Key expiry",value:e.keyExpiry?kF(e.keyExpiry):"—"}];return o("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-1.5",children:t.map(n=>f("div",{className:"flex items-baseline justify-between gap-3 text-xs",children:[o("span",{className:"text-foreground-subtle shrink-0",children:n.label}),o("span",{className:`text-foreground truncate ${n.mono?"font-mono":""}`,children:n.value})]},n.label))})}function kF(e){const t=e-Date.now();if(t<0)return`Expired ${Qv(e)}`;const n=Math.floor(t/864e5);if(n>60)return new Date(e).toLocaleDateString();if(n>1)return`in ${n} days`;const r=Math.floor(t/36e5);return r>1?`in ${r}h`:`in ${Math.max(1,Math.floor(t/6e4))} min`}function SF({peers:e,loading:t}){const n=H(()=>e.map(a=>({...a,_id:a.id})),[e]),r=U(a=>{a&&navigator.clipboard?.writeText(a)},[]),s=H(()=>[{key:"hostname",header:"Hostname",render:a=>f("div",{className:"flex flex-col",children:[f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"font-medium text-foreground",children:a.hostname||"(unknown)"}),a.isSelf&&o(zt,{variant:"info",children:"self"}),a.exitNodeOption&&o(zt,{variant:"warning",children:"exit-node"})]}),a.userLogin&&o("div",{className:"text-[10px] text-foreground-subtle truncate",children:a.userLogin})]})},{key:"magicDns",header:"MagicDNS",render:a=>a.magicDns?f("div",{className:"flex items-center gap-1",children:[o("span",{className:"font-mono text-xs truncate",children:a.magicDns}),o("button",{onClick:()=>r(a.magicDns),className:"p-0.5 hover:bg-foreground-subtle/10 rounded","aria-label":"Copy MagicDNS",children:o(aa,{className:"h-3 w-3 text-foreground-subtle"})})]}):o("span",{className:"text-foreground-subtle",children:"—"})},{key:"addresses",header:"IP",render:a=>{const i=a.addresses[0]??"";return i?f("div",{className:"flex items-center gap-1",children:[o("span",{className:"font-mono text-xs",children:i}),o("button",{onClick:()=>r(i),className:"p-0.5 hover:bg-foreground-subtle/10 rounded","aria-label":"Copy IP",children:o(aa,{className:"h-3 w-3 text-foreground-subtle"})})]}):o("span",{className:"text-foreground-subtle",children:"—"})}},{key:"connection",header:"Connection",render:a=>f("div",{className:"flex items-center gap-1.5",children:[o(zt,{variant:CF(a.connection),children:a.connection}),a.relay&&o("span",{className:"text-[10px] text-foreground-subtle font-mono",children:a.relay})]})},{key:"routes",header:"Routes",render:a=>a.advertisedRoutes.length>0?o("span",{className:"text-[10px] font-mono text-foreground-subtle truncate",children:a.advertisedRoutes.join(", ")}):o("span",{className:"text-foreground-subtle",children:"—"})},{key:"tx",header:"TX / RX",render:a=>f("span",{className:"text-[10px] text-foreground-subtle font-mono",children:["↑ ",Tf(a.txBytes)," · ↓ ",Tf(a.rxBytes)]})},{key:"lastSeen",header:"Last seen",render:a=>o("span",{className:"text-[10px] text-foreground-subtle",children:a.lastSeenMs>0?Qv(a.lastSeenMs):"—"})}],[r]);return t&&e.length===0?f("div",{className:"p-4 text-xs text-foreground-subtle",children:[o(Se,{className:"h-3 w-3 animate-spin inline mr-1"})," Loading peers…"]}):e.length===0?o("div",{className:"p-4 text-xs text-foreground-subtle",children:"No peers visible — your tailnet may be empty or the host is not joined."}):o("div",{className:"p-4",children:o(Da,{columns:s,rows:n,rowKey:a=>a._id,minWidthPx:820})})}function CF(e){return e==="direct"?"success":e==="relay"?"warning":"info"}function Tf(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:e<1024*1024*1024?`${(e/1024/1024).toFixed(1)}MB`:`${(e/1024/1024/1024).toFixed(2)}GB`}function Qv(e){const t=Date.now()-e;return t<6e4?"just now":t<36e5?`${Math.round(t/6e4)}m ago`:t<864e5?`${Math.round(t/36e5)}h ago`:`${Math.round(t/864e5)}d ago`}function MF(e){return new Promise(t=>setTimeout(t,e))}function EF(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"addresses",label:"Network Addresses",icon:hn,content:o(fF,{})},{id:"remote-access",label:"Remote Access",icon:_n,content:o(nF,{})},{id:"mesh",label:"Mesh Networks",icon:Wa,content:o(xF,{})},{id:"turn",label:"TURN Servers",icon:$n,content:o(iF,{})}]})})}const IF=[{kind:"device-export",tabId:"device-export",title:"Device export",subtitle:"Outbound exporters that publish CamStack devices to other ecosystems (HomeAssistant, HomeKit, Alexa, …).",icon:wO,emptyTitle:"No device-export providers installed",emptyDescription:"Install an export addon (e.g. @camstack/addon-export-ha-mqtt) to surface your CamStack devices in HomeAssistant, HomeKit, …",addLabel:"Add export"},{kind:"email",tabId:"email",title:"Email providers",subtitle:"Outbound email relays used for magic-link login, notifications, and alerts (SMTP today, future SendGrid, …).",icon:L6,emptyTitle:"No email providers installed",emptyDescription:"Install an email-provider addon (e.g. @camstack/addon-smtp) so the hub can deliver magic-link logins and notifications.",addLabel:"Add email provider"},{kind:"broker",tabId:"broker",title:"Brokers",subtitle:"Message brokers consumed by exporters and downstream automations (MQTT today, future Kafka, …).",icon:Za,emptyTitle:"No brokers installed",emptyDescription:"Install a broker addon (e.g. @camstack/addon-mqtt-broker) to publish device events for downstream automations.",addLabel:"Add broker"}];function AF(e){if(typeof e=="string")return e;if(e&&typeof e=="object"){const t=e.name;if(typeof t=="string")return t}return null}function PF(e){const t=e,n=t?.manifest;if(!n?.id)return null;const r=[];for(const i of n.capabilities??[]){const l=AF(i);l!==null&&r.push(l)}const s=n.packageDisplayName??n.name??n.id,a=t?.process?.state??null;return{addonId:n.id,displayName:s,isActive:a==="running",packageName:n.packageName??`@camstack/addon-${n.id}`,capNames:r,processState:a}}function _F(e,t){const n=new Set(t);return e.filter(r=>r.capNames.some(s=>n.has(s)))}function $F(e){for(const[t,n]of Object.entries(hm))if(n===e)return t;return null}function DF(e){return e==="running"?{label:"Running",className:"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300"}:e==="crashed"||e==="failed"?{label:e==="failed"?"Failed":"Crashed",className:"bg-danger/15 text-danger"}:e==="stopped"||e==="disabled"?{label:"Stopped",className:"bg-foreground-subtle/15 text-foreground-subtle"}:{label:e??"Unknown",className:"bg-foreground-subtle/15 text-foreground-subtle"}}function nu({label:e,className:t}){return o("span",{className:`text-[10px] rounded-full px-2 py-0.5 font-medium ${t}`,children:e})}function TF({addonId:e}){const{data:t,isLoading:n}=Ax({addonId:e},{refetchInterval:1e4,retry:!1});if(n||!t)return null;const r=w2.safeParse(t);if(!r.success)return null;const s=r.data,a=`${s.brokerCount} broker${s.brokerCount===1?"":"s"}${s.embeddedRunning?" • embedded up":""}`;return o(nu,{label:a,className:"bg-primary/10 text-primary"})}function LF({addonId:e}){const{data:t,isLoading:n}=ld({addonId:e},{refetchInterval:1e4,retry:!1});if(n||!t)return null;const r=um.safeParse(t);if(!r.success)return null;const s=r.data,a=s.linkState==="linked"?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-300":s.linkState==="error"?"bg-danger/15 text-danger":"bg-foreground-subtle/15 text-foreground-subtle",i=`${s.linkState} • ${s.exposedDeviceCount} exposed`;return o(nu,{label:i,className:a})}function RF({kind:e,addonId:t}){return e==="broker"?o(TF,{addonId:t}):e==="device-export"?o(LF,{addonId:t}):null}function OF({descriptor:e,rows:t,isLoading:n}){const r=$F(e.kind),s=e.kind==="device-export";return o(ns,{title:e.title,subtitle:e.subtitle,pageIcon:e.icon,itemIcon:e.icon,capability:r??e.kind,installButtonLabel:e.addLabel,items:t,isLoading:n,emptyTitle:e.emptyTitle,emptyDescription:e.emptyDescription,renderStatusBadges:a=>{const i=DF(a.processState);return f(me,{children:[o(nu,{label:i.label,className:i.className}),o(RF,{kind:e.kind,addonId:a.addonId})]})},renderExpandedPanel:s?a=>o(Md,{addonId:a.addonId}):void 0,showChrome:!0})}function BF(){const e=wn(void 0,{refetchInterval:1e4}),t=(e.data??[]).map(PF).filter(r=>r!==null),n=IF.map(r=>{const s=Object.entries(hm).filter(([,a])=>a===r.kind).map(([a])=>a);return{id:r.tabId,label:r.title,icon:r.icon,content:o(OF,{descriptor:r,rows:_F(t,s),isLoading:e.isLoading})}});return o(tt,{icon:_o,title:"Integrations",subtitle:"External systems this hub talks to — device exporters, email relays, and message brokers. Settings, Logs and Events are docked under every provider.",children:o(ri,{tabs:n})})}function zF(e){const t=e.basePath;if(typeof t=="string"&&t.length>0)return t;const n=Object.keys(e);return n.length===0?"":n.join(", ")}function FF({location:e,onEdit:t,onDelete:n,onSetDefault:r}){const s=zF(e.config);return f("div",{className:"flex items-center gap-3 px-3 py-2 border-t border-border first:border-t-0 hover:bg-primary/5",children:[f("div",{className:"flex items-center gap-2 min-w-0 flex-1",children:[o("div",{className:"w-[88px] shrink-0",children:e.isDefault?f("span",{className:"inline-flex items-center gap-0.5 rounded bg-primary/10 border border-primary/20 px-1.5 py-0.5 text-[10px] font-semibold text-primary uppercase tracking-wide",title:"Default location for this type",children:[o(zi,{className:"h-2.5 w-2.5 fill-primary"}),"Default"]}):f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-0.5 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 hover:border-primary/30 uppercase tracking-wide",title:"Promote to default for this type",children:[o(zi,{className:"h-2.5 w-2.5"}),"Set default"]})}),o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono",children:e.providerId}),e.isSystem&&o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5",title:"System-managed location — cannot be deleted; edit config to relocate",children:"system"}),f("div",{className:"min-w-0",children:[o("div",{className:"text-xs font-medium text-foreground truncate",children:e.displayName}),s&&o("div",{className:"text-[10px] text-foreground-subtle truncate font-mono",children:s})]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[!e.isDefault&&f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10",title:"Set as default for this type",children:[o(zi,{className:"h-3 w-3"}),"Set default"]}),f("button",{onClick:()=>t(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle border border-border hover:text-foreground hover:bg-primary/10",children:[o(eo,{className:"h-3 w-3"}),"Edit"]}),!e.isSystem&&zs[e.type]!=="singleton"&&o("button",{onClick:()=>n(e),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10",title:"Delete location",children:o(Ze,{className:"h-3 w-3"})})]})]})}function jF({type:e,displayName:t,description:n,locations:r,onAdd:s,onEdit:a,onDelete:i,onSetDefault:l}){const c=H(()=>{const d=[...r];return d.sort((u,p)=>u.isDefault!==p.isDefault?u.isDefault?-1:1:u.displayName.localeCompare(p.displayName)),d},[r]);return f("div",{className:"rounded-lg border border-border bg-surface",children:[f("div",{className:"flex items-start justify-between border-b border-border px-3 py-2",children:[f("div",{className:"space-y-0.5",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-sm font-semibold text-foreground capitalize",children:t}),o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5 font-mono",children:e})]}),n&&o("p",{className:"text-[11px] text-foreground-subtle",children:n}),zs[e]==="singleton"&&o("p",{className:"text-[10px] text-foreground-subtle italic",children:"Singleton — one location per type. Edit the existing entry; it can't be split."})]}),zs[e]==="multi"&&f("button",{onClick:()=>s(e),className:"inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3 w-3"}),"Add"]})]}),c.length===0?o("div",{className:"px-3 py-4 text-center text-[11px] text-foreground-subtle italic",children:zs[e]==="multi"?'No location registered. Click "Add" to register one.':"No location registered yet — should be auto-seeded at next boot."}):o("div",{children:c.map(d=>o(FF,{location:d,onEdit:a,onDelete:i,onSetDefault:l},d.id))})]})}function VF(e){const t=e.trim().toLowerCase();return t.length===0?"":t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Lf(e,t){const n=VF(t),r=n.length>0?n:"default";return`${e}:${r}`}function Gv({initialType:e,onClose:t,onCreated:n}){const r=ke(),s=Te().trpcClient,[a,i]=_("picker"),[l,c]=_(e),[d,u]=_(null),[p,h]=_({}),[m,g]=_(""),[b,x]=_(null),[y,w]=_(!1),[v,N]=_(null),[k,C]=_(!1),E=xd(),I=H(()=>{const D=E.data;return Array.isArray(D)?D.filter(L=>L.supportedLocationTypes.includes(l)):[]},[E.data,l]),A=E.isLoading,z=ja({onSuccess:()=>{r.invalidateQueries({queryKey:[["storage","listLocations"]]}),n()}}),P=H(()=>b!==null&&b.length>0?b:Lf(l,m),[l,m,b]),B=async()=>{if(d){C(!0),N(null);try{const L=await(O=>s.storage.testConfig.query(O))({providerId:d.providerId,config:p});N(L)}catch(D){N({ok:!1,error:D instanceof Error?D.message:String(D)})}finally{C(!1)}}},R=()=>{d&&z.mutate({id:P,type:l,displayName:m.trim(),providerId:d.providerId,config:p,isDefault:y})},M={picker:"Add Location — Pick provider",config:`Add Location — ${d?.displayName??""}`,naming:"Add Location — Name & defaults"};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:D=>D.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:M[a]}),f("p",{className:"text-xs text-foreground-subtle",children:["Type: ",o("span",{className:"font-mono",children:l})]})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),a==="picker"&&f("div",{className:"p-4 space-y-2",children:[A&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading providers…"}),!A&&I.length===0&&f("div",{className:"rounded border border-border bg-background px-3 py-4 text-center text-xs text-foreground-subtle",children:['No storage-provider supports type "',l,'". Install a compatible addon (e.g. ',o("code",{className:"font-mono",children:"remote-storage"}),") to enable it."]}),I.map(D=>f("button",{onClick:()=>{u(D),i("config")},className:"flex w-full items-center gap-3 rounded-lg border border-border bg-background p-3 text-left hover:border-primary/40 hover:bg-primary/5 transition-colors",children:[f("div",{className:"flex-1 min-w-0",children:[o("p",{className:"text-xs font-semibold text-foreground",children:D.displayName}),o("p",{className:"text-[10px] text-foreground-subtle font-mono mt-0.5 truncate",children:D.providerId})]}),o(wt,{className:"h-4 w-4 text-foreground-subtle flex-shrink-0"})]},D.providerId))]}),a==="config"&&d&&f("div",{className:"p-4 space-y-3 max-h-[60vh] overflow-y-auto",children:[o(Dn,{schema:d.configSchema,values:p,onChange:h}),v&&o("div",{className:`rounded border px-3 py-2 text-[11px] ${v.ok?"border-success/30 bg-success/5 text-success":"border-danger/30 bg-danger/5 text-danger"}`,children:v.ok?"Connection OK.":`Test failed: ${v.error??"unknown error"}`}),f("div",{className:"flex items-center justify-between pt-1",children:[o("button",{onClick:()=>i("picker"),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Back"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{B()},disabled:k,className:"rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50",children:k?"Testing…":"Test connection"}),o("button",{onClick:()=>i("naming"),className:"rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:"Next"})]})]})]}),a==="naming"&&d&&f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Display name"}),o("input",{type:"text",value:m,onChange:D=>g(D.target.value),placeholder:`${l} on ${d.displayName}`,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1",children:[f("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:["Id ",o("span",{className:"lowercase tracking-normal text-foreground-subtle",children:"— auto-derived; override if needed"})]}),o("input",{type:"text",value:P,onChange:D=>x(D.target.value),placeholder:Lf(l,m),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground font-mono focus:outline-none focus:ring-1 focus:ring-primary"}),f("p",{className:"text-[10px] text-foreground-subtle",children:["Format: ",o("code",{className:"font-mono",children:"<type>:<slug>"}),". Lowercase letters, digits, and hyphens only."]})]}),f("label",{className:"flex items-start gap-2 rounded border border-border bg-background px-3 py-2 cursor-pointer hover:bg-primary/5",children:[o("input",{type:"checkbox",checked:y,onChange:D=>w(D.target.checked),className:"accent-primary mt-0.5"}),f("div",{className:"space-y-0.5",children:[f("div",{className:"text-xs font-medium text-foreground",children:['Mark as default for type "',l,'"']}),f("div",{className:"text-[10px] text-foreground-subtle",children:["Setting this as default will demote the current default for this type. References like"," ",f("code",{className:"font-mono",children:['"',l,'"']})," resolve to whichever location is the default."]})]})]}),z.isError&&o("div",{className:"rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]",children:z.error instanceof Error?z.error.message:String(z.error)}),f("div",{className:"flex items-center justify-between pt-1",children:[o("button",{onClick:()=>i("config"),className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Back"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{c(e),u(null),h({}),g(""),x(null),w(!1),N(null),i("picker")},className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Reset"}),f("button",{onClick:R,disabled:z.isPending||m.trim().length===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[z.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):null,z.isPending?"Saving…":"Save"]})]})]})]})]})})}function HF({location:e,onClose:t,onSaved:n}){const r=ke(),s=Te().trpcClient,[a,i]=_({...e.config}),[l,c]=_(e.displayName),[d,u]=_(null),[p,h]=_(!1),m=xd(),g=H(()=>{const w=m.data;return Array.isArray(w)?w.find(N=>N.providerId===e.providerId)??null:null},[m.data,e.providerId]),b=ja({onSuccess:()=>{r.invalidateQueries({queryKey:[["storage","listLocations"]]}),n()}}),x=async()=>{h(!0),u(null);try{const v=await(N=>s.storage.testConfig.query(N))({providerId:e.providerId,config:a});u(v)}catch(w){u({ok:!1,error:w instanceof Error?w.message:String(w)})}finally{h(!1)}},y=()=>{b.mutate({id:e.id,type:e.type,providerId:e.providerId,isDefault:e.isDefault,displayName:l.trim(),config:a})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:t,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:w=>w.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[f("h2",{className:"text-sm font-semibold text-foreground",children:["Edit ",e.displayName]}),f("p",{className:"text-xs text-foreground-subtle",children:[o("span",{className:"font-mono",children:e.id})," · ",g?.displayName??e.providerId]})]}),o("button",{onClick:t,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-3 max-h-[60vh] overflow-y-auto",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Display name"}),o("input",{type:"text",value:l,onChange:w=>c(w.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})]}),g&&o(Dn,{schema:g.configSchema,values:a,onChange:i}),!g&&!m.isLoading&&f("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300",children:["Provider ",o("code",{className:"font-mono",children:e.providerId})," is no longer registered. Field schema unavailable; raw config is preserved on save."]}),d&&o("div",{className:`rounded border px-3 py-2 text-[11px] ${d.ok?"border-success/30 bg-success/5 text-success":"border-danger/30 bg-danger/5 text-danger"}`,children:d.ok?"Connection OK.":`Test failed: ${d.error??"unknown error"}`}),b.isError&&o("div",{className:"rounded border border-danger/30 bg-danger/5 text-danger px-3 py-2 text-[11px]",children:b.error instanceof Error?b.error.message:String(b.error)})]}),f("div",{className:"flex items-center justify-between gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:t,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:()=>{x()},disabled:p||!g,className:"rounded border border-border px-3 py-1.5 text-xs text-foreground hover:bg-primary/10 disabled:opacity-50",children:p?"Testing…":"Test connection"}),f("button",{onClick:y,disabled:b.isPending||l.trim().length===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[b.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):null,b.isPending?"Saving…":"Save"]})]})]})]})})}const qF={data:"Data",media:"Media",recordings:"Recordings","recordings-high":"Recordings (High)","recordings-low":"Recordings (Low)","recordings-clips":"Recordings (Clips)","event-images":"Event Images",models:"Models","addons-data":"Addons Data",cache:"Cache",logs:"Logs",backups:"Backups"},UF={backups:"Snapshot archives. Default landing for `backup-orchestrator`.",recordings:"Continuous recordings (combined high + low + clips when no slot is specified).","recordings-high":"High-quality continuous recordings.","recordings-low":"Low-quality continuous recordings.","recordings-clips":"Event clips (motion / detection triggers).","event-images":"Detection snapshots, thumbnails, and crops.",models:"ML model files. Read by inference-engine addons.",logs:"Long-term log archives."};function QF(){const e=ke(),t=nt(),{data:n,isLoading:r,isError:s}=My({}),[a,i]=_(null),[l,c]=_(null),d=Ey({onSuccess:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]})}}),u=ja({onSuccess:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]})}}),p=g=>{g.isDefault||u.mutate({id:g.id,type:g.type,providerId:g.providerId,displayName:g.displayName,config:g.config,isDefault:!0})},h=async g=>{if(g.isDefault){await t({title:"Cannot delete default location",message:`"${g.displayName}" is the default for type "${g.type}". Mark another location as default first, then delete this one.`,confirmLabel:"OK",variant:"warning"});return}await t({title:`Delete location "${g.displayName}"?`,message:"This removes the location record. Files on disk are not deleted; the underlying directory or remote path stays untouched.",confirmLabel:"Delete",variant:"danger"})&&d.mutate({id:g.id})},m=H(()=>{const g=new Map;for(const b of Lu)g.set(b,[]);for(const b of n??[]){const x=g.get(b.type);x?x.push(b):g.set(b.type,[b])}return g},[n]);return f(tt,{children:[r&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading locations…"}),s&&o("div",{className:"text-xs text-danger",children:"Failed to load storage locations."}),!r&&!s&&o("div",{className:"space-y-3",children:Lu.map(g=>o(jF,{type:g,displayName:qF[g],description:UF[g],locations:m.get(g)??[],onAdd:b=>i(b),onEdit:b=>c(b),onDelete:b=>{h(b)},onSetDefault:b=>p(b)},g))}),a!==null&&o(Gv,{initialType:a,onClose:()=>i(null),onCreated:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]}),i(null)}}),l!==null&&o(HF,{location:l,onClose:()=>c(null),onSaved:()=>{e.invalidateQueries({queryKey:[["storage","listLocations"]]}),c(null)}})]})}const GF=[["backup","listDestinations"]],KF=["backup","listArchives"];function WF({destinationId:e,restoreSupported:t,onOpenRestoreWizard:n}){const r=ke(),s=nt(),{data:a,isLoading:i,isError:l}=id({destinationId:e}),c=a??[],d=Bb({onSuccess:()=>{r.invalidateQueries({queryKey:[[...KF]]}),r.invalidateQueries({queryKey:GF})}}),u=U(async b=>{await s({title:"Delete this archive?",message:`Permanently deletes "${b.label??b.id}" and frees ${It(b.sizeBytes)}.`,confirmLabel:"Delete",variant:"danger"})&&d.mutate({destinationId:e,backupId:b.id})},[s,e,d]),[p,h]=_(null),m=U(async b=>{h(b.id);try{const x=localStorage.getItem("camstack_admin_token"),y={};x&&(y.Authorization=`Bearer ${x}`);const w=await fetch(YF(e,b.id),{headers:y});if(!w.ok)throw new Error(`download failed: ${w.status} ${w.statusText}`);const v=await w.blob(),N=URL.createObjectURL(v),k=document.createElement("a");k.href=N,k.download=`${b.label??b.id}.tar.gz`,document.body.appendChild(k),k.click(),k.remove(),URL.revokeObjectURL(N)}finally{h(null)}},[e]),g=H(()=>[...c].sort((b,x)=>x.createdAt-b.createdAt),[c]);return i?o("div",{className:"text-xs text-foreground-subtle animate-pulse py-2",children:"Loading archives…"}):l?o("div",{className:"text-xs text-danger py-2",children:"Failed to read manifest for this destination"}):g.length===0?o("div",{className:"text-xs text-foreground-subtle italic py-2",children:"No archives at this destination yet."}):o("div",{className:"rounded border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[640px]",children:[o("thead",{children:f("tr",{className:"text-foreground-subtle bg-background/30",children:[o("th",{className:"text-left px-3 py-1.5 font-medium",children:"When"}),o("th",{className:"text-left px-3 py-1.5 font-medium",children:"Label"}),o("th",{className:"text-left px-3 py-1.5 font-medium",children:"Includes"}),o("th",{className:"text-right px-3 py-1.5 font-medium",children:"Size"}),o("th",{className:"text-right px-3 py-1.5 font-medium w-52",children:"Actions"})]})}),o("tbody",{children:g.map(b=>f("tr",{className:"border-t border-border hover:bg-primary/5",children:[o("td",{className:"px-3 py-1.5 text-foreground tabular-nums",children:ZF(b.createdAt)}),o("td",{className:"px-3 py-1.5 text-foreground",children:b.label??o("span",{className:"text-foreground-subtle italic",children:"—"})}),o("td",{className:"px-3 py-1.5 text-foreground-subtle",children:b.locations.join(", ")}),o("td",{className:"px-3 py-1.5 text-foreground text-right tabular-nums",children:It(b.sizeBytes)}),o("td",{className:"px-3 py-1.5",children:f("div",{className:"flex items-center justify-end gap-1",children:[f("button",{onClick:()=>{m(b)},disabled:p===b.id,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-foreground-subtle hover:text-foreground hover:bg-primary/10 disabled:opacity-50",title:"Download archive",children:[p===b.id?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xt,{className:"h-3 w-3"}),"Download"]}),t&&n&&f("button",{onClick:()=>n({destinationId:e,archiveId:b.id}),className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-primary hover:bg-primary/10",title:"Restore from this archive",children:[o(kt,{className:"h-3 w-3"}),"Restore"]}),o("button",{onClick:()=>{u(b)},disabled:d.isPending,className:"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium text-danger hover:bg-danger/10 disabled:opacity-50",title:"Delete archive",children:d.isPending?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"})})]})})]},b.id))})]})})}function YF(e,t){return`/api/backup/download/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}function ZF(e){return new Date(e).toLocaleString(void 0,{day:"2-digit",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit"})}const Kv=[{id:"manual",label:"Manual only",cron:""},{id:"hourly",label:"Every hour",cron:"0 * * * *",description:"On the hour"},{id:"every-3h",label:"Every 3 hours",cron:"0 */3 * * *",description:"00:00, 03:00, 06:00, 09:00 …"},{id:"every-6h",label:"Every 6 hours",cron:"0 */6 * * *",description:"00:00, 06:00, 12:00, 18:00"},{id:"daily-3am",label:"Daily at 03:00",cron:"0 3 * * *",description:"Every night at 3 AM"},{id:"weekly-sun",label:"Weekly Sunday 03:00",cron:"0 3 * * 0",description:"Sunday morning at 3 AM"}];function XF(e){const t=e.trim();for(const n of Kv)if(n.cron===t)return n.id;return"custom"}function JF({value:e,onChange:t,previewCount:n=5,disabled:r=!1}){const s=XF(e),[a,i]=_(s==="custom");Y(()=>{s!=="custom"&&i(!1)},[s]);const l=nj(e,250),c=Fb({cron:l,count:n},{enabled:l.trim().length>0}),d=c.data??null,u=h=>{i(!1),t(h.cron)},p=a||s==="custom";return f("div",{className:"space-y-3",children:[f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Schedule preset"}),f("div",{className:"flex flex-wrap gap-1.5",children:[Kv.map(h=>{const m=!a&&s===h.id;return o("button",{type:"button",onClick:()=>u(h),disabled:r,className:"rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 "+(m?"border-primary bg-primary/10 text-primary":"border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground"),title:h.description??h.label,children:h.label},h.id)}),o("button",{type:"button",onClick:()=>{i(!0),e.trim().length===0&&t("0 3 * * *")},disabled:r,className:"rounded border px-2 py-1 text-[11px] transition-colors disabled:opacity-50 "+(p?"border-primary bg-primary/10 text-primary":"border-border bg-background text-foreground-subtle hover:bg-primary/5 hover:text-foreground"),children:"Custom…"})]})]}),p&&f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Cron expression (5-field POSIX)"}),o("input",{type:"text",value:e,onChange:h=>t(h.target.value),disabled:r,placeholder:"0 3 * * *",spellCheck:!1,className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs font-mono text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"}),f("p",{className:"text-[10px] text-foreground-subtle",children:["Format: ",o("span",{className:"font-mono",children:"minute hour day-of-month month day-of-week"})," · all times server-local"]})]}),o(ej,{cron:l,preview:d,loading:c.isFetching})]})}function ej({cron:e,preview:t,loading:n}){return n&&t===null?f("div",{className:"flex items-center gap-2 rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle",children:[o(Se,{className:"h-3 w-3 animate-spin"}),"Validating…"]}):t===null?null:t.ok?t.nextRuns.length===0?o("div",{className:"rounded border border-border bg-background/40 px-3 py-2 text-[11px] text-foreground-subtle",children:"No future runs match this expression."}):f("div",{className:"space-y-1",children:[o("div",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle",children:"Next runs"}),o("ul",{className:"rounded border border-border bg-background/40 divide-y divide-border",children:t.nextRuns.map((r,s)=>f("li",{className:"flex items-center justify-between px-3 py-1.5 text-[11px]",children:[o("span",{className:"text-foreground tabular-nums",children:new Date(r).toLocaleString()}),o("span",{className:"text-foreground-subtle text-[10px] tabular-nums",children:tj(r)})]},`${r}-${s}`))})]}):o("div",{className:"rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger",children:t.error??"Invalid cron expression"})}function tj(e){const t=e-Date.now();if(t<=0)return"now";const n=Math.floor(t/1e3);if(n<60)return`in ${n}s`;const r=Math.floor(n/60);if(r<60)return`in ${r}m`;const s=Math.floor(r/60);return s<24?`in ${s}h`:`in ${Math.floor(s/24)}d`}function nj(e,t){const[n,r]=_(e),s=H(()=>e,[e]);return Y(()=>{const a=setTimeout(()=>r(s),t);return()=>clearTimeout(a)},[s,t]),n}const rj=[["backup","listDestinations"]];function oj({onCreateAt:e,onOpenRestoreWizard:t}){const{data:n,isLoading:r,isError:s}=ad(),a=n??[],[i,l]=_(null),c=u=>{l(p=>p===u?null:u)},d=cj();return r?o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Loading destinations…"}):s?o("div",{className:"text-xs text-danger",children:"Failed to load destinations"}):a.length===0?o("div",{className:"rounded-lg border border-border bg-surface px-4 py-8 text-center",children:o("p",{className:"text-xs text-foreground-subtle",children:"No `backups`-typed storage locations registered. Add one in Settings → Storage to begin."})}):o("div",{className:"rounded-lg border border-border bg-surface overflow-x-auto",children:f("table",{className:"w-full text-xs min-w-[720px]",children:[o("thead",{children:f("tr",{className:"text-foreground-subtle border-b border-border bg-background/40",children:[o("th",{className:"text-left px-3 py-2 font-medium w-6"}),o("th",{className:"text-left px-3 py-2 font-medium",children:"Destination"}),o("th",{className:"text-left px-3 py-2 font-medium w-20",children:"Enabled"}),o("th",{className:"text-left px-3 py-2 font-medium w-28",children:"Retention"}),o("th",{className:"text-left px-3 py-2 font-medium w-56",children:"Schedule"}),o("th",{className:"text-left px-3 py-2 font-medium w-44",children:"Last success"}),o("th",{className:"text-right px-3 py-2 font-medium w-44",children:"Actions"})]})}),o("tbody",{children:a.map(u=>{const p=d.get(u.id);return o(sj,{row:u,isOpen:i===u.id,onToggle:()=>c(u.id),onCreateAt:e,liveLastSuccessAt:p?.at,liveLastSuccessSizeBytes:p?.sizeBytes,...t?{onOpenRestoreWizard:t}:{}},u.id)})})]})})}function sj({row:e,isOpen:t,onToggle:n,onCreateAt:r,onOpenRestoreWizard:s,liveLastSuccessAt:a,liveLastSuccessSizeBytes:i}){const l=ke(),c=zb({onSuccess:()=>{l.invalidateQueries({queryKey:rj})}}),[d,u]=_(String(e.retentionCount));Y(()=>{u(String(e.retentionCount))},[e.retentionCount]);const[p,h]=_(!1),m=U(x=>{c.mutate({locationId:e.id,enabled:x,retentionCount:e.retentionCount,...e.label!==void 0?{label:e.label}:{},...e.cron!==void 0?{cron:e.cron}:{}})},[c,e.id,e.retentionCount,e.label,e.cron]),g=U(()=>{const x=Number.parseInt(d,10);if(Number.isNaN(x)||x<1){u(String(e.retentionCount));return}x!==e.retentionCount&&c.mutate({locationId:e.id,enabled:e.enabled,retentionCount:x,...e.label!==void 0?{label:e.label}:{},...e.cron!==void 0?{cron:e.cron}:{}})},[c,d,e.id,e.enabled,e.retentionCount,e.label,e.cron]),b=U(x=>{c.mutate({locationId:e.id,enabled:e.enabled,retentionCount:e.retentionCount,...e.label!==void 0?{label:e.label}:{},cron:x},{onSuccess:()=>{h(!1)}})},[c,e.id,e.enabled,e.retentionCount,e.label]);return f(me,{children:[f("tr",{className:"border-t border-border first:border-t-0 hover:bg-primary/5",children:[o("td",{className:"px-2 py-2",children:o("button",{onClick:n,className:"inline-flex items-center justify-center rounded p-1 text-foreground-subtle hover:bg-primary/10 hover:text-foreground",title:t?"Hide archives":"Show archives",children:t?o(lt,{className:"h-3.5 w-3.5"}):o(wt,{className:"h-3.5 w-3.5"})})}),o("td",{className:"px-3 py-2",children:f("button",{onClick:n,className:"text-left hover:underline focus:outline-none",title:"View archives",children:[o("div",{className:"text-foreground font-medium",children:e.displayName}),f("div",{className:"flex items-center gap-1.5 mt-0.5",children:[o("span",{className:"text-[10px] uppercase tracking-wide text-foreground-subtle bg-background border border-border rounded px-1.5 py-0.5",children:e.kind}),o("span",{className:"text-[10px] text-foreground-subtle font-mono",children:e.id})]})]})}),o("td",{className:"px-3 py-2",children:o("label",{className:"inline-flex items-center cursor-pointer",children:o("input",{type:"checkbox",className:"accent-primary",checked:e.enabled,disabled:c.isPending,onChange:x=>m(x.target.checked)})})}),o("td",{className:"px-3 py-2",children:o("input",{type:"number",min:1,max:1e3,value:d,disabled:c.isPending,onChange:x=>u(x.target.value),onBlur:g,onKeyDown:x=>{x.key==="Enter"&&x.target.blur(),x.key==="Escape"&&u(String(e.retentionCount))},className:"w-16 rounded border border-border bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"})}),o("td",{className:"px-3 py-2",children:o(aj,{cron:e.cron,nextRunAt:e.nextRunAt,onEdit:()=>h(!0),disabled:c.isPending})}),o("td",{className:"px-3 py-2 text-foreground-subtle",children:(()=>{const x=dj(a,e.lastSuccessAt),y=x===a?i:e.lastSuccessSizeBytes;return x!==void 0?o(uj,{at:x,sizeBytes:y}):o("span",{className:"italic",children:"Never"})})()}),o("td",{className:"px-3 py-2",children:o("div",{className:"flex items-center justify-end gap-1.5",children:e.triggerSupported&&f("button",{onClick:()=>r(e),className:"inline-flex items-center gap-1 rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3 w-3"}),"Create here"]})})})]}),t&&o("tr",{className:"border-t border-border bg-background/30",children:o("td",{colSpan:7,className:"px-4 py-3",children:o(WF,{destinationId:e.id,restoreSupported:e.restoreSupported,...s?{onOpenRestoreWizard:s}:{}})})}),p&&o(lj,{destinationName:e.displayName,currentCron:e.cron??"",onSave:b,onClose:()=>h(!1),saving:c.isPending,saveError:c.error instanceof Error?c.error.message:null})]})}function aj({cron:e,nextRunAt:t,onEdit:n,disabled:r}){const s=typeof e=="string"&&e.trim().length>0;return f("button",{type:"button",onClick:n,disabled:r,className:"group flex flex-col items-start gap-0.5 text-left rounded px-1.5 py-1 -mx-1.5 hover:bg-primary/5 disabled:opacity-50",title:"Edit schedule",children:[f("div",{className:"flex items-center gap-1.5",children:[o(PR,{className:"h-3 w-3 text-foreground-subtle group-hover:text-foreground"}),o("span",{className:s?"font-mono text-foreground":"italic text-foreground-subtle",children:s?e:"Manual"})]}),s&&t!==void 0&&f("span",{className:"text-[10px] text-foreground-subtle tabular-nums",children:["next ",ij(t)]})]})}function ij(e){const t=e-Date.now();if(t<=0)return"imminent";const n=Math.floor(t/1e3);if(n<60)return`in ${n}s`;const r=Math.floor(n/60);if(r<60)return`in ${r}m`;const s=Math.floor(r/60);return s<24?`in ${s}h`:`in ${Math.floor(s/24)}d`}function lj({destinationName:e,currentCron:t,onSave:n,onClose:r,saving:s,saveError:a}){const[i,l]=_(t);return o("tr",{children:o("td",{colSpan:7,className:"p-0",children:o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:r,children:f("div",{className:"w-full max-w-lg rounded-xl border border-border bg-surface shadow-2xl",onClick:c=>c.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Schedule"}),f("p",{className:"text-xs text-foreground-subtle",children:["→ ",e]})]}),o("button",{onClick:r,className:"text-foreground-subtle hover:text-foreground",title:"Close",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4",children:[o(JF,{value:i,onChange:l,disabled:s}),a!==null&&o("div",{className:"mt-3 rounded border border-danger/40 bg-danger/10 px-3 py-2 text-[11px] text-danger",children:a})]}),f("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:r,disabled:s,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground disabled:opacity-50",children:"Cancel"}),o("button",{onClick:()=>n(i.trim()),disabled:s||i.trim()===t.trim(),className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:s?"Saving…":"Save"})]})]})})})})}function cj(){const{map:e}=Kc(Ne.BackupCompleted,t=>t.destinationId);return H(()=>{const t=new Map;for(const[n,r]of e)t.set(n,{at:Date.now(),sizeBytes:r.sizeMB*1024*1024});return t},[e])}function dj(e,t){return e===void 0?t:t===void 0||e>t?e:t}function uj({at:e,sizeBytes:t}){const n=pj(e),r=H(()=>new Date(e).toLocaleString(),[e]);return f("span",{title:r,className:"text-foreground tabular-nums",children:[n,t!==void 0&&f("span",{className:"ml-1 text-foreground-subtle",children:["· ",It(t)]})]})}function pj(e){const[,t]=_(0);return Y(()=>{const n=setInterval(()=>t(r=>r+1),3e4);return()=>clearInterval(n)},[]),fj(e)}function fj(e){const t=Math.max(0,Date.now()-e),n=Math.floor(t/1e3);if(n<60)return`${n}s ago`;const r=Math.floor(n/60);if(r<60)return`${r}m ago`;const s=Math.floor(r/60);if(s<24)return`${s}h ago`;const a=Math.floor(s/24);if(a<30)return`${a}d ago`;const i=Math.floor(a/30);return i<12?`${i}mo ago`:`${Math.floor(a/365)}y ago`}const hj=[["backup","list"]];function mj({initialDestinationId:e,initialArchiveId:t,onClose:n,onScheduled:r}){const s=ke(),[a,i]=_(e&&t?2:1),[l,c]=_(e),[d,u]=_(t),[p,h]=_(new Set),{data:m}=ad(),g=m??[],{data:b,isLoading:x}=id({destinationId:l??""},{enabled:!!l}),y=b??[];Y(()=>{if(l!==void 0)return;const z=g.filter(P=>P.restoreSupported);z.length===1&&c(z[0].id)},[l,g]);const{data:w}=Rb({destinationId:l??"",backupId:d??""},{enabled:!!l&&!!d}),v=H(()=>w?.locations??[],[w]);Y(()=>{v.length!==0&&h(z=>z.size===0?new Set(v):z)},[v]);const N=Ob({onSuccess:()=>{s.invalidateQueries({queryKey:hj}),r(),n()}}),k=z=>{h(P=>{const B=new Set(P);return B.has(z)?B.delete(z):B.add(z),B})},C=!!l&&!!d,E=p.size>0,I=C&&E&&!N.isPending,A=()=>{!l||!d||N.mutate({destinationId:l,backupId:d,locations:[...p]})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:n,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:z=>z.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Restore Backup"}),f("p",{className:"text-xs text-foreground-subtle",children:["Step ",a," of 3 — ",a===1?"pick source":a===2?"pick locations":"confirm"]})]}),o("button",{onClick:n,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),a===1&&o(gj,{destinations:g,destinationId:l,onPickDestination:z=>{c(z),u(void 0),h(new Set)},archives:y,archivesLoading:x,archiveId:d,onPickArchive:u}),a===2&&o(bj,{locations:v,picked:p,onToggle:k}),a===3&&o(xj,{destinationName:g.find(z=>z.id===l)?.displayName??l??"",archive:y.find(z=>z.id===d),picked:[...p]}),f("div",{className:"flex justify-between gap-2 border-t border-border px-4 py-3",children:[o("div",{children:a>1&&f("button",{onClick:()=>i(z=>z===3?2:1),className:"inline-flex items-center gap-1 rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:[o(Qd,{className:"h-3 w-3"}),"Back"]})}),f("div",{className:"flex items-center gap-2",children:[o("button",{onClick:n,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),a<3?f("button",{disabled:a===1&&!C||a===2&&!E,onClick:()=>i(z=>z===1?2:3),className:"inline-flex items-center gap-1 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:["Next",o(yR,{className:"h-3 w-3"})]}):f("button",{onClick:A,disabled:!I,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[N.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(kt,{className:"h-3.5 w-3.5"}),"Schedule Restore"]})]})]})]})})}function gj({destinations:e,destinationId:t,onPickDestination:n,archives:r,archivesLoading:s,archiveId:a,onPickArchive:i}){const l=e.filter(c=>c.restoreSupported);return f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Destination"}),f("select",{value:t??"",onChange:c=>n(c.target.value),className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary",children:[o("option",{value:"",disabled:!0,children:"Select destination…"}),l.map(c=>f("option",{value:c.id,children:[c.displayName," (",c.kind,")"]},c.id))]})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Archive"}),!t&&o("div",{className:"text-xs text-foreground-subtle italic",children:"Pick a destination first."}),t&&s&&o("div",{className:"text-xs text-foreground-subtle animate-pulse",children:"Reading archives…"}),t&&!s&&r.length===0&&o("div",{className:"text-xs text-foreground-subtle italic",children:"No archives available at this destination."}),t&&r.length>0&&o("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:r.map(c=>{const d=a===c.id;return f("label",{className:`flex items-center justify-between px-3 py-2 text-xs cursor-pointer ${d?"bg-primary/10":"hover:bg-primary/5"}`,children:[f("div",{className:"flex items-center gap-2",children:[o("input",{type:"radio",name:"archive",checked:d,onChange:()=>i(c.id),className:"accent-primary"}),f("div",{children:[o("div",{className:"font-medium text-foreground",children:c.label??c.id}),o("div",{className:"text-[10px] text-foreground-subtle",children:new Date(c.createdAt).toLocaleString()})]})]}),o("span",{className:"text-[10px] text-foreground-subtle tabular-nums",children:It(c.sizeBytes)})]},c.id)})})]})]})}function bj({locations:e,picked:t,onToggle:n}){return e.length===0?o("div",{className:"p-4",children:o("div",{className:"text-xs text-foreground-subtle",children:"Loading archive manifest… If this persists, the archive may predate manifests — restoring will apply everything in the tarball."})}):f("div",{className:"p-4 space-y-3",children:[o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-700 dark:text-amber-300",children:"Selected entries will overwrite live data on the next server restart. Unchecked entries stay current."}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Apply"}),o("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:e.map(r=>f("label",{className:"flex items-center gap-2 px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer",children:[o("input",{type:"checkbox",checked:t.has(r),onChange:()=>n(r),className:"accent-primary"}),o("span",{className:"font-mono text-foreground",children:r}),o("span",{className:"ml-auto text-[10px] text-foreground-subtle",children:vj(r)})]},r))})]})]})}function xj({destinationName:e,archive:t,picked:n}){return f("div",{className:"p-4 space-y-3 text-xs",children:[o("div",{className:"rounded border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-amber-700 dark:text-amber-300",children:"Restore is applied at next server boot. Active connections will drop when you restart."}),f("dl",{className:"space-y-1.5",children:[o(As,{term:"Destination",value:e}),o(As,{term:"Archive",value:t?.label??t?.id??"—"}),t&&o(As,{term:"Created",value:`${new Date(t.createdAt).toLocaleString()} · ${It(t.sizeBytes)}`}),o(As,{term:"Locations",value:n.length>0?n.join(", "):"— (full archive)"})]})]})}function As({term:e,value:t}){return f("div",{className:"flex justify-between gap-3",children:[o("dt",{className:"text-foreground-subtle",children:e}),o("dd",{className:"text-foreground font-mono text-right truncate",children:t})]})}const yj={db:"Database",addons:"Addon configs","addons-data":"Addon data",tls:"TLS certificates",cache:"Cache",data:"Top-level data"};function vj(e){return yj[e]??""}const wj=[["backup","list"]],Nj=[["backup","listLocations"]];function kj(){const e=ke(),t=nt(),{data:n}=Lb(),r=Tb({onSuccess:()=>{e.invalidateQueries({queryKey:wj}),e.invalidateQueries({queryKey:[["backup","listDestinations"]]}),e.invalidateQueries({queryKey:[["backup","listArchives"]]})}}),s=hb(),[a,i]=_(null),[l,c]=_(null),[d,u]=_(!1),[p,h]=_(!1),[m,g]=_(!1),b=async()=>{await t({title:"Restart server now?",message:"Active connections will drop and the apply-backup hook will run before boot.",confirmLabel:"Restart",variant:"warning"})&&s.mutate({confirm:!0})};return f(tt,{children:[f("div",{className:"flex items-center justify-end gap-2 flex-wrap",children:[f("button",{onClick:()=>u(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-surface border border-border px-3 py-1.5 text-xs font-medium text-foreground hover:bg-primary/5 hover:border-primary/30",children:[o(kt,{className:"h-3.5 w-3.5"}),"Restore…"]}),f("button",{onClick:()=>g(!0),className:"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90",children:[o(Et,{className:"h-3.5 w-3.5"}),"Add destination"]})]}),p&&o("div",{className:"rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2.5 text-xs text-amber-700 dark:text-amber-300",children:f("div",{className:"flex items-center justify-between gap-3",children:[f("div",{className:"flex items-center gap-2",children:[o(kt,{className:"h-3.5 w-3.5"}),o("span",{children:"Restore scheduled. Restart the server to apply."})]}),f("button",{onClick:()=>{b()},disabled:s.isPending,className:"inline-flex items-center gap-1.5 rounded bg-amber-500/20 px-2 py-1 font-medium text-amber-800 dark:text-amber-200 hover:bg-amber-500/30 disabled:opacity-50",children:[s.isPending?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(kt,{className:"h-3.5 w-3.5"}),"Restart Now"]})]})}),o(oj,{onCreateAt:x=>i(x),onOpenRestoreWizard:x=>c(x)}),a&&o(Sj,{destination:a,locations:n??[],onClose:()=>i(null),onSubmit:(x,y)=>{r.mutate({destinations:[a.id],locations:x,label:y||void 0},{onSuccess:()=>{i(null),e.invalidateQueries({queryKey:Nj})}})},submitting:r.isPending}),(l||d)&&o(mj,{...l?{initialDestinationId:l.destinationId,initialArchiveId:l.archiveId}:{},onClose:()=>{c(null),u(!1)},onScheduled:()=>h(!0)}),m&&o(Gv,{initialType:"backups",onClose:()=>g(!1),onCreated:()=>{g(!1),e.invalidateQueries({queryKey:[["backup","listDestinations"]]})}})]})}function Sj({destination:e,locations:t,onClose:n,onSubmit:r,submitting:s}){const a=t.filter(p=>p.present),[i,l]=_(""),[c,d]=_(()=>new Set(a.map(p=>p.name))),u=p=>{d(h=>{const m=new Set(h);return m.has(p)?m.delete(p):m.add(p),m})};return o("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm",onClick:n,children:f("div",{className:"w-full max-w-md rounded-xl border border-border bg-surface shadow-2xl",onClick:p=>p.stopPropagation(),children:[f("div",{className:"flex items-start justify-between border-b border-border px-4 py-3",children:[f("div",{className:"space-y-0.5",children:[o("h2",{className:"text-sm font-semibold text-foreground",children:"Create Backup"}),f("p",{className:"text-xs text-foreground-subtle",children:["→ ",e.displayName]})]}),o("button",{onClick:n,className:"text-foreground-subtle hover:text-foreground",children:o(Fe,{className:"h-4 w-4"})})]}),f("div",{className:"p-4 space-y-3",children:[f("div",{className:"space-y-1",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Label (optional)"}),o("input",{type:"text",value:i,onChange:p=>l(p.target.value),placeholder:"pre-upgrade",className:"w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-primary"})]}),f("div",{className:"space-y-1.5",children:[o("label",{className:"text-[10px] text-foreground-subtle uppercase tracking-wide",children:"Include"}),f("div",{className:"rounded border border-border bg-background divide-y divide-border max-h-64 overflow-y-auto",children:[a.length===0&&o("div",{className:"px-3 py-2 text-xs text-foreground-subtle italic",children:"Nothing to back up."}),a.map(p=>f("label",{className:"flex items-center justify-between px-3 py-2 text-xs hover:bg-primary/5 cursor-pointer",children:[f("div",{className:"flex items-center gap-2",children:[o("input",{type:"checkbox",checked:c.has(p.name),onChange:()=>u(p.name),className:"accent-primary"}),o("span",{className:"font-mono text-foreground",children:p.name})]}),f("div",{className:"text-[10px] text-foreground-subtle tabular-nums",children:[It(p.sizeBytes)," · ",p.fileCount," files"]})]},p.name))]})]})]}),f("div",{className:"flex justify-end gap-2 border-t border-border px-4 py-3",children:[o("button",{onClick:n,className:"rounded px-3 py-1.5 text-xs text-foreground-subtle border border-border hover:text-foreground",children:"Cancel"}),f("button",{onClick:()=>r(Array.from(c),i.trim()),disabled:s||c.size===0,className:"inline-flex items-center gap-1.5 rounded bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",children:[s?o(Se,{className:"h-3.5 w-3.5 animate-spin"}):o(V0,{className:"h-3.5 w-3.5"}),s?"Creating…":"Create"]})]})]})})}function Cj(){return o("div",{className:"flex flex-col p-4",children:o(ri,{tabs:[{id:"storage",label:"Storage",icon:ia,content:o(QF,{})},{id:"backup",label:"Backup",icon:V0,content:o(kj,{})}]})})}function Mj(){const{data:e,isLoading:t}=zn(void 0,{staleTime:3e4}),n=(e??[]).find(s=>s.isHub&&s.isOnline),r=n?.addons.map(s=>s.id)??[];return o(tt,{children:t?o("div",{className:"text-muted-foreground text-sm py-12 text-center",children:"Loading hub topology…"}):n?r.length===0?o("div",{className:"text-muted-foreground text-sm py-12 text-center",children:"No addons installed on the hub yet."}):o(to,{nodeId:n.id,addonIds:r,level:"global"}):f("div",{className:"flex flex-col items-center justify-center text-muted-foreground text-sm gap-2 py-12",children:[o(Jt,{className:"h-8 w-8 opacity-30"}),o("p",{children:"No online hub node found."}),o("p",{className:"text-xs",children:"Settings will appear once the hub is reachable."})]})})}function Ej(e){const t=new FormData;return t.append("file",e.file,e.file.name),t.append("nodeId",e.nodeId),e.addonId&&t.append("addonId",e.addonId),new Promise((n,r)=>{const s=new XMLHttpRequest;s.open("POST","/api/addons/upload"),e.token&&s.setRequestHeader("Authorization",`Bearer ${e.token}`),s.upload.addEventListener("progress",a=>{a.lengthComputable&&e.onProgress(Math.round(a.loaded/a.total*100))}),s.addEventListener("load",()=>{let a;try{a=JSON.parse(s.responseText)}catch{r(new Error(`HTTP ${s.status}`));return}s.status>=200&&s.status<300?n(a):r(new Error(a.error??`HTTP ${s.status}`))}),s.addEventListener("error",()=>r(new Error("Network error during upload"))),s.addEventListener("abort",()=>r(new Error("Upload aborted"))),s.send(t)})}function Ij({nodeId:e,addons:t,isHub:n}){const r=ke(),s=nt(),[a,i]=_(null),[l,c]=_(null),[d,u]=_(!1),[p,h]=_(null),[m,g]=_(0),b=te(null),x=Ba(),y=Dx(),w=Bx({nodeId:e}),v=w.data??[],N=new Map(t.map(P=>[P.id,P.capabilities])),k=v.length>0?v.map(P=>({id:P.id,status:P.status,capabilities:N.get(P.id)??[],version:P.version,packageName:P.packageName})):t.map(P=>({id:P.id,status:P.status,capabilities:P.capabilities,version:void 0,packageName:void 0})),C=()=>{r.invalidateQueries({queryKey:[["nodes","topology"]]}),w.refetch()},E=async P=>{i(P);try{await x.mutateAsync({nodeId:e,addonId:P}),C()}catch(B){console.error("Failed to restart addon:",B)}finally{i(null)}},I=async P=>{if(await s({title:"Uninstall addon",message:`Remove "${P}" from ${e}? The addon directory will be deleted on disk.`,confirmLabel:"Uninstall",variant:"danger"})){c(P);try{await y.mutateAsync({nodeId:e,addonId:P}),C()}catch(R){console.error("Failed to uninstall addon:",R)}finally{c(null)}}},z=f("div",{className:"flex items-center gap-2 mb-2",children:[o("input",{ref:b,type:"file",accept:".tgz,.tar.gz",className:"hidden",onChange:async P=>{const B=P.target.files?.[0];if(B){P.target.value="",h(null),u(!0),g(0);try{const R=localStorage.getItem("camstack_admin_token");await Ej({file:B,nodeId:e,token:R,onProgress:g}),C()}catch(R){h(R instanceof Error?R.message:String(R))}finally{u(!1),g(0)}}}}),f("button",{onClick:()=>b.current?.click(),disabled:d,className:"inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1 text-[11px] font-medium text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors disabled:opacity-50",children:[d?o(Se,{className:"h-3 w-3 animate-spin"}):o(Xa,{className:"h-3 w-3"}),d?`Uploading… ${m}%`:"Upload addon (.tgz)"]}),d&&o("div",{className:"flex-1 h-1 rounded-full bg-muted overflow-hidden max-w-[140px]",children:o("div",{className:"h-full bg-primary transition-all",style:{width:`${m}%`}})}),p&&o("span",{className:"text-[10px] text-destructive",children:p})]});return k.length===0?f("div",{children:[z,o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:w.isLoading?"Loading addons…":"No addons on this node"})]}):f("div",{children:[z,f("table",{className:"w-full text-xs",children:[o("thead",{children:f("tr",{className:"text-muted-foreground text-left",children:[o("th",{className:"py-2 font-medium",children:"Addon"}),o("th",{className:"py-2 font-medium",children:"Version"}),o("th",{className:"py-2 font-medium",children:"Capabilities"}),o("th",{className:"py-2 font-medium",children:"Status"}),o("th",{className:"py-2 font-medium w-16"})]})}),o("tbody",{children:k.map(P=>f("tr",{className:"border-t border-border/50",children:[f("td",{className:"py-2 font-medium",children:[o("div",{children:P.id}),P.packageName&&o("div",{className:"text-[9px] text-muted-foreground",children:P.packageName})]}),o("td",{className:"py-2 text-muted-foreground",children:P.version??"—"}),o("td",{className:"py-2",children:o("div",{className:"flex flex-wrap gap-1",children:P.capabilities.length>0?P.capabilities.map(B=>o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-blue-500/10 text-blue-400",children:B},B)):o("span",{className:"text-muted-foreground",children:"—"})})}),o("td",{className:"py-2",children:o("span",{className:`text-[10px] px-1.5 py-0.5 rounded-full ${P.status==="running"?"bg-success/10 text-success":P.status==="error"?"bg-destructive/10 text-destructive":"bg-muted text-muted-foreground"}`,children:P.status})}),o("td",{className:"py-2",children:f("div",{className:"flex items-center gap-1 justify-end",children:[o("button",{onClick:()=>E(P.id),disabled:a===P.id||l===P.id,className:"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:`Restart ${P.id}`,children:o(kt,{className:`h-3 w-3 ${a===P.id?"animate-spin":""}`})}),o("button",{onClick:()=>I(P.id),disabled:a===P.id||l===P.id,className:"p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-50",title:`Uninstall ${P.id}`,children:l===P.id?o(Se,{className:"h-3 w-3 animate-spin"}):o(Ze,{className:"h-3 w-3"})})]})})]},P.id))})]})]})}function Aj(e){if(e<60)return`${e}s`;const t=Math.floor(e/60);if(t<60)return`${t}m`;const n=Math.floor(t/60);return n<24?`${n}h ${t%60}m`:`${Math.floor(n/24)}d ${n%24}h`}function Pj({state:e}){return o("span",{className:`text-[10px] px-1.5 py-0.5 rounded-full ${e==="running"?"bg-success/10 text-success":e==="crashed"?"bg-destructive/10 text-destructive":"bg-muted text-muted-foreground"}`,children:e})}const _j=["trace","debug","info","warn","error"];function $j({proc:e,nodeId:t,defaultExpanded:n,activePanel:r,onTogglePanel:s}){const a=e.services??[],i=a.length===1,[l,c]=_(i||n),[d,u]=_(null),[p,h]=_("info"),m=e.name.includes("(core)"),g=Ba(),b=Tx(),x=zx(),y=async N=>{u(N);try{await g.mutateAsync({nodeId:t,addonId:N})}catch(k){console.error("Failed to restart addon:",k)}finally{u(null)}},w=async()=>{u(e.name);try{await b.mutateAsync({nodeId:t,processName:e.name})}catch(N){console.error("Failed to restart process:",N)}finally{u(null)}},v=async N=>{const k=`${t}/${e.name}`;try{await x.mutateAsync({nodeId:k,level:N}),h(N)}catch(C){console.error("Failed to set log level:",C)}};return f("div",{className:"border border-border/50 rounded-lg overflow-hidden",children:[f("div",{role:i?void 0:"button",tabIndex:i?void 0:0,onClick:i?void 0:()=>c(!l),onKeyDown:i?void 0:N=>{(N.key==="Enter"||N.key===" ")&&c(!l)},className:`flex items-center gap-2 w-full px-3 py-2 bg-muted/20 transition-colors text-left select-none ${i?"":"hover:bg-muted/40 cursor-pointer"}`,children:[i?o("span",{className:"h-3 w-3 shrink-0"}):l?o(lt,{className:"h-3 w-3 text-muted-foreground shrink-0"}):o(wt,{className:"h-3 w-3 text-muted-foreground shrink-0"}),m?o(hn,{className:"h-3.5 w-3.5 text-primary shrink-0"}):o(Ka,{className:"h-3.5 w-3.5 text-amber-500 shrink-0"}),o("span",{className:"text-xs font-semibold flex-1",children:e.name}),f("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:["PID ",e.pid]}),o(Pj,{state:e.state}),f("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:[e.cpuPercent,"% CPU"]}),o("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:It(e.memoryRss)}),o("span",{className:"text-[10px] text-muted-foreground tabular-nums",children:Aj(e.uptimeSeconds)}),!m&&f("div",{className:"flex items-center gap-1",onClick:N=>N.stopPropagation(),children:[f(bg,{children:[o(xg,{className:"text-[9px] px-1.5 py-0.5 rounded border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors font-mono",title:"Set log level",children:p}),o(yg,{align:"end",className:"min-w-[70px] py-0.5",children:_j.map(N=>o(vg,{onClick:()=>v(N),className:`h-auto px-2 py-1 text-[10px] font-mono ${N===p?"text-primary font-semibold":""}`,children:N},N))})]}),o("button",{onClick:w,disabled:d===e.name,className:"p-1 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:"Restart process",children:o(kt,{className:`h-3 w-3 ${d===e.name?"animate-spin":""}`})})]})]}),l&&a.length>0&&o("div",{className:"divide-y divide-border/30",children:a.map(N=>f("div",{children:[f("div",{className:"flex items-center gap-2 px-3 py-1.5 pl-9 hover:bg-muted/10 transition-colors",children:[o("div",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${N.status==="running"?"bg-success":"bg-muted-foreground/30"}`}),o("span",{className:"text-xs font-medium flex-1 min-w-0 truncate",children:N.addonId}),N.capabilities.length>0&&f("div",{className:"flex gap-1 flex-shrink-0",children:[N.capabilities.slice(0,3).map(k=>o("span",{className:"text-[9px] px-1 py-0.5 rounded bg-blue-500/10 text-blue-400 truncate max-w-[80px]",children:k},k)),N.capabilities.length>3&&f("span",{className:"text-[9px] text-muted-foreground",children:["+",N.capabilities.length-3]})]}),f("div",{className:"flex items-center gap-1 shrink-0",children:[o("button",{onClick:()=>s(N.addonId,"logs"),className:`p-0.5 rounded transition-colors ${r?.addonId===N.addonId&&r.type==="logs"?"bg-primary/10 text-primary":"hover:bg-muted text-muted-foreground hover:text-foreground"}`,title:`Show logs for ${N.addonId}`,children:o(at,{className:"h-3 w-3"})}),o("button",{onClick:()=>s(N.addonId,"events"),className:`p-0.5 rounded transition-colors ${r?.addonId===N.addonId&&r.type==="events"?"bg-primary/10 text-primary":"hover:bg-muted text-muted-foreground hover:text-foreground"}`,title:`Show events for ${N.addonId}`,children:o(Za,{className:"h-3 w-3"})}),o("button",{onClick:()=>y(N.addonId),disabled:d===N.addonId,className:"p-0.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",title:`Restart ${N.addonId}`,children:o(kt,{className:`h-3 w-3 ${d===N.addonId?"animate-spin":""}`})})]})]}),r?.addonId===N.addonId&&r.type==="logs"&&o("div",{className:"border-t border-border/40 bg-muted/5",children:o(tn,{addonId:N.addonId,agentId:t,maxHeight:"max-h-48",showFilters:!1,onClose:()=>s(N.addonId,"logs")})}),r?.addonId===N.addonId&&r.type==="events"&&o("div",{className:"border-t border-border/40 bg-muted/5",children:o(br,{addonId:N.addonId,category:"addon.*",maxHeight:"max-h-48",onClose:()=>s(N.addonId,"events")})})]},N.addonId))}),l&&a.length===0&&o("div",{className:"px-3 py-2 pl-9 text-[10px] text-muted-foreground",children:"No services"})]})}function Dj({nodeId:e,processes:t}){const[n,r]=_(null),s=(a,i)=>{r(l=>l?.addonId===a&&l.type===i?null:{addonId:a,type:i})};return t.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No processes on this node"}):o("div",{className:"space-y-2 py-1",children:t.map((a,i)=>o($j,{proc:a,nodeId:e,defaultExpanded:i===0,activePanel:n,onTogglePanel:s},a.name))})}function Tj(e){return e<60?`${e}s`:e<3600?`${Math.floor(e/60)}m ${e%60}s`:e<86400?`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`:`${Math.floor(e/86400)}d ${Math.floor(e%86400/3600)}h`}function Lj(e,t=80){return e.length<=t?e:`…${e.slice(e.length-t+1)}`}function Rj({nodeId:e}){const t=ke(),n=nt(),[r,s]=_("all"),a=Gr("metrics.node-processes-snapshot",k=>k.nodeId===e),{data:i}=Ex({nodeId:e},{staleTime:6e4}),l=a?.processes??i,c=H(()=>l?[...l]:[],[l]),d=H(()=>r==="ghost"?c.filter(k=>k.classification==="ghost"):c,[c,r]),u=H(()=>{const k=c.filter(E=>E.classification==="ghost"),C=new Map;for(const E of k)C.has(E.ppid)||C.set(E.ppid,[]),C.get(E.ppid).push(E);return[...C.entries()].filter(([,E])=>E.length>1).map(([E,I])=>({ppid:E,children:I})).sort((E,I)=>I.children.length-E.children.length)},[c]),p=Ix({onSettled:()=>{t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]})}}),h=H(()=>{const k=new Map;for(const C of c)k.set(C.pid,C.classification);return k},[c]),m=async(k,C)=>{if(k.classification==="root"||k.classification==="system")return;const E=k.classification==="ghost"?"ghost":k.addonId??"process",I=C?"SIGKILL":"SIGTERM";await n({title:`Send ${I}?`,message:`Target pid ${k.pid} (${E}) on node ${e}.`,confirmLabel:`Send ${I}`,variant:"danger"})&&p.mutate({nodeId:e,pid:k.pid,force:C})},g=async(k,C)=>{try{await p.mutateAsync({nodeId:e,pid:k,force:C})}catch{}},b=async k=>{const C=h.get(k.ppid);if(C==="root"||C==="system"){await n({title:"Cannot kill protected ancestor",message:C==="root"?`pid ${k.ppid} is the current node supervisor. Restart the node via the cluster page instead.`:`pid ${k.ppid} is a system ancestor (concurrently / vite / npm wrapper). Killing it would tear down the dev tree.`,confirmLabel:"OK",cancelLabel:"Close",variant:"warning"});return}await n({title:`Kill ghost parent + ${k.children.length} child(ren)?`,message:`SIGKILL parent pid ${k.ppid} and SIGTERM ${k.children.length} ghost child(ren) on node ${e}.`,confirmLabel:"Kill all",variant:"danger"})&&(await Promise.all([g(k.ppid,!0),...k.children.map(I=>g(I.pid,!1))]),t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}))},x=async()=>{const k=c.filter(E=>E.classification==="ghost");k.length===0||!await n({title:`Kill all ${k.length} ghost process(es)?`,message:`SIGKILL ${k.length} ghost process(es) on node ${e}. This is irreversible.`,confirmLabel:"Kill all",variant:"danger"})||(await Promise.all(k.map(E=>g(E.pid,!0))),t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}))},y=c.filter(k=>k.classification==="ghost").length,w=c.filter(k=>k.classification==="managed").length,v=c.filter(k=>k.classification==="root").length,N=c.filter(k=>k.classification==="system").length;return f("div",{className:"space-y-4",children:[f("div",{className:"flex items-start justify-between gap-4",children:[f("p",{className:"text-[11px] text-foreground-subtle",children:["ps"," scan + kernel `$process.list` cross-reference. Ghosts = camstack-shaped commands with no managed binding (usually orphaned to ppid=1). Refreshes every 10s."]}),f("button",{type:"button",onClick:()=>t.invalidateQueries({queryKey:[["metricsProvider","listNodeProcesses"]]}),className:"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[11px] text-foreground hover:bg-surface-hover",children:[o(ct,{className:"h-3 w-3"})," Refresh"]})]}),f("div",{className:"grid grid-cols-4 gap-3",children:[f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"Root"}),o("div",{className:"text-xl font-semibold text-foreground",children:v})]}),f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"Managed"}),o("div",{className:"text-xl font-semibold text-foreground",children:w})]}),f("div",{className:"rounded-lg border border-border p-3",children:[o("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle",children:"System"}),o("div",{className:"text-xl font-semibold text-foreground",children:N})]}),f("div",{className:`rounded-lg border p-3 ${y>0?"border-destructive/40 bg-destructive/5":"border-border"}`,children:[f("div",{className:"text-[10px] uppercase tracking-wider text-foreground-subtle flex items-center gap-1",children:[y>0&&o(vs,{className:"h-3 w-3 text-destructive"})," Ghosts"]}),o("div",{className:`text-xl font-semibold ${y>0?"text-destructive":"text-foreground"}`,children:y})]})]}),u.length>0&&f("div",{className:"rounded-lg border border-amber-500/40 bg-amber-500/5 p-3",children:[f("div",{className:"flex items-center gap-1 text-[11px] font-semibold text-amber-400 mb-2",children:[o(it,{className:"h-3 w-3"})," Recurring ghost parents (",u.length,")"]}),o("div",{className:"space-y-1.5",children:u.map(k=>f("div",{className:"text-[11px] text-foreground flex items-center justify-between gap-2",children:[f("div",{className:"flex items-center gap-2",children:[f("span",{className:"font-mono text-foreground-subtle",children:["ppid ",k.ppid]}),f("span",{children:["→ ",k.children.length," ghost(s)"]})]}),f("button",{type:"button",disabled:p.isPending,onClick:()=>{b(k)},className:"inline-flex items-center gap-1 rounded border border-amber-500/40 bg-amber-500/10 px-2 py-0.5 text-[10px] text-amber-400 hover:bg-amber-500/20 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill parent + ",k.children.length]})]},k.ppid))})]}),f("div",{className:"flex items-center justify-between gap-2 text-[11px]",children:[f("div",{className:"flex items-center gap-2",children:[o("span",{className:"text-foreground-subtle",children:"Filter:"}),f("button",{type:"button",className:`px-2 py-0.5 rounded ${r==="all"?"bg-primary text-primary-foreground":"border border-border text-foreground hover:bg-surface-hover"}`,onClick:()=>s("all"),children:["All (",c.length,")"]}),f("button",{type:"button",className:`px-2 py-0.5 rounded ${r==="ghost"?"bg-destructive text-destructive-foreground":"border border-border text-foreground hover:bg-surface-hover"}`,onClick:()=>s("ghost"),children:["Ghost only (",y,")"]})]}),y>0&&f("button",{type:"button",disabled:p.isPending,onClick:()=>{x()},className:"inline-flex items-center gap-1 rounded border border-destructive/40 bg-destructive/10 px-2 py-1 text-[11px] font-medium text-destructive hover:bg-destructive/20 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill all ",y," ghost(s)"]})]}),o("div",{className:"rounded-lg border border-border overflow-hidden",children:f("table",{className:"w-full text-xs",children:[o("thead",{className:"bg-surface",children:f("tr",{className:"text-foreground-subtle text-[10px] uppercase tracking-wider",children:[o("th",{className:"text-left px-3 py-2",children:"Class"}),o("th",{className:"text-right px-3 py-2",children:"PID"}),o("th",{className:"text-right px-3 py-2",children:"PPID"}),o("th",{className:"text-left px-3 py-2",children:"Addon"}),o("th",{className:"text-left px-3 py-2",children:"Command"}),o("th",{className:"text-right px-3 py-2",children:"CPU%"}),o("th",{className:"text-right px-3 py-2",children:"RSS"}),o("th",{className:"text-right px-3 py-2",children:"Uptime"}),o("th",{className:"w-44"})]})}),f("tbody",{children:[d.length===0&&o("tr",{children:o("td",{colSpan:9,className:"px-3 py-4 text-center text-foreground-subtle text-[11px]",children:r==="ghost"?"No ghost processes detected.":"Scanning…"})}),d.map(k=>f("tr",{className:`border-t border-border ${k.classification==="ghost"?"bg-destructive/5":""}`,children:[o("td",{className:"px-3 py-2",children:o("span",{className:`inline-block rounded-full px-1.5 py-0.5 text-[10px] font-medium ${k.classification==="ghost"?"bg-destructive/20 text-destructive":k.classification==="root"?"bg-sky-500/20 text-sky-400":k.classification==="system"?"bg-foreground-subtle/20 text-foreground-subtle":"bg-success/20 text-success"}`,children:k.classification})}),o("td",{className:"px-3 py-2 text-right font-mono text-foreground",children:k.pid}),f("td",{className:"px-3 py-2 text-right font-mono text-foreground-subtle",children:[k.ppid,k.orphaned?" ⚠":""]}),o("td",{className:"px-3 py-2 text-foreground-subtle text-[11px]",children:k.addonId??"—"}),o("td",{className:"px-3 py-2 font-mono text-[10px] text-foreground-subtle break-all",children:Lj(k.command)}),o("td",{className:"px-3 py-2 text-right text-foreground",children:k.cpuPercent.toFixed(1)}),o("td",{className:"px-3 py-2 text-right text-foreground",children:It(k.memoryRssBytes)}),o("td",{className:"px-3 py-2 text-right text-foreground-subtle",children:Tj(k.uptimeSec)}),o("td",{className:"px-3 py-2 text-right",children:f("div",{className:"inline-flex gap-1",children:[f("button",{type:"button",disabled:p.isPending||k.classification==="root"||k.classification==="system",onClick:()=>{m(k,!1)},title:"SIGTERM",className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded border border-border text-[10px] text-foreground hover:bg-surface-hover disabled:opacity-30",children:[o(Ze,{className:"h-3 w-3"})," Term"]}),f("button",{type:"button",disabled:p.isPending||k.classification==="root"||k.classification==="system",onClick:()=>{m(k,!0)},title:"SIGKILL",className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded border border-destructive/30 text-[10px] text-destructive hover:bg-destructive/10 disabled:opacity-30",children:[o(vs,{className:"h-3 w-3"})," Kill"]})]})})]},k.pid))]})]})}),p.isError&&f("div",{className:"rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-[11px] text-destructive",children:["Kill failed: ",p.error instanceof Error?p.error.message:"unknown"]})]})}function Oj({nodeId:e,addonIds:t}){return t.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No addons on this node"}):o("div",{className:"w-full py-2",children:o(to,{nodeId:e,addonIds:t,level:"global"})})}function Bj({nodeId:e,addons:t}){const n=ke(),{data:r,isLoading:s}=Zx({nodeId:e}),a=H(()=>{const l=new Map;for(const c of t)for(const d of c.capabilities){const u=l.get(d)??[];u.push(c.id),l.set(d,u)}return[...l.entries()].sort(([c],[d])=>c.localeCompare(d)).map(([c,d])=>({capName:c,providers:d}))},[t]),i=Xx({onSuccess:()=>{n.invalidateQueries({queryKey:[["pipelineOrchestrator","getCapabilityBindings"]]})}});return a.length===0?o("div",{className:"py-4 text-xs text-muted-foreground text-center",children:"No capabilities on this node"}):f("table",{className:"w-full text-xs",children:[o("thead",{children:f("tr",{className:"text-muted-foreground text-left",children:[o("th",{className:"py-2 font-medium w-1/2",children:"Capability"}),o("th",{className:"py-2 font-medium",children:"Bound provider"})]})}),o("tbody",{children:a.map(({capName:l,providers:c})=>{const u=r?.[l]??c[0]??"",p=c.length===1;return f("tr",{className:"border-t border-border/50",children:[o("td",{className:"py-2 font-medium",children:l}),o("td",{className:"py-2",children:o("select",{value:u,onChange:h=>i.mutate({nodeId:e,capName:l,addonId:h.target.value}),disabled:p||i.isPending||s,className:"w-full rounded-md border border-border bg-surface px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-60",title:p?"Only one provider installed — choice becomes available once a second addon registers this capability":void 0,children:c.map(h=>o("option",{value:h,children:h},h))})})]},l)})})]})}function zj(e){if(e==null)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/86400),r=Math.floor(t%86400/3600),s=Math.floor(t%3600/60);return n>0?`${n}d ${r}h ${s}m`:r>0?`${r}h ${s}m`:`${s}m`}function Fj(e){const[t,n]=_(!1),[r,s]=_(e.name),a=ke(),i=Rx({onSuccess:()=>{a.invalidateQueries({queryKey:[["nodes","topology"]]})}}),l=(e.localIps??[]).filter(p=>!p.includes(":")),c=(e.localIps??[]).filter(p=>p.includes(":")),d=async()=>{if(!r.trim()||r===e.name){n(!1);return}try{await i.mutateAsync({nodeId:e.nodeId,name:r.trim()}),n(!1)}catch(p){console.error("Rename failed:",p)}},u=[["Node ID",o("span",{className:"font-mono text-xs",children:e.nodeId})],["Display Name",t?f("div",{className:"flex items-center gap-1.5",children:[o("input",{type:"text",className:"flex-1 px-2 py-0.5 text-xs border border-border rounded bg-background focus:outline-none focus:ring-1 focus:ring-primary",value:r,onChange:p=>s(p.target.value),onKeyDown:p=>{p.key==="Enter"&&d(),p.key==="Escape"&&n(!1)},disabled:i.isPending,autoFocus:!0}),o("button",{onClick:()=>void d(),disabled:i.isPending,className:"p-0.5 text-success hover:bg-success/10 rounded",title:"Save",children:o(_t,{className:"h-3.5 w-3.5"})}),o("button",{onClick:()=>n(!1),className:"p-0.5 text-muted-foreground hover:bg-muted rounded",title:"Cancel",children:o(Fe,{className:"h-3.5 w-3.5"})})]}):f("div",{className:"flex items-center gap-1.5",children:[o("span",{className:"text-xs",children:e.name}),!e.isHub&&o("button",{onClick:()=>{s(e.name),n(!0)},className:"p-0.5 text-muted-foreground hover:text-primary rounded",title:"Rename",children:o(eo,{className:"h-3 w-3"})})]})],["Hostname",o("span",{className:"text-xs",children:e.hostname})],["Role",e.isHub?o("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-primary/10 text-primary font-medium",children:"Hub"}):o("span",{className:"text-[10px] px-1.5 py-0.5 rounded bg-muted text-muted-foreground font-medium",children:"Agent"})],["Platform",f("span",{className:"text-xs",children:[e.platform," / ",e.arch]})],["CPU",f("span",{className:"text-xs",children:[e.cpuModel??"—"," (",e.cpuCores," cores)"]})],["Memory",o("span",{className:"text-xs",children:e.memoryMB>0?`${(e.memoryMB/1024).toFixed(1)} GB`:"—"})],["Uptime",o("span",{className:"text-xs",children:zj(e.uptime)})],["Engines",e.engines.length>0?o("div",{className:"flex flex-wrap gap-1",children:e.engines.map(p=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:p},p))}):o("span",{className:"text-xs text-muted-foreground",children:"—"})]];return l.length>0&&u.push(["IPv4",o("div",{className:"flex flex-wrap gap-1.5",children:l.map((p,h)=>o("span",{className:"font-mono text-xs px-1.5 py-0.5 rounded bg-muted",children:p},`${p}-${h}`))})]),c.length>0&&u.push(["IPv6",o("div",{className:"flex flex-wrap gap-1.5",children:c.map((p,h)=>o("span",{className:"font-mono text-[10px] px-1.5 py-0.5 rounded bg-muted truncate max-w-[280px]",title:p,children:p},`${p}-${h}`))})]),o("div",{className:"py-2",children:o("table",{className:"w-full text-sm",children:o("tbody",{children:u.map(([p,h],m)=>f("tr",{className:m%2===0?"bg-muted/20":"",children:[o("td",{className:"py-1.5 px-2 text-xs font-medium text-muted-foreground w-28 align-top whitespace-nowrap",children:p}),o("td",{className:"py-1.5 px-2",children:h})]},p))})})})}function jj({node:e}){const[t,n]=_("info"),r=e.processes??[],s=e.addons.map(a=>a.id);return e.isOnline?f("div",{className:"border border-border rounded-xl overflow-hidden",children:[f("div",{className:"flex items-center gap-3 px-4 py-3 bg-muted/30 border-b border-border",children:[o("div",{className:"w-2.5 h-2.5 rounded-full bg-success"}),o("span",{className:"text-sm font-semibold",children:e.name}),f("span",{className:"text-xs text-muted-foreground",children:[e.cpuModel??e.platform," · ",e.memoryMB>0?`${Math.round(e.memoryMB/1024)}GB`:""," · ",e.arch]}),e.engines.map(a=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:a},a)),f("div",{className:"ml-auto flex gap-3 text-xs text-muted-foreground",children:[f("span",{className:"flex items-center gap-1",children:[o(bt,{className:"h-3 w-3"})," ",e.cpuPercent,"%"]}),f("span",{className:"flex items-center gap-1",children:[o(Xd,{className:"h-3 w-3"})," ",e.memoryPercent,"%"]})]})]}),o("div",{className:"flex border-b border-border px-4",children:["info","addons","forks","processes","settings","capabilities"].map(a=>o("button",{onClick:()=>n(a),className:`px-3 py-2 text-xs font-medium border-b-2 transition-colors ${t===a?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground"}`,children:a==="info"?"Info":a==="addons"?`Addons (${e.addons.length})`:a==="forks"?`Forks (${r.length})`:a==="processes"?"Processes":a==="settings"?"Settings":"Capabilities"},a))}),f("div",{className:"px-4 py-2",children:[t==="info"&&o(Fj,{nodeId:e.id,name:e.name,hostname:e.hostname,platform:e.platform,arch:e.arch,cpuModel:e.cpuModel,cpuCores:e.cpuCores,memoryMB:e.memoryMB,engines:e.engines,isHub:e.isHub,uptime:e.uptime,localIps:e.localIps}),t==="addons"&&o(Ij,{nodeId:e.id,addons:e.addons,isHub:e.isHub}),t==="forks"&&o(Dj,{nodeId:e.id,processes:r}),t==="processes"&&o(Rj,{nodeId:e.id}),t==="settings"&&o(Oj,{nodeId:e.id,addonIds:s}),t==="capabilities"&&o(Bj,{nodeId:e.id,addons:e.addons})]})]}):f("div",{className:"border border-border rounded-xl overflow-hidden opacity-60",children:[f("div",{className:"flex items-center gap-3 px-4 py-3 bg-muted/30",children:[o("div",{className:"w-2.5 h-2.5 rounded-full bg-destructive"}),o("span",{className:"text-sm font-semibold",children:e.name}),f("span",{className:"text-xs text-muted-foreground",children:[e.cpuModel??e.platform," · ",e.memoryMB>0?`${Math.round(e.memoryMB/1024)}GB`:""," · ",e.arch]}),e.engines.map(a=>o("span",{className:"text-[9px] px-1.5 py-0.5 rounded-full bg-purple-500/10 text-purple-400 font-medium",children:a},a)),o("span",{className:"ml-auto text-xs px-2 py-0.5 rounded-full bg-destructive/10 text-destructive",children:"offline"})]}),f("div",{className:"px-4 py-3 text-xs text-muted-foreground",children:[e.addons.length," addon",e.addons.length!==1?"s":""," assigned — will resume when node reconnects"]})]})}function Vj({nodes:e}){const t=[...e].sort((n,r)=>n.isHub?-1:r.isHub?1:n.isOnline&&!r.isOnline?-1:!n.isOnline&&r.isOnline?1:n.name.localeCompare(r.name));return o("div",{className:"flex flex-col gap-4",children:t.map(n=>o(jj,{node:n},n.id))})}function We(e){if(typeof e=="string"||typeof e=="number")return""+e;let t="";if(Array.isArray(e))for(let n=0,r;n<e.length;n++)(r=We(e[n]))!==""&&(t+=(t&&" ")+r);else for(let n in e)e[n]&&(t+=(t&&" ")+n);return t}var Hj={value:()=>{}};function oi(){for(var e=0,t=arguments.length,n={},r;e<t;++e){if(!(r=arguments[e]+"")||r in n||/[\s.]/.test(r))throw new Error("illegal type: "+r);n[r]=[]}return new Qs(n)}function Qs(e){this._=e}function qj(e,t){return e.trim().split(/^|\s+/).map(function(n){var r="",s=n.indexOf(".");if(s>=0&&(r=n.slice(s+1),n=n.slice(0,s)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}Qs.prototype=oi.prototype={constructor:Qs,on:function(e,t){var n=this._,r=qj(e+"",n),s,a=-1,i=r.length;if(arguments.length<2){for(;++a<i;)if((s=(e=r[a]).type)&&(s=Uj(n[s],e.name)))return s;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++a<i;)if(s=(e=r[a]).type)n[s]=Rf(n[s],e.name,t);else if(t==null)for(s in n)n[s]=Rf(n[s],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new Qs(e)},call:function(e,t){if((s=arguments.length-2)>0)for(var n=new Array(s),r=0,s,a;r<s;++r)n[r]=arguments[r+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(a=this._[e],r=0,s=a.length;r<s;++r)a[r].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var r=this._[e],s=0,a=r.length;s<a;++s)r[s].value.apply(t,n)}};function Uj(e,t){for(var n=0,r=e.length,s;n<r;++n)if((s=e[n]).name===t)return s.value}function Rf(e,t,n){for(var r=0,s=e.length;r<s;++r)if(e[r].name===t){e[r]=Hj,e=e.slice(0,r).concat(e.slice(r+1));break}return n!=null&&e.push({name:t,value:n}),e}var ic="http://www.w3.org/1999/xhtml";const Of={svg:"http://www.w3.org/2000/svg",xhtml:ic,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function si(e){var t=e+="",n=t.indexOf(":");return n>=0&&(t=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),Of.hasOwnProperty(t)?{space:Of[t],local:e}:e}function Qj(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===ic&&t.documentElement.namespaceURI===ic?t.createElement(e):t.createElementNS(n,e)}}function Gj(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Wv(e){var t=si(e);return(t.local?Gj:Qj)(t)}function Kj(){}function ru(e){return e==null?Kj:function(){return this.querySelector(e)}}function Wj(e){typeof e!="function"&&(e=ru(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=new Array(i),c,d,u=0;u<i;++u)(c=a[u])&&(d=e.call(c,c.__data__,u,a))&&("__data__"in c&&(d.__data__=c.__data__),l[u]=d);return new xt(r,this._parents)}function Yj(e){return e==null?[]:Array.isArray(e)?e:Array.from(e)}function Zj(){return[]}function Yv(e){return e==null?Zj:function(){return this.querySelectorAll(e)}}function Xj(e){return function(){return Yj(e.apply(this,arguments))}}function Jj(e){typeof e=="function"?e=Xj(e):e=Yv(e);for(var t=this._groups,n=t.length,r=[],s=[],a=0;a<n;++a)for(var i=t[a],l=i.length,c,d=0;d<l;++d)(c=i[d])&&(r.push(e.call(c,c.__data__,d,i)),s.push(c));return new xt(r,s)}function Zv(e){return function(){return this.matches(e)}}function Xv(e){return function(t){return t.matches(e)}}var eV=Array.prototype.find;function tV(e){return function(){return eV.call(this.children,e)}}function nV(){return this.firstElementChild}function rV(e){return this.select(e==null?nV:tV(typeof e=="function"?e:Xv(e)))}var oV=Array.prototype.filter;function sV(){return Array.from(this.children)}function aV(e){return function(){return oV.call(this.children,e)}}function iV(e){return this.selectAll(e==null?sV:aV(typeof e=="function"?e:Xv(e)))}function lV(e){typeof e!="function"&&(e=Zv(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=[],c,d=0;d<i;++d)(c=a[d])&&e.call(c,c.__data__,d,a)&&l.push(c);return new xt(r,this._parents)}function Jv(e){return new Array(e.length)}function cV(){return new xt(this._enter||this._groups.map(Jv),this._parents)}function ma(e,t){this.ownerDocument=e.ownerDocument,this.namespaceURI=e.namespaceURI,this._next=null,this._parent=e,this.__data__=t}ma.prototype={constructor:ma,appendChild:function(e){return this._parent.insertBefore(e,this._next)},insertBefore:function(e,t){return this._parent.insertBefore(e,t)},querySelector:function(e){return this._parent.querySelector(e)},querySelectorAll:function(e){return this._parent.querySelectorAll(e)}};function dV(e){return function(){return e}}function uV(e,t,n,r,s,a){for(var i=0,l,c=t.length,d=a.length;i<d;++i)(l=t[i])?(l.__data__=a[i],r[i]=l):n[i]=new ma(e,a[i]);for(;i<c;++i)(l=t[i])&&(s[i]=l)}function pV(e,t,n,r,s,a,i){var l,c,d=new Map,u=t.length,p=a.length,h=new Array(u),m;for(l=0;l<u;++l)(c=t[l])&&(h[l]=m=i.call(c,c.__data__,l,t)+"",d.has(m)?s[l]=c:d.set(m,c));for(l=0;l<p;++l)m=i.call(e,a[l],l,a)+"",(c=d.get(m))?(r[l]=c,c.__data__=a[l],d.delete(m)):n[l]=new ma(e,a[l]);for(l=0;l<u;++l)(c=t[l])&&d.get(h[l])===c&&(s[l]=c)}function fV(e){return e.__data__}function hV(e,t){if(!arguments.length)return Array.from(this,fV);var n=t?pV:uV,r=this._parents,s=this._groups;typeof e!="function"&&(e=dV(e));for(var a=s.length,i=new Array(a),l=new Array(a),c=new Array(a),d=0;d<a;++d){var u=r[d],p=s[d],h=p.length,m=mV(e.call(u,u&&u.__data__,d,r)),g=m.length,b=l[d]=new Array(g),x=i[d]=new Array(g),y=c[d]=new Array(h);n(u,p,b,x,y,m,t);for(var w=0,v=0,N,k;w<g;++w)if(N=b[w]){for(w>=v&&(v=w+1);!(k=x[v])&&++v<g;);N._next=k||null}}return i=new xt(i,r),i._enter=l,i._exit=c,i}function mV(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function gV(){return new xt(this._exit||this._groups.map(Jv),this._parents)}function bV(e,t,n){var r=this.enter(),s=this,a=this.exit();return typeof e=="function"?(r=e(r),r&&(r=r.selection())):r=r.append(e+""),t!=null&&(s=t(s),s&&(s=s.selection())),n==null?a.remove():n(a),r&&s?r.merge(s).order():s}function xV(e){for(var t=e.selection?e.selection():e,n=this._groups,r=t._groups,s=n.length,a=r.length,i=Math.min(s,a),l=new Array(s),c=0;c<i;++c)for(var d=n[c],u=r[c],p=d.length,h=l[c]=new Array(p),m,g=0;g<p;++g)(m=d[g]||u[g])&&(h[g]=m);for(;c<s;++c)l[c]=n[c];return new xt(l,this._parents)}function yV(){for(var e=this._groups,t=-1,n=e.length;++t<n;)for(var r=e[t],s=r.length-1,a=r[s],i;--s>=0;)(i=r[s])&&(a&&i.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(i,a),a=i);return this}function vV(e){e||(e=wV);function t(p,h){return p&&h?e(p.__data__,h.__data__):!p-!h}for(var n=this._groups,r=n.length,s=new Array(r),a=0;a<r;++a){for(var i=n[a],l=i.length,c=s[a]=new Array(l),d,u=0;u<l;++u)(d=i[u])&&(c[u]=d);c.sort(t)}return new xt(s,this._parents).order()}function wV(e,t){return e<t?-1:e>t?1:e>=t?0:NaN}function NV(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function kV(){return Array.from(this)}function SV(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],s=0,a=r.length;s<a;++s){var i=r[s];if(i)return i}return null}function CV(){let e=0;for(const t of this)++e;return e}function MV(){return!this.node()}function EV(e){for(var t=this._groups,n=0,r=t.length;n<r;++n)for(var s=t[n],a=0,i=s.length,l;a<i;++a)(l=s[a])&&e.call(l,l.__data__,a,s);return this}function IV(e){return function(){this.removeAttribute(e)}}function AV(e){return function(){this.removeAttributeNS(e.space,e.local)}}function PV(e,t){return function(){this.setAttribute(e,t)}}function _V(e,t){return function(){this.setAttributeNS(e.space,e.local,t)}}function $V(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttribute(e):this.setAttribute(e,n)}}function DV(e,t){return function(){var n=t.apply(this,arguments);n==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,n)}}function TV(e,t){var n=si(e);if(arguments.length<2){var r=this.node();return n.local?r.getAttributeNS(n.space,n.local):r.getAttribute(n)}return this.each((t==null?n.local?AV:IV:typeof t=="function"?n.local?DV:$V:n.local?_V:PV)(n,t))}function e1(e){return e.ownerDocument&&e.ownerDocument.defaultView||e.document&&e||e.defaultView}function LV(e){return function(){this.style.removeProperty(e)}}function RV(e,t,n){return function(){this.style.setProperty(e,t,n)}}function OV(e,t,n){return function(){var r=t.apply(this,arguments);r==null?this.style.removeProperty(e):this.style.setProperty(e,r,n)}}function BV(e,t,n){return arguments.length>1?this.each((t==null?LV:typeof t=="function"?OV:RV)(e,t,n??"")):Lr(this.node(),e)}function Lr(e,t){return e.style.getPropertyValue(t)||e1(e).getComputedStyle(e,null).getPropertyValue(t)}function zV(e){return function(){delete this[e]}}function FV(e,t){return function(){this[e]=t}}function jV(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function VV(e,t){return arguments.length>1?this.each((t==null?zV:typeof t=="function"?jV:FV)(e,t)):this.node()[e]}function t1(e){return e.trim().split(/^|\s+/)}function ou(e){return e.classList||new n1(e)}function n1(e){this._node=e,this._names=t1(e.getAttribute("class")||"")}n1.prototype={add:function(e){var t=this._names.indexOf(e);t<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function r1(e,t){for(var n=ou(e),r=-1,s=t.length;++r<s;)n.add(t[r])}function o1(e,t){for(var n=ou(e),r=-1,s=t.length;++r<s;)n.remove(t[r])}function HV(e){return function(){r1(this,e)}}function qV(e){return function(){o1(this,e)}}function UV(e,t){return function(){(t.apply(this,arguments)?r1:o1)(this,e)}}function QV(e,t){var n=t1(e+"");if(arguments.length<2){for(var r=ou(this.node()),s=-1,a=n.length;++s<a;)if(!r.contains(n[s]))return!1;return!0}return this.each((typeof t=="function"?UV:t?HV:qV)(n,t))}function GV(){this.textContent=""}function KV(e){return function(){this.textContent=e}}function WV(e){return function(){var t=e.apply(this,arguments);this.textContent=t??""}}function YV(e){return arguments.length?this.each(e==null?GV:(typeof e=="function"?WV:KV)(e)):this.node().textContent}function ZV(){this.innerHTML=""}function XV(e){return function(){this.innerHTML=e}}function JV(e){return function(){var t=e.apply(this,arguments);this.innerHTML=t??""}}function eH(e){return arguments.length?this.each(e==null?ZV:(typeof e=="function"?JV:XV)(e)):this.node().innerHTML}function tH(){this.nextSibling&&this.parentNode.appendChild(this)}function nH(){return this.each(tH)}function rH(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function oH(){return this.each(rH)}function sH(e){var t=typeof e=="function"?e:Wv(e);return this.select(function(){return this.appendChild(t.apply(this,arguments))})}function aH(){return null}function iH(e,t){var n=typeof e=="function"?e:Wv(e),r=t==null?aH:typeof t=="function"?t:ru(t);return this.select(function(){return this.insertBefore(n.apply(this,arguments),r.apply(this,arguments)||null)})}function lH(){var e=this.parentNode;e&&e.removeChild(this)}function cH(){return this.each(lH)}function dH(){var e=this.cloneNode(!1),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function uH(){var e=this.cloneNode(!0),t=this.parentNode;return t?t.insertBefore(e,this.nextSibling):e}function pH(e){return this.select(e?uH:dH)}function fH(e){return arguments.length?this.property("__data__",e):this.node().__data__}function hH(e){return function(t){e.call(this,t,this.__data__)}}function mH(e){return e.trim().split(/^|\s+/).map(function(t){var n="",r=t.indexOf(".");return r>=0&&(n=t.slice(r+1),t=t.slice(0,r)),{type:t,name:n}})}function gH(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,s=t.length,a;n<s;++n)a=t[n],(!e.type||a.type===e.type)&&a.name===e.name?this.removeEventListener(a.type,a.listener,a.options):t[++r]=a;++r?t.length=r:delete this.__on}}}function bH(e,t,n){return function(){var r=this.__on,s,a=hH(t);if(r){for(var i=0,l=r.length;i<l;++i)if((s=r[i]).type===e.type&&s.name===e.name){this.removeEventListener(s.type,s.listener,s.options),this.addEventListener(s.type,s.listener=a,s.options=n),s.value=t;return}}this.addEventListener(e.type,a,n),s={type:e.type,name:e.name,value:t,listener:a,options:n},r?r.push(s):this.__on=[s]}}function xH(e,t,n){var r=mH(e+""),s,a=r.length,i;if(arguments.length<2){var l=this.node().__on;if(l){for(var c=0,d=l.length,u;c<d;++c)for(s=0,u=l[c];s<a;++s)if((i=r[s]).type===u.type&&i.name===u.name)return u.value}return}for(l=t?bH:gH,s=0;s<a;++s)this.each(l(r[s],t,n));return this}function s1(e,t,n){var r=e1(e),s=r.CustomEvent;typeof s=="function"?s=new s(t,n):(s=r.document.createEvent("Event"),n?(s.initEvent(t,n.bubbles,n.cancelable),s.detail=n.detail):s.initEvent(t,!1,!1)),e.dispatchEvent(s)}function yH(e,t){return function(){return s1(this,e,t)}}function vH(e,t){return function(){return s1(this,e,t.apply(this,arguments))}}function wH(e,t){return this.each((typeof t=="function"?vH:yH)(e,t))}function*NH(){for(var e=this._groups,t=0,n=e.length;t<n;++t)for(var r=e[t],s=0,a=r.length,i;s<a;++s)(i=r[s])&&(yield i)}var a1=[null];function xt(e,t){this._groups=e,this._parents=t}function rs(){return new xt([[document.documentElement]],a1)}function kH(){return this}xt.prototype=rs.prototype={constructor:xt,select:Wj,selectAll:Jj,selectChild:rV,selectChildren:iV,filter:lV,data:hV,enter:cV,exit:gV,join:bV,merge:xV,selection:kH,order:yV,sort:vV,call:NV,nodes:kV,node:SV,size:CV,empty:MV,each:EV,attr:TV,style:BV,property:VV,classed:QV,text:YV,html:eH,raise:nH,lower:oH,append:sH,insert:iH,remove:cH,clone:pH,datum:fH,on:xH,dispatch:wH,[Symbol.iterator]:NH};function ht(e){return typeof e=="string"?new xt([[document.querySelector(e)]],[document.documentElement]):new xt([[e]],a1)}function SH(e){let t;for(;t=e.sourceEvent;)e=t;return e}function Lt(e,t){if(e=SH(e),t===void 0&&(t=e.currentTarget),t){var n=t.ownerSVGElement||t;if(n.createSVGPoint){var r=n.createSVGPoint();return r.x=e.clientX,r.y=e.clientY,r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}if(t.getBoundingClientRect){var s=t.getBoundingClientRect();return[e.clientX-s.left-t.clientLeft,e.clientY-s.top-t.clientTop]}}return[e.pageX,e.pageY]}const CH={passive:!1},To={capture:!0,passive:!1};function il(e){e.stopImmediatePropagation()}function Ar(e){e.preventDefault(),e.stopImmediatePropagation()}function i1(e){var t=e.document.documentElement,n=ht(e).on("dragstart.drag",Ar,To);"onselectstart"in t?n.on("selectstart.drag",Ar,To):(t.__noselect=t.style.MozUserSelect,t.style.MozUserSelect="none")}function l1(e,t){var n=e.document.documentElement,r=ht(e).on("dragstart.drag",null);t&&(r.on("click.drag",Ar,To),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in n?r.on("selectstart.drag",null):(n.style.MozUserSelect=n.__noselect,delete n.__noselect)}const Ps=e=>()=>e;function lc(e,{sourceEvent:t,subject:n,target:r,identifier:s,active:a,x:i,y:l,dx:c,dy:d,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:s,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:i,enumerable:!0,configurable:!0},y:{value:l,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:d,enumerable:!0,configurable:!0},_:{value:u}})}lc.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function MH(e){return!e.ctrlKey&&!e.button}function EH(){return this.parentNode}function IH(e,t){return t??{x:e.x,y:e.y}}function AH(){return navigator.maxTouchPoints||"ontouchstart"in this}function c1(){var e=MH,t=EH,n=IH,r=AH,s={},a=oi("start","drag","end"),i=0,l,c,d,u,p=0;function h(N){N.on("mousedown.drag",m).filter(r).on("touchstart.drag",x).on("touchmove.drag",y,CH).on("touchend.drag touchcancel.drag",w).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function m(N,k){if(!(u||!e.call(this,N,k))){var C=v(this,t.call(this,N,k),N,k,"mouse");C&&(ht(N.view).on("mousemove.drag",g,To).on("mouseup.drag",b,To),i1(N.view),il(N),d=!1,l=N.clientX,c=N.clientY,C("start",N))}}function g(N){if(Ar(N),!d){var k=N.clientX-l,C=N.clientY-c;d=k*k+C*C>p}s.mouse("drag",N)}function b(N){ht(N.view).on("mousemove.drag mouseup.drag",null),l1(N.view,d),Ar(N),s.mouse("end",N)}function x(N,k){if(e.call(this,N,k)){var C=N.changedTouches,E=t.call(this,N,k),I=C.length,A,z;for(A=0;A<I;++A)(z=v(this,E,N,k,C[A].identifier,C[A]))&&(il(N),z("start",N,C[A]))}}function y(N){var k=N.changedTouches,C=k.length,E,I;for(E=0;E<C;++E)(I=s[k[E].identifier])&&(Ar(N),I("drag",N,k[E]))}function w(N){var k=N.changedTouches,C=k.length,E,I;for(u&&clearTimeout(u),u=setTimeout(function(){u=null},500),E=0;E<C;++E)(I=s[k[E].identifier])&&(il(N),I("end",N,k[E]))}function v(N,k,C,E,I,A){var z=a.copy(),P=Lt(A||C,k),B,R,M;if((M=n.call(N,new lc("beforestart",{sourceEvent:C,target:h,identifier:I,active:i,x:P[0],y:P[1],dx:0,dy:0,dispatch:z}),E))!=null)return B=M.x-P[0]||0,R=M.y-P[1]||0,function D(T,L,O){var F=P,j;switch(T){case"start":s[I]=D,j=i++;break;case"end":delete s[I],--i;case"drag":P=Lt(O||L,k),j=i;break}z.call(T,N,new lc(T,{sourceEvent:L,subject:M,target:h,identifier:I,active:j,x:P[0]+B,y:P[1]+R,dx:P[0]-F[0],dy:P[1]-F[1],dispatch:z}),E)}}return h.filter=function(N){return arguments.length?(e=typeof N=="function"?N:Ps(!!N),h):e},h.container=function(N){return arguments.length?(t=typeof N=="function"?N:Ps(N),h):t},h.subject=function(N){return arguments.length?(n=typeof N=="function"?N:Ps(N),h):n},h.touchable=function(N){return arguments.length?(r=typeof N=="function"?N:Ps(!!N),h):r},h.on=function(){var N=a.on.apply(a,arguments);return N===a?h:N},h.clickDistance=function(N){return arguments.length?(p=(N=+N)*N,h):Math.sqrt(p)},h}function su(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function d1(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function os(){}var Lo=.7,ga=1/Lo,Pr="\\s*([+-]?\\d+)\\s*",Ro="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Yt="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",PH=/^#([0-9a-f]{3,8})$/,_H=new RegExp(`^rgb\\(${Pr},${Pr},${Pr}\\)$`),$H=new RegExp(`^rgb\\(${Yt},${Yt},${Yt}\\)$`),DH=new RegExp(`^rgba\\(${Pr},${Pr},${Pr},${Ro}\\)$`),TH=new RegExp(`^rgba\\(${Yt},${Yt},${Yt},${Ro}\\)$`),LH=new RegExp(`^hsl\\(${Ro},${Yt},${Yt}\\)$`),RH=new RegExp(`^hsla\\(${Ro},${Yt},${Yt},${Ro}\\)$`),Bf={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};su(os,ar,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:zf,formatHex:zf,formatHex8:OH,formatHsl:BH,formatRgb:Ff,toString:Ff});function zf(){return this.rgb().formatHex()}function OH(){return this.rgb().formatHex8()}function BH(){return u1(this).formatHsl()}function Ff(){return this.rgb().formatRgb()}function ar(e){var t,n;return e=(e+"").trim().toLowerCase(),(t=PH.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?jf(t):n===3?new st(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?_s(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?_s(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=_H.exec(e))?new st(t[1],t[2],t[3],1):(t=$H.exec(e))?new st(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=DH.exec(e))?_s(t[1],t[2],t[3],t[4]):(t=TH.exec(e))?_s(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=LH.exec(e))?qf(t[1],t[2]/100,t[3]/100,1):(t=RH.exec(e))?qf(t[1],t[2]/100,t[3]/100,t[4]):Bf.hasOwnProperty(e)?jf(Bf[e]):e==="transparent"?new st(NaN,NaN,NaN,0):null}function jf(e){return new st(e>>16&255,e>>8&255,e&255,1)}function _s(e,t,n,r){return r<=0&&(e=t=n=NaN),new st(e,t,n,r)}function zH(e){return e instanceof os||(e=ar(e)),e?(e=e.rgb(),new st(e.r,e.g,e.b,e.opacity)):new st}function cc(e,t,n,r){return arguments.length===1?zH(e):new st(e,t,n,r??1)}function st(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}su(st,cc,d1(os,{brighter(e){return e=e==null?ga:Math.pow(ga,e),new st(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Lo:Math.pow(Lo,e),new st(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new st(Zn(this.r),Zn(this.g),Zn(this.b),ba(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Vf,formatHex:Vf,formatHex8:FH,formatRgb:Hf,toString:Hf}));function Vf(){return`#${Gn(this.r)}${Gn(this.g)}${Gn(this.b)}`}function FH(){return`#${Gn(this.r)}${Gn(this.g)}${Gn(this.b)}${Gn((isNaN(this.opacity)?1:this.opacity)*255)}`}function Hf(){const e=ba(this.opacity);return`${e===1?"rgb(":"rgba("}${Zn(this.r)}, ${Zn(this.g)}, ${Zn(this.b)}${e===1?")":`, ${e})`}`}function ba(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Zn(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function Gn(e){return e=Zn(e),(e<16?"0":"")+e.toString(16)}function qf(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new Rt(e,t,n,r)}function u1(e){if(e instanceof Rt)return new Rt(e.h,e.s,e.l,e.opacity);if(e instanceof os||(e=ar(e)),!e)return new Rt;if(e instanceof Rt)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,s=Math.min(t,n,r),a=Math.max(t,n,r),i=NaN,l=a-s,c=(a+s)/2;return l?(t===a?i=(n-r)/l+(n<r)*6:n===a?i=(r-t)/l+2:i=(t-n)/l+4,l/=c<.5?a+s:2-a-s,i*=60):l=c>0&&c<1?0:i,new Rt(i,l,c,e.opacity)}function jH(e,t,n,r){return arguments.length===1?u1(e):new Rt(e,t,n,r??1)}function Rt(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}su(Rt,jH,d1(os,{brighter(e){return e=e==null?ga:Math.pow(ga,e),new Rt(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Lo:Math.pow(Lo,e),new Rt(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,s=2*n-r;return new st(ll(e>=240?e-240:e+120,s,r),ll(e,s,r),ll(e<120?e+240:e-120,s,r),this.opacity)},clamp(){return new Rt(Uf(this.h),$s(this.s),$s(this.l),ba(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=ba(this.opacity);return`${e===1?"hsl(":"hsla("}${Uf(this.h)}, ${$s(this.s)*100}%, ${$s(this.l)*100}%${e===1?")":`, ${e})`}`}}));function Uf(e){return e=(e||0)%360,e<0?e+360:e}function $s(e){return Math.max(0,Math.min(1,e||0))}function ll(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const au=e=>()=>e;function VH(e,t){return function(n){return e+n*t}}function HH(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function qH(e){return(e=+e)==1?p1:function(t,n){return n-t?HH(t,n,e):au(isNaN(t)?n:t)}}function p1(e,t){var n=t-e;return n?VH(e,n):au(isNaN(e)?t:e)}const xa=(function e(t){var n=qH(t);function r(s,a){var i=n((s=cc(s)).r,(a=cc(a)).r),l=n(s.g,a.g),c=n(s.b,a.b),d=p1(s.opacity,a.opacity);return function(u){return s.r=i(u),s.g=l(u),s.b=c(u),s.opacity=d(u),s+""}}return r.gamma=e,r})(1);function UH(e,t){t||(t=[]);var n=e?Math.min(t.length,e.length):0,r=t.slice(),s;return function(a){for(s=0;s<n;++s)r[s]=e[s]*(1-a)+t[s]*a;return r}}function QH(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function GH(e,t){var n=t?t.length:0,r=e?Math.min(n,e.length):0,s=new Array(r),a=new Array(n),i;for(i=0;i<r;++i)s[i]=So(e[i],t[i]);for(;i<n;++i)a[i]=t[i];return function(l){for(i=0;i<r;++i)a[i]=s[i](l);return a}}function KH(e,t){var n=new Date;return e=+e,t=+t,function(r){return n.setTime(e*(1-r)+t*r),n}}function Qt(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}function WH(e,t){var n={},r={},s;(e===null||typeof e!="object")&&(e={}),(t===null||typeof t!="object")&&(t={});for(s in t)s in e?n[s]=So(e[s],t[s]):r[s]=t[s];return function(a){for(s in n)r[s]=n[s](a);return r}}var dc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,cl=new RegExp(dc.source,"g");function YH(e){return function(){return e}}function ZH(e){return function(t){return e(t)+""}}function f1(e,t){var n=dc.lastIndex=cl.lastIndex=0,r,s,a,i=-1,l=[],c=[];for(e=e+"",t=t+"";(r=dc.exec(e))&&(s=cl.exec(t));)(a=s.index)>n&&(a=t.slice(n,a),l[i]?l[i]+=a:l[++i]=a),(r=r[0])===(s=s[0])?l[i]?l[i]+=s:l[++i]=s:(l[++i]=null,c.push({i,x:Qt(r,s)})),n=cl.lastIndex;return n<t.length&&(a=t.slice(n),l[i]?l[i]+=a:l[++i]=a),l.length<2?c[0]?ZH(c[0].x):YH(t):(t=c.length,function(d){for(var u=0,p;u<t;++u)l[(p=c[u]).i]=p.x(d);return l.join("")})}function So(e,t){var n=typeof t,r;return t==null||n==="boolean"?au(t):(n==="number"?Qt:n==="string"?(r=ar(t))?(t=r,xa):f1:t instanceof ar?xa:t instanceof Date?KH:QH(t)?UH:Array.isArray(t)?GH:typeof t.valueOf!="function"&&typeof t.toString!="function"||isNaN(t)?WH:Qt)(e,t)}var Qf=180/Math.PI,uc={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function h1(e,t,n,r,s,a){var i,l,c;return(i=Math.sqrt(e*e+t*t))&&(e/=i,t/=i),(c=e*n+t*r)&&(n-=e*c,r-=t*c),(l=Math.sqrt(n*n+r*r))&&(n/=l,r/=l,c/=l),e*r<t*n&&(e=-e,t=-t,c=-c,i=-i),{translateX:s,translateY:a,rotate:Math.atan2(t,e)*Qf,skewX:Math.atan(c)*Qf,scaleX:i,scaleY:l}}var Ds;function XH(e){const t=new(typeof DOMMatrix=="function"?DOMMatrix:WebKitCSSMatrix)(e+"");return t.isIdentity?uc:h1(t.a,t.b,t.c,t.d,t.e,t.f)}function JH(e){return e==null||(Ds||(Ds=document.createElementNS("http://www.w3.org/2000/svg","g")),Ds.setAttribute("transform",e),!(e=Ds.transform.baseVal.consolidate()))?uc:(e=e.matrix,h1(e.a,e.b,e.c,e.d,e.e,e.f))}function m1(e,t,n,r){function s(d){return d.length?d.pop()+" ":""}function a(d,u,p,h,m,g){if(d!==p||u!==h){var b=m.push("translate(",null,t,null,n);g.push({i:b-4,x:Qt(d,p)},{i:b-2,x:Qt(u,h)})}else(p||h)&&m.push("translate("+p+t+h+n)}function i(d,u,p,h){d!==u?(d-u>180?u+=360:u-d>180&&(d+=360),h.push({i:p.push(s(p)+"rotate(",null,r)-2,x:Qt(d,u)})):u&&p.push(s(p)+"rotate("+u+r)}function l(d,u,p,h){d!==u?h.push({i:p.push(s(p)+"skewX(",null,r)-2,x:Qt(d,u)}):u&&p.push(s(p)+"skewX("+u+r)}function c(d,u,p,h,m,g){if(d!==p||u!==h){var b=m.push(s(m)+"scale(",null,",",null,")");g.push({i:b-4,x:Qt(d,p)},{i:b-2,x:Qt(u,h)})}else(p!==1||h!==1)&&m.push(s(m)+"scale("+p+","+h+")")}return function(d,u){var p=[],h=[];return d=e(d),u=e(u),a(d.translateX,d.translateY,u.translateX,u.translateY,p,h),i(d.rotate,u.rotate,p,h),l(d.skewX,u.skewX,p,h),c(d.scaleX,d.scaleY,u.scaleX,u.scaleY,p,h),d=u=null,function(m){for(var g=-1,b=h.length,x;++g<b;)p[(x=h[g]).i]=x.x(m);return p.join("")}}}var eq=m1(XH,"px, ","px)","deg)"),tq=m1(JH,", ",")",")"),nq=1e-12;function Gf(e){return((e=Math.exp(e))+1/e)/2}function rq(e){return((e=Math.exp(e))-1/e)/2}function oq(e){return((e=Math.exp(2*e))-1)/(e+1)}const Gs=(function e(t,n,r){function s(a,i){var l=a[0],c=a[1],d=a[2],u=i[0],p=i[1],h=i[2],m=u-l,g=p-c,b=m*m+g*g,x,y;if(b<nq)y=Math.log(h/d)/t,x=function(E){return[l+E*m,c+E*g,d*Math.exp(t*E*y)]};else{var w=Math.sqrt(b),v=(h*h-d*d+r*b)/(2*d*n*w),N=(h*h-d*d-r*b)/(2*h*n*w),k=Math.log(Math.sqrt(v*v+1)-v),C=Math.log(Math.sqrt(N*N+1)-N);y=(C-k)/t,x=function(E){var I=E*y,A=Gf(k),z=d/(n*w)*(A*oq(t*I+k)-rq(k));return[l+z*m,c+z*g,d*A/Gf(t*I+k)]}}return x.duration=y*1e3*t/Math.SQRT2,x}return s.rho=function(a){var i=Math.max(.001,+a),l=i*i,c=l*l;return e(i,l,c)},s})(Math.SQRT2,2,4);var Rr=0,ho=0,co=0,g1=1e3,ya,mo,va=0,ir=0,ai=0,Oo=typeof performance=="object"&&performance.now?performance:Date,b1=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function iu(){return ir||(b1(sq),ir=Oo.now()+ai)}function sq(){ir=0}function wa(){this._call=this._time=this._next=null}wa.prototype=x1.prototype={constructor:wa,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?iu():+n)+(t==null?0:+t),!this._next&&mo!==this&&(mo?mo._next=this:ya=this,mo=this),this._call=e,this._time=n,pc()},stop:function(){this._call&&(this._call=null,this._time=1/0,pc())}};function x1(e,t,n){var r=new wa;return r.restart(e,t,n),r}function aq(){iu(),++Rr;for(var e=ya,t;e;)(t=ir-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Rr}function Kf(){ir=(va=Oo.now())+ai,Rr=ho=0;try{aq()}finally{Rr=0,lq(),ir=0}}function iq(){var e=Oo.now(),t=e-va;t>g1&&(ai-=t,va=e)}function lq(){for(var e,t=ya,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:ya=n);mo=e,pc(r)}function pc(e){if(!Rr){ho&&(ho=clearTimeout(ho));var t=e-ir;t>24?(e<1/0&&(ho=setTimeout(Kf,e-Oo.now()-ai)),co&&(co=clearInterval(co))):(co||(va=Oo.now(),co=setInterval(iq,g1)),Rr=1,b1(Kf))}}function Wf(e,t,n){var r=new wa;return t=t==null?0:+t,r.restart(s=>{r.stop(),e(s+t)},t,n),r}var cq=oi("start","end","cancel","interrupt"),dq=[],y1=0,Yf=1,fc=2,Ks=3,Zf=4,hc=5,Ws=6;function ii(e,t,n,r,s,a){var i=e.__transition;if(!i)e.__transition={};else if(n in i)return;uq(e,n,{name:t,index:r,group:s,on:cq,tween:dq,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:y1})}function lu(e,t){var n=Ht(e,t);if(n.state>y1)throw new Error("too late; already scheduled");return n}function rn(e,t){var n=Ht(e,t);if(n.state>Ks)throw new Error("too late; already running");return n}function Ht(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw new Error("transition not found");return n}function uq(e,t,n){var r=e.__transition,s;r[t]=n,n.timer=x1(a,0,n.time);function a(d){n.state=Yf,n.timer.restart(i,n.delay,n.time),n.delay<=d&&i(d-n.delay)}function i(d){var u,p,h,m;if(n.state!==Yf)return c();for(u in r)if(m=r[u],m.name===n.name){if(m.state===Ks)return Wf(i);m.state===Zf?(m.state=Ws,m.timer.stop(),m.on.call("interrupt",e,e.__data__,m.index,m.group),delete r[u]):+u<t&&(m.state=Ws,m.timer.stop(),m.on.call("cancel",e,e.__data__,m.index,m.group),delete r[u])}if(Wf(function(){n.state===Ks&&(n.state=Zf,n.timer.restart(l,n.delay,n.time),l(d))}),n.state=fc,n.on.call("start",e,e.__data__,n.index,n.group),n.state===fc){for(n.state=Ks,s=new Array(h=n.tween.length),u=0,p=-1;u<h;++u)(m=n.tween[u].value.call(e,e.__data__,n.index,n.group))&&(s[++p]=m);s.length=p+1}}function l(d){for(var u=d<n.duration?n.ease.call(null,d/n.duration):(n.timer.restart(c),n.state=hc,1),p=-1,h=s.length;++p<h;)s[p].call(e,u);n.state===hc&&(n.on.call("end",e,e.__data__,n.index,n.group),c())}function c(){n.state=Ws,n.timer.stop(),delete r[t];for(var d in r)return;delete e.__transition}}function Ys(e,t){var n=e.__transition,r,s,a=!0,i;if(n){t=t==null?null:t+"";for(i in n){if((r=n[i]).name!==t){a=!1;continue}s=r.state>fc&&r.state<hc,r.state=Ws,r.timer.stop(),r.on.call(s?"interrupt":"cancel",e,e.__data__,r.index,r.group),delete n[i]}a&&delete e.__transition}}function pq(e){return this.each(function(){Ys(this,e)})}function fq(e,t){var n,r;return function(){var s=rn(this,e),a=s.tween;if(a!==n){r=n=a;for(var i=0,l=r.length;i<l;++i)if(r[i].name===t){r=r.slice(),r.splice(i,1);break}}s.tween=r}}function hq(e,t,n){var r,s;if(typeof n!="function")throw new Error;return function(){var a=rn(this,e),i=a.tween;if(i!==r){s=(r=i).slice();for(var l={name:t,value:n},c=0,d=s.length;c<d;++c)if(s[c].name===t){s[c]=l;break}c===d&&s.push(l)}a.tween=s}}function mq(e,t){var n=this._id;if(e+="",arguments.length<2){for(var r=Ht(this.node(),n).tween,s=0,a=r.length,i;s<a;++s)if((i=r[s]).name===e)return i.value;return null}return this.each((t==null?fq:hq)(n,e,t))}function cu(e,t,n){var r=e._id;return e.each(function(){var s=rn(this,r);(s.value||(s.value={}))[t]=n.apply(this,arguments)}),function(s){return Ht(s,r).value[t]}}function v1(e,t){var n;return(typeof t=="number"?Qt:t instanceof ar?xa:(n=ar(t))?(t=n,xa):f1)(e,t)}function gq(e){return function(){this.removeAttribute(e)}}function bq(e){return function(){this.removeAttributeNS(e.space,e.local)}}function xq(e,t,n){var r,s=n+"",a;return function(){var i=this.getAttribute(e);return i===s?null:i===r?a:a=t(r=i,n)}}function yq(e,t,n){var r,s=n+"",a;return function(){var i=this.getAttributeNS(e.space,e.local);return i===s?null:i===r?a:a=t(r=i,n)}}function vq(e,t,n){var r,s,a;return function(){var i,l=n(this),c;return l==null?void this.removeAttribute(e):(i=this.getAttribute(e),c=l+"",i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l)))}}function wq(e,t,n){var r,s,a;return function(){var i,l=n(this),c;return l==null?void this.removeAttributeNS(e.space,e.local):(i=this.getAttributeNS(e.space,e.local),c=l+"",i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l)))}}function Nq(e,t){var n=si(e),r=n==="transform"?tq:v1;return this.attrTween(e,typeof t=="function"?(n.local?wq:vq)(n,r,cu(this,"attr."+e,t)):t==null?(n.local?bq:gq)(n):(n.local?yq:xq)(n,r,t))}function kq(e,t){return function(n){this.setAttribute(e,t.call(this,n))}}function Sq(e,t){return function(n){this.setAttributeNS(e.space,e.local,t.call(this,n))}}function Cq(e,t){var n,r;function s(){var a=t.apply(this,arguments);return a!==r&&(n=(r=a)&&Sq(e,a)),n}return s._value=t,s}function Mq(e,t){var n,r;function s(){var a=t.apply(this,arguments);return a!==r&&(n=(r=a)&&kq(e,a)),n}return s._value=t,s}function Eq(e,t){var n="attr."+e;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(t==null)return this.tween(n,null);if(typeof t!="function")throw new Error;var r=si(e);return this.tween(n,(r.local?Cq:Mq)(r,t))}function Iq(e,t){return function(){lu(this,e).delay=+t.apply(this,arguments)}}function Aq(e,t){return t=+t,function(){lu(this,e).delay=t}}function Pq(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?Iq:Aq)(t,e)):Ht(this.node(),t).delay}function _q(e,t){return function(){rn(this,e).duration=+t.apply(this,arguments)}}function $q(e,t){return t=+t,function(){rn(this,e).duration=t}}function Dq(e){var t=this._id;return arguments.length?this.each((typeof e=="function"?_q:$q)(t,e)):Ht(this.node(),t).duration}function Tq(e,t){if(typeof t!="function")throw new Error;return function(){rn(this,e).ease=t}}function Lq(e){var t=this._id;return arguments.length?this.each(Tq(t,e)):Ht(this.node(),t).ease}function Rq(e,t){return function(){var n=t.apply(this,arguments);if(typeof n!="function")throw new Error;rn(this,e).ease=n}}function Oq(e){if(typeof e!="function")throw new Error;return this.each(Rq(this._id,e))}function Bq(e){typeof e!="function"&&(e=Zv(e));for(var t=this._groups,n=t.length,r=new Array(n),s=0;s<n;++s)for(var a=t[s],i=a.length,l=r[s]=[],c,d=0;d<i;++d)(c=a[d])&&e.call(c,c.__data__,d,a)&&l.push(c);return new bn(r,this._parents,this._name,this._id)}function zq(e){if(e._id!==this._id)throw new Error;for(var t=this._groups,n=e._groups,r=t.length,s=n.length,a=Math.min(r,s),i=new Array(r),l=0;l<a;++l)for(var c=t[l],d=n[l],u=c.length,p=i[l]=new Array(u),h,m=0;m<u;++m)(h=c[m]||d[m])&&(p[m]=h);for(;l<r;++l)i[l]=t[l];return new bn(i,this._parents,this._name,this._id)}function Fq(e){return(e+"").trim().split(/^|\s+/).every(function(t){var n=t.indexOf(".");return n>=0&&(t=t.slice(0,n)),!t||t==="start"})}function jq(e,t,n){var r,s,a=Fq(t)?lu:rn;return function(){var i=a(this,e),l=i.on;l!==r&&(s=(r=l).copy()).on(t,n),i.on=s}}function Vq(e,t){var n=this._id;return arguments.length<2?Ht(this.node(),n).on.on(e):this.each(jq(n,e,t))}function Hq(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function qq(){return this.on("end.remove",Hq(this._id))}function Uq(e){var t=this._name,n=this._id;typeof e!="function"&&(e=ru(e));for(var r=this._groups,s=r.length,a=new Array(s),i=0;i<s;++i)for(var l=r[i],c=l.length,d=a[i]=new Array(c),u,p,h=0;h<c;++h)(u=l[h])&&(p=e.call(u,u.__data__,h,l))&&("__data__"in u&&(p.__data__=u.__data__),d[h]=p,ii(d[h],t,n,h,d,Ht(u,n)));return new bn(a,this._parents,t,n)}function Qq(e){var t=this._name,n=this._id;typeof e!="function"&&(e=Yv(e));for(var r=this._groups,s=r.length,a=[],i=[],l=0;l<s;++l)for(var c=r[l],d=c.length,u,p=0;p<d;++p)if(u=c[p]){for(var h=e.call(u,u.__data__,p,c),m,g=Ht(u,n),b=0,x=h.length;b<x;++b)(m=h[b])&&ii(m,t,n,b,h,g);a.push(h),i.push(u)}return new bn(a,i,t,n)}var Gq=rs.prototype.constructor;function Kq(){return new Gq(this._groups,this._parents)}function Wq(e,t){var n,r,s;return function(){var a=Lr(this,e),i=(this.style.removeProperty(e),Lr(this,e));return a===i?null:a===n&&i===r?s:s=t(n=a,r=i)}}function w1(e){return function(){this.style.removeProperty(e)}}function Yq(e,t,n){var r,s=n+"",a;return function(){var i=Lr(this,e);return i===s?null:i===r?a:a=t(r=i,n)}}function Zq(e,t,n){var r,s,a;return function(){var i=Lr(this,e),l=n(this),c=l+"";return l==null&&(c=l=(this.style.removeProperty(e),Lr(this,e))),i===c?null:i===r&&c===s?a:(s=c,a=t(r=i,l))}}function Xq(e,t){var n,r,s,a="style."+t,i="end."+a,l;return function(){var c=rn(this,e),d=c.on,u=c.value[a]==null?l||(l=w1(t)):void 0;(d!==n||s!==u)&&(r=(n=d).copy()).on(i,s=u),c.on=r}}function Jq(e,t,n){var r=(e+="")=="transform"?eq:v1;return t==null?this.styleTween(e,Wq(e,r)).on("end.style."+e,w1(e)):typeof t=="function"?this.styleTween(e,Zq(e,r,cu(this,"style."+e,t))).each(Xq(this._id,e)):this.styleTween(e,Yq(e,r,t),n).on("end.style."+e,null)}function eU(e,t,n){return function(r){this.style.setProperty(e,t.call(this,r),n)}}function tU(e,t,n){var r,s;function a(){var i=t.apply(this,arguments);return i!==s&&(r=(s=i)&&eU(e,i,n)),r}return a._value=t,a}function nU(e,t,n){var r="style."+(e+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(t==null)return this.tween(r,null);if(typeof t!="function")throw new Error;return this.tween(r,tU(e,t,n??""))}function rU(e){return function(){this.textContent=e}}function oU(e){return function(){var t=e(this);this.textContent=t??""}}function sU(e){return this.tween("text",typeof e=="function"?oU(cu(this,"text",e)):rU(e==null?"":e+""))}function aU(e){return function(t){this.textContent=e.call(this,t)}}function iU(e){var t,n;function r(){var s=e.apply(this,arguments);return s!==n&&(t=(n=s)&&aU(s)),t}return r._value=e,r}function lU(e){var t="text";if(arguments.length<1)return(t=this.tween(t))&&t._value;if(e==null)return this.tween(t,null);if(typeof e!="function")throw new Error;return this.tween(t,iU(e))}function cU(){for(var e=this._name,t=this._id,n=N1(),r=this._groups,s=r.length,a=0;a<s;++a)for(var i=r[a],l=i.length,c,d=0;d<l;++d)if(c=i[d]){var u=Ht(c,t);ii(c,e,n,d,i,{time:u.time+u.delay+u.duration,delay:0,duration:u.duration,ease:u.ease})}return new bn(r,this._parents,e,n)}function dU(){var e,t,n=this,r=n._id,s=n.size();return new Promise(function(a,i){var l={value:i},c={value:function(){--s===0&&a()}};n.each(function(){var d=rn(this,r),u=d.on;u!==e&&(t=(e=u).copy(),t._.cancel.push(l),t._.interrupt.push(l),t._.end.push(c)),d.on=t}),s===0&&a()})}var uU=0;function bn(e,t,n,r){this._groups=e,this._parents=t,this._name=n,this._id=r}function N1(){return++uU}var an=rs.prototype;bn.prototype={constructor:bn,select:Uq,selectAll:Qq,selectChild:an.selectChild,selectChildren:an.selectChildren,filter:Bq,merge:zq,selection:Kq,transition:cU,call:an.call,nodes:an.nodes,node:an.node,size:an.size,empty:an.empty,each:an.each,on:Vq,attr:Nq,attrTween:Eq,style:Jq,styleTween:nU,text:sU,textTween:lU,remove:qq,tween:mq,delay:Pq,duration:Dq,ease:Lq,easeVarying:Oq,end:dU,[Symbol.iterator]:an[Symbol.iterator]};function pU(e){return((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2}var fU={time:null,delay:0,duration:250,ease:pU};function hU(e,t){for(var n;!(n=e.__transition)||!(n=n[t]);)if(!(e=e.parentNode))throw new Error(`transition ${t} not found`);return n}function mU(e){var t,n;e instanceof bn?(t=e._id,e=e._name):(t=N1(),(n=fU).time=iu(),e=e==null?null:e+"");for(var r=this._groups,s=r.length,a=0;a<s;++a)for(var i=r[a],l=i.length,c,d=0;d<l;++d)(c=i[d])&&ii(c,e,t,d,i,n||hU(c,t));return new bn(r,this._parents,e,t)}rs.prototype.interrupt=pq;rs.prototype.transition=mU;const Ts=e=>()=>e;function gU(e,{sourceEvent:t,target:n,transform:r,dispatch:s}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:s}})}function dn(e,t,n){this.k=e,this.x=t,this.y=n}dn.prototype={constructor:dn,scale:function(e){return e===1?this:new dn(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new dn(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var li=new dn(1,0,0);k1.prototype=dn.prototype;function k1(e){for(;!e.__zoom;)if(!(e=e.parentNode))return li;return e.__zoom}function dl(e){e.stopImmediatePropagation()}function uo(e){e.preventDefault(),e.stopImmediatePropagation()}function bU(e){return(!e.ctrlKey||e.type==="wheel")&&!e.button}function xU(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute("viewBox")?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Xf(){return this.__zoom||li}function yU(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function vU(){return navigator.maxTouchPoints||"ontouchstart"in this}function wU(e,t,n){var r=e.invertX(t[0][0])-n[0][0],s=e.invertX(t[1][0])-n[1][0],a=e.invertY(t[0][1])-n[0][1],i=e.invertY(t[1][1])-n[1][1];return e.translate(s>r?(r+s)/2:Math.min(0,r)||Math.max(0,s),i>a?(a+i)/2:Math.min(0,a)||Math.max(0,i))}function S1(){var e=bU,t=xU,n=wU,r=yU,s=vU,a=[0,1/0],i=[[-1/0,-1/0],[1/0,1/0]],l=250,c=Gs,d=oi("start","zoom","end"),u,p,h,m=500,g=150,b=0,x=10;function y(M){M.property("__zoom",Xf).on("wheel.zoom",I,{passive:!1}).on("mousedown.zoom",A).on("dblclick.zoom",z).filter(s).on("touchstart.zoom",P).on("touchmove.zoom",B).on("touchend.zoom touchcancel.zoom",R).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}y.transform=function(M,D,T,L){var O=M.selection?M.selection():M;O.property("__zoom",Xf),M!==O?k(M,D,T,L):O.interrupt().each(function(){C(this,arguments).event(L).start().zoom(null,typeof D=="function"?D.apply(this,arguments):D).end()})},y.scaleBy=function(M,D,T,L){y.scaleTo(M,function(){var O=this.__zoom.k,F=typeof D=="function"?D.apply(this,arguments):D;return O*F},T,L)},y.scaleTo=function(M,D,T,L){y.transform(M,function(){var O=t.apply(this,arguments),F=this.__zoom,j=T==null?N(O):typeof T=="function"?T.apply(this,arguments):T,V=F.invert(j),$=typeof D=="function"?D.apply(this,arguments):D;return n(v(w(F,$),j,V),O,i)},T,L)},y.translateBy=function(M,D,T,L){y.transform(M,function(){return n(this.__zoom.translate(typeof D=="function"?D.apply(this,arguments):D,typeof T=="function"?T.apply(this,arguments):T),t.apply(this,arguments),i)},null,L)},y.translateTo=function(M,D,T,L,O){y.transform(M,function(){var F=t.apply(this,arguments),j=this.__zoom,V=L==null?N(F):typeof L=="function"?L.apply(this,arguments):L;return n(li.translate(V[0],V[1]).scale(j.k).translate(typeof D=="function"?-D.apply(this,arguments):-D,typeof T=="function"?-T.apply(this,arguments):-T),F,i)},L,O)};function w(M,D){return D=Math.max(a[0],Math.min(a[1],D)),D===M.k?M:new dn(D,M.x,M.y)}function v(M,D,T){var L=D[0]-T[0]*M.k,O=D[1]-T[1]*M.k;return L===M.x&&O===M.y?M:new dn(M.k,L,O)}function N(M){return[(+M[0][0]+ +M[1][0])/2,(+M[0][1]+ +M[1][1])/2]}function k(M,D,T,L){M.on("start.zoom",function(){C(this,arguments).event(L).start()}).on("interrupt.zoom end.zoom",function(){C(this,arguments).event(L).end()}).tween("zoom",function(){var O=this,F=arguments,j=C(O,F).event(L),V=t.apply(O,F),$=T==null?N(V):typeof T=="function"?T.apply(O,F):T,q=Math.max(V[1][0]-V[0][0],V[1][1]-V[0][1]),G=O.__zoom,Z=typeof D=="function"?D.apply(O,F):D,oe=c(G.invert($).concat(q/G.k),Z.invert($).concat(q/Z.k));return function(ne){if(ne===1)ne=Z;else{var X=oe(ne),re=q/X[2];ne=new dn(re,$[0]-X[0]*re,$[1]-X[1]*re)}j.zoom(null,ne)}})}function C(M,D,T){return!T&&M.__zooming||new E(M,D)}function E(M,D){this.that=M,this.args=D,this.active=0,this.sourceEvent=null,this.extent=t.apply(M,D),this.taps=0}E.prototype={event:function(M){return M&&(this.sourceEvent=M),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(M,D){return this.mouse&&M!=="mouse"&&(this.mouse[1]=D.invert(this.mouse[0])),this.touch0&&M!=="touch"&&(this.touch0[1]=D.invert(this.touch0[0])),this.touch1&&M!=="touch"&&(this.touch1[1]=D.invert(this.touch1[0])),this.that.__zoom=D,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(M){var D=ht(this.that).datum();d.call(M,this.that,new gU(M,{sourceEvent:this.sourceEvent,target:y,transform:this.that.__zoom,dispatch:d}),D)}};function I(M,...D){if(!e.apply(this,arguments))return;var T=C(this,D).event(M),L=this.__zoom,O=Math.max(a[0],Math.min(a[1],L.k*Math.pow(2,r.apply(this,arguments)))),F=Lt(M);if(T.wheel)(T.mouse[0][0]!==F[0]||T.mouse[0][1]!==F[1])&&(T.mouse[1]=L.invert(T.mouse[0]=F)),clearTimeout(T.wheel);else{if(L.k===O)return;T.mouse=[F,L.invert(F)],Ys(this),T.start()}uo(M),T.wheel=setTimeout(j,g),T.zoom("mouse",n(v(w(L,O),T.mouse[0],T.mouse[1]),T.extent,i));function j(){T.wheel=null,T.end()}}function A(M,...D){if(h||!e.apply(this,arguments))return;var T=M.currentTarget,L=C(this,D,!0).event(M),O=ht(M.view).on("mousemove.zoom",$,!0).on("mouseup.zoom",q,!0),F=Lt(M,T),j=M.clientX,V=M.clientY;i1(M.view),dl(M),L.mouse=[F,this.__zoom.invert(F)],Ys(this),L.start();function $(G){if(uo(G),!L.moved){var Z=G.clientX-j,oe=G.clientY-V;L.moved=Z*Z+oe*oe>b}L.event(G).zoom("mouse",n(v(L.that.__zoom,L.mouse[0]=Lt(G,T),L.mouse[1]),L.extent,i))}function q(G){O.on("mousemove.zoom mouseup.zoom",null),l1(G.view,L.moved),uo(G),L.event(G).end()}}function z(M,...D){if(e.apply(this,arguments)){var T=this.__zoom,L=Lt(M.changedTouches?M.changedTouches[0]:M,this),O=T.invert(L),F=T.k*(M.shiftKey?.5:2),j=n(v(w(T,F),L,O),t.apply(this,D),i);uo(M),l>0?ht(this).transition().duration(l).call(k,j,L,M):ht(this).call(y.transform,j,L,M)}}function P(M,...D){if(e.apply(this,arguments)){var T=M.touches,L=T.length,O=C(this,D,M.changedTouches.length===L).event(M),F,j,V,$;for(dl(M),j=0;j<L;++j)V=T[j],$=Lt(V,this),$=[$,this.__zoom.invert($),V.identifier],O.touch0?!O.touch1&&O.touch0[2]!==$[2]&&(O.touch1=$,O.taps=0):(O.touch0=$,F=!0,O.taps=1+!!u);u&&(u=clearTimeout(u)),F&&(O.taps<2&&(p=$[0],u=setTimeout(function(){u=null},m)),Ys(this),O.start())}}function B(M,...D){if(this.__zooming){var T=C(this,D).event(M),L=M.changedTouches,O=L.length,F,j,V,$;for(uo(M),F=0;F<O;++F)j=L[F],V=Lt(j,this),T.touch0&&T.touch0[2]===j.identifier?T.touch0[0]=V:T.touch1&&T.touch1[2]===j.identifier&&(T.touch1[0]=V);if(j=T.that.__zoom,T.touch1){var q=T.touch0[0],G=T.touch0[1],Z=T.touch1[0],oe=T.touch1[1],ne=(ne=Z[0]-q[0])*ne+(ne=Z[1]-q[1])*ne,X=(X=oe[0]-G[0])*X+(X=oe[1]-G[1])*X;j=w(j,Math.sqrt(ne/X)),V=[(q[0]+Z[0])/2,(q[1]+Z[1])/2],$=[(G[0]+oe[0])/2,(G[1]+oe[1])/2]}else if(T.touch0)V=T.touch0[0],$=T.touch0[1];else return;T.zoom("touch",n(v(j,V,$),T.extent,i))}}function R(M,...D){if(this.__zooming){var T=C(this,D).event(M),L=M.changedTouches,O=L.length,F,j;for(dl(M),h&&clearTimeout(h),h=setTimeout(function(){h=null},m),F=0;F<O;++F)j=L[F],T.touch0&&T.touch0[2]===j.identifier?delete T.touch0:T.touch1&&T.touch1[2]===j.identifier&&delete T.touch1;if(T.touch1&&!T.touch0&&(T.touch0=T.touch1,delete T.touch1),T.touch0)T.touch0[1]=this.__zoom.invert(T.touch0[0]);else if(T.end(),T.taps===2&&(j=Lt(j,this),Math.hypot(p[0]-j[0],p[1]-j[1])<x)){var V=ht(this).on("dblclick.zoom");V&&V.apply(this,arguments)}}}return y.wheelDelta=function(M){return arguments.length?(r=typeof M=="function"?M:Ts(+M),y):r},y.filter=function(M){return arguments.length?(e=typeof M=="function"?M:Ts(!!M),y):e},y.touchable=function(M){return arguments.length?(s=typeof M=="function"?M:Ts(!!M),y):s},y.extent=function(M){return arguments.length?(t=typeof M=="function"?M:Ts([[+M[0][0],+M[0][1]],[+M[1][0],+M[1][1]]]),y):t},y.scaleExtent=function(M){return arguments.length?(a[0]=+M[0],a[1]=+M[1],y):[a[0],a[1]]},y.translateExtent=function(M){return arguments.length?(i[0][0]=+M[0][0],i[1][0]=+M[1][0],i[0][1]=+M[0][1],i[1][1]=+M[1][1],y):[[i[0][0],i[0][1]],[i[1][0],i[1][1]]]},y.constrain=function(M){return arguments.length?(n=M,y):n},y.duration=function(M){return arguments.length?(l=+M,y):l},y.interpolate=function(M){return arguments.length?(c=M,y):c},y.on=function(){var M=d.on.apply(d,arguments);return M===d?y:M},y.clickDistance=function(M){return arguments.length?(b=(M=+M)*M,y):Math.sqrt(b)},y.tapDistance=function(M){return arguments.length?(x=+M,y):x},y}const en={error001:()=>"[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001",error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>"The React Flow parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,{id:t,sourceHandle:n,targetHandle:r})=>`Couldn't create edge for ${e} handle id: "${e==="source"?n:r}", edge id: ${t}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(e="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${e}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs."},Bo=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],C1=["Enter"," ","Escape"],M1={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:e,x:t,y:n})=>`Moved selected node ${e}. New position, x: ${t}, y: ${n}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var Or;(function(e){e.Strict="strict",e.Loose="loose"})(Or||(Or={}));var Xn;(function(e){e.Free="free",e.Vertical="vertical",e.Horizontal="horizontal"})(Xn||(Xn={}));var zo;(function(e){e.Partial="partial",e.Full="full"})(zo||(zo={}));const E1={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var En;(function(e){e.Bezier="default",e.Straight="straight",e.Step="step",e.SmoothStep="smoothstep",e.SimpleBezier="simplebezier"})(En||(En={}));var Na;(function(e){e.Arrow="arrow",e.ArrowClosed="arrowclosed"})(Na||(Na={}));var we;(function(e){e.Left="left",e.Top="top",e.Right="right",e.Bottom="bottom"})(we||(we={}));const Jf={[we.Left]:we.Right,[we.Right]:we.Left,[we.Top]:we.Bottom,[we.Bottom]:we.Top};function I1(e){return e===null?null:e?"valid":"invalid"}const A1=e=>"id"in e&&"source"in e&&"target"in e,NU=e=>"id"in e&&"position"in e&&!("source"in e)&&!("target"in e),du=e=>"id"in e&&"internals"in e&&!("source"in e)&&!("target"in e),ss=(e,t=[0,0])=>{const{width:n,height:r}=Nn(e),s=e.origin??t,a=n*s[0],i=r*s[1];return{x:e.position.x-a,y:e.position.y-i}},kU=(e,t={nodeOrigin:[0,0]})=>{if(e.length===0)return{x:0,y:0,width:0,height:0};const n=e.reduce((r,s)=>{const a=typeof s=="string";let i=!t.nodeLookup&&!a?s:void 0;t.nodeLookup&&(i=a?t.nodeLookup.get(s):du(s)?s:t.nodeLookup.get(s.id));const l=i?ka(i,t.nodeOrigin):{x:0,y:0,x2:0,y2:0};return ci(r,l)},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return di(n)},as=(e,t={})=>{let n={x:1/0,y:1/0,x2:-1/0,y2:-1/0},r=!1;return e.forEach(s=>{(t.filter===void 0||t.filter(s))&&(n=ci(n,ka(s)),r=!0)}),r?di(n):{x:0,y:0,width:0,height:0}},uu=(e,t,[n,r,s]=[0,0,1],a=!1,i=!1)=>{const l={...ls(t,[n,r,s]),width:t.width/s,height:t.height/s},c=[];for(const d of e.values()){const{measured:u,selectable:p=!0,hidden:h=!1}=d;if(i&&!p||h)continue;const m=u.width??d.width??d.initialWidth??null,g=u.height??d.height??d.initialHeight??null,b=Fo(l,zr(d)),x=(m??0)*(g??0),y=a&&b>0;(!d.internals.handleBounds||y||b>=x||d.dragging)&&c.push(d)}return c},SU=(e,t)=>{const n=new Set;return e.forEach(r=>{n.add(r.id)}),t.filter(r=>n.has(r.source)||n.has(r.target))};function CU(e,t){const n=new Map,r=t?.nodes?new Set(t.nodes.map(s=>s.id)):null;return e.forEach(s=>{s.measured.width&&s.measured.height&&(t?.includeHiddenNodes||!s.hidden)&&(!r||r.has(s.id))&&n.set(s.id,s)}),n}async function MU({nodes:e,width:t,height:n,panZoom:r,minZoom:s,maxZoom:a},i){if(e.size===0)return Promise.resolve(!0);const l=CU(e,i),c=as(l),d=pu(c,t,n,i?.minZoom??s,i?.maxZoom??a,i?.padding??.1);return await r.setViewport(d,{duration:i?.duration,ease:i?.ease,interpolate:i?.interpolate}),Promise.resolve(!0)}function P1({nodeId:e,nextPosition:t,nodeLookup:n,nodeOrigin:r=[0,0],nodeExtent:s,onError:a}){const i=n.get(e),l=i.parentId?n.get(i.parentId):void 0,{x:c,y:d}=l?l.internals.positionAbsolute:{x:0,y:0},u=i.origin??r;let p=i.extent||s;if(i.extent==="parent"&&!i.expandParent)if(!l)a?.("005",en.error005());else{const m=l.measured.width,g=l.measured.height;m&&g&&(p=[[c,d],[c+m,d+g]])}else l&&Fr(i.extent)&&(p=[[i.extent[0][0]+c,i.extent[0][1]+d],[i.extent[1][0]+c,i.extent[1][1]+d]]);const h=Fr(p)?lr(t,p,i.measured):t;return(i.measured.width===void 0||i.measured.height===void 0)&&a?.("015",en.error015()),{position:{x:h.x-c+(i.measured.width??0)*u[0],y:h.y-d+(i.measured.height??0)*u[1]},positionAbsolute:h}}async function EU({nodesToRemove:e=[],edgesToRemove:t=[],nodes:n,edges:r,onBeforeDelete:s}){const a=new Set(e.map(h=>h.id)),i=[];for(const h of n){if(h.deletable===!1)continue;const m=a.has(h.id),g=!m&&h.parentId&&i.find(b=>b.id===h.parentId);(m||g)&&i.push(h)}const l=new Set(t.map(h=>h.id)),c=r.filter(h=>h.deletable!==!1),u=SU(i,c);for(const h of c)l.has(h.id)&&!u.find(g=>g.id===h.id)&&u.push(h);if(!s)return{edges:u,nodes:i};const p=await s({nodes:i,edges:u});return typeof p=="boolean"?p?{edges:u,nodes:i}:{edges:[],nodes:[]}:p}const Br=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),lr=(e={x:0,y:0},t,n)=>({x:Br(e.x,t[0][0],t[1][0]-(n?.width??0)),y:Br(e.y,t[0][1],t[1][1]-(n?.height??0))});function _1(e,t,n){const{width:r,height:s}=Nn(n),{x:a,y:i}=n.internals.positionAbsolute;return lr(e,[[a,i],[a+r,i+s]],t)}const eh=(e,t,n)=>e<t?Br(Math.abs(e-t),1,t)/t:e>n?-Br(Math.abs(e-n),1,t)/t:0,$1=(e,t,n=15,r=40)=>{const s=eh(e.x,r,t.width-r)*n,a=eh(e.y,r,t.height-r)*n;return[s,a]},ci=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),mc=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),di=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),zr=(e,t=[0,0])=>{const{x:n,y:r}=du(e)?e.internals.positionAbsolute:ss(e,t);return{x:n,y:r,width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}},ka=(e,t=[0,0])=>{const{x:n,y:r}=du(e)?e.internals.positionAbsolute:ss(e,t);return{x:n,y:r,x2:n+(e.measured?.width??e.width??e.initialWidth??0),y2:r+(e.measured?.height??e.height??e.initialHeight??0)}},D1=(e,t)=>di(ci(mc(e),mc(t))),Fo=(e,t)=>{const n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},th=e=>Ot(e.width)&&Ot(e.height)&&Ot(e.x)&&Ot(e.y),Ot=e=>!isNaN(e)&&isFinite(e),IU=(e,t)=>{},is=(e,t=[1,1])=>({x:t[0]*Math.round(e.x/t[0]),y:t[1]*Math.round(e.y/t[1])}),ls=({x:e,y:t},[n,r,s],a=!1,i=[1,1])=>{const l={x:(e-n)/s,y:(t-r)/s};return a?is(l,i):l},Sa=({x:e,y:t},[n,r,s])=>({x:e*s+n,y:t*s+r});function vr(e,t){if(typeof e=="number")return Math.floor((t-t/(1+e))*.5);if(typeof e=="string"&&e.endsWith("px")){const n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(n)}if(typeof e=="string"&&e.endsWith("%")){const n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(t*n*.01)}return console.error(`[React Flow] The padding value "${e}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function AU(e,t,n){if(typeof e=="string"||typeof e=="number"){const r=vr(e,n),s=vr(e,t);return{top:r,right:s,bottom:r,left:s,x:s*2,y:r*2}}if(typeof e=="object"){const r=vr(e.top??e.y??0,n),s=vr(e.bottom??e.y??0,n),a=vr(e.left??e.x??0,t),i=vr(e.right??e.x??0,t);return{top:r,right:i,bottom:s,left:a,x:a+i,y:r+s}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function PU(e,t,n,r,s,a){const{x:i,y:l}=Sa(e,[t,n,r]),{x:c,y:d}=Sa({x:e.x+e.width,y:e.y+e.height},[t,n,r]),u=s-c,p=a-d;return{left:Math.floor(i),top:Math.floor(l),right:Math.floor(u),bottom:Math.floor(p)}}const pu=(e,t,n,r,s,a)=>{const i=AU(a,t,n),l=(t-i.x)/e.width,c=(n-i.y)/e.height,d=Math.min(l,c),u=Br(d,r,s),p=e.x+e.width/2,h=e.y+e.height/2,m=t/2-p*u,g=n/2-h*u,b=PU(e,m,g,u,t,n),x={left:Math.min(b.left-i.left,0),top:Math.min(b.top-i.top,0),right:Math.min(b.right-i.right,0),bottom:Math.min(b.bottom-i.bottom,0)};return{x:m-x.left+x.right,y:g-x.top+x.bottom,zoom:u}},jo=()=>typeof navigator<"u"&&navigator?.userAgent?.indexOf("Mac")>=0;function Fr(e){return e!=null&&e!=="parent"}function Nn(e){return{width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}}function T1(e){return(e.measured?.width??e.width??e.initialWidth)!==void 0&&(e.measured?.height??e.height??e.initialHeight)!==void 0}function L1(e,t={width:0,height:0},n,r,s){const a={...e},i=r.get(n);if(i){const l=i.origin||s;a.x+=i.internals.positionAbsolute.x-(t.width??0)*l[0],a.y+=i.internals.positionAbsolute.y-(t.height??0)*l[1]}return a}function nh(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}function _U(){let e,t;return{promise:new Promise((r,s)=>{e=r,t=s}),resolve:e,reject:t}}function $U(e){return{...M1,...e||{}}}function Co(e,{snapGrid:t=[0,0],snapToGrid:n=!1,transform:r,containerBounds:s}){const{x:a,y:i}=Bt(e),l=ls({x:a-(s?.left??0),y:i-(s?.top??0)},r),{x:c,y:d}=n?is(l,t):l;return{xSnapped:c,ySnapped:d,...l}}const fu=e=>({width:e.offsetWidth,height:e.offsetHeight}),R1=e=>e?.getRootNode?.()||window?.document,DU=["INPUT","SELECT","TEXTAREA"];function O1(e){const t=e.composedPath?.()?.[0]||e.target;return t?.nodeType!==1?!1:DU.includes(t.nodeName)||t.hasAttribute("contenteditable")||!!t.closest(".nokey")}const B1=e=>"clientX"in e,Bt=(e,t)=>{const n=B1(e),r=n?e.clientX:e.touches?.[0].clientX,s=n?e.clientY:e.touches?.[0].clientY;return{x:r-(t?.left??0),y:s-(t?.top??0)}},rh=(e,t,n,r,s)=>{const a=t.querySelectorAll(`.${e}`);return!a||!a.length?null:Array.from(a).map(i=>{const l=i.getBoundingClientRect();return{id:i.getAttribute("data-handleid"),type:e,nodeId:s,position:i.getAttribute("data-handlepos"),x:(l.left-n.left)/r,y:(l.top-n.top)/r,...fu(i)}})};function z1({sourceX:e,sourceY:t,targetX:n,targetY:r,sourceControlX:s,sourceControlY:a,targetControlX:i,targetControlY:l}){const c=e*.125+s*.375+i*.375+n*.125,d=t*.125+a*.375+l*.375+r*.125,u=Math.abs(c-e),p=Math.abs(d-t);return[c,d,u,p]}function Ls(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function oh({pos:e,x1:t,y1:n,x2:r,y2:s,c:a}){switch(e){case we.Left:return[t-Ls(t-r,a),n];case we.Right:return[t+Ls(r-t,a),n];case we.Top:return[t,n-Ls(n-s,a)];case we.Bottom:return[t,n+Ls(s-n,a)]}}function F1({sourceX:e,sourceY:t,sourcePosition:n=we.Bottom,targetX:r,targetY:s,targetPosition:a=we.Top,curvature:i=.25}){const[l,c]=oh({pos:n,x1:e,y1:t,x2:r,y2:s,c:i}),[d,u]=oh({pos:a,x1:r,y1:s,x2:e,y2:t,c:i}),[p,h,m,g]=z1({sourceX:e,sourceY:t,targetX:r,targetY:s,sourceControlX:l,sourceControlY:c,targetControlX:d,targetControlY:u});return[`M${e},${t} C${l},${c} ${d},${u} ${r},${s}`,p,h,m,g]}function j1({sourceX:e,sourceY:t,targetX:n,targetY:r}){const s=Math.abs(n-e)/2,a=n<e?n+s:n-s,i=Math.abs(r-t)/2,l=r<t?r+i:r-i;return[a,l,s,i]}function TU({sourceNode:e,targetNode:t,selected:n=!1,zIndex:r=0,elevateOnSelect:s=!1,zIndexMode:a="basic"}){if(a==="manual")return r;const i=s&&n?r+1e3:r,l=Math.max(e.parentId||s&&e.selected?e.internals.z:0,t.parentId||s&&t.selected?t.internals.z:0);return i+l}function LU({sourceNode:e,targetNode:t,width:n,height:r,transform:s}){const a=ci(ka(e),ka(t));a.x===a.x2&&(a.x2+=1),a.y===a.y2&&(a.y2+=1);const i={x:-s[0]/s[2],y:-s[1]/s[2],width:n/s[2],height:r/s[2]};return Fo(i,di(a))>0}const RU=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`xy-edge__${e}${t||""}-${n}${r||""}`,OU=(e,t)=>t.some(n=>n.source===e.source&&n.target===e.target&&(n.sourceHandle===e.sourceHandle||!n.sourceHandle&&!e.sourceHandle)&&(n.targetHandle===e.targetHandle||!n.targetHandle&&!e.targetHandle)),BU=(e,t,n={})=>{if(!e.source||!e.target)return t;const r=n.getEdgeId||RU;let s;return A1(e)?s={...e}:s={...e,id:r(e)},OU(s,t)?t:(s.sourceHandle===null&&delete s.sourceHandle,s.targetHandle===null&&delete s.targetHandle,t.concat(s))};function V1({sourceX:e,sourceY:t,targetX:n,targetY:r}){const[s,a,i,l]=j1({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,s,a,i,l]}const sh={[we.Left]:{x:-1,y:0},[we.Right]:{x:1,y:0},[we.Top]:{x:0,y:-1},[we.Bottom]:{x:0,y:1}},zU=({source:e,sourcePosition:t=we.Bottom,target:n})=>t===we.Left||t===we.Right?e.x<n.x?{x:1,y:0}:{x:-1,y:0}:e.y<n.y?{x:0,y:1}:{x:0,y:-1},ah=(e,t)=>Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));function FU({source:e,sourcePosition:t=we.Bottom,target:n,targetPosition:r=we.Top,center:s,offset:a,stepPosition:i}){const l=sh[t],c=sh[r],d={x:e.x+l.x*a,y:e.y+l.y*a},u={x:n.x+c.x*a,y:n.y+c.y*a},p=zU({source:d,sourcePosition:t,target:u}),h=p.x!==0?"x":"y",m=p[h];let g=[],b,x;const y={x:0,y:0},w={x:0,y:0},[,,v,N]=j1({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(l[h]*c[h]===-1){h==="x"?(b=s.x??d.x+(u.x-d.x)*i,x=s.y??(d.y+u.y)/2):(b=s.x??(d.x+u.x)/2,x=s.y??d.y+(u.y-d.y)*i);const I=[{x:b,y:d.y},{x:b,y:u.y}],A=[{x:d.x,y:x},{x:u.x,y:x}];l[h]===m?g=h==="x"?I:A:g=h==="x"?A:I}else{const I=[{x:d.x,y:u.y}],A=[{x:u.x,y:d.y}];if(h==="x"?g=l.x===m?A:I:g=l.y===m?I:A,t===r){const M=Math.abs(e[h]-n[h]);if(M<=a){const D=Math.min(a-1,a-M);l[h]===m?y[h]=(d[h]>e[h]?-1:1)*D:w[h]=(u[h]>n[h]?-1:1)*D}}if(t!==r){const M=h==="x"?"y":"x",D=l[h]===c[M],T=d[M]>u[M],L=d[M]<u[M];(l[h]===1&&(!D&&T||D&&L)||l[h]!==1&&(!D&&L||D&&T))&&(g=h==="x"?I:A)}const z={x:d.x+y.x,y:d.y+y.y},P={x:u.x+w.x,y:u.y+w.y},B=Math.max(Math.abs(z.x-g[0].x),Math.abs(P.x-g[0].x)),R=Math.max(Math.abs(z.y-g[0].y),Math.abs(P.y-g[0].y));B>=R?(b=(z.x+P.x)/2,x=g[0].y):(b=g[0].x,x=(z.y+P.y)/2)}const k={x:d.x+y.x,y:d.y+y.y},C={x:u.x+w.x,y:u.y+w.y};return[[e,...k.x!==g[0].x||k.y!==g[0].y?[k]:[],...g,...C.x!==g[g.length-1].x||C.y!==g[g.length-1].y?[C]:[],n],b,x,v,N]}function jU(e,t,n,r){const s=Math.min(ah(e,t)/2,ah(t,n)/2,r),{x:a,y:i}=t;if(e.x===a&&a===n.x||e.y===i&&i===n.y)return`L${a} ${i}`;if(e.y===i){const d=e.x<n.x?-1:1,u=e.y<n.y?1:-1;return`L ${a+s*d},${i}Q ${a},${i} ${a},${i+s*u}`}const l=e.x<n.x?1:-1,c=e.y<n.y?-1:1;return`L ${a},${i+s*c}Q ${a},${i} ${a+s*l},${i}`}function gc({sourceX:e,sourceY:t,sourcePosition:n=we.Bottom,targetX:r,targetY:s,targetPosition:a=we.Top,borderRadius:i=5,centerX:l,centerY:c,offset:d=20,stepPosition:u=.5}){const[p,h,m,g,b]=FU({source:{x:e,y:t},sourcePosition:n,target:{x:r,y:s},targetPosition:a,center:{x:l,y:c},offset:d,stepPosition:u});let x=`M${p[0].x} ${p[0].y}`;for(let y=1;y<p.length-1;y++)x+=jU(p[y-1],p[y],p[y+1],i);return x+=`L${p[p.length-1].x} ${p[p.length-1].y}`,[x,h,m,g,b]}function ih(e){return e&&!!(e.internals.handleBounds||e.handles?.length)&&!!(e.measured.width||e.width||e.initialWidth)}function VU(e){const{sourceNode:t,targetNode:n}=e;if(!ih(t)||!ih(n))return null;const r=t.internals.handleBounds||lh(t.handles),s=n.internals.handleBounds||lh(n.handles),a=ch(r?.source??[],e.sourceHandle),i=ch(e.connectionMode===Or.Strict?s?.target??[]:(s?.target??[]).concat(s?.source??[]),e.targetHandle);if(!a||!i)return e.onError?.("008",en.error008(a?"target":"source",{id:e.id,sourceHandle:e.sourceHandle,targetHandle:e.targetHandle})),null;const l=a?.position||we.Bottom,c=i?.position||we.Top,d=cr(t,a,l),u=cr(n,i,c);return{sourceX:d.x,sourceY:d.y,targetX:u.x,targetY:u.y,sourcePosition:l,targetPosition:c}}function lh(e){if(!e)return null;const t=[],n=[];for(const r of e)r.width=r.width??1,r.height=r.height??1,r.type==="source"?t.push(r):r.type==="target"&&n.push(r);return{source:t,target:n}}function cr(e,t,n=we.Left,r=!1){const s=(t?.x??0)+e.internals.positionAbsolute.x,a=(t?.y??0)+e.internals.positionAbsolute.y,{width:i,height:l}=t??Nn(e);if(r)return{x:s+i/2,y:a+l/2};switch(t?.position??n){case we.Top:return{x:s+i/2,y:a};case we.Right:return{x:s+i,y:a+l/2};case we.Bottom:return{x:s+i/2,y:a+l};case we.Left:return{x:s,y:a+l/2}}}function ch(e,t){return e&&(t?e.find(n=>n.id===t):e[0])||null}function bc(e,t){return e?typeof e=="string"?e:`${t?`${t}__`:""}${Object.keys(e).sort().map(r=>`${r}=${e[r]}`).join("&")}`:""}function HU(e,{id:t,defaultColor:n,defaultMarkerStart:r,defaultMarkerEnd:s}){const a=new Set;return e.reduce((i,l)=>([l.markerStart||r,l.markerEnd||s].forEach(c=>{if(c&&typeof c=="object"){const d=bc(c,t);a.has(d)||(i.push({id:d,color:c.color||n,...c}),a.add(d))}}),i),[]).sort((i,l)=>i.id.localeCompare(l.id))}const H1=1e3,qU=10,hu={nodeOrigin:[0,0],nodeExtent:Bo,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},UU={...hu,checkEquality:!0};function mu(e,t){const n={...e};for(const r in t)t[r]!==void 0&&(n[r]=t[r]);return n}function QU(e,t,n){const r=mu(hu,n);for(const s of e.values())if(s.parentId)bu(s,e,t,r);else{const a=ss(s,r.nodeOrigin),i=Fr(s.extent)?s.extent:r.nodeExtent,l=lr(a,i,Nn(s));s.internals.positionAbsolute=l}}function GU(e,t){if(!e.handles)return e.measured?t?.internals.handleBounds:void 0;const n=[],r=[];for(const s of e.handles){const a={id:s.id,width:s.width??1,height:s.height??1,nodeId:e.id,x:s.x,y:s.y,position:s.position,type:s.type};s.type==="source"?n.push(a):s.type==="target"&&r.push(a)}return{source:n,target:r}}function gu(e){return e==="manual"}function xc(e,t,n,r={}){const s=mu(UU,r),a={i:0},i=new Map(t),l=s?.elevateNodesOnSelect&&!gu(s.zIndexMode)?H1:0;let c=e.length>0,d=!1;t.clear(),n.clear();for(const u of e){let p=i.get(u.id);if(s.checkEquality&&u===p?.internals.userNode)t.set(u.id,p);else{const h=ss(u,s.nodeOrigin),m=Fr(u.extent)?u.extent:s.nodeExtent,g=lr(h,m,Nn(u));p={...s.defaults,...u,measured:{width:u.measured?.width,height:u.measured?.height},internals:{positionAbsolute:g,handleBounds:GU(u,p),z:q1(u,l,s.zIndexMode),userNode:u}},t.set(u.id,p)}(p.measured===void 0||p.measured.width===void 0||p.measured.height===void 0)&&!p.hidden&&(c=!1),u.parentId&&bu(p,t,n,r,a),d||=u.selected??!1}return{nodesInitialized:c,hasSelectedNodes:d}}function KU(e,t){if(!e.parentId)return;const n=t.get(e.parentId);n?n.set(e.id,e):t.set(e.parentId,new Map([[e.id,e]]))}function bu(e,t,n,r,s){const{elevateNodesOnSelect:a,nodeOrigin:i,nodeExtent:l,zIndexMode:c}=mu(hu,r),d=e.parentId,u=t.get(d);if(!u){console.warn(`Parent node ${d} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}KU(e,n),s&&!u.parentId&&u.internals.rootParentIndex===void 0&&c==="auto"&&(u.internals.rootParentIndex=++s.i,u.internals.z=u.internals.z+s.i*qU),s&&u.internals.rootParentIndex!==void 0&&(s.i=u.internals.rootParentIndex);const p=a&&!gu(c)?H1:0,{x:h,y:m,z:g}=WU(e,u,i,l,p,c),{positionAbsolute:b}=e.internals,x=h!==b.x||m!==b.y;(x||g!==e.internals.z)&&t.set(e.id,{...e,internals:{...e.internals,positionAbsolute:x?{x:h,y:m}:b,z:g}})}function q1(e,t,n){const r=Ot(e.zIndex)?e.zIndex:0;return gu(n)?r:r+(e.selected?t:0)}function WU(e,t,n,r,s,a){const{x:i,y:l}=t.internals.positionAbsolute,c=Nn(e),d=ss(e,n),u=Fr(e.extent)?lr(d,e.extent,c):d;let p=lr({x:i+u.x,y:l+u.y},r,c);e.extent==="parent"&&(p=_1(p,c,t));const h=q1(e,s,a),m=t.internals.z??0;return{x:p.x,y:p.y,z:m>=h?m+1:h}}function xu(e,t,n,r=[0,0]){const s=[],a=new Map;for(const i of e){const l=t.get(i.parentId);if(!l)continue;const c=a.get(i.parentId)?.expandedRect??zr(l),d=D1(c,i.rect);a.set(i.parentId,{expandedRect:d,parent:l})}return a.size>0&&a.forEach(({expandedRect:i,parent:l},c)=>{const d=l.internals.positionAbsolute,u=Nn(l),p=l.origin??r,h=i.x<d.x?Math.round(Math.abs(d.x-i.x)):0,m=i.y<d.y?Math.round(Math.abs(d.y-i.y)):0,g=Math.max(u.width,Math.round(i.width)),b=Math.max(u.height,Math.round(i.height)),x=(g-u.width)*p[0],y=(b-u.height)*p[1];(h>0||m>0||x||y)&&(s.push({id:c,type:"position",position:{x:l.position.x-h+x,y:l.position.y-m+y}}),n.get(c)?.forEach(w=>{e.some(v=>v.id===w.id)||s.push({id:w.id,type:"position",position:{x:w.position.x+h,y:w.position.y+m}})})),(u.width<i.width||u.height<i.height||h||m)&&s.push({id:c,type:"dimensions",setAttributes:!0,dimensions:{width:g+(h?p[0]*h-x:0),height:b+(m?p[1]*m-y:0)}})}),s}function YU(e,t,n,r,s,a,i){const l=r?.querySelector(".xyflow__viewport");let c=!1;if(!l)return{changes:[],updatedInternals:c};const d=[],u=window.getComputedStyle(l),{m22:p}=new window.DOMMatrixReadOnly(u.transform),h=[];for(const m of e.values()){const g=t.get(m.id);if(!g)continue;if(g.hidden){t.set(g.id,{...g,internals:{...g.internals,handleBounds:void 0}}),c=!0;continue}const b=fu(m.nodeElement),x=g.measured.width!==b.width||g.measured.height!==b.height;if(!!(b.width&&b.height&&(x||!g.internals.handleBounds||m.force))){const w=m.nodeElement.getBoundingClientRect(),v=Fr(g.extent)?g.extent:a;let{positionAbsolute:N}=g.internals;g.parentId&&g.extent==="parent"?N=_1(N,b,t.get(g.parentId)):v&&(N=lr(N,v,b));const k={...g,measured:b,internals:{...g.internals,positionAbsolute:N,handleBounds:{source:rh("source",m.nodeElement,w,p,g.id),target:rh("target",m.nodeElement,w,p,g.id)}}};t.set(g.id,k),g.parentId&&bu(k,t,n,{nodeOrigin:s,zIndexMode:i}),c=!0,x&&(d.push({id:g.id,type:"dimensions",dimensions:b}),g.expandParent&&g.parentId&&h.push({id:g.id,parentId:g.parentId,rect:zr(k,s)}))}}if(h.length>0){const m=xu(h,t,n,s);d.push(...m)}return{changes:d,updatedInternals:c}}async function ZU({delta:e,panZoom:t,transform:n,translateExtent:r,width:s,height:a}){if(!t||!e.x&&!e.y)return Promise.resolve(!1);const i=await t.setViewportConstrained({x:n[0]+e.x,y:n[1]+e.y,zoom:n[2]},[[0,0],[s,a]],r),l=!!i&&(i.x!==n[0]||i.y!==n[1]||i.k!==n[2]);return Promise.resolve(l)}function dh(e,t,n,r,s,a){let i=s;const l=r.get(i)||new Map;r.set(i,l.set(n,t)),i=`${s}-${e}`;const c=r.get(i)||new Map;if(r.set(i,c.set(n,t)),a){i=`${s}-${e}-${a}`;const d=r.get(i)||new Map;r.set(i,d.set(n,t))}}function U1(e,t,n){e.clear(),t.clear();for(const r of n){const{source:s,target:a,sourceHandle:i=null,targetHandle:l=null}=r,c={edgeId:r.id,source:s,target:a,sourceHandle:i,targetHandle:l},d=`${s}-${i}--${a}-${l}`,u=`${a}-${l}--${s}-${i}`;dh("source",c,u,e,s,i),dh("target",c,d,e,a,l),t.set(r.id,r)}}function Q1(e,t){if(!e.parentId)return!1;const n=t.get(e.parentId);return n?n.selected?!0:Q1(n,t):!1}function uh(e,t,n){let r=e;do{if(r?.matches?.(t))return!0;if(r===n)return!1;r=r?.parentElement}while(r);return!1}function XU(e,t,n,r){const s=new Map;for(const[a,i]of e)if((i.selected||i.id===r)&&(!i.parentId||!Q1(i,e))&&(i.draggable||t&&typeof i.draggable>"u")){const l=e.get(a);l&&s.set(a,{id:a,position:l.position||{x:0,y:0},distance:{x:n.x-l.internals.positionAbsolute.x,y:n.y-l.internals.positionAbsolute.y},extent:l.extent,parentId:l.parentId,origin:l.origin,expandParent:l.expandParent,internals:{positionAbsolute:l.internals.positionAbsolute||{x:0,y:0}},measured:{width:l.measured.width??0,height:l.measured.height??0}})}return s}function ul({nodeId:e,dragItems:t,nodeLookup:n,dragging:r=!0}){const s=[];for(const[i,l]of t){const c=n.get(i)?.internals.userNode;c&&s.push({...c,position:l.position,dragging:r})}if(!e)return[s[0],s];const a=n.get(e)?.internals.userNode;return[a?{...a,position:t.get(e)?.position||a.position,dragging:r}:s[0],s]}function JU({dragItems:e,snapGrid:t,x:n,y:r}){const s=e.values().next().value;if(!s)return null;const a={x:n-s.distance.x,y:r-s.distance.y},i=is(a,t);return{x:i.x-a.x,y:i.y-a.y}}function eQ({onNodeMouseDown:e,getStoreItems:t,onDragStart:n,onDrag:r,onDragStop:s}){let a={x:null,y:null},i=0,l=new Map,c=!1,d={x:0,y:0},u=null,p=!1,h=null,m=!1,g=!1,b=null;function x({noDragClassName:w,handleSelector:v,domNode:N,isSelectable:k,nodeId:C,nodeClickDistance:E=0}){h=ht(N);function I({x:B,y:R}){const{nodeLookup:M,nodeExtent:D,snapGrid:T,snapToGrid:L,nodeOrigin:O,onNodeDrag:F,onSelectionDrag:j,onError:V,updateNodePositions:$}=t();a={x:B,y:R};let q=!1;const G=l.size>1,Z=G&&D?mc(as(l)):null,oe=G&&L?JU({dragItems:l,snapGrid:T,x:B,y:R}):null;for(const[ne,X]of l){if(!M.has(ne))continue;let re={x:B-X.distance.x,y:R-X.distance.y};L&&(re=oe?{x:Math.round(re.x+oe.x),y:Math.round(re.y+oe.y)}:is(re,T));let be=null;if(G&&D&&!X.extent&&Z){const{positionAbsolute:ee}=X.internals,ae=ee.x-Z.x+D[0][0],fe=ee.x+X.measured.width-Z.x2+D[1][0],ge=ee.y-Z.y+D[0][1],Q=ee.y+X.measured.height-Z.y2+D[1][1];be=[[ae,ge],[fe,Q]]}const{position:J,positionAbsolute:W}=P1({nodeId:ne,nextPosition:re,nodeLookup:M,nodeExtent:be||D,nodeOrigin:O,onError:V});q=q||X.position.x!==J.x||X.position.y!==J.y,X.position=J,X.internals.positionAbsolute=W}if(g=g||q,!!q&&($(l,!0),b&&(r||F||!C&&j))){const[ne,X]=ul({nodeId:C,dragItems:l,nodeLookup:M});r?.(b,l,ne,X),F?.(b,ne,X),C||j?.(b,X)}}async function A(){if(!u)return;const{transform:B,panBy:R,autoPanSpeed:M,autoPanOnNodeDrag:D}=t();if(!D){c=!1,cancelAnimationFrame(i);return}const[T,L]=$1(d,u,M);(T!==0||L!==0)&&(a.x=(a.x??0)-T/B[2],a.y=(a.y??0)-L/B[2],await R({x:T,y:L})&&I(a)),i=requestAnimationFrame(A)}function z(B){const{nodeLookup:R,multiSelectionActive:M,nodesDraggable:D,transform:T,snapGrid:L,snapToGrid:O,selectNodesOnDrag:F,onNodeDragStart:j,onSelectionDragStart:V,unselectNodesAndEdges:$}=t();p=!0,(!F||!k)&&!M&&C&&(R.get(C)?.selected||$()),k&&F&&C&&e?.(C);const q=Co(B.sourceEvent,{transform:T,snapGrid:L,snapToGrid:O,containerBounds:u});if(a=q,l=XU(R,D,q,C),l.size>0&&(n||j||!C&&V)){const[G,Z]=ul({nodeId:C,dragItems:l,nodeLookup:R});n?.(B.sourceEvent,l,G,Z),j?.(B.sourceEvent,G,Z),C||V?.(B.sourceEvent,Z)}}const P=c1().clickDistance(E).on("start",B=>{const{domNode:R,nodeDragThreshold:M,transform:D,snapGrid:T,snapToGrid:L}=t();u=R?.getBoundingClientRect()||null,m=!1,g=!1,b=B.sourceEvent,M===0&&z(B),a=Co(B.sourceEvent,{transform:D,snapGrid:T,snapToGrid:L,containerBounds:u}),d=Bt(B.sourceEvent,u)}).on("drag",B=>{const{autoPanOnNodeDrag:R,transform:M,snapGrid:D,snapToGrid:T,nodeDragThreshold:L,nodeLookup:O}=t(),F=Co(B.sourceEvent,{transform:M,snapGrid:D,snapToGrid:T,containerBounds:u});if(b=B.sourceEvent,(B.sourceEvent.type==="touchmove"&&B.sourceEvent.touches.length>1||C&&!O.has(C))&&(m=!0),!m){if(!c&&R&&p&&(c=!0,A()),!p){const j=Bt(B.sourceEvent,u),V=j.x-d.x,$=j.y-d.y;Math.sqrt(V*V+$*$)>L&&z(B)}(a.x!==F.xSnapped||a.y!==F.ySnapped)&&l&&p&&(d=Bt(B.sourceEvent,u),I(F))}}).on("end",B=>{if(!(!p||m)&&(c=!1,p=!1,cancelAnimationFrame(i),l.size>0)){const{nodeLookup:R,updateNodePositions:M,onNodeDragStop:D,onSelectionDragStop:T}=t();if(g&&(M(l,!1),g=!1),s||D||!C&&T){const[L,O]=ul({nodeId:C,dragItems:l,nodeLookup:R,dragging:!1});s?.(B.sourceEvent,l,L,O),D?.(B.sourceEvent,L,O),C||T?.(B.sourceEvent,O)}}}).filter(B=>{const R=B.target;return!B.button&&(!w||!uh(R,`.${w}`,N))&&(!v||uh(R,v,N))});h.call(P)}function y(){h?.on(".drag",null)}return{update:x,destroy:y}}function tQ(e,t,n){const r=[],s={x:e.x-n,y:e.y-n,width:n*2,height:n*2};for(const a of t.values())Fo(s,zr(a))>0&&r.push(a);return r}const nQ=250;function rQ(e,t,n,r){let s=[],a=1/0;const i=tQ(e,n,t+nQ);for(const l of i){const c=[...l.internals.handleBounds?.source??[],...l.internals.handleBounds?.target??[]];for(const d of c){if(r.nodeId===d.nodeId&&r.type===d.type&&r.id===d.id)continue;const{x:u,y:p}=cr(l,d,d.position,!0),h=Math.sqrt(Math.pow(u-e.x,2)+Math.pow(p-e.y,2));h>t||(h<a?(s=[{...d,x:u,y:p}],a=h):h===a&&s.push({...d,x:u,y:p}))}}if(!s.length)return null;if(s.length>1){const l=r.type==="source"?"target":"source";return s.find(c=>c.type===l)??s[0]}return s[0]}function G1(e,t,n,r,s,a=!1){const i=r.get(e);if(!i)return null;const l=s==="strict"?i.internals.handleBounds?.[t]:[...i.internals.handleBounds?.source??[],...i.internals.handleBounds?.target??[]],c=(n?l?.find(d=>d.id===n):l?.[0])??null;return c&&a?{...c,...cr(i,c,c.position,!0)}:c}function K1(e,t){return e||(t?.classList.contains("target")?"target":t?.classList.contains("source")?"source":null)}function oQ(e,t){let n=null;return t?n=!0:e&&!t&&(n=!1),n}const W1=()=>!0;function sQ(e,{connectionMode:t,connectionRadius:n,handleId:r,nodeId:s,edgeUpdaterType:a,isTarget:i,domNode:l,nodeLookup:c,lib:d,autoPanOnConnect:u,flowId:p,panBy:h,cancelConnection:m,onConnectStart:g,onConnect:b,onConnectEnd:x,isValidConnection:y=W1,onReconnectEnd:w,updateConnection:v,getTransform:N,getFromHandle:k,autoPanSpeed:C,dragThreshold:E=1,handleDomNode:I}){const A=R1(e.target);let z=0,P;const{x:B,y:R}=Bt(e),M=K1(a,I),D=l?.getBoundingClientRect();let T=!1;if(!D||!M)return;const L=G1(s,M,r,c,t);if(!L)return;let O=Bt(e,D),F=!1,j=null,V=!1,$=null;function q(){if(!u||!D)return;const[J,W]=$1(O,D,C);h({x:J,y:W}),z=requestAnimationFrame(q)}const G={...L,nodeId:s,type:M,position:L.position},Z=c.get(s);let ne={inProgress:!0,isValid:null,from:cr(Z,G,we.Left,!0),fromHandle:G,fromPosition:G.position,fromNode:Z,to:O,toHandle:null,toPosition:Jf[G.position],toNode:null,pointer:O};function X(){T=!0,v(ne),g?.(e,{nodeId:s,handleId:r,handleType:M})}E===0&&X();function re(J){if(!T){const{x:Q,y:le}=Bt(J),ue=Q-B,de=le-R;if(!(ue*ue+de*de>E*E))return;X()}if(!k()||!G){be(J);return}const W=N();O=Bt(J,D),P=rQ(ls(O,W,!1,[1,1]),n,c,G),F||(q(),F=!0);const ee=Y1(J,{handle:P,connectionMode:t,fromNodeId:s,fromHandleId:r,fromType:i?"target":"source",isValidConnection:y,doc:A,lib:d,flowId:p,nodeLookup:c});$=ee.handleDomNode,j=ee.connection,V=oQ(!!P,ee.isValid);const ae=c.get(s),fe=ae?cr(ae,G,we.Left,!0):ne.from,ge={...ne,from:fe,isValid:V,to:ee.toHandle&&V?Sa({x:ee.toHandle.x,y:ee.toHandle.y},W):O,toHandle:ee.toHandle,toPosition:V&&ee.toHandle?ee.toHandle.position:Jf[G.position],toNode:ee.toHandle?c.get(ee.toHandle.nodeId):null,pointer:O};v(ge),ne=ge}function be(J){if(!("touches"in J&&J.touches.length>0)){if(T){(P||$)&&j&&V&&b?.(j);const{inProgress:W,...ee}=ne,ae={...ee,toPosition:ne.toHandle?ne.toPosition:null};x?.(J,ae),a&&w?.(J,ae)}m(),cancelAnimationFrame(z),F=!1,V=!1,j=null,$=null,A.removeEventListener("mousemove",re),A.removeEventListener("mouseup",be),A.removeEventListener("touchmove",re),A.removeEventListener("touchend",be)}}A.addEventListener("mousemove",re),A.addEventListener("mouseup",be),A.addEventListener("touchmove",re),A.addEventListener("touchend",be)}function Y1(e,{handle:t,connectionMode:n,fromNodeId:r,fromHandleId:s,fromType:a,doc:i,lib:l,flowId:c,isValidConnection:d=W1,nodeLookup:u}){const p=a==="target",h=t?i.querySelector(`.${l}-flow__handle[data-id="${c}-${t?.nodeId}-${t?.id}-${t?.type}"]`):null,{x:m,y:g}=Bt(e),b=i.elementFromPoint(m,g),x=b?.classList.contains(`${l}-flow__handle`)?b:h,y={handleDomNode:x,isValid:!1,connection:null,toHandle:null};if(x){const w=K1(void 0,x),v=x.getAttribute("data-nodeid"),N=x.getAttribute("data-handleid"),k=x.classList.contains("connectable"),C=x.classList.contains("connectableend");if(!v||!w)return y;const E={source:p?v:r,sourceHandle:p?N:s,target:p?r:v,targetHandle:p?s:N};y.connection=E;const A=k&&C&&(n===Or.Strict?p&&w==="source"||!p&&w==="target":v!==r||N!==s);y.isValid=A&&d(E),y.toHandle=G1(v,w,N,u,n,!0)}return y}const yc={onPointerDown:sQ,isValid:Y1};function aQ({domNode:e,panZoom:t,getTransform:n,getViewScale:r}){const s=ht(e);function a({translateExtent:l,width:c,height:d,zoomStep:u=1,pannable:p=!0,zoomable:h=!0,inversePan:m=!1}){const g=v=>{if(v.sourceEvent.type!=="wheel"||!t)return;const N=n(),k=v.sourceEvent.ctrlKey&&jo()?10:1,C=-v.sourceEvent.deltaY*(v.sourceEvent.deltaMode===1?.05:v.sourceEvent.deltaMode?1:.002)*u,E=N[2]*Math.pow(2,C*k);t.scaleTo(E)};let b=[0,0];const x=v=>{(v.sourceEvent.type==="mousedown"||v.sourceEvent.type==="touchstart")&&(b=[v.sourceEvent.clientX??v.sourceEvent.touches[0].clientX,v.sourceEvent.clientY??v.sourceEvent.touches[0].clientY])},y=v=>{const N=n();if(v.sourceEvent.type!=="mousemove"&&v.sourceEvent.type!=="touchmove"||!t)return;const k=[v.sourceEvent.clientX??v.sourceEvent.touches[0].clientX,v.sourceEvent.clientY??v.sourceEvent.touches[0].clientY],C=[k[0]-b[0],k[1]-b[1]];b=k;const E=r()*Math.max(N[2],Math.log(N[2]))*(m?-1:1),I={x:N[0]-C[0]*E,y:N[1]-C[1]*E},A=[[0,0],[c,d]];t.setViewportConstrained({x:I.x,y:I.y,zoom:N[2]},A,l)},w=S1().on("start",x).on("zoom",p?y:null).on("zoom.wheel",h?g:null);s.call(w,{})}function i(){s.on("zoom",null)}return{update:a,destroy:i,pointer:Lt}}const ui=e=>({x:e.x,y:e.y,zoom:e.k}),pl=({x:e,y:t,zoom:n})=>li.translate(e,t).scale(n),Cr=(e,t)=>e.target.closest(`.${t}`),Z1=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),iQ=e=>((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2,fl=(e,t=0,n=iQ,r=()=>{})=>{const s=typeof t=="number"&&t>0;return s||r(),s?e.transition().duration(t).ease(n).on("end",r):e},X1=e=>{const t=e.ctrlKey&&jo()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t};function lQ({zoomPanValues:e,noWheelClassName:t,d3Selection:n,d3Zoom:r,panOnScrollMode:s,panOnScrollSpeed:a,zoomOnPinch:i,onPanZoomStart:l,onPanZoom:c,onPanZoomEnd:d}){return u=>{if(Cr(u,t))return u.ctrlKey&&u.preventDefault(),!1;u.preventDefault(),u.stopImmediatePropagation();const p=n.property("__zoom").k||1;if(u.ctrlKey&&i){const x=Lt(u),y=X1(u),w=p*Math.pow(2,y);r.scaleTo(n,w,x,u);return}const h=u.deltaMode===1?20:1;let m=s===Xn.Vertical?0:u.deltaX*h,g=s===Xn.Horizontal?0:u.deltaY*h;!jo()&&u.shiftKey&&s!==Xn.Vertical&&(m=u.deltaY*h,g=0),r.translateBy(n,-(m/p)*a,-(g/p)*a,{internal:!0});const b=ui(n.property("__zoom"));clearTimeout(e.panScrollTimeout),e.isPanScrolling?(c?.(u,b),e.panScrollTimeout=setTimeout(()=>{d?.(u,b),e.isPanScrolling=!1},150)):(e.isPanScrolling=!0,l?.(u,b))}}function cQ({noWheelClassName:e,preventScrolling:t,d3ZoomHandler:n}){return function(r,s){const a=r.type==="wheel",i=!t&&a&&!r.ctrlKey,l=Cr(r,e);if(r.ctrlKey&&a&&l&&r.preventDefault(),i||l)return null;r.preventDefault(),n.call(this,r,s)}}function dQ({zoomPanValues:e,onDraggingChange:t,onPanZoomStart:n}){return r=>{if(r.sourceEvent?.internal)return;const s=ui(r.transform);e.mouseButton=r.sourceEvent?.button||0,e.isZoomingOrPanning=!0,e.prevViewport=s,r.sourceEvent?.type==="mousedown"&&t(!0),n&&n?.(r.sourceEvent,s)}}function uQ({zoomPanValues:e,panOnDrag:t,onPaneContextMenu:n,onTransformChange:r,onPanZoom:s}){return a=>{e.usedRightMouseButton=!!(n&&Z1(t,e.mouseButton??0)),a.sourceEvent?.sync||r([a.transform.x,a.transform.y,a.transform.k]),s&&!a.sourceEvent?.internal&&s?.(a.sourceEvent,ui(a.transform))}}function pQ({zoomPanValues:e,panOnDrag:t,panOnScroll:n,onDraggingChange:r,onPanZoomEnd:s,onPaneContextMenu:a}){return i=>{if(!i.sourceEvent?.internal&&(e.isZoomingOrPanning=!1,a&&Z1(t,e.mouseButton??0)&&!e.usedRightMouseButton&&i.sourceEvent&&a(i.sourceEvent),e.usedRightMouseButton=!1,r(!1),s)){const l=ui(i.transform);e.prevViewport=l,clearTimeout(e.timerId),e.timerId=setTimeout(()=>{s?.(i.sourceEvent,l)},n?150:0)}}}function fQ({zoomActivationKeyPressed:e,zoomOnScroll:t,zoomOnPinch:n,panOnDrag:r,panOnScroll:s,zoomOnDoubleClick:a,userSelectionActive:i,noWheelClassName:l,noPanClassName:c,lib:d,connectionInProgress:u}){return p=>{const h=e||t,m=n&&p.ctrlKey,g=p.type==="wheel";if(p.button===1&&p.type==="mousedown"&&(Cr(p,`${d}-flow__node`)||Cr(p,`${d}-flow__edge`)))return!0;if(!r&&!h&&!s&&!a&&!n||i||u&&!g||Cr(p,l)&&g||Cr(p,c)&&(!g||s&&g&&!e)||!n&&p.ctrlKey&&g)return!1;if(!n&&p.type==="touchstart"&&p.touches?.length>1)return p.preventDefault(),!1;if(!h&&!s&&!m&&g||!r&&(p.type==="mousedown"||p.type==="touchstart")||Array.isArray(r)&&!r.includes(p.button)&&p.type==="mousedown")return!1;const b=Array.isArray(r)&&r.includes(p.button)||!p.button||p.button<=1;return(!p.ctrlKey||g)&&b}}function hQ({domNode:e,minZoom:t,maxZoom:n,translateExtent:r,viewport:s,onPanZoom:a,onPanZoomStart:i,onPanZoomEnd:l,onDraggingChange:c}){const d={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},u=e.getBoundingClientRect(),p=S1().scaleExtent([t,n]).translateExtent(r),h=ht(e).call(p);w({x:s.x,y:s.y,zoom:Br(s.zoom,t,n)},[[0,0],[u.width,u.height]],r);const m=h.on("wheel.zoom"),g=h.on("dblclick.zoom");p.wheelDelta(X1);function b(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).transform(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function x({noWheelClassName:P,noPanClassName:B,onPaneContextMenu:R,userSelectionActive:M,panOnScroll:D,panOnDrag:T,panOnScrollMode:L,panOnScrollSpeed:O,preventScrolling:F,zoomOnPinch:j,zoomOnScroll:V,zoomOnDoubleClick:$,zoomActivationKeyPressed:q,lib:G,onTransformChange:Z,connectionInProgress:oe,paneClickDistance:ne,selectionOnDrag:X}){M&&!d.isZoomingOrPanning&&y();const re=D&&!q&&!M;p.clickDistance(X?1/0:!Ot(ne)||ne<0?0:ne);const be=re?lQ({zoomPanValues:d,noWheelClassName:P,d3Selection:h,d3Zoom:p,panOnScrollMode:L,panOnScrollSpeed:O,zoomOnPinch:j,onPanZoomStart:i,onPanZoom:a,onPanZoomEnd:l}):cQ({noWheelClassName:P,preventScrolling:F,d3ZoomHandler:m});if(h.on("wheel.zoom",be,{passive:!1}),!M){const W=dQ({zoomPanValues:d,onDraggingChange:c,onPanZoomStart:i});p.on("start",W);const ee=uQ({zoomPanValues:d,panOnDrag:T,onPaneContextMenu:!!R,onPanZoom:a,onTransformChange:Z});p.on("zoom",ee);const ae=pQ({zoomPanValues:d,panOnDrag:T,panOnScroll:D,onPaneContextMenu:R,onPanZoomEnd:l,onDraggingChange:c});p.on("end",ae)}const J=fQ({zoomActivationKeyPressed:q,panOnDrag:T,zoomOnScroll:V,panOnScroll:D,zoomOnDoubleClick:$,zoomOnPinch:j,userSelectionActive:M,noPanClassName:B,noWheelClassName:P,lib:G,connectionInProgress:oe});p.filter(J),$?h.on("dblclick.zoom",g):h.on("dblclick.zoom",null)}function y(){p.on("zoom",null)}async function w(P,B,R){const M=pl(P),D=p?.constrain()(M,B,R);return D&&await b(D),new Promise(T=>T(D))}async function v(P,B){const R=pl(P);return await b(R,B),new Promise(M=>M(R))}function N(P){if(h){const B=pl(P),R=h.property("__zoom");(R.k!==P.zoom||R.x!==P.x||R.y!==P.y)&&p?.transform(h,B,null,{sync:!0})}}function k(){const P=h?k1(h.node()):{x:0,y:0,k:1};return{x:P.x,y:P.y,zoom:P.k}}function C(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).scaleTo(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function E(P,B){return h?new Promise(R=>{p?.interpolate(B?.interpolate==="linear"?So:Gs).scaleBy(fl(h,B?.duration,B?.ease,()=>R(!0)),P)}):Promise.resolve(!1)}function I(P){p?.scaleExtent(P)}function A(P){p?.translateExtent(P)}function z(P){const B=!Ot(P)||P<0?0:P;p?.clickDistance(B)}return{update:x,destroy:y,setViewport:v,setViewportConstrained:w,getViewport:k,scaleTo:C,scaleBy:E,setScaleExtent:I,setTranslateExtent:A,syncViewport:N,setClickDistance:z}}var jr;(function(e){e.Line="line",e.Handle="handle"})(jr||(jr={}));function mQ({width:e,prevWidth:t,height:n,prevHeight:r,affectsX:s,affectsY:a}){const i=e-t,l=n-r,c=[i>0?1:i<0?-1:0,l>0?1:l<0?-1:0];return i&&s&&(c[0]=c[0]*-1),l&&a&&(c[1]=c[1]*-1),c}function ph(e){const t=e.includes("right")||e.includes("left"),n=e.includes("bottom")||e.includes("top"),r=e.includes("left"),s=e.includes("top");return{isHorizontal:t,isVertical:n,affectsX:r,affectsY:s}}function Cn(e,t){return Math.max(0,t-e)}function Mn(e,t){return Math.max(0,e-t)}function Rs(e,t,n){return Math.max(0,t-e,e-n)}function fh(e,t){return e?!t:t}function gQ(e,t,n,r,s,a,i,l){let{affectsX:c,affectsY:d}=t;const{isHorizontal:u,isVertical:p}=t,h=u&&p,{xSnapped:m,ySnapped:g}=n,{minWidth:b,maxWidth:x,minHeight:y,maxHeight:w}=r,{x:v,y:N,width:k,height:C,aspectRatio:E}=e;let I=Math.floor(u?m-e.pointerX:0),A=Math.floor(p?g-e.pointerY:0);const z=k+(c?-I:I),P=C+(d?-A:A),B=-a[0]*k,R=-a[1]*C;let M=Rs(z,b,x),D=Rs(P,y,w);if(i){let O=0,F=0;c&&I<0?O=Cn(v+I+B,i[0][0]):!c&&I>0&&(O=Mn(v+z+B,i[1][0])),d&&A<0?F=Cn(N+A+R,i[0][1]):!d&&A>0&&(F=Mn(N+P+R,i[1][1])),M=Math.max(M,O),D=Math.max(D,F)}if(l){let O=0,F=0;c&&I>0?O=Mn(v+I,l[0][0]):!c&&I<0&&(O=Cn(v+z,l[1][0])),d&&A>0?F=Mn(N+A,l[0][1]):!d&&A<0&&(F=Cn(N+P,l[1][1])),M=Math.max(M,O),D=Math.max(D,F)}if(s){if(u){const O=Rs(z/E,y,w)*E;if(M=Math.max(M,O),i){let F=0;!c&&!d||c&&!d&&h?F=Mn(N+R+z/E,i[1][1])*E:F=Cn(N+R+(c?I:-I)/E,i[0][1])*E,M=Math.max(M,F)}if(l){let F=0;!c&&!d||c&&!d&&h?F=Cn(N+z/E,l[1][1])*E:F=Mn(N+(c?I:-I)/E,l[0][1])*E,M=Math.max(M,F)}}if(p){const O=Rs(P*E,b,x)/E;if(D=Math.max(D,O),i){let F=0;!c&&!d||d&&!c&&h?F=Mn(v+P*E+B,i[1][0])/E:F=Cn(v+(d?A:-A)*E+B,i[0][0])/E,D=Math.max(D,F)}if(l){let F=0;!c&&!d||d&&!c&&h?F=Cn(v+P*E,l[1][0])/E:F=Mn(v+(d?A:-A)*E,l[0][0])/E,D=Math.max(D,F)}}}A=A+(A<0?D:-D),I=I+(I<0?M:-M),s&&(h?z>P*E?A=(fh(c,d)?-I:I)/E:I=(fh(c,d)?-A:A)*E:u?(A=I/E,d=c):(I=A*E,c=d));const T=c?v+I:v,L=d?N+A:N;return{width:k+(c?-I:I),height:C+(d?-A:A),x:a[0]*I*(c?-1:1)+T,y:a[1]*A*(d?-1:1)+L}}const J1={width:0,height:0,x:0,y:0},bQ={...J1,pointerX:0,pointerY:0,aspectRatio:1};function xQ(e){return[[0,0],[e.measured.width,e.measured.height]]}function yQ(e,t,n){const r=t.position.x+e.position.x,s=t.position.y+e.position.y,a=e.measured.width??0,i=e.measured.height??0,l=n[0]*a,c=n[1]*i;return[[r-l,s-c],[r+a-l,s+i-c]]}function vQ({domNode:e,nodeId:t,getStoreItems:n,onChange:r,onEnd:s}){const a=ht(e);let i={controlDirection:ph("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function l({controlPosition:d,boundaries:u,keepAspectRatio:p,resizeDirection:h,onResizeStart:m,onResize:g,onResizeEnd:b,shouldResize:x}){let y={...J1},w={...bQ};i={boundaries:u,resizeDirection:h,keepAspectRatio:p,controlDirection:ph(d)};let v,N=null,k=[],C,E,I,A=!1;const z=c1().on("start",P=>{const{nodeLookup:B,transform:R,snapGrid:M,snapToGrid:D,nodeOrigin:T,paneDomNode:L}=n();if(v=B.get(t),!v)return;N=L?.getBoundingClientRect()??null;const{xSnapped:O,ySnapped:F}=Co(P.sourceEvent,{transform:R,snapGrid:M,snapToGrid:D,containerBounds:N});y={width:v.measured.width??0,height:v.measured.height??0,x:v.position.x??0,y:v.position.y??0},w={...y,pointerX:O,pointerY:F,aspectRatio:y.width/y.height},C=void 0,v.parentId&&(v.extent==="parent"||v.expandParent)&&(C=B.get(v.parentId),E=C&&v.extent==="parent"?xQ(C):void 0),k=[],I=void 0;for(const[j,V]of B)if(V.parentId===t&&(k.push({id:j,position:{...V.position},extent:V.extent}),V.extent==="parent"||V.expandParent)){const $=yQ(V,v,V.origin??T);I?I=[[Math.min($[0][0],I[0][0]),Math.min($[0][1],I[0][1])],[Math.max($[1][0],I[1][0]),Math.max($[1][1],I[1][1])]]:I=$}m?.(P,{...y})}).on("drag",P=>{const{transform:B,snapGrid:R,snapToGrid:M,nodeOrigin:D}=n(),T=Co(P.sourceEvent,{transform:B,snapGrid:R,snapToGrid:M,containerBounds:N}),L=[];if(!v)return;const{x:O,y:F,width:j,height:V}=y,$={},q=v.origin??D,{width:G,height:Z,x:oe,y:ne}=gQ(w,i.controlDirection,T,i.boundaries,i.keepAspectRatio,q,E,I),X=G!==j,re=Z!==V,be=oe!==O&&X,J=ne!==F&&re;if(!be&&!J&&!X&&!re)return;if((be||J||q[0]===1||q[1]===1)&&($.x=be?oe:y.x,$.y=J?ne:y.y,y.x=$.x,y.y=$.y,k.length>0)){const fe=oe-O,ge=ne-F;for(const Q of k)Q.position={x:Q.position.x-fe+q[0]*(G-j),y:Q.position.y-ge+q[1]*(Z-V)},L.push(Q)}if((X||re)&&($.width=X&&(!i.resizeDirection||i.resizeDirection==="horizontal")?G:y.width,$.height=re&&(!i.resizeDirection||i.resizeDirection==="vertical")?Z:y.height,y.width=$.width,y.height=$.height),C&&v.expandParent){const fe=q[0]*($.width??0);$.x&&$.x<fe&&(y.x=fe,w.x=w.x-($.x-fe));const ge=q[1]*($.height??0);$.y&&$.y<ge&&(y.y=ge,w.y=w.y-($.y-ge))}const W=mQ({width:y.width,prevWidth:j,height:y.height,prevHeight:V,affectsX:i.controlDirection.affectsX,affectsY:i.controlDirection.affectsY}),ee={...y,direction:W};x?.(P,ee)!==!1&&(A=!0,g?.(P,ee),r($,L))}).on("end",P=>{A&&(b?.(P,{...y}),s?.({...y}),A=!1)});a.call(z)}function c(){a.on(".drag",null)}return{update:l,destroy:c}}var ew={exports:{}},tw={};/**
|
|
1143
1143
|
* @license React
|
|
1144
1144
|
* use-sync-external-store-shim/with-selector.production.js
|
|
1145
1145
|
*
|