Files
Borealis-Github-Replica/Data/Engine/web-interface/build/assets/index-fCNyajYO.js

417 lines
397 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{r as s,j as e,a as es}from"./react-CcTm0Ooe.js";import{a as Oo}from"./react-dom-BH-0RoFc.js";/* empty css *//* empty css *//* empty css */import{u as dt,a as mt,H as De,P as ze,b as zn,c as Po,d as Eo,R as lo,B as Mo,e as Do}from"./@reactflow-Cn6m1kzj.js";/* empty css */import{I as nt,S as zo,T as st,a as co,B as Z,b as Fo,D as Ze,c as et,d as rt,e as $t,f as tt,g as Ie,M as Et,h as fe,i as m,A as as,j as is,k as $,E as ls,l as cs,m as Lo,n as $o,K as uo,o as Ys,p as Uo,J as Wo,C as Vo,F as Ho,G as Go,q as qo,r as po,U as Jo,s as Yo,L as Ko,t as tn,u as Us,v as ps,w as ts,x as Fs,P as Xo,y as fo,z as Qo,R as Zo,H as Fn,W as kn,N as Ln,O as ho,Q as er,V as tr,X as sr,Y as nr,Z as or,_ as In,$ as Qe,a0 as mo,a1 as Rt,a2 as Bt,a3 as Ue,a4 as Q,a5 as At,a6 as Tt,a7 as Rn,a8 as Nt,a9 as Ls,aa as bs,ab as Ht,ac as Gt,ad as wt,ae as Mt,af as vs,ag as ys,ah as Nn,ai as Tn,aj as on,ak as rr,al as ar,am as ir,an as lr,ao as cr,ap as dr,aq as ur,ar as Ss,as as $s,at as xo,au as pr,av as fr,aw as os,ax as go,ay as hr,az as mr,aA as xr,aB as gr,aC as br,aD as yr,aE as jr,aF as wr,aG as vr,aH as Ks,aI as Sr,aJ as Cr,aK as _r,aL as kr,aM as Ir,aN as Rr,aO as Nr,aP as Tr,aQ as ds,aR as rn,aS as bo,aT as yo,aU as Ar,aV as Br,aW as Or,aX as Pr,aY as $n,aZ as Un,a_ as Er,a$ as Mr,b0 as Dr,b1 as zr,b2 as Fr,b3 as Lr,b4 as $r,b5 as Ur,b6 as Wr,b7 as Vr}from"./@mui-DuExnnZV.js";import{P as qt}from"./prismjs-DnVqcinS.js";import{R as Hr}from"./react-resizable-Dz87KGdU.js";import"./reactflow-CapO1AcK.js";import{S as jo}from"./react-color-Cj5ADBFD.js";import"./tinycolor2-Begke6kS.js";import{R as Gr}from"./react-markdown-DU1c7IVQ.js";import{A as An}from"./ag-grid-react-CI8oSmtp.js";import{M as Bn,y as On,z as Pn}from"./ag-grid-community-3ngxp7D-.js";import{_ as En}from"./react-simple-code-editor-VgXKD24u.js";import{d as Xs}from"./dayjs-DS_BHG0d.js";import{l as qr}from"./socket.io-client-CDVIIGn8.js";import"./@icons-BDZNmjFP.js";import"./scheduler-BmyE5rk0.js";import"./d3-transition-CT0P4Hy_.js";import"./d3-dispatch-kxCwF96_.js";import"./d3-timer-DdKHrDhs.js";import"./d3-interpolate-B6xYU604.js";import"./d3-color-9lF95FHy.js";import"./d3-selection-DSeOx27A.js";import"./d3-ease-DRPgKoYJ.js";import"./d3-zoom-C9ulvfG5.js";import"./d3-drag-CKshNLwO.js";import"./classcat-RvS1aOr8.js";import"./zustand-C9Nr5JuV.js";import"./use-sync-external-store-iOpSvWgw.js";import"./clsx-ZPAKJJud.js";import"./@emotion-DhAReQXH.js";import"./hoist-non-react-statics-DQogQWOa.js";import"./@babel-BtohYyOd.js";import"./stylis-DDa9OTMq.js";import"./reselect-CSPtcQt5.js";import"./react-transition-group-Ds4sJYaS.js";import"./dom-helpers-D0mFdbeO.js";import"./react-is-D_P3mdcN.js";import"./prop-types-CWaErGoZ.js";import"./@popperjs-CMBiYTiD.js";import"./reactcss-DwOrawQG.js";import"./lodash-BBjvixB0.js";import"./lodash-es-DN0AVw_E.js";import"./material-colors-7R66pBqW.js";import"./property-information-CI8MXcm-.js";import"./unist-util-visit-SwKB2sUE.js";import"./unist-util-visit-parents-MnEmTlHn.js";import"./unist-util-is-DiTsIWAy.js";import"./hast-util-whitespace-D1ONPEmv.js";import"./space-separated-tokens-DD3iYX1K.js";import"./comma-separated-tokens-xMQ5YY98.js";import"./style-to-object-pmhRd-Nr.js";import"./inline-style-parser-D--Rb2MU.js";import"./unified-DVSGJAo0.js";import"./bail-FqpXQuLt.js";import"./is-buffer-Boa4a7IC.js";import"./extend-B7yenLig.js";import"./is-plain-obj-C1gvLhAf.js";import"./trough-B_b8ryxu.js";import"./vfile-BlpNzP9y.js";import"./vfile-message-BOGBuebs.js";import"./unist-util-stringify-position-Ch_qCilz.js";import"./remark-parse-CQxuRO-h.js";import"./mdast-util-from-markdown-CLAsVoWb.js";import"./micromark-CTBPIv-_.js";import"./micromark-util-combine-extensions-Bka6Sc1c.js";import"./micromark-util-chunked-DrRIdSP-.js";import"./micromark-factory-space-x2vfxbz5.js";import"./micromark-util-character-Bcm1tP9o.js";import"./micromark-core-commonmark-AH8VCgT7.js";import"./micromark-util-classify-character-Cq7Fg3xE.js";import"./micromark-util-resolve-all-PQCKh0dx.js";import"./decode-named-character-reference-C3-224fz.js";import"./micromark-util-subtokenize-QwsxNXk2.js";import"./micromark-factory-destination-CypD_wgM.js";import"./micromark-factory-label-CRHH4ZHP.js";import"./micromark-factory-title-B7kCBvC9.js";import"./micromark-factory-whitespace-B322EA6O.js";import"./micromark-util-normalize-identifier-C9ANKk3v.js";import"./micromark-util-html-tag-name-DbKNfynz.js";import"./micromark-util-decode-numeric-character-reference-DRnCnno4.js";import"./micromark-util-decode-string-DJl8Y_PO.js";import"./mdast-util-to-string-C_aolqmU.js";import"./remark-rehype-BJ4RwZvz.js";import"./mdast-util-to-hast-Dxh8Xa5R.js";import"./micromark-util-sanitize-uri-nvkIJkgW.js";import"./unist-util-position-KiAvrw8y.js";import"./trim-lines-D8znQY54.js";import"./mdast-util-definitions-CfSXY7bG.js";import"./unist-util-generated-CMz5gPdA.js";import"./engine.io-client-C44f3zIw.js";import"./engine.io-parser-BiEtp6m2.js";import"./@socket.io-Dkula2eQ.js";import"./socket.io-parser-BBkuslX-.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))a(d);new MutationObserver(d=>{for(const u of d)if(u.type==="childList")for(const r of u.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&a(r)}).observe(document,{childList:!0,subtree:!0});function o(d){const u={};return d.integrity&&(u.integrity=d.integrity),d.referrerPolicy&&(u.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?u.credentials="include":d.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function a(d){if(d.ep)return;d.ep=!0;const u=o(d);fetch(d.href,u)}})();const Jr=({id:n,data:t})=>{const{getNodes:o,setNodes:a}=dt(),d=mt(w=>w.edges),[u,r]=s.useState({}),[i,c]=s.useState([]),[p,l]=s.useState(!1),[h,f]=s.useState({}),y=s.useRef([]),C=s.useRef({host:"",mode:"",agentId:"",siteId:""}),I=t!=null&&t.agent_site_id?String(t.agent_site_id):"",k=(t==null?void 0:t.agent_host)||"",v=((t==null?void 0:t.agent_mode)||"currentuser").toString().toLowerCase()==="system"?"system":"currentuser",j=(t==null?void 0:t.agent_id)||"",B=s.useMemo(()=>{if(!u||typeof u!="object")return{};const w={};return Object.entries(u).forEach(([W,F])=>{if(!F||typeof F!="object"||(F.status||"").toString().toLowerCase()==="offline")return;const ee=(F.hostname||F.agent_hostname||"").trim()||"unknown",Re=(F.service_mode||"").toString().toLowerCase()==="system"?"system":"currentuser";w[ee]||(w[ee]={currentuser:null,system:null}),w[ee][Re]={agent_id:W,status:F.status||"offline",last_seen:F.last_seen||0,info:F}}),w},[u]),R=s.useMemo(()=>new Intl.Collator(void 0,{sensitivity:"base",numeric:!0}),[]),x=s.useMemo(()=>Object.entries(B).map(([W,F])=>{const te=[F.currentuser,F.system].filter(Boolean);if(!te.length)return null;const ee=W,be=Math.max(...te.map(Re=>Re.last_seen||0));return{host:W,label:ee,contexts:F,latest:be}}).filter(Boolean).sort((W,F)=>R.compare(W.host,F.host)),[B,R]);s.useEffect(()=>{const w=()=>{fetch("/api/agents").then(F=>F.json()).then(r).catch(()=>{})};w();const W=setInterval(w,1e4);return()=>clearInterval(W)},[]),s.useEffect(()=>{(()=>{fetch("/api/sites").then(W=>W.json()).then(W=>{const F=Array.isArray(W==null?void 0:W.sites)?W.sites:[];c(F)}).catch(()=>c([]))})()},[]),s.useEffect(()=>{const w=x.map(({host:F})=>F).filter(Boolean);if(!w.length){f({});return}const W=w.map(encodeURIComponent).join(",");fetch(`/api/sites/device_map?hostnames=${W}`).then(F=>F.json()).then(F=>{const te=F!=null&&F.mapping&&typeof F.mapping=="object"?F.mapping:{};f(te)}).catch(()=>f({}))},[x]);const S=s.useMemo(()=>I?x.filter(({host:w})=>{const W=h[w];return!W||typeof W.site_id>"u"||W.site_id===null?!1:String(W.site_id)===I}):x,[x,I,h]);s.useEffect(()=>{if(I||!k)return;const w=h[k];if(!w||typeof w.site_id>"u"||w.site_id===null)return;const W=String(w.site_id);a(F=>F.map(te=>te.id===n?{...te,data:{...te.data,agent_site_id:W}}:te))},[k,I,h,n,a]),s.useEffect(()=>{if(!(!k||S.some(W=>W.host===k))){if(j&&u[j]){const W=u[j],F=((W==null?void 0:W.hostname)||(W==null?void 0:W.agent_hostname)||"").trim()||"unknown";if(S.some(ee=>ee.host===F)&&F&&F!==k){a(ee=>ee.map(be=>be.id===n?{...be,data:{...be.data,agent_host:F}}:be));return}}a(W=>W.map(F=>F.id===n?{...F,data:{...F.data,agent_host:"",agent_id:"",agent_mode:"currentuser"}}:F))}},[S,k,j,u,n,a]);const z=s.useMemo(()=>{const w=Array.isArray(i)?[...i]:[];w.sort((F,te)=>((F==null?void 0:F.name)||"").localeCompare((te==null?void 0:te.name)||"",void 0,{sensitivity:"base"}));const W=w.map(F=>({value:String(F.id),label:F.name||`Site ${F.id}`}));return[{value:"",label:"All Sites"},...W]},[i]),E=s.useMemo(()=>{const w=S.map(({host:W,label:F})=>({value:W,label:F}));return[{value:"",label:"-- Select --"},...w]},[S]),U=k?B[k]:null,X=s.useMemo(()=>[{value:"currentuser",label:"CURRENTUSER (Screen Capture / Macros)",disabled:!(U!=null&&U.currentuser)},{value:"system",label:"SYSTEM (Scripts)",disabled:!(U!=null&&U.system)}],[U]);s.useEffect(()=>{a(w=>w.map(W=>W.id===n?{...W,data:{...W.data,siteOptions:z,hostOptions:E,modeOptions:X}}:W))},[n,a,z,E,X]),s.useEffect(()=>{var F,te;if(!k){(j||v!=="currentuser")&&a(ee=>ee.map(be=>be.id===n?{...be,data:{...be.data,agent_id:"",agent_mode:"currentuser"}}:be));return}const w=B[k];if(!w){(j||v!=="currentuser")&&a(ee=>ee.map(be=>be.id===n?{...be,data:{...be.data,agent_id:"",agent_mode:"currentuser"}}:be));return}if(!w[v]){const ee=w.currentuser?"currentuser":w.system?"system":"currentuser",be=((F=w[ee])==null?void 0:F.agent_id)||"";(ee!==v||be!==j)&&a(Re=>Re.map(Ae=>Ae.id===n?{...Ae,data:{...Ae.data,agent_mode:ee,agent_id:be}}:Ae));return}const W=((te=w[v])==null?void 0:te.agent_id)||"";W!==j&&a(ee=>ee.map(be=>be.id===n?{...be,data:{...be.data,agent_id:W}}:be))},[k,v,B,j,n,a]),s.useEffect(()=>{const w=C.current;if(!(w.host!==k||w.mode!==v||w.agentId!==j||w.siteId!==I))return;w.agentId&&(w.agentId!==j||w.host!==k||w.mode!==v)&&(l(!1),y.current=[]),C.current={host:k,mode:v,agentId:j,siteId:I}},[k,v,j,I]);const ue=s.useMemo(()=>d.filter(w=>w.source===n&&w.sourceHandle==="provisioner").map(w=>w.target),[d,n]),Se=s.useCallback(()=>(o(),ue.map(w=>{var F;const W=(F=window.__BorealisInstructionNodes)==null?void 0:F[w];return typeof W=="function"?W():null}).filter(w=>w)),[ue,o]),ce=s.useCallback(w=>{j&&fetch("/api/agent/provision",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:j,roles:w})}).then(()=>{l(!0),y.current=w}).catch(()=>{})},[j]),de=s.useCallback(()=>{const w=Se();ce(w)},[Se,ce]),me=s.useCallback(()=>{j&&fetch("/api/agent/provision",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:j,roles:[]})}).then(()=>{l(!1),y.current=[]}).catch(()=>{})},[j]);return s.useEffect(()=>{const w=Se(),W=JSON.stringify(y.current||[]),F=JSON.stringify(w);p&&F!==W&&ce(w)},[ue,p,Se,ce]),s.useMemo(()=>{if(!k)return"Unassigned";const w=B[k];if(!w)return"Offline";const W=w[v];if(!j||!W)return"Unavailable";const F=(W.status||"").toString().toLowerCase();return F==="provisioned"?"Connected":F==="orphaned"||!F?"Available":F.charAt(0).toUpperCase()+F.slice(1)},[B,k,v,j]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"source",position:ze.Bottom,id:"provisioner",className:"borealis-handle",style:{top:"100%",background:"#58a6ff"}}),e.jsx("div",{className:"borealis-node-header",children:"Device Agent"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",minHeight:"80px",gap:"8px"},children:[e.jsx("div",{style:{fontSize:"8px",color:"#666"},children:"Right-Click to Configure Agent"}),e.jsx("button",{onClick:p?me:de,style:{padding:"6px 14px",fontSize:"10px",background:p?"#3a3a3a":"#0475c2",color:"#fff",border:"1px solid #0475c2",borderRadius:"4px",cursor:j?"pointer":"not-allowed",opacity:j?1:.5,minWidth:"150px"},disabled:!j,children:p?"Disconnect":"Connect to Device"}),e.jsx("div",{style:{fontSize:"8px",color:"#777"},children:k?`${k} · ${v.toUpperCase()}`:"No device selected"})]})]})},Yr={type:"Borealis_Agent",label:"Device Agent",description:`
Select and connect to a remote Borealis Agent.
- Assign roles to agent dynamically by connecting "Agent Role" nodes.
- Auto-provisions agent as role assignments change.
- See live agent status and re-connect/disconnect easily.
- Choose between CURRENTUSER and SYSTEM contexts for each device.
`.trim(),content:"Select and manage an Agent with dynamic roles",component:Jr,config:[{key:"agent_site_id",label:"Site",type:"select",optionsKey:"siteOptions",defaultValue:""},{key:"agent_host",label:"Device",type:"select",optionsKey:"hostOptions",defaultValue:""},{key:"agent_mode",label:"Agent Context",type:"select",optionsKey:"modeOptions",defaultValue:"currentuser"},{key:"agent_id",label:"Agent ID",type:"text",readOnly:!0,defaultValue:""}],usage_documentation:`
### Borealis Agent Node
This node allows you to establish a connection with a device running a Borealis "Agent", so you can instruct the agent to do things from your workflow.
#### Features
- **Select** a site, then a device, then finally an agent context (CURRENTUSER vs SYSTEM).
- **Connect/Disconnect** from the agent at any time.
- **Attach roles** (by connecting "Agent Role" nodes to this node's output handle) to assign behaviors dynamically.
#### How to Use
1. **Drag and drop in a Borealis Agent node.**
2. **Pick an agent** from the dropdown list (auto-populates from API backend).
3. **Click "Connect to Agent"**.
4. **Attach Agent Role Nodes** (e.g., Screenshot, Macro Keypress) to the "provisioner" output handle to define what the agent should do.
5. Agent will automatically update its roles as you change connected Role Nodes.
#### Good to Know
- If an agent disconnects or goes offline, its status will show "Reconnecting..." until it returns.
- **Roles update LIVE**: Any time you change attached roles, the agent gets updated instantly.
`.trim()},Kr=Object.freeze(Object.defineProperty({__proto__:null,default:Yr},Symbol.toStringTag,{value:"Module"})),Xr=4e3;window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Qr="Continuous",Zr=["Run Once","Continuous","Trigger-Once","Trigger-Continuous"],fn={idle:"#333",running:"#00d18c",error:"#ff4f4f"},ea=({id:n,data:t})=>{const{setNodes:o,getNodes:a}=dt(),d=mt(B=>B.edges),[u,r]=s.useState([]),[i,c]=s.useState({state:"idle",message:""}),p=s.useRef(null),l=d.find(B=>B.target===n&&B.targetHandle==="agent"),h=l&&a().find(B=>B.id===l.source),f=!!(h&&h.data&&h.data.agent_id),y=h&&h.data&&h.data.agent_id,C=(t==null?void 0:t.active)===!0||(t==null?void 0:t.active)==="true",[I,k]=s.useState({success:!0,message:"",timestamp:null});s.useEffect(()=>{if(!window.BorealisSocket)return;const B=window.BorealisSocket;p.current=B;function R(x){x&&x.agent_id===y&&x.node_id===n&&(k({success:!!x.success,message:x.message||"",timestamp:x.timestamp||Date.now()}),c({state:x.success?"success":"error",message:x.message||(x.success?"Success":"Error")}))}return B.on("macro_status",R),()=>{B.off("macro_status",R)}},[y,n]),s.useEffect(()=>{let B=null;async function R(){window.BorealisSocket&&f&&window.BorealisSocket.emit("list_agent_windows",{agent_id:y})}R(),B=setInterval(R,Xr);function x(S){(S==null?void 0:S.agent_id)===y&&Array.isArray(S.windows)&&(r(S.windows),o(z=>z.map(E=>E.id===n?{...E,data:{...E.data,windowList:S.windows}}:E)))}return window.BorealisSocket&&window.BorealisSocket.on("agent_window_list",x),()=>{clearInterval(B),window.BorealisSocket&&window.BorealisSocket.off("agent_window_list",x)}},[y,f,o,n]);const v=()=>{o(B=>B.map(R=>{var x,S;return R.id===n?{...R,data:{...R.data,active:((x=R.data)==null?void 0:x.active)===!0||((S=R.data)==null?void 0:S.active)==="true"?"false":"true"}}:R}))},j=(u||[]).find(B=>String(B.handle)===String(t==null?void 0:t.window_handle));return e.jsxs("div",{className:"borealis-node",style:{minWidth:280,position:"relative"},children:[e.jsx("div",{style:{position:"absolute",left:-30,top:26,fontSize:"8px",color:"#6ef9fb",letterSpacing:.5,pointerEvents:"none"},children:"Agent"}),e.jsx(De,{type:"target",position:ze.Left,id:"agent",style:{top:25},className:"borealis-handle"}),e.jsx("div",{style:{position:"absolute",left:-34,top:70,fontSize:"8px",color:"#6ef9fb",letterSpacing:.5,pointerEvents:"none"},children:"Trigger"}),e.jsx(De,{type:"target",position:ze.Left,id:"trigger",style:{top:68},className:"borealis-handle"}),e.jsxs("div",{className:"borealis-node-header",style:{position:"relative"},children:["Agent Role: Macro",e.jsx("div",{style:{position:"absolute",top:"50%",right:"8px",width:"10px",transform:"translateY(-50%)",height:"10px",borderRadius:"50%",backgroundColor:i.state==="error"?fn.error:C?fn.running:fn.idle,border:"1px solid #222"}})]}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("strong",{children:"Status"}),":"," ",i.state==="error"?e.jsxs("span",{style:{color:"#ff4f4f"},children:["Error",I.message?`: ${I.message}`:""]}):C?e.jsxs("span",{style:{color:"#00d18c"},children:["Running",I.message?` (${I.message})`:""]}):"Idle",e.jsx("br",{}),e.jsx("strong",{children:"Agent Connection"}),": ",f?"Connected":"Not Connected",e.jsx("br",{}),e.jsx("strong",{children:"Target Window"}),":"," ",j?`${j.title} (${j.handle})`:t!=null&&t.window_handle?`Handle: ${t.window_handle}`:e.jsx("span",{style:{color:"#888"},children:"Not set"}),e.jsx("br",{}),e.jsx("strong",{children:"Mode"}),": ",(t==null?void 0:t.operation_mode)||Qr,e.jsx("br",{}),e.jsx("strong",{children:"Macro Type"}),": ",(t==null?void 0:t.macro_type)||"keypress",e.jsx("br",{}),e.jsx("button",{onClick:v,style:{marginTop:8,padding:"4px 10px",background:C?"#3a3a3a":"#0475c2",color:"#fff",border:"1px solid #0475c2",borderRadius:3,fontSize:"11px",cursor:"pointer"},children:C?"Pause Macro":"Start Macro"}),e.jsx("br",{}),e.jsx("span",{style:{fontSize:"9px",color:"#aaa"},children:I.timestamp?`Last event: ${new Date(I.timestamp).toLocaleTimeString()}`:""})]})]})},ta={type:"Macro_KeyPress",label:"Agent Role: Macro",description:`
Send automated key presses or typed text to any open application window on the connected agent.
Supports manual, continuous, trigger, and one-shot modes for automation and event-driven workflows.
`,content:"Send Key Press or Typed Text to Window via Agent",component:ea,config:[{key:"window_handle",label:"Target Window",type:"select",dynamicOptions:!0,defaultValue:""},{key:"macro_type",label:"Macro Type",type:"select",options:["keypress","typed_text"],defaultValue:"keypress"},{key:"key",label:"Key",type:"text",defaultValue:""},{key:"text",label:"Typed Text",type:"text",defaultValue:""},{key:"interval_ms",label:"Interval (ms)",type:"text",defaultValue:"1000"},{key:"randomize_interval",label:"Randomize Interval",type:"select",options:["true","false"],defaultValue:"false"},{key:"random_min",label:"Random Min (ms)",type:"text",defaultValue:"750"},{key:"random_max",label:"Random Max (ms)",type:"text",defaultValue:"950"},{key:"operation_mode",label:"Operation Mode",type:"select",options:Zr,defaultValue:"Continuous"},{key:"active",label:"Macro Enabled",type:"select",options:["true","false"],defaultValue:"false"},{key:"trigger",label:"Trigger Value",type:"text",defaultValue:"0"}],usage_documentation:`
### Agent Role: Macro
**Modes:**
- **Continuous**: Macro sends input non-stop when started by button.
- **Trigger-Continuous**: Macro sends input as long as upstream trigger is "1".
- **Trigger-Once**: Macro fires once per upstream "1" (one-shot edge).
- **Run Once**: Macro runs only once when started by button.
**Macro Types:**
- **Single Keypress**: Press a single key.
- **Typed Text**: Types out a string.
**Window Target:**
- Dropdown of live windows from agent, stays updated.
**Event-Driven Support:**
- Chain with other Borealis nodes (text recognition, event triggers, etc).
**Live Status:**
- Displays last agent macro event and error feedback in node.
---
`.trim()},sa=Object.freeze(Object.defineProperty({__proto__:null,default:ta},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const na=({id:n,data:t})=>{const{setNodes:o,getNodes:a}=dt(),d=mt(k=>k.edges),u=s.useCallback(()=>{try{const k=d.find(j=>j.target===n&&j.sourceHandle==="provisioner"),v=a().find(j=>j.id===(k==null?void 0:k.source));return(v==null?void 0:v.data)||null}catch{return null}},[d,a,n]),r=parseInt((t==null?void 0:t.interval)||1e3,10)||1e3,i={x:parseInt((t==null?void 0:t.x)??250,10),y:parseInt((t==null?void 0:t.y)??100,10),w:parseInt((t==null?void 0:t.w)??300,10),h:parseInt((t==null?void 0:t.h)??200,10)},c=((t==null?void 0:t.visible)??"true")==="true",p=(t==null?void 0:t.alias)||"",[l,h]=s.useState((t==null?void 0:t.value)||""),f=u(),y=((f==null?void 0:f.agent_mode)||"").toString().toLowerCase()==="system"?"SYSTEM Agent":"CURRENTUSER Agent",C=((f==null?void 0:f.agent_host)||"").toString();s.useEffect(()=>{const k=setInterval(()=>{l&&(window.BorealisValueBus[n]=l,o(v=>v.map(j=>j.id===n?{...j,data:{...j.data,value:l}}:j)))},window.BorealisUpdateRate||100);return()=>clearInterval(k)},[n,l,o]),s.useEffect(()=>{const k=window.BorealisSocket;if(!k)return;const v=j=>{if((j==null?void 0:j.node_id)!==n)return;const B=u(),R=B==null?void 0:B.agent_id;if(!R||(j==null?void 0:j.agent_id)!==R)return;j.image_base64&&(h(j.image_base64),window.BorealisValueBus[n]=j.image_base64);const{x,y:S,w:z,h:E}=j;x!==void 0&&S!==void 0&&z!==void 0&&E!==void 0&&o(U=>U.map(X=>X.id===n?{...X,data:{...X.data,x,y:S,w:z,h:E}}:X))};return k.on("agent_screenshot_task",v),()=>k.off("agent_screenshot_task",v)},[n,o,u]),window.__BorealisInstructionNodes=window.__BorealisInstructionNodes||{},window.__BorealisInstructionNodes[n]=()=>{const k=u()||{},j=(k.agent_mode||"").toString().toLowerCase()==="system"?"system":"currentuser";return{node_id:n,role:"screenshot",interval:r,visible:c,alias:p,target_agent_mode:j,target_agent_host:k.agent_host||"",...i}};const I=()=>{const k=u(),v=k==null?void 0:k.agent_id;if(!v){alert("No valid agent connection found.");return}const j=`${window.location.origin}/api/agent/${v}/node/${n}/screenshot/live`;navigator.clipboard.writeText(j).then(()=>console.log(`[Clipboard] Live View URL copied: ${j}`)).catch(B=>console.error("Clipboard copy failed:",B))};return e.jsxs("div",{className:"borealis-node",style:{position:"relative"},children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Agent Role: Screenshot"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:[e.jsxs("div",{children:[e.jsx("b",{children:"Region:"})," X:",i.x," Y:",i.y," W:",i.w," H:",i.h]}),e.jsxs("div",{children:[e.jsx("b",{children:"Interval:"})," ",r," ms"]}),e.jsxs("div",{children:[e.jsx("b",{children:"Agent Context:"})," ",y]}),e.jsxs("div",{children:[e.jsx("b",{children:"Target Host:"})," ",C||e.jsx("span",{style:{color:"#666"},children:"unknown"})]}),e.jsxs("div",{children:[e.jsx("b",{children:"Overlay:"})," ",c?"Yes":"No"]}),e.jsxs("div",{children:[e.jsx("b",{children:"Label:"})," ",p||e.jsx("span",{style:{color:"#666"},children:"none"})]}),e.jsx("div",{style:{textAlign:"center",fontSize:"8px",color:"#aaa"},children:l?`Last image: ${Math.round(l.length/1024)} KB`:"Awaiting Screenshot Data..."})]}),e.jsx("div",{style:{position:"absolute",top:4,right:4},children:e.jsx(nt,{size:"small",onClick:I,children:e.jsx(zo,{style:{fontSize:14}})})})]})},oa={type:"Agent_Role_Screenshot",label:"Agent Role: Screenshot",description:`
Capture a live screenshot of a defined region from a remote Borealis Agent.
- Define region (X, Y, Width, Height)
- Select update interval (ms)
- Optionally show a visual overlay with a label
- Pushes base64 PNG stream to downstream nodes
- Use copy button to share live view URL
- Targets the CURRENTUSER or SYSTEM agent context selected upstream
`.trim(),content:"Capture screenshot region via agent",component:na,config:[{key:"interval",label:"Update Interval (ms)",type:"text",defaultValue:"1000"},{key:"x",label:"Region X",type:"text",defaultValue:"250"},{key:"y",label:"Region Y",type:"text",defaultValue:"100"},{key:"w",label:"Region Width",type:"text",defaultValue:"300"},{key:"h",label:"Region Height",type:"text",defaultValue:"200"},{key:"visible",label:"Show Overlay on Agent",type:"select",options:["true","false"],defaultValue:"true"},{key:"alias",label:"Overlay Label",type:"text",defaultValue:""}],usage_documentation:`
### Agent Role: Screenshot Node
This node defines a screenshot-capture role for a Borealis Agent.
**How It Works**
- The region (X, Y, W, H) is sent to the Agent for real-time screenshot capture.
- The interval determines how often the Agent captures and pushes new images.
- Optionally, an overlay with a label can be displayed on the Agent's screen for visual feedback.
- The captured screenshot (as a base64 PNG) is available to downstream nodes.
- Use the share button to copy a live viewing URL for the screenshot stream.
**Configuration**
- All fields are edited via the right sidebar.
- Coordinates update live if region is changed from the Agent.
**Warning**
- Changing region from the Agent UI will update this node's coordinates.
- Do not remove the bi-directional region write-back: if the region moves, this node updates immediately.
**Example Use Cases**
- Automated visual QA (comparing regions of apps)
- OCR on live application windows
- Remote monitoring dashboards
`.trim()},ra=Object.freeze(Object.defineProperty({__proto__:null,default:oa},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const aa=({id:n,data:t})=>{const o=mt(j=>j.edges),{setNodes:a}=dt(),[d,u]=s.useState((t==null?void 0:t.alertType)||"Once"),[r,i]=s.useState((t==null?void 0:t.interval)||1e3),[c,p]=s.useState("0"),[l,h]=s.useState((t==null?void 0:t.audio)||null),[f,y]=s.useState("0"),C=s.useRef(null),I=()=>{if(C.current){console.log(`[Alert Node ${n}] Attempting to play sound`);try{C.current.pause(),C.current.currentTime=0,C.current.load(),C.current.play().then(()=>{console.log(`[Alert Node ${n}] Sound played successfully`)}).catch(j=>{console.warn(`[Alert Node ${n}] Audio play blocked or errored:`,j)})}catch(j){console.error(`[Alert Node ${n}] Failed to play sound:`,j)}}else console.warn(`[Alert Node ${n}] No audioRef loaded`)},k=j=>{const B=j.target.files[0];if(!B)return;if(console.log(`[Alert Node ${n}] File selected:`,B.name,B.type),!["audio/wav","audio/mp3","audio/mpeg","audio/ogg"].includes(B.type)){console.warn(`[Alert Node ${n}] Unsupported audio type: ${B.type}`);return}const x=new FileReader;x.onload=S=>{const z=S.target.result,E=B.type||"audio/mpeg",U=z.startsWith("data:")?z:`data:${E};base64,${z}`;C.current&&(C.current.pause(),C.current.src="",C.current.load(),C.current=null);const X=new Audio;X.src=U;let ue=!1;X.addEventListener("canplaythrough",()=>{ue||(ue=!0,console.log(`[Alert Node ${n}] Audio is decodable and ready: ${B.name}`),h(U),C.current=X,X.load(),a(Se=>Se.map(ce=>ce.id===n?{...ce,data:{...ce.data,audio:U}}:ce)))}),setTimeout(()=>{ue||console.warn(`[Alert Node ${n}] WARNING: Audio not marked ready in time. May fail silently.`)},2e3)},x.onerror=S=>{console.error(`[Alert Node ${n}] File read error:`,S)},x.readAsDataURL(B)};s.useEffect(()=>{if(l){console.log(`[Alert Node ${n}] Loading embedded audio from workflow`),C.current&&(C.current.pause(),C.current.src="",C.current.load(),C.current=null);const j=new Audio(l);j.addEventListener("canplaythrough",()=>{console.log(`[Alert Node ${n}] Embedded audio ready`)}),C.current=j,j.load()}else console.log(`[Alert Node ${n}] No custom audio, using fallback silent wav`),C.current=new Audio("data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YRAAAAAA"),C.current.load()},[l]),s.useEffect(()=>{let j=window.BorealisUpdateRate,B=null;const R=()=>{const z=o.find(X=>X.target===n),E=(z==null?void 0:z.source)||null,U=E&&window.BorealisValueBus[E]||"0";y(U),d==="Once"&&U==="1"&&c!=="1"&&(console.log(`[Alert Node ${n}] Triggered ONCE playback`),I()),p(U)},x=()=>{d==="Constant"?B=setInterval(()=>{const z=o.find(X=>X.target===n),E=(z==null?void 0:z.source)||null,U=E&&window.BorealisValueBus[E]||"0";y(U),String(U)==="1"&&(console.log(`[Alert Node ${n}] Triggered CONSTANT playback`),I())},r):B=setInterval(R,j)};x();const S=setInterval(()=>{const z=window.BorealisUpdateRate;z!==j&&d==="Once"&&(j=z,clearInterval(B),x())},250);return()=>{clearInterval(B),clearInterval(S)}},[o,d,r,c]);const v=f==="1"?"#ff4444":"#44ff44";return e.jsxs("div",{className:"borealis-node",style:{position:"relative"},children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsxs("div",{className:"borealis-node-header",style:{position:"relative"},children:[(t==null?void 0:t.label)||"Alert Sound",e.jsx("div",{style:{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",width:"10px",height:"10px",borderRadius:"50%",backgroundColor:v,border:"1px solid #222"}})]}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"8px",fontSize:"9px",color:"#ccc"},children:'Play a sound alert when input is "1"'}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginBottom:"4px"},children:"Alerting Type:"}),e.jsxs("select",{value:d,onChange:j=>u(j.target.value),style:ia,children:[e.jsx("option",{value:"Once",children:"Once"}),e.jsx("option",{value:"Constant",children:"Constant"})]}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginBottom:"4px"},children:"Alert Interval (ms):"}),e.jsx("input",{type:"number",min:"100",step:"100",value:r,onChange:j=>i(parseInt(j.target.value)),disabled:d==="Once",style:{...Wn,background:d==="Once"?"#2a2a2a":"#1e1e1e"}}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginTop:"6px",marginBottom:"4px"},children:"Custom Sound:"}),e.jsxs("div",{style:{display:"flex",gap:"4px"},children:[e.jsx("input",{type:"file",accept:".wav,.mp3,.mpeg,.ogg",onChange:k,style:{...Wn,marginBottom:0,flex:1}}),e.jsx("button",{style:{fontSize:"9px",padding:"4px 8px",backgroundColor:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",cursor:"pointer"},onClick:I,title:"Test playback",children:"Test"})]})]})]})},ia={fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",width:"100%",marginBottom:"8px"},Wn={fontSize:"9px",padding:"4px",color:"#ccc",border:"1px solid #444",borderRadius:"2px",width:"100%",marginBottom:"8px"},la={type:"AlertSoundNode",label:"Alert Sound",description:`
Plays a sound alert when input = "1"
- "Once" = Only when 0 -> 1 transition
- "Constant" = Repeats every X ms while input stays 1
- Custom audio supported (MP3/WAV/OGG)
- Base64 audio embedded in workflow and restored
- Visual status indicator (green = 0, red = 1)
- Manual "Test" button for validation
`.trim(),content:"Sound alert when input value = 1",component:aa},ca=Object.freeze(Object.defineProperty({__proto__:null,default:la},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const da=({id:n,data:t})=>{const o=mt(c=>c.edges),{setNodes:a}=dt(),[d,u]=s.useState("Line Does Not Exist"),r=s.useRef(d),i=parseInt(t==null?void 0:t.lineNumber,10)||1;return s.useEffect(()=>{let c=null,p=window.BorealisUpdateRate;const l=()=>{const f=o.find(k=>k.target===n);if(!f){r.current="Line Does Not Exist",u("Line Does Not Exist"),window.BorealisValueBus[n]="Line Does Not Exist";return}const y=window.BorealisValueBus[f.source];if(!Array.isArray(y)){r.current="Line Does Not Exist",u("Line Does Not Exist"),window.BorealisValueBus[n]="Line Does Not Exist";return}const C=Math.max(0,i-1),I=y[C]??"Line Does Not Exist";I!==r.current&&(r.current=I,u(I),window.BorealisValueBus[n]=I)};c=setInterval(l,p);const h=setInterval(()=>{const f=window.BorealisUpdateRate;f!==p&&(clearInterval(c),p=f,c=setInterval(l,p))},300);return()=>{clearInterval(c),clearInterval(h)}},[n,o,i]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Array Index Extractor"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:[e.jsx("div",{style:{marginBottom:"6px",color:"#ccc"},children:"Output a specific line from an upstream array."}),e.jsxs("div",{style:{color:"#888",marginBottom:4},children:["Line Number: ",e.jsx("b",{children:i})]}),e.jsx("label",{style:{display:"block",marginBottom:"2px"},children:"Output:"}),e.jsx("input",{type:"text",value:d,disabled:!0,style:{width:"100%",fontSize:"9px",background:"#2a2a2a",color:"#ccc",border:"1px solid #444",borderRadius:"2px",padding:"3px"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},ua={type:"ArrayIndexExtractor",label:"Array Index Extractor",description:`
Outputs a specific line from an upstream array, such as the result of OCR multi-line extraction.
- Specify the **line number** (1 = first line)
- Outputs the value at that index if present
- If index is out of bounds, outputs "Line Does Not Exist"
`.trim(),content:"Output a Specific Array Index's Value",component:da,config:[{key:"lineNumber",label:"Line Number (1 = First Line)",type:"text",defaultValue:"1"}],usage_documentation:`
### Array Index Extractor Node
This node allows you to extract a specific line or item from an upstream array value.
**Typical Use:**
- Used after OCR or any node that outputs an array of lines or items.
- Set the **Line Number** (1-based, so "1" = first line).
**Behavior:**
- If the line exists, outputs the value at that position.
- If not, outputs: \`Line Does Not Exist\`.
**Input:**
- Connect an upstream node that outputs an array (such as OCR Text Extraction).
**Sidebar Config:**
- Set the desired line number from the configuration sidebar for live updates.
---
`.trim()},pa=Object.freeze(Object.defineProperty({__proto__:null,default:ua},Symbol.toStringTag,{value:"Module"})),fa=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(B=>B.edges),d=s.useRef(null),u=s.useRef(!1),r=s.useRef({x:0,y:0}),i=s.useRef({width:0,height:0}),[c,p]=s.useState((t==null?void 0:t.jsonData)||{}),l=parseInt((t==null?void 0:t.width)||"300",10),h=parseInt((t==null?void 0:t.height)||"150",10),[f,y]=s.useState({width:l,height:h}),C=s.useRef(c),I=s.useCallback(()=>{const B=`${Math.round(f.width)}px`,R=`${Math.round(f.height)}px`;o(x=>x.map(S=>S.id===n?{...S,data:{...S.data,width:B,height:R}}:S))},[f,n,o]);s.useEffect(()=>{const B=x=>{if(!u.current)return;const S=x.clientX-r.current.x,z=x.clientY-r.current.y;y({width:Math.max(100,i.current.width+S),height:Math.max(60,i.current.height+z)})},R=()=>{u.current&&(u.current=!1,I())};return window.addEventListener("mousemove",B),window.addEventListener("mouseup",R),()=>{window.removeEventListener("mousemove",B),window.removeEventListener("mouseup",R)}},[I]);const k=B=>{B.stopPropagation(),u.current=!0,r.current={x:B.clientX,y:B.clientY},i.current={...f}};s.useEffect(()=>{let B=window.BorealisUpdateRate;const x=setInterval(()=>{const z=a.find(E=>E.target===n);if(z&&z.source){const E=window.BorealisValueBus[z.source];typeof E=="object"&&JSON.stringify(E)!==JSON.stringify(C.current)&&(C.current=E,p(E),window.BorealisValueBus[n]=E,o(U=>U.map(X=>X.id===n?{...X,data:{...X.data,jsonData:E}}:X)))}else window.BorealisValueBus[n]=C.current},B),S=setInterval(()=>{window.BorealisUpdateRate!==B&&(clearInterval(x),clearInterval(S))},200);return()=>{clearInterval(x),clearInterval(S)}},[n,a,o]);const v=JSON.stringify(c,null,2),j=qt.highlight(v,qt.languages.json,"json");return e.jsxs("div",{ref:d,className:"borealis-node",style:{display:"flex",flexDirection:"column",width:f.width,height:f.height,overflow:"visible",position:"relative",boxSizing:"border-box"},children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"Display JSON Data"}),e.jsxs("div",{className:"borealis-node-content",style:{flex:1,padding:"4px",fontSize:"9px",color:"#ccc",display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsx("div",{style:{marginBottom:"4px"},children:"Display prettified JSON from upstream."}),e.jsx("div",{style:{flex:1,width:"100%",background:"#1e1e1e",border:"1px solid #444",borderRadius:"2px",padding:"4px",overflowY:"auto",fontFamily:"monospace",fontSize:"9px"},children:e.jsx("pre",{dangerouslySetInnerHTML:{__html:j},style:{margin:0}})})]}),e.jsx("div",{onMouseDown:k,style:{position:"absolute",width:"20px",height:"20px",right:"-4px",bottom:"-4px",cursor:"nwse-resize",background:"transparent",zIndex:10}})]})},ha={type:"Node_JSON_Pretty_Display",label:"Display JSON Data",description:"Display upstream JSON object as prettified JSON with syntax highlighting.",content:"Display prettified multi-line JSON from upstream node.",component:fa},ma=Object.freeze(Object.defineProperty({__proto__:null,default:ha},Symbol.toStringTag,{value:"Module"})),xa=({id:n,data:t})=>{const{setNodes:o,getEdges:a}=dt(),[d,u]=s.useState((t==null?void 0:t.keyName)||""),[r,i]=s.useState((t==null?void 0:t.result)||""),c=p=>{const l=p.target.value;u(l),o(h=>h.map(f=>f.id===n?{...f,data:{...f.data,keyName:l}}:f))};return s.useEffect(()=>{let p=window.BorealisUpdateRate,l;const h=()=>{var v;const I=(v=a().filter(j=>j.target===n)[0])==null?void 0:v.source;let k="Key Not Found";if(I&&window.BorealisValueBus[I]!==void 0){let j=window.BorealisValueBus[I];if(j&&typeof j=="object"&&d){const B=d.split(".");let R=j;for(let x of B)if(R!=null&&(typeof R=="object"||Array.isArray(R))&&x in R)R=R[x];else{R=void 0;break}R!==void 0&&(k=String(R))}}k!==r&&(i(k),window.BorealisValueBus[n]=k,o(j=>j.map(B=>B.id===n?{...B,data:{...B.data,result:k}}:B)))};h(),l=setInterval(h,p);const f=setInterval(()=>{const y=window.BorealisUpdateRate;y!==p&&(clearInterval(l),p=y,l=setInterval(h,p))},250);return()=>{clearInterval(l),clearInterval(f)}},[d,n,o,a,r]),e.jsxs("div",{className:"borealis-node",children:[e.jsx("div",{className:"borealis-node-header",children:"JSON Value Extractor"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("label",{style:{fontSize:"9px",display:"block",marginBottom:"4px"},children:"Key:"}),e.jsx("input",{type:"text",value:d,onChange:c,placeholder:"e.g. name.en",style:{fontSize:"9px",padding:"4px",width:"100%",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px"}}),e.jsx("label",{style:{fontSize:"9px",display:"block",margin:"8px 0 4px"},children:"Value:"}),e.jsx("textarea",{readOnly:!0,value:r,rows:2,style:{fontSize:"9px",padding:"4px",width:"100%",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",resize:"none"}})]}),e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},ga={type:"JSON_Value_Extractor",label:"JSON Value Extractor",description:"Extract a nested value by dot-delimited path from upstream JSON data.",content:"Provide a dot-separated key path (e.g. 'name.en'); outputs the extracted string or 'Key Not Found'.",component:xa},ba=Object.freeze(Object.defineProperty({__proto__:null,default:ga},Symbol.toStringTag,{value:"Module"})),ya=(n="")=>{let t=0;for(let o=0;o<n.length;o+=101){const a=n.charCodeAt(o);t=(t<<5)-t+a,t|=0}return Math.abs(t)};window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const ja=({id:n,data:t})=>{const o=mt(j=>j.edges),{setNodes:a}=dt(),[d,u]=s.useState(""),r=s.useRef(""),i=s.useRef({engine:"",backend:"",dataType:""}),c=s.useRef(0),p=s.useRef(0),l=(t==null?void 0:t.engine)||"None",h=(t==null?void 0:t.backend)||"CPU",f=(t==null?void 0:t.dataType)||"Mixed",y=(t==null?void 0:t.customRateEnabled)??!0,C=(t==null?void 0:t.customRateMs)||1e3,I=(t==null?void 0:t.changeThreshold)||0,k=async j=>{const B=j.replace(/^data:image\/[a-zA-Z]+;base64,/,"");try{const R=await fetch("/api/ocr",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image_base64:B,engine:l,backend:h})}),x=await R.json();return R.ok&&Array.isArray(x.lines)?x.lines:[`[ERROR] ${x.error||"Invalid OCR response."}`]}catch(R){return[`[ERROR] OCR API request failed: ${R.message}`]}},v=j=>f==="Numerical"?j.map(B=>B.replace(/[^\d.%\s]/g,"").replace(/\s+/g," ").trim()).filter(Boolean):f==="String"?j.map(B=>B.replace(/[^a-zA-Z\s]/g,"").replace(/\s+/g," ").trim()).filter(Boolean):j;return s.useEffect(()=>{let j=null,B=window.BorealisUpdateRate||100;const R=async()=>{const S=o.find(W=>W.target===n);if(!S){window.BorealisValueBus[n]=[],u("");return}const z=window.BorealisValueBus[S.source]||"",E=Date.now(),U=y?C:window.BorealisUpdateRate||100,X=i.current.engine!==l||i.current.backend!==h||i.current.dataType!==f,ue=ya(z),Se=Math.abs(ue-p.current),ce=I/100*1e9,de=Se>ce;if(!X&&(!de||E-c.current<U))return;i.current={engine:l,backend:h,dataType:f},c.current=E,p.current=ue,r.current=z;const me=await k(z),w=v(me);u(w.join(`
`)),window.BorealisValueBus[n]=w};j=setInterval(R,B);const x=setInterval(()=>{const S=window.BorealisUpdateRate||100;S!==B&&(clearInterval(j),j=setInterval(R,S),B=S)},300);return()=>{clearInterval(j),clearInterval(x)}},[n,l,h,f,y,C,I,o]),e.jsxs("div",{className:"borealis-node",style:{minWidth:"200px"},children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"OCR-Based Text Extraction"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{fontSize:"9px",marginBottom:"8px",color:"#ccc"},children:"Extract Multi-Line Text from Upstream Image Node"}),e.jsx("label",{style:wa,children:"OCR Output:"}),e.jsx("textarea",{readOnly:!0,value:d,rows:6,style:{width:"100%",fontSize:"9px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",padding:"4px",resize:"vertical"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},wa={fontSize:"9px",display:"block",marginTop:"6px",marginBottom:"2px"},va={type:"OCR_Text_Extraction",label:"OCR Text Extraction",description:"Extract text from upstream image using backend OCR engine via API. Includes rate limiting and sensitivity detection for smart processing.",content:"Extract Multi-Line Text from Upstream Image Node",component:ja,config:[{key:"engine",label:"OCR Engine",type:"select",options:["None","TesseractOCR","EasyOCR"],defaultValue:"None"},{key:"backend",label:"Compute Backend",type:"select",options:["CPU","GPU"],defaultValue:"CPU"},{key:"dataType",label:"Data Type Filter",type:"select",options:["Mixed","Numerical","String"],defaultValue:"Mixed"},{key:"customRateEnabled",label:"Custom API Rate Limit Enabled",type:"select",options:["true","false"],defaultValue:"true"},{key:"customRateMs",label:"Custom API Rate Limit (ms)",type:"text",defaultValue:"1000"},{key:"changeThreshold",label:"Change Detection Sensitivity (0-100)",type:"text",defaultValue:"0"}],usage_documentation:`
### OCR Text Extraction Node
Extracts text (lines) from an **upstream image node** using a selectable backend OCR engine (Tesseract or EasyOCR). Designed for screenshots, scanned forms, and live image data pipelines.
**Features:**
- **Engine:** Select between None, TesseractOCR, or EasyOCR
- **Backend:** Choose CPU or GPU (if supported)
- **Data Type Filter:** Post-processes recognized lines for numerical-only or string-only content
- **Custom API Rate Limit:** When enabled, you can set a custom polling rate for OCR requests (in ms)
- **Change Detection Sensitivity:** Node will only re-OCR if the input image changes significantly (hash-based, 0 disables)
**Outputs:**
- Array of recognized lines, pushed to downstream nodes
- Output is displayed in the node (read-only)
**Usage:**
- Connect an image node (base64 output) to this node's input
- Configure OCR engine and options in the sidebar
- Useful for extracting values from screen regions, live screenshots, PDF scans, etc.
**Notes:**
- Setting Engine to 'None' disables OCR
- Use numerical/string filter for precise downstream parsing
- Polling rate too fast may cause backend overload
- Change threshold is a 0-100 scale (0 = always run, 100 = image must change completely)
`.trim()},Sa=Object.freeze(Object.defineProperty({__proto__:null,default:va},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Ca=({id:n,data:t})=>{const o=mt(p=>p.edges),{setNodes:a}=dt(),[d,u]=s.useState(""),[r,i]=s.useState(""),c=s.useRef("");return s.useEffect(()=>{let p=null,l=window.BorealisUpdateRate;const h=()=>{const y=o.find(k=>k.target===n),C=y&&window.BorealisValueBus[y.source]||"";i(C);let I=C;try{if(((t==null?void 0:t.enabled)??!0)&&(t!=null&&t.pattern)){const k=new RegExp(t.pattern,t.flags||"g");let v=(t.replacement??"").trim();v.startsWith('"')&&v.endsWith('"')&&(v=v.slice(1,-1)),I=C.replace(k,v)}}catch(k){I=`[Error] ${k.message}`}I!==c.current&&(c.current=I,u(I),window.BorealisValueBus[n]=I)};p=setInterval(h,l);const f=setInterval(()=>{const y=window.BorealisUpdateRate;y!==l&&(clearInterval(p),p=setInterval(h,y),l=y)},300);return()=>{clearInterval(p),clearInterval(f)}},[n,o,t==null?void 0:t.pattern,t==null?void 0:t.replacement,t==null?void 0:t.flags,t==null?void 0:t.enabled]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Regex Replace"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"6px",fontSize:"9px",color:"#ccc"},children:"Performs live regex-based find/replace on incoming string value."}),e.jsxs("div",{style:{fontSize:"9px",color:"#ccc",marginBottom:2},children:[e.jsx("b",{children:"Pattern:"})," ",(t==null?void 0:t.pattern)||e.jsx("i",{children:"(not set)"}),e.jsx("br",{}),e.jsx("b",{children:"Flags:"})," ",(t==null?void 0:t.flags)||"g",e.jsx("br",{}),e.jsx("b",{children:"Enabled:"})," ",(t==null?void 0:t.enabled)??!0?"Yes":"No"]}),e.jsx("label",{style:{fontSize:"8px",color:"#888"},children:"Original:"}),e.jsx("textarea",{readOnly:!0,value:r,rows:2,style:{width:"100%",fontSize:"9px",background:"#222",color:"#ccc",border:"1px solid #444",borderRadius:"2px",padding:"3px",resize:"vertical",marginBottom:"6px"}}),e.jsx("label",{style:{fontSize:"8px",color:"#888"},children:"Output:"}),e.jsx("textarea",{readOnly:!0,value:d,rows:2,style:{width:"100%",fontSize:"9px",background:"#2a2a2a",color:"#ccc",border:"1px solid #444",borderRadius:"2px",padding:"3px",resize:"vertical"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},_a={type:"RegexReplace",label:"Regex Replace",description:`
Live regex-based string find/replace node.
- Runs a JavaScript regular expression on every input update.
- Useful for cleanup, format fixes, redacting, token extraction.
- Configurable flags, replacement text, and enable toggle.
- Handles errors gracefully, shows live preview in the sidebar.
`.trim(),content:"Perform regex replacement on incoming string",component:Ca,config:[{key:"pattern",label:"Regex Pattern",type:"text",defaultValue:"\\d+"},{key:"replacement",label:"Replacement",type:"text",defaultValue:""},{key:"flags",label:"Regex Flags",type:"text",defaultValue:"g"},{key:"enabled",label:"Enable Replacement",type:"select",options:["true","false"],defaultValue:"true"}],usage_documentation:`
### Regex Replace Node
**Purpose:**
Perform flexible find-and-replace on strings using JavaScript-style regular expressions.
#### Typical Use Cases
- Clean up text, numbers, or IDs in a data stream
- Mask or redact sensitive info (emails, credit cards, etc)
- Extract tokens, words, or reformat content
#### Configuration (see "Config" tab):
- **Regex Pattern**: The search pattern (supports capture groups)
- **Replacement**: The replacement string. You can use \`$1, $2\` for capture groups.
- **Regex Flags**: Default \`g\` (global). Add \`i\` (case-insensitive), \`m\` (multiline), etc.
- **Enable Replacement**: On/Off toggle (for easy debugging)
#### Behavior
- Upstream value is live-updated.
- When enabled, node applies the regex and emits the result downstream.
- Shows both input and output in the sidebar for debugging.
- If the regex is invalid, error is displayed as output.
#### Output
- Emits the transformed string to all downstream nodes.
- Updates in real time at the global Borealis update rate.
#### Example
Pattern: \`(\\d+)\`
Replacement: \`[number:$1]\`
Input: \`abc 123 def 456\`
Output: \`abc [number:123] def [number:456]\`
---
**Tips:**
- Use double backslashes (\\) in patterns when needed (e.g. \`\\\\d+\`).
- Flags can be any combination (e.g. \`gi\`).
`.trim()},ka=Object.freeze(Object.defineProperty({__proto__:null,default:_a},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Ia=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(p=>p.edges),d=(t==null?void 0:t.pattern)??"",u=(t==null?void 0:t.flags)??"i",r=s.useRef("0"),[i,c]=s.useState("0");return s.useEffect(()=>{let p=null,l=window.BorealisUpdateRate;const h=()=>{const y=a.find(v=>v.target===n),C=y&&window.BorealisValueBus[y.source]||"";let I=!1;try{d&&(I=new RegExp(d,u).test(C))}catch{I=!1}const k=I?"1":"0";k!==r.current&&(r.current=k,c(k),window.BorealisValueBus[n]=k,o(v=>v.map(j=>j.id===n?{...j,data:{...j.data,match:k}}:j)))};p=setInterval(h,l);const f=setInterval(()=>{const y=window.BorealisUpdateRate;y!==l&&(clearInterval(p),p=setInterval(h,y),l=y)},300);return()=>{clearInterval(p),clearInterval(f)}},[n,a,d,u,o]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Regex Search"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",color:"#ccc"},children:["Match: ",i]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Ra={type:"RegexSearch",label:"Regex Search",description:`
Test for text matches with a regular expression pattern.
- Accepts a regex pattern and flags (e.g. "i", "g", "m")
- Connect any node to the input to test its value.
- Outputs "1" if the regex matches, otherwise "0".
- Useful for input validation, filtering, or text triggers.
`.trim(),content:"Outputs '1' if regex matches input, otherwise '0'",component:Ia,config:[{key:"pattern",label:"Regex Pattern",type:"text",defaultValue:"",placeholder:"e.g. World"},{key:"flags",label:"Regex Flags",type:"text",defaultValue:"i",placeholder:"e.g. i"}],usage_documentation:`
### Regex Search Node
This node tests its input value against a user-supplied regular expression pattern.
**Configuration (Sidebar):**
- **Regex Pattern**: Standard JavaScript regex pattern.
- **Regex Flags**: Any combination of \`i\` (ignore case), \`g\` (global), \`m\` (multiline), etc.
**Input:**
- Accepts a string from any upstream node.
**Output:**
- Emits "1" if the pattern matches the input string.
- Emits "0" if there is no match or the pattern/flags are invalid.
**Common Uses:**
- Search for words/phrases in extracted text.
- Filter values using custom patterns.
- Create triggers based on input structure (e.g. validate an email, detect phone numbers, etc).
#### Example:
- **Pattern:** \`World\`
- **Flags:** \`i\`
- **Input:** \`Hello world!\`
- **Output:** \`1\` (matched, case-insensitive)
`.trim()},Na=Object.freeze(Object.defineProperty({__proto__:null,default:Ra},Symbol.toStringTag,{value:"Module"})),Ta=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(v=>v.edges),d=s.useRef(null),u=s.useRef(!1),r=s.useRef({x:0,y:0}),i=s.useRef({width:0,height:0}),[c,p]=s.useState((t==null?void 0:t.lines)||[]),l=s.useRef(c),h=parseInt((t==null?void 0:t.width)||"300",10),f=parseInt((t==null?void 0:t.height)||"150",10),[y,C]=s.useState({width:h,height:f}),I=s.useCallback(()=>{const v=`${Math.round(y.width)}px`,j=`${Math.round(y.height)}px`;o(B=>B.map(R=>R.id===n?{...R,data:{...R.data,width:v,height:j}}:R))},[y,n,o]);s.useEffect(()=>{const v=B=>{if(!u.current)return;const R=B.clientX-r.current.x,x=B.clientY-r.current.y;C({width:Math.max(100,i.current.width+R),height:Math.max(60,i.current.height+x)})},j=()=>{u.current&&(u.current=!1,I())};return window.addEventListener("mousemove",v),window.addEventListener("mouseup",j),()=>{window.removeEventListener("mousemove",v),window.removeEventListener("mouseup",j)}},[I]);const k=v=>{v.stopPropagation(),u.current=!0,r.current={x:v.clientX,y:v.clientY},i.current={...y}};return s.useEffect(()=>{let v=window.BorealisUpdateRate;const B=setInterval(()=>{const x=a.find(S=>S.target===n);if(x&&x.source){const S=window.BorealisValueBus[x.source]||[];JSON.stringify(S)!==JSON.stringify(l.current)&&(l.current=S,p(S),window.BorealisValueBus[n]=S,o(z=>z.map(E=>E.id===n?{...E,data:{...E.data,lines:S}}:E)))}else window.BorealisValueBus[n]=l.current},v),R=setInterval(()=>{window.BorealisUpdateRate!==v&&(clearInterval(B),clearInterval(R))},200);return()=>{clearInterval(B),clearInterval(R)}},[n,a,o]),e.jsxs("div",{ref:d,className:"borealis-node",style:{display:"flex",flexDirection:"column",width:y.width,height:y.height,overflow:"visible",position:"relative",boxSizing:"border-box"},children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Display Multi-Line Array"}),e.jsxs("div",{className:"borealis-node-content",style:{flex:1,padding:"4px",fontSize:"9px",color:"#ccc",display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsx("div",{style:{marginBottom:"4px"},children:(t==null?void 0:t.content)||"Display upstream multi-line text arrays."}),e.jsx("label",{style:{marginBottom:"4px"},children:"Upstream Text Data:"}),e.jsx("textarea",{value:c.join(`
`),readOnly:!0,style:{flex:1,width:"100%",fontSize:"9px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",padding:"4px",resize:"none",overflowY:"auto",boxSizing:"border-box"}})]}),e.jsx("div",{onMouseDown:k,style:{position:"absolute",width:"20px",height:"20px",right:"-4px",bottom:"-4px",cursor:"nwse-resize",background:"transparent",zIndex:10}})]})},Aa={type:"Node_TextArray_Display",label:"Display Multi-Line Array",description:"Display upstream multi-line text arrays.",content:"Display upstream multi-line text arrays.",component:Ta},Ba=Object.freeze(Object.defineProperty({__proto__:null,default:Aa},Symbol.toStringTag,{value:"Module"})),Oa=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(k=>k.edges);window.BorealisValueBus||(window.BorealisValueBus={});const d=(t==null?void 0:t.url)||"http://localhost:5000/health",u=((t==null?void 0:t.useProxy)??"true")==="true",r=(t==null?void 0:t.body)||"",i=parseInt((t==null?void 0:t.intervalSec)||"10",10)||10,[c,p]=s.useState(null),[l,h]=s.useState(null),[f,y]=s.useState(""),C=s.useRef(null);s.useEffect(()=>{let k=!1;const v=async()=>{try{p(null);const R=a.find(Se=>Se.target===n),S=(R?window.BorealisValueBus[R.source]:null)||d;let z=u?`/api/proxy?url=${encodeURIComponent(S)}`:S;const E={};r.trim()&&(E.method="POST",E.headers={"Content-Type":"application/json"},E.body=r);const U=await fetch(z,E);if(h(U.status),y(U.statusText),!U.ok)throw C.current=null,window.BorealisValueBus[n]=void 0,o(Se=>Se.map(ce=>ce.id===n?{...ce,data:{...ce.data,result:void 0}}:ce)),new Error(`HTTP ${U.status}`);const X=await U.json(),ue=JSON.stringify(X,null,2);!k&&C.current!==ue&&(C.current=ue,window.BorealisValueBus[n]=X,o(Se=>Se.map(ce=>ce.id===n?{...ce,data:{...ce.data,result:ue}}:ce)))}catch(R){console.error("API Request node fetch error:",R),p(R.message)}};v();const j=Math.max(i,1)*1e3,B=setInterval(v,j);return()=>{k=!0,clearInterval(B)}},[d,r,i,u,n,o,a]);const I=a.find(k=>k.target===n);return I&&I.source,e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"API Request"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",color:"#ccc"},children:[e.jsxs("div",{children:[e.jsx("b",{children:"Status:"})," ",c?e.jsx("span",{style:{color:"#f66"},children:c}):l!==null?e.jsxs("span",{style:{color:"#6f6"},children:[l," ",f]}):"N/A"]}),e.jsxs("div",{style:{marginTop:"4px"},children:[e.jsx("b",{children:"Result:"}),e.jsx("pre",{style:{background:"#181818",color:"#b6ffb4",fontSize:"8px",maxHeight:62,overflow:"auto",margin:0,padding:"4px",borderRadius:"2px"},children:t!=null&&t.result?String(t.result).slice(0,350):"No data"})]})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Pa={type:"API_Request",label:"API Request",description:"Fetch JSON from an API endpoint with optional POST body, polling, and proxy toggle. Accepts URL from upstream.",content:"Fetch JSON from HTTP or remote API endpoint, with CORS proxy option.",component:Oa,config:[{key:"url",label:"Request URL",type:"text",defaultValue:"http://localhost:5000/health"},{key:"useProxy",label:"Use Proxy (bypass CORS)",type:"select",options:["true","false"],defaultValue:"true"},{key:"body",label:"Request Body (JSON)",type:"textarea",defaultValue:""},{key:"intervalSec",label:"Polling Interval (sec)",type:"text",defaultValue:"10"}],usage_documentation:`
### API Request Node
Fetches JSON from an HTTP or HTTPS API endpoint, with an option to POST a JSON body and control polling interval.
**Features:**
- **URL**: You can set a static URL, or connect an upstream node to dynamically control the API endpoint.
- **Use Proxy**: When enabled, requests route through the Borealis backend proxy to bypass CORS/browser restrictions.
- **Request Body**: POST JSON data (leave blank for GET).
- **Polling Interval**: Set how often (in seconds) to re-fetch the API.
**Outputs:**
- The downstream value is the parsed JSON object from the API response.
**Typical Use Cases:**
- Poll external APIs (weather, status, data, etc)
- Connect to local/internal REST endpoints
- Build data pipelines with API triggers
**Input & UI Behavior:**
- If an upstream node is connected, its output value will override the Request URL.
- All config is handled in the right sidebar (Node Properties).
**Error Handling:**
- If the fetch fails, the node displays the error in the UI.
- Only 2xx status codes are considered successful.
**Security Note:**
- Use Proxy mode for APIs requiring CORS bypass or additional privacy.
`.trim()},Ea=Object.freeze(Object.defineProperty({__proto__:null,default:Pa},Symbol.toStringTag,{value:"Module"})),Ma=({id:n,data:t})=>{const{setNodes:o}=dt();mt(l=>l.edges);const a=(t==null?void 0:t.lines)||[],[d,u]=s.useState(a),r=s.useRef(a),i=s.useRef(null),c=l=>{const h=l.target.files&&l.target.files[0];h&&h.text().then(f=>{const y=f.split(/\r\n|\n/);r.current=y,u(y),window.BorealisValueBus[n]=y,o(C=>C.map(I=>I.id===n?{...I,data:{...I.data,lines:y}}:I))})},p=()=>{var l;(l=i.current)==null||l.click()};return s.useEffect(()=>{let l=window.BorealisUpdateRate;const h=setInterval(()=>{window.BorealisValueBus[n]=r.current},l),f=setInterval(()=>{window.BorealisUpdateRate!==l&&(clearInterval(h),clearInterval(f))},250);return()=>{clearInterval(h),clearInterval(f)}},[n]),e.jsxs("div",{className:"borealis-node",children:[e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Upload Text File"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"8px",fontSize:"9px",color:"#ccc"},children:(t==null?void 0:t.content)||"Upload a text-based file, output a multi-line string array."}),e.jsx("button",{onClick:p,style:{width:"100%",padding:"6px",fontSize:"9px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",cursor:"pointer"},children:"Select File..."}),e.jsx("input",{type:"file",accept:".txt,.log,.ini,text/*",style:{display:"none"},ref:i,onChange:c})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Da={type:"Upload_Text_File",label:"Upload Text File",description:"A node to upload a text file (TXT/LOG/INI/ETC) and store it as a multi-line text array.",content:"Upload a text-based file, output a multi-line string array.",component:Ma},za=Object.freeze(Object.defineProperty({__proto__:null,default:Da},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Fa=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(l=>l.edges),[d,u]=s.useState(typeof(t==null?void 0:t.enabled)=="boolean"?t.enabled:(t==null?void 0:t.enabled)==="false"?!1:(t==null?void 0:t.enabled)==="true"?!0:(t==null?void 0:t.enabled)!==void 0?!!t.enabled:!0),[r,i]=s.useState(typeof(t==null?void 0:t.value)<"u"?t.value:void 0),c=s.useRef(r);s.useEffect(()=>{o(l=>l.map(h=>h.id===n?{...h,data:{...h.data,enabled:d}}:h))},[d,n,o]),s.useEffect(()=>{typeof(t==null?void 0:t.value)<"u"&&(window.BorealisValueBus[n]=t.value,i(t.value),c.current=t.value)},[n,t==null?void 0:t.value]),s.useEffect(()=>{let l=null,h=window.BorealisUpdateRate||100;const f=()=>{const C=a.find(k=>k.target===n),I=!!(C&&C.source);if(d&&I){const k=window.BorealisValueBus[C.source];k!==c.current&&(c.current=k,i(k),window.BorealisValueBus[n]=k,o(v=>v.map(j=>j.id===n?{...j,data:{...j.data,value:k}}:j)))}else d||c.current!==0&&(c.current=0,i(0),window.BorealisValueBus[n]=0,o(k=>k.map(v=>v.id===n?{...v,data:{...v.data,value:0}}:v)))};l=setInterval(f,h);const y=setInterval(()=>{const C=window.BorealisUpdateRate;C!==h&&(clearInterval(l),h=C,l=setInterval(f,h))},250);return()=>{clearInterval(l),clearInterval(y)}},[n,a,d,o]);const p=a.find(l=>l.target===n);return p&&p.source,e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Edge Toggle"}),e.jsx("div",{className:"borealis-node-content",children:e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsx(st,{title:d?"Turn Off / Send Zero":"Turn On / Allow Data",arrow:!0,children:e.jsx(co,{checked:d,size:"small",onChange:()=>u(l=>!l),sx:{"& .MuiSwitch-switchBase.Mui-checked":{color:"#58a6ff"},"& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track":{backgroundColor:"#58a6ff"}}})}),e.jsx("span",{style:{fontSize:9,color:d?"#00d18c":"#ff4f4f",fontWeight:"bold",marginLeft:4,userSelect:"none"},children:d?"Flow Enabled":"Flow Disabled"})]})}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},La={type:"Edge_Toggle",label:"Edge Toggle",description:`
Toggles edge data flow ON/OFF using a switch.
- When enabled, passes upstream value to downstream.
- When disabled, sends zero (0) so downstream always sees a cleared value.
- Use to quickly enable/disable parts of your workflow without unlinking edges.
`.trim(),content:"Toggle ON/OFF to allow or send zero downstream",component:Fa,config:[{key:"enabled",label:"Toggle Enabled",type:"select",options:["true","false"],defaultValue:"true"}],usage_documentation:`
### Edge Toggle Node
**Purpose:**
Allows you to control data flow along a workflow edge without disconnecting the wire.
**Behavior:**
- When **Enabled**: passes upstream value downstream as usual.
- When **Disabled**: pushes \`0\` (zero) so that downstream logic always sees a cleared value (acts as an instant "mute" switch).
**Persistence:**
- Toggle state is saved in the workflow and restored on load/import.
**Tips:**
- Use for debug toggling, feature gating, or for rapid workflow prototyping.
---
`.trim()},$a=Object.freeze(Object.defineProperty({__proto__:null,default:La},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Ua=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(i=>i.edges),[d,u]=s.useState((t==null?void 0:t.value)||""),r=s.useRef(d);return s.useEffect(()=>{r.current=(t==null?void 0:t.value)||"",u(r.current),window.BorealisValueBus[n]=r.current},[t==null?void 0:t.value,n]),s.useEffect(()=>{let i=window.BorealisUpdateRate||100,c=null;const p=()=>{const h=a.find(y=>(y==null?void 0:y.target)===n);if(!!(h!=null&&h.source)){const y=window.BorealisValueBus[h.source]??"";y!==r.current&&(r.current=y,u(y),window.BorealisValueBus[n]=y,o(C=>C.map(I=>I.id===n?{...I,data:{...I.data,value:y}}:I)))}else window.BorealisValueBus[n]=r.current};c=setInterval(p,i);const l=setInterval(()=>{const h=window.BorealisUpdateRate||100;h!==i&&(clearInterval(c),i=h,c=setInterval(p,i))},250);return()=>{clearInterval(c),clearInterval(l)}},[n,o,a]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:e.jsx("span",{children:(t==null?void 0:t.label)||"Data Node"})}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",color:"#ccc",marginTop:4},children:["Value: ",d]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Wa={type:"DataNode",label:"String / Number",description:`Foundational node for live value propagation.
- Accepts input or manual value
- Pushes downstream
- Uses shared memory`,content:"Store a String or Number",component:Ua,config:[{key:"value",label:"Value",type:"text"}],usage_documentation:`
### Description:
This node acts as a basic live data emitter. When connected to an upstream node, it inherits its value, otherwise it accepts user-defined input of either a number or a string.
**Acceptable Inputs**:
- **Static Value** (*Number or String*)
**Behavior**:
- **Pass-through Conduit** (*If Upstream Node is Connected*) > Value cannot be manually changed while connected to an upstream node.
- Uses global Borealis "**Update Rate**" for updating value if connected to an upstream node.
`.trim()},Va=Object.freeze(Object.defineProperty({__proto__:null,default:Wa},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Ha=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(i=>i.edges),[d,u]=s.useState("0"),r=s.useRef("0");return s.useEffect(()=>{let i=window.BorealisUpdateRate,c=null;const p=()=>{let h=(t==null?void 0:t.inputType)||"Number",f=(t==null?void 0:t.operator)||"Equal (==)",y=t==null?void 0:t.rangeStart,C=t==null?void 0:t.rangeEnd;h==="String"&&!["Equal (==)","Not Equal (!=)"].includes(f)&&(f="Equal (==)",o(x=>x.map(S=>S.id===n?{...S,data:{...S.data,operator:f}}:S)));const I=a.filter(x=>(x==null?void 0:x.target)===n&&x.targetHandle==="a"),k=a.filter(x=>(x==null?void 0:x.target)===n&&x.targetHandle==="b"),v=x=>{const S=x.map(z=>window.BorealisValueBus[z.source]).filter(z=>z!==void 0);return h==="Number"?S.reduce((z,E)=>z+(parseFloat(E)||0),0):S.join("")},j=v(I),B=v(k);let R="0";if(f==="Within Range"){const x=parseFloat(j),S=parseFloat(y),z=parseFloat(C);!isNaN(x)&&!isNaN(S)&&!isNaN(z)&&S<=z?R=x>=S&&x<=z?"1":"0":R="0"}else R={"Equal (==)":j===B,"Not Equal (!=)":j!==B,"Greater Than (>)":j>B,"Less Than (<)":j<B,"Greater Than or Equal (>=)":j>=B,"Less Than or Equal (<=)":j<=B}[f]?"1":"0";r.current=R,u(R),window.BorealisValueBus[n]=R,o(x=>x.map(S=>S.id===n?{...S,data:{...S.data,value:R}}:S))};c=setInterval(p,i);const l=setInterval(()=>{const h=window.BorealisUpdateRate;h!==i&&(clearInterval(c),i=h,c=setInterval(p,i))},250);return()=>{clearInterval(c),clearInterval(l)}},[n,a,t==null?void 0:t.inputType,t==null?void 0:t.operator,t==null?void 0:t.rangeStart,t==null?void 0:t.rangeEnd,o]),e.jsxs("div",{className:"borealis-node",children:[e.jsx("div",{style:{position:"absolute",left:-16,top:12,fontSize:"8px",color:"#ccc"},children:"A"}),e.jsx("div",{style:{position:"absolute",left:-16,top:50,fontSize:"8px",color:"#ccc"},children:"B"}),e.jsx(De,{type:"target",position:ze.Left,id:"a",style:{top:12},className:"borealis-handle"}),e.jsx(De,{type:"target",position:ze.Left,id:"b",style:{top:50},className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:e.jsx("span",{children:(t==null?void 0:t.label)||"Logic Comparison"})}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",color:"#ccc",marginTop:4},children:["Result: ",d]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Ga={type:"ComparisonNode",label:"Logic Comparison",description:"Compare A vs B using logic operators, with range support.",content:"Compare A and B using Logic, with new range operator.",component:Ha,config:[{key:"inputType",label:"Input Type",type:"select",options:["Number","String"]},{key:"operator",label:"Operator",type:"select",options:["Equal (==)","Not Equal (!=)","Greater Than (>)","Less Than (<)","Greater Than or Equal (>=)","Less Than or Equal (<=)","Within Range"]},{key:"rangeStart",label:"Range Start",type:"text"},{key:"rangeEnd",label:"Range End",type:"text"}],usage_documentation:`
### Logic Comparison Node
This node compares two inputs (A and B) using the selected operator, including a numeric range.
**Modes:**
- **Number**: Sums all connected inputs and compares.
- **String**: Concatenates all inputs for comparison.
- Only **Equal (==)** and **Not Equal (!=)** are valid for strings.
- **Within Range**: If operator is "Within Range", compares if input A is within [Range Start, Range End] (inclusive).
**Output:**
- Returns \`1\` if comparison is true.
- Returns \`0\` if comparison is false.
**Input Notes:**
- A and B can each have multiple inputs.
- Input order matters for strings (concatenation).
- Input handles:
- **A** = Top left
- **B** = Middle left
**"Within Range" Operator:**
- Only works for **Number** input type.
- Enter "Range Start" and "Range End" in the right sidebar.
- The result is \`1\` if A >= Range Start AND A <= Range End (inclusive).
- Result is \`0\` if out of range or values are invalid.
**Example:**
- Range Start: 33
- Range End: 77
- A: 44 -> 1 (true, in range)
- A: 88 -> 0 (false, out of range)
`.trim()},qa=Object.freeze(Object.defineProperty({__proto__:null,default:Ga},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Ja=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(i=>i.edges),[d,u]=s.useState((t==null?void 0:t.value)||"0"),r=s.useRef(d);return s.useEffect(()=>{let i=null,c=window.BorealisUpdateRate;const p=()=>{const h=(t==null?void 0:t.operator)||"Add",f=a.filter(j=>j.target===n&&j.targetHandle==="a"),y=a.filter(j=>j.target===n&&j.targetHandle==="b"),C=j=>j.map(B=>parseFloat(window.BorealisValueBus[B.source])||0).reduce((B,R)=>B+R,0),I=C(f),k=C(y);let v=0;switch(h){case"Add":v=I+k;break;case"Subtract":v=I-k;break;case"Multiply":v=I*k;break;case"Divide":v=k!==0?I/k:0;break;case"Average":const j=f.length+y.length,B=I+k;v=j>0?B/j:0;break}r.current=v,u(v.toString()),window.BorealisValueBus[n]=v.toString(),o(j=>j.map(B=>B.id===n?{...B,data:{...B.data,value:v.toString()}}:B))};i=setInterval(p,c);const l=setInterval(()=>{const h=window.BorealisUpdateRate;h!==c&&(clearInterval(i),c=h,i=setInterval(p,c))},250);return()=>{clearInterval(i),clearInterval(l)}},[n,a,o,t==null?void 0:t.operator]),e.jsxs("div",{className:"borealis-node",children:[e.jsx("div",{style:{position:"absolute",left:-16,top:12,fontSize:"8px",color:"#ccc"},children:"A"}),e.jsx("div",{style:{position:"absolute",left:-16,top:50,fontSize:"8px",color:"#ccc"},children:"B"}),e.jsx(De,{type:"target",position:ze.Left,id:"a",style:{top:12},className:"borealis-handle"}),e.jsx(De,{type:"target",position:ze.Left,id:"b",style:{top:50},className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:e.jsx("span",{children:(t==null?void 0:t.label)||"Math Operation"})}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px",color:"#ccc",marginTop:4},children:["Result: ",d]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Ya={type:"MathNode",label:"Math Operation",description:`
Live math node for computing on two grouped inputs.
- Sums all A and B handle inputs separately
- Performs selected math operation: Add, Subtract, Multiply, Divide, Average
- Emits result as string via BorealisValueBus
- Updates at the global update rate
**Common Uses:**
Live dashboard math, sensor fusion, calculation chains, dynamic thresholds
`.trim(),content:"Perform Math Operations",component:Ja,config:[{key:"operator",label:"Operator",type:"select",options:["Add","Subtract","Multiply","Divide","Average"]}],usage_documentation:`
### Math Operation Node
Performs live math between two groups of inputs (**A** and **B**).
#### Usage
- Connect any number of nodes to the **A** and **B** input handles.
- The node **sums all values** from A and from B before applying the operator.
- Select the math operator in the sidebar config:
- **Add**: A + B
- **Subtract**: A - B
- **Multiply**: A * B
- **Divide**: A / B (0 if B=0)
- **Average**: (A + B) / total number of inputs
#### Output
- The computed result is pushed as a string to downstream nodes every update tick.
#### Input Handles
- **A** (Top Left)
- **B** (Middle Left)
#### Example
If three nodes outputting 5, 10, 15 are connected to A,
and one node outputs 2 is connected to B,
and operator is Multiply:
- **A** = 5 + 10 + 15 = 30
- **B** = 2
- **Result** = 30 * 2 = 60
`.trim()},Ka=Object.freeze(Object.defineProperty({__proto__:null,default:Ya},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const Xa=({id:n})=>{const t=mt(c=>c.edges),[o,a]=s.useState(100),d=s.useRef(""),[u,r]=s.useState(""),i=(c,p)=>new Promise(l=>{const h=new Image;h.crossOrigin="anonymous",h.onload=()=>{const f=document.createElement("canvas");f.width=h.width,f.height=h.height;const y=f.getContext("2d");y.drawImage(h,0,0);const C=y.getImageData(0,0,f.width,f.height),I=C.data,k=259*(p+255)/(255*(259-p));for(let v=0;v<I.length;v+=4)I[v]=k*(I[v]-128)+128,I[v+1]=k*(I[v+1]-128)+128,I[v+2]=k*(I[v+2]-128)+128;y.putImageData(C,0,0),l(f.toDataURL("image/png").replace(/^data:image\/png;base64,/,""))},h.onerror=()=>l(c),h.src=`data:image/png;base64,${c}`});return s.useEffect(()=>{const c=t.find(l=>l.target===n);if(!(c!=null&&c.source))return;const p=window.BorealisValueBus[c.source]??"";p&&i(p,o).then(l=>{r(l),window.BorealisValueBus[n]=l})},[o,t,n]),s.useEffect(()=>{let c=null;return c=setInterval(async()=>{const l=t.find(f=>f.target===n),h=l?window.BorealisValueBus[l.source]:"";if(h&&h!==d.current){const f=await i(h,o);d.current=h,r(f),window.BorealisValueBus[n]=f}},window.BorealisUpdateRate),()=>clearInterval(c)},[n,o,t]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"Adjust Contrast"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:[e.jsx("label",{children:"Contrast (1255):"}),e.jsx("input",{type:"number",min:"1",max:"255",value:o,onChange:c=>a(parseInt(c.target.value)||100),style:{width:"100%",fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",marginTop:"4px"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},Qa={type:"ContrastNode",label:"Adjust Contrast",description:"Modify contrast of base64 image using a contrast multiplier.",content:"Adjusts contrast of image using canvas pixel transform.",component:Xa},Za=Object.freeze(Object.defineProperty({__proto__:null,default:Qa},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const ei=({id:n,data:t})=>{const o=mt(f=>f.edges),a=parseInt(t==null?void 0:t.value,10),[d,u]=s.useState(isNaN(a)?128:a),[r,i]=s.useState(""),c=s.useRef(""),p=s.useRef("");s.useEffect(()=>{const f=parseInt(t==null?void 0:t.value,10);isNaN(f)||u(f)},[t==null?void 0:t.value]);const l=f=>{let y=parseInt(f.target.value,10);isNaN(y)&&(y=128),y=Math.max(0,Math.min(255,y)),t.value=y,u(y),window.BorealisValueBus[n]=y},h=async(f,y)=>!f||typeof f!="string"?"":new Promise(C=>{const I=new Image;I.crossOrigin="anonymous",I.onload=()=>{const k=document.createElement("canvas");k.width=I.width,k.height=I.height;const v=k.getContext("2d");v.drawImage(I,0,0);const j=v.getImageData(0,0,k.width,k.height),B=j.data;for(let R=0;R<B.length;R+=4){const S=(B[R]+B[R+1]+B[R+2])/3<y?0:255;B[R]=S,B[R+1]=S,B[R+2]=S}v.putImageData(j,0,0),C(k.toDataURL("image/png").replace(/^data:image\/png;base64,/,""))},I.onerror=()=>C(f),I.src="data:image/png;base64,"+f});return s.useEffect(()=>{let f=window.BorealisUpdateRate,y=null;const C=async()=>{const k=o.find(v=>v.target===n);if(k!=null&&k.source){const v=window.BorealisValueBus[k.source]??"";if(v!==p.current){const j=await h(v,d);p.current=v,c.current=j,i(j),window.BorealisValueBus[n]=j}}else p.current="",c.current="",i(""),window.BorealisValueBus[n]=""};y=setInterval(C,f);const I=setInterval(()=>{const k=window.BorealisUpdateRate;k!==f&&(clearInterval(y),f=k,y=setInterval(C,f))},250);return()=>{clearInterval(y),clearInterval(I)}},[n,o,d]),s.useEffect(()=>{const f=o.find(C=>C.target===n);if(!(f!=null&&f.source))return;const y=window.BorealisValueBus[f.source]??"";y&&h(y,d).then(C=>{c.current=C,i(C),window.BorealisValueBus[n]=C})},[d,o,n]),e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"BW Threshold"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:[e.jsx("div",{style:{marginBottom:"6px",color:"#ccc"},children:"Threshold Strength (0255):"}),e.jsx("input",{type:"number",min:"0",max:"255",value:d,onChange:l,style:{width:"100%",fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",marginBottom:"6px"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},ti={type:"BWThresholdNode",label:"BW Threshold",description:`
Black & White Threshold (Stateless)
- Converts a base64 image to black & white using a user-defined threshold value
- Reapplies threshold when the number changes, even if image stays the same
- Outputs a new base64 PNG with BW transformation
`.trim(),content:"Applies black & white threshold to base64 image input.",component:ei},si=Object.freeze(Object.defineProperty({__proto__:null,default:ti},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const ni=({id:n})=>{const t=mt(p=>p.edges),[o,a]=s.useState(100),[d,u]=s.useState(""),r=s.useRef(""),i=(p,l)=>new Promise(h=>{const f=new Image;f.crossOrigin="anonymous",f.onload=()=>{const y=document.createElement("canvas");y.width=f.width,y.height=f.height;const C=y.getContext("2d");C.drawImage(f,0,0);const I=C.getImageData(0,0,y.width,y.height),k=I.data,v=l/100;for(let j=0;j<k.length;j+=4){const B=k[j],R=k[j+1],x=k[j+2],S=(B+R+x)/3;k[j]=B*(1-v)+S*v,k[j+1]=R*(1-v)+S*v,k[j+2]=x*(1-v)+S*v}C.putImageData(I,0,0),h(y.toDataURL("image/png").replace(/^data:image\/png;base64,/,""))},f.onerror=()=>h(p),f.src=`data:image/png;base64,${p}`});s.useEffect(()=>{const p=t.find(h=>h.target===n);if(!(p!=null&&p.source))return;const l=window.BorealisValueBus[p.source]??"";l&&i(l,o).then(h=>{r.current=l,u(h),window.BorealisValueBus[n]=h})},[o,t,n]),s.useEffect(()=>{let p=null;return p=setInterval(async()=>{const h=t.find(y=>y.target===n),f=h?window.BorealisValueBus[h.source]:"";if(f&&f!==r.current){const y=await i(f,o);r.current=f,u(y),window.BorealisValueBus[n]=y}},window.BorealisUpdateRate),()=>clearInterval(p)},[n,t,o]);const c=p=>{let l=parseInt(p.target.value,10);isNaN(l)&&(l=100),l=Math.min(100,Math.max(0,l)),a(l)};return e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"Convert to Grayscale"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:[e.jsx("label",{style:{display:"block",marginBottom:"4px"},children:"Grayscale Intensity (0100):"}),e.jsx("input",{type:"number",min:"0",max:"100",step:"1",value:o,onChange:c,style:{width:"100%",fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},oi={type:"GrayscaleNode",label:"Convert to Grayscale",description:`
Adjustable Grayscale Conversion
- Accepts base64 image input
- Applies grayscale effect using a % level
- 0% = no change, 100% = full grayscale
- Outputs result downstream as base64
`.trim(),content:"Convert image to grayscale with adjustable intensity.",component:ni},ri=Object.freeze(Object.defineProperty({__proto__:null,default:oi},Symbol.toStringTag,{value:"Module"})),ai=({id:n})=>{const{getEdges:t}=dt(),[o,a]=s.useState("");s.useEffect(()=>{const u=setInterval(()=>{var c;const i=t().find(p=>p.target===n);if(i){const p=(c=window.BorealisValueBus)==null?void 0:c[i.source];typeof p=="string"&&a(p)}},1e3);return()=>clearInterval(u)},[n,t]);const d=async()=>{const u=await(async()=>await(await fetch(`data:image/png;base64,${o}`)).blob())();if(window.showSaveFilePicker)try{const i=await(await window.showSaveFilePicker({suggestedName:"image.png",types:[{description:"PNG Image",accept:{"image/png":[".png"]}}]})).createWritable();await i.write(u),await i.close()}catch(r){console.warn("Save cancelled:",r)}else{const r=document.createElement("a");r.href=URL.createObjectURL(u),r.download="image.png",r.style.display="none",document.body.appendChild(r),r.click(),URL.revokeObjectURL(r.href),document.body.removeChild(r)}};return e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"Export Image"}),e.jsxs("div",{className:"borealis-node-content",style:{fontSize:"9px"},children:["Export upstream base64-encoded image data as a PNG on-disk.",e.jsx("button",{style:{marginTop:"6px",width:"100%",fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px"},onClick:d,disabled:!o,children:"Download PNG"})]})]})},ii={type:"ExportImageNode",label:"Export Image",description:"Lets the user download the base64 PNG image to disk.",content:"Save base64 PNG to disk as a file.",component:ai},li=Object.freeze(Object.defineProperty({__proto__:null,default:ii},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const ci=({id:n})=>{const{getEdges:t}=dt(),[o,a]=s.useState(""),d=s.useRef(null),u=s.useRef(null),[r,i]=s.useState(!1);s.useEffect(()=>{const p=setInterval(()=>{const h=t().find(f=>f.target===n);if(h){const f=window.BorealisValueBus[h.source]||"";a(f),window.BorealisValueBus[n]=f}else a(""),window.BorealisValueBus[n]=""},window.BorealisUpdateRate);return()=>clearInterval(p)},[t,n]),s.useEffect(()=>{const p=d.current;if(!p)return;const l=p.getContext("2d");if(o){const h=new Image;h.onload=()=>{p.width=h.width,p.height=h.height,l.clearRect(0,0,p.width,p.height),l.drawImage(h,0,0)},h.src="data:image/png;base64,"+o}else l.clearRect(0,0,p.width,p.height)},[o]),s.useEffect(()=>{if(!r||!o)return;const p=document.createElement("div");u.current=p,Object.assign(p.style,{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",backgroundColor:"rgba(0,0,0,0.8)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"1000",cursor:"zoom-out",transition:"opacity 0.3s ease"});const l=()=>i(!1);p.addEventListener("click",l);const h=document.createElement("canvas"),f=h.getContext("2d"),y=new Image;return y.onload=()=>{let C=y.width,I=y.height;const k=window.innerWidth*.8,v=window.innerHeight*.8,j=Math.min(1,k/C,v/I);h.width=C,h.height=I,f.clearRect(0,0,C,I),f.drawImage(y,0,0),h.style.width=`${C*j}px`,h.style.height=`${I*j}px`,h.style.transition="transform 0.3s ease"},y.src="data:image/png;base64,"+o,p.appendChild(h),document.body.appendChild(p),()=>{p.removeEventListener("click",l),u.current&&(document.body.removeChild(u.current),u.current=null)}},[r,o]);const c=()=>{o&&i(p=>!p)};return e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:"Image Viewer"}),e.jsx("div",{className:"borealis-node-content",style:{cursor:o?"zoom-in":"default"},children:o?e.jsx("canvas",{ref:d,onClick:c,style:{width:"100%",border:"1px solid #333",marginTop:"6px",marginBottom:"6px"}}):e.jsx("div",{style:{fontSize:"9px",color:"#888",marginTop:"6px"},children:"Waiting for image..."})}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},di={type:"Image_Viewer",label:"Image Viewer",description:`
Displays base64 image via canvas for high performance
- Accepts upstream base64 image
- Renders with canvas for speed
- Click to zoom/unzoom overlay with smooth transition
`.trim(),content:"Visual preview of base64 image with zoom overlay.",component:ci},ui=Object.freeze(Object.defineProperty({__proto__:null,default:di},Symbol.toStringTag,{value:"Module"}));window.BorealisValueBus||(window.BorealisValueBus={});window.BorealisUpdateRate||(window.BorealisUpdateRate=100);const pi=({id:n,data:t})=>{const{setNodes:o}=dt(),[a,d]=s.useState((t==null?void 0:t.value)||""),u=s.useRef(a),r=i=>{console.log("handleFileUpload triggered for node:",n);const c=i.target.files||i.currentTarget.files;if(!c||c.length===0){console.log("No files selected or files array is empty");return}const p=c[0];if(!p){console.log("File object not found");return}if(console.log("Selected file:",p.name,p.type,p.size),!["image/jpeg","image/png"].includes(p.type)){console.warn("Unsupported file type in node:",n,p.type);return}const h=new FileReader;h.onload=f=>{var I;console.log("FileReader onload in node:",n);const C=(((I=f==null?void 0:f.target)==null?void 0:I.result)||"").replace(/^data:image\/[a-zA-Z]+;base64,/,"");console.log("Raw Base64 (truncated):",C.substring(0,50)),u.current=C,d(C),window.BorealisValueBus[n]=C,o(k=>k.map(v=>v.id===n?{...v,data:{...v.data,value:C}}:v))},h.onerror=f=>{console.error("FileReader error in node:",n,f)},h.readAsDataURL(p)};return s.useEffect(()=>{let i=window.BorealisUpdateRate||100,c=null;const p=()=>{window.BorealisValueBus[n]=u.current},l=()=>{c=setInterval(p,i)};l();const h=setInterval(()=>{const f=window.BorealisUpdateRate||100;f!==i&&(i=f,clearInterval(c),l())},250);return()=>{clearInterval(c),clearInterval(h)}},[n,o]),e.jsxs("div",{className:"borealis-node",style:{minWidth:"160px"},children:[e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Raw Base64 Image Upload"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"8px",fontSize:"9px",color:"#ccc"},children:(t==null?void 0:t.content)||"Upload a JPG/PNG, store only the raw base64 in ValueBus."}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginBottom:"4px"},children:"Upload Image File"}),e.jsx("input",{type:"file",accept:".jpg,.jpeg,.png",onChange:r,style:{fontSize:"9px",padding:"4px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",width:"100%",marginBottom:"8px"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},fi={type:"ImageUploadNode_RawBase64",label:"Upload Image",description:`
A node to upload an image (JPG/PNG) and store it in base64 format for later use downstream.
`.trim(),content:"Upload an image, output only the raw base64 string.",component:pi},hi=Object.freeze(Object.defineProperty({__proto__:null,default:fi},Symbol.toStringTag,{value:"Module"})),mi=({id:n,data:t})=>{const[o,a]=s.useState((t==null?void 0:t.label)||"Backdrop Group Box"),[d,u]=s.useState(!1),r=s.useRef(null);s.useEffect(()=>{d&&r.current&&r.current.focus()},[d]);const i=l=>{l.stopPropagation(),u(!0)},c=l=>{const h=l.target.value;a(h),window.BorealisValueBus[n]=h},p=()=>{u(!1)};return e.jsx("div",{style:{pointerEvents:"auto"},children:e.jsxs(Hr,{width:200,height:120,minConstraints:[120,80],maxConstraints:[600,600],resizeHandles:["se"],className:"borealis-node",handle:l=>e.jsx("span",{className:`react-resizable-handle react-resizable-handle-${l}`,style:{pointerEvents:"auto"},onMouseDown:h=>h.stopPropagation(),onClick:h=>h.stopPropagation()}),onClick:l=>l.stopPropagation(),style:{backgroundColor:"rgba(44, 44, 44, 0.5)",border:"1px solid #3a3a3a",borderRadius:"4px",boxShadow:"0 0 5px rgba(88, 166, 255, 0.15)",overflow:"hidden",position:"relative",zIndex:0},children:[e.jsx("div",{onClick:i,style:{backgroundColor:"rgba(35, 35, 35, 0.5)",padding:"6px 10px",fontWeight:"bold",fontSize:"10px",cursor:"pointer",userSelect:"none"},children:d?e.jsx("input",{ref:r,type:"text",value:o,onChange:c,onBlur:p,onClick:l=>l.stopPropagation(),onMouseDown:l=>l.stopPropagation(),style:{fontSize:"10px",padding:"2px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",width:"100%"}}):e.jsx("span",{children:o})}),e.jsx("div",{style:{padding:"10px",fontSize:"9px",height:"100%"}})]})})},xi={type:"BackdropGroupBoxNode",label:"Backdrop Group Box",description:`
Resizable Grouping Node
- Purely cosmetic, for grouping related nodes
- Resizable by dragging bottom-right corner
- Rename by clicking on title bar
`.trim(),content:"Use as a visual group label",component:mi},gi=Object.freeze(Object.defineProperty({__proto__:null,default:xi},Symbol.toStringTag,{value:"Module"})),bi=({data:n})=>{const[t,o]=s.useState(""),[a,d]=s.useState(!1),[u,r]=s.useState(!1),i=s.useRef(null),c=()=>r(!0),p=()=>r(!1),l=async()=>{var f;if(window.showDirectoryPicker)try{const y=await window.showDirectoryPicker();o(y.name||"Selected Directory")}catch(y){console.warn("Directory Selection Cancelled:",y)}else(f=i.current)==null||f.click()},h=f=>{var C;const y=f.target.files;if(y.length>0){const I=(C=y[0].webkitRelativePath)==null?void 0:C.split("/")[0];o(I||"Selected Folder")}};return e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:n.label}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"8px"},children:n.content}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginTop:"6px"},children:"Export Path:"}),e.jsxs("div",{style:{display:"flex",gap:"4px",alignItems:"center",marginBottom:"6px"},children:[e.jsx("input",{type:"text",readOnly:!0,value:t,placeholder:"Click to Select Folder",onClick:l,style:{flex:1,fontSize:"9px",padding:"3px",background:"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",cursor:"pointer"}}),e.jsx(Z,{variant:"outlined",size:"small",onClick:c,sx:{fontSize:"9px",padding:"2px 8px",minWidth:"unset",borderColor:"#58a6ff",color:"#58a6ff"},children:"Export"})]}),e.jsxs("label",{style:{fontSize:"9px",display:"block",marginTop:"4px"},children:[e.jsx("input",{type:"checkbox",checked:a,onChange:f=>d(f.target.checked),style:{marginRight:"4px"}}),"Append CSV Data if Headers Match"]})]}),e.jsx("input",{ref:i,type:"file",webkitdirectory:"true",directory:"",multiple:!0,style:{display:"none"},onChange:h}),e.jsx(Fo,{open:u,autoHideDuration:1e3,onClose:p,message:"Feature Coming Soon...",anchorOrigin:{vertical:"bottom",horizontal:"center"}})]})},yi={type:"ExportToCSVNode",label:"Export to CSV",description:`
Reporting Node
This node lets the user choose a folder to export CSV data to disk.
When the "Export" button is clicked, CSV content (from upstream logic) is intended to be saved
to the selected directory. This is a placeholder for future file system interaction.
Inputs:
- Structured Table Data (via upstream node)
Outputs:
- None (writes directly to disk in future)
`.trim(),content:"Export Input Data to CSV File",component:bi},ji=Object.freeze(Object.defineProperty({__proto__:null,default:yi},Symbol.toStringTag,{value:"Module"})),wi=({id:n,data:t})=>{const{setNodes:o}=dt(),a=mt(l=>l.edges),[d,u]=s.useState((t==null?void 0:t.value)||"/Data/Server/WebUI/src/Nodes/Templates/Node_Template.jsx"),r=s.useRef(d),i=l=>{const h=l.target.value;r.current=h,u(h),window.BorealisValueBus[n]=h,o(f=>f.map(y=>y.id===n?{...y,data:{...y.data,value:h}}:y))};s.useEffect(()=>{let l=window.BorealisUpdateRate,h;const f=()=>{const C=a.find(k=>k.target===n);if(!!(C&&C.source)){const k=window.BorealisValueBus[C.source]||"";k!==r.current&&(r.current=k,u(k),window.BorealisValueBus[n]=k,o(v=>v.map(j=>j.id===n?{...j,data:{...j.data,value:k}}:j)))}else window.BorealisValueBus[n]=r.current};h=setInterval(f,l);const y=setInterval(()=>{const C=window.BorealisUpdateRate;C!==l&&(clearInterval(h),l=C,h=setInterval(f,l))},250);return()=>{clearInterval(h),clearInterval(y)}},[n,a,o]);const c=a.find(l=>l.target===n),p=!!(c&&c.source);return e.jsxs("div",{className:"borealis-node",children:[e.jsx(De,{type:"target",position:ze.Left,className:"borealis-handle"}),e.jsx("div",{className:"borealis-node-header",children:(t==null?void 0:t.label)||"Node Template"}),e.jsxs("div",{className:"borealis-node-content",children:[e.jsx("div",{style:{marginBottom:"8px",fontSize:"9px",color:"#ccc"},children:(t==null?void 0:t.content)||"Template acting as a design scaffold for designing nodes for Borealis."}),e.jsx("label",{style:{fontSize:"9px",display:"block",marginBottom:"4px"},children:"Template Location:"}),e.jsx("input",{type:"text",value:d,onChange:i,disabled:p,style:{fontSize:"9px",padding:"4px",background:p?"#2a2a2a":"#1e1e1e",color:"#ccc",border:"1px solid #444",borderRadius:"2px",width:"100%"}})]}),e.jsx(De,{type:"source",position:ze.Right,className:"borealis-handle"})]})},vi={type:"Node_Template",label:"Node Template",description:"Node structure template to be used as a scaffold when building new nodes for Borealis.",content:"Template acting as a design scaffold for designing nodes for Borealis.",component:wi},Si=Object.freeze(Object.defineProperty({__proto__:null,default:vi},Symbol.toStringTag,{value:"Module"}));function Ci({open:n,onClose:t,onConfirm:o}){return e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Close All Flow Tabs?"}),e.jsx(rt,{children:e.jsx($t,{sx:{color:"#ccc"},children:"This will remove all existing flow tabs and create a fresh tab named Flow 1."})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:o,sx:{color:"#ff4f4f"},children:"Close All"})]})]})}function _i({open:n,onClose:t}){return e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Not Authorized"}),e.jsx(rt,{children:e.jsx($t,{sx:{color:"#ccc"},children:"You are not authorized to access this section."})}),e.jsx(tt,{children:e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"OK"})})]})}function ki({open:n,onClose:t}){return e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsxs(rt,{sx:{textAlign:"center",pt:3},children:[e.jsx("img",{src:"/Borealis_Logo.png",alt:"Borealis Logo",style:{width:"120px",marginBottom:"12px"}}),e.jsx(et,{sx:{p:0,mb:1},children:"Borealis - Automation Platform"}),e.jsxs($t,{sx:{color:"#ccc"},children:["Designed by Nicole Rappe @"," ",e.jsx("a",{href:"https://bunny-lab.io",target:"_blank",rel:"noopener noreferrer",style:{color:"#58a6ff",textDecoration:"none"},children:"Bunny Lab"})]})]}),e.jsx(tt,{children:e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"Close"})})]})}function Ii({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Rename Tab"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"Tab Name",fullWidth:!0,variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function Ri({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Rename Workflow"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"Workflow Name",fullWidth:!0,variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function wo({open:n,value:t,onChange:o,onCancel:a,onSave:d,title:u="Folder Name",confirmText:r="Save"}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:u}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"Folder Name",fullWidth:!0,variant:"outlined",value:t,onChange:i=>o(i.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:r})]})]})}function Ni({open:n,value:t,onChange:o,onCancel:a,onCreate:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"New Workflow"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"Workflow Name",fullWidth:!0,variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Create"})]})]})}function Ti({open:n,onCancel:t,onConfirm:o}){return e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Clear Device Activity"}),e.jsx(rt,{children:e.jsx($t,{sx:{color:"#ccc"},children:"All device activity history will be cleared, are you sure?"})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:o,sx:{color:"#ff4f4f"},children:"Clear"})]})]})}function Ai({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Save Workflow"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"Workflow Name",fullWidth:!0,variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function Zt({open:n,message:t,onCancel:o,onConfirm:a}){return e.jsxs(Ze,{open:n,onClose:o,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Confirm Delete"}),e.jsx(rt,{children:e.jsx($t,{sx:{color:"#ccc"},children:t})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:o,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Confirm"})]})]})}function Bi({open:n,onCancel:t,onConfirm:o}){return e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Remove Device"}),e.jsx(rt,{children:e.jsx($t,{sx:{color:"#ccc"},children:"Are you sure you want to remove this device? If the agent is still running, it will automatically re-enroll the device."})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:o,sx:{bgcolor:"#ff4f4f",color:"#fff","&:hover":{bgcolor:"#e04444"}},children:"Remove"})]})]})}function Oi({anchor:n,onClose:t,onRename:o,onCloseTab:a}){return e.jsxs(Et,{open:!!n,onClose:t,anchorReference:"anchorPosition",anchorPosition:n?{top:n.y,left:n.x}:void 0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[e.jsx(fe,{onClick:o,children:"Rename"}),e.jsx(fe,{onClick:a,children:"Close Workflow"})]})}function Pi({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Create a New Custom View"}),e.jsxs(rt,{children:[e.jsx($t,{sx:{color:"#ccc",mb:1},children:"Saving a view will save column order, visibility, and filters."}),e.jsx(Ie,{autoFocus:!0,fullWidth:!0,margin:"dense",label:"View Name",variant:"outlined",value:t,onChange:u=>o(u.target.value),placeholder:"Add a name for this custom view",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function Ei({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Rename Custom View"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,fullWidth:!0,margin:"dense",label:"View Name",variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function Mi({open:n,onCancel:t,onCreate:o}){const[a,d]=es.useState(""),[u,r]=es.useState("");return es.useEffect(()=>{n&&(d(""),r(""))},[n]),e.jsxs(Ze,{open:n,onClose:t,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Create Site"}),e.jsxs(rt,{children:[e.jsx($t,{sx:{color:"#ccc",mb:1},children:"Create a new site and optionally add a description."}),e.jsx(Ie,{autoFocus:!0,fullWidth:!0,margin:"dense",label:"Site Name",variant:"outlined",value:a,onChange:i=>d(i.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}}),e.jsx(Ie,{fullWidth:!0,multiline:!0,minRows:3,margin:"dense",label:"Description",variant:"outlined",value:u,onChange:i=>r(i.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:2}})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:t,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:()=>{const i=(a||"").trim();i&&o&&o(i,u||"")},sx:{color:"#58a6ff"},children:"Create"})]})]})}function Di({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Rename Site"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,fullWidth:!0,margin:"dense",label:"Site Name",variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function zi({currentPage:n,onNavigate:t,isAdmin:o=!1}){const[a,d]=s.useState({sites:!0,devices:!0,automation:!0,filters:!0,access:!0,admin:!0}),u=({icon:r,label:i,pageKey:c,indent:p=0})=>{const l=n===c;return e.jsxs(Ko,{onClick:()=>t(c),sx:{pl:p?4:2,py:1,color:l?"#e6f2ff":"#ccc",position:"relative",background:l?"linear-gradient(90deg, rgba(88,166,255,0.10) 0%, rgba(88,166,255,0.03) 60%, rgba(88,166,255,0.00) 100%)":"transparent",borderTopRightRadius:0,borderBottomRightRadius:0,boxShadow:l?"inset 0 0 0 1px rgba(88,166,255,0.25)":"none",transition:"background 160ms ease, box-shadow 160ms ease, color 160ms ease","&:hover":{background:l?"linear-gradient(90deg, rgba(88,166,255,0.14) 0%, rgba(88,166,255,0.06) 60%, rgba(88,166,255,0.00) 100%)":"#2c2c2c"}},selected:l,children:[e.jsx(m,{sx:{position:"absolute",left:0,top:0,bottom:0,width:l?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,boxShadow:l?"0 0 6px rgba(88,166,255,0.35)":"none",transition:"width 180ms ease, box-shadow 200ms ease"}}),r&&e.jsx(m,{sx:{mr:1,display:"flex",alignItems:"center",color:l?"#7db7ff":"#58a6ff",transition:"color 160ms ease"},children:r}),e.jsx(tn,{primary:i,primaryTypographyProps:{fontSize:"0.75rem",fontWeight:l?600:400}})]})};return e.jsx(m,{sx:{width:260,bgcolor:"#121212",borderRight:"1px solid #333",display:"flex",flexDirection:"column",overflow:"hidden"},children:e.jsxs(m,{sx:{flex:1,overflowY:"auto"},children:[(()=>{const r=n==="sites";return e.jsxs(as,{expanded:a.sites,onChange:(i,c)=>d(p=>({...p,sites:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Sites"})})}),e.jsx(cs,{sx:{p:0,bgcolor:"#232323"},children:e.jsx(u,{icon:e.jsx(Lo,{fontSize:"small"}),label:"All Sites",pageKey:"sites"})})]})})(),(()=>{const r=["devices","ssh_devices","winrm_devices","agent_devices"].includes(n);return e.jsxs(as,{expanded:a.devices,onChange:(i,c)=>d(p=>({...p,devices:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Inventory"})})}),e.jsxs(cs,{sx:{p:0,bgcolor:"#232323"},children:[e.jsx(u,{icon:e.jsx($o,{fontSize:"small"}),label:"Device Approvals",pageKey:"admin_device_approvals"}),e.jsx(u,{icon:e.jsx(uo,{fontSize:"small"}),label:"Enrollment Codes",pageKey:"admin_enrollment_codes",indent:!0}),e.jsx(u,{icon:e.jsx(Ys,{fontSize:"small"}),label:"Devices",pageKey:"devices"}),e.jsx(u,{icon:e.jsx(Ys,{fontSize:"small"}),label:"Agent Devices",pageKey:"agent_devices",indent:!0}),e.jsx(u,{icon:e.jsx(Ys,{fontSize:"small"}),label:"SSH Devices",pageKey:"ssh_devices",indent:!0}),e.jsx(u,{icon:e.jsx(Ys,{fontSize:"small"}),label:"WinRM Devices",pageKey:"winrm_devices",indent:!0})]})]})})(),(()=>{const r=["jobs","assemblies","community"].includes(n);return e.jsxs(as,{expanded:a.automation,onChange:(i,c)=>d(p=>({...p,automation:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Automation"})})}),e.jsxs(cs,{sx:{p:0,bgcolor:"#232323"},children:[e.jsx(u,{icon:e.jsx(Uo,{fontSize:"small"}),label:"Assemblies",pageKey:"assemblies"}),e.jsx(u,{icon:e.jsx(Wo,{fontSize:"small"}),label:"Scheduled Jobs",pageKey:"jobs"}),e.jsx(u,{icon:e.jsx(Vo,{fontSize:"small"}),label:"Community Content",pageKey:"community"})]})]})})(),(()=>{const r=n==="filters"||n==="groups";return e.jsxs(as,{expanded:a.filters,onChange:(i,c)=>d(p=>({...p,filters:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Filters & Groups"})})}),e.jsxs(cs,{sx:{p:0,bgcolor:"#232323"},children:[e.jsx(u,{icon:e.jsx(Ho,{fontSize:"small"}),label:"Filters",pageKey:"filters"}),e.jsx(u,{icon:e.jsx(Go,{fontSize:"small"}),label:"Groups",pageKey:"groups"})]})]})})(),(()=>{if(!o)return null;const r=n==="access_credentials"||n==="access_users"||n==="access_github_token";return e.jsxs(as,{expanded:a.access,onChange:(i,c)=>d(p=>({...p,access:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Access Management"})})}),e.jsxs(cs,{sx:{p:0,bgcolor:"#232323"},children:[e.jsx(u,{icon:e.jsx(qo,{fontSize:"small"}),label:"Credentials",pageKey:"access_credentials"}),e.jsx(u,{icon:e.jsx(po,{fontSize:"small"}),label:"GitHub API Token",pageKey:"access_github_token"}),e.jsx(u,{icon:e.jsx(Jo,{fontSize:"small"}),label:"Users",pageKey:"access_users"})]})]})})(),(()=>{if(!o)return null;const r=n==="server_info"||n==="admin_enrollment_codes"||n==="admin_device_approvals";return e.jsxs(as,{expanded:a.admin,onChange:(i,c)=>d(p=>({...p,admin:c})),square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{position:"relative",background:r?"linear-gradient(90deg, rgba(88,166,255,0.08) 0%, rgba(88,166,255,0.00) 100%)":"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0},"&::before":{content:'""',position:"absolute",left:0,top:0,bottom:0,width:r?3:0,bgcolor:"#58a6ff",borderTopRightRadius:2,borderBottomRightRadius:2,transition:"width 160ms ease"}},children:e.jsx($,{sx:{fontSize:"0.85rem",color:"#58a6ff"},children:e.jsx("b",{children:"Admin Settings"})})}),e.jsx(cs,{sx:{p:0,bgcolor:"#232323"},children:e.jsx(u,{icon:e.jsx(Yo,{fontSize:"small"}),label:"Server Info",pageKey:"server_info"})})]})})()]})})}const Fi=es.memo(zi);function Li({tabs:n,activeTabId:t,onTabChange:o,onAddTab:a,onTabRightClick:d}){const u=(()=>{const i=n.findIndex(c=>c.id===t);return i>=0?i:0})(),r=(i,c)=>{if(c==="__addtab__")a();else{const p=n[c];p&&o(p.id)}};return e.jsx(m,{sx:{display:"flex",alignItems:"center",backgroundColor:"#232323",borderBottom:"1px solid #333",height:"36px"},children:e.jsxs(Us,{value:u,onChange:r,variant:"scrollable",scrollButtons:"auto",textColor:"inherit",TabIndicatorProps:{style:{backgroundColor:"#58a6ff"}},sx:{minHeight:"36px",height:"36px",flexGrow:1},children:[n.map((i,c)=>e.jsx(ps,{label:i.tab_name,value:c,onContextMenu:p=>d(p,i.id),sx:{minHeight:"36px",height:"36px",textTransform:"none",backgroundColor:i.id===t?"#2C2C2C":"transparent",color:"#58a6ff"}},i.id)),e.jsx(st,{title:"Create a New Concurrent Tab",arrow:!0,children:e.jsx(ps,{icon:e.jsx(ts,{}),value:"__addtab__",sx:{minHeight:"36px",height:"36px",color:"#58a6ff",textTransform:"none"}})})]})})}function Vn(n,t=.7){if(!/^#[0-9A-Fa-f]{6}$/.test(n))return n;let o=parseInt(n.slice(1,3),16),a=parseInt(n.slice(3,5),16),d=parseInt(n.slice(5,7),16);return o=Math.round(o*t),a=Math.round(a*t),d=Math.round(d*t),`#${o.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${d.toString(16).padStart(2,"0")}`}function $i({drawerOpen:n,setDrawerOpen:t,title:o,nodeData:a,setNodes:d,selectedNode:u}){var R;const[r,i]=s.useState(0),c=dt().setNodes,p=d||c,l=(x,S)=>i(S),[h,f]=s.useState(!1),[y,C]=s.useState(o||""),[I,k]=s.useState(!1),v=((R=u==null?void 0:u.data)==null?void 0:R.accentColor)||"#58a6ff",j=()=>{const x=(a==null?void 0:a.config)||[],S=a==null?void 0:a.nodeId,z=(E=[])=>E.map(U=>{if(typeof U=="string")return{value:U,label:U,disabled:!1};if(U&&typeof U=="object"){const X=U.value??U.id??U.handle??(typeof U.label=="string"?U.label:""),ue=U.label??U.name??U.title??(typeof X<"u"?String(X):"");return{value:typeof X>"u"?"":String(X),label:typeof ue>"u"?"":String(ue),disabled:!!U.disabled}}return{value:String(U??""),label:String(U??""),disabled:!1}});return x.map((E,U)=>{const X=(a==null?void 0:a[E.key])??"",ue=!!E.readOnly;if(E.type==="select"){let Se=E.options||[];return E.optionsKey&&Array.isArray(a==null?void 0:a[E.optionsKey])?Se=a[E.optionsKey]:E.dynamicOptions&&(a!=null&&a.windowList)&&Array.isArray(a.windowList)&&(Se=a.windowList.map(ce=>({value:String(ce.handle),label:`${ce.title} (${ce.handle})`})).sort((ce,de)=>ce.label.localeCompare(de.label,void 0,{sensitivity:"base"}))),Se=z(Se),E.dynamicOptions&&(!(a!=null&&a.windowList)||!Array.isArray(a.windowList))&&(Se=[]),e.jsxs(m,{sx:{mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",mb:.5},children:E.label||E.key}),e.jsx(Ie,{select:!0,fullWidth:!0,size:"small",value:X,onChange:ce=>{if(ue)return;const de=ce.target.value;S&&(p(me=>me.map(w=>w.id===S?{...w,data:{...w.data,[E.key]:de}}:w)),window.BorealisValueBus[S]=de)},SelectProps:{MenuProps:{PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#ccc",border:"1px solid #58a6ff","& .MuiMenuItem-root":{color:"#ccc",fontSize:"0.85rem","&:hover":{backgroundColor:"#2a2a2a"},"&.Mui-selected":{backgroundColor:"#2c2c2c !important",color:"#58a6ff"},"&.Mui-selected:hover":{backgroundColor:"#2a2a2a !important"}}}}}},sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1e1e1e",color:"#ccc",fontSize:"0.85rem","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#58a6ff"},"&.Mui-focused fieldset":{borderColor:"#58a6ff"}},"& .MuiSelect-select":{backgroundColor:"#1e1e1e"}},children:Se.length===0?e.jsx(fe,{disabled:!0,value:"",children:E.label==="Target Window"?"No windows detected":"No options"}):Se.map((ce,de)=>e.jsx(fe,{value:ce.value,disabled:ce.disabled,children:ce.label},de))})]},U)}return e.jsxs(m,{sx:{mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",mb:.5},children:E.label||E.key}),e.jsx(Ie,{variant:"outlined",size:"small",fullWidth:!0,value:X,disabled:ue,InputProps:{readOnly:ue,sx:{color:"#ccc",backgroundColor:"#1e1e1e","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"},"&.Mui-focused fieldset":{borderColor:"#58a6ff"}}},onChange:Se=>{if(ue)return;const ce=Se.target.value;S&&(p(de=>de.map(me=>me.id===S?{...me,data:{...me.data,[E.key]:ce}}:me)),window.BorealisValueBus[S]=ce)}})]},U)})},B=()=>e.jsx(st,{title:"Override Node Header/Accent Color",children:e.jsx(nt,{size:"small","aria-label":"Override Node Color",onClick:()=>k(!0),sx:{ml:1,border:"1px solid #58a6ff",background:v,color:"#222",width:28,height:28,p:0},children:e.jsx(Xo,{fontSize:"small"})})});return e.jsxs(e.Fragment,{children:[e.jsx(m,{onClick:()=>t(!1),sx:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.3)",opacity:n?1:0,pointerEvents:n?"auto":"none",transition:"opacity 0.6s ease",zIndex:10}}),e.jsxs(m,{sx:{position:"absolute",top:0,right:0,bottom:0,width:400,bgcolor:"#2C2C2C",color:"#ccc",borderLeft:"1px solid #333",padding:0,zIndex:11,overflowY:"auto",transform:n?"translateX(0)":"translateX(100%)",transition:"transform 0.3s ease"},onClick:x=>x.stopPropagation(),children:[e.jsxs(m,{sx:{backgroundColor:"#232323",borderBottom:"1px solid #333"},children:[e.jsx(m,{sx:{padding:"12px 16px"},children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsx($,{variant:"h7",sx:{color:"#0475c2",fontWeight:"bold"},children:"Edit "+(o||"Node")}),e.jsxs(m,{sx:{display:"flex",alignItems:"center"},children:[e.jsx(nt,{size:"small","aria-label":"Rename Node",onClick:()=>{C(o||""),f(!0)},sx:{ml:1,color:"#58a6ff"},children:e.jsx(Fs,{fontSize:"small"})}),B()]})]})}),e.jsxs(Us,{value:r,onChange:l,variant:"fullWidth",textColor:"inherit",TabIndicatorProps:{style:{backgroundColor:"#ccc"}},sx:{borderTop:"1px solid #333",borderBottom:"1px solid #333",minHeight:"36px",height:"36px"},children:[e.jsx(ps,{label:"Config",sx:{color:"#ccc","&.Mui-selected":{color:"#ccc"},minHeight:"36px",height:"36px",textTransform:"none"}}),e.jsx(ps,{label:"Usage Docs",sx:{color:"#ccc","&.Mui-selected":{color:"#ccc"},minHeight:"36px",height:"36px",textTransform:"none"}})]})]}),e.jsxs(m,{sx:{padding:2},children:[r===0&&j(),r===1&&e.jsx(m,{sx:{fontSize:"0.85rem",color:"#aaa"},children:e.jsx(Gr,{children:(a==null?void 0:a.usage_documentation)||"No usage documentation provided for this node.",components:{h3:({node:x,...S})=>e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:1},...S}),p:({node:x,...S})=>e.jsx($,{paragraph:!0,sx:{mb:1.5},...S}),ul:({node:x,...S})=>e.jsx("ul",{style:{marginBottom:"1em",paddingLeft:"1.2em"},...S}),li:({node:x,...S})=>e.jsx("li",{style:{marginBottom:"0.5em"},...S})}})})]})]}),e.jsxs(Ze,{open:h,onClose:()=>f(!1),PaperProps:{sx:{bgcolor:"#232323"}},children:[e.jsx(et,{children:"Rename Node"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,fullWidth:!0,variant:"outlined",label:"Node Title",value:y,onChange:x=>C(x.target.value),sx:{mt:1,bgcolor:"#1e1e1e","& .MuiOutlinedInput-root":{color:"#ccc",backgroundColor:"#1e1e1e","& fieldset":{borderColor:"#444"}},label:{color:"#aaa"}}})}),e.jsxs(tt,{children:[e.jsx(Z,{sx:{color:"#aaa"},onClick:()=>f(!1),children:"Cancel"}),e.jsx(Z,{sx:{color:"#58a6ff"},onClick:()=>{const x=(u==null?void 0:u.id)||(a==null?void 0:a.nodeId);if(!x){f(!1);return}p(S=>S.map(z=>z.id===x?{...z,data:{...z.data,label:y}}:z)),f(!1)},children:"Save"})]})]}),e.jsxs(Ze,{open:I,onClose:()=>k(!1),PaperProps:{sx:{bgcolor:"#232323"}},children:[e.jsx(et,{children:"Pick Node Header/Accent Color"}),e.jsxs(rt,{children:[e.jsx(jo,{color:v,onChangeComplete:x=>{const S=(u==null?void 0:u.id)||(a==null?void 0:a.nodeId);if(!S)return;const z=x.hex,E=Vn(z,.7);p(U=>U.map(X=>X.id===S?{...X,data:{...X.data,accentColor:z},style:{...X.style,"--borealis-accent":z,"--borealis-accent-dark":E,"--borealis-title":z}}:X))},disableAlpha:!0,presetColors:["#58a6ff","#0475c2","#00d18c","#ff4f4f","#ff8c00","#6b21a8","#0e7490","#888","#fff","#000"]}),e.jsxs(m,{sx:{mt:2},children:[e.jsxs($,{variant:"body2",children:["The node's header text and accent gradient will use your selected color.",e.jsx("br",{}),"The accent gradient fades to a slightly darker version."]}),e.jsxs(m,{sx:{mt:2,display:"flex",alignItems:"center"},children:[e.jsx("span",{style:{display:"inline-block",width:48,height:22,borderRadius:4,border:"1px solid #888",background:`linear-gradient(to bottom, ${v} 0%, ${Vn(v,.7)} 100%)`}}),e.jsx("span",{style:{marginLeft:10,color:v,fontWeight:"bold"},children:v})]})]})]}),e.jsx(tt,{children:e.jsx(Z,{onClick:()=>k(!1),sx:{color:"#aaa"},children:"Close"})})]})]})}const Hn=400,Gn={type:"bezier",animated:!0,style:{strokeDasharray:"6 3",stroke:"#58a6ff",strokeWidth:1},label:"",labelStyle:{fill:"#fff",fontWeight:"bold"},labelBgStyle:{fill:"#2c2c2c",fillOpacity:.85,rx:16,ry:16},labelBgPadding:[8,4]};let Qs=null;function Os(n){return JSON.parse(JSON.stringify(n))}function Ui({open:n,onClose:t,edge:o,updateEdge:a}){const[d,u]=s.useState(0),[r,i]=s.useState(()=>o?Os(o):{}),[c,p]=s.useState({field:null,anchor:null});s.useEffect(()=>{o&&o.id!==r.id&&i(Os(o))},[o]);const l=(R,x)=>{i(S=>{const z={...S};return R==="label"?z.label=x:R==="labelStyle.fill"?z.labelStyle={...z.labelStyle,fill:x}:R==="labelBgStyle.fill"?z.labelBgStyle={...z.labelBgStyle,fill:x}:R==="labelBgStyle.rx"?z.labelBgStyle={...z.labelBgStyle,rx:x,ry:x}:R==="labelBgPadding"?z.labelBgPadding=x:R==="labelBgStyle.fillOpacity"?z.labelBgStyle={...z.labelBgStyle,fillOpacity:x}:R==="type"?z.type=x:R==="animated"?z.animated=x:R==="style.stroke"?z.style={...z.style,stroke:x}:R==="style.strokeDasharray"?z.style={...z.style,strokeDasharray:x}:R==="style.strokeWidth"?z.style={...z.style,strokeWidth:x}:R==="labelStyle.fontWeight"?z.labelStyle={...z.labelStyle,fontWeight:x}:z[R]=x,R==="style.strokeDasharray"&&(x===""?(z.animated=!1,z.style={...z.style,strokeDasharray:""}):(z.animated=!0,z.style={...z.style,strokeDasharray:x})),a({...z,id:S.id}),z})},h=(R,x)=>{p({field:R,anchor:x.currentTarget})},f=()=>{p({field:null,anchor:null})},y=R=>{l(c.field,R.hex),f()},C=()=>{i(Os({...Gn,id:o.id})),a({...Gn,id:o.id})},I=()=>{Qs=Os(r)},k=()=>{Qs&&(i(Os({...Qs,id:o.id})),a({...Qs,id:o.id}))},v=(R,x,S)=>e.jsxs("span",{style:{display:"inline-block",verticalAlign:"middle",position:"relative"},children:[e.jsx(Z,{variant:"outlined",size:"small",onClick:z=>h(x,z),sx:{ml:1,borderColor:"#444",color:"#ccc",minWidth:0,width:32,height:24,p:0,bgcolor:"#232323"},children:e.jsx("span",{style:{display:"inline-block",width:20,height:16,background:S,borderRadius:3,border:"1px solid #888"}})}),c.field===x&&e.jsx(m,{sx:{position:"absolute",top:"32px",right:0,zIndex:1302,boxShadow:"0 2px 16px rgba(0,0,0,0.24)"},children:e.jsx(jo,{color:S,onChange:y,disableAlpha:!0,presetColors:["#fff","#000","#58a6ff","#ff4f4f","#2c2c2c","#00d18c","#e3e3e3","#0475c2","#ff8c00","#6b21a8","#0e7490"]})})]}),j=()=>{var R,x,S,z,E;return e.jsxs(m,{sx:{px:2,pt:1,pb:2},children:[e.jsx(m,{sx:{display:"flex",alignItems:"center",mb:1},children:e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Label"})}),e.jsx(Ie,{fullWidth:!0,size:"small",variant:"outlined",value:r.label||"",onChange:U=>l("label",U.target.value),sx:{mb:2,input:{color:"#fff",bgcolor:"#1e1e1e",fontSize:"0.95rem"},"& fieldset":{borderColor:"#444"}}}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:1},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Text Color"}),v("Label Text Color","labelStyle.fill",((R=r.labelStyle)==null?void 0:R.fill)||"#fff")]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:1},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Background"}),v("Label Background Color","labelBgStyle.fill",((x=r.labelBgStyle)==null?void 0:x.fill)||"#2c2c2c")]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Padding"}),e.jsx(Ie,{size:"small",type:"text",value:r.labelBgPadding?r.labelBgPadding.join(","):"8,4",onChange:U=>{const X=U.target.value.split(",").map(ue=>parseInt(ue.trim())).filter(ue=>!isNaN(ue));X.length===2&&l("labelBgPadding",X)},sx:{width:80,input:{color:"#fff",bgcolor:"#1e1e1e",fontSize:"0.95rem"}}})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Background Style"}),e.jsxs(Ie,{select:!0,size:"small",value:(((S=r.labelBgStyle)==null?void 0:S.rx)??11)>=11?"rounded":"square",onChange:U=>{l("labelBgStyle.rx",U.target.value==="rounded"?11:0)},sx:{width:150,bgcolor:"#1e1e1e","& .MuiSelect-select":{color:"#fff"}},children:[e.jsx(fe,{value:"rounded",children:"Rounded"}),e.jsx(fe,{value:"square",children:"Square"})]})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Background Opacity"}),e.jsx(Fn,{value:((z=r.labelBgStyle)==null?void 0:z.fillOpacity)??.85,min:0,max:1,step:.05,onChange:(U,X)=>l("labelBgStyle.fillOpacity",X),sx:{width:100,ml:2}}),e.jsx(Ie,{size:"small",type:"number",value:((E=r.labelBgStyle)==null?void 0:E.fillOpacity)??.85,onChange:U=>l("labelBgStyle.fillOpacity",parseFloat(U.target.value)||0),sx:{width:60,ml:2,input:{color:"#fff",bgcolor:"#1e1e1e",fontSize:"0.95rem"}}})]})]})},B=()=>{var R,x,S,z,E;return e.jsxs(m,{sx:{px:2,pt:1,pb:2},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Edge Style"}),e.jsxs(Ie,{select:!0,size:"small",value:r.type||"bezier",onChange:U=>l("type",U.target.value),sx:{width:200,bgcolor:"#1e1e1e","& .MuiSelect-select":{color:"#fff"}},children:[e.jsx(fe,{value:"step",children:"Step"}),e.jsx(fe,{value:"bezier",children:"Curved (Bezier)"}),e.jsx(fe,{value:"straight",children:"Straight"}),e.jsx(fe,{value:"smoothstep",children:"Smoothstep"})]})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Edge Animation"}),e.jsxs(Ie,{select:!0,size:"small",value:((R=r.style)==null?void 0:R.strokeDasharray)==="6 3"?"dashes":((x=r.style)==null?void 0:x.strokeDasharray)==="2 4"?"dots":"solid",onChange:U=>{const X=U.target.value;l("style.strokeDasharray",X==="dashes"?"6 3":X==="dots"?"2 4":"")},sx:{width:200,bgcolor:"#1e1e1e","& .MuiSelect-select":{color:"#fff"}},children:[e.jsx(fe,{value:"dashes",children:"Dashes"}),e.jsx(fe,{value:"dots",children:"Dots"}),e.jsx(fe,{value:"solid",children:"Solid"})]})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Color"}),v("Edge Color","style.stroke",((S=r.style)==null?void 0:S.stroke)||"#58a6ff")]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",mb:2},children:[e.jsx($,{variant:"body2",sx:{color:"#ccc",flex:1},children:"Edge Width"}),e.jsx(Fn,{value:((z=r.style)==null?void 0:z.strokeWidth)??2,min:1,max:10,step:1,onChange:(U,X)=>l("style.strokeWidth",X),sx:{width:100,ml:2}}),e.jsx(Ie,{size:"small",type:"number",value:((E=r.style)==null?void 0:E.strokeWidth)??2,onChange:U=>l("style.strokeWidth",parseInt(U.target.value)||1),sx:{width:60,ml:2,input:{color:"#fff",bgcolor:"#1e1e1e",fontSize:"0.95rem"}}})]})]})};return o?e.jsxs(e.Fragment,{children:[e.jsx(m,{onClick:t,sx:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.3)",opacity:n?1:0,pointerEvents:n?"auto":"none",transition:"opacity 0.6s ease",zIndex:10}}),e.jsxs(m,{sx:{position:"absolute",top:0,right:0,bottom:0,width:Hn,bgcolor:"#2C2C2C",color:"#ccc",borderLeft:"1px solid #333",padding:0,zIndex:11,display:"flex",flexDirection:"column",height:"100%",transform:n?"translateX(0)":`translateX(${Hn}px)`,transition:"transform 0.3s cubic-bezier(.77,0,.18,1)"},onClick:R=>R.stopPropagation(),children:[e.jsxs(m,{sx:{backgroundColor:"#232323",borderBottom:"1px solid #333"},children:[e.jsx(m,{sx:{padding:"12px 16px",display:"flex",alignItems:"center"},children:e.jsx($,{variant:"h7",sx:{color:"#0475c2",fontWeight:"bold",flex:1},children:"Edit Edge Properties"})}),e.jsxs(Us,{value:d,onChange:(R,x)=>u(x),variant:"fullWidth",textColor:"inherit",TabIndicatorProps:{style:{backgroundColor:"#ccc"}},sx:{borderTop:"1px solid #333",borderBottom:"1px solid #333",minHeight:"36px",height:"36px"},children:[e.jsx(ps,{label:"Label",sx:{color:"#ccc","&.Mui-selected":{color:"#ccc"},minHeight:"36px",height:"36px",textTransform:"none"}}),e.jsx(ps,{label:"Style",sx:{color:"#ccc","&.Mui-selected":{color:"#ccc"},minHeight:"36px",height:"36px",textTransform:"none"}})]})]}),e.jsxs(m,{sx:{flex:1,overflowY:"auto"},children:[d===0&&j(),d===1&&B()]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",px:2,py:1,borderTop:"1px solid #333",backgroundColor:"#232323",flexShrink:0},children:[e.jsxs(m,{children:[e.jsx(st,{title:"Copy Style",children:e.jsx(nt,{onClick:I,children:e.jsx(fo,{})})}),e.jsx(st,{title:"Paste Style",children:e.jsx(nt,{onClick:k,children:e.jsx(Qo,{})})})]}),e.jsx(m,{children:e.jsx(st,{title:"Reset to Default",children:e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(Zo,{}),onClick:C,sx:{color:"#58a6ff",borderColor:"#58a6ff",textTransform:"none"},children:"Reset to Default"})})})]})]})]}):null}function Wi({flowId:n,nodes:t,edges:o,setNodes:a,setEdges:d,nodeTypes:u,categorizedNodes:r}){var M;const[i,c]=s.useState(!1),[p,l]=s.useState(null),[h,f]=s.useState(!1),[y,C]=s.useState(null),[I,k]=s.useState(null),[v,j]=s.useState(null),B=s.useRef(null),{project:R}=dt(),[x,S]=s.useState([]),[z,E]=s.useState([]),U=s.useRef({width:0,height:0}),X=t.find(g=>g.id===p),ue=o.find(g=>g.id===y),Se=(g,L)=>{g.preventDefault(),k({mouseX:g.clientX+2,mouseY:g.clientY-6,nodeId:L.id})},ce=(g,L)=>{g.preventDefault(),j({mouseX:g.clientX+2,mouseY:g.clientY-6,edgeId:L.id})},de=g=>{d(L=>L.filter(we=>we.source!==g&&we.target!==g)),k(null)},me=g=>{a(L=>L.filter(we=>we.id!==g)),d(L=>L.filter(we=>we.source!==g&&we.target!==g)),k(null)},w=g=>{l(g),c(!0),k(null)},W=g=>{d(L=>L.filter(we=>we.id!==g)),j(null)},F=g=>{C(g),f(!0),j(null)},te=()=>{f(!1),C(null)},ee=g=>{d(L=>L.map(we=>we.id===g.id?{...we,...g}:we))},be=s.useCallback(g=>{if(!B.current)return;const L=B.current.getBoundingClientRect(),we=B.current.querySelector(`.react-flow__node[data-id="${g.id}"]`);if(we){const G=we.getBoundingClientRect(),ie=G.left-L.left,Ce=G.top-L.top,Ee=ie+G.width,Ne=Ce+G.height,Ke=R({x:ie,y:Ce}),at=R({x:Ee,y:Ce}),ut=R({x:ie,y:Ne});U.current={width:at.x-Ke.x,height:ut.y-Ke.y}}const T=[];t.forEach(G=>{if(G.id===g.id)return;const ie=B.current.querySelector(`.react-flow__node[data-id="${G.id}"]`);if(!ie)return;const Ce=ie.getBoundingClientRect(),Ee=Ce.left-L.left,Ne=Ce.top-L.top,Ke=Ee+Ce.width,at=Ne+Ce.height,ut=R({x:Ee,y:Ne}),Pe=R({x:Ke,y:Ne}),gt=R({x:Ee,y:at});T.push({xFlow:ut.x,xPx:Ee}),T.push({xFlow:Pe.x,xPx:Ke}),T.push({yFlow:ut.y,yPx:Ne}),T.push({yFlow:gt.y,yPx:at})}),S(T)},[t,R]),Re=s.useCallback((g,L)=>{let T=null,G=null;const ie=[],{width:Ce,height:Ee}=U.current;x.forEach(Ne=>{Ne.xFlow!=null&&(Math.abs(L.position.x-Ne.xFlow)<5?(T=Ne.xFlow,ie.push({xPx:Ne.xPx})):Math.abs(L.position.x+Ce-Ne.xFlow)<5&&(T=Ne.xFlow-Ce,ie.push({xPx:Ne.xPx}))),Ne.yFlow!=null&&(Math.abs(L.position.y-Ne.yFlow)<5?(G=Ne.yFlow,ie.push({yPx:Ne.yPx})):Math.abs(L.position.y+Ee-Ne.yFlow)<5&&(G=Ne.yFlow-Ee,ie.push({yPx:Ne.yPx})))}),T!==null||G!==null?(a(Ne=>zn([{id:L.id,type:"position",position:{x:T!==null?T:L.position.x,y:G!==null?G:L.position.y}}],Ne)),E(ie)):E([])},[x,a]),Ae=s.useCallback(g=>{g.preventDefault();const L=g.dataTransfer.getData("application/reactflow");if(!L)return;const we=B.current.getBoundingClientRect(),T=R({x:g.clientX-we.left,y:g.clientY-we.top}),G="node-"+Date.now(),ie=Object.values(r).flat().find(Ne=>Ne.type===L),Ce={};((ie==null?void 0:ie.config)||[]).forEach(Ne=>{Ne.defaultValue!==void 0&&(Ce[Ne.key]=Ne.defaultValue)});const Ee={id:G,type:L,position:T,data:{label:(ie==null?void 0:ie.label)||L,content:ie==null?void 0:ie.content,...Ce},dragHandle:".borealis-node-header"};a(Ne=>[...Ne,Ee])},[R,a,r]),Le=s.useCallback(g=>{g.preventDefault(),g.dataTransfer.dropEffect="move"},[]),Fe=s.useCallback(g=>{d(L=>Po({...g,type:"bezier",animated:!0,style:{strokeDasharray:"6 3",stroke:"#58a6ff"}},L))},[d]),je=s.useCallback(g=>{a(L=>zn(g,L))},[a]),V=s.useCallback(g=>{d(L=>Eo(g,L))},[d]);s.useEffect(()=>{const g=document.getElementById("nodeCount");g&&(g.innerText=t.length)},[t]);const O=X?Object.values(r).flat().find(g=>g.type===X.type):null;return e.jsxs("div",{className:"flow-editor-container",ref:B,style:{position:"relative"},children:[e.jsx($i,{drawerOpen:i,setDrawerOpen:c,title:X?((M=X.data)==null?void 0:M.label)||X.id:"",nodeData:X&&O?{config:O.config,usage_documentation:O.usage_documentation,...X.data,nodeId:X.id}:null,setNodes:a,selectedNode:X}),e.jsx(Ui,{open:h,onClose:te,edge:ue?{...ue}:null,updateEdge:g=>{!g.id&&y&&(g.id=y),ee(g)}}),e.jsx(lo,{nodes:t,edges:o,nodeTypes:u,onNodesChange:je,onEdgesChange:V,onConnect:Fe,onDrop:Ae,onDragOver:Le,onNodeContextMenu:Se,onEdgeContextMenu:ce,defaultViewport:{x:0,y:0,zoom:1.5},edgeOptions:{type:"bezier",animated:!0,style:{strokeDasharray:"6 3",stroke:"#58a6ff"}},proOptions:{hideAttribution:!0},onNodeDragStart:(g,L)=>be(L),onNodeDrag:Re,onNodeDragStop:()=>{S([]),E([])},children:e.jsx(Mo,{id:n,variant:"lines",gap:65,size:1,color:"rgba(255,255,255,0.2)"})}),z.map((g,L)=>g.xPx!=null?e.jsx("div",{className:"helper-line helper-line-vertical",style:{left:g.xPx+"px",top:0}},L):e.jsx("div",{className:"helper-line helper-line-horizontal",style:{top:g.yPx+"px",left:0}},L)),e.jsxs(Et,{open:!!I,onClose:()=>k(null),anchorReference:"anchorPosition",anchorPosition:I?{top:I.mouseY,left:I.mouseX}:void 0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[e.jsxs(fe,{onClick:()=>w(I.nodeId),children:[e.jsx(Fs,{sx:{fontSize:18,color:"#58a6ff",mr:1}}),"Edit Properties"]}),e.jsxs(fe,{onClick:()=>de(I.nodeId),children:[e.jsx(kn,{sx:{fontSize:18,color:"#58a6ff",mr:1}}),"Disconnect All Edges"]}),e.jsxs(fe,{onClick:()=>me(I.nodeId),children:[e.jsx(Ln,{sx:{fontSize:18,color:"#ff4f4f",mr:1}}),"Remove Node"]})]}),e.jsxs(Et,{open:!!v,onClose:()=>j(null),anchorReference:"anchorPosition",anchorPosition:v?{top:v.mouseY,left:v.mouseX}:void 0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[e.jsxs(fe,{onClick:()=>F(v.edgeId),children:[e.jsx(Fs,{sx:{fontSize:18,color:"#58a6ff",mr:1}}),"Edit Properties"]}),e.jsxs(fe,{onClick:()=>W(v.edgeId),children:[e.jsx(Ln,{sx:{fontSize:18,color:"#ff4f4f",mr:1}}),"Unlink Edge"]})]})]})}function Vi({categorizedNodes:n,handleExportFlow:t,handleImportFlow:o,handleSaveFlow:a,handleOpenCloseAllDialog:d,fileInputRef:u,onFileInputChange:r,currentTabName:i}){const[c,p]=s.useState(null),[l,h]=s.useState(!1),[f,y]=s.useState(!1),[C,I]=s.useState(""),k=v=>(j,B)=>{p(B?v:null)};return e.jsxs("div",{style:{width:l?40:300,backgroundColor:"#121212",borderRight:"1px solid #333",overflow:"hidden",display:"flex",flexDirection:"column",height:"100%"},children:[e.jsx("div",{style:{flex:1,overflowY:"auto"},children:!l&&e.jsxs(e.Fragment,{children:[e.jsxs(as,{defaultExpanded:!0,square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{backgroundColor:"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0}},children:e.jsx($,{sx:{fontSize:"0.9rem",color:"#0475c2"},children:e.jsx("b",{children:"Workflows"})})}),e.jsxs(cs,{sx:{p:0,bgcolor:"#232323"},children:[e.jsx(st,{title:"Save Current Flow to Workflows Folder",placement:"right",arrow:!0,children:e.jsx(Z,{fullWidth:!0,startIcon:e.jsx(ho,{}),onClick:()=>{I(i||"workflow"),y(!0)},sx:hn,children:"Save Workflow"})}),e.jsx(st,{title:"Import JSON File into New Flow Tab",placement:"right",arrow:!0,children:e.jsx(Z,{fullWidth:!0,startIcon:e.jsx(er,{}),onClick:o,sx:hn,children:"Import Workflow (JSON)"})}),e.jsx(st,{title:"Export Current Tab to a JSON File",placement:"right",arrow:!0,children:e.jsx(Z,{fullWidth:!0,startIcon:e.jsx(tr,{}),onClick:t,sx:hn,children:"Export Workflow (JSON)"})})]})]}),e.jsxs(as,{defaultExpanded:!0,square:!0,disableGutters:!0,sx:{"&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{backgroundColor:"#2c2c2c",minHeight:"36px","& .MuiAccordionSummary-content":{margin:0}},children:e.jsx($,{sx:{fontSize:"0.9rem",color:"#0475c2"},children:e.jsx("b",{children:"Nodes"})})}),e.jsx(cs,{sx:{p:0},children:Object.entries(n).map(([v,j])=>e.jsxs(as,{square:!0,expanded:c===v,onChange:k(v),disableGutters:!0,sx:{bgcolor:"#232323","&:before":{display:"none"},margin:0,border:0},children:[e.jsx(is,{expandIcon:e.jsx(ls,{}),sx:{bgcolor:"#1e1e1e",px:2,minHeight:"32px","& .MuiAccordionSummary-content":{margin:0}},children:e.jsx($,{sx:{color:"#888",fontSize:"0.75rem"},children:v})}),e.jsx(cs,{sx:{px:1,py:0},children:j.map(B=>e.jsx(st,{title:e.jsx("span",{style:{whiteSpace:"pre-line",wordWrap:"break-word",maxWidth:220},children:B.description||"Drag & Drop into Editor"}),placement:"right",arrow:!0,children:e.jsxs(Z,{fullWidth:!0,sx:Hi,draggable:!0,onDragStart:R=>{R.dataTransfer.setData("application/reactflow",B.type),R.dataTransfer.effectAllowed="move"},startIcon:e.jsx(sr,{sx:{color:"#666",fontSize:18}}),children:[e.jsx("span",{style:{flexGrow:1,textAlign:"left"},children:B.label}),e.jsx(kn,{sx:{color:"#58a6ff",fontSize:18,ml:1}})]})},`${v}-${B.type}`))})]},v))})]}),e.jsx("input",{type:"file",accept:".json,application/json",style:{display:"none"},ref:u,onChange:r})]})}),e.jsx(st,{title:l?"Expand Sidebar":"Collapse Sidebar",placement:"left",children:e.jsx(m,{onClick:()=>h(!l),sx:{height:"36px",borderTop:"1px solid #333",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",color:"#888",backgroundColor:"#121212",transition:"background-color 0.2s ease","&:hover":{backgroundColor:"#1e1e1e"},"&:active":{backgroundColor:"#2a2a2a"}},children:l?e.jsx(nr,{}):e.jsx(or,{})})}),e.jsx(Ai,{open:f,value:C,onChange:I,onCancel:()=>y(!1),onSave:()=>{y(!1),a(C)}})]})}const hn={color:"#ccc",backgroundColor:"#232323",justifyContent:"flex-start",pl:2,fontSize:"0.9rem",textTransform:"none","&:hover":{backgroundColor:"#2a2a2a"}},Hi={color:"#ccc",backgroundColor:"#232323",justifyContent:"space-between",pl:2,pr:1,fontSize:"0.9rem",textTransform:"none","&:hover":{backgroundColor:"#2a2a2a"}};function Gi(){const[n,t]=s.useState("checking");s.useEffect(()=>{fetch("/health").then(a=>a.ok?t("online"):t("offline")).catch(()=>t("offline"))},[]);const o=()=>{var d;const a=parseInt((d=document.getElementById("updateRateInput"))==null?void 0:d.value);!isNaN(a)&&a>=50?(window.BorealisUpdateRate=a,console.log("Global update rate set to",a+"ms")):alert("Please enter a valid number (min 50).")};return e.jsxs(m,{component:"footer",sx:{bgcolor:"#1e1e1e",color:"white",px:2,py:1,display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:2},children:[e.jsx("b",{children:"Nodes"}),": ",e.jsx("span",{id:"nodeCount",children:"0"}),e.jsx(In,{orientation:"vertical",flexItem:!0,sx:{borderColor:"#444"}}),e.jsx("b",{children:"Update Rate (ms):"}),e.jsx("input",{id:"updateRateInput",type:"number",min:"50",step:"50",defaultValue:window.BorealisUpdateRate,style:{width:"80px",background:"#121212",color:"#fff",border:"1px solid #444",borderRadius:"3px",padding:"3px",fontSize:"0.8rem"}}),e.jsx(Z,{variant:"outlined",size:"small",onClick:o,sx:{color:"#58a6ff",borderColor:"#58a6ff",fontSize:"0.75rem",textTransform:"none",px:1.5},children:"Apply Rate"})]}),e.jsxs(m,{sx:{fontSize:"1.0rem",display:"flex",alignItems:"center",gap:1},children:[e.jsx("strong",{style:{color:"#58a6ff"},children:"Backend API Server"}),":",e.jsx("a",{href:"http://localhost:5000/health",target:"_blank",rel:"noopener noreferrer",style:{color:n==="online"?"#00d18c":"#ff4f4f",textDecoration:"none",fontWeight:"bold"},children:n==="checking"?"...":n.charAt(0).toUpperCase()+n.slice(1)})]})]})}function qi({onLogin:n}){const[t,o]=s.useState("admin"),[a,d]=s.useState(""),[u,r]=s.useState(""),[i,c]=s.useState(!1),[p,l]=s.useState("credentials"),[h,f]=s.useState(""),[y,C]=s.useState(null),[I,k]=s.useState(""),[v,j]=s.useState(""),[B,R]=s.useState(""),[x,S]=s.useState(""),z=s.useMemo(()=>v?v.replace(/(.{4})/g,"$1 ").trim():"",[v]),E=async me=>{try{if(window.crypto&&window.crypto.subtle&&window.isSecureContext){const W=new TextEncoder().encode(me),F=await window.crypto.subtle.digest("SHA-512",W);return Array.from(new Uint8Array(F)).map(ee=>ee.toString(16).padStart(2,"0")).join("")}}catch{}return null},U=()=>{l("credentials"),f(""),C(null),k(""),j(""),R(""),S("")},X=async me=>{me.preventDefault(),c(!0),r("");try{const w=await E(a),F=await fetch("/api/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(w?{username:t,password_sha512:w}:{username:t,password:a})}),te=await F.json();if(!F.ok)throw new Error((te==null?void 0:te.error)||"Invalid username or password");if((te==null?void 0:te.status)==="mfa_required"){f(te.pending_token||""),C(te.stage||"verify"),l("mfa"),k(""),j(te.secret||""),R(te.qr_image||""),S(te.otpauth_url||""),r(""),d("");return}if(te!=null&&te.token)try{document.cookie=`borealis_auth=${te.token}; Path=/; SameSite=Lax`}catch{}n({username:te.username,role:te.role})}catch(w){const W=(w==null?void 0:w.message)||"Unable to log in";r(W),U()}finally{c(!1)}},ue=async me=>{if(me.preventDefault(),!h){r("Your MFA session expired. Please log in again."),U();return}if(!I||I.trim().length<6){r("Enter the 6-digit code from your authenticator app.");return}c(!0),r("");try{const w=await fetch("/api/auth/mfa/verify",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({pending_token:h,code:I})}),W=await w.json();if(!w.ok){const F=W==null?void 0:W.error;if(F==="expired"||F==="invalid_session"||F==="mfa_pending"){r("Your MFA session expired. Please log in again."),U();return}r({invalid_code:"Incorrect code. Please try again.",mfa_not_configured:"MFA is not configured for this account."}[F]||(W==null?void 0:W.error)||"Failed to verify code.");return}if(W!=null&&W.token)try{document.cookie=`borealis_auth=${W.token}; Path=/; SameSite=Lax`}catch{}r(""),n({username:W.username,role:W.role})}catch{r("Failed to verify code.")}finally{c(!1)}},Se=()=>{U(),d(""),r("")},ce=me=>{const W=(me.target.value||"").replace(/\D/g,"").slice(0,6);k(W)},de=p==="mfa"?"Multi-Factor Authentication":"Borealis - Automation Platform";return e.jsx(m,{sx:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh",backgroundColor:"#2b2b2b"},children:e.jsxs(m,{component:"form",onSubmit:p==="mfa"?ue:X,sx:{display:"flex",flexDirection:"column",alignItems:"center",width:320},children:[e.jsx("img",{src:"/Borealis_Logo.png",alt:"Borealis Logo",style:{width:"120px",marginBottom:"16px"}}),e.jsx($,{variant:"h6",sx:{mb:2,textAlign:"center"},children:de}),p==="credentials"?e.jsxs(e.Fragment,{children:[e.jsx(Ie,{label:"Username",variant:"outlined",fullWidth:!0,value:t,disabled:i,onChange:me=>o(me.target.value),margin:"normal"}),e.jsx(Ie,{label:"Password",type:"password",variant:"outlined",fullWidth:!0,value:a,disabled:i,onChange:me=>d(me.target.value),margin:"normal"}),u&&e.jsx($,{color:"error",sx:{mt:1},children:u}),e.jsx(Z,{type:"submit",variant:"contained",fullWidth:!0,disabled:i,sx:{mt:2,bgcolor:"#58a6ff","&:hover":{bgcolor:"#1d82d3"}},children:i?"Signing In...":"Login"})]}):e.jsxs(e.Fragment,{children:[y==="setup"?e.jsxs(e.Fragment,{children:[e.jsxs($,{variant:"body2",sx:{color:"#ccc",textAlign:"center",mb:2},children:["Scan the QR code with your authenticator app, then enter the 6-digit code to complete setup for ",t,"."]}),B?e.jsx("img",{src:B,alt:"MFA enrollment QR code",style:{width:"180px",height:"180px",marginBottom:"12px"}}):null,z?e.jsxs(m,{sx:{bgcolor:"#1d1d1d",borderRadius:1,px:2,py:1,mb:1.5,width:"100%"},children:[e.jsx($,{variant:"caption",sx:{color:"#999"},children:"Manual code"}),e.jsx($,{variant:"body1",sx:{fontFamily:"monospace",letterSpacing:"0.3rem",color:"#fff",mt:.5,textAlign:"center",wordBreak:"break-word"},children:z})]}):null,x?e.jsx($,{variant:"caption",sx:{color:"#888",mb:2,wordBreak:"break-all",textAlign:"center"},children:x}):null]}):e.jsxs($,{variant:"body2",sx:{color:"#ccc",textAlign:"center",mb:2},children:["Enter the 6-digit code from your authenticator app for ",t,"."]}),e.jsx(Ie,{label:"6-digit code",variant:"outlined",fullWidth:!0,value:I,onChange:ce,disabled:i,margin:"normal",inputProps:{inputMode:"numeric",pattern:"[0-9]*",maxLength:6,style:{letterSpacing:"0.4rem",textAlign:"center",fontSize:"1.2rem"}},autoComplete:"one-time-code"}),u&&e.jsx($,{color:"error",sx:{mt:1,textAlign:"center"},children:u}),e.jsx(Z,{type:"submit",variant:"contained",fullWidth:!0,disabled:i||I.length<6,sx:{mt:2,bgcolor:"#58a6ff","&:hover":{bgcolor:"#1d82d3"}},children:i?"Verifying...":"Verify Code"}),e.jsx(Z,{type:"button",variant:"text",fullWidth:!0,disabled:i,onClick:Se,sx:{mt:1,color:"#58a6ff"},children:"Use a different account"})]})]})})}function Ji({onOpenDevicesForSite:n}){var je;const[t,o]=s.useState([]),[a,d]=s.useState("name"),[u,r]=s.useState("asc"),[i,c]=s.useState(()=>new Set),p=s.useMemo(()=>({name:"Name",description:"Description",device_count:"Devices"}),[]),l=s.useMemo(()=>[{id:"name",label:p.name},{id:"description",label:p.description},{id:"device_count",label:p.device_count}],[p]),[h,f]=s.useState(l),y=s.useRef(null),[C,I]=s.useState(null),[k,v]=s.useState({}),[j,B]=s.useState(null),[R,x]=s.useState(!1),[S,z]=s.useState(!1),[E,U]=s.useState(!1),[X,ue]=s.useState(""),Se=s.useCallback(async()=>{try{const O=await(await fetch("/api/sites")).json();o(Array.isArray(O==null?void 0:O.sites)?O.sites:[])}catch{o([])}},[]);s.useEffect(()=>{Se()},[Se]),s.useEffect(()=>{try{const V=localStorage.getItem("site_list_initial_filters");if(V){const O=JSON.parse(V);O&&typeof O=="object"&&v(M=>({...M,...O})),localStorage.removeItem("site_list_initial_filters")}}catch{}},[]);const ce=V=>{a===V?r(u==="asc"?"desc":"asc"):(d(V),r("asc"))},de=s.useMemo(()=>!k||Object.keys(k).length===0?t:t.filter(V=>Object.entries(k).every(([O,M])=>{const g=String(M||"").toLowerCase();return g?String(V[O]??"").toLowerCase().includes(g):!0})),[t,k]),me=s.useMemo(()=>{const V=u==="asc"?1:-1,O=[...de];return O.sort((M,g)=>a==="device_count"?((M.device_count||0)-(g.device_count||0))*V:String(M[a]??"").localeCompare(String(g[a]??""))*V),O},[de,a,u]),w=V=>O=>{y.current=V;try{O.dataTransfer.setData("text/plain",V)}catch{}},W=V=>{V.preventDefault()},F=V=>O=>{O.preventDefault();const M=y.current;!M||M===V||(f(g=>{const L=[...g],we=L.findIndex(ie=>ie.id===M),T=L.findIndex(ie=>ie.id===V);if(we<0||T<0)return g;const[G]=L.splice(we,1);return L.splice(T,0,G),L}),y.current=null)},te=V=>O=>B({id:V,anchorEl:O.currentTarget}),ee=()=>B(null),be=V=>O=>v(M=>({...M,[V]:O.target.value})),Re=me.length>0&&me.every(V=>i.has(V.id)),Ae=i.size>0&&!Re,Le=V=>{const O=V.target.checked;c(M=>{const g=new Set(M);return O?me.forEach(L=>g.add(L.id)):g.clear(),g})},Fe=V=>O=>{const M=O.target.checked;c(g=>{const L=new Set(g);return M?L.add(V):L.delete(V),L})};return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e"},elevation:2,children:[e.jsxs(m,{sx:{p:2,pb:1,display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:"Sites"}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(Fs,{}),disabled:i.size!==1,onClick:()=>{const V=i.size===1?Array.from(i)[0]:null;if(V!=null){const O=t.find(M=>M.id===V);ue((O==null?void 0:O.name)||""),U(!0)}},sx:{color:i.size===1?"#58a6ff":"#666",borderColor:i.size===1?"#58a6ff":"#333",textTransform:"none"},children:"Rename"}),e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(mo,{}),disabled:i.size===0,onClick:()=>z(!0),sx:{color:i.size?"#ff8a8a":"#666",borderColor:i.size?"#ff4f4f":"#333",textTransform:"none"},children:"Delete"}),e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(ts,{}),onClick:()=>x(!0),sx:{color:"#58a6ff",borderColor:"#58a6ff",textTransform:"none"},children:"Create Site"})]})]}),e.jsxs(Rt,{size:"small",sx:{minWidth:700},children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{padding:"checkbox",children:e.jsx(At,{indeterminate:Ae,checked:Re,onChange:Le,sx:{color:"#777"}})}),h.map(V=>e.jsx(Q,{sortDirection:a===V.id?u:!1,draggable:!0,onDragStart:w(V.id),onDragOver:W,onDrop:F(V.id),children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Tt,{active:a===V.id,direction:a===V.id?u:"asc",onClick:()=>ce(V.id),children:V.label}),e.jsx(nt,{size:"small",onClick:te(V.id),sx:{color:k[V.id]?"#58a6ff":"#888"},children:e.jsx(Rn,{fontSize:"inherit"})})]})},V.id))]})}),e.jsxs(Nt,{children:[me.map(V=>e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{padding:"checkbox",onClick:O=>O.stopPropagation(),children:e.jsx(At,{checked:i.has(V.id),onChange:Fe(V.id),sx:{color:"#777"}})}),h.map(O=>{switch(O.id){case"name":return e.jsx(Q,{onClick:()=>{n&&n(V.name)},sx:{color:"#58a6ff","&:hover":{cursor:"pointer",textDecoration:"underline"}},children:V.name},O.id);case"description":return e.jsx(Q,{children:V.description||""},O.id);case"device_count":return e.jsx(Q,{children:V.device_count??0},O.id);default:return e.jsx(Q,{},O.id)}})]},V.id)),me.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:h.length+1,sx:{color:"#888"},children:"No sites defined."})})]})]}),e.jsx(Ls,{open:!!C,anchorEl:C,onClose:()=>I(null),anchorOrigin:{vertical:"bottom",horizontal:"right"},PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",p:1}},children:e.jsxs(m,{sx:{display:"flex",flexDirection:"column",gap:.5,p:1},children:[[{id:"name",label:"Name"},{id:"description",label:"Description"},{id:"device_count",label:"Devices"}].map(V=>e.jsxs(fe,{disableRipple:!0,onClick:O=>O.stopPropagation(),sx:{gap:1},children:[e.jsx(At,{size:"small",checked:h.some(O=>O.id===V.id),onChange:O=>{const M=O.target.checked;f(g=>{const L=g.some(we=>we.id===V.id);return M?L?g:[...g,{id:V.id,label:V.label}]:g.filter(we=>we.id!==V.id)})},sx:{p:.3,color:"#bbb"}}),e.jsx($,{variant:"body2",sx:{color:"#ddd"},children:V.label})]},V.id)),e.jsx(m,{sx:{display:"flex",gap:1,pt:.5},children:e.jsx(Z,{size:"small",variant:"outlined",onClick:()=>f(l),sx:{textTransform:"none",borderColor:"#555",color:"#bbb"},children:"Reset Default"})})]})}),e.jsx(Ls,{open:!!j,anchorEl:(j==null?void 0:j.anchorEl)||null,onClose:ee,anchorOrigin:{vertical:"bottom",horizontal:"left"},PaperProps:{sx:{bgcolor:"#1e1e1e",p:1}},children:j&&e.jsxs(m,{sx:{display:"flex",gap:1,alignItems:"center"},children:[e.jsx(Ie,{autoFocus:!0,size:"small",placeholder:`Filter ${((je=h.find(V=>V.id===j.id))==null?void 0:je.label)||""}`,value:k[j.id]||"",onChange:be(j.id),onKeyDown:V=>{V.key==="Escape"&&ee()},sx:{input:{color:"#fff"},minWidth:220,"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}}}}),e.jsx(Z,{variant:"outlined",size:"small",onClick:()=>{v(V=>({...V,[j.id]:""})),ee()},sx:{textTransform:"none",borderColor:"#555",color:"#bbb"},children:"Clear"})]})}),e.jsx(Mi,{open:R,onCancel:()=>x(!1),onCreate:async(V,O)=>{try{if(!(await fetch("/api/sites",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:V,description:O})})).ok)return;x(!1),await Se()}catch{}}}),e.jsx(Zt,{open:S,message:`Delete ${i.size} selected site(s)? This cannot be undone.`,onCancel:()=>z(!1),onConfirm:async()=>{try{const V=Array.from(i);await fetch("/api/sites/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:V})})}catch{}z(!1),c(new Set),await Se()}}),e.jsx(Di,{open:E,value:X,onChange:ue,onCancel:()=>U(!1),onSave:async()=>{const V=(X||"").trim();if(!V)return;const O=i.size===1?Array.from(i)[0]:null;if(O!=null)try{const M=await fetch("/api/sites/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:O,new_name:V})});if(!M.ok){try{const g=await M.json();console.warn("Rename failed",g)}catch{}return}U(!1),await Se()}catch(M){console.warn("Rename error",M)}}})]})}function Yi(n,t,o="Scripts"){const a={},d={id:"root",label:o,path:"",isFolder:!0,children:[]};return a[d.id]=d,(t||[]).forEach(u=>{const r=(u||"").split("/");let i=d.children,c="";r.forEach(p=>{const l=c?`${c}/${p}`:p;let h=i.find(f=>f.id===l);h||(h={id:l,label:p,path:l,isFolder:!0,children:[]},i.push(h),a[l]=h),i=h.children,c=l})}),(n||[]).forEach(u=>{const r=(u.rel_path||"").split("/");let i=d.children,c="";r.forEach((p,l)=>{const h=c?`${c}/${p}`:p,f=l===r.length-1;let y=i.find(C=>C.id===h);y||(y={id:h,label:f&&(u.name||u.file_name)||p,path:h,isFolder:!f,fileName:u.file_name,script:f?u:null,children:[]},i.push(y),a[h]=y),f||(i=y.children,c=h)})}),{root:[d],map:a}}function vo({open:n,onClose:t,hostnames:o=[]}){const[a,d]=s.useState([]),[u,r]=s.useState({}),[i,c]=s.useState(""),[p,l]=s.useState(!1),[h,f]=s.useState(""),[y,C]=s.useState(!1),[I,k]=s.useState("scripts"),[v,j]=s.useState([]),[B,R]=s.useState(!1),[x,S]=s.useState(""),[z,E]=s.useState(""),[U,X]=s.useState(!0),[ue,Se]=s.useState([]),[ce,de]=s.useState({}),[me,w]=s.useState({}),[W,F]=s.useState({loading:!1,error:""}),te=s.useCallback(async()=>{try{const g=await fetch(`/api/assembly/list?island=${I==="ansible"?"ansible":"scripts"}`);if(!g.ok)throw new Error(`HTTP ${g.status}`);const L=await g.json(),{root:we,map:T}=Yi(L.items||[],L.folders||[],I==="ansible"?"Ansible Playbooks":"Scripts");d(we),r(T)}catch(M){console.error("Failed to load scripts:",M),d([]),r({})}},[I]);s.useEffect(()=>{n&&(c(""),f(""),Se([]),de({}),w({}),F({loading:!1,error:""}),X(!0),E(""),te())},[n,te]),s.useEffect(()=>{if(!n||I!=="ansible")return;let M=!1;return R(!0),S(""),(async()=>{try{const g=await fetch("/api/credentials");if(!g.ok)throw new Error(`HTTP ${g.status}`);const L=await g.json();if(M)return;const we=Array.isArray(L==null?void 0:L.credentials)?L.credentials.filter(T=>{const G=String(T.connection_type||"").toLowerCase();return G==="ssh"||G==="winrm"}):[];we.sort((T,G)=>String((T==null?void 0:T.name)||"").localeCompare(String((G==null?void 0:G.name)||""))),j(we)}catch(g){M||(j([]),S(String(g.message||g)))}finally{M||R(!1)}})(),()=>{M=!0}},[n,I]),s.useEffect(()=>{n||E("")},[n]),s.useEffect(()=>{if(!(I!=="ansible"||U)){if(!v.length){E("");return}(!z||!v.some(M=>String(M.id)===String(z)))&&E(String(v[0].id))}},[I,v,z,U]);const ee=(M=[])=>M.map(g=>e.jsx(ys,{itemId:g.id,label:e.jsxs(m,{sx:{display:"flex",alignItems:"center"},children:[g.isFolder?e.jsx(Nn,{fontSize:"small",sx:{mr:1,color:"#ccc"}}):e.jsx(Tn,{fontSize:"small",sx:{mr:1,color:"#ccc"}}),e.jsx($,{variant:"body2",sx:{color:"#e6edf3"},children:g.label})]}),children:g.children&&g.children.length?ee(g.children):null},g.id)),be=(M,g)=>{const L=u[g];L&&!L.isFolder&&(c(L.path),f(""),w({}))},Re=M=>Array.isArray(M)?M.map(g=>{if(!g||typeof g!="object")return null;const L=typeof g.name=="string"?g.name.trim():typeof g.key=="string"?g.key.trim():"";if(!L)return null;const we=typeof g.type=="string"?g.type.toLowerCase():"string",T=typeof g.label=="string"&&g.label.trim()?g.label.trim():L,G=typeof g.description=="string"?g.description:"",ie=!!g.required,Ce=g.hasOwnProperty("default")?g.default:g.hasOwnProperty("defaultValue")?g.defaultValue:g.hasOwnProperty("default_value")?g.default_value:"";return{name:L,label:T,type:we,description:G,required:ie,default:Ce}}).filter(Boolean):[],Ae=M=>{const{type:g,default:L}=M;if(g==="boolean"){if(typeof L=="boolean")return L;if(L==null)return!1;const we=String(L).trim().toLowerCase();return we?["true","1","yes","on"].includes(we):!1}if(g==="number"){if(L==null||L==="")return"";if(typeof L=="number"&&Number.isFinite(L))return String(L);const we=Number(L);return Number.isFinite(we)?String(we):""}return L==null?"":String(L)};s.useEffect(()=>{if(!i){Se([]),de({}),w({}),F({loading:!1,error:""});return}let M=!1;return(async()=>{var L;F({loading:!0,error:""});try{const we=I==="ansible"?"ansible":"scripts",T=(i||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();if(!T){Se([]),de({}),w({}),F({loading:!1,error:""});return}let G=T;we==="scripts"&&G.toLowerCase().startsWith("scripts/")?G=G.slice(8):we==="ansible"&&G.toLowerCase().startsWith("ansible_playbooks/")&&(G=G.slice(18));const ie=await fetch(`/api/assembly/load?island=${we}&path=${encodeURIComponent(G)}`);if(!ie.ok)throw new Error(`Failed to load assembly (HTTP ${ie.status})`);const Ce=await ie.json(),Ee=Re(((L=Ce==null?void 0:Ce.assembly)==null?void 0:L.variables)||[]);if(!M){Se(Ee);const Ne={};Ee.forEach(Ke=>{Ne[Ke.name]=Ae(Ke)}),de(Ne),w({}),F({loading:!1,error:""})}}catch(we){M||(Se([]),de({}),w({}),F({loading:!1,error:(we==null?void 0:we.message)||String(we)}))}})(),()=>{M=!0}},[i,I]);const Le=(M,g)=>{const{name:L,type:we}=M;L&&(de(T=>({...T,[L]:we==="boolean"?!!g:g})),w(T=>{if(!T[L])return T;const G={...T};return delete G[L],G}))},Fe=()=>{const M={};return ue.forEach(g=>{if(!(g!=null&&g.name))return;const{name:L,type:we}=g,G=Object.prototype.hasOwnProperty.call(ce,L)?ce[L]:Ae(g);if(we==="boolean")M[L]=!!G;else if(we==="number")if(G===""||G===null||G===void 0)M[L]="";else{const ie=Number(G);M[L]=Number.isFinite(ie)?ie:""}else M[L]=G==null?"":String(G)}),M},je=async()=>{if(!i){f(I==="ansible"?"Please choose a playbook to run.":"Please choose a script to run.");return}if(I==="ansible"&&!U&&!z){f("Select a credential to run this playbook.");return}if(ue.length){const M={};if(ue.forEach(g=>{if(!g||!g.required||g.type==="boolean")return;const we=Object.prototype.hasOwnProperty.call(ce,g.name)?ce[g.name]:Ae(g);(we==null||we==="")&&(M[g.name]="Required")}),Object.keys(M).length){w(M),f("Please fill in all required variable values.");return}}l(!0),f("");try{let M;const g=Fe();if(I==="ansible")M=await fetch("/api/ansible/quick_run",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({playbook_path:i,hostnames:o,variable_values:g,credential_id:!U&&z?Number(z):null,use_service_account:!!U})});else{const we=i.startsWith("Scripts/")?i:`Scripts/${i}`;M=await fetch("/api/scripts/quick_run",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({script_path:we,hostnames:o,run_mode:y?"current_user":"system",variable_values:g})})}const L=await M.json();if(!M.ok)throw new Error(L.error||`HTTP ${M.status}`);t&&t()}catch(M){f(String(M.message||M))}finally{l(!1)}},O=p||!i||I==="ansible"&&!U&&(!z||!v.length);return e.jsxs(Ze,{open:n,onClose:p?void 0:t,fullWidth:!0,maxWidth:"md",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Quick Job"}),e.jsxs(rt,{children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,mb:1},children:[e.jsx(Z,{size:"small",variant:I==="scripts"?"outlined":"text",onClick:()=>k("scripts"),sx:{textTransform:"none",color:"#58a6ff",borderColor:"#58a6ff"},children:"Scripts"}),e.jsx(Z,{size:"small",variant:I==="ansible"?"outlined":"text",onClick:()=>k("ansible"),sx:{textTransform:"none",color:"#58a6ff",borderColor:"#58a6ff"},children:"Ansible"})]}),e.jsxs($,{variant:"body2",sx:{color:"#aaa",mb:1},children:["Select a ",I==="ansible"?"playbook":"script"," to run on ",o.length," device",o.length!==1?"s":"","."]}),I==="ansible"&&e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1.5,flexWrap:"wrap",mb:2},children:[e.jsx(bs,{control:e.jsx(At,{checked:U,onChange:M=>{const g=M.target.checked;X(g),g?E(""):!z&&v.length&&E(String(v[0].id))},size:"small"}),label:"Use Configured svcBorealis Account",sx:{mr:2}}),e.jsxs(Ht,{size:"small",sx:{minWidth:260},disabled:U||B||!v.length,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Credential"}),e.jsx(wt,{value:z,label:"Credential",onChange:M=>E(M.target.value),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:v.map(M=>{const g=String(M.connection_type||"").toUpperCase();return e.jsxs(fe,{value:String(M.id),children:[M.name,g?` (${g})`:""]},M.id)})})]}),U&&e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Runs with the agent's svcBorealis account."}),B&&e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),!B&&x&&e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:x}),!U&&!B&&!x&&!v.length&&e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:"No SSH or WinRM credentials available. Create one under Access Management."})]}),e.jsxs(m,{sx:{display:"flex",gap:2},children:[e.jsx(Qe,{sx:{flex:1,p:1,bgcolor:"#1e1e1e",maxHeight:400,overflow:"auto"},children:e.jsx(vs,{sx:{color:"#e6edf3"},onItemSelectionToggle:be,children:a.length?ee(a):e.jsx($,{variant:"body2",sx:{color:"#888",p:1},children:I==="ansible"?"No playbooks found.":"No scripts found."})})}),e.jsxs(m,{sx:{width:320},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:1},children:"Selection"}),e.jsx($,{variant:"body2",sx:{color:i?"#e6edf3":"#888"},children:i||(I==="ansible"?"No playbook selected":"No script selected")}),e.jsx(m,{sx:{mt:2},children:I!=="ansible"&&e.jsxs(e.Fragment,{children:[e.jsx(bs,{control:e.jsx(At,{size:"small",checked:y,onChange:M=>C(M.target.checked)}),label:e.jsx($,{variant:"body2",children:"Run as currently logged-in user"})}),e.jsx($,{variant:"caption",sx:{color:"#888"},children:"Unchecked = Run-As BUILTIN\\SYSTEM"})]})}),e.jsxs(m,{sx:{mt:3},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:1},children:"Variables"}),W.loading?e.jsx($,{variant:"body2",sx:{color:"#888"},children:"Loading variables…"}):W.error?e.jsx($,{variant:"body2",sx:{color:"#ff4f4f"},children:W.error}):ue.length?e.jsx(m,{sx:{display:"flex",flexDirection:"column",gap:1.5},children:ue.map(M=>e.jsxs(m,{children:[M.type==="boolean"?e.jsx(bs,{control:e.jsx(At,{size:"small",checked:!!ce[M.name],onChange:g=>Le(M,g.target.checked)}),label:e.jsxs($,{variant:"body2",children:[M.label,M.required?" *":""]})}):e.jsx(Ie,{fullWidth:!0,size:"small",label:`${M.label}${M.required?" *":""}`,type:M.type==="number"?"number":M.type==="credential"?"password":"text",value:ce[M.name]??"",onChange:g=>Le(M,g.target.value),InputLabelProps:{shrink:!0},sx:{"& .MuiOutlinedInput-root":{bgcolor:"#1b1b1b",color:"#e6edf3"},"& .MuiInputBase-input":{color:"#e6edf3"}},error:!!me[M.name],helperText:me[M.name]||M.description||""}),M.type==="boolean"&&M.description?e.jsx($,{variant:"caption",sx:{color:"#888",ml:3},children:M.description}):null]},M.name))}):e.jsx($,{variant:"body2",sx:{color:"#888"},children:"No variables defined for this assembly."})]}),h&&e.jsx($,{variant:"body2",sx:{color:"#ff4f4f",mt:1},children:h})]})]})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:t,disabled:p,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:je,disabled:O,sx:{color:O?"#666":"#58a6ff"},children:"Run"})]})]})}const mn=[{value:"ssh",label:"SSH"},{value:"winrm",label:"WinRM"}],qn={hostname:"",address:"",description:"",operating_system:""};function So({open:n,onClose:t,defaultType:o=null,onCreated:a}){const[d,u]=s.useState(o||"ssh"),[r,i]=s.useState(qn),[c,p]=s.useState(!1),[l,h]=s.useState("");s.useEffect(()=>{n&&(u(o||"ssh"),i(qn),h(""))},[n,o]);const f=()=>{c||t&&t()},y=v=>j=>{const B=j.target.value;i(R=>({...R,[v]:B}))},C=async()=>{if(c)return;const v=r.hostname.trim(),j=r.address.trim();if(!v){h("Hostname is required.");return}if(!d){h("Select a device type.");return}if(!j){h("Address is required.");return}p(!0),h("");const B={hostname:v,address:j,description:r.description.trim(),operating_system:r.operating_system.trim()},R=d==="winrm"?"/api/winrm_devices":"/api/ssh_devices";try{const x=await fetch(R,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(B)}),S=await x.json().catch(()=>({}));if(!x.ok)throw new Error((S==null?void 0:S.error)||`HTTP ${x.status}`);a&&a(S.device||null),t&&t()}catch(x){h(String(x.message||x))}finally{p(!1)}},I=o?`Add ${o.toUpperCase()} Device`:"Add Device",k=(mn.find(v=>v.value===d)||mn[0]).label;return e.jsxs(Ze,{open:n,onClose:f,fullWidth:!0,maxWidth:"sm",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:I}),e.jsxs(rt,{sx:{display:"flex",flexDirection:"column",gap:2,mt:1},children:[!o&&e.jsx(Ie,{select:!0,label:"Device Type",size:"small",value:d,onChange:v=>u(v.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}},children:mn.map(v=>e.jsx(fe,{value:v.value,children:v.label},v.value))}),e.jsx(Ie,{label:"Hostname",value:r.hostname,onChange:y("hostname"),size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}},helperText:"Name used inside Borealis."}),e.jsx(Ie,{label:`${k} Address`,value:r.address,onChange:y("address"),size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}},helperText:"IP or FQDN reachable from the Borealis server."}),e.jsx(Ie,{label:"Description",value:r.description,onChange:y("description"),size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}}}),e.jsx(Ie,{label:"Operating System",value:r.operating_system,onChange:y("operating_system"),size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}}}),l&&e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:l})]}),e.jsxs(tt,{sx:{px:3,pb:2},children:[e.jsx(Z,{onClick:f,sx:{color:"#58a6ff"},disabled:c,children:"Cancel"}),e.jsx(Z,{onClick:C,variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},disabled:c,children:c?"Saving...":"Save"})]})]})}Bn.registerModules([On]);const Co=Pn.withParams({accentColor:"#FFA6FF",backgroundColor:"#1f2836",browserColorScheme:"dark",chromeBackgroundColor:{ref:"foregroundColor",mix:.07,onto:"backgroundColor"},fontFamily:{googleFont:"IBM Plex Sans"},foregroundColor:"#FFF",headerFontSize:14}),Ki=Co.themeName||"ag-theme-quartz",Qt='"IBM Plex Sans", "Helvetica Neue", Arial, sans-serif',xn='"Quartz Regular"',Xi=n=>{const t=(n||"").toString().toLowerCase();return t?t.includes("mac")||t.includes("os x")||t.includes("darwin")?"fa-brands fa-apple":t.includes("win")?"fa-brands fa-windows":t.includes("linux")||t.includes("ubuntu")||t.includes("debian")||t.includes("fedora")||t.includes("red hat")||t.includes("centos")||t.includes("suse")||t.includes("rhel")?"fa-brands fa-linux":"":""},Qi=es.memo(function(t){const{value:o,data:a,onSaveDescription:d,fontFamily:u}=t,r=typeof o=="string"?o:o==null?"":String(o),[i,c]=s.useState(r),[p,l]=s.useState(!1),[h,f]=s.useState(!1),[y,C]=s.useState("");s.useEffect(()=>{!p&&!h&&c(r)},[r,p,h]);const I=s.useCallback(x=>{x.stopPropagation(),l(!0),C("")},[]),k=s.useCallback(x=>{c(x.target.value)},[]),v=s.useCallback(async x=>{if(x.stopPropagation(),x.key==="Enter"){x.preventDefault();const S=(i||"").trim();if(S===r.trim()){l(!1),c(r),C("");return}if(typeof d!="function"||!a){l(!1),C("");return}f(!0),C("");const z=await d(a,S);f(!1),z?l(!1):C("Failed to save description")}else x.key==="Escape"&&(x.preventDefault(),c(r),l(!1),C(""))},[a,i,d,r]),j=s.useCallback(x=>{x.stopPropagation(),!h&&(l(!1),c(r),C(""))},[h,r]),B=s.useCallback(x=>{x.stopPropagation()},[]),R=h?"rgba(255,255,255,0.04)":p?"rgba(255,255,255,0.16)":"rgba(255,255,255,0.02)";return e.jsx(Ie,{value:i,onFocus:I,onChange:k,onKeyDown:v,onBlur:j,onClick:B,onMouseDown:B,variant:"outlined",size:"small",fullWidth:!0,disabled:h,error:!!y,helperText:y||void 0,FormHelperTextProps:y?{sx:{minHeight:18,fontSize:"0.75rem"}}:{sx:{display:"none"}},sx:{mt:.5,mb:.5,"& .MuiOutlinedInput-root":{backgroundColor:R,transition:"background-color 0.2s ease, border-color 0.2s ease",color:"rgba(255,255,255,0.85)",fontFamily:u||Qt,fontSize:"0.875rem",height:34,py:0,pr:0,"& fieldset":{borderColor:p?"#FFA6FF":"rgba(255,255,255,0.25)"},"&:hover fieldset":{borderColor:"#FFA6FF"},"&.Mui-focused fieldset":{borderColor:"#FFA6FF"},"&.Mui-disabled":{backgroundColor:"rgba(255,255,255,0.08)"}},"& .MuiOutlinedInput-input":{color:"rgba(255,255,255,0.85)",py:.75,px:1.5},"& .MuiFormHelperText-root":{color:"#ff7b7b",mt:.25}},inputProps:{sx:{textOverflow:"ellipsis"}}})});function Jn(n,t=300){if(!n)return"unknown";if(Date.now()/1e3-n<=t)return"Currently Online";const a=new Date(n*1e3),d=a.toLocaleDateString("en-US",{month:"2-digit",day:"2-digit",year:"numeric"}),u=a.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"});return`${d} @ ${u}`}function Zi(n,t=300){return n&&Date.now()/1e3-n<=t?"Online":"Offline"}function Yn(n){const t=Number(n);if(!Number.isFinite(t)||t<=0)return"";const o=[],a=Math.floor(t/86400);a&&o.push(`${a}d`);const d=Math.floor(t%86400/3600);d&&o.push(`${d}h`);const u=Math.floor(t%3600/60);u&&o.push(`${u}m`);const r=Math.floor(t%60);return!o.length&&r&&o.push(`${r}s`),o.join(" ")}function _o({onSelectDevice:n,filterMode:t="all",title:o,showAddButton:a,addButtonLabel:d,defaultAddType:u}){const[r,i]=s.useState([]),[c,p]=s.useState(null),[l,h]=s.useState(null),[f,y]=s.useState(!1),[C,I]=s.useState(()=>new Set),[k,v]=s.useState(!1),[j,B]=s.useState(!1),[R,x]=s.useState(null),S=s.useMemo(()=>{if(o)return o;switch(t){case"agent":return"Agent Devices";case"ssh":return"SSH Devices";case"winrm":return"WinRM Devices";default:return"Device Inventory"}},[t,o]),z=s.useMemo(()=>u!==void 0?u:t==="ssh"||t==="winrm"?t:null,[u,t]),E=s.useMemo(()=>d||(t==="ssh"?"Add SSH Device":t==="winrm"?"Add WinRM Device":"Add Device"),[d,t]),U=s.useMemo(()=>typeof a=="boolean"?a:t!=="agent",[a,t]),[X,ue]=s.useState([]),[Se,ce]=s.useState("default"),[de,me]=s.useState(!1),[w,W]=s.useState(""),[F,te]=s.useState(!1),[ee,be]=s.useState(""),[Re,Ae]=s.useState(null),[Le,Fe]=s.useState(null),[je,V]=s.useState(null),O=s.useMemo(()=>({status:"Status",agentVersion:"Agent Version",site:"Site",hostname:"Hostname",description:"Description",lastUser:"Last User",type:"Type",os:"OS",internalIp:"Internal IP",externalIp:"External IP",lastReboot:"Last Reboot",created:"Created",lastSeen:"Last Seen",agentId:"Agent ID",agentHash:"Agent Hash",agentGuid:"Agent GUID",domain:"Domain",uptime:"Uptime",memory:"Memory",network:"Network",software:"Software",storage:"Storage",cpu:"CPU",siteDescription:"Site Description"}),[]),M=s.useMemo(()=>[{id:"status",label:O.status},{id:"agentVersion",label:O.agentVersion},{id:"site",label:O.site},{id:"hostname",label:O.hostname},{id:"description",label:O.description},{id:"lastUser",label:O.lastUser},{id:"type",label:O.type},{id:"os",label:O.os}],[O]),[g,L]=s.useState(M),[we,T]=s.useState(null),G=s.useRef(null),[ie,Ce]=s.useState({}),Ee=s.useCallback(N=>{if(!N||typeof N!="object")return{};const H={};return Object.entries(N).forEach(([Y,se])=>{if(typeof se=="string"){const ye=se.trim();ye&&(H[Y]={filterType:"text",type:"contains",filter:ye});return}if(!se||typeof se!="object")return;const ne=JSON.parse(JSON.stringify(se));ne.filterType||(ne.filterType="text"),!(ne.filterType==="text"&&(typeof ne.filter=="string"&&(ne.filter=ne.filter.trim()),Array.isArray(ne.conditions)&&(ne.conditions=ne.conditions.map(ye=>{if(!ye||typeof ye!="object")return null;const ve={...ye};return typeof ve.filter=="string"&&(ve.filter=ve.filter.trim()),!ve.filter&&!["blank","notBlank"].includes(ve.type??"")?null:ve}).filter(Boolean),ne.conditions.length||delete ne.conditions),!ne.filter&&!ne.conditions&&!["blank","notBlank"].includes(ne.type??"")))&&(H[Y]=ne)}),H},[]),Ne=s.useCallback((N,H)=>JSON.stringify(N??{})===JSON.stringify(H??{}),[]),Ke=s.useCallback(N=>{const H=N&&typeof N=="object"?Ee(N):{};Ce(Y=>Ne(Y,H)?Y:H)},[Ne,Ee]),at=s.useCallback(N=>{if(!N||typeof N!="object")return;const H=Ee(N);Object.keys(H).length&&Ce(Y=>{const se=Y||{},ne={...se};let ye=!1;return Object.entries(H).forEach(([ve,ge])=>{ge&&(!ne[ve]||!Ne(ne[ve],ge))&&(ne[ve]=ge,ye=!0)}),ye?ne:se})},[Ne,Ee]),ut=ie,[Pe,gt]=s.useState([]),[bt,vt]=s.useState(!1),[Ut,It]=s.useState(null),[yt,pt]=s.useState([]),[St,ct]=s.useState(null),oe=s.useRef(0),_e=Ki,$e=s.useCallback(async(N={})=>{const{force:H=!1}=N||{},Y=Date.now(),se=Y-oe.current;if(!H&&St&&se>=0&&se<6e4)return St;try{const ne=new URLSearchParams({repo:"bunny-lab-io/Borealis",branch:"main"});H&&ne.set("refresh","1");const ye=await fetch(`/api/repo/current_hash?${ne.toString()}`),ve=await ye.json(),ge=((ve==null?void 0:ve.sha)||"").trim();if(!ye.ok||!ge){const Me=new Error(`Latest hash status ${ye.status}${ve!=null&&ve.error?` - ${ve.error}`:""}`);throw Me.response=ve,Me}return oe.current=Y,ct(Me=>ge||Me||null),ge||null}catch(ne){return console.warn("Failed to fetch repository hash",ne),!H&&St?St:(oe.current=Y,ct(ye=>ye||null),null)}},[St]),Xe=s.useCallback((N,H)=>{const Y=(N||"").trim(),se=(H||"").trim();return se?Y&&Y===se?"Up-to-Date":"Needs Updated":"Unknown"},[]),We=s.useCallback(async(N={})=>{const{refreshRepo:H=!1}=N||{};let Y=St;if(H||!Y){const ve=await $e({force:H});ve&&(Y=ve)}const se=new Map,ne=new Map,ye=new Map;try{const ve=await fetch("/api/agent/hash_list");if(ve.ok){const ge=await ve.json();(Array.isArray(ge==null?void 0:ge.agents)?ge.agents:[]).forEach(Ve=>{if(!Ve||typeof Ve!="object")return;const it=(Ve.agent_hash||"").trim();if(!it)return;const J=(Ve.agent_id||"").trim(),Te=(Ve.agent_guid||"").trim().toLowerCase(),Ge=(Ve.hostname||"").trim().toLowerCase(),He=(Ve.source||"").trim()==="memory";J&&(!se.has(J)||He)&&se.set(J,it),Te&&(!ne.has(Te)||He)&&ne.set(Te,it),Ge&&(!ye.has(Ge)||He)&&ye.set(Ge,it)})}}catch(ve){console.warn("Failed to fetch agent hash list",ve)}try{const ve=await fetch("/api/devices");if(!ve.ok){const Te=new Error(`Failed to fetch devices (${ve.status})`);try{Te.response=await ve.json()}catch{}throw Te}const ge=await ve.json(),Me=Array.isArray(ge==null?void 0:ge.devices)?ge.devices:[],Ve=Te=>{if(!Te)return"";try{return JSON.stringify(Te)}catch{return""}},it=Me.map((Te,Ge)=>{const He=Te&&typeof Te.summary=="object"?{...Te.summary}:{},fs=(Te.hostname||He.hostname||"").trim()||`device-${Ge+1}`,zt=(Te.agent_id||He.agent_id||"").trim(),Ft=(Te.agent_guid||He.agent_guid||"").trim(),kt=Ft.toLowerCase(),qe=Ft||zt||fs||`device-${Ge+1}`;let xt=(Te.agent_hash||He.agent_hash||"").trim();zt&&se.has(zt)&&(xt=se.get(zt)||xt),!xt&&kt&&ne.has(kt)&&(xt=ne.get(kt)||xt);const ns=fs.trim().toLowerCase();!xt&&ns&&ye.has(ns)&&(xt=ye.get(ns)||xt);const hs=Number(Te.last_seen||He.last_seen||0)||0,Cs=Te.status||Zi(hs);Ft&&!He.agent_guid&&(He.agent_guid=Ft);let ms=Number(Te.created_at||0)||0,Kt=He.created||"";if(!ms&&Kt){const xs=Date.parse(Kt.replace(" ","T"));Number.isNaN(xs)||(ms=Math.floor(xs/1e3))}if(!Kt&&Te.created_at_iso)try{Kt=new Date(Te.created_at_iso).toLocaleString()}catch{}const Ws=Te.operating_system||He.operating_system||He.agent_operating_system||"-",Vs=(Te.device_type||He.device_type||"").trim(),Hs=(Te.last_user||He.last_user||"").trim(),_s=(Te.domain||He.domain||"").trim(),an=(Te.internal_ip||He.internal_ip||"").trim(),ks=(Te.external_ip||He.external_ip||"").trim(),Gs=(Te.last_reboot||He.last_reboot||"").trim(),Is=Number(Te.uptime||He.uptime_sec||He.uptime_seconds||He.uptime||0)||0,js=(Te.connection_type||He.connection_type||"").trim().toLowerCase(),Xt=js==="ssh"?"SSH":js==="winrm"?"WinRM":"",ln=(Te.connection_endpoint||He.connection_endpoint||"").trim(),Vt=Array.isArray(Te.memory)?Te.memory:[],Rs=Array.isArray(Te.network)?Te.network:[],Ns=Array.isArray(Te.software)?Te.software:[],Ts=Array.isArray(Te.storage)?Te.storage:[],As=Te.cpu&&typeof Te.cpu=="object"&&Te.cpu||(He.cpu&&typeof He.cpu=="object"?He.cpu:{}),cn=Vt.length?`${Vt.length} module(s)`:"",qs=Rs.length?Rs.map(xs=>xs.adapter||xs.name||"").filter(Boolean).join(", "):"",Js=Ns.length?`${Ns.length} item(s)`:"",dn=Ts.length?`${Ts.length} volume(s)`:"",un=As.name||He.processor||"";return{id:qe,hostname:fs,status:Cs,lastSeen:hs,lastSeenDisplay:Jn(hs),os:Ws,lastUser:Hs,type:Vs||Xt||"",site:Te.site_name||"Not Configured",siteId:Te.site_id||null,siteDescription:Te.site_description||"",description:(Te.description||He.description||"").trim(),created:Kt,createdTs:ms,createdIso:Te.created_at_iso||"",agentGuid:Ft,agentHash:xt,agentVersion:Xe(xt,Y),agentId:zt,domain:_s,internalIp:an,externalIp:ks,lastReboot:Gs,uptime:Is,uptimeDisplay:Yn(Is),memory:cn,memoryRaw:Ve(Vt),network:qs,networkRaw:Ve(Rs),software:Js,softwareRaw:Ve(Ns),storage:dn,storageRaw:Ve(Ts),cpu:un,cpuRaw:Ve(As),summary:He,details:Te.details||{},connectionType:js,connectionLabel:Xt,connectionEndpoint:ln,isRemote:!!Xt}});let J=it;t==="agent"?J=it.filter(Te=>!Te.connectionType):t==="ssh"?J=it.filter(Te=>Te.connectionType==="ssh"):t==="winrm"&&(J=it.filter(Te=>Te.connectionType==="winrm")),i(J)}catch(ve){console.warn("Failed to load devices:",ve),i([])}},[St,$e,Xe,t]),Je=s.useCallback(async()=>{try{const H=await(await fetch("/api/device_list_views")).json();H&&Array.isArray(H.views)?ue(H.views):ue([])}catch{ue([])}},[]);s.useEffect(()=>{We({refreshRepo:!0})},[We]),s.useEffect(()=>{Je()},[Je]);const ft=s.useCallback(async()=>{try{const H=await(await fetch("/api/sites")).json();gt(Array.isArray(H==null?void 0:H.sites)?H.sites:[])}catch{gt([])}},[]);s.useEffect(()=>{try{const N=localStorage.getItem("device_list_initial_filters");if(N){const Y=JSON.parse(N);Y&&typeof Y=="object"&&(at(Y),Y.site&&L(se=>{if(se.some(ge=>ge.id==="site"))return se;const ne=se.some(ge=>ge.id==="agentVersion"),ye=se.filter(ge=>!["status","agentVersion"].includes(ge.id)),ve=[{id:"status",label:O.status},...ne?[{id:"agentVersion",label:O.agentVersion}]:[],{id:"site",label:O.site}];return ne?[...ve,...ye]:ve.concat(se.filter(ge=>ge.id!=="status"))})),localStorage.removeItem("device_list_initial_filters")}const H=localStorage.getItem("device_list_initial_site_filter");H&&H.trim()&&(L(Y=>{if(Y.some(ge=>ge.id==="site"))return Y;const ne=[...Y],ye=ne.findIndex(ge=>ge.id==="agentVersion"),ve=ye>=0?ye+1:1;return ne.splice(ve,0,{id:"site",label:O.site}),ne}),at({site:H}),localStorage.removeItem("device_list_initial_site_filter"))}catch{}},[O.site,at]);const ht=s.useCallback(N=>{if(!N||N.id==="default"){L(M),Ke({});return}try{const se=["status",...(Array.isArray(N.columns)?N.columns:[]).filter(ne=>ne!=="status")].filter(ne=>O[ne]).map(ne=>({id:ne,label:O[ne]}));L(se.length?se:M),Ke(N.filters&&typeof N.filters=="object"?N.filters:{})}catch{L(M),Ke({})}},[O,M,Ke]),Jt=s.useMemo(()=>({Online:{text:"#00d18c",background:"rgba(0, 209, 140, 0.16)",border:"1px solid rgba(0, 209, 140, 0.45)",dot:"#00d18c"},Offline:{text:"#b0b8c8",background:"rgba(176, 184, 200, 0.14)",border:"1px solid rgba(176, 184, 200, 0.35)",dot:"#c3cada"},default:{text:"#e2e6f0",background:"rgba(226, 230, 240, 0.12)",border:"1px solid rgba(226, 230, 240, 0.25)",dot:"#e2e6f0"}}),[]),Ct=s.useCallback((N,H)=>{if(H){const Y=new Date(H*1e3),se=String(Y.getMonth()+1).padStart(2,"0"),ne=String(Y.getDate()).padStart(2,"0"),ye=Y.getFullYear(),ve=Y.getHours()%12||12,ge=String(Y.getMinutes()).padStart(2,"0"),Me=Y.getHours()>=12?"PM":"AM";return`${se}/${ne}/${ye} @ ${ve}:${ge} ${Me}`}return N||""},[]),Wt=s.useMemo(()=>JSON.parse(JSON.stringify(ut||{})),[ut]);s.useEffect(()=>{var N;(N=G.current)!=null&&N.api&&G.current.api.setFilterModel(Wt)},[Wt]);const lt=s.useCallback(N=>{const H=N.api.getFilterModel()||{};Ke(H)},[Ke]),Dt=s.useCallback(()=>{var se;const N=(se=G.current)==null?void 0:se.api;if(!N)return;const Y=N.getSelectedNodes().map(ne=>{var ye;return(ye=ne.data)==null?void 0:ye.id}).filter(ne=>ne!=null);I(new Set(Y))},[]),Ot=s.useCallback((N,H)=>{p(N.currentTarget),h(H)},[]),_t=s.useCallback(()=>p(null),[]),Yt=s.useCallback(()=>{_t(),y(!0)},[_t]),ss=s.useCallback(async()=>{var H;if(!l)return;const N=l.agentId||((H=l.summary)==null?void 0:H.agent_id)||l.id;try{N&&await fetch(`/api/agent/${encodeURIComponent(N)}`,{method:"DELETE"})}catch(Y){console.warn("Failed to remove agent",Y)}i(Y=>Y.filter(se=>se.id!==l.id)),I(Y=>{if(!Y.has(l.id))return Y;const se=new Set(Y);return se.delete(l.id),se}),y(!1),h(null)},[l]),A=s.useCallback(N=>{const H=N.data;if(!H)return null;const Y=ve=>{ve.preventDefault(),ve.stopPropagation(),n&&n(H)},se=H.connectionLabel||"";let ne="#2d3042",ye="#a4c7ff";return se==="SSH"?(ne="#2a3b28",ye="#7cffc4"):se==="WinRM"&&(ne="#352e3b",ye="#ffb6ff"),e.jsxs(m,{component:"span",sx:{display:"flex",alignItems:"center",gap:1},children:[se?e.jsx(m,{component:"span",sx:{display:"inline-flex",alignItems:"center",px:.75,py:.1,borderRadius:999,bgcolor:ne,color:ye,fontSize:"11px",fontWeight:600,textTransform:"uppercase"},children:se}):null,e.jsx("a",{href:"#",onClick:Y,style:{color:"#58a6ff",textDecoration:"none",fontWeight:500},children:H.hostname||""})]})},[n]),q=s.useCallback(N=>{const H=N.value||"";if(!H)return null;const Y=Jt[H]||Jt.default;return e.jsxs(m,{component:"span",sx:{display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:76,px:1.5,py:.4,borderRadius:999,backgroundColor:Y.background,border:Y.border,color:Y.text,fontWeight:600,fontSize:"13px",lineHeight:1,fontFamily:Qt,textTransform:"capitalize",gap:.75},children:[e.jsx(m,{component:"span",sx:{width:8,height:8,borderRadius:"50%",backgroundColor:Y.dot,boxShadow:"0 0 0 2px rgba(0, 0, 0, 0.22)"}}),H]})},[Jt,Qt]),le=s.useCallback(N=>{const H=N.value,Y=typeof H=="string"?H:H==null?"":String(H),se=Y.trim()||"-",ne=Xi(Y);return e.jsxs(m,{component:"span",sx:{display:"inline-flex",alignItems:"center",gap:1,color:"rgba(255,255,255,0.85)",fontFamily:Qt},children:[ne?e.jsx(m,{component:"i",className:ne,"aria-hidden":"true",sx:{fontSize:"1rem",width:"1.5rem",textAlign:"center",color:"rgba(255,255,255,0.75)"}}):null,e.jsx(m,{component:"span",sx:{lineHeight:1.3},children:se})]})},[]),he=s.useCallback(N=>{const H=N.data;if(!H)return null;const Y=se=>{se.stopPropagation(),Ot(se,H)};return e.jsx(nt,{size:"small",onClick:Y,sx:{color:"#ccc"},children:e.jsx(on,{fontSize:"small"})})},[Ot]),_=s.useCallback(async(N,H)=>{var ne;if(!N)return!1;const Y=(H||"").trim(),se=(N.hostname||((ne=N.summary)==null?void 0:ne.hostname)||"").trim();if(!se)return!1;try{const ye=await fetch(`/api/device/description/${se}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:Y})});if(!ye.ok)throw new Error(`HTTP ${ye.status}`);const ve=N.id||N.agentGuid||N.hostname||se;return i(ge=>ge.map(Me=>{if((Me.id||Me.agentGuid||Me.hostname||"")!==ve)return Me;const it={...Me,description:Y,summary:{...Me.summary||{},description:Y}};return Me.details&&(it.details={...Me.details,description:Y}),it})),h(ge=>{if(!ge||(ge.id||ge.agentGuid||ge.hostname||"")!==ve)return ge;const Ve={...ge,description:Y,summary:{...ge.summary||{},description:Y}};return ge.details&&(Ve.details={...ge.details,description:Y}),Ve}),!0}catch(ye){return console.warn("Failed to save description",ye),!1}},[i,h]),K=s.useMemo(()=>{const N=g.map(H=>{switch(H.id){case"status":return{field:"status",headerName:H.label,cellRenderer:q,cellClass:"status-pill-cell",width:112,minWidth:112,flex:0};case"agentVersion":return{field:"agentVersion",headerName:H.label,width:140,minWidth:150,flex:0};case"site":return{field:"site",headerName:H.label,valueGetter:Y=>{var se;return((se=Y.data)==null?void 0:se.site)||"Not Configured"},width:140,minWidth:140,flex:0};case"hostname":return{field:"hostname",headerName:H.label,cellRenderer:A,width:210,minWidth:210,flex:0};case"description":return{field:"description",headerName:H.label,width:280,minWidth:280,flex:0,cellRenderer:Qi,cellRendererParams:{onSaveDescription:_,fontFamily:Qt}};case"lastUser":return{field:"lastUser",headerName:H.label,width:220,minWidth:220,flex:0};case"type":return{field:"type",headerName:H.label,width:170,minWidth:170,flex:0};case"os":return{field:"os",headerName:H.label,width:410,minWidth:410,flex:1,cellRenderer:le};case"internalIp":return{field:"internalIp",headerName:H.label,width:140,minWidth:140,flex:0};case"externalIp":return{field:"externalIp",headerName:H.label,width:140,minWidth:140,flex:0};case"lastReboot":return{field:"lastReboot",headerName:H.label,width:180,minWidth:180,flex:0};case"created":return{field:"created",headerName:H.label,valueGetter:Y=>{var se,ne;return Ct((se=Y.data)==null?void 0:se.created,(ne=Y.data)==null?void 0:ne.createdTs)},comparator:(Y,se,ne,ye)=>{var ve,ge;return(((ve=ne==null?void 0:ne.data)==null?void 0:ve.createdTs)||0)-(((ge=ye==null?void 0:ye.data)==null?void 0:ge.createdTs)||0)},width:200,minWidth:200,flex:0};case"lastSeen":return{field:"lastSeen",headerName:H.label,valueGetter:Y=>{var se;return Jn((se=Y.data)==null?void 0:se.lastSeen)},comparator:(Y,se,ne,ye)=>{var ve,ge;return(((ve=ne==null?void 0:ne.data)==null?void 0:ve.lastSeen)||0)-(((ge=ye==null?void 0:ye.data)==null?void 0:ge.lastSeen)||0)},width:200,minWidth:200,flex:0};case"agentId":return{field:"agentId",headerName:H.label,width:290,minWidth:290,flex:0};case"agentHash":return{field:"agentHash",headerName:H.label,width:365,minWidth:365,flex:0};case"agentGuid":return{field:"agentGuid",headerName:H.label,width:345,minWidth:345,flex:0};case"domain":return{field:"domain",headerName:H.label,width:160,minWidth:160,flex:0};case"uptime":return{field:"uptime",headerName:H.label,valueGetter:Y=>{var se,ne;return((se=Y.data)==null?void 0:se.uptimeDisplay)||Yn(((ne=Y.data)==null?void 0:ne.uptime)||0)},comparator:(Y,se,ne,ye)=>{var ve,ge;return(((ve=ne==null?void 0:ne.data)==null?void 0:ve.uptime)||0)-(((ge=ye==null?void 0:ye.data)==null?void 0:ge.uptime)||0)},width:140,minWidth:140,flex:0};case"memory":case"network":case"software":case"storage":case"cpu":case"siteDescription":return{field:H.id,headerName:H.label,minWidth:200};default:return{field:H.id,headerName:H.label}}});return[{headerName:"",field:"__select__",width:52,maxWidth:52,checkboxSelection:!0,headerCheckboxSelection:!0,resizable:!1,sortable:!1,suppressMenu:!0,filter:!1,pinned:"left",lockPosition:!0},...N,{headerName:"",field:"__actions__",width:64,maxWidth:64,resizable:!1,sortable:!1,suppressMenu:!0,filter:!1,cellRenderer:he,pinned:"right"}]},[g,he,Ct,_,A,q]),pe=s.useMemo(()=>({sortable:!0,filter:"agTextColumnFilter",resizable:!0,flex:1,minWidth:160}),[]),re=s.useCallback(N=>{N.api.setFilterModel(Wt)},[Wt]),ke=s.useCallback(N=>{var H,Y,se;return((H=N.data)==null?void 0:H.id)||((Y=N.data)==null?void 0:Y.agentGuid)||((se=N.data)==null?void 0:se.hostname)||String(N.rowIndex??"")},[]);return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e",fontFamily:Qt,color:"#f5f7fa",display:"flex",flexDirection:"column",flexGrow:1,minWidth:0,height:"100%"},elevation:2,children:[e.jsxs(m,{sx:{p:2,pb:1,display:"flex",flexDirection:"column",gap:1},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:S}),e.jsxs(m,{sx:{display:"flex",alignItems:"center"},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",mr:1},children:[e.jsxs(Ie,{select:!0,size:"small",value:Se,onChange:N=>{const H=N.target.value;if(ce(H),H==="default")ht({id:"default"});else{const Y=X.find(se=>String(se.id)===String(H));Y&&ht(Y)}},sx:{minWidth:220,mr:0,"& .MuiOutlinedInput-root":{height:32,pr:0,borderTopRightRadius:0,borderBottomRightRadius:0,"& fieldset":{borderColor:"#555",borderRight:"1px solid #555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiSelect-select":{display:"flex",alignItems:"center",py:0}},SelectProps:{MenuProps:{PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff"}}},renderValue:N=>{if(N==="default")return"Default View";const H=X.find(Y=>String(Y.id)===String(N));return H?H.name:"Default View"}},children:[e.jsx(fe,{value:"default",children:"Default View"}),X.map(N=>e.jsx(fe,{value:N.id,disableRipple:!0,children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%"},children:[e.jsx("span",{children:N.name}),e.jsx(nt,{size:"small",onClick:H=>{H.stopPropagation(),Fe(H.currentTarget),V(N)},sx:{color:"#ccc"},children:e.jsx(on,{fontSize:"small"})})]})},N.id))]}),e.jsx(nt,{size:"small",onClick:()=>{W(""),me(!0)},sx:{ml:"-1px",border:"1px solid #555",borderLeft:"1px solid #555",borderRadius:"0 4px 4px 0",color:"#bbb",height:32,width:32},children:e.jsx(ts,{fontSize:"small"})})]}),e.jsx(st,{title:"Refresh Devices to Detect Changes",children:e.jsx(nt,{size:"small",onClick:()=>We({refreshRepo:!0}),sx:{color:"#bbb",mr:1},children:e.jsx(rr,{fontSize:"small"})})}),e.jsx(st,{title:"Column Chooser",children:e.jsx(nt,{size:"small",onClick:N=>T(N.currentTarget),sx:{color:"#bbb",mr:1},children:e.jsx(ar,{fontSize:"small"})})}),U&&e.jsx(Z,{variant:"contained",size:"small",startIcon:e.jsx(ts,{}),sx:{bgcolor:"#58a6ff",color:"#0b0f19"},onClick:()=>{x(z??null),B(!0)},children:E})]})]}),e.jsx(m,{sx:{display:"flex",gap:1},children:e.jsx(Z,{variant:"outlined",size:"small",disabled:C.size===0,onClick:()=>v(!0),sx:{color:C.size===0?"#666":"#58a6ff",borderColor:C.size===0?"#333":"#58a6ff",textTransform:"none"},children:"Quick Job"})})]}),e.jsx(m,{sx:{mt:"10px",px:2,pb:2,flexGrow:1,minHeight:0,display:"flex",flexDirection:"column"},children:e.jsx(m,{className:_e,sx:{width:"100%",flexGrow:1,minHeight:0,height:"100%",fontFamily:Qt,"--ag-font-family":Qt,"--ag-icon-font-family":xn,"& .ag-root-wrapper":{borderRadius:1,minHeight:400},"& .ag-root, & .ag-header, & .ag-center-cols-container, & .ag-paging-panel":{fontFamily:Qt},"& .ag-icon":{fontFamily:xn},"& .status-pill-cell":{display:"flex",alignItems:"center"},"& .status-pill-cell .ag-cell-wrapper":{width:"100%",display:"flex",alignItems:"center",justifyContent:"center",height:"100%",paddingTop:0,paddingBottom:0,lineHeight:"normal"},"& .status-pill-cell .ag-cell-value":{width:"100%",display:"flex",justifyContent:"center",alignItems:"center",height:"100%"},"& .status-pill-cell .ag-cell-value > span":{margin:0}},children:e.jsx(An,{ref:G,rowData:r,columnDefs:K,defaultColDef:pe,rowSelection:"multiple",rowMultiSelectWithClick:!0,pagination:!0,paginationPageSize:25,animateRows:!0,onSelectionChanged:Dt,onFilterChanged:lt,onGridReady:re,getRowId:ke,theme:Co,style:{width:"100%",height:"100%",fontFamily:Qt,"--ag-icon-font-family":xn}})})}),e.jsxs(Et,{anchorEl:Le,open:!!Le,onClose:()=>{Fe(null),V(null)},PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[e.jsx(fe,{onClick:()=>{const N=je;Fe(null),N&&(Ae(N),be(N.name||""),te(!0))},children:"Rename"}),e.jsx(fe,{sx:{color:"#ff4f4f"},onClick:async()=>{const N=je;if(Fe(null),!!N){try{await fetch(`/api/device_list_views/${encodeURIComponent(N.id)}`,{method:"DELETE"})}catch{}ue(H=>H.filter(Y=>String(Y.id)!==String(N.id))),String(Se)===String(N.id)&&(ce("default"),ht({id:"default"}))}},children:"Delete"})]}),e.jsx(Pi,{open:de,value:w,onChange:W,onCancel:()=>me(!1),onSave:async()=>{const N=(w||"").trim();if(!N)return;const H=(g||[]).map(se=>se.id),Y={name:N,columns:H,filters:ut};try{const se=await fetch("/api/device_list_views",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(Y)});if(se.ok){const ne=await se.json();ue(ye=>[...ye,ne].sort((ve,ge)=>String(ve.name).localeCompare(String(ge.name)))),ce(String(ne.id)),me(!1),W("")}}catch{}}}),e.jsx(Ei,{open:F,value:ee,onChange:be,onCancel:()=>te(!1),onSave:async()=>{const N=Re,H=(ee||"").trim();if(!(!N||!H))try{const Y=await fetch(`/api/device_list_views/${encodeURIComponent(N.id)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:H})});if(Y.ok){const se=await Y.json();ue(ne=>ne.map(ye=>String(ye.id)===String(N.id)?se:ye)),te(!1),be(""),Ae(null)}}catch{}}}),e.jsx(Ls,{open:!!we,anchorEl:we,onClose:()=>T(null),anchorOrigin:{vertical:"bottom",horizontal:"right"},PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",p:1}},children:e.jsxs(m,{sx:{display:"flex",flexDirection:"column",gap:.5,p:1},children:[Object.entries(O).filter(([N])=>N!=="status").map(([N,H])=>e.jsxs(fe,{disableRipple:!0,onClick:Y=>Y.stopPropagation(),sx:{gap:1},children:[e.jsx(At,{size:"small",checked:g.some(Y=>Y.id===N),onChange:Y=>{const se=Y.target.checked;L(ne=>{const ye=ne.some(ve=>ve.id===N);if(se){if(ye)return ne;const ve=O[N]||H||N;return[...ne,{id:N,label:ve}]}return ne.filter(ve=>ve.id!==N)})},sx:{p:.3,color:"#bbb"}}),e.jsx($,{variant:"body2",sx:{color:"#ddd"},children:H||N})]},N)),e.jsx(m,{sx:{display:"flex",gap:1,pt:.5},children:e.jsx(Z,{size:"small",variant:"outlined",onClick:()=>L(M),sx:{textTransform:"none",borderColor:"#555",color:"#bbb"},children:"Reset Default"})})]})}),e.jsxs(Et,{anchorEl:c,open:!!c,onClose:_t,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[e.jsx(fe,{onClick:async()=>{_t(),await ft();const N=new Set(C);l&&!N.has(l.id)&&N.add(l.id);const H=new Map(r.map(se=>[se.id,se.hostname])),Y=Array.from(N).map(se=>H.get(se)).filter(Boolean);pt(Y),It(null),vt(!0)},children:"Add to Site"}),e.jsx(fe,{onClick:async()=>{_t(),await ft();const N=new Set(C);l&&!N.has(l.id)&&N.add(l.id);const H=new Map(r.map(se=>[se.id,se.hostname])),Y=Array.from(N).map(se=>H.get(se)).filter(Boolean);pt(Y),It(null),vt(!0)},children:"Move to Another Site"}),e.jsx(fe,{onClick:Yt,sx:{color:"#ff8a8a"},children:"Delete"})]}),e.jsx(Bi,{open:f,onCancel:()=>y(!1),onConfirm:ss}),k&&e.jsx(vo,{open:k,onClose:()=>v(!1),hostnames:r.filter(N=>C.has(N.id)).map(N=>N.hostname)}),bt&&e.jsx(Ls,{open:bt,onClose:()=>vt(!1),anchorReference:"anchorPosition",anchorPosition:{top:Math.max(Math.floor(window.innerHeight*.5),200),left:Math.max(Math.floor(window.innerWidth*.5),300)},PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",p:2,minWidth:360}},children:e.jsxs(m,{sx:{display:"flex",flexDirection:"column",gap:1},children:[e.jsxs($,{variant:"subtitle1",children:["Assign ",yt.length," device(s) to a site"]}),e.jsx(Ie,{select:!0,size:"small",label:"Select Site",value:Ut??"",onChange:N=>It(Number(N.target.value)),sx:{"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"}},children:Pe.map(N=>e.jsx(fe,{value:N.id,children:N.name},N.id))}),e.jsxs(m,{sx:{display:"flex",justifyContent:"flex-end",gap:1},children:[e.jsx(Z,{variant:"outlined",size:"small",onClick:()=>vt(!1),sx:{textTransform:"none",borderColor:"#555",color:"#bbb"},children:"Cancel"}),e.jsx(Z,{variant:"outlined",size:"small",disabled:!Ut||yt.length===0,onClick:async()=>{try{await fetch("/api/sites/assign",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({site_id:Ut,hostnames:yt})})}catch{}vt(!1);try{const N=r.map(ne=>ne.hostname).filter(Boolean).map(encodeURIComponent).join(","),Y=await(await fetch(`/api/sites/device_map?hostnames=${N}`)).json(),se=(Y==null?void 0:Y.mapping)||{};setSiteMapping(se),i(ne=>ne.map(ye=>{var ve;return{...ye,site:((ve=se[ye.hostname])==null?void 0:ve.site_name)||"Not Configured"}}))}catch{}},sx:{textTransform:"none",borderColor:"#58a6ff",color:"#58a6ff"},children:"Assign"})]})]})}),e.jsx(So,{open:j,defaultType:R,onClose:()=>{B(!1),x(z??null)},onCreated:()=>{B(!1),x(z??null),We({refreshRepo:!0})}})]})}function el({device:n,onBack:t}){const[o,a]=s.useState(0),[d,u]=s.useState(n||{}),[r,i]=s.useState({}),[c,p]=s.useState({}),[l,h]=s.useState("name"),[f,y]=s.useState("asc"),[C,I]=s.useState(""),[k,v]=s.useState(""),[j,B]=s.useState(""),[R,x]=s.useState(""),[S,z]=s.useState(""),[E,U]=s.useState(!1),[X,ue]=s.useState(""),[Se,ce]=s.useState(""),[de,me]=s.useState([]),[w,W]=s.useState("ran_at"),[F,te]=s.useState("desc"),[ee,be]=s.useState(!1),[Re,Ae]=s.useState(""),[Le,Fe]=s.useState(""),[je,V]=s.useState("powershell"),[O,M]=s.useState(!1),[g,L]=s.useState(null),[we,T]=s.useState(!1),[G,ie]=s.useState({}),[Ce,Ee]=s.useState(()=>{if(n!=null&&n.status)return n.status;const _=n==null?void 0:n.lastSeen;return _&&Date.now()/1e3-_<=300?"Online":"Offline"});s.useEffect(()=>{ce("")},[S]),s.useEffect(()=>{j!=="ssh"&&(ue(""),ce(""))},[j]),s.useEffect(()=>{let _=!1;return(async()=>{const pe={},re=(N,H,Y="")=>{const se=typeof H=="string"?H.trim():"";if(!se)return;const ne=String(N||"").replace(/\\/g,"/").replace(/^\/+/,"").trim(),ye=new Set;if(ne&&(ye.add(ne),Y)){const ge=`${Y}/${ne}`.replace(/\/+/g,"/");ye.add(ge)}const ve=ne&&ne.split("/").pop()||"";if(ve){ye.add(ve);const ge=ve.lastIndexOf(".");ge>0&&ye.add(ve.slice(0,ge))}ye.forEach(ge=>{ge&&!pe[ge]&&(pe[ge]=se)})},ke=async(N,H="")=>{try{const Y=await fetch(`/api/assembly/list?island=${N}`);if(!Y.ok)return;const se=await Y.json();(Array.isArray(se.items)?se.items:[]).forEach(ye=>{if(!ye||typeof ye!="object")return;const ve=ye.rel_path||ye.path||ye.file_name||ye.playbook_path||"",ge=(ye.name||ye.tab_name||ye.display_name||ye.file_name||"").trim();re(ve,ge,H)})}catch{}};await ke("scripts","Scripts"),await ke("workflows","Workflows"),await ke("ansible","Ansible_Playbooks"),_||ie(pe)})(),()=>{_=!0}},[]);const Ne=(_,K=300)=>_&&Date.now()/1e3-_<=K?"Online":"Offline",Ke=_=>_==="Online"?"#00d18c":"#ff4f4f",at=s.useCallback((_,K)=>{const pe=String(K||"").replace(/\\/g,"/").trim(),re=pe&&pe.split("/").pop()||"",ke=re&&re.includes(".")?re.slice(0,re.lastIndexOf(".")):re;return G[pe]||(re?G[re]:"")||(ke?G[ke]:"")||_||re||K||""},[G]),ut=(_,K=120)=>{if(!_)return"unknown";if(Date.now()/1e3-_<=K)return"Currently Online";const re=new Date(_*1e3),ke=re.toLocaleDateString("en-US",{month:"2-digit",day:"2-digit",year:"numeric"}),N=re.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"});return`${ke} @ ${N}`};s.useEffect(()=>{var ke,N,H;n&&Ee(n.status||Ne(n.lastSeen));const _=(n==null?void 0:n.agent_guid)||(n==null?void 0:n.guid)||(n==null?void 0:n.agentGuid)||((ke=n==null?void 0:n.summary)==null?void 0:ke.agent_guid),K=(n==null?void 0:n.agentId)||((N=n==null?void 0:n.summary)==null?void 0:N.agent_id)||(n==null?void 0:n.id),pe=(n==null?void 0:n.hostname)||((H=n==null?void 0:n.summary)==null?void 0:H.hostname);if(!n||!_&&!pe)return;(async()=>{var Y,se,ne,ye,ve,ge;try{const Me=fetch("/api/agents").catch(()=>null);let Ve=null;if(_)try{Ve=await fetch(`/api/devices/${encodeURIComponent(_)}`)}catch{Ve=null}if((!Ve||!Ve.ok)&&pe)try{Ve=await fetch(`/api/device/details/${encodeURIComponent(pe)}`)}catch{Ve=null}if(!Ve||!Ve.ok)throw new Error(`Failed to load device record (${Ve?Ve.status:"no response"})`);const[it,J]=await Promise.all([Me==null?void 0:Me.then(qe=>qe?qe.json():{}).catch(()=>({})),Ve.json()]);it&&K&&it[K]&&u({id:K,...it[K]});const Ge={...(J!=null&&J.summary&&typeof J.summary=="object"?J.summary:((Y=J==null?void 0:J.details)==null?void 0:Y.summary)||{})||{}};J!=null&&J.description&&(Ge.description=J.description);const He=(Ge.connection_type||Ge.remote_type||"").toLowerCase(),us=Ge.connection_endpoint||Ge.connection_address||(J==null?void 0:J.connection_endpoint)||"";B(He),x(us),z(us),ue(""),ce("");const fs={summary:Ge,memory:Array.isArray(J==null?void 0:J.memory)?J.memory:Array.isArray((se=J==null?void 0:J.details)==null?void 0:se.memory)?J.details.memory:[],network:Array.isArray(J==null?void 0:J.network)?J.network:Array.isArray((ne=J==null?void 0:J.details)==null?void 0:ne.network)?J.details.network:[],software:Array.isArray(J==null?void 0:J.software)?J.software:Array.isArray((ye=J==null?void 0:J.details)==null?void 0:ye.software)?J.details.software:[],storage:Array.isArray(J==null?void 0:J.storage)?J.storage:Array.isArray((ve=J==null?void 0:J.details)==null?void 0:ve.storage)?J.details.storage:[],cpu:(J==null?void 0:J.cpu)||((ge=J==null?void 0:J.details)==null?void 0:ge.cpu)||{}};i(fs);const zt=qe=>{if(!qe||Number.isNaN(qe.getTime()))return"";const xt=ns=>String(ns).padStart(2,"0");return`${qe.getUTCFullYear()}-${xt(qe.getUTCMonth()+1)}-${xt(qe.getUTCDate())} ${xt(qe.getUTCHours())}:${xt(qe.getUTCMinutes())}:${xt(qe.getUTCSeconds())}`};let Ft=Ge.created||"";Ft||(J!=null&&J.created_at&&Number(J.created_at)?Ft=zt(new Date(Number(J.created_at)*1e3)):J!=null&&J.created_at_iso&&(Ft=zt(new Date(J.created_at_iso))));const kt={hostname:(J==null?void 0:J.hostname)||Ge.hostname||pe||"",lastUser:(J==null?void 0:J.last_user)||Ge.last_user||"",deviceType:(J==null?void 0:J.device_type)||Ge.device_type||"",created:Ft,createdAtIso:(J==null?void 0:J.created_at_iso)||"",lastSeen:(J==null?void 0:J.last_seen)||Ge.last_seen||0,lastReboot:(J==null?void 0:J.last_reboot)||Ge.last_reboot||"",operatingSystem:(J==null?void 0:J.operating_system)||Ge.operating_system||Ge.agent_operating_system||"",agentId:(J==null?void 0:J.agent_id)||Ge.agent_id||K||"",agentGuid:(J==null?void 0:J.agent_guid)||Ge.agent_guid||_||"",agentHash:(J==null?void 0:J.agent_hash)||Ge.agent_hash||"",internalIp:(J==null?void 0:J.internal_ip)||Ge.internal_ip||"",externalIp:(J==null?void 0:J.external_ip)||Ge.external_ip||"",siteId:J==null?void 0:J.site_id,siteName:(J==null?void 0:J.site_name)||"",siteDescription:(J==null?void 0:J.site_description)||"",status:(J==null?void 0:J.status)||"",connectionType:He,connectionEndpoint:us};p(kt),v(Ge.description||(J==null?void 0:J.description)||""),u(qe=>({...qe||{},id:K||(qe==null?void 0:qe.id),hostname:kt.hostname||(qe==null?void 0:qe.hostname),agent_hash:kt.agentHash||(qe==null?void 0:qe.agent_hash),agent_operating_system:kt.operatingSystem||(qe==null?void 0:qe.agent_operating_system),device_type:kt.deviceType||(qe==null?void 0:qe.device_type),last_seen:kt.lastSeen||(qe==null?void 0:qe.last_seen)})),kt.status?Ee(kt.status):kt.lastSeen&&Ee(Ne(kt.lastSeen))}catch(Me){console.warn("Failed to load device info",Me),p({})}})()},[n]);const Pe=s.useMemo(()=>((c==null?void 0:c.hostname)||(d==null?void 0:d.hostname)||(n==null?void 0:n.hostname)||"").trim(),[c==null?void 0:c.hostname,d==null?void 0:d.hostname,n==null?void 0:n.hostname]),gt=s.useCallback(async()=>{var pe;if(j!=="ssh")return;const _=Pe;if(!_)return;const K=S.trim();if(!K){ce("Address is required.");return}if(K===R.trim()){ue("No changes to save.");return}U(!0),ce(""),ue("");try{const re=await fetch(`/api/ssh_devices/${encodeURIComponent(_)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({address:K})}),ke=await re.json().catch(()=>({}));if(!re.ok)throw new Error((ke==null?void 0:ke.error)||`HTTP ${re.status}`);const N=((pe=ke==null?void 0:ke.device)==null?void 0:pe.connection_endpoint)||K;x(N),z(N),p(H=>({...H||{},connectionEndpoint:N})),ue("SSH endpoint updated."),setTimeout(()=>ue(""),3e3)}catch(re){ce(String(re.message||re))}finally{U(!1)}},[j,S,R,Pe]),bt=s.useCallback(async()=>{if(Pe)try{const _=await fetch(`/api/device/activity/${encodeURIComponent(Pe)}`);if(!_.ok)throw new Error(`HTTP ${_.status}`);const K=await _.json();me(K.history||[])}catch(_){console.warn("Failed to load activity history",_),me([])}},[Pe]);s.useEffect(()=>{bt()},[bt]),s.useEffect(()=>{const _=typeof window<"u"?window.BorealisSocket:null;if(!_||!Pe)return;let K=null;const pe=Pe.toLowerCase(),re=(N=200)=>{K&&clearTimeout(K),K=setTimeout(()=>{K=null,bt()},N)},ke=(N={})=>{const H=String((N==null?void 0:N.hostname)||"").trim().toLowerCase();if(H&&H===pe){const Y=(N==null?void 0:N.change)==="updated"?150:0;re(Y)}};return _.on("device_activity_changed",ke),()=>{K&&clearTimeout(K),_.off("device_activity_changed",ke)}},[Pe,bt]);const vt=async()=>{if(Pe)try{const _=await fetch(`/api/device/activity/${encodeURIComponent(Pe)}`,{method:"DELETE"});if(!_.ok)throw new Error(`HTTP ${_.status}`);me([])}catch(_){console.warn("Failed to clear activity history",_)}},Ut=async()=>{var K;const _=c.hostname||((K=r.summary)==null?void 0:K.hostname);if(_)try{await fetch(`/api/device/description/${_}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:k})}),i(pe=>({...pe,summary:{...pe.summary||{},description:k}})),p(pe=>({...pe||{},hostname:_}))}catch(pe){console.warn("Failed to save description",pe)}},It=_=>{if(!_)return"unknown";try{const[K,pe]=_.split(" "),[re,ke,N]=K.split("-").map(Number);let[H,Y,se]=pe.split(":").map(Number);const ne=H>=12?"PM":"AM";return H=H%12||12,`${ke.toString().padStart(2,"0")}/${N.toString().padStart(2,"0")}/${re} @ ${H}:${Y.toString().padStart(2,"0")} ${ne}`}catch{return _}},yt=_=>_?_.replace(/-/g,":").toUpperCase():"unknown",pt=_=>{if(_==null||_==="unknown")return"unknown";let K=Number(_);const pe=["B","KB","MB","GB","TB"];let re=0;for(;K>=1024&&re<pe.length-1;)K/=1024,re++;return`${K.toFixed(1)} ${pe[re]}`},St=_=>{const K=Number(_||0);if(!K)return"unknown";const pe=new Date(K*1e3),re=String(pe.getMonth()+1).padStart(2,"0"),ke=String(pe.getDate()).padStart(2,"0"),N=pe.getFullYear();let H=pe.getHours();const Y=H>=12?"PM":"AM";H=H%12||12;const se=String(pe.getMinutes()).padStart(2,"0");return`${re}/${ke}/${N} @ ${H}:${se} ${Y}`},ct=_=>{l===_?y(f==="asc"?"desc":"asc"):(h(_),y("asc"))},oe=s.useMemo(()=>{const K=(r.software||[]).filter(re=>re.name.toLowerCase().includes(C.toLowerCase())),pe=f==="asc"?1:-1;return[...K].sort((re,ke)=>{const N=re[l]||"",H=ke[l]||"";return String(N).localeCompare(String(H))*pe})},[r.software,C,l,f]),_e=r.summary||{},$e=s.useMemo(()=>{const _=r.cpu||_e.cpu||{},K=_.logical_cores||_.cores||_.physical_cores;let pe=_.base_clock_ghz;if(!pe&&typeof(_e.processor||"")=="string"){const H=String(_e.processor).match(/\(([^)]*?)ghz\)/i);if(H&&H[1]){const Y=parseFloat(H[1]);Number.isNaN(Y)||(pe=Y)}}const re=(_.name||"").trim(),N=(_e.processor||"").trim()||[re,pe?`(${Number(pe).toFixed(1)}GHz)`:null,K?`@ ${K} Cores`:null].filter(Boolean).join(" ");return{cores:K,ghz:pe,name:re,display:N}},[_e]),Xe=[{label:"Hostname",value:c.hostname||_e.hostname||d.hostname||(n==null?void 0:n.hostname)||"unknown"},{label:"Last User",value:e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(m,{component:"span",sx:{display:"inline-block",width:10,height:10,borderRadius:10,bgcolor:d!=null&&d.collector_active?"#00d18c":"#ff4f4f"}}),e.jsx("span",{children:c.lastUser||_e.last_user||"unknown"})]})},{label:"Device Type",value:c.deviceType||_e.device_type||"unknown"},{label:"Created",value:c.created?It(c.created):_e.created?It(_e.created):"unknown"},{label:"Last Seen",value:ut(c.lastSeen||d.last_seen||(n==null?void 0:n.lastSeen))},{label:"Last Reboot",value:c.lastReboot?It(c.lastReboot):_e.last_reboot?It(_e.last_reboot):"unknown"},{label:"Operating System",value:c.operatingSystem||_e.operating_system||d.agent_operating_system||"unknown"},{label:"Agent ID",value:c.agentId||_e.agent_id||"unknown"},{label:"Agent GUID",value:c.agentGuid||_e.agent_guid||"unknown"},{label:"Agent Hash",value:c.agentHash||_e.agent_hash||"unknown"}],We=({icon:_,title:K,main:pe,sub:re,color:ke})=>{const N=ke||"#232323",H=ne=>{const ye=String(ne||"").replace("#",""),ve=parseInt(ye.length===3?ye.split("").map(ge=>ge+ge).join(""):ye,16);return{r:ve>>16&255,g:ve>>8&255,b:ve&255}},Y=(ne,ye=1)=>{try{const{r:ve,g:ge,b:Me}=H(ne);return`rgba(${ve}, ${ge}, ${Me}, ${ye})`}catch{return`rgba(88,166,255, ${ye})`}},se=(ne,ye=.5,ve=1)=>{try{const{r:ge,g:Me,b:Ve}=H(ne),it=He=>Math.round(He+(255-He)*ye),J=it(ge),Te=it(Me),Ge=it(Ve);return`rgba(${J}, ${Te}, ${Ge}, ${ve})`}catch{return Y("#58a6ff",ve)}};return e.jsxs(Qe,{elevation:0,sx:{px:2,py:1.5,borderRadius:2,position:"relative",color:"#fff",minWidth:260,border:"1px solid #2f2f2f",background:`linear-gradient(90deg, rgba(88,166,255,0.12) 0%, rgba(88,166,255,0.06) 55%, rgba(88,166,255,0) 100%), ${N}`,boxShadow:`inset 0 0 0 1px ${se(N,.35,.6)}`},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,mb:1},children:[_,e.jsx($,{variant:"caption",sx:{opacity:.95,fontWeight:700},children:K})]}),e.jsx($,{variant:"h6",sx:{lineHeight:1.2,mb:1},children:pe}),e.jsx(m,{sx:{flexGrow:1,minHeight:12}}),e.jsx(m,{sx:{minHeight:8}}),re?e.jsx($,{variant:"body2",sx:{opacity:.85},children:re}):null]})},Je=({title:_,children:K,sx:pe})=>e.jsxs(Qe,{elevation:0,sx:{p:1.5,borderRadius:2,bgcolor:"#1c1c1c",border:"1px solid #2a2a2a",mb:1.5,...pe||{}},children:[e.jsx($,{variant:"caption",sx:{color:"#58a6ff",fontWeight:400,fontSize:"14px",letterSpacing:.2,display:"block",mb:1},children:_}),K]}),ft=()=>{const _=($e.name||_e.processor||""||"").split(`
`)[0]||"Unknown CPU",K=$e.ghz||$e.cores?e.jsxs("span",{children:[$e.ghz?`${Number($e.ghz).toFixed(2)}GHz `:"",$e.cores?e.jsxs("span",{style:{opacity:.75},children:["(",$e.cores,"-Cores)"]}):null]}):"";let pe=_e.total_ram;if(!pe&&Array.isArray(r.memory))try{pe=r.memory.reduce((ge,Me)=>ge+(Number(Me.capacity||0)||0),0)}catch{}const re=pe?`${pt(pe)}`:"Unknown";let ke="";try{const ge=(r.memory||[]).map(Me=>parseInt(String(Me.speed||"").replace(/[^0-9]/g,""),10)).filter(Me=>!Number.isNaN(Me)&&Me>0);ge.length&&(ke=`Speed: ${Math.max(...ge)} MT/s`)}catch{}let N=null;Array.isArray(r.storage)&&(N=r.storage.find(ge=>String(ge.drive||"").toUpperCase().startsWith("C:"))||r.storage[0]||null);const H=N&&N.total!=null?`${pt(N.total)}`:"Unknown",Y=N&&N.used!=null&&N.total!=null?`${pt(N.used)} of ${pt(N.total)} used`:N&&N.free!=null&&N.total!=null?`${pt(N.total-N.free)} of ${pt(N.total)} used`:"",se=(_e.internal_ip||"").trim();let ne=null;Array.isArray(r.network)&&(ne=r.network.find(ge=>(ge.ips||[]).includes(se))||r.network[0]||null);function ye(ge){const Me=String(ge||"").trim();if(!Me)return"unknown";const Ve=Me.toLowerCase();if(Ve.includes("gbps")||Ve.includes("mbps"))return Me;const it=Ve.match(/(\d+\.?\d*)\s*([gmk]?)(bps)/);if(!it)return Me;let J=parseFloat(it[1]);const Te=it[2];return Te==="g"?`${J} Gbps`:Te==="m"?`${J} Mbps`:Te==="k"?`${(J/1e3).toFixed(1)} Mbps`:J>=1e9?`${(J/1e9).toFixed(1)} Gbps`:J>=1e6?`${(J/1e6).toFixed(0)} Mbps`:Me}const ve=ne?ye(ne.link_speed||ne.speed):"Unknown";return e.jsxs(m,{children:[e.jsxs(m,{sx:{display:"grid",gridTemplateColumns:"repeat( auto-fit, minmax(260px, 1fr) )",gap:1.5,mb:2},children:[e.jsx(We,{icon:e.jsx(lr,{sx:{fontSize:32,opacity:.95}}),title:"Processor",main:_,sub:K,color:"#132332"}),e.jsx(We,{icon:e.jsx(cr,{sx:{fontSize:32,opacity:.95}}),title:"Installed RAM",main:re,sub:ke||" ",color:"#291a2e"}),e.jsx(We,{icon:e.jsx(dr,{sx:{fontSize:32,opacity:.95}}),title:"Storage",main:H,sub:Y||" ",color:"#142616"}),e.jsx(We,{icon:e.jsx(ur,{sx:{fontSize:32,opacity:.95}}),title:"Network",main:ve,sub:ne&&ne.adapter?ne.adapter:" ",color:"#2b1a18"})]}),e.jsxs(m,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",md:"1.2fr 1fr 1fr"},gap:2},children:[e.jsx(Je,{title:"Device Summary",children:e.jsx(m,{children:e.jsx(Rt,{size:"small",children:e.jsxs(Nt,{children:[e.jsxs(Ue,{children:[e.jsx(Q,{sx:{fontWeight:500},children:"Description"}),e.jsx(Q,{children:e.jsx(Ie,{size:"small",value:k,onChange:ge=>v(ge.target.value),onBlur:Ut,placeholder:"Enter description",sx:{input:{color:"#fff"},"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}}}})})]}),j==="ssh"&&e.jsxs(Ue,{children:[e.jsx(Q,{sx:{fontWeight:500},children:"SSH Endpoint"}),e.jsxs(Q,{children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1.5},children:[e.jsx(Ie,{size:"small",value:S,onChange:ge=>z(ge.target.value),placeholder:"user@host or host",sx:{maxWidth:300,input:{color:"#fff"},"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}}}}),e.jsx(Z,{size:"small",variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},onClick:gt,disabled:E||S.trim()===R.trim(),children:E?"Saving...":"Save"})]}),X&&e.jsx($,{variant:"caption",sx:{color:"#7db7ff"},children:X}),Se&&e.jsx($,{variant:"caption",sx:{color:"#ff8080"},children:Se})]})]}),Xe.map(ge=>e.jsxs(Ue,{children:[e.jsx(Q,{sx:{fontWeight:500},children:ge.label}),e.jsx(Q,{children:ge.value})]},ge.label))]})})})}),e.jsx(Je,{title:"Storage",children:Wt()}),e.jsxs(m,{children:[e.jsx(Je,{title:"Memory",children:Ct()}),e.jsx(Je,{title:"Network",children:lt()})]})]})]})},ht=_=>e.jsx(m,{children:e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsx(Ue,{children:_.map(K=>e.jsx(Q,{children:K},K))})}),e.jsx(Nt,{children:e.jsx(Ue,{children:e.jsx(Q,{colSpan:_.length,sx:{color:"#888"},children:"No data available."})})})]})}),Jt=()=>oe.length?e.jsxs(m,{sx:{width:"100%"},children:[e.jsx(m,{sx:{mb:1,width:"100%"},children:e.jsx(Ie,{size:"small",placeholder:"Search software...",value:C,onChange:_=>I(_.target.value),sx:{input:{color:"#fff"},"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}}}})}),e.jsx(m,{sx:{width:"100%",maxHeight:"calc(100vh - 320px)",overflow:"auto",pr:1},children:e.jsxs(Rt,{size:"small",sx:{width:"100%"},children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{sortDirection:l==="name"?f:!1,children:e.jsx(Tt,{active:l==="name",direction:l==="name"?f:"asc",onClick:()=>ct("name"),children:"Software Name"})}),e.jsx(Q,{sortDirection:l==="version"?f:!1,children:e.jsx(Tt,{active:l==="version",direction:l==="version"?f:"asc",onClick:()=>ct("version"),children:"Version"})}),e.jsx(Q,{children:"Action"})]})}),e.jsx(Nt,{children:oe.map((_,K)=>e.jsxs(Ue,{children:[e.jsx(Q,{children:_.name}),e.jsx(Q,{children:_.version}),e.jsx(Q,{})]},`${_.name}-${K}`))})]})})]}):ht(["Software Name","Version","Action"]),Ct=()=>{const _=r.memory||[];return _.length?e.jsx(m,{children:e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Slot"}),e.jsx(Q,{children:"Speed"}),e.jsx(Q,{children:"Serial Number"}),e.jsx(Q,{children:"Capacity"})]})}),e.jsx(Nt,{children:_.map((K,pe)=>e.jsxs(Ue,{children:[e.jsx(Q,{children:K.slot}),e.jsx(Q,{children:K.speed}),e.jsx(Q,{children:K.serial}),e.jsx(Q,{children:pt(K.capacity)})]},`${K.slot}-${pe}`))})]})}):ht(["Slot","Speed","Serial Number","Capacity"])},Wt=()=>{const _=re=>{if(re==null)return;if(typeof re=="number")return Number.isNaN(re)?void 0:re;const ke=parseFloat(String(re).replace(/[^0-9.]+/g,""));return Number.isNaN(ke)?void 0:ke},K=(r.storage||[]).map(re=>{const ke=_(re.total);let N=_(re.usage),H=_(re.used),Y=_(re.free),se;return N!==void 0&&(N<=1&&(N*=100),se=100-N),H===void 0&&ke!==void 0&&N!==void 0&&(H=N/100*ke),Y===void 0&&ke!==void 0&&H!==void 0&&(Y=ke-H),se===void 0&&ke!==void 0&&Y!==void 0&&(se=Y/ke*100),N===void 0&&se!==void 0&&(N=100-se),{drive:re.drive,disk_type:re.disk_type,used:H,freePct:se,freeBytes:Y,total:ke,usage:N}});if(!K.length)return ht(["Drive","Type","Capacity"]);const pe=re=>re!==void 0&&!Number.isNaN(re)?`${re.toFixed(0)}%`:"unknown";return e.jsx(m,{children:K.map((re,ke)=>{const N=re.usage??(re.total?(re.used||0)/re.total*100:0),H=re.used,Y=re.freeBytes,se=re.total;return e.jsxs(m,{sx:{p:1,borderBottom:"1px solid #2a2a2a","&:last-child":{borderBottom:"none"}},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",mb:1},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1.2},children:[e.jsx(m,{sx:{width:8,height:8,bgcolor:"#58a6ff",borderRadius:.5}}),e.jsx($,{variant:"body2",sx:{fontWeight:600},children:`Drive ${String(re.drive||"").replace("\\","")}`}),e.jsx($,{variant:"caption",sx:{opacity:.7},children:re.disk_type||"Fixed Disk"})]}),e.jsx($,{variant:"body2",sx:{opacity:.9},children:se!==void 0?pt(se):"unknown"})]}),e.jsx(m,{sx:{position:"relative",height:8,borderRadius:1,bgcolor:"#2b2b2b",background:"linear-gradient(180deg, #323232 0%, #2a2a2a 100%)",boxShadow:"inset 0 0 0 1px #3a3a3a, inset 0 1px 0 rgba(255,255,255,0.06)"},children:e.jsx(m,{sx:{position:"absolute",left:0,top:0,bottom:0,width:`${Math.max(0,Math.min(100,N||0)).toFixed(0)}%`,borderRadius:1,background:"linear-gradient(90deg, rgba(0,209,140,0.95) 0%, rgba(0,209,140,0.80) 45%, rgba(0,209,140,0.70) 100%)",boxShadow:"inset 0 0 0 1px rgba(255,255,255,0.15), 0 0 6px rgba(0,209,140,0.25)"}})}),e.jsxs(m,{sx:{display:"flex",justifyContent:"space-between",mt:.75},children:[e.jsx($,{variant:"caption",sx:{opacity:.85},children:H!==void 0?`${pt(H)} - ${pe(N)} in use`:"unknown"}),e.jsx($,{variant:"caption",sx:{opacity:.85},children:Y!==void 0&&se!==void 0?`${pt(Y)} - ${pe(100-(N||0))} remaining`:""})]})]},`${re.drive}-${ke}`)})})},lt=()=>{const _=r.network||[],K=c.internalIp||_e.internal_ip||"unknown",pe=c.externalIp||_e.external_ip||"unknown",re=e.jsxs(m,{sx:{mb:_.length?1.5:1},children:[e.jsxs($,{variant:"body2",sx:{display:"block",opacity:.9},children:["Internal IP: ",K]}),e.jsxs($,{variant:"body2",sx:{display:"block",opacity:.9},children:["External IP: ",pe]})]});return _.length?e.jsxs(m,{children:[re,e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Adapter"}),e.jsx(Q,{children:"IP Address"}),e.jsx(Q,{children:"MAC Address"})]})}),e.jsx(Nt,{children:_.map((ke,N)=>e.jsxs(Ue,{children:[e.jsx(Q,{children:ke.adapter}),e.jsx(Q,{children:(ke.ips||[]).join(", ")}),e.jsx(Q,{children:yt(ke.mac)})]},`${ke.adapter}-${N}`))})]})]}):e.jsxs(m,{children:[re,ht(["Adapter","IP Address","MAC Address"])]})},Dt=_=>{const K=String(_||"").toLowerCase();return K==="running"?"#58a6ff":K==="success"?"#00d18c":K==="failed"?"#ff4f4f":"#666"},Ot=(_,K)=>{try{return qt.highlight(_??"",qt.languages[K]||qt.languages.markup,K)}catch{return String(_||"")}},_t=s.useCallback(async(_,K)=>{if(!(!_||!_.id))try{const pe=await fetch(`/api/device/activity/job/${_.id}`);if(!pe.ok)throw new Error(`HTTP ${pe.status}`);const re=await pe.json(),ke=(re.script_path||"").toLowerCase().endsWith(".ps1")?"powershell":(re.script_path||"").toLowerCase().endsWith(".bat")?"batch":(re.script_path||"").toLowerCase().endsWith(".sh")?"bash":(re.script_path||"").toLowerCase().endsWith(".yml")?"yaml":"powershell";V(ke);const N=at(re.script_name,re.script_path);Ae(`${K==="stderr"?"StdErr":"StdOut"} - ${N}`),Fe(K==="stderr"?re.stderr||"":re.stdout||""),be(!0)}catch(pe){console.warn("Failed to load output",pe)}},[at]),Yt=_=>{w===_?te(F==="asc"?"desc":"asc"):(W(_),te("asc"))},ss=s.useMemo(()=>(de||[]).map(_=>({..._,script_display_name:at(_.script_name,_.script_path)})),[de,at]),A=s.useMemo(()=>{const _=F==="asc"?1:-1,K=w==="script_name"?"script_display_name":w;return[...ss].sort((pe,re)=>{const ke=pe[K],N=re[K];return K==="ran_at"?((ke||0)-(N||0))*_:String(ke??"").localeCompare(String(N??""))*_})},[ss,w,F]),q=()=>e.jsx(m,{children:e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Assembly"}),e.jsx(Q,{sortDirection:w==="script_name"?F:!1,children:e.jsx(Tt,{active:w==="script_name",direction:w==="script_name"?F:"asc",onClick:()=>Yt("script_name"),children:"Task"})}),e.jsx(Q,{sortDirection:w==="ran_at"?F:!1,children:e.jsx(Tt,{active:w==="ran_at",direction:w==="ran_at"?F:"asc",onClick:()=>Yt("ran_at"),children:"Ran On"})}),e.jsx(Q,{sortDirection:w==="status"?F:!1,children:e.jsx(Tt,{active:w==="status",direction:w==="status"?F:"asc",onClick:()=>Yt("status"),children:"Job Status"})}),e.jsx(Q,{children:"StdOut / StdErr"})]})}),e.jsxs(Nt,{children:[A.map(_=>e.jsxs(Ue,{children:[e.jsx(Q,{children:(_.script_type||"").toLowerCase()==="ansible"?"Ansible Playbook":"Script"}),e.jsx(Q,{children:_.script_display_name||_.script_name}),e.jsx(Q,{children:St(_.ran_at)}),e.jsx(Q,{children:e.jsx(m,{sx:{display:"inline-block",px:1.2,py:.25,borderRadius:999,bgcolor:Dt(_.status),color:"#fff",fontWeight:600,fontSize:"12px"},children:_.status})}),e.jsx(Q,{children:e.jsxs(m,{sx:{display:"flex",gap:1},children:[String(_.script_type||"").toLowerCase()==="ansible"&&String(_.status||"")==="Running"?e.jsx(Z,{size:"small",sx:{color:"#ff6666",textTransform:"none",minWidth:0,p:0},onClick:async()=>{try{const K=await fetch(`/api/ansible/run_for_activity/${encodeURIComponent(_.id)}`),pe=await K.json();if(!K.ok)throw new Error(pe.error||`HTTP ${K.status}`);const re=pe.run_id;if(re)try{const ke=window.BorealisSocket;ke&&ke.emit("ansible_playbook_cancel",{run_id:re})}catch{}else alert("Unable to locate run id for this playbook run.")}catch(K){alert(String(K.message||K))}},children:"Cancel"}):null,_.has_stdout?e.jsx(Z,{size:"small",onClick:()=>_t(_,"stdout"),sx:{color:"#58a6ff",textTransform:"none",minWidth:0,p:0},children:"StdOut"}):null,_.has_stderr?e.jsx(Z,{size:"small",onClick:()=>_t(_,"stderr"),sx:{color:"#ff4f4f",textTransform:"none",minWidth:0,p:0},children:"StdErr"}):null]})})]},_.id)),A.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:5,sx:{color:"#888"},children:"No activity yet."})})]})]})}),le=[{label:"Summary",content:ft()},{label:"Installed Software",content:Jt()},{label:"Activity History",content:q()}],he=Ce||Ne(d.last_seen||(n==null?void 0:n.lastSeen));return e.jsxs(Qe,{sx:{m:2,p:2,bgcolor:"#1e1e1e"},elevation:2,children:[e.jsxs(m,{sx:{mb:2,display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center"},children:[t&&e.jsx(Z,{variant:"outlined",size:"small",onClick:t,sx:{mr:2},children:"Back"}),e.jsxs($,{variant:"h6",sx:{color:"#58a6ff",display:"flex",alignItems:"center"},children:[e.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:10,background:Ke(he),marginRight:8}}),d.hostname||"Device Details"]})]}),e.jsxs(m,{children:[e.jsx(nt,{size:"small",disabled:!(d!=null&&d.hostname||n!=null&&n.hostname),onClick:_=>L(_.currentTarget),sx:{color:d!=null&&d.hostname||n!=null&&n.hostname?"#58a6ff":"#666",borderColor:d!=null&&d.hostname||n!=null&&n.hostname?"#58a6ff":"#333",border:"1px solid",borderRadius:1,width:32,height:32},children:e.jsx(ir,{fontSize:"small"})}),e.jsxs(Et,{anchorEl:g,open:!!g,onClose:()=>L(null),children:[e.jsx(fe,{onClick:()=>{L(null),M(!0)},children:"Quick Job"}),e.jsx(fe,{onClick:()=>{L(null),T(!0)},children:"Clear Device Activity"})]})]})]}),e.jsx(Us,{value:o,onChange:(_,K)=>a(K),sx:{borderBottom:1,borderColor:"#333"},children:le.map(_=>e.jsx(ps,{label:_.label},_.label))}),e.jsx(m,{sx:{mt:2},children:le[o].content}),e.jsxs(Ze,{open:ee,onClose:()=>be(!1),fullWidth:!0,maxWidth:"md",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:Re}),e.jsx(rt,{children:e.jsx(m,{sx:{border:"1px solid #333",borderRadius:1,bgcolor:"#1e1e1e",maxHeight:500,overflow:"auto"},children:e.jsx(En,{value:Le,onValueChange:()=>{},highlight:_=>Ot(_,je),padding:12,style:{fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',fontSize:12,color:"#e6edf3",minHeight:200},textareaProps:{readOnly:!0}})})}),e.jsx(tt,{children:e.jsx(Z,{onClick:()=>be(!1),sx:{color:"#58a6ff"},children:"Close"})})]}),e.jsx(Ti,{open:we,onCancel:()=>T(!1),onConfirm:()=>{vt(),T(!1)}}),O&&e.jsx(vo,{open:O,onClose:()=>M(!1),hostnames:[(d==null?void 0:d.hostname)||(n==null?void 0:n.hostname)].filter(Boolean)})]})}function tl(n){return e.jsx(_o,{...n,filterMode:"agent",title:"Agent Devices",showAddButton:!1})}const sl={"& th, & td":{color:"#ddd",borderColor:"#2a2a2a",fontSize:13,py:.75},"& th":{fontWeight:600},"& th .MuiTableSortLabel-root":{color:"#ddd"},"& th .MuiTableSortLabel-root.Mui-active":{color:"#ddd"}},gn={hostname:"",address:"",description:"",operating_system:""};function ko({type:n="ssh"}){const t=n==="winrm"?"WinRM":"SSH",o=n==="winrm"?"/api/winrm_devices":"/api/ssh_devices",a=`${t} Devices`,d=`Add ${t} Device`,u=`${t} Address`,r=`Loading ${t} devices…`,i=`No ${t} devices have been added yet.`,c=n==="winrm"?"Manage remote endpoints reachable via WinRM for playbook execution.":"Manage remote endpoints reachable via SSH for playbook execution.",p=`Edit ${t} Device`,l=`New ${t} Device`,[h,f]=s.useState([]),[y,C]=s.useState("hostname"),[I,k]=s.useState("asc"),[v,j]=s.useState(!0),[B,R]=s.useState(""),[x,S]=s.useState(!1),[z,E]=s.useState(gn),[U,X]=s.useState(""),[ue,Se]=s.useState(!1),[ce,de]=s.useState(null),[me,w]=s.useState(null),[W,F]=s.useState(!1),[te,ee]=s.useState(!1),be=!!ce,Re=s.useCallback(async()=>{j(!0),R("");try{const g=await fetch(o);if(!g.ok){const T=await g.json().catch(()=>({}));throw new Error((T==null?void 0:T.error)||`HTTP ${g.status}`)}const L=await g.json(),we=Array.isArray(L==null?void 0:L.devices)?L.devices:[];f(we)}catch(g){R(String(g.message||g)),f([])}finally{j(!1)}},[o]);s.useEffect(()=>{Re()},[Re]);const Ae=s.useMemo(()=>{const g=[...h];return g.sort((L,we)=>{const T=Ce=>{switch(y){case"created_at":return Number(Ce.created_at||0);case"address":return(Ce.connection_endpoint||"").toLowerCase();case"description":return(Ce.description||"").toLowerCase();default:return(Ce.hostname||"").toLowerCase()}},G=T(L),ie=T(we);return G<ie?I==="asc"?-1:1:G>ie?I==="asc"?1:-1:0}),g},[h,I,y]),Le=g=>()=>{y===g?k(L=>L==="asc"?"desc":"asc"):(C(g),k("asc"))},Fe=()=>{ee(!0),X("")},je=g=>{var L;de(g),E({hostname:g.hostname||"",address:g.connection_endpoint||"",description:g.description||"",operating_system:((L=g.summary)==null?void 0:L.operating_system)||""}),S(!0),X("")},V=()=>{ue||(S(!1),E(gn),de(null),X(""))},O=async()=>{if(ue)return;const g={hostname:z.hostname.trim(),address:z.address.trim(),description:z.description.trim(),operating_system:z.operating_system.trim()};if(!g.hostname){X("Hostname is required.");return}if(!g.address){X("Address is required.");return}Se(!0),X("");try{const L=be?`${o}/${encodeURIComponent(ce.hostname)}`:o,we=await fetch(L,{method:be?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)}),T=await we.json().catch(()=>({}));if(!we.ok)throw new Error((T==null?void 0:T.error)||`HTTP ${we.status}`);S(!1),E(gn),de(null),X(""),f(G=>{const ie=[...G];if(T!=null&&T.device){const Ce=ie.findIndex(Ee=>Ee.hostname===T.device.hostname);return Ce>=0?ie[Ce]=T.device:ie.push(T.device),ie}return G}),Re()}catch(L){X(String(L.message||L))}finally{Se(!1)}},M=async()=>{if(me){F(!0);try{const g=await fetch(`${o}/${encodeURIComponent(me.hostname)}`,{method:"DELETE"}),L=await g.json().catch(()=>({}));if(!g.ok)throw new Error((L==null?void 0:L.error)||`HTTP ${g.status}`);f(we=>we.filter(T=>T.hostname!==me.hostname)),w(null)}catch(g){R(String(g.message||g))}finally{F(!1)}}};return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e"},elevation:2,children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",p:2,borderBottom:"1px solid #2a2a2a"},children:[e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:a}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:c})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Z,{size:"small",variant:"outlined",startIcon:e.jsx(Ss,{}),sx:{color:"#58a6ff",borderColor:"#58a6ff"},onClick:Re,disabled:v,children:"Refresh"}),e.jsx(Z,{size:"small",variant:"contained",startIcon:e.jsx(ts,{}),sx:{bgcolor:"#58a6ff",color:"#0b0f19"},onClick:Fe,children:d})]})]}),B&&e.jsx(m,{sx:{px:2,py:1.5,color:"#ff8080"},children:e.jsx($,{variant:"body2",children:B})}),v&&e.jsxs(m,{sx:{px:2,py:1.5,display:"flex",alignItems:"center",gap:1,color:"#7db7ff"},children:[e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),e.jsx($,{variant:"body2",children:r})]}),e.jsxs(Rt,{size:"small",sx:sl,children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{sortDirection:y==="hostname"?I:!1,children:e.jsx(Tt,{active:y==="hostname",direction:y==="hostname"?I:"asc",onClick:Le("hostname"),children:"Hostname"})}),e.jsx(Q,{sortDirection:y==="address"?I:!1,children:e.jsx(Tt,{active:y==="address",direction:y==="address"?I:"asc",onClick:Le("address"),children:u})}),e.jsx(Q,{sortDirection:y==="description"?I:!1,children:e.jsx(Tt,{active:y==="description",direction:y==="description"?I:"asc",onClick:Le("description"),children:"Description"})}),e.jsx(Q,{sortDirection:y==="created_at"?I:!1,children:e.jsx(Tt,{active:y==="created_at",direction:y==="created_at"?I:"asc",onClick:Le("created_at"),children:"Added"})}),e.jsx(Q,{align:"right",children:"Actions"})]})}),e.jsxs(Nt,{children:[Ae.map(g=>{var T;const L=Number(g.created_at||0)*1e3,we=L?new Date(L).toLocaleString():((T=g.summary)==null?void 0:T.created)||"";return e.jsxs(Ue,{children:[e.jsx(Q,{children:g.hostname}),e.jsx(Q,{children:g.connection_endpoint||""}),e.jsx(Q,{children:g.description||""}),e.jsx(Q,{children:we}),e.jsxs(Q,{align:"right",children:[e.jsx(nt,{size:"small",sx:{color:"#7db7ff"},onClick:()=>je(g),children:e.jsx(Fs,{fontSize:"small"})}),e.jsx(nt,{size:"small",sx:{color:"#ff8080"},onClick:()=>w(g),children:e.jsx($s,{fontSize:"small"})})]})]},g.hostname)}),!Ae.length&&!v&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:5,sx:{textAlign:"center",color:"#888"},children:i})})]})]}),e.jsxs(Ze,{open:x,onClose:V,fullWidth:!0,maxWidth:"sm",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:be?p:l}),e.jsxs(rt,{sx:{display:"flex",flexDirection:"column",gap:2,mt:1},children:[e.jsx(Ie,{label:"Hostname",value:z.hostname,disabled:be,onChange:g=>E(L=>({...L,hostname:g.target.value})),fullWidth:!0,size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}},helperText:"Hostname used within Borealis (unique)."}),e.jsx(Ie,{label:u,value:z.address,onChange:g=>E(L=>({...L,address:g.target.value})),fullWidth:!0,size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}},helperText:`IP or FQDN Borealis can reach over ${t}.`}),e.jsx(Ie,{label:"Description",value:z.description,onChange:g=>E(L=>({...L,description:g.target.value})),fullWidth:!0,size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}}}),e.jsx(Ie,{label:"Operating System",value:z.operating_system,onChange:g=>E(L=>({...L,operating_system:g.target.value})),fullWidth:!0,size:"small",sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#1f1f1f",color:"#fff","& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}},"& .MuiInputLabel-root":{color:"#aaa"}}}),B&&e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:B})]}),e.jsxs(tt,{sx:{px:3,pb:2},children:[e.jsx(Z,{onClick:V,sx:{color:"#58a6ff"},disabled:ue,children:"Cancel"}),e.jsx(Z,{onClick:O,variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},disabled:ue,children:ue?"Saving...":"Save"})]})]}),e.jsx(Zt,{open:!!me,message:me?`Remove ${t} device '${me.hostname}' from inventory?`:"",onCancel:()=>w(null),onConfirm:M,confirmDisabled:W}),e.jsx(So,{open:te,defaultType:n,onClose:()=>ee(!1),onCreated:()=>{ee(!1),Re()}})]})}function nl(n){return e.jsx(ko,{...n,type:"winrm"})}const Io=({title:n,description:t,icon:o,actions:a,children:d,sx:u})=>e.jsxs(Qe,{elevation:0,sx:{p:1.5,borderRadius:2,bgcolor:"#1c1c1c",border:"1px solid #2a2a2a",mb:1.5,...u||{}},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",mb:1},children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center"},children:[o?e.jsx(m,{sx:{color:"#58a6ff",display:"flex",alignItems:"center",justifyContent:"center",minWidth:48,mr:1},children:o}):null,e.jsxs(m,{children:[e.jsx($,{variant:"caption",sx:{color:"#58a6ff",fontWeight:400,fontSize:"14px",letterSpacing:.2},children:n}),t?e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:t}):null]})]}),a?e.jsx(m,{sx:{display:"flex",alignItems:"center",gap:1},children:a}):null]}),d]}),Mn=n=>{!n||!Array.isArray(n.children)||(n.children.sort((t,o)=>{const a=!!t.isFolder,d=!!o.isFolder;return a!==d?a?-1:1:String(t.label||"").localeCompare(String(o.label||""),void 0,{sensitivity:"base"})}),n.children.forEach(Mn))};function ol(n,t){const o={},a={id:"root",label:"Workflows",path:"",isFolder:!0,children:[]};return o[a.id]=a,(t||[]).forEach(d=>{const u=(d||"").split("/");let r=a.children,i="";u.forEach(c=>{const p=i?`${i}/${c}`:c;let l=r.find(h=>h.id===p);l||(l={id:p,label:c,path:p,isFolder:!0,children:[]},r.push(l),o[p]=l),r=l.children,i=p})}),(n||[]).forEach(d=>{const u=(d.rel_path||"").split("/");let r=a.children,i="";u.forEach((c,p)=>{const l=i?`${i}/${c}`:c,h=p===u.length-1;let f=r.find(y=>y.id===l);f||(f={id:l,label:h?d.tab_name&&d.tab_name.trim()||d.file_name:c,path:l,isFolder:!h,fileName:d.file_name,workflow:h?d:null,children:[]},r.push(f),o[l]=f),h||(r=f.children,i=l)})}),Mn(a),{root:[a],map:o}}function rl({onOpenWorkflow:n}){var Le,Fe;const[t,o]=s.useState([]),[a,d]=s.useState({}),[u,r]=s.useState(null),[i,c]=s.useState(null),[p,l]=s.useState(""),[h,f]=s.useState(!1),[y,C]=s.useState(!1),[I,k]=s.useState("rename"),[v,j]=s.useState(!1),[B,R]=s.useState(""),[x,S]=s.useState(!1),z=xo(),[E,U]=s.useState(null),X=async je=>{if(!E||!je.isFolder)return;if(E.path===je.path||je.path.startsWith(`${E.path}/`)){U(null);return}const V=je.path?`${je.path}/${E.fileName}`:E.fileName;try{await fetch("/api/assembly/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"file",path:E.path,new_path:V})}),ue()}catch(O){console.error("Failed to move workflow:",O)}U(null)},ue=s.useCallback(async()=>{try{const je=await fetch("/api/assembly/list?island=workflows");if(!je.ok)throw new Error(`HTTP ${je.status}`);const V=await je.json(),{root:O,map:M}=ol(V.items||[],V.folders||[]);o(O),d(M)}catch(je){console.error("Failed to load workflows:",je),o([]),d({})}},[]);s.useEffect(()=>{ue()},[ue]);const Se=(je,V)=>{je.preventDefault(),c(V),r(u===null?{mouseX:je.clientX-2,mouseY:je.clientY-4}:null)},ce=()=>{r(null),i&&(l(i.label),i.isFolder?(k("rename"),C(!0)):f(!0))},de=()=>{r(null),i&&!i.isFolder&&n&&n(i.workflow)},me=()=>{r(null),i&&S(!0)},w=()=>{i&&(r(null),k("create"),l(""),C(!0))},W=()=>{i&&(r(null),R(""),j(!0))},F=async()=>{if(i){try{await fetch("/api/assembly/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"file",path:i.path,new_name:p})}),ue()}catch(je){console.error("Failed to rename workflow:",je)}f(!1)}},te=async()=>{try{if(I==="rename"&&i)await fetch("/api/assembly/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"folder",path:i.path,new_name:p})});else{const je=i?i.path:"",V=je?`${je}/${p}`:p;await fetch("/api/assembly/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"folder",path:V})})}ue()}catch(je){console.error("Folder operation failed:",je)}C(!1)},ee=(je,V)=>{const O=a[V];O&&!O.isFolder&&n&&n(O.workflow)},be=async()=>{if(i){try{i.isFolder?await fetch("/api/assembly/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"folder",path:i.path})}):await fetch("/api/assembly/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:"workflows",kind:"file",path:i.path})}),ue()}catch(je){console.error("Failed to delete:",je)}S(!1)}},Re=je=>(je||[]).map(V=>e.jsx(ys,{itemId:V.id,label:e.jsxs(m,{sx:{display:"flex",alignItems:"center"},draggable:!V.isFolder,onDragStart:()=>!V.isFolder&&U(V),onDragOver:O=>{E&&V.isFolder&&O.preventDefault()},onDrop:O=>{O.preventDefault(),X(V)},onContextMenu:O=>Se(O,V),children:[V.isFolder?e.jsx(Nn,{sx:{mr:1,color:"#0475c2"}}):e.jsx(Tn,{sx:{mr:1,color:"#0475c2"}}),e.jsx($,{sx:{flexGrow:1,color:"#e6edf3"},children:V.label})]}),children:V.children&&V.children.length>0?Re(V.children):null},V.id)),Ae=((Fe=(Le=t[0])==null?void 0:Le.children)==null?void 0:Fe.map(je=>je.id))||[];return e.jsxs(Io,{title:"Workflows",description:"Node-Based Automation Pipelines",icon:e.jsx(kn,{sx:{fontSize:40}}),actions:e.jsx(Z,{size:"small",variant:"outlined",onClick:()=>{c({id:"root",path:"",isFolder:!0}),R(""),j(!0)},sx:{color:"#58a6ff",borderColor:"#2f81f7",textTransform:"none","&:hover":{borderColor:"#58a6ff"}},children:"New Workflow"}),children:[e.jsx(m,{sx:{p:1},onDragOver:je=>{E&&je.preventDefault()},onDrop:je=>{je.preventDefault(),X({path:"",isFolder:!0})},children:e.jsx(vs,{sx:{color:"#e6edf3"},onNodeSelect:ee,apiRef:z,defaultExpandedItems:["root",...Ae],children:Re(t)},Ae.join(","))}),e.jsxs(Et,{open:u!==null,onClose:()=>r(null),anchorReference:"anchorPosition",anchorPosition:u?{top:u.mouseY,left:u.mouseX}:void 0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[(i==null?void 0:i.isFolder)&&e.jsxs(e.Fragment,{children:[e.jsx(fe,{onClick:W,children:"New Workflow"}),e.jsx(fe,{onClick:w,children:"New Subfolder"}),i.id!=="root"&&e.jsx(fe,{onClick:ce,children:"Rename"}),i.id!=="root"&&e.jsx(fe,{onClick:me,children:"Delete"})]}),!(i!=null&&i.isFolder)&&e.jsxs(e.Fragment,{children:[e.jsx(fe,{onClick:de,children:"Edit"}),e.jsx(fe,{onClick:ce,children:"Rename"}),e.jsx(fe,{onClick:me,children:"Delete"})]})]}),e.jsx(Ri,{open:h,value:p,onChange:l,onCancel:()=>f(!1),onSave:F}),e.jsx(wo,{open:y,value:p,onChange:l,onCancel:()=>C(!1),onSave:te,title:I==="rename"?"Rename Folder":"New Folder",confirmText:I==="rename"?"Save":"Create"}),e.jsx(Ni,{open:v,value:B,onChange:R,onCancel:()=>j(!1),onCreate:()=>{j(!1),n&&n(null,(i==null?void 0:i.path)||"",B)}}),e.jsx(Zt,{open:x,message:"If you delete this, there is no undo button, are you sure you want to proceed?",onCancel:()=>S(!1),onConfirm:be})]})}function al(n,t,o){const a=r=>{const i=[String(n||"").trim(),String(n||"").replace(/\s+/g,"_")].filter(Boolean),c=String(r||"").replace(/\\/g,"/").split("/").filter(Boolean);return c.length&&i.includes(c[0])&&c.shift(),c},d={},u={id:"root",label:n,path:"",isFolder:!0,children:[]};return d[u.id]=u,(o||[]).forEach(r=>{const i=a(r);let c=u.children,p="";i.forEach(l=>{const h=p?`${p}/${l}`:l;let f=c.find(y=>y.id===h);f||(f={id:h,label:l,path:h,isFolder:!0,children:[]},c.push(f),d[h]=f),c=f.children,p=h})}),(t||[]).forEach(r=>{const i=a(r==null?void 0:r.rel_path);let c=u.children,p="";i.forEach((l,h)=>{const f=p?`${p}/${l}`:l,y=h===i.length-1;let C=c.find(I=>I.id===f);C||(C={id:f,label:y&&(r.name||r.display_name||r.file_name)||l,path:f,isFolder:!y,fileName:r.file_name,meta:y?r:null,children:[]},c.push(C),d[f]=C),y||(c=C.children,p=f)})}),Mn(u),{root:[u],map:d}}function Kn({title:n,description:t,rootLabel:o,baseApi:a,newItemLabel:d="New Script",onEdit:u}){var je,V;const[r,i]=s.useState([]),[c,p]=s.useState({}),[l,h]=s.useState(null),[f,y]=s.useState(null),[C,I]=s.useState(""),[k,v]=s.useState(!1),[j,B]=s.useState(!1),[R,x]=s.useState("rename"),[S,z]=s.useState(!1),[E,U]=s.useState(""),[X,ue]=s.useState(!1),Se=xo(),[ce,de]=s.useState(null),me=es.useMemo(()=>String(a||"").toLowerCase().endsWith("/api/ansible")?"ansible":"scripts",[a]),w=s.useCallback(async()=>{try{const O=await fetch(`/api/assembly/list?island=${encodeURIComponent(me)}`);if(!O.ok)throw new Error(`HTTP ${O.status}`);const M=await O.json(),{root:g,map:L}=al(o,M.items||[],M.folders||[]);i(g),p(L)}catch(O){console.error(`Failed to load ${n}:`,O),i([]),p({})}},[me,n,o]);s.useEffect(()=>{w()},[w]);const W=(O,M)=>{O.preventDefault(),y(M),h(l===null?{mouseX:O.clientX-2,mouseY:O.clientY-4}:null)},F=async O=>{if(!ce||!O.isFolder)return;if(ce.path===O.path||O.path.startsWith(`${ce.path}/`)){de(null);return}const M=O.path?`${O.path}/${ce.fileName}`:ce.fileName;try{await fetch("/api/assembly/move",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:me,kind:"file",path:ce.path,new_path:M})}),w()}catch(g){console.error("Failed to move:",g)}de(null)},te=async(O,M)=>{const g=c[M];g&&!g.isFolder&&(h(null),u&&u(g.path))},ee=async()=>{var O;try{const M={island:me,kind:"file",path:f.path,new_name:C};(O=f==null?void 0:f.meta)!=null&&O.type&&(M.type=f.meta.type);const g=await fetch("/api/assembly/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(M)}),L=await g.json();if(!g.ok)throw new Error((L==null?void 0:L.error)||`HTTP ${g.status}`);v(!1),w()}catch(M){console.error("Failed to rename file:",M),v(!1)}},be=async()=>{try{if(R==="rename"&&f)await fetch("/api/assembly/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:me,kind:"folder",path:f.path,new_name:C})});else{const O=f?f.path:"",M=O?`${O}/${C}`:C;await fetch("/api/assembly/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:me,kind:"folder",path:M})})}B(!1),w()}catch(O){console.error("Folder operation failed:",O),B(!1)}},Re=async()=>{if(f)try{f.isFolder?await fetch("/api/assembly/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:me,kind:"folder",path:f.path})}):await fetch("/api/assembly/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:me,kind:"file",path:f.path})}),ue(!1),w()}catch(O){console.error("Failed to delete:",O),ue(!1)}},Ae=()=>{var L;const O=(E||"").trim(),g={folder:f!=null&&f.isFolder?f.path:((L=f==null?void 0:f.path)==null?void 0:L.split("/").slice(0,-1).join("/"))||"",suggestedFileName:O,defaultType:me==="ansible"?"ansible":"powershell",type:me==="ansible"?"ansible":"powershell",category:me==="ansible"?"application":"script"};z(!1),U(""),u&&u(null,g)},Le=O=>(O||[]).map(M=>e.jsx(ys,{itemId:M.id,label:e.jsxs(m,{sx:{display:"flex",alignItems:"center"},draggable:!M.isFolder,onDragStart:()=>!M.isFolder&&de(M),onDragOver:g=>{ce&&M.isFolder&&g.preventDefault()},onDrop:g=>{g.preventDefault(),F(M)},onContextMenu:g=>W(g,M),onDoubleClick:()=>{M.isFolder||u&&u(M.path)},children:[M.isFolder?e.jsx(Nn,{sx:{mr:1,color:"#0475c2"}}):e.jsx(Tn,{sx:{mr:1,color:"#0475c2"}}),e.jsx($,{sx:{flexGrow:1,color:"#e6edf3"},children:M.label})]}),children:M.children&&M.children.length>0?Le(M.children):null},M.id)),Fe=((V=(je=r[0])==null?void 0:je.children)==null?void 0:V.map(O=>O.id))||[];return e.jsxs(Io,{title:n,description:t,icon:n==="Scripts"?e.jsx(pr,{sx:{fontSize:40}}):e.jsx(fr,{sx:{fontSize:40}}),actions:e.jsx(Z,{size:"small",variant:"outlined",onClick:()=>{U(""),z(!0)},sx:{color:"#58a6ff",borderColor:"#2f81f7",textTransform:"none","&:hover":{borderColor:"#58a6ff"}},children:d}),children:[e.jsx(m,{sx:{p:1},onDragOver:O=>{ce&&O.preventDefault()},onDrop:O=>{O.preventDefault(),F({path:"",isFolder:!0})},children:e.jsx(vs,{sx:{color:"#e6edf3"},onNodeSelect:te,apiRef:Se,defaultExpandedItems:["root",...Fe],children:Le(r)},Fe.join(","))}),e.jsxs(Et,{open:l!==null,onClose:()=>h(null),anchorReference:"anchorPosition",anchorPosition:l?{top:l.mouseY,left:l.mouseX}:void 0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"}},children:[(f==null?void 0:f.isFolder)&&e.jsxs(e.Fragment,{children:[e.jsx(fe,{onClick:()=>{h(null),z(!0)},children:d}),e.jsx(fe,{onClick:()=>{h(null),x("create"),I(""),B(!0)},children:"New Subfolder"}),f.id!=="root"&&e.jsx(fe,{onClick:()=>{h(null),I(f.label),v(!0)},children:"Rename"}),f.id!=="root"&&e.jsx(fe,{onClick:()=>{h(null),ue(!0)},children:"Delete"})]}),!(f!=null&&f.isFolder)&&e.jsxs(e.Fragment,{children:[e.jsx(fe,{onClick:()=>{h(null),u&&u(f.path)},children:"Edit"}),e.jsx(fe,{onClick:()=>{h(null),I(f.label),v(!0)},children:"Rename"}),e.jsx(fe,{onClick:()=>{h(null),ue(!0)},children:"Delete"})]})]}),e.jsx(wo,{open:j,value:C,onChange:I,onCancel:()=>B(!1),onSave:be,title:R==="rename"?"Rename Folder":"New Folder",confirmText:R==="rename"?"Save":"Create"}),e.jsx(Qe,{component:O=>e.jsx("div",{...O}),sx:{display:k?"block":"none"},children:e.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.4)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:e.jsxs(Qe,{sx:{bgcolor:"#121212",color:"#fff",p:2,minWidth:360},children:[e.jsx($,{variant:"h6",sx:{mb:1},children:"Rename"}),e.jsx("input",{autoFocus:!0,value:C,onChange:O=>I(O.target.value),style:{width:"100%",padding:8,background:"#2a2a2a",color:"#ccc",border:"1px solid #444",borderRadius:4}}),e.jsxs(m,{sx:{display:"flex",justifyContent:"flex-end",mt:2},children:[e.jsx(Z,{onClick:()=>v(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:ee,sx:{color:"#58a6ff"},children:"Save"})]})]})})}),e.jsx(Qe,{component:O=>e.jsx("div",{...O}),sx:{display:S?"block":"none"},children:e.jsx("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.4)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999},children:e.jsxs(Qe,{sx:{bgcolor:"#121212",color:"#fff",p:2,minWidth:360},children:[e.jsx($,{variant:"h6",sx:{mb:1},children:d}),e.jsx("input",{autoFocus:!0,value:E,onChange:O=>U(O.target.value),placeholder:"Name",style:{width:"100%",padding:8,background:"#2a2a2a",color:"#ccc",border:"1px solid #444",borderRadius:4}}),e.jsxs(m,{sx:{display:"flex",justifyContent:"flex-end",mt:2},children:[e.jsx(Z,{onClick:()=>z(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:Ae,sx:{color:"#58a6ff"},children:"Create"})]})]})})}),e.jsx(Zt,{open:X,message:"If you delete this, there is no undo button, are you sure you want to proceed?",onCancel:()=>ue(!1),onConfirm:Re})]})}function Xn({onOpenWorkflow:n,onOpenScript:t}){return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e"},elevation:2,children:[e.jsxs(m,{sx:{p:2,pb:1},children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:"Assemblies"}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Collections of various types of components used to perform various automations upon targeted devices."})]}),e.jsx(m,{sx:{px:2,pb:2},children:e.jsxs(m,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",md:"1.2fr 1fr 1fr"},gap:2},children:[e.jsx(rl,{onOpenWorkflow:n}),e.jsx(Kn,{title:"Scripts",description:"Powershell, Batch, and Bash Scripts",rootLabel:"Scripts",baseApi:"/api/scripts",newItemLabel:"New Script",onEdit:(o,a)=>t&&t(o,"scripts",a)}),e.jsx(Kn,{title:"Ansible Playbooks",description:"Declarative Instructions for Consistent Automation",rootLabel:"Ansible Playbooks",baseApi:"/api/ansible",newItemLabel:"New Playbook",onEdit:(o,a)=>t&&t(o,"ansible",a)})]})})]})}const _n=[{key:"ansible",label:"Ansible Playbook",prism:"yaml"},{key:"powershell",label:"PowerShell Script",prism:"powershell"},{key:"batch",label:"Batch Script",prism:"batch"},{key:"bash",label:"Bash Script",prism:"bash"}],il=[{key:"script",label:"Script"},{key:"application",label:"Application"}],ll=[{key:"string",label:"String"},{key:"number",label:"Number"},{key:"boolean",label:"Boolean"},{key:"credential",label:"Credential"}],Pt={field:"#1C1C1C",sectionCard:"#2E2E2E",menuSelected:"rgba(88,166,255,0.16)",menuSelectedHover:"rgba(88,166,255,0.24)",primaryActionSaving:"rgba(88,166,255,0.12)",primaryActionHover:"rgba(88,166,255,0.18)",dialog:"#1a1f27"},rs={"& .MuiOutlinedInput-root":{bgcolor:Pt.field,color:"#e6edf3",borderRadius:1,minHeight:40,"& fieldset":{borderColor:"#2b3544"},"&:hover fieldset":{borderColor:"#3a4657"},"&.Mui-focused fieldset":{borderColor:"#58a6ff"}},"& .MuiOutlinedInput-input":{padding:"9px 12px",fontSize:"0.95rem",lineHeight:1.4},"& .MuiOutlinedInput-inputMultiline":{padding:"9px 12px"},"& .MuiInputLabel-root":{color:"#9ba3b4",transform:"translate(12px, 11px) scale(0.8)"},"& .MuiInputLabel-root.Mui-focused":{color:"#58a6ff"},"& .MuiInputLabel-root.MuiInputLabel-shrink":{transform:"translate(12px, -6px) scale(0.75)"},"& input[type=number]":{MozAppearance:"textfield"},"& input[type=number]::-webkit-outer-spin-button":{WebkitAppearance:"none",margin:0},"& input[type=number]::-webkit-inner-spin-button":{WebkitAppearance:"none",margin:0}},Ps={...rs,"& .MuiSelect-select":{padding:"10px 12px !important",display:"flex",alignItems:"center"}},Zs={color:"#58a6ff",fontWeight:400,fontSize:"14px",letterSpacing:.2},cl={bgcolor:Pt.sectionCard,borderRadius:2,border:"1px solid #262f3d"},Es={PaperProps:{sx:{bgcolor:Pt.field,color:"#e6edf3",border:"1px solid #2b3544","& .MuiMenuItem-root.Mui-selected":{bgcolor:Pt.menuSelected},"& .MuiMenuItem-root.Mui-selected:hover":{bgcolor:Pt.menuSelectedHover}}}};function dl(n){return Object.fromEntries(n.map(t=>[t.key,t]))}const ul=dl(_n),pl="#0d1117";function fl(n,t){try{const o=qt.languages[t]||qt.languages.markup;return qt.highlight(n??"",o,t)}catch{return(n??"").replace(/[&<>]/g,o=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[o])}}function bn(n=""){const t=n.trim().replace(/[^a-zA-Z0-9._-]+/g,"_")||"assembly";return t.endsWith(".json")?t:`${t}.json`}function Ms(n=""){return n?n.replace(/\\/g,"/").replace(/^\/+|\/+$/g,"").replace(/\/+/g,"/"):""}function hl(n){if(!n||Number.isNaN(n))return"0 B";if(n<1024)return`${n} B`;const t=["KB","MB","GB","TB"];let o=-1,a=n;for(;a>=1024&&o<t.length-1;)a/=1024,o+=1;return`${a.toFixed(1)} ${t[o]}`}function sn(n="powershell"){return{name:"",description:"",category:n==="ansible"?"application":"script",type:n,script:"",timeoutSeconds:3600,sites:{mode:"all",values:[]},variables:[],files:[]}}function ml(n=[]){return(Array.isArray(n)?n:[]).map((t,o)=>({id:`${Date.now()}_${o}_${Math.random().toString(36).slice(2,8)}`,name:(t==null?void 0:t.name)||(t==null?void 0:t.key)||"",label:(t==null?void 0:t.label)||"",type:(t==null?void 0:t.type)||"string",defaultValue:(t==null?void 0:t.default)??(t==null?void 0:t.default_value)??"",required:!!(t!=null&&t.required),description:(t==null?void 0:t.description)||""}))}function Qn(n=""){if(typeof n!="string")return{success:!1,value:""};const t=n.trim();if(!t)return{success:!0,value:""};const o=t.replace(/\s+/g,"");try{if(typeof window<"u"&&typeof window.atob=="function"){const a=window.atob(o);if(typeof TextDecoder<"u")try{return{success:!0,value:new TextDecoder("utf-8",{fatal:!1}).decode(Uint8Array.from(a,r=>r.charCodeAt(0)))}}catch{}let d="";for(let u=0;u<a.length;u+=1)d+=String.fromCharCode(a.charCodeAt(u));try{return{success:!0,value:decodeURIComponent(escape(d))}}catch{return{success:!0,value:d}}}}catch{}try{if(typeof Buffer<"u")return{success:!0,value:Buffer.from(o,"base64").toString("utf-8")}}catch{}return{success:!1,value:""}}function xl(n=""){if(typeof n!="string"&&(n=n==null?"":String(n)),!n)return"";try{if(typeof TextEncoder<"u"&&typeof window<"u"&&typeof window.btoa=="function"){const o=new TextEncoder().encode(n);let a="";return o.forEach(d=>{a+=String.fromCharCode(d)}),window.btoa(a)}}catch{}try{if(typeof Buffer<"u")return Buffer.from(n,"utf-8").toString("base64")}catch{}return""}function gl(n=[]){return(Array.isArray(n)?n:[]).map((t,o)=>({id:`${Date.now()}_${o}_${Math.random().toString(36).slice(2,8)}`,fileName:(t==null?void 0:t.file_name)||(t==null?void 0:t.name)||"file.bin",size:(t==null?void 0:t.size)||0,mimeType:(t==null?void 0:t.mime_type)||(t==null?void 0:t.mimeType)||"",data:(t==null?void 0:t.data)||""}))}function bl(n={},t="powershell"){const o=sn(t);if(n&&typeof n=="object"){o.name=n.name||n.display_name||o.name,o.description=n.description||"",o.category=n.category||o.category,o.type=n.type||o.type;const a=Array.isArray(n.script_lines)?n.script_lines.map(i=>i==null?"":String(i)).join(`
`):"",d=n.script??n.content??a;if(typeof d=="string"){const i=(n.script_encoding||n.scriptEncoding||"").toLowerCase();if(["base64","b64","base-64"].includes(i)){const c=Qn(d);o.script=c.success?c.value:d}else if(i)o.script=d;else{const c=Qn(d);o.script=c.success?c.value:d}}else o.script=a;const u=n.timeout_seconds??n.timeout??o.timeoutSeconds;o.timeoutSeconds=Number.isFinite(Number(u))?Number(u):o.timeoutSeconds;const r=n.sites||{};o.sites={mode:r.mode||(Array.isArray(r.values)&&r.values.length?"specific":"all"),values:Array.isArray(r.values)?r.values:[]},o.variables=ml(n.variables),o.files=gl(n.files)}return o}function yl(n){var u,r,i;const t=typeof n.script=="string"?n.script.replace(/\r\n/g,`
`):"",o=Number(n.timeoutSeconds),a=Number.isFinite(o)?Math.max(0,Math.round(o)):3600,d=xl(t);return{version:1,name:((u=n.name)==null?void 0:u.trim())||"",description:n.description||"",category:n.category||"script",type:n.type||"powershell",script:d,script_encoding:"base64",timeout_seconds:a,sites:{mode:((r=n.sites)==null?void 0:r.mode)==="specific"?"specific":"all",values:Array.isArray((i=n.sites)==null?void 0:i.values)?n.sites.values.filter(c=>c&&c.trim()).map(c=>c.trim()):[]},variables:(n.variables||[]).map(c=>{var p;return{name:((p=c.name)==null?void 0:p.trim())||"",label:c.label||"",type:c.type||"string",default:c.defaultValue??"",required:!!c.required,description:c.description||""}}),files:(n.files||[]).map(c=>({file_name:c.fileName||"file.bin",size:c.size||0,mime_type:c.mimeType||"",data:c.data||""}))}}function jl({open:n,value:t,onChange:o,onCancel:a,onSave:d}){return e.jsxs(Ze,{open:n,onClose:a,PaperProps:{sx:{bgcolor:Pt.dialog,color:"#fff"}},children:[e.jsx(et,{children:"Rename Assembly File"}),e.jsx(rt,{children:e.jsx(Ie,{autoFocus:!0,margin:"dense",label:"File Name",fullWidth:!0,variant:"outlined",value:t,onChange:u=>o(u.target.value),sx:rs})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:a,sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:d,sx:{color:"#58a6ff"},children:"Save"})]})]})}function Zn({mode:n="scripts",initialPath:t="",initialContext:o=null,onConsumeInitialData:a,onSaved:d}){var g,L,we;const u=n==="ansible",r=u?"ansible":"powershell",[i,c]=s.useState(()=>sn(r)),[p,l]=s.useState(""),[h,f]=s.useState(""),[y,C]=s.useState(()=>Ms((o==null?void 0:o.folder)||"")),[I,k]=s.useState(!1),[v,j]=s.useState(""),[B,R]=s.useState(!1),[x,S]=s.useState(!1),[z,E]=s.useState([]),[U,X]=s.useState(!1),ue=s.useRef(null),Se=s.useMemo(()=>u?_n.filter(T=>T.key==="ansible"):_n.filter(T=>T.key!=="ansible"),[u]),ce=s.useMemo(()=>{const T=new Map;return z.forEach(G=>{if(!G)return;const ie=G.id!=null?String(G.id):"";ie&&T.set(ie,G)}),T},[z]),de=u?"ansible":"scripts";s.useEffect(()=>{if(!t)return;let T=!1;return(async()=>{try{const G=await fetch(`/api/assembly/load?island=${encodeURIComponent(de)}&path=${encodeURIComponent(t)}`);if(!G.ok)throw new Error(`HTTP ${G.status}`);const ie=await G.json();if(T)return;const Ce=ie.rel_path||t;l(Ce),C(Ms(Ce.split("/").slice(0,-1).join("/"))),f(ie.file_name||Ce.split("/").pop()||"");const Ee=bl(ie.assembly||ie,r);c(Ee)}catch(G){console.error("Failed to load assembly:",G)}finally{!T&&a&&a()}})(),()=>{T=!0}},[t,de]),s.useEffect(()=>{const T=o;if(!T||!T.nonce||ue.current===T.nonce)return;ue.current=T.nonce;const G=sn(T.defaultType||r);T.name&&(G.name=T.name),T.description&&(G.description=T.description),T.category&&(G.category=T.category),T.type&&(G.type=T.type),c(G),l("");const ie=T.suggestedFileName||T.name||"";f(ie?bn(ie):""),C(Ms(T.folder||"")),a&&a()},[o==null?void 0:o.nonce]),s.useEffect(()=>{let T=!1;return(async()=>{try{X(!0);const ie=await fetch("/api/sites");if(!ie.ok)throw new Error(`HTTP ${ie.status}`);const Ce=await ie.json();if(T)return;const Ee=Array.isArray(Ce==null?void 0:Ce.sites)?Ce.sites:[];E(Ee.map(Ne=>({...Ne,id:(Ne==null?void 0:Ne.id)!=null?String(Ne.id):""})).filter(Ne=>Ne.id))}catch(ie){T||(console.error("Failed to load sites:",ie),E([]))}finally{T||X(!1)}})(),()=>{T=!0}},[]);const me=((g=ul[i.type])==null?void 0:g.prism)||"powershell",w=T=>{c(G=>({...G,...T}))},W=T=>{c(G=>({...G,sites:{mode:T,values:T==="specific"?G.sites.values||[]:[]}}))},F=T=>{const G=Array.isArray(T)?T:typeof T=="string"?T.split(",").map(ie=>ie.trim()).filter(Boolean):[];c(ie=>({...ie,sites:{mode:"specific",values:G.map(Ce=>String(Ce))}}))},te=()=>{c(T=>({...T,variables:[...T.variables,{id:`${Date.now()}_${Math.random().toString(36).slice(2,8)}`,name:"",label:"",type:"string",defaultValue:"",required:!1,description:""}]}))},ee=(T,G)=>{c(ie=>({...ie,variables:ie.variables.map(Ce=>Ce.id===T?{...Ce,...G}:Ce)}))},be=T=>{c(G=>({...G,variables:G.variables.filter(ie=>ie.id!==T)}))},Re=async T=>{const G=Array.from(T.target.files||[]);if(!G.length)return;const ie=G.map(Ee=>new Promise(Ne=>{const Ke=new FileReader;Ke.onload=()=>{const at=Ke.result||"",ut=typeof at=="string"&&at.includes(",")?at.split(",",2)[1]:at;Ne({id:`${Date.now()}_${Math.random().toString(36).slice(2,8)}`,fileName:Ee.name,size:Ee.size,mimeType:Ee.type,data:ut})},Ke.onerror=()=>Ne(null),Ke.readAsDataURL(Ee)})),Ce=(await Promise.all(ie)).filter(Boolean);Ce.length&&c(Ee=>({...Ee,files:[...Ee.files,...Ce]})),T.target.value=""},Ae=T=>{c(G=>({...G,files:G.files.filter(ie=>ie.id!==T)}))},Le=()=>{if(p)return p;const T=bn(h||i.name||(u?"playbook":"assembly")),G=Ms(y);return G?`${G}/${T}`:T},Fe=async()=>{if(!i.name.trim()){alert("Assembly Name is required.");return}const T=yl(i);T.type=i.type;const G=Le();if(!G){alert("Unable to determine file path.");return}S(!0);try{if(p){const ie=await fetch("/api/assembly/edit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:de,path:p,content:T})}),Ce=await ie.json().catch(()=>({}));if(!ie.ok)throw new Error((Ce==null?void 0:Ce.error)||`HTTP ${ie.status}`);Ce!=null&&Ce.rel_path&&(l(Ce.rel_path),C(Ms(Ce.rel_path.split("/").slice(0,-1).join("/"))),f(Ce.rel_path.split("/").pop()||h))}else{const ie=await fetch("/api/assembly/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:de,kind:"file",path:G,content:T,type:i.type})}),Ce=await ie.json();if(!ie.ok)throw new Error((Ce==null?void 0:Ce.error)||`HTTP ${ie.status}`);Ce.rel_path?(l(Ce.rel_path),C(Ce.rel_path.split("/").slice(0,-1).join("/")),f(Ce.rel_path.split("/").pop()||"")):(l(G),f(G.split("/").pop()||""))}d&&d()}catch(ie){console.error("Failed to save assembly:",ie),alert(ie.message||"Failed to save assembly")}finally{S(!1)}},je=async()=>{try{const T=bn(v||h||i.name),G=await fetch("/api/assembly/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:de,kind:"file",path:p,new_name:T,type:i.type})}),ie=await G.json();if(!G.ok)throw new Error((ie==null?void 0:ie.error)||`HTTP ${G.status}`);const Ce=ie.rel_path||p;l(Ce),C(Ce.split("/").slice(0,-1).join("/")),f(Ce.split("/").pop()||T),k(!1)}catch(T){console.error("Failed to rename assembly:",T),alert(T.message||"Failed to rename"),k(!1)}},V=async()=>{if(!p){R(!1);return}try{const T=await fetch("/api/assembly/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({island:de,kind:"file",path:p})});if(!T.ok){const G=await T.json().catch(()=>({}));throw new Error((G==null?void 0:G.error)||`HTTP ${T.status}`)}R(!1),c(sn(r)),l(""),f(""),d&&d()}catch(T){console.error("Failed to delete assembly:",T),alert(T.message||"Failed to delete assembly"),R(!1)}},O=((L=i.sites)==null?void 0:L.mode)==="specific"?"specific":"all",M=Array.isArray((we=i.sites)==null?void 0:we.values)?i.sites.values.map(T=>String(T)):[];return e.jsxs(m,{sx:{display:"flex",flexDirection:"column",flex:1,height:"100%",overflow:"hidden",ml:-.95,mt:-.95,bgcolor:pl},children:[e.jsx(m,{sx:{flex:1,overflow:"auto",p:{xs:2,md:3}},children:e.jsxs(Qe,{sx:{p:{xs:2.5,md:3},...cl,minHeight:"100%"},elevation:0,children:[e.jsxs(os,{container:!0,alignItems:"center",justifyContent:"space-between",sx:{mb:3},children:[e.jsx(os,{item:!0,xs:12,sm:6,children:e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:"Assembly Editor"}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Create and edit variables, scripts, and other fields related to assemblies."})]})}),e.jsx(os,{item:!0,xs:12,sm:6,children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1.5,flexWrap:"wrap",justifyContent:{xs:"flex-start",sm:"flex-end"},mt:{xs:2,sm:0}},children:[p?e.jsx(st,{title:"Rename File",children:e.jsx(Z,{size:"small",onClick:()=>{j(h),k(!0)},sx:{color:"#58a6ff",textTransform:"none"},children:"Rename"})}):null,p?e.jsx(st,{title:"Delete Assembly",children:e.jsx(Z,{size:"small",onClick:()=>R(!0),sx:{color:"#ff6b6b",textTransform:"none"},children:"Delete"})}):null,e.jsx(Z,{variant:"outlined",onClick:Fe,disabled:x,sx:{color:"#58a6ff",borderColor:"#58a6ff",textTransform:"none",backgroundColor:x?Pt.primaryActionSaving:Pt.field,"&:hover":{borderColor:"#7db7ff",backgroundColor:Pt.primaryActionHover},"&.Mui-disabled":{color:"#3c4452",borderColor:"#2b3544"}},children:x?"Saving...":"Save Assembly"})]})})]}),e.jsx(m,{sx:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:2,mb:0,flexWrap:"wrap"},children:e.jsx(m,{sx:{flex:"1 1 auto",minWidth:120},children:e.jsx($,{variant:"caption",sx:Zs,children:"Overview"})})}),e.jsxs(os,{container:!0,spacing:2,children:[e.jsxs(os,{item:!0,xs:12,md:6,children:[e.jsx(Ie,{label:"Assembly Name",value:i.name,onChange:T=>w({name:T.target.value}),fullWidth:!0,variant:"outlined",sx:{...rs,mb:2}}),e.jsx(Ie,{label:"Description",value:i.description,onChange:T=>w({description:T.target.value}),multiline:!0,minRows:2,maxRows:8,fullWidth:!0,variant:"outlined",sx:{...rs,"& .MuiOutlinedInput-inputMultiline":{padding:"6px 12px",lineHeight:1.4}}})]}),e.jsxs(os,{item:!0,xs:12,md:6,children:[e.jsx(Ie,{select:!0,fullWidth:!0,label:"Category",value:i.category,onChange:T=>w({category:T.target.value}),sx:{...Ps,mb:2},SelectProps:{MenuProps:Es},children:il.map(T=>e.jsx(fe,{value:T.key,children:T.label},T.key))}),e.jsx(Ie,{select:!0,fullWidth:!0,label:"Type",value:i.type,onChange:T=>w({type:T.target.value}),sx:Ps,SelectProps:{MenuProps:Es},children:Se.map(T=>e.jsx(fe,{value:T.key,children:T.label},T.key))})]})]}),e.jsxs(m,{sx:{mt:3},children:[e.jsx($,{variant:"caption",sx:{...Zs,mb:1},children:"Script Content"}),e.jsx(m,{sx:{border:"1px solid #2b3544",borderRadius:1,background:Pt.field},children:e.jsx(En,{value:i.script,onValueChange:T=>w({script:T}),highlight:T=>fl(T,me),padding:12,placeholder:p?`Editing: ${p}`:"Start typing your script...",style:{fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',fontSize:14,color:"#e6edf3",background:Pt.field,outline:"none",minHeight:320,lineHeight:1.45,caretColor:"#58a6ff"}})})]}),e.jsxs(os,{container:!0,spacing:2,sx:{mt:4},children:[e.jsx(os,{item:!0,xs:12,md:6,children:e.jsx(Ie,{label:"Timeout (seconds)",type:"text",inputMode:"numeric",value:i.timeoutSeconds,onChange:T=>{const G=T.target.value.replace(/[^0-9]/g,"");w({timeoutSeconds:G?Number(G):0})},fullWidth:!0,variant:"outlined",sx:rs,helperText:"Timeout this script if not completed within X seconds"})}),e.jsx(os,{item:!0,xs:12,md:6,children:e.jsxs(m,{sx:{display:"flex",flexDirection:{xs:"column",sm:"row"},gap:2,alignItems:"flex-start"},children:[e.jsxs(Ie,{select:!0,fullWidth:!0,label:"Site Scope",value:O,onChange:T=>W(T.target.value),sx:{...Ps,width:{xs:"100%",sm:320,lg:360}},SelectProps:{MenuProps:Es},children:[e.jsx(fe,{value:"all",children:"All Sites"}),e.jsx(fe,{value:"specific",children:"Specific Sites"})]}),O==="specific"?e.jsx(Ie,{select:!0,fullWidth:!0,label:"Allowed Sites",value:M,onChange:T=>F(Array.isArray(T.target.value)?T.target.value:[]),sx:{...Ps,width:{xs:"100%",sm:360,lg:420}},SelectProps:{multiple:!0,renderValue:T=>!T||T.length===0?e.jsx($,{sx:{color:"#6b7687"},children:"Select sites"}):T.map(ie=>{var Ce;return((Ce=ce.get(String(ie)))==null?void 0:Ce.name)||String(ie)}).join(", "),MenuProps:Es},children:U?e.jsx(fe,{disabled:!0,children:e.jsx(tn,{primary:"Loading sites..."})}):z.length?z.map(T=>{const G=String(T.id),ie=M.includes(G);return e.jsxs(fe,{value:G,sx:{display:"flex",alignItems:"flex-start",gap:1},children:[e.jsx(At,{checked:ie,sx:{color:"#58a6ff",mr:1}}),e.jsx(tn,{primary:T.name,secondary:T.description?T.description:void 0,primaryTypographyProps:{sx:{color:"#e6edf3"}},secondaryTypographyProps:{sx:{color:"#7f8794"}}})]},G)}):e.jsx(fe,{disabled:!0,children:e.jsx(tn,{primary:"No sites available"})})}):null]})})]}),e.jsxs(m,{sx:{mt:3},children:[e.jsx($,{variant:"caption",sx:{...Zs,mb:1},children:"Environment Variables"}),e.jsxs($,{variant:"body2",sx:{color:"#9ba3b4",mb:2},children:["Variables are dynamically passed into the script as environment variables at runtime. They are written like ",e.jsx("b",{children:"$env:variableName"})," in the script editor."]}),(i.variables||[]).length?e.jsx(m,{sx:{display:"flex",flexDirection:"column",gap:2},children:i.variables.map(T=>e.jsx(Qe,{sx:{p:2,bgcolor:Pt.field,border:"1px solid #2b3544",borderRadius:1},children:e.jsxs(m,{sx:{display:"flex",flexDirection:"column",gap:{xs:2,lg:1.5}},children:[e.jsxs(m,{sx:{display:"flex",flexWrap:"wrap",alignItems:"center",gap:{xs:2,lg:1.5},pt:.5},children:[e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 28%"},minWidth:{lg:220}},children:e.jsx(st,{title:"This is the name of the variable you will be referencing inside of the script via $env:<variable>.",arrow:!0,placement:"top-start",children:e.jsx(Ie,{label:"Variable",value:T.name,onChange:G=>ee(T.id,{name:G.target.value}),fullWidth:!0,variant:"outlined",sx:rs})})}),e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 22%"},minWidth:{lg:180}},children:e.jsx(st,{title:"This is the name that will be given to the variable and seen by Borealis server operators.",arrow:!0,placement:"top-start",children:e.jsx(Ie,{label:"Display Label",value:T.label,onChange:G=>ee(T.id,{label:G.target.value}),fullWidth:!0,variant:"outlined",sx:rs})})}),e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 18%"},minWidth:{lg:160}},children:e.jsx(st,{title:"This defines the type of variable data the script should expect.",arrow:!0,placement:"top-start",children:e.jsx(Ie,{select:!0,fullWidth:!0,label:"Type",value:T.type,onChange:G=>ee(T.id,{type:G.target.value}),sx:Ps,SelectProps:{MenuProps:Es},children:ll.map(G=>e.jsx(fe,{value:G.key,children:G.label},G.key))})})}),e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 24%"},minWidth:{lg:220},display:"flex",alignItems:"center"},children:T.type==="boolean"?e.jsx(st,{title:"This is the value that will be pre-populated in the assembly when ran. Use a sensible default value.",arrow:!0,placement:"top-start",children:e.jsx(bs,{control:e.jsx(At,{checked:!!T.defaultValue,onChange:G=>ee(T.id,{defaultValue:G.target.checked}),sx:{color:"#58a6ff"}}),label:"Default Value",sx:{color:"#9ba3b4",m:0,"& .MuiFormControlLabel-label":{fontSize:"0.95rem"}}})}):e.jsx(st,{title:"This is the value that will be pre-populated in the assembly when ran. Use a sensible default value.",arrow:!0,placement:"top-start",children:e.jsx(Ie,{label:"Default Value",value:T.defaultValue??"",onChange:G=>ee(T.id,{defaultValue:G.target.value}),fullWidth:!0,variant:"outlined",sx:rs})})}),e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 28%"},minWidth:{lg:220}},children:e.jsx(st,{title:"Instruct the operator in why this variable exists and how to set it appropriately.",arrow:!0,placement:"top-start",children:e.jsx(Ie,{label:"Description",value:T.description,onChange:G=>ee(T.id,{description:G.target.value}),fullWidth:!0,variant:"outlined",sx:rs})})}),e.jsx(m,{sx:{flex:{xs:"1 1 100%",lg:"0 0 auto"},display:"flex",justifyContent:"flex-end",alignItems:"center",ml:{lg:"auto"}},children:e.jsx(st,{title:"Remove this Variable.",arrow:!0,children:e.jsx(nt,{onClick:()=>be(T.id),sx:{color:"#ff6b6b"},children:e.jsx($s,{})})})})]}),e.jsx(m,{sx:{display:"flex",flexWrap:"wrap",gap:{xs:2,lg:1.5}},children:e.jsxs(m,{sx:{flex:{xs:"1 1 100%",lg:"0 1 50%"},minWidth:{lg:220},display:"flex",alignItems:"center",gap:1.5},children:[e.jsx($,{variant:"caption",sx:{color:"#9ba3b4",fontSize:"0.75rem",ml:.5},children:"Required"}),e.jsx(At,{checked:!!T.required,onChange:G=>ee(T.id,{required:G.target.checked}),sx:{color:"#58a6ff",p:.5},inputProps:{"aria-label":"Required"}})]})})]})},T.id))}):e.jsx($,{variant:"body2",sx:{color:"#787f8b",mb:1},children:"No variables have been defined."}),e.jsx(Z,{startIcon:e.jsx(ts,{}),onClick:te,sx:{mt:2,color:"#58a6ff",textTransform:"none"},children:"Add Variable"})]}),e.jsxs(m,{sx:{mt:4},children:[e.jsx($,{variant:"caption",sx:{...Zs,mb:1},children:"Files"}),e.jsx($,{variant:"body2",sx:{color:"#9ba3b4",mb:2},children:"Upload supporting files. They will be embedded as Base64 and available to the assembly at runtime."}),(i.files||[]).length?e.jsx(m,{sx:{display:"flex",flexDirection:"column",gap:1.5},children:i.files.map(T=>e.jsxs(Qe,{sx:{p:1.5,bgcolor:Pt.field,border:"1px solid #2b3544",display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs(m,{children:[e.jsx($,{variant:"body2",sx:{color:"#e6edf3"},children:T.fileName}),e.jsxs($,{variant:"caption",sx:{color:"#7f8794"},children:[hl(T.size),T.mimeType?`${T.mimeType}`:""]})]}),e.jsx(nt,{onClick:()=>Ae(T.id),sx:{color:"#ff6b6b"},children:e.jsx($s,{})})]},T.id))}):e.jsx($,{variant:"body2",sx:{color:"#787f8b",mb:1},children:"No files uploaded yet."}),e.jsxs(Z,{component:"label",startIcon:e.jsx(go,{}),sx:{mt:2,color:"#58a6ff",textTransform:"none"},children:["Upload File",e.jsx("input",{type:"file",hidden:!0,multiple:!0,onChange:Re})]})]})]})}),e.jsx(jl,{open:I,value:v,onChange:j,onCancel:()=>k(!1),onSave:je}),e.jsx(Zt,{open:B,message:"Deleting this assembly cannot be undone. Continue?",onCancel:()=>R(!1),onConfirm:V})]})}Bn.registerModules([On]);const Ro=Pn.withParams({accentColor:"#FFA6FF",backgroundColor:"#1f2836",browserColorScheme:"dark",chromeBackgroundColor:{ref:"foregroundColor",mix:.07,onto:"backgroundColor"},fontFamily:{googleFont:"IBM Plex Sans"},foregroundColor:"#FFF",headerFontSize:14}),wl=Ro.themeName||"ag-theme-quartz",Lt='"IBM Plex Sans", "Helvetica Neue", Arial, sans-serif',yn='"Quartz Regular"';function vl({counts:n}){const t=Math.max(1,Number((n==null?void 0:n.total_targets)||0)),o=[{key:"success",color:"#00d18c"},{key:"running",color:"#58a6ff"},{key:"failed",color:"#ff4f4f"},{key:"timed_out",color:"#b36ae2"},{key:"expired",color:"#777777"},{key:"pending",color:"#999999"}],a=u=>u==="pending"?"Scheduled":u.replace(/_/g," ").replace(/^./,r=>r.toUpperCase()),d=o.filter(u=>u.key!=="pending").some(u=>Number((n==null?void 0:n[u.key])||0)>0);return e.jsxs(m,{sx:{display:"flex",flexDirection:"column",gap:.25,lineHeight:1.7,fontFamily:Lt},children:[e.jsx(m,{sx:{display:"flex",borderRadius:1,overflow:"hidden",width:220,height:6},children:o.map(u=>{const r=Number((n==null?void 0:n[u.key])||0);if(!r)return null;const i=`${Math.round(r/t*100)}%`;return e.jsx(m,{component:"span",sx:{display:"block",height:"100%",width:i,backgroundColor:u.color}},u.key)})}),e.jsx(m,{sx:{display:"flex",flexWrap:"wrap",columnGap:.75,rowGap:.25,color:"#aaa",fontSize:11,fontFamily:Lt},children:!d&&Number((n==null?void 0:n.pending)||0)>0?e.jsx(m,{component:"span",children:"Scheduled"}):o.filter(u=>Number((n==null?void 0:n[u.key])||0)>0).map(u=>e.jsxs(m,{component:"span",sx:{display:"inline-flex",alignItems:"center",gap:.5},children:[e.jsx(m,{component:"span",sx:{width:6,height:6,borderRadius:1,backgroundColor:u.color}}),n==null?void 0:n[u.key]," ",a(u.key)]},u.key))})]})}function Sl({onCreateJob:n,onEditJob:t,refreshToken:o}){const[a,d]=s.useState([]),[u,r]=s.useState(!1),[i,c]=s.useState(""),[p,l]=s.useState(!1),[h,f]=s.useState(()=>new Set),y=s.useRef(null),C=s.useCallback(async({showLoading:E=!1}={})=>{E&&(r(!0),c(""));try{const U=await fetch("/api/scheduled_jobs"),X=await U.json().catch(()=>({}));if(!U.ok)throw new Error((X==null?void 0:X.error)||`HTTP ${U.status}`);const ue=de=>{const me=String(de||"").toLowerCase(),w={immediately:"Immediately",once:"Once",every_5_minutes:"Every 5 Minutes",every_10_minutes:"Every 10 Minutes",every_15_minutes:"Every 15 Minutes",every_30_minutes:"Every 30 Minutes",every_hour:"Every Hour",daily:"Daily",weekly:"Weekly",monthly:"Monthly",yearly:"Yearly"};if(w[me])return w[me];try{return me.replace(/_/g," ").replace(/^./,W=>W.toUpperCase())}catch{return String(de||"")}},Se=de=>{if(!de)return"";try{const me=new Date(Number(de)*1e3);return Number.isNaN(me==null?void 0:me.getTime())?"":me.toLocaleString(void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"numeric",minute:"2-digit"})}catch{return""}},ce=((X==null?void 0:X.jobs)||[]).map(de=>{var te;const me=Array.isArray(de.components)&&((te=de.components[0])==null?void 0:te.name)||"Demonstration Component",w=Array.isArray(de.targets)?`${de.targets.length} device${de.targets.length!==1?"s":""}`:"",W=ue(de.schedule_type||"immediately"),F={total_targets:Array.isArray(de.targets)?de.targets.length:0,pending:Array.isArray(de.targets)?de.targets.length:0,...de.result_counts||{}};return F&&F.total_targets==null&&(F.total_targets=Array.isArray(de.targets)?de.targets.length:0),{id:de.id,name:de.name,scriptWorkflow:me,target:w,occurrence:W,lastRun:Se(de.last_run_ts),nextRun:Se(de.next_run_ts||de.start_ts),result:de.last_status||(de.next_run_ts?"Scheduled":""),resultsCounts:F,enabled:!!de.enabled,raw:de}});d(ce),c(""),f(de=>{if(!de.size)return de;const me=new Set(ce.map((F,te)=>F.id??F.name??String(te)));let w=!1;const W=new Set;return de.forEach(F=>{me.has(F)?W.add(F):w=!0}),w?W:de})}catch(U){d([]),f(()=>new Set),c(String((U==null?void 0:U.message)||U||"Failed to load scheduled jobs"))}finally{E&&r(!1)}},[]);s.useEffect(()=>{let E,U=!0;return(async()=>U&&await C({showLoading:!0}))(),E=setInterval(()=>{C()},5e3),()=>{U=!1,E&&clearInterval(E)}},[C,o]);const I=s.useCallback(E=>{y.current=E.api},[]);s.useEffect(()=>{const E=y.current;E&&(u?E.showLoadingOverlay():a.length?E.hideOverlay():E.showNoRowsOverlay())},[u,a]),s.useEffect(()=>{const E=y.current;E&&E.forEachNode(U=>{const X=h.has(U.id);U.isSelected()!==X&&U.setSelected(X)})},[a,h]);const k=h.size>0,v=s.useCallback(()=>{const E=y.current;if(!E)return;const U=E.getSelectedNodes(),X=new Set;U.forEach(ue=>{(ue==null?void 0:ue.id)!=null&&X.add(String(ue.id))}),f(X)},[]),j=s.useCallback(E=>{var U,X;return((U=E==null?void 0:E.data)==null?void 0:U.id)??((X=E==null?void 0:E.data)==null?void 0:X.name)??String((E==null?void 0:E.rowIndex)??"")},[]),B=s.useCallback(E=>{const U=E.data;if(!U)return null;const X=ue=>{ue.preventDefault(),ue.stopPropagation(),typeof t=="function"&&t(U.raw)};return e.jsx(Z,{onClick:X,sx:{color:"#58a6ff",textTransform:"none",p:0,minWidth:0,fontFamily:Lt},children:U.name||"-"})},[t]),R=s.useCallback(E=>{var U;return e.jsx(vl,{counts:(U=E==null?void 0:E.data)==null?void 0:U.resultsCounts})},[]),x=s.useCallback(E=>{const U=E.data;if(!U)return null;const X=async ue=>{ue.stopPropagation();const Se=ue.target.checked;try{await fetch(`/api/scheduled_jobs/${U.id}/toggle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({enabled:Se})})}catch{}d(ce=>ce.map(de=>{if((de.id??de.name)===(U.id??U.name)){const me={...de.raw||{},enabled:Se};return{...de,enabled:Se,raw:me}}return de}))};return e.jsx(co,{size:"small",checked:!!U.enabled,onChange:X,onClick:ue=>ue.stopPropagation(),sx:{"& .MuiSwitch-switchBase.Mui-checked":{color:"#58a6ff"},"& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track":{bgcolor:"#58a6ff"}}})},[]),S=s.useMemo(()=>[{headerName:"",field:"__checkbox__",checkboxSelection:!0,headerCheckboxSelection:!0,maxWidth:60,minWidth:60,sortable:!1,filter:!1,resizable:!1,suppressMenu:!0,pinned:!1},{headerName:"Name",field:"name",cellRenderer:B,sort:"asc"},{headerName:"Assembly(s)",field:"scriptWorkflow",valueGetter:E=>{var U;return((U=E.data)==null?void 0:U.scriptWorkflow)||"Demonstration Component"}},{headerName:"Target",field:"target"},{headerName:"Recurrence",field:"occurrence"},{headerName:"Last Run",field:"lastRun"},{headerName:"Next Run",field:"nextRun"},{headerName:"Results",field:"resultsCounts",minWidth:280,cellRenderer:R,sortable:!1,filter:!1},{headerName:"Enabled",field:"enabled",minWidth:140,maxWidth:160,cellRenderer:x,sortable:!1,filter:!1,resizable:!1,suppressMenu:!0}],[x,B,R]),z=s.useMemo(()=>({sortable:!0,filter:"agTextColumnFilter",resizable:!0,flex:1,minWidth:140,cellStyle:{display:"flex",alignItems:"center",color:"#f5f7fa",fontFamily:Lt,fontSize:"13px"},headerClass:"scheduled-jobs-grid-header"}),[]);return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e",color:"#f5f7fa",fontFamily:Lt,display:"flex",flexDirection:"column",flexGrow:1,minWidth:0,minHeight:420},elevation:2,children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",p:2,borderBottom:"1px solid #2a2a2a"},children:[e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:.3},children:"Scheduled Jobs"}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"List of automation jobs with schedules, results, and actions."})]}),e.jsxs(m,{sx:{display:"flex",gap:1,alignItems:"center"},children:[e.jsx(Z,{variant:"outlined",size:"small",disabled:!k,sx:{color:k?"#ff8080":"#666",borderColor:k?"#ff8080":"#333",textTransform:"none",fontFamily:Lt,"&:hover":{borderColor:k?"#ff8080":"#333"}},onClick:()=>l(!0),children:"Delete Job"}),e.jsx(Z,{variant:"contained",size:"small",sx:{bgcolor:"#58a6ff",color:"#0b0f19",textTransform:"none",fontFamily:Lt,"&:hover":{bgcolor:"#7db7ff"}},onClick:()=>n&&n(),children:"Create Job"})]})]}),u&&e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,color:"#7db7ff",px:2,py:1.5,borderBottom:"1px solid #2a2a2a"},children:[e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),e.jsx($,{variant:"body2",children:"Loading scheduled jobs…"})]}),i&&e.jsx(m,{sx:{px:2,py:1.5,color:"#ff8080",borderBottom:"1px solid #2a2a2a"},children:e.jsx($,{variant:"body2",children:i})}),e.jsx(m,{sx:{flexGrow:1,minHeight:0,display:"flex",flexDirection:"column",mt:"10px",px:2,pb:2},children:e.jsx(m,{className:wl,sx:{width:"100%",height:"100%",flexGrow:1,fontFamily:Lt,"--ag-font-family":Lt,"--ag-icon-font-family":yn,"--ag-row-border-style":"solid","--ag-row-border-color":"#2a2a2a","--ag-row-border-width":"1px","& .ag-root-wrapper":{borderRadius:1,minHeight:320},"& .ag-root, & .ag-header, & .ag-center-cols-container, & .ag-paging-panel":{fontFamily:Lt},"& .ag-icon":{fontFamily:yn},"& .scheduled-jobs-grid-header":{fontFamily:Lt,fontWeight:600,color:"#f5f7fa"}},children:e.jsx(An,{rowData:a,columnDefs:S,defaultColDef:z,animateRows:!0,rowHeight:46,headerHeight:44,suppressCellFocus:!0,rowSelection:"multiple",rowMultiSelectWithClick:!0,suppressRowClickSelection:!0,getRowId:j,overlayNoRowsTemplate:"<span class='ag-overlay-no-rows-center'>No scheduled jobs found.</span>",onGridReady:I,onSelectionChanged:v,theme:Ro,style:{width:"100%",height:"100%",fontFamily:Lt,"--ag-icon-font-family":yn}})})}),e.jsxs(Ze,{open:p,onClose:()=>l(!1),PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Are you sure you want to delete this job(s)?"}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:()=>l(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:async()=>{try{const E=Array.from(h),U=new Set(E);await Promise.allSettled(E.map(X=>fetch(`/api/scheduled_jobs/${X}`,{method:"DELETE"}))),d(X=>X.filter((ue,Se)=>{const ce=j({data:ue,rowIndex:Se});return!U.has(ce)})),f(()=>new Set)}catch{}l(!1),await C({showLoading:!0})},variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},children:"Confirm"})]})]})]})}const en={width:12,height:12,border:"none",background:"transparent",opacity:0,pointerEvents:"none"},jt={pending:{label:"Pending",color:"#aab2bf",Icon:hr},running:{label:"Running",color:"#58a6ff",Icon:mr},expired:{label:"Expired",color:"#aab2bf",Icon:xr},success:{label:"Success",color:"#00d18c",Icon:gr},failed:{label:"Failed",color:"#ff4f4f",Icon:br}},Cl=[{key:"hostname",label:"Hostname"},{key:"online",label:"Status"},{key:"site",label:"Site"},{key:"ran_on",label:"Ran On"},{key:"job_status",label:"Job Status"},{key:"output",label:"StdOut / StdErr"}];function _l({data:n}){const{label:t,color:o,count:a,onClick:d,isActive:u,Icon:r}=n||{},i=Number.isFinite(a)?a:Number(a)||0,c=o||"#333",p=o?`${o}55`:"rgba(88,166,255,0.35)",l=s.useCallback(h=>{h==null||h.preventDefault(),h==null||h.stopPropagation(),d&&d()},[d]);return e.jsxs(m,{onClick:l,sx:{px:5.4,py:3.8,backgroundColor:"#1f1f1f",borderRadius:1.5,border:`1px solid ${c}`,boxShadow:u?`0 0 0 2px ${p}`:"none",cursor:"pointer",minWidth:324,textAlign:"left",transition:"border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease",transform:u?"translateY(-2px)":"none",display:"flex",alignItems:"flex-start",justifyContent:"flex-start"},children:[e.jsx(De,{type:"target",position:ze.Left,id:"left-top",style:{...en,top:"32%",transform:"translateY(-50%)"},isConnectable:!1}),e.jsx(De,{type:"target",position:ze.Left,id:"left-bottom",style:{...en,top:"68%",transform:"translateY(-50%)"},isConnectable:!1}),e.jsx(De,{type:"source",position:ze.Right,id:"right-top",style:{...en,top:"32%",transform:"translateY(-50%)"},isConnectable:!1}),e.jsx(De,{type:"source",position:ze.Right,id:"right-bottom",style:{...en,top:"68%",transform:"translateY(-50%)"},isConnectable:!1}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1.2},children:[r?e.jsx(r,{sx:{color:o||"#e6edf3",fontSize:32}}):null,e.jsx($,{variant:"subtitle2",sx:{fontWeight:600,color:o||"#e6edf3",userSelect:"none",fontSize:"1.3rem"},children:`${i} ${t||""}`})]})]})}function ws({title:n,action:t}){return e.jsxs(m,{sx:{mt:2,mb:1,display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsx($,{variant:"subtitle1",sx:{color:"#7db7ff"},children:n}),t||null]})}function nn(n=[],t={}){return n.map(o=>e.jsx(ys,{itemId:o.id,label:o.label,children:o.children&&o.children.length?nn(o.children,t):null},o.id))}function No(n,t){const o={},a={id:"root_s",label:"Scripts",path:"",isFolder:!0,children:[]};return o[a.id]=a,(t||[]).forEach(d=>{const u=(d||"").split("/");let r=a.children,i="";u.forEach(c=>{const p=i?`${i}/${c}`:c;let l=r.find(h=>h.id===p);l||(l={id:p,label:c,path:p,isFolder:!0,children:[]},r.push(l),o[p]=l),r=l.children,i=p})}),(n||[]).forEach(d=>{const u=(d.rel_path||"").split("/");let r=a.children,i="";u.forEach((c,p)=>{const l=i?`${i}/${c}`:c,h=p===u.length-1;let f=r.find(y=>y.id===l);f||(f={id:l,label:h&&(d.name||d.file_name)||c,path:l,isFolder:!h,fileName:d.file_name,script:h?d:null,children:[]},r.push(f),o[l]=f),h||(r=f.children,i=l)})}),{root:[a],map:o}}function kl(n,t){return No(n,t)}function Il(n,t){const o={},a={id:"root_w",label:"Workflows",path:"",isFolder:!0,children:[]};return o[a.id]=a,(t||[]).forEach(d=>{const u=(d||"").split("/");let r=a.children,i="";u.forEach(c=>{const p=i?`${i}/${c}`:c;let l=r.find(h=>h.id===p);l||(l={id:p,label:c,path:p,isFolder:!0,children:[]},r.push(l),o[p]=l),r=l.children,i=p})}),(n||[]).forEach(d=>{const u=(d.rel_path||"").split("/");let r=a.children,i="";u.forEach((c,p)=>{var y;const l=i?`${i}/${c}`:c,h=p===u.length-1;let f=r.find(C=>C.id===l);f||(f={id:l,label:h?((y=d.tab_name)==null?void 0:y.trim())||d.file_name:c,path:l,isFolder:!h,fileName:d.file_name,workflow:h?d:null,children:[]},r.push(f),o[l]=f),h||(r=f.children,i=l)})}),{root:[a],map:o}}function Rl(n=[]){return(Array.isArray(n)?n:[]).map(t=>{if(!t||typeof t!="object")return null;const o=typeof t.name=="string"?t.name.trim():typeof t.key=="string"?t.key.trim():"";if(!o)return null;const a=typeof t.label=="string"&&t.label.trim()?t.label.trim():o,d=typeof t.type=="string"?t.type.toLowerCase():"string",u=!!t.required,r=typeof t.description=="string"?t.description:"";let i="";return Object.prototype.hasOwnProperty.call(t,"default")?i=t.default:Object.prototype.hasOwnProperty.call(t,"defaultValue")?i=t.defaultValue:Object.prototype.hasOwnProperty.call(t,"default_value")&&(i=t.default_value),{name:o,label:a,type:d,required:u,description:r,default:i}}).filter(Boolean)}function Ds(n,t){if(n==="boolean"){if(typeof t=="boolean")return t;if(typeof t=="number")return t!==0;if(t==null)return!1;const o=String(t).trim().toLowerCase();return o?["true","1","yes","on"].includes(o):!1}if(n==="number"){if(t==null||t==="")return"";if(typeof t=="number"&&Number.isFinite(t))return String(t);const o=Number(t);return Number.isFinite(o)?String(o):""}return t==null?"":String(t)}function eo(n=[],t=[],o={}){const a=Rl(n),d={},u={};(Array.isArray(t)?t:[]).forEach(c=>{if(!c||typeof c!="object")return;const p=typeof c.name=="string"?c.name.trim():"";p&&(Object.prototype.hasOwnProperty.call(c,"value")?d[p]=c.value:Object.prototype.hasOwnProperty.call(c,"default")&&(d[p]=c.default),u[p]={label:typeof c.label=="string"&&c.label.trim()?c.label.trim():p,type:typeof c.type=="string"?c.type.toLowerCase():void 0,required:!!c.required,description:typeof c.description=="string"?c.description:"",default:Object.prototype.hasOwnProperty.call(c,"default")?c.default:""})}),o&&typeof o=="object"&&Object.entries(o).forEach(([c,p])=>{const l=typeof c=="string"?c.trim():"";l&&(d[l]=p)});const r=new Set,i=a.map(c=>{const p=Object.prototype.hasOwnProperty.call(d,c.name)?d[c.name]:void 0;return r.add(c.name),{...c,value:p!==void 0?Ds(c.type,p):Ds(c.type,c.default)}});return(Array.isArray(t)?t:[]).forEach(c=>{if(!c||typeof c!="object")return;const p=typeof c.name=="string"?c.name.trim():"";if(!p||r.has(p))return;const l=u[p]||{},h=l.type||(typeof d[p]=="boolean"?"boolean":typeof d[p]=="number"?"number":"string"),f=Object.prototype.hasOwnProperty.call(l,"default")?l.default:"",y=Object.prototype.hasOwnProperty.call(d,p)?d[p]:Object.prototype.hasOwnProperty.call(c,"value")?c.value:f;i.push({name:p,label:l.label||p,type:h,required:!!l.required,description:l.description||"",default:f,value:Ds(h,y)}),r.add(p)}),Object.entries(d).forEach(([c,p])=>{const l=typeof c=="string"?c.trim():"";if(!l||r.has(l))return;const h=typeof p=="boolean"?"boolean":typeof p=="number"?"number":"string";i.push({name:l,label:l,type:h,required:!1,description:"",default:"",value:Ds(h,p)}),r.add(l)}),i}function Nl({comp:n,onRemove:t,onVariableChange:o,errors:a={}}){const d=Array.isArray(n.variables)?n.variables.filter(r=>r&&typeof r.name=="string"&&r.name):[],u=n.description||n.path||"";return e.jsx(Qe,{sx:{bgcolor:"#2a2a2a",border:"1px solid #3a3a3a",p:1.2,mb:1.2,borderRadius:1},children:e.jsxs(m,{sx:{display:"flex",gap:2},children:[e.jsxs(m,{sx:{flex:1},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#e6edf3"},children:(n.type==="script",n.name)}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:u})]}),e.jsx(In,{orientation:"vertical",flexItem:!0,sx:{borderColor:"#333"}}),e.jsxs(m,{sx:{flex:1},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:1},children:"Variables"}),d.length?e.jsx(m,{sx:{display:"flex",flexDirection:"column",gap:1.5},children:d.map(r=>e.jsx(m,{children:r.type==="boolean"?e.jsxs(e.Fragment,{children:[e.jsx(bs,{control:e.jsx(At,{size:"small",checked:!!r.value,onChange:i=>o(n.localId,r.name,i.target.checked)}),label:e.jsxs($,{variant:"body2",children:[r.label,r.required?" *":""]})}),r.description?e.jsx($,{variant:"caption",sx:{color:"#888",ml:3},children:r.description}):null]}):e.jsx(Ie,{fullWidth:!0,size:"small",label:`${r.label}${r.required?" *":""}`,type:r.type==="number"?"number":r.type==="credential"?"password":"text",value:r.value??"",onChange:i=>o(n.localId,r.name,i.target.value),InputLabelProps:{shrink:!0},sx:{"& .MuiOutlinedInput-root":{bgcolor:"#1b1b1b",color:"#e6edf3"},"& .MuiInputBase-input":{color:"#e6edf3"}},error:!!a[r.name],helperText:a[r.name]||r.description||""})},r.name))}):e.jsx($,{variant:"body2",sx:{color:"#888"},children:"No variables defined for this assembly."})]}),e.jsx(m,{children:e.jsx(nt,{onClick:()=>t(n.localId),size:"small",sx:{color:"#ff6666"},children:e.jsx($s,{fontSize:"small"})})})]})})}function Tl({onCancel:n,onCreated:t,initialJob:o=null}){const[a,d]=s.useState(0),[u,r]=s.useState(""),[i,c]=s.useState(""),[p,l]=s.useState([]),[h,f]=s.useState([]),[y,C]=s.useState("immediately"),[I,k]=s.useState(()=>Xs().add(5,"minute").second(0)),[v,j]=s.useState(!1),[B,R]=s.useState("no_expire"),[x,S]=s.useState("system"),[z,E]=s.useState([]),[U,X]=s.useState(!1),[ue,Se]=s.useState(""),[ce,de]=s.useState(""),[me,w]=s.useState(!0),W=s.useCallback(async()=>{X(!0),Se("");try{const b=await fetch("/api/credentials");if(!b.ok)throw new Error(`HTTP ${b.status}`);const P=await b.json(),D=Array.isArray(P==null?void 0:P.credentials)?P.credentials:[];D.sort((ae,xe)=>String((ae==null?void 0:ae.name)||"").localeCompare(String((xe==null?void 0:xe.name)||""))),E(D)}catch(b){E([]),Se(String(b.message||b))}finally{X(!1)}},[]);s.useEffect(()=>{W()},[W]);const F=s.useMemo(()=>x==="ssh"||x==="winrm",[x]),te=s.useCallback(b=>{const P=String(b||"system").toLowerCase();S(P),P==="winrm"?(w(!0),de("")):w(!1)},[]),ee=s.useMemo(()=>{if(!F)return z;const b=x==="winrm"?"winrm":"ssh";return z.filter(P=>String(P.connection_type||"").toLowerCase()===b)},[z,F,x]);s.useEffect(()=>{if(F){if(x==="winrm"&&me){de("");return}if(!ee.length){de("");return}(!ce||!ee.some(b=>String(b.id)===String(ce)))&&de(String(ee[0].id))}},[F,ee,ce,x,me]);const[be,Re]=s.useState(!1),[Ae,Le]=s.useState("scripts"),[Fe,je]=s.useState([]),[V,O]=s.useState({}),[M,g]=s.useState([]),[L,we]=s.useState({}),[T,G]=s.useState([]),[ie,Ce]=s.useState({}),[Ee,Ne]=s.useState(""),[Ke,at]=s.useState(!1),[ut,Pe]=s.useState([]),[gt,bt]=s.useState({}),[vt,Ut]=s.useState(""),[It,yt]=s.useState({}),[pt,St]=s.useState([]),[ct,oe]=s.useState(null),[_e,$e]=s.useState("hostname"),[Xe,We]=s.useState("asc"),[Je,ft]=s.useState({}),[ht,Jt]=s.useState(null),[Ct,Wt]=s.useState(null),[lt,Dt]=s.useState(""),Ot=s.useCallback(()=>`${Date.now()}_${Math.random().toString(36).slice(2,8)}`,[]),_t=s.useCallback(b=>["online","job_status","output"].includes(b)?"all":"",[]),Yt=s.useCallback(b=>{if(!Je||typeof Je!="object")return!1;const P=Je[b];if(P==null)return!1;if(typeof P=="string"){const D=P.trim();return!(!D||D==="all")}return!0},[Je]),ss=s.useCallback((b,P)=>{Wt(P),Dt(Je[P]??_t(P)),Jt(b.currentTarget)},[Je,_t]),A=s.useCallback(()=>{Jt(null),Wt(null)},[]),q=s.useCallback(()=>{if(!Ct){A();return}const b=lt;ft(P=>{const D={...P||{}};return!b||b==="all"||typeof b=="string"&&!b.trim()?delete D[Ct]:D[Ct]=b,D}),A()},[Ct,lt,A]),le=s.useCallback(()=>{if(!Ct){A();return}ft(b=>{const P={...b||{}};return delete P[Ct],P}),Dt(_t(Ct)),A()},[Ct,A,_t]),he=()=>{const b=Ct;if(!b)return null;if(b==="online")return e.jsxs(wt,{size:"small",fullWidth:!0,value:typeof lt=="string"&&lt?lt:"all",onChange:ae=>Dt(ae.target.value),children:[e.jsx(fe,{value:"all",children:"All Statuses"}),e.jsx(fe,{value:"online",children:"Online"}),e.jsx(fe,{value:"offline",children:"Offline"})]});if(b==="job_status"){const ae=["success","failed","running","pending","expired","timed out"];return e.jsxs(wt,{size:"small",fullWidth:!0,value:typeof lt=="string"&&lt?lt:"all",onChange:xe=>Dt(xe.target.value),children:[e.jsx(fe,{value:"all",children:"All Results"}),ae.map(xe=>e.jsx(fe,{value:xe,children:xe.replace(/\b\w/g,Be=>Be.toUpperCase())},xe))]})}if(b==="output")return e.jsxs(wt,{size:"small",fullWidth:!0,value:typeof lt=="string"&&lt?lt:"all",onChange:ae=>Dt(ae.target.value),children:[e.jsx(fe,{value:"all",children:"All Output"}),e.jsx(fe,{value:"stdout",children:"StdOut Only"}),e.jsx(fe,{value:"stderr",children:"StdErr Only"}),e.jsx(fe,{value:"both",children:"StdOut & StdErr"}),e.jsx(fe,{value:"none",children:"No Output"})]});const P={hostname:"Filter hostname",site:"Filter site",ran_on:"Filter date/time"},D=typeof lt=="string"?lt:"";return e.jsx(Ie,{size:"small",autoFocus:!0,fullWidth:!0,placeholder:P[b]||"Filter value",value:D,onChange:ae=>Dt(ae.target.value),onKeyDown:ae=>{ae.key==="Enter"&&(ae.preventDefault(),q())}})},_=s.useCallback(b=>{$e(P=>P===b?(We(D=>D==="asc"?"desc":"asc"),P):(We(b==="ran_on"?"desc":"asc"),b))},[]),K=s.useCallback(b=>{if(!b)return"";try{return new Date(Number(b)*1e3).toLocaleString(void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"numeric",minute:"2-digit"})}catch{return""}},[]),pe=s.useMemo(()=>{const b=(P,D)=>D==="pending"?P==="pending"||P==="scheduled"||P==="queued"||P==="":D==="running"?P==="running":D==="success"?P==="success":D==="failed"?P==="failed"||P==="failure"||P==="timed out"||P==="timed_out"||P==="warning":D==="expired"?P==="expired":!0;return pt.filter(P=>{const D=String((P==null?void 0:P.job_status)||"").trim().toLowerCase();if(ct&&!b(D,ct))return!1;if(Je&&typeof Je=="object"){for(const[ae,xe]of Object.entries(Je))if(xe!=null){if(typeof xe=="string"){const Be=xe.trim();if(!Be||Be==="all")continue}if(ae==="hostname"){const Be=String(xe||"").toLowerCase();if(!String((P==null?void 0:P.hostname)||"").toLowerCase().includes(Be))return!1}else if(ae==="online"){if(xe==="online"&&!(P!=null&&P.online)||xe==="offline"&&(P!=null&&P.online))return!1}else if(ae==="site"){const Be=String(xe||"").toLowerCase();if(!String((P==null?void 0:P.site)||"").toLowerCase().includes(Be))return!1}else if(ae==="ran_on"){const Be=String(xe||"").toLowerCase();if(!K(P==null?void 0:P.ran_on).toLowerCase().includes(Be))return!1}else if(ae==="job_status"){const Be=String(xe||"").toLowerCase();if(!D.includes(Be))return!1}else if(ae==="output"&&(xe==="stdout"&&!(P!=null&&P.has_stdout)||xe==="stderr"&&!(P!=null&&P.has_stderr)||xe==="both"&&(!(P!=null&&P.has_stdout)||!(P!=null&&P.has_stderr))||xe==="none"&&(P!=null&&P.has_stdout||P!=null&&P.has_stderr)))return!1}}return!0})},[pt,ct,Je,K]),re=s.useMemo(()=>{const b=[...pe],P=Xe==="asc"?1:-1;return b.sort((D,ae)=>{let xe=0;switch(_e){case"hostname":xe=String((D==null?void 0:D.hostname)||"").localeCompare(String((ae==null?void 0:ae.hostname)||""));break;case"online":xe=(D!=null&&D.online?1:0)-(ae!=null&&ae.online?1:0);break;case"site":xe=String((D==null?void 0:D.site)||"").localeCompare(String((ae==null?void 0:ae.site)||""));break;case"ran_on":xe=Number((D==null?void 0:D.ran_on)||0)-Number((ae==null?void 0:ae.ran_on)||0);break;case"job_status":xe=String((D==null?void 0:D.job_status)||"").localeCompare(String((ae==null?void 0:ae.job_status)||""));break;case"output":{const Be=Oe=>(Oe!=null&&Oe.has_stdout?2:0)+(Oe!=null&&Oe.has_stderr?1:0);xe=Be(D)-Be(ae);break}default:xe=0}return xe===0&&(xe=String((D==null?void 0:D.hostname)||"").localeCompare(String((ae==null?void 0:ae.hostname)||""))),xe*P}),b},[pe,Xe,_e]),ke=s.useCallback((b,P)=>{const D=(P||"").replace(/\\/g,"/").replace(/^\/+/,"").trim();return D?b==="script"?D.startsWith("Scripts/")?D:`Scripts/${D}`:D:""},[]),N=s.useCallback(async(b,P)=>{const D=ke(b,P);if(!D)return{doc:null,normalizedPath:""};const ae=D.replace(/\\/g,"/").replace(/^\/+/,"").trim();if(!ae)return{doc:null,normalizedPath:""};let xe=ae;if(b==="script"&&xe.toLowerCase().startsWith("scripts/")?xe=xe.slice(8):b==="ansible"&&xe.toLowerCase().startsWith("ansible_playbooks/")&&(xe=xe.slice(18)),!xe)return{doc:null,normalizedPath:D};try{const Oe=await fetch(`/api/assembly/load?island=${b==="ansible"?"ansible":"scripts"}&path=${encodeURIComponent(xe)}`);return Oe.ok?{doc:await Oe.json(),normalizedPath:D}:{doc:null,normalizedPath:D}}catch{return{doc:null,normalizedPath:D}}},[ke]),H=s.useCallback(async(b=[])=>{const P=[];for(const D of b){if(!D||typeof D!="object")continue;const ae=D.type||D.component_type||"script";if(ae==="workflow"){P.push({...D,type:"workflow",variables:Array.isArray(D.variables)?D.variables:[],localId:Ot()});continue}const xe=ae==="ansible"?"ansible":"script",Be=D.path||D.script_path||D.rel_path||"",{doc:Oe,normalizedPath:Ye}=await N(xe,Be),ot=(Oe==null?void 0:Oe.assembly)||{},Bs=(ot==null?void 0:ot.variables)||(Oe==null?void 0:Oe.variables)||[],pn=eo(Bs,D.variables,D.variable_values);P.push({...D,type:xe,path:Ye||Be,name:D.name||(ot==null?void 0:ot.name)||D.file_name||D.tab_name||Ye||Be,description:D.description||(ot==null?void 0:ot.description)||Ye||Be,variables:pn,localId:Ot()})}return P},[N,Ot]),Y=s.useCallback(b=>(Array.isArray(b)?b:[]).map(P=>{if(!P||typeof P!="object")return P;const{localId:D,...ae}=P,xe={...ae};if(Array.isArray(P.variables)){const Be={};xe.variables=P.variables.filter(Oe=>Oe&&typeof Oe.name=="string"&&Oe.name).map(Oe=>{const Ye={name:Oe.name,label:Oe.label||Oe.name,type:Oe.type||"string",required:!!Oe.required,description:Oe.description||""};return Object.prototype.hasOwnProperty.call(Oe,"default")&&(Ye.default=Oe.default),Object.prototype.hasOwnProperty.call(Oe,"value")&&(Ye.value=Oe.value,Be[Oe.name]=Oe.value),Ye}),xe.variables.length||(xe.variables=[]),Object.keys(Be).length?xe.variable_values=Be:delete xe.variable_values}return xe}),[]),se=s.useCallback((b,P,D)=>{!b||!P||(l(ae=>ae.map(xe=>{if(!xe||xe.localId!==b)return xe;const Oe=(Array.isArray(xe.variables)?xe.variables:[]).map(Ye=>!Ye||Ye.name!==P?Ye:{...Ye,value:Ds(Ye.type||"string",D)});return{...xe,variables:Oe}})),yt(ae=>{if(!ae[b]||!ae[b][P])return ae;const xe={...ae},Be={...xe[b]};return delete Be[P],Object.keys(Be).length?xe[b]=Be:delete xe[b],xe}))},[]),ne=s.useCallback(b=>{l(P=>P.filter(D=>D.localId!==b)),yt(P=>{if(!P[b])return P;const D={...P};return delete D[b],D})},[]),ye=s.useMemo(()=>!(u.trim().length>0&&p.length>0&&h.length>0)||F&&!(x==="winrm"&&me)&&!ce?!1:y!=="immediately"?!!I:!0,[u,p.length,h.length,y,I,F,ce,x,me]),[ve,ge]=s.useState(!1),Me=!!(o&&o.id),[Ve,it]=s.useState([]),[J,Te]=s.useState("started_ts"),[Ge,He]=s.useState("desc"),us=s.useRef(new Map),[fs,zt]=s.useState(!1),[Ft,kt]=s.useState(""),[qe,xt]=s.useState([]),[ns,hs]=s.useState(!1),[Cs,ms]=s.useState(""),Kt=s.useCallback(async()=>{if(Me)try{const[b,P,D]=await Promise.all([fetch(`/api/scheduled_jobs/${o.id}/runs?days=30`),fetch(`/api/scheduled_jobs/${o.id}`),fetch(`/api/scheduled_jobs/${o.id}/devices`)]),ae=await b.json(),xe=await P.json(),Be=await D.json();if(!b.ok)throw new Error(ae.error||`HTTP ${b.status}`);if(!P.ok)throw new Error(xe.error||`HTTP ${P.status}`);if(!D.ok)throw new Error(Be.error||`HTTP ${D.status}`);it(Array.isArray(ae.runs)?ae.runs:[]),Gs(xe.job||{});const Oe=Array.isArray(Be.devices)?Be.devices.map(Ye=>({...Ye,activities:Array.isArray(Ye.activities)?Ye.activities:[]})):[];St(Oe)}catch{it([]),Gs({}),St([])}},[Me,o==null?void 0:o.id]);s.useEffect(()=>{if(!Me)return;let b;return(async()=>{try{await Kt()}catch{}})(),b=setInterval(Kt,1e4),()=>{b&&clearInterval(b)}},[Me,Kt]);const Ws=b=>{const D={Success:{bg:"#00d18c",fg:"#000"},Running:{bg:"#58a6ff",fg:"#000"},Scheduled:{bg:"#999999",fg:"#fff"},Expired:{bg:"#777777",fg:"#fff"},Failed:{bg:"#ff4f4f",fg:"#fff"},Warning:{bg:"#ff8c00",fg:"#000"}}[b]||{bg:"#aaa",fg:"#000"};return e.jsx("span",{style:{display:"inline-block",padding:"2px 8px",borderRadius:999,background:D.bg,color:D.fg,fontWeight:600,fontSize:12},children:b||""})},Vs=s.useMemo(()=>{if(!Array.isArray(Ve)||Ve.length===0)return[];const b=new Map;Ve.forEach(D=>{const ae=(D==null?void 0:D.scheduled_ts)||(D==null?void 0:D.started_ts)||(D==null?void 0:D.finished_ts)||(D==null?void 0:D.id);if(!ae)return;const xe=String(ae),Be=b.get(xe)||{key:xe,scheduled_ts:(D==null?void 0:D.scheduled_ts)||null,started_ts:null,finished_ts:null,statuses:new Set};!Be.scheduled_ts&&(D!=null&&D.scheduled_ts)&&(Be.scheduled_ts=D.scheduled_ts),D!=null&&D.started_ts&&(Be.started_ts=Be.started_ts==null?D.started_ts:Math.min(Be.started_ts,D.started_ts)),D!=null&&D.finished_ts&&(Be.finished_ts=Be.finished_ts==null?D.finished_ts:Math.max(Be.finished_ts,D.finished_ts)),D!=null&&D.status&&Be.statuses.add(String(D.status)),b.set(xe,Be)});const P=[];return b.forEach(D=>{const ae=Array.from(D.statuses).map(ot=>String(ot||"").trim().toLowerCase()).filter(Boolean);if(!ae.length||ae.some(ot=>ot==="running"||ot==="pending"||ot==="scheduled"))return;const Be=ae.some(ot=>["failed","failure","expired","timed out","timed_out","warning"].includes(ot)),Oe=ae.every(ot=>ot==="success"),Ye=Be?"Failed":Oe?"Success":"Failed";P.push({key:D.key,scheduled_ts:D.scheduled_ts,started_ts:D.started_ts,finished_ts:D.finished_ts,status:Ye})}),P},[Ve]),Hs=s.useMemo(()=>{const b=Ge==="asc"?1:-1,P=J;return[...Vs].sort((D,ae)=>{const xe=Ye=>P==="scheduled_ts"||P==="started_ts"||P==="finished_ts"?Number((Ye==null?void 0:Ye[P])||0):String((Ye==null?void 0:Ye[P])||""),Be=xe(D),Oe=xe(ae);return typeof Be=="number"&&typeof Oe=="number"?(Be-Oe)*b:String(Be).localeCompare(String(Oe))*b})},[Vs,J,Ge]),_s=b=>{J===b?He(Ge==="asc"?"desc":"asc"):(Te(b),He("asc"))},an=()=>e.jsx(m,{sx:{maxHeight:400,overflowY:"auto"},children:e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{sortDirection:J==="scheduled_ts"?Ge:!1,children:e.jsx(Tt,{active:J==="scheduled_ts",direction:J==="scheduled_ts"?Ge:"asc",onClick:()=>_s("scheduled_ts"),children:"Scheduled"})}),e.jsx(Q,{sortDirection:J==="started_ts"?Ge:!1,children:e.jsx(Tt,{active:J==="started_ts",direction:J==="started_ts"?Ge:"asc",onClick:()=>_s("started_ts"),children:"Started"})}),e.jsx(Q,{sortDirection:J==="finished_ts"?Ge:!1,children:e.jsx(Tt,{active:J==="finished_ts",direction:J==="finished_ts"?Ge:"asc",onClick:()=>_s("finished_ts"),children:"Finished"})}),e.jsx(Q,{children:"Status"})]})}),e.jsxs(Nt,{children:[Hs.map(b=>e.jsxs(Ue,{children:[e.jsx(Q,{children:K(b.scheduled_ts)}),e.jsx(Q,{children:K(b.started_ts)}),e.jsx(Q,{children:K(b.finished_ts)}),e.jsx(Q,{children:Ws(b.status)})]},b.key)),Hs.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:4,sx:{color:"#888"},children:"No runs in the last 30 days."})})]})]})}),[ks,Gs]=s.useState({}),Is=(ks==null?void 0:ks.result_counts)||{},js=s.useMemo(()=>{const b={pending:0,running:0,success:0,failed:0,expired:0};return pt.forEach(P=>{const D=String((P==null?void 0:P.job_status)||"").trim().toLowerCase();!D||D==="pending"||D==="scheduled"||D==="queued"?b.pending+=1:D==="running"?b.running+=1:D==="success"?b.success+=1:D==="expired"?b.expired+=1:D==="failed"||D==="failure"||D==="timed out"||D==="timed_out"||D==="warning"?b.failed+=1:b.pending+=1}),b},[pt]),Xt=s.useMemo(()=>{const b={pending:0,running:0,success:0,failed:0,expired:0};return Object.keys(b).forEach(P=>{const D=Number((Is||{})[P]??0),ae=js[P]??0;b[P]=D>0?D:ae}),b},[Is,js]),ln=s.useMemo(()=>({statusNode:_l}),[]),Vt=s.useCallback(b=>{oe(P=>P===b?null:b)},[]),Rs=s.useMemo(()=>[{id:"pending",type:"statusNode",position:{x:-420,y:170},data:{label:jt.pending.label,color:jt.pending.color,count:Xt.pending,Icon:jt.pending.Icon,onClick:()=>Vt("pending"),isActive:ct==="pending"},draggable:!1,selectable:!1},{id:"running",type:"statusNode",position:{x:0,y:0},data:{label:jt.running.label,color:jt.running.color,count:Xt.running,Icon:jt.running.Icon,onClick:()=>Vt("running"),isActive:ct==="running"},draggable:!1,selectable:!1},{id:"expired",type:"statusNode",position:{x:0,y:340},data:{label:jt.expired.label,color:jt.expired.color,count:Xt.expired,Icon:jt.expired.Icon,onClick:()=>Vt("expired"),isActive:ct==="expired"},draggable:!1,selectable:!1},{id:"success",type:"statusNode",position:{x:420,y:0},data:{label:jt.success.label,color:jt.success.color,count:Xt.success,Icon:jt.success.Icon,onClick:()=>Vt("success"),isActive:ct==="success"},draggable:!1,selectable:!1},{id:"failed",type:"statusNode",position:{x:420,y:340},data:{label:jt.failed.label,color:jt.failed.color,count:Xt.failed,Icon:jt.failed.Icon,onClick:()=>Vt("failed"),isActive:ct==="failed"},draggable:!1,selectable:!1}],[Xt,Vt,ct]),Ns=s.useMemo(()=>[{id:"pending-running",source:"pending",target:"running",sourceHandle:"right-top",targetHandle:"left-top",type:"smoothstep",animated:!0,className:"status-flow-edge"},{id:"pending-expired",source:"pending",target:"expired",sourceHandle:"right-bottom",targetHandle:"left-bottom",type:"smoothstep",animated:!0,className:"status-flow-edge"},{id:"running-success",source:"running",target:"success",sourceHandle:"right-top",targetHandle:"left-top",type:"smoothstep",animated:!0,className:"status-flow-edge"},{id:"running-failed",source:"running",target:"failed",sourceHandle:"right-bottom",targetHandle:"left-bottom",type:"smoothstep",animated:!0,className:"status-flow-edge"}],[]),Ts=()=>{var b;return e.jsxs(m,{sx:{bgcolor:"#2e2e2e",border:"1px solid #2a2a2a",borderRadius:1,mb:2},children:[e.jsx(vr,{styles:{"@keyframes statusFlowDash":{"0%":{strokeDashoffset:0},"100%":{strokeDashoffset:-24}},".status-flow-edge .react-flow__edge-path":{strokeDasharray:"10 6",animation:"statusFlowDash 1.2s linear infinite",strokeWidth:2,stroke:"#58a6ff"}}}),e.jsx(m,{sx:{height:380,p:3},children:e.jsx(lo,{nodes:Rs,edges:Ns,nodeTypes:ln,fitView:!0,fitViewOptions:{padding:.2},nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!1,panOnDrag:!1,zoomOnScroll:!1,zoomOnPinch:!1,panOnScroll:!1,zoomOnDoubleClick:!1,preventScrolling:!1,onNodeClick:(P,D)=>{D!=null&&D.id&&jt[D.id]&&Vt(D.id)},selectionOnDrag:!1,proOptions:{hideAttribution:!0},style:{background:"transparent"}})}),ct?e.jsxs(m,{sx:{mt:1,px:3,pb:3,display:"flex",alignItems:"center",gap:1.5},children:[e.jsxs($,{variant:"caption",sx:{color:"#aaa"},children:["Showing devices with ",((b=jt[ct])==null?void 0:b.label)||ct," results"]}),e.jsx(Z,{size:"small",sx:{color:"#58a6ff",textTransform:"none",p:0},onClick:()=>oe(null),children:"Clear Filter"})]}):null]})},As=s.useCallback((b="")=>{const P=String(b||"").toLowerCase();return P.endsWith(".ps1")?"powershell":P.endsWith(".bat")?"batch":P.endsWith(".sh")?"bash":P.endsWith(".yml")||P.endsWith(".yaml")?"yaml":"powershell"},[]),cn=s.useCallback((b,P)=>{try{return qt.highlight(b??"",qt.languages[P]||qt.languages.markup,P)}catch{return String(b||"")}},[]),qs=s.useCallback(async b=>{const P=Number(b||0);if(!P)return null;if(us.current.has(P))return us.current.get(P);try{const D=await fetch(`/api/device/activity/job/${P}`);if(!D.ok)throw new Error(`HTTP ${D.status}`);const ae=await D.json();return us.current.set(P,ae),ae}catch{return null}},[]),Js=s.useCallback(async(b,P="stdout")=>{if(!b)return;const D=P==="stderr"?"StdErr":"StdOut",xe=(Array.isArray(b.activities)?b.activities:[]).filter(Oe=>P==="stderr"?Oe.has_stderr:Oe.has_stdout);if(kt(`${D} - ${b.hostname||""}`),xt([]),ms(""),hs(!0),zt(!0),!xe.length){ms(`No ${D} available for this device.`),hs(!1);return}const Be=[];for(const Oe of xe){const Ye=Number(Oe.activity_id||Oe.id||0);if(!Ye)continue;const ot=await qs(Ye);if(!ot)continue;const Bs=P==="stderr"?ot.stderr||"":ot.stdout||"",pn=Oe.component_name||ot.script_name||ot.script_path||`Activity ${Ye}`;Be.push({key:`${Ye}-${P}`,title:pn,path:ot.script_path||"",lang:As(ot.script_path||""),content:Bs})}Be.length||ms(`No ${D} available for this device.`),xt(Be),hs(!1)},[As,qs]);s.useEffect(()=>{let b=!1;return(async()=>{var D,ae;if(o&&o.id){r(o.name||""),c(typeof o.name=="string"?o.name.trim():""),f(Array.isArray(o.targets)?o.targets:[]),C(o.schedule_type||((D=o.schedule)==null?void 0:D.type)||"immediately"),k(o.start_ts?Xs(Number(o.start_ts)*1e3).second(0):(ae=o.schedule)!=null&&ae.start?Xs(o.schedule.start).second(0):Xs().add(5,"minute").second(0)),j(!!o.duration_stop_enabled),R(o.expiration||"no_expire"),S(o.execution_context||"system"),de(o.credential_id?String(o.credential_id):""),(o.execution_context||"").toLowerCase()==="winrm"?w(o.use_service_account!==!1):w(!1);const xe=Array.isArray(o.components)?o.components:[],Be=await H(xe);b||(l(Be),yt({}))}else o||(c(""),l([]),yt({}),de(""),w(!0))})(),()=>{b=!0}},[o,H]);const dn=async()=>{Re(!0);try{const b=await fetch("/api/assembly/list?island=scripts");if(b.ok){const P=await b.json(),{root:D,map:ae}=No(P.items||[],P.folders||[]);je(D),O(ae)}else je([]),O({})}catch{je([]),O({})}try{const b=await fetch("/api/assembly/list?island=workflows");if(b.ok){const P=await b.json(),{root:D,map:ae}=Il(P.items||[],P.folders||[]);g(D),we(ae)}else g([]),we({})}catch{g([]),we({})}try{const b=await fetch("/api/assembly/list?island=ansible");if(b.ok){const P=await b.json(),{root:D,map:ae}=kl(P.items||[],P.folders||[]);G(D),Ce(ae)}else G([]),Ce({})}catch{G([]),Ce({})}},un=s.useCallback(async()=>{const P=(Ae==="scripts"?V:Ae==="ansible"?ie:L)[Ee];if(!P||P.isFolder)return!1;if(Ae==="workflows"&&P.workflow)return alert("Workflows within Scheduled Jobs are not supported yet"),!1;if(Ae==="scripts"||Ae==="ansible"){const D=Ae==="scripts"?"script":"ansible",ae=P.path||P.id||"",{doc:xe,normalizedPath:Be}=await N(D,ae),Oe=(xe==null?void 0:xe.assembly)||{},Ye=(Oe==null?void 0:Oe.variables)||(xe==null?void 0:xe.variables)||[],ot=eo(Ye,[],{});return l(Bs=>[...Bs,{type:D,path:Be||ae,name:(Oe==null?void 0:Oe.name)||P.fileName||P.label,description:(Oe==null?void 0:Oe.description)||Be||ae,variables:ot,localId:Ot()}]),Ne(""),!0}return Ne(""),!1},[Ae,V,ie,L,Ee,N,Ot]),xs=async()=>{at(!0),bt({});try{const b=await fetch("/api/agents");if(b.ok){const P=await b.json(),D=Object.values(P||{}).map(ae=>({hostname:ae.hostname||ae.agent_hostname||ae.id||"unknown",display:ae.hostname||ae.agent_hostname||ae.id||"unknown",online:!!ae.collector_active}));D.sort((ae,xe)=>ae.display.localeCompare(xe.display)),Pe(D)}else Pe([])}catch{Pe([])}},Bo=async()=>{if(F&&!(x==="winrm"&&me)&&!ce){alert("Please select a credential for this execution context.");return}const b={};if(p.forEach(ae=>{!ae||!ae.localId||(Array.isArray(ae.variables)?ae.variables:[]).forEach(xe=>{if(!xe||!xe.name||!xe.required||(xe.type||"string")==="boolean")return;const Be=xe.value;(Be==null||Be==="")&&(b[ae.localId]||(b[ae.localId]={}),b[ae.localId][xe.name]="Required")})}),Object.keys(b).length){yt(b),d(1),alert("Please fill in all required variable values.");return}yt({});const P=Y(p),D={name:u,components:P,targets:h,schedule:{type:y,start:y!=="immediately"?(()=>{var ae;try{const xe=((ae=I==null?void 0:I.toDate)==null?void 0:ae.call(I))||new Date(I);return xe.setSeconds(0,0),xe.toISOString()}catch{return I}})():null},duration:{stopAfterEnabled:v,expiration:B},execution_context:x,credential_id:F&&!me&&ce?Number(ce):null,use_service_account:x==="winrm"?!!me:!1};try{const ae=await fetch(o&&o.id?`/api/scheduled_jobs/${o.id}`:"/api/scheduled_jobs",{method:o&&o.id?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(D)}),xe=await ae.json();if(!ae.ok)throw new Error(xe.error||`HTTP ${ae.status}`);t&&t(xe.job||D),n&&n()}catch(ae){alert(String(ae.message||ae))}},Dn=s.useMemo(()=>{const b=[{key:"name",label:"Job Name"},{key:"components",label:"Assemblies"},{key:"targets",label:"Targets"},{key:"schedule",label:"Schedule"},{key:"context",label:"Execution Context"}];return Me&&b.push({key:"history",label:"Job History"}),b},[Me]);return e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e",overflow:"auto"},elevation:2,children:[e.jsxs(m,{sx:{p:2,pb:1},children:[e.jsxs($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:["Create a Scheduled Job",i&&e.jsx(m,{component:"span",sx:{color:"#aaa",fontSize:"inherit",fontWeight:400},children:`: "${i}"`})]}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Configure advanced schedulable automation jobs for one or more devices."})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",borderBottom:"1px solid #333",px:2},children:[e.jsx(Us,{value:a,onChange:(b,P)=>d(P),sx:{minHeight:36},children:Dn.map((b,P)=>e.jsx(ps,{label:b.label,sx:{minHeight:36}},b.key))}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,mb:1},children:[e.jsx(Z,{onClick:n,sx:{color:"#58a6ff",textTransform:"none"},children:"Cancel"}),e.jsx(Z,{variant:"outlined",onClick:()=>ye?ge(!0):null,startIcon:e.jsx(ts,{}),disabled:!ye,sx:{color:ye?"#58a6ff":"#666",borderColor:ye?"#58a6ff":"#444",textTransform:"none"},children:o&&o.id?"Save Changes":"Create Job"})]})]}),e.jsxs(m,{sx:{p:2},children:[a===0&&e.jsxs(m,{children:[e.jsx(ws,{title:"Name"}),e.jsx(Ie,{fullWidth:!1,sx:{width:{xs:"100%",sm:"60%",md:"50%"},"& .MuiOutlinedInput-root":{bgcolor:"#1b1b1b"},"& .MuiInputBase-input":{color:"#e6edf3"}},placeholder:"Example Job Name",value:u,onChange:b=>r(b.target.value),onBlur:b=>c(b.target.value.trim()),InputLabelProps:{shrink:!0},error:u.trim().length===0,helperText:u.trim().length===0?"Job name is required":""})]}),a===1&&e.jsxs(m,{children:[e.jsx(ws,{title:"Assemblies",action:e.jsx(Z,{size:"small",startIcon:e.jsx(ts,{}),onClick:dn,sx:{color:"#58a6ff",borderColor:"#58a6ff"},variant:"outlined",children:"Add Assembly"})}),p.length===0&&e.jsx($,{variant:"body2",sx:{color:"#888"},children:"No assemblies added yet."}),p.map(b=>e.jsx(Nl,{comp:b,onRemove:ne,onVariableChange:se,errors:It[b.localId]||{}},b.localId||`${b.type}-${b.path}`)),p.length===0&&e.jsx($,{variant:"caption",sx:{color:"#ff6666"},children:"At least one assembly is required."})]}),a===2&&e.jsxs(m,{children:[e.jsx(ws,{title:"Targets",action:e.jsx(Z,{size:"small",startIcon:e.jsx(ts,{}),onClick:xs,sx:{color:"#58a6ff",borderColor:"#58a6ff"},variant:"outlined",children:"Add Target"})}),e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Name"}),e.jsx(Q,{children:"Status"}),e.jsx(Q,{align:"right",children:"Actions"})]})}),e.jsxs(Nt,{children:[h.map(b=>e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{children:b}),e.jsx(Q,{children:"—"}),e.jsx(Q,{align:"right",children:e.jsx(nt,{size:"small",onClick:()=>f(P=>P.filter(D=>D!==b)),sx:{color:"#ff6666"},children:e.jsx($s,{fontSize:"small"})})})]},b)),h.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:3,sx:{color:"#888"},children:"No targets selected."})})]})]}),h.length===0&&e.jsx($,{variant:"caption",sx:{color:"#ff6666"},children:"At least one target is required."})]}),a===3&&e.jsxs(m,{children:[e.jsx(ws,{title:"Schedule"}),e.jsxs(m,{sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[e.jsxs(m,{sx:{minWidth:260},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:.5},children:"Recurrence"}),e.jsxs(wt,{size:"small",fullWidth:!0,value:y,onChange:b=>C(b.target.value),children:[e.jsx(fe,{value:"immediately",children:"Immediately"}),e.jsx(fe,{value:"once",children:"At selected date and time"}),e.jsx(fe,{value:"every_5_minutes",children:"Every 5 Minutes"}),e.jsx(fe,{value:"every_10_minutes",children:"Every 10 Minutes"}),e.jsx(fe,{value:"every_15_minutes",children:"Every 15 Minutes"}),e.jsx(fe,{value:"every_30_minutes",children:"Every 30 Minutes"}),e.jsx(fe,{value:"every_hour",children:"Every Hour"}),e.jsx(fe,{value:"daily",children:"Daily"}),e.jsx(fe,{value:"weekly",children:"Weekly"}),e.jsx(fe,{value:"monthly",children:"Monthly"}),e.jsx(fe,{value:"yearly",children:"Yearly"})]})]}),y!=="immediately"&&e.jsxs(m,{sx:{minWidth:280},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:.5},children:"Start date and execution time"}),e.jsx(yr,{dateAdapter:jr,children:e.jsx(wr,{value:I,onChange:b=>k(b!=null&&b.second?b.second(0):b),views:["year","month","day","hours","minutes"],format:"YYYY-MM-DD hh:mm A",slotProps:{textField:{size:"small"}}})})]})]}),e.jsx(In,{sx:{my:2,borderColor:"#333"}}),e.jsx(ws,{title:"Duration"}),e.jsx(bs,{control:e.jsx(At,{checked:v,onChange:b=>j(b.target.checked)}),label:e.jsx($,{variant:"body2",children:"Stop running this job after"})}),e.jsxs(m,{sx:{mt:1,minWidth:260,width:260},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#ccc",mb:.5},children:"Expiration"}),e.jsxs(wt,{size:"small",fullWidth:!0,value:B,onChange:b=>R(b.target.value),children:[e.jsx(fe,{value:"no_expire",children:"Does not Expire"}),e.jsx(fe,{value:"30m",children:"30 Minutes"}),e.jsx(fe,{value:"1h",children:"1 Hour"}),e.jsx(fe,{value:"2h",children:"2 Hours"}),e.jsx(fe,{value:"6h",children:"6 Hours"}),e.jsx(fe,{value:"12h",children:"12 Hours"}),e.jsx(fe,{value:"1d",children:"1 Day"}),e.jsx(fe,{value:"2d",children:"2 Days"}),e.jsx(fe,{value:"3d",children:"3 Days"})]})]})]}),a===4&&e.jsxs(m,{children:[e.jsx(ws,{title:"Execution Context"}),e.jsxs(wt,{size:"small",value:x,onChange:b=>te(b.target.value),sx:{minWidth:320},children:[e.jsx(fe,{value:"system",children:"Run on agent as SYSTEM (device-local)"}),e.jsx(fe,{value:"current_user",children:"Run on agent as logged-in user (device-local)"}),e.jsx(fe,{value:"ssh",children:"Run from server via SSH (remote)"}),e.jsx(fe,{value:"winrm",children:"Run from server via WinRM (remote)"})]}),F&&e.jsxs(m,{sx:{mt:2,display:"flex",alignItems:"center",gap:1.5,flexWrap:"wrap"},children:[x==="winrm"&&e.jsx(bs,{control:e.jsx(At,{checked:me,onChange:b=>{const P=b.target.checked;w(P),P?de(""):!ce&&ee.length&&de(String(ee[0].id))}}),label:"Use Configured svcBorealis Account"}),e.jsxs(Ht,{size:"small",sx:{minWidth:320},disabled:U||!ee.length||x==="winrm"&&me,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Credential"}),e.jsx(wt,{value:ce,label:"Credential",onChange:b=>de(b.target.value),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:ee.map(b=>e.jsx(fe,{value:String(b.id),children:b.name},b.id))})]}),e.jsx(Z,{size:"small",variant:"outlined",startIcon:e.jsx(Ss,{fontSize:"small"}),onClick:W,disabled:U,sx:{color:"#58a6ff",borderColor:"#58a6ff"},children:"Refresh"}),U&&e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),!U&&ue&&e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:ue}),x==="winrm"&&me&&e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Runs with the agent's svcBorealis account."}),!U&&!ue&&!ee.length&&!(x==="winrm"&&me)&&e.jsxs($,{variant:"body2",sx:{color:"#ff8080"},children:["No ",x==="winrm"?"WinRM":"SSH"," credentials available. Create one under Access Management > Credentials."]})]})]}),Me&&a===Dn.findIndex(b=>b.key==="history")&&e.jsxs(m,{children:[e.jsxs(m,{sx:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff"},children:"Job History"}),e.jsx(Z,{size:"small",variant:"outlined",sx:{color:"#ff6666",borderColor:"#ff6666",textTransform:"none"},onClick:async()=>{try{await fetch(`/api/scheduled_jobs/${o.id}/runs`,{method:"DELETE"}),await Kt()}catch{}},children:"Clear Job History"})]}),e.jsx($,{variant:"caption",sx:{color:"#aaa"},children:"Showing the last 30 days of runs."}),e.jsx(m,{sx:{mt:2},children:e.jsx(Ts,{})}),e.jsxs(m,{sx:{mt:2},children:[e.jsx($,{variant:"subtitle1",sx:{color:"#7db7ff",mb:.5},children:"Devices"}),e.jsx($,{variant:"caption",sx:{color:"#aaa"},children:"Devices targeted by this scheduled job. Individual job history is listed here."}),e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsx(Ue,{children:Cl.map(b=>e.jsx(Q,{children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:.5},children:[e.jsx(Tt,{active:_e===b.key,direction:_e===b.key?Xe:"asc",onClick:()=>_(b.key),children:b.label}),e.jsx(nt,{size:"small",onClick:P=>ss(P,b.key),sx:{color:Yt(b.key)?"#58a6ff":"#666"},children:e.jsx(Rn,{fontSize:"inherit"})})]})},b.key))})}),e.jsxs(Nt,{children:[re.map((b,P)=>e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{children:b.hostname}),e.jsxs(Q,{children:[e.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:10,background:b.online?"#00d18c":"#ff4f4f",marginRight:8,verticalAlign:"middle"}}),b.online?"Online":"Offline"]}),e.jsx(Q,{children:b.site||""}),e.jsx(Q,{children:K(b.ran_on)}),e.jsx(Q,{children:Ws(b.job_status)}),e.jsx(Q,{children:e.jsxs(m,{sx:{display:"flex",gap:1},children:[b.has_stdout?e.jsx(Z,{size:"small",sx:{color:"#58a6ff",textTransform:"none",minWidth:0,p:0},onClick:D=>{D.stopPropagation(),Js(b,"stdout")},children:"StdOut"}):null,b.has_stderr?e.jsx(Z,{size:"small",sx:{color:"#ff4f4f",textTransform:"none",minWidth:0,p:0},onClick:D=>{D.stopPropagation(),Js(b,"stderr")},children:"StdErr"}):null]})})]},`${b.hostname}-${P}`)),re.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:6,sx:{color:"#888"},children:"No targets found for this job."})})]})]}),e.jsx(Et,{anchorEl:ht,open:!!ht,onClose:A,disableAutoFocusItem:!0,PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#e6edf3",minWidth:240}},children:e.jsxs(m,{sx:{p:1.5,display:"flex",flexDirection:"column",gap:1},children:[he(),e.jsxs(m,{sx:{display:"flex",justifyContent:"space-between",gap:1},children:[e.jsx(Z,{size:"small",sx:{color:"#ff6666",textTransform:"none"},onClick:le,children:"Clear"}),e.jsx(Z,{size:"small",sx:{color:"#58a6ff",textTransform:"none"},onClick:q,children:"Apply"})]})]})})]}),e.jsxs(m,{sx:{mt:2},children:[e.jsx($,{variant:"subtitle1",sx:{color:"#7db7ff",mb:.5},children:"Past Job History"}),e.jsx($,{variant:"caption",sx:{color:"#aaa"},children:"Historical job history summaries. Detailed job history is not recorded."}),e.jsx(m,{sx:{mt:1},children:an()})]})]})]}),e.jsxs(Ze,{open:fs,onClose:()=>zt(!1),fullWidth:!0,maxWidth:"md",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:Ft}),e.jsxs(rt,{dividers:!0,children:[ns?e.jsx($,{variant:"body2",sx:{color:"#888"},children:"Loading output…"}):null,!ns&&Cs?e.jsx($,{variant:"body2",sx:{color:"#888"},children:Cs}):null,!ns&&!Cs?qe.map(b=>e.jsxs(m,{sx:{mb:2},children:[e.jsx($,{variant:"subtitle2",sx:{color:"#7db7ff"},children:b.title}),b.path?e.jsx($,{variant:"caption",sx:{color:"#888",display:"block",mb:.5},children:b.path}):null,e.jsx(m,{sx:{border:"1px solid #333",borderRadius:1,bgcolor:"#1e1e1e"},children:e.jsx(En,{value:b.content??"",onValueChange:()=>{},highlight:P=>cn(P,b.lang),padding:12,style:{fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',fontSize:12,color:"#e6edf3",minHeight:160},textareaProps:{readOnly:!0}})})]},b.key)):null]}),e.jsx(tt,{children:e.jsx(Z,{onClick:()=>zt(!1),sx:{color:"#58a6ff"},children:"Close"})})]}),e.jsxs(Ze,{open:be,onClose:()=>Re(!1),fullWidth:!0,maxWidth:"md",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Select an Assembly"}),e.jsxs(rt,{children:[e.jsxs(m,{sx:{display:"flex",gap:2,mb:1},children:[e.jsx(Z,{size:"small",variant:Ae==="scripts"?"outlined":"text",onClick:()=>Le("scripts"),sx:{textTransform:"none",color:"#58a6ff",borderColor:"#58a6ff"},children:"Scripts"}),e.jsx(Z,{size:"small",variant:Ae==="ansible"?"outlined":"text",onClick:()=>Le("ansible"),sx:{textTransform:"none",color:"#58a6ff",borderColor:"#58a6ff"},children:"Ansible"}),e.jsx(Z,{size:"small",variant:Ae==="workflows"?"outlined":"text",onClick:()=>Le("workflows"),sx:{textTransform:"none",color:"#58a6ff",borderColor:"#58a6ff"},children:"Workflows"})]}),Ae==="scripts"&&e.jsx(Qe,{sx:{p:1,bgcolor:"#1e1e1e",maxHeight:400,overflow:"auto"},children:e.jsx(vs,{onItemSelectionToggle:(b,P)=>{const D=V[P];D&&!D.isFolder&&Ne(P)},children:Fe.length?Fe.map(b=>e.jsx(ys,{itemId:b.id,label:b.label,children:b.children&&b.children.length?nn(b.children,V):null},b.id)):e.jsx($,{variant:"body2",sx:{color:"#888",p:1},children:"No scripts found."})})}),Ae==="workflows"&&e.jsx(Qe,{sx:{p:1,bgcolor:"#1e1e1e",maxHeight:400,overflow:"auto"},children:e.jsx(vs,{onItemSelectionToggle:(b,P)=>{const D=L[P];D&&!D.isFolder&&Ne(P)},children:M.length?M.map(b=>e.jsx(ys,{itemId:b.id,label:b.label,children:b.children&&b.children.length?nn(b.children,L):null},b.id)):e.jsx($,{variant:"body2",sx:{color:"#888",p:1},children:"No workflows found."})})}),Ae==="ansible"&&e.jsx(Qe,{sx:{p:1,bgcolor:"#1e1e1e",maxHeight:400,overflow:"auto"},children:e.jsx(vs,{onItemSelectionToggle:(b,P)=>{const D=ie[P];D&&!D.isFolder&&Ne(P)},children:T.length?T.map(b=>e.jsx(ys,{itemId:b.id,label:b.label,children:b.children&&b.children.length?nn(b.children,ie):null},b.id)):e.jsx($,{variant:"body2",sx:{color:"#888",p:1},children:"No playbooks found."})})})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:()=>Re(!1),sx:{color:"#58a6ff"},children:"Close"}),e.jsx(Z,{onClick:async()=>{await un()&&Re(!1)},sx:{color:"#58a6ff"},disabled:!Ee,children:"Add"})]})]}),e.jsxs(Ze,{open:Ke,onClose:()=>at(!1),fullWidth:!0,maxWidth:"md",PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Select Targets"}),e.jsxs(rt,{children:[e.jsx(m,{sx:{mb:2,display:"flex",gap:2},children:e.jsx(Ie,{size:"small",placeholder:"Search devices...",value:vt,onChange:b=>Ut(b.target.value),sx:{flex:1,"& .MuiOutlinedInput-root":{bgcolor:"#1b1b1b"},"& .MuiInputBase-input":{color:"#e6edf3"}}})}),e.jsxs(Rt,{size:"small",children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{width:40}),e.jsx(Q,{children:"Name"}),e.jsx(Q,{children:"Status"})]})}),e.jsxs(Nt,{children:[ut.filter(b=>b.display.toLowerCase().includes(vt.toLowerCase())).map(b=>e.jsxs(Ue,{hover:!0,onClick:()=>bt(P=>({...P,[b.hostname]:!P[b.hostname]})),children:[e.jsx(Q,{children:e.jsx(At,{size:"small",checked:!!gt[b.hostname],onChange:P=>bt(D=>({...D,[b.hostname]:P.target.checked}))})}),e.jsx(Q,{children:b.display}),e.jsxs(Q,{children:[e.jsx("span",{style:{display:"inline-block",width:10,height:10,borderRadius:10,background:b.online?"#00d18c":"#ff4f4f",marginRight:8,verticalAlign:"middle"}}),b.online?"Online":"Offline"]})]},b.hostname)),ut.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:3,sx:{color:"#888"},children:"No devices available."})})]})]})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:()=>at(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:()=>{const b=Object.keys(gt).filter(P=>gt[P]);f(P=>Array.from(new Set([...P,...b]))),at(!1)},sx:{color:"#58a6ff"},children:"Add Selected"})]})]}),e.jsxs(Ze,{open:ve,onClose:()=>ge(!1),PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{sx:{pb:0},children:o&&o.id?"Are you sure you wish to save changes?":"Are you sure you wish to create this Job?"}),e.jsxs(tt,{sx:{p:2},children:[e.jsx(Z,{onClick:()=>ge(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:()=>{ge(!1),Bo()},variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},children:"Confirm"})]})]})]})}const Al=[{value:"machine",label:"Machine"},{value:"domain",label:"Domain"},{value:"token",label:"Token"}],Bl=[{value:"ssh",label:"SSH"},{value:"winrm",label:"WinRM"}],Ol=[{value:"",label:"None"},{value:"sudo",label:"sudo"},{value:"su",label:"su"},{value:"runas",label:"runas"},{value:"enable",label:"enable"}];function jn(){return{name:"",description:"",site_id:"",credential_type:"machine",connection_type:"ssh",username:"",password:"",private_key:"",private_key_passphrase:"",become_method:"",become_username:"",become_password:""}}function to(n){if(n===null||typeof n>"u"||n==="")return"";const t=Number(n);return Number.isNaN(t)?"":String(t)}function Pl({open:n,mode:t="create",credential:o,onClose:a,onSaved:d}){const u=t==="edit"&&o&&o.id,[r,i]=s.useState(jn),[c,p]=s.useState([]),[l,h]=s.useState(!1),[f,y]=s.useState(""),[C,I]=s.useState(!1),[k,v]=s.useState(!1),[j,B]=s.useState(!1),[R,x]=s.useState(!1),[S,z]=s.useState(!1),[E,U]=s.useState(!1),[X,ue]=s.useState(!1),[Se,ce]=s.useState(!1),[de,me]=s.useState(!1),w=o==null?void 0:o.id;s.useEffect(()=>{if(!n)return;let V=!1;return(async()=>{try{const O=await fetch("/api/sites");if(!O.ok)return;const M=await O.json();if(V)return;const g=Array.isArray(M==null?void 0:M.sites)?M.sites.filter(L=>L&&L.id).map(L=>({id:L.id,name:L.name||`Site ${L.id}`})):[];g.sort((L,we)=>String(L.name||"").localeCompare(String(we.name||""))),p(g)}catch{V||p([])}})(),()=>{V=!0}},[n]),s.useEffect(()=>{if(n)if(y(""),I(!1),v(!1),B(!1),x(!1),z(!1),U(!1),ue(!1),ce(!1),u&&w){const V=O=>{const M=jn();M.name=(O==null?void 0:O.name)||"",M.description=(O==null?void 0:O.description)||"",M.site_id=to(O==null?void 0:O.site_id),M.credential_type=((O==null?void 0:O.credential_type)||"machine").toLowerCase(),M.connection_type=((O==null?void 0:O.connection_type)||"ssh").toLowerCase(),M.username=(O==null?void 0:O.username)||"",M.become_method=((O==null?void 0:O.become_method)||"").toLowerCase(),M.become_username=(O==null?void 0:O.become_username)||"",i(M)};o!=null&&o.name?V(o):(me(!0),(async()=>{try{const O=await fetch(`/api/credentials/${w}`);if(O.ok){const M=await O.json();V((M==null?void 0:M.credential)||{})}}catch{}finally{me(!1)}})())}else i(jn())},[n,u,w,o]);const W=s.useMemo(()=>({hasPassword:!!(o!=null&&o.has_password),hasPrivateKey:!!(o!=null&&o.has_private_key),hasPrivateKeyPassphrase:!!(o!=null&&o.has_private_key_passphrase),hasBecomePassword:!!(o!=null&&o.has_become_password)}),[o]),F=l||de,te=V=>O=>{var g;const M=((g=O==null?void 0:O.target)==null?void 0:g.value)??"";i(L=>({...L,[V]:M})),V==="password"?(I(!0),z(!1)):V==="private_key"?(v(!0),U(!1)):V==="private_key_passphrase"?(B(!0),ue(!1)):V==="become_password"&&(x(!0),ce(!1))},ee=async V=>{var M;const O=(M=V.target.files)==null?void 0:M[0];if(O)try{const g=await O.text();i(L=>({...L,private_key:g})),v(!0),U(!1)}catch{y("Unable to read private key file.")}finally{V.target.value=""}},be=()=>{l||a&&a()},Re=()=>r.name.trim()?(y(""),!0):(y("Credential name is required."),!1),Ae=()=>{const V={name:r.name.trim(),description:r.description.trim(),credential_type:(r.credential_type||"machine").toLowerCase(),connection_type:(r.connection_type||"ssh").toLowerCase(),username:r.username.trim(),become_method:r.become_method.trim(),become_username:r.become_username.trim()},O=to(r.site_id);return O?V.site_id=Number(O):V.site_id=null,C&&(V.password=r.password),k&&(V.private_key=r.private_key),j&&(V.private_key_passphrase=r.private_key_passphrase),R&&(V.become_password=r.become_password),S&&(V.clear_password=!0),E&&(V.clear_private_key=!0),X&&(V.clear_private_key_passphrase=!0),Se&&(V.clear_become_password=!0),V},Le=async()=>{if(!Re())return;h(!0),y("");const V=Ae();try{const O=await fetch(u?`/api/credentials/${w}`:"/api/credentials",{method:u?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(V)}),M=await O.json();if(!O.ok)throw new Error((M==null?void 0:M.error)||`Request failed (${O.status})`);d&&d((M==null?void 0:M.credential)||null)}catch(O){y(String(O.message||O))}finally{h(!1)}},Fe=u?"Edit Credential":"Create Credential",je={fontSize:12,color:"#8a8a8a",mt:.5};return e.jsxs(Ze,{open:n,onClose:be,maxWidth:"md",fullWidth:!0,PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{sx:{pb:1},children:Fe}),e.jsxs(rt,{dividers:!0,sx:{display:"flex",flexDirection:"column",gap:2},children:[de&&e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,color:"#aaa"},children:[e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),e.jsx($,{variant:"body2",children:"Loading credential details…"})]}),f&&e.jsx(m,{sx:{bgcolor:"#2c1c1c",border:"1px solid #663939",borderRadius:1,p:1},children:e.jsx($,{variant:"body2",sx:{color:"#ff8080"},children:f})}),e.jsx(Ie,{label:"Name",value:r.name,onChange:te("name"),required:!0,disabled:F,sx:{"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),e.jsx(Ie,{label:"Description",value:r.description,onChange:te("description"),disabled:F,multiline:!0,minRows:2,sx:{"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),e.jsxs(m,{sx:{display:"flex",flexWrap:"wrap",gap:2},children:[e.jsxs(Ht,{sx:{minWidth:220},size:"small",disabled:F,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Site"}),e.jsxs(wt,{value:r.site_id,label:"Site",onChange:te("site_id"),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:[e.jsx(fe,{value:"",children:"(None)"}),c.map(V=>e.jsx(fe,{value:String(V.id),children:V.name},V.id))]})]}),e.jsxs(Ht,{sx:{minWidth:180},size:"small",disabled:F,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Credential Type"}),e.jsx(wt,{value:r.credential_type,label:"Credential Type",onChange:te("credential_type"),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:Al.map(V=>e.jsx(fe,{value:V.value,children:V.label},V.value))})]}),e.jsxs(Ht,{sx:{minWidth:180},size:"small",disabled:F,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Connection"}),e.jsx(wt,{value:r.connection_type,label:"Connection",onChange:te("connection_type"),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:Bl.map(V=>e.jsx(fe,{value:V.value,children:V.label},V.value))})]})]}),e.jsx(Ie,{label:"Username",value:r.username,onChange:te("username"),disabled:F,sx:{"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Ie,{label:"Password",type:"password",value:r.password,onChange:te("password"),disabled:F,sx:{flex:1,"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),u&&W.hasPassword&&!C&&!S&&e.jsx(st,{title:"Clear stored password",children:e.jsx(nt,{size:"small",onClick:()=>z(!0),sx:{color:"#ff8080"},children:e.jsx(Ks,{fontSize:"small"})})})]}),u&&W.hasPassword&&!C&&!S&&e.jsx($,{sx:je,children:"Stored password will remain unless you change or clear it."}),S&&e.jsx($,{sx:{...je,color:"#ffaaaa"},children:"Password will be removed when saving."}),e.jsxs(m,{sx:{display:"flex",gap:1,alignItems:"flex-start"},children:[e.jsx(Ie,{label:"SSH Private Key",value:r.private_key,onChange:te("private_key"),disabled:F,multiline:!0,minRows:4,maxRows:12,sx:{flex:1,"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff",fontFamily:"monospace"},"& label":{color:"#888"}}}),e.jsxs(Z,{variant:"outlined",component:"label",startIcon:e.jsx(go,{}),disabled:F,sx:{alignSelf:"center",borderColor:"#58a6ff",color:"#58a6ff"},children:["Upload",e.jsx("input",{type:"file",hidden:!0,accept:".pem,.key,.txt",onChange:ee})]}),u&&W.hasPrivateKey&&!k&&!E&&e.jsx(st,{title:"Clear stored private key",children:e.jsx(nt,{size:"small",onClick:()=>U(!0),sx:{color:"#ff8080"},children:e.jsx(Ks,{fontSize:"small"})})})]}),u&&W.hasPrivateKey&&!k&&!E&&e.jsx($,{sx:je,children:"Private key is stored. Upload or paste a new one to replace, or clear it."}),E&&e.jsx($,{sx:{...je,color:"#ffaaaa"},children:"Private key will be removed when saving."}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Ie,{label:"Private Key Passphrase",type:"password",value:r.private_key_passphrase,onChange:te("private_key_passphrase"),disabled:F,sx:{flex:1,"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),u&&W.hasPrivateKeyPassphrase&&!j&&!X&&e.jsx(st,{title:"Clear stored passphrase",children:e.jsx(nt,{size:"small",onClick:()=>ue(!0),sx:{color:"#ff8080"},children:e.jsx(Ks,{fontSize:"small"})})})]}),u&&W.hasPrivateKeyPassphrase&&!j&&!X&&e.jsx($,{sx:je,children:"A passphrase is stored for this key."}),X&&e.jsx($,{sx:{...je,color:"#ffaaaa"},children:"Key passphrase will be removed when saving."}),e.jsxs(m,{sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[e.jsxs(Ht,{sx:{minWidth:180},size:"small",disabled:F,children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Privilege Escalation"}),e.jsx(wt,{value:r.become_method,label:"Privilege Escalation",onChange:te("become_method"),sx:{bgcolor:"#1f1f1f",color:"#fff"},children:Ol.map(V=>e.jsx(fe,{value:V.value,children:V.label},V.value||"none"))})]}),e.jsx(Ie,{label:"Escalation Username",value:r.become_username,onChange:te("become_username"),disabled:F,sx:{flex:1,minWidth:200,"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}})]}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Ie,{label:"Escalation Password",type:"password",value:r.become_password,onChange:te("become_password"),disabled:F,sx:{flex:1,"& .MuiInputBase-root":{bgcolor:"#1f1f1f",color:"#fff"},"& label":{color:"#888"}}}),u&&W.hasBecomePassword&&!R&&!Se&&e.jsx(st,{title:"Clear stored escalation password",children:e.jsx(nt,{size:"small",onClick:()=>ce(!0),sx:{color:"#ff8080"},children:e.jsx(Ks,{fontSize:"small"})})})]}),u&&W.hasBecomePassword&&!R&&!Se&&e.jsx($,{sx:je,children:"Escalation password is stored."}),Se&&e.jsx($,{sx:{...je,color:"#ffaaaa"},children:"Escalation password will be removed when saving."})]}),e.jsxs(tt,{sx:{px:3,py:2},children:[e.jsx(Z,{onClick:be,sx:{color:"#58a6ff"},disabled:l,children:"Cancel"}),e.jsx(Z,{onClick:Le,variant:"outlined",sx:{color:"#58a6ff",borderColor:"#58a6ff"},disabled:F,children:l?e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}):"Save"})]})]})}Bn.registerModules([On]);const To=Pn.withParams({accentColor:"#FFA6FF",backgroundColor:"#1f2836",browserColorScheme:"dark",chromeBackgroundColor:{ref:"foregroundColor",mix:.07,onto:"backgroundColor"},fontFamily:{googleFont:"IBM Plex Sans"},foregroundColor:"#FFF",headerFontSize:14}),El=To.themeName||"ag-theme-quartz",gs='"IBM Plex Sans", "Helvetica Neue", Arial, sans-serif',wn='"Quartz Regular"';function Ml(n){if(!n)return"-";const t=new Date(Number(n)*1e3);return Number.isNaN(t==null?void 0:t.getTime())?"-":`${t.toLocaleDateString()} ${t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}`}function so(n){return n?String(n).toLowerCase().replace(/(^|\s)\w/g,o=>o.toUpperCase()):"-"}function Dl(n){const t=(n||"").toLowerCase();return t==="ssh"?e.jsx(Sr,{fontSize:"small",sx:{mr:.6,color:"#58a6ff"}}):t==="winrm"?e.jsx(Cr,{fontSize:"small",sx:{mr:.6,color:"#58a6ff"}}):e.jsx(_r,{fontSize:"small",sx:{mr:.6,color:"#58a6ff"}})}function zl({isAdmin:n=!1}){const[t,o]=s.useState([]),[a,d]=s.useState(!1),[u,r]=s.useState(""),[i,c]=s.useState(null),[p,l]=s.useState(null),[h,f]=s.useState(!1),[y,C]=s.useState("create"),[I,k]=s.useState(null),[v,j]=s.useState(null),[B,R]=s.useState(!1),x=s.useRef(null),S=s.useCallback((ee,be)=>{c(ee.currentTarget),l(be)},[]),z=s.useCallback(()=>{c(null),l(null)},[]),E=s.useCallback(ee=>{const be=ee.data||{},Re=so(be.connection_type);return e.jsxs(m,{sx:{display:"flex",alignItems:"center",fontFamily:gs},children:[Dl(be.connection_type),e.jsx(m,{component:"span",sx:{color:"#f5f7fa"},children:Re})]})},[]),U=s.useCallback(ee=>{const be=ee.data;if(!be)return null;const Re=Ae=>{Ae.preventDefault(),Ae.stopPropagation(),S(Ae,be)};return e.jsx(nt,{size:"small",onClick:Re,sx:{color:"#7db7ff"},children:e.jsx(on,{fontSize:"small"})})},[S]),X=s.useMemo(()=>[{headerName:"Name",field:"name",sort:"asc",cellRenderer:ee=>ee.value||"-"},{headerName:"Credential Type",field:"credential_type",valueGetter:ee=>{var be;return so((be=ee.data)==null?void 0:be.credential_type)}},{headerName:"Connection",field:"connection_type",cellRenderer:E},{headerName:"Site",field:"site_name",cellRenderer:ee=>ee.value||"-"},{headerName:"Username",field:"username",cellRenderer:ee=>ee.value||"-"},{headerName:"Updated",field:"updated_at",valueGetter:ee=>{var be,Re;return Ml(((be=ee.data)==null?void 0:be.updated_at)||((Re=ee.data)==null?void 0:Re.created_at))}},{headerName:"",field:"__actions__",minWidth:70,maxWidth:80,sortable:!1,filter:!1,resizable:!1,suppressMenu:!0,cellRenderer:U,pinned:"right"}],[U,E]),ue=s.useMemo(()=>({sortable:!0,filter:"agTextColumnFilter",resizable:!0,flex:1,minWidth:140,cellStyle:{display:"flex",alignItems:"center",color:"#f5f7fa",fontFamily:gs,fontSize:"13px"},headerClass:"credential-grid-header"}),[]),Se=s.useCallback(ee=>{var be,Re,Ae;return((be=ee.data)==null?void 0:be.id)||((Re=ee.data)==null?void 0:Re.name)||((Ae=ee.data)==null?void 0:Ae.username)||String(ee.rowIndex??"")},[]),ce=s.useCallback(async()=>{d(!0),r("");try{const ee=await fetch("/api/credentials");if(!ee.ok)throw new Error(`HTTP ${ee.status}`);const be=await ee.json(),Re=Array.isArray(be==null?void 0:be.credentials)?be.credentials:[];Re.sort((Ae,Le)=>String((Ae==null?void 0:Ae.name)||"").localeCompare(String((Le==null?void 0:Le.name)||""))),o(Re)}catch(ee){o([]),r(String(ee.message||ee))}finally{d(!1)}},[]);s.useEffect(()=>{ce()},[ce]);const de=()=>{C("create"),k(null),f(!0)},me=ee=>{z(),C("edit"),k(ee),f(!0)},w=ee=>{z(),j(ee)},W=async()=>{if(v!=null&&v.id){R(!0);try{const ee=await fetch(`/api/credentials/${v.id}`,{method:"DELETE"});if(!ee.ok){const be=await ee.json().catch(()=>({}));throw new Error((be==null?void 0:be.error)||`HTTP ${ee.status}`)}j(null),await ce()}catch(ee){r(String(ee.message||ee))}finally{R(!1)}}},F=async()=>{f(!1),k(null),await ce()},te=s.useCallback(ee=>{x.current=ee.api},[]);return s.useEffect(()=>{const ee=x.current;ee&&(a?ee.showLoadingOverlay():t.length?ee.hideOverlay():ee.showNoRowsOverlay())},[a,t]),n?e.jsxs(e.Fragment,{children:[e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e",fontFamily:gs,color:"#f5f7fa",display:"flex",flexDirection:"column",flexGrow:1,minWidth:0,minHeight:420},elevation:2,children:[e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",p:2,borderBottom:"1px solid #2a2a2a"},children:[e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:.3},children:"Credentials"}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Stored credentials for remote automation tasks and Ansible playbook runs."})]}),e.jsxs(m,{sx:{display:"flex",gap:1},children:[e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(Ss,{}),sx:{borderColor:"#58a6ff",color:"#58a6ff"},onClick:ce,disabled:a,children:"Refresh"}),e.jsx(Z,{variant:"contained",size:"small",startIcon:e.jsx(ts,{}),sx:{bgcolor:"#58a6ff",color:"#0b0f19"},onClick:de,children:"New Credential"})]})]}),a&&e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,color:"#7db7ff",px:2,py:1.5,borderBottom:"1px solid #2a2a2a"},children:[e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),e.jsx($,{variant:"body2",children:"Loading credentials…"})]}),u&&e.jsx(m,{sx:{px:2,py:1.5,color:"#ff8080",borderBottom:"1px solid #2a2a2a"},children:e.jsx($,{variant:"body2",children:u})}),e.jsx(m,{sx:{flexGrow:1,minHeight:0,display:"flex",flexDirection:"column",mt:"10px",px:2,pb:2},children:e.jsx(m,{className:El,sx:{width:"100%",height:"100%",flexGrow:1,fontFamily:gs,"--ag-font-family":gs,"--ag-icon-font-family":wn,"--ag-row-border-style":"solid","--ag-row-border-color":"#2a2a2a","--ag-row-border-width":"1px","& .ag-root-wrapper":{borderRadius:1,minHeight:320},"& .ag-root, & .ag-header, & .ag-center-cols-container, & .ag-paging-panel":{fontFamily:gs},"& .ag-icon":{fontFamily:wn}},style:{color:"#f5f7fa"},children:e.jsx(An,{rowData:t,columnDefs:X,defaultColDef:ue,animateRows:!0,rowHeight:46,headerHeight:44,getRowId:Se,overlayNoRowsTemplate:"<span class='ag-overlay-no-rows-center'>No credentials have been created yet.</span>",onGridReady:te,suppressCellFocus:!0,theme:To,style:{width:"100%",height:"100%",fontFamily:gs,"--ag-icon-font-family":wn}})})})]}),e.jsxs(Et,{anchorEl:i,open:!!i,onClose:z,elevation:2,PaperProps:{sx:{bgcolor:"#1f1f1f",color:"#f5f5f5"}},children:[e.jsx(fe,{onClick:()=>me(p),children:"Edit"}),e.jsx(fe,{onClick:()=>w(p),sx:{color:"#ff8080"},children:"Delete"})]}),e.jsx(Pl,{open:h,mode:y,credential:I,onClose:()=>{f(!1),k(null)},onSaved:F}),e.jsx(Zt,{open:!!v,onCancel:()=>j(null),onConfirm:W,confirmDisabled:B,message:v?`Delete credential '${v.name||""}'? Any jobs referencing it will require an update.`:""})]}):e.jsxs(Qe,{sx:{m:2,p:3,bgcolor:"#1e1e1e"},children:[e.jsx($,{variant:"h6",sx:{color:"#ff8080"},children:"Access denied"}),e.jsx($,{variant:"body2",sx:{color:"#bbb"},children:"You do not have permission to manage credentials."})]})}const Fl={m:2,p:0,bgcolor:"#1e1e1e"},Ll={minWidth:820,"& th, & td":{color:"#ddd",borderColor:"#2a2a2a",fontSize:13,py:.75},"& th .MuiTableSortLabel-root":{color:"#ddd"},"& th .MuiTableSortLabel-root.Mui-active":{color:"#ddd"}},$l={bgcolor:"#1e1e1e",color:"#fff",fontSize:"13px"},Ul={input:{color:"#fff"},minWidth:220,"& .MuiOutlinedInput-root":{"& fieldset":{borderColor:"#555"},"&:hover fieldset":{borderColor:"#888"}}};function no(n){if(!n)return"-";const t=new Date((n||0)*1e3),o=t.toLocaleDateString("en-US",{month:"2-digit",day:"2-digit",year:"numeric"}),a=t.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"});return`${o} @ ${a}`}async function oo(n){const o=new TextEncoder().encode(n||""),a=await crypto.subtle.digest("SHA-512",o);return Array.from(new Uint8Array(a)).map(u=>u.toString(16).padStart(2,"0")).join("")}function Wl({isAdmin:n=!1}){var ct;const[t,o]=s.useState([]),[a,d]=s.useState("username"),[u,r]=s.useState("asc"),[i,c]=s.useState(null),[p,l]=s.useState(null),[h,f]=s.useState(!1),[y,C]=s.useState(null),[I,k]=s.useState(""),[v,j]=s.useState(!1),[B,R]=s.useState({username:"",display_name:"",password:"",role:"User"}),[x,S]=s.useState(!1),[z,E]=s.useState(null),[U,X]=s.useState(!1),[ue,Se]=s.useState(null),[ce,de]=s.useState(null),[me,w]=s.useState(!1),[W,F]=s.useState(""),[te,ee]=s.useState(null),[be,Re]=s.useState(null),[Ae,Le]=s.useState(!1),[Fe,je]=s.useState(null),V=s.useMemo(()=>[{id:"display_name",label:"Display Name"},{id:"username",label:"User Name"},{id:"last_login",label:"Last Login"},{id:"role",label:"User Role"},{id:"mfa_enabled",label:"MFA"},{id:"actions",label:""}],[]),[O,M]=s.useState({}),[g,L]=s.useState(null),we=oe=>_e=>L({id:oe,anchorEl:_e.currentTarget}),T=()=>L(null),G=oe=>_e=>M($e=>({...$e,[oe]:_e.target.value})),ie=s.useCallback(async()=>{try{const _e=await(await fetch("/api/users",{credentials:"include"})).json();Array.isArray(_e==null?void 0:_e.users)?o(_e.users.map($e=>({...$e,mfa_enabled:$e&&typeof $e.mfa_enabled<"u"&&$e.mfa_enabled?1:0}))):o([])}catch{o([])}},[]);s.useEffect(()=>{n&&((async()=>{try{const oe=await fetch("/api/auth/me",{credentials:"include"});if(oe.ok){const _e=await oe.json();ee(_e)}}catch{}})(),ie())},[ie,n]);const Ce=oe=>{a===oe?r(u==="asc"?"desc":"asc"):(d(oe),r("asc"))},Ee=s.useMemo(()=>{const oe=Xe=>{for(const[We,Je]of Object.entries(O||{})){if(!Je)continue;const ft=String(Je).toLowerCase();let ht="";if(We==="last_login"?ht=String(no(Xe.last_login)):ht=String(Xe[We]??""),!ht.toLowerCase().includes(ft))return!1}return!0},_e=u==="asc"?1:-1,$e=t.filter(oe);return $e.sort((Xe,We)=>a==="last_login"?((Xe.last_login||0)-(We.last_login||0))*_e:a==="mfa_enabled"?((Xe.mfa_enabled?1:0)-(We.mfa_enabled?1:0))*_e:String(Xe[a]??"").toLowerCase().localeCompare(String(We[a]??"").toLowerCase())*_e),$e},[t,O,a,u]),Ne=(oe,_e)=>{c({mouseX:oe.clientX,mouseY:oe.clientY,anchorEl:oe.currentTarget}),l(_e)},Ke=()=>{c(null),l(null)},at=oe=>{if(oe){if(te&&oe.username&&String(te.username).toLowerCase()===String(oe.username).toLowerCase()){F("You cannot delete the user you are currently logged in as."),w(!0);return}E(oe),S(!0)}},ut=async()=>{const oe=z;if(S(!1),!!oe)try{const _e=await fetch(`/api/users/${encodeURIComponent(oe.username)}`,{method:"DELETE",credentials:"include"}),$e=await _e.json();if(!_e.ok){F(($e==null?void 0:$e.error)||"Failed to delete user"),w(!0);return}await ie()}catch(_e){console.error(_e),F("Failed to delete user"),w(!0)}},Pe=oe=>{if(!oe)return;if(te&&oe.username&&String(te.username).toLowerCase()===String(oe.username).toLowerCase()){F("You cannot change your own role."),w(!0);return}const _e=String(oe.role||"User").toLowerCase()==="admin"?"User":"Admin";Se(oe),de(_e),X(!0)},gt=async()=>{const oe=ue,_e=ce;if(X(!1),!(!oe||!_e))try{const $e=await fetch(`/api/users/${encodeURIComponent(oe.username)}/role`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({role:_e})}),Xe=await $e.json();if(!$e.ok){F((Xe==null?void 0:Xe.error)||"Failed to change role"),w(!0);return}await ie()}catch($e){console.error($e),F("Failed to change role"),w(!0)}},bt=oe=>{oe&&(je(oe),Le(!0))},vt=async()=>{const oe=Fe;if(Le(!1),je(null),!oe)return;const _e=oe.username,$e=!!oe.mfa_enabled;Re(_e);try{const Xe=await fetch(`/api/users/${encodeURIComponent(_e)}/mfa`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({enabled:$e,reset_secret:!0})}),We=await Xe.json();if(!Xe.ok){F((We==null?void 0:We.error)||"Failed to reset MFA for this user."),w(!0);return}await ie()}catch(Xe){console.error(Xe),F("Failed to reset MFA for this user."),w(!0)}finally{Re(null)}},Ut=async(oe,_e)=>{if(!oe)return;const $e=!!oe.mfa_enabled,Xe=_e?1:0;o(We=>We.map(Je=>String(Je.username).toLowerCase()===String(oe.username).toLowerCase()?{...Je,mfa_enabled:Xe}:Je)),Re(oe.username);try{const We=await fetch(`/api/users/${encodeURIComponent(oe.username)}/mfa`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({enabled:_e})}),Je=await We.json();if(!We.ok){o(ft=>ft.map(ht=>String(ht.username).toLowerCase()===String(oe.username).toLowerCase()?{...ht,mfa_enabled:$e?1:0}:ht)),F((Je==null?void 0:Je.error)||"Failed to update MFA settings."),w(!0);return}await ie()}catch(We){console.error(We),o(Je=>Je.map(ft=>String(ft.username).toLowerCase()===String(oe.username).toLowerCase()?{...ft,mfa_enabled:$e?1:0}:ft)),F("Failed to update MFA settings."),w(!0)}finally{Re(null)}},It=async()=>{const oe=y;if(!oe)return;const _e=I||"";if(_e.trim())try{const $e=await oo(_e),Xe=await fetch(`/api/users/${encodeURIComponent(oe.username)}/reset_password`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({password_sha512:$e})}),We=await Xe.json();if(!Xe.ok){alert((We==null?void 0:We.error)||"Failed to reset password");return}f(!1),C(null),k("")}catch($e){console.error($e),alert("Failed to reset password")}},yt=oe=>{oe&&(C(oe),f(!0),k(""))},pt=()=>{j(!0),R({username:"",display_name:"",password:"",role:"User"})},St=async()=>{const oe=(B.username||"").trim(),_e=(B.display_name||oe).trim(),$e=(B.password||"").trim(),Xe=B.role||"User";if(!(!oe||!$e))try{const We=await oo($e),Je=await fetch("/api/users",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({username:oe,display_name:_e,password_sha512:We,role:Xe})}),ft=await Je.json();if(!Je.ok){alert((ft==null?void 0:ft.error)||"Failed to create user");return}j(!1),await ie()}catch(We){console.error(We),alert("Failed to create user")}};return n?e.jsxs(e.Fragment,{children:[e.jsxs(Qe,{sx:Fl,elevation:2,children:[e.jsxs(m,{sx:{p:2,pb:1,display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:0},children:"User Management"}),e.jsx($,{variant:"body2",sx:{color:"#aaa"},children:"Manage authorized users of the Borealis Automation Platform."})]}),e.jsx(Z,{variant:"outlined",size:"small",onClick:pt,sx:{color:"#58a6ff",borderColor:"#58a6ff",textTransform:"none"},children:"Create User"})]}),e.jsxs(Rt,{size:"small",sx:Ll,children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{padding:"checkbox"}),V.map(oe=>e.jsx(Q,{sortDirection:["actions"].includes(oe.id)?!1:a===oe.id?u:!1,children:oe.id!=="actions"?e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(Tt,{active:a===oe.id,direction:a===oe.id?u:"asc",onClick:()=>Ce(oe.id),children:oe.label}),e.jsx(nt,{size:"small",onClick:we(oe.id),sx:{color:O[oe.id]?"#58a6ff":"#888"},children:e.jsx(Rn,{fontSize:"inherit"})})]}):null},oe.id))]})}),e.jsxs(Nt,{children:[Ee.map(oe=>e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{padding:"checkbox"}),e.jsx(Q,{children:oe.display_name||oe.username}),e.jsx(Q,{children:oe.username}),e.jsx(Q,{children:no(oe.last_login)}),e.jsx(Q,{children:oe.role||"User"}),e.jsx(Q,{align:"center",children:e.jsx(At,{size:"small",checked:!!oe.mfa_enabled,disabled:!!(be&&String(be).toLowerCase()===String(oe.username).toLowerCase()),onChange:_e=>{_e.stopPropagation(),Ut(oe,_e.target.checked)},onClick:_e=>_e.stopPropagation(),sx:{color:"#888","&.Mui-checked":{color:"#58a6ff"}},inputProps:{"aria-label":`Toggle MFA for ${oe.username}`}})}),e.jsx(Q,{align:"right",children:e.jsx(nt,{size:"small",onClick:_e=>Ne(_e,oe),sx:{color:"#ccc"},children:e.jsx(on,{fontSize:"inherit"})})})]},oe.username)),Ee.length===0&&e.jsx(Ue,{children:e.jsx(Q,{colSpan:V.length+1,sx:{color:"#888"},children:"No users found."})})]})]}),e.jsx(Ls,{open:!!g,anchorEl:(g==null?void 0:g.anchorEl)||null,onClose:T,anchorOrigin:{vertical:"bottom",horizontal:"left"},PaperProps:{sx:{bgcolor:"#1e1e1e",p:1}},children:g&&e.jsxs(m,{sx:{display:"flex",gap:1,alignItems:"center"},children:[e.jsx(Ie,{autoFocus:!0,size:"small",placeholder:`Filter ${((ct=V.find(oe=>oe.id===g.id))==null?void 0:ct.label)||""}`,value:O[g.id]||"",onChange:G(g.id),onKeyDown:oe=>{oe.key==="Escape"&&T()},sx:Ul}),e.jsx(Z,{variant:"outlined",size:"small",onClick:()=>{M(oe=>({...oe,[g.id]:""})),T()},sx:{textTransform:"none",borderColor:"#555",color:"#bbb"},children:"Clear"})]})}),e.jsxs(Et,{anchorEl:i==null?void 0:i.anchorEl,open:!!i,onClose:Ke,anchorOrigin:{vertical:"bottom",horizontal:"right"},transformOrigin:{vertical:"top",horizontal:"right"},PaperProps:{sx:$l},children:[e.jsx(fe,{disabled:te&&p&&String(te.username).toLowerCase()===String(p.username).toLowerCase(),onClick:()=>{const oe=p;Ke(),at(oe)},children:"Delete User"}),e.jsx(fe,{onClick:()=>{const oe=p;Ke(),yt(oe)},children:"Reset Password"}),e.jsx(fe,{disabled:te&&p&&String(te.username).toLowerCase()===String(p.username).toLowerCase(),onClick:()=>{const oe=p;Ke(),Pe(oe)},children:"Change Role"}),e.jsx(fe,{onClick:()=>{const oe=p;Ke(),bt(oe)},children:"Reset MFA"})]}),e.jsxs(Ze,{open:h,onClose:()=>f(!1),PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Reset Password"}),e.jsxs(rt,{children:[e.jsxs($t,{sx:{color:"#ccc"},children:["Enter a new password for ",y==null?void 0:y.username,"."]}),e.jsx(Ie,{autoFocus:!0,margin:"dense",fullWidth:!0,label:"New Password",type:"password",variant:"outlined",value:I,onChange:oe=>k(oe.target.value),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:()=>{f(!1),C(null)},sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:It,sx:{color:"#58a6ff"},children:"OK"})]})]}),e.jsxs(Ze,{open:v,onClose:()=>j(!1),PaperProps:{sx:{bgcolor:"#121212",color:"#fff"}},children:[e.jsx(et,{children:"Create User"}),e.jsxs(rt,{children:[e.jsx(Ie,{autoFocus:!0,margin:"dense",fullWidth:!0,label:"Username",variant:"outlined",value:B.username,onChange:oe=>R(_e=>({..._e,username:oe.target.value})),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}}),e.jsx(Ie,{margin:"dense",fullWidth:!0,label:"Display Name (optional)",variant:"outlined",value:B.display_name,onChange:oe=>R(_e=>({..._e,display_name:oe.target.value})),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}}),e.jsx(Ie,{margin:"dense",fullWidth:!0,label:"Password",type:"password",variant:"outlined",value:B.password,onChange:oe=>R(_e=>({..._e,password:oe.target.value})),sx:{"& .MuiOutlinedInput-root":{backgroundColor:"#2a2a2a",color:"#ccc","& fieldset":{borderColor:"#444"},"&:hover fieldset":{borderColor:"#666"}},label:{color:"#aaa"},mt:1}}),e.jsxs(Ht,{fullWidth:!0,sx:{mt:2},children:[e.jsx(Gt,{sx:{color:"#aaa"},children:"Role"}),e.jsxs(wt,{native:!0,value:B.role,onChange:oe=>R(_e=>({..._e,role:oe.target.value})),sx:{backgroundColor:"#2a2a2a",color:"#ccc",borderColor:"#444"},children:[e.jsx("option",{value:"User",children:"User"}),e.jsx("option",{value:"Admin",children:"Admin"})]})]})]}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:()=>j(!1),sx:{color:"#58a6ff"},children:"Cancel"}),e.jsx(Z,{onClick:St,sx:{color:"#58a6ff"},children:"Create"})]})]})]}),e.jsx(Zt,{open:x,message:`Are you sure you want to delete user '${(z==null?void 0:z.username)||""}'?`,onCancel:()=>S(!1),onConfirm:ut}),e.jsx(Zt,{open:U,message:ue?`Change role for '${ue.username}' to ${ce}?`:"",onCancel:()=>X(!1),onConfirm:gt}),e.jsx(Zt,{open:Ae,message:Fe?`Reset MFA enrollment for '${Fe.username}'? This clears their existing authenticator.`:"",onCancel:()=>{Le(!1),je(null)},onConfirm:vt}),e.jsx(Zt,{open:me,message:W,onCancel:()=>w(!1),onConfirm:()=>w(!1)})]}):null}const Vl={m:2,p:0,bgcolor:"#1e1e1e",color:"#f5f7fa",display:"flex",flexDirection:"column",flexGrow:1,minWidth:0,minHeight:320},Hl={mt:2,"& .MuiOutlinedInput-root":{bgcolor:"#181818",color:"#f5f7fa","& fieldset":{borderColor:"#2a2a2a"},"&:hover fieldset":{borderColor:"#58a6ff"},"&.Mui-focused fieldset":{borderColor:"#58a6ff"}},"& .MuiInputLabel-root":{color:"#bbb"},"& .MuiInputLabel-root.Mui-focused":{color:"#7db7ff"}};function Gl({isAdmin:n=!1}){const[t,o]=s.useState(!1),[a,d]=s.useState(!1),[u,r]=s.useState(""),[i,c]=s.useState(""),[p,l]=s.useState(""),[h,f]=s.useState(!1),[y,C]=s.useState({message:"",valid:null,status:"",rateLimit:null,error:""}),I=s.useCallback(async()=>{o(!0),l("");try{const R=await fetch("/api/github/token"),x=await R.json();if(!R.ok)throw new Error((x==null?void 0:x.error)||`HTTP ${R.status}`);const S=typeof(x==null?void 0:x.token)=="string"?x.token:"";r(S),c(S),f(!1),C({message:typeof(x==null?void 0:x.message)=="string"?x.message:"",valid:(x==null?void 0:x.valid)===!0,status:typeof(x==null?void 0:x.status)=="string"?x.status:"",rateLimit:typeof(x==null?void 0:x.rate_limit)=="number"?x.rate_limit:null,error:typeof(x==null?void 0:x.error)=="string"?x.error:""})}catch(R){const x=R&&typeof R.message=="string"?R.message:String(R);l(x),r(""),c(""),C({message:"",valid:null,status:"",rateLimit:null,error:""})}finally{o(!1)}},[]);s.useEffect(()=>{n&&I()},[I,n]);const k=s.useCallback(async()=>{d(!0),l("");try{const R=await fetch("/api/github/token",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:i})}),x=await R.json();if(!R.ok)throw new Error((x==null?void 0:x.error)||`HTTP ${R.status}`);const S=typeof(x==null?void 0:x.token)=="string"?x.token:"";r(S),c(S),f(!1),C({message:typeof(x==null?void 0:x.message)=="string"?x.message:"",valid:(x==null?void 0:x.valid)===!0,status:typeof(x==null?void 0:x.status)=="string"?x.status:"",rateLimit:typeof(x==null?void 0:x.rate_limit)=="number"?x.rate_limit:null,error:typeof(x==null?void 0:x.error)=="string"?x.error:""})}catch(R){const x=R&&typeof R.message=="string"?R.message:String(R);l(x)}finally{d(!1)}},[i]),v=s.useMemo(()=>i!==u,[i,u]),j=s.useMemo(()=>{if(v)return{text:"Token has not been saved yet — Save to verify.",color:"#f0c36d"};const R=y.message||"";return R?y.valid?{text:R,color:"#7dffac"}:(y.status||"").toLowerCase()==="missing"?{text:R,color:"#bbb"}:{text:R,color:"#ff8080"}:{text:"",color:"#bbb"}},[v,y]),B=s.useCallback(()=>{f(R=>!R)},[]);return n?e.jsxs(Qe,{sx:Vl,elevation:2,children:[e.jsx(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",p:2,borderBottom:"1px solid #2a2a2a"},children:e.jsxs(m,{children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:.3},children:"Github API Token"}),e.jsxs($,{variant:"body2",sx:{color:"#aaa"},children:['Using a Github "Personal Access Token" increases the Github API rate limits from 60/hr to 5,000/hr. This is important for production Borealis usage as it likes to hit its unauthenticated API limits sometimes despite my best efforts.',e.jsx("br",{}),"Navigate to"," ",e.jsx(kr,{href:"https://github.com/settings/tokens",target:"_blank",rel:"noopener noreferrer",sx:{color:"#7db7ff"},children:"https://github.com/settings/tokens"})," "," ",e.jsx("b",{children:"Personal Access Tokens Tokens (Classic) Generate New Token New Personal Access Token (Classic)"})]}),e.jsx("br",{}),e.jsxs($,{variant:"body2",sx:{color:"#ccc"},children:[e.jsx(m,{component:"span",sx:{fontWeight:600},children:"Note:"})," ",e.jsx(m,{component:"code",sx:{bgcolor:"#222",px:.75,py:.25,borderRadius:1,fontSize:"0.85rem"},children:"Borealis Automation Platform"})]}),e.jsxs($,{variant:"body2",sx:{color:"#ccc"},children:[e.jsx(m,{component:"span",sx:{fontWeight:600},children:"Scope:"})," ",e.jsx(m,{component:"code",sx:{bgcolor:"#222",px:.75,py:.25,borderRadius:1,fontSize:"0.85rem"},children:"public_repo"})]}),e.jsxs($,{variant:"body2",sx:{color:"#ccc"},children:[e.jsx(m,{component:"span",sx:{fontWeight:600},children:"Expiration:"})," ",e.jsx(m,{component:"code",sx:{bgcolor:"#222",px:.75,py:.25,borderRadius:1,fontSize:"0.85rem"},children:"No Expiration"})]})]})}),e.jsxs(m,{sx:{px:2,py:2,display:"flex",flexDirection:"column",gap:1.5},children:[e.jsx(Ie,{label:"Personal Access Token",value:i,onChange:R=>c(R.target.value),fullWidth:!0,variant:"outlined",sx:Hl,disabled:a||t,type:h?"text":"password",InputProps:{endAdornment:e.jsxs(Ir,{position:"end",sx:{mr:-1,display:"flex",alignItems:"center",gap:1},children:[e.jsx(Z,{variant:"contained",size:"small",onClick:B,disabled:t||a,startIcon:h?e.jsx(Rr,{}):e.jsx(Nr,{}),sx:{bgcolor:"#3a3a3a",color:"#f5f7fa",minWidth:96,mr:.5,"&:hover":{bgcolor:"#4a4a4a"}},children:h?"Hide":"Reveal"}),e.jsx(Z,{variant:"contained",size:"small",onClick:k,disabled:a||t,startIcon:a?null:e.jsx(ho,{}),sx:{bgcolor:"#58a6ff",color:"#0b0f19",minWidth:88,mr:1,"&:hover":{bgcolor:"#7db7ff"}},children:a?e.jsx(Mt,{size:16,sx:{color:"#0b0f19"}}):"Save"})]})}}),e.jsxs(m,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:2},children:[e.jsx(Z,{variant:"outlined",size:"small",startIcon:e.jsx(Ss,{}),sx:{borderColor:"#58a6ff",color:"#58a6ff"},onClick:I,disabled:t||a,children:"Refresh"}),(j.text||!v&&y.rateLimit)&&e.jsxs($,{variant:"body2",sx:{display:"inline-flex",alignItems:"center",color:j.color||"#7db7ff",textAlign:"right"},children:[j.text&&`${j.text} `,!v&&y.rateLimit&&`- Hourly Request Rate Limit: ${y.rateLimit.toLocaleString()}`]})]}),t&&e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:1,color:"#7db7ff",px:2,py:1.5,borderBottom:"1px solid #2a2a2a"},children:[e.jsx(Mt,{size:18,sx:{color:"#58a6ff"}}),e.jsx($,{variant:"body2",children:"Loading token…"})]}),p&&e.jsx(m,{sx:{px:2,py:1.5,color:"#ff8080",borderBottom:"1px solid #2a2a2a"},children:e.jsx($,{variant:"body2",children:p})})]})]}):e.jsxs(Qe,{sx:{m:2,p:3,bgcolor:"#1e1e1e"},children:[e.jsx($,{variant:"h6",sx:{color:"#ff8080"},children:"Access denied"}),e.jsx($,{variant:"body2",sx:{color:"#bbb"},children:"You do not have permission to manage the GitHub API token."})]})}function ql({isAdmin:n=!1}){const[t,o]=s.useState(null),[a,d]=s.useState(null),[u,r]=s.useState(!1);return s.useEffect(()=>{if(!n)return;let i=!0;const c=async()=>{try{const l=await fetch("/api/server/time");if(!l.ok)throw new Error(`HTTP ${l.status}`);const h=await l.json();i&&(o((h==null?void 0:h.display)||(h==null?void 0:h.iso)||null),d(null))}catch(l){i&&d(String(l))}};c();const p=setInterval(c,6e4);return()=>{i=!1,clearInterval(p)}},[n]),n?e.jsxs(Qe,{sx:{m:2,p:0,bgcolor:"#1e1e1e"},elevation:2,children:[e.jsxs(m,{sx:{p:2},children:[e.jsx($,{variant:"h6",sx:{color:"#58a6ff",mb:1},children:"Server Info"}),e.jsx($,{sx:{color:"#aaa",mb:1},children:"Basic server information will appear here for informative and debug purposes."}),e.jsxs(m,{sx:{display:"flex",gap:2,alignItems:"baseline"},children:[e.jsx($,{sx:{color:"#ccc",fontWeight:600,minWidth:120},children:"Server Time"}),e.jsx($,{sx:{color:a?"#ff6b6b":"#ddd",fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'},children:a?`Error: ${a}`:t||"Loading..."})]}),e.jsxs(m,{sx:{mt:3},children:[e.jsx($,{variant:"subtitle1",sx:{color:"#58a6ff",mb:1},children:"Project Links"}),e.jsxs(m,{sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[e.jsx(Z,{variant:"outlined",color:"primary",startIcon:e.jsx(po,{}),onClick:()=>window.open("https://github.com/bunny-lab-io/Borealis","_blank"),sx:{borderColor:"#3a3a3a",color:"#7db7ff"},children:"GitHub Project"}),e.jsx(Z,{variant:"outlined",color:"inherit",startIcon:e.jsx(Tr,{}),onClick:()=>r(!0),sx:{borderColor:"#3a3a3a",color:"#ddd"},children:"About Borealis"})]})]})]}),e.jsx(ki,{open:u,onClose:()=>r(!1)})]}):null}const Jl=[{value:1,label:"1 hour"},{value:3,label:"3 hours"},{value:6,label:"6 hours"},{value:12,label:"12 hours"},{value:24,label:"24 hours"}],Yl={active:"success",used:"default",expired:"warning"},Kl=n=>{if(!n)return"—";const t=n.split("-");if(t.length<=1){const o=n.slice(0,4);return`${o}${"•".repeat(Math.max(0,n.length-o.length))}`}return t.map((o,a)=>a===0||a===t.length-1?o:"•".repeat(o.length)).join("-")},vn=n=>{if(!n)return"—";const t=new Date(n);return Number.isNaN(t.getTime())?n:t.toLocaleString()},Sn=n=>{if(!n)return"expired";const t=Number.isFinite(n==null?void 0:n.max_uses)?n.max_uses:1;if((Number.isFinite(n==null?void 0:n.use_count)?n.use_count:0)>=Math.max(1,t||1))return"used";if(!n.expires_at)return"expired";const a=new Date(n.expires_at);return Number.isNaN(a.getTime())?"expired":a.getTime()>Date.now()?"active":"expired"};function Xl(){const[n,t]=s.useState([]),[o,a]=s.useState(!1),[d,u]=s.useState(""),[r,i]=s.useState(null),[c,p]=s.useState("all"),[l,h]=s.useState(6),[f,y]=s.useState(!1),[C,I]=s.useState(2),k=s.useMemo(()=>c==="all"?n:n.filter(S=>Sn(S)===c),[n,c]),v=s.useCallback(async()=>{a(!0),u("");try{const S=c==="all"?"":`?status=${encodeURIComponent(c)}`,z=await fetch(`/api/admin/enrollment-codes${S}`,{credentials:"include"});if(!z.ok){const U=await z.json().catch(()=>({}));throw new Error(U.error||`Request failed (${z.status})`)}const E=await z.json();t(Array.isArray(E.codes)?E.codes:[])}catch(S){u(S.message||"Unable to load enrollment codes")}finally{a(!1)}},[c]);s.useEffect(()=>{v()},[v]);const j=s.useCallback(async()=>{y(!0),u("");try{const S=await fetch("/api/admin/enrollment-codes",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({ttl_hours:l,max_uses:C})});if(!S.ok){const E=await S.json().catch(()=>({}));throw new Error(E.error||`Request failed (${S.status})`)}const z=await S.json();i({type:"success",message:`Installer code ${z.code} created`}),await v()}catch(S){i({type:"error",message:S.message||"Failed to create code"})}finally{y(!1)}},[v,l,C]),B=s.useCallback(async S=>{if(!(!S||!window.confirm("Delete this unused installer code?"))){u("");try{const E=await fetch(`/api/admin/enrollment-codes/${encodeURIComponent(S)}`,{method:"DELETE",credentials:"include"});if(!E.ok){const U=await E.json().catch(()=>({}));throw new Error(U.error||`Request failed (${E.status})`)}i({type:"success",message:"Installer code deleted"}),await v()}catch(E){i({type:"error",message:E.message||"Failed to delete code"})}}},[v]),R=s.useCallback(S=>{var z;if(S)try{if((z=navigator.clipboard)!=null&&z.writeText)navigator.clipboard.writeText(S),i({type:"success",message:"Code copied to clipboard"});else{const E=document.createElement("textarea");E.value=S,E.style.position="fixed",E.style.opacity="0",document.body.appendChild(E),E.select(),document.execCommand("copy"),document.body.removeChild(E),i({type:"success",message:"Code copied to clipboard"})}}catch(E){i({type:"error",message:E.message||"Unable to copy code"})}},[]),x=S=>{const z=Sn(S);return e.jsx(yo,{size:"small",label:z,color:Yl[z]||"default",variant:"outlined"})};return e.jsxs(m,{sx:{p:3,display:"flex",flexDirection:"column",gap:3},children:[e.jsxs(ds,{direction:"row",alignItems:"center",spacing:2,children:[e.jsx(uo,{color:"primary"}),e.jsx($,{variant:"h5",children:"Enrollment Installer Codes"})]}),e.jsxs(Qe,{sx:{p:2,display:"flex",flexDirection:"column",gap:2},children:[e.jsxs(ds,{direction:{xs:"column",sm:"row"},spacing:2,alignItems:{xs:"stretch",sm:"center"},children:[e.jsxs(Ht,{size:"small",sx:{minWidth:160},children:[e.jsx(Gt,{id:"status-filter-label",children:"Filter"}),e.jsxs(wt,{labelId:"status-filter-label",label:"Filter",value:c,onChange:S=>p(S.target.value),children:[e.jsx(fe,{value:"all",children:"All"}),e.jsx(fe,{value:"active",children:"Active"}),e.jsx(fe,{value:"used",children:"Used"}),e.jsx(fe,{value:"expired",children:"Expired"})]})]}),e.jsxs(Ht,{size:"small",sx:{minWidth:180},children:[e.jsx(Gt,{id:"ttl-select-label",children:"Duration"}),e.jsx(wt,{labelId:"ttl-select-label",label:"Duration",value:l,onChange:S=>h(Number(S.target.value)),children:Jl.map(S=>e.jsx(fe,{value:S.value,children:S.label},S.value))})]}),e.jsxs(Ht,{size:"small",sx:{minWidth:160},children:[e.jsx(Gt,{id:"uses-select-label",children:"Allowed Uses"}),e.jsx(wt,{labelId:"uses-select-label",label:"Allowed Uses",value:C,onChange:S=>I(Number(S.target.value)),children:[1,2,3,5].map(S=>e.jsx(fe,{value:S,children:S===1?"Single use":`${S} uses`},S))})]}),e.jsx(Z,{variant:"contained",color:"primary",onClick:j,disabled:f,startIcon:f?e.jsx(Mt,{size:16,color:"inherit"}):null,children:f?"Generating…":"Generate Code"}),e.jsx(Z,{variant:"outlined",startIcon:e.jsx(Ss,{}),onClick:v,disabled:o,children:"Refresh"})]}),r?e.jsx(rn,{severity:r.type,onClose:()=>i(null),variant:"outlined",children:r.message}):null,d?e.jsx(rn,{severity:"error",variant:"outlined",children:d}):null,e.jsx(bo,{component:Qe,variant:"outlined",sx:{maxHeight:420},children:e.jsxs(Rt,{size:"small",stickyHeader:!0,children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Status"}),e.jsx(Q,{children:"Installer Code"}),e.jsx(Q,{children:"Expires At"}),e.jsx(Q,{children:"Created By"}),e.jsx(Q,{children:"Usage"}),e.jsx(Q,{children:"Last Used"}),e.jsx(Q,{children:"Consumed At"}),e.jsx(Q,{children:"Used By GUID"}),e.jsx(Q,{align:"right",children:"Actions"})]})}),e.jsx(Nt,{children:o?e.jsx(Ue,{children:e.jsx(Q,{colSpan:7,align:"center",children:e.jsxs(ds,{direction:"row",spacing:1,alignItems:"center",justifyContent:"center",children:[e.jsx(Mt,{size:20}),e.jsx($,{variant:"body2",children:"Loading installer codes…"})]})})}):k.length===0?e.jsx(Ue,{children:e.jsx(Q,{colSpan:7,align:"center",children:e.jsx($,{variant:"body2",color:"text.secondary",children:"No installer codes match this filter."})})}):k.map(S=>{Sn(S);const z=Math.max(1,Number.isFinite(S==null?void 0:S.max_uses)?S.max_uses:1),E=Math.max(0,Number.isFinite(S==null?void 0:S.use_count)?S.use_count:0),U=E!==0;return e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{children:x(S)}),e.jsx(Q,{sx:{fontFamily:"monospace"},children:Kl(S.code)}),e.jsx(Q,{children:vn(S.expires_at)}),e.jsx(Q,{children:S.created_by_user_id||"—"}),e.jsx(Q,{sx:{fontFamily:"monospace"},children:`${E} / ${z}`}),e.jsx(Q,{children:vn(S.last_used_at)}),e.jsx(Q,{children:vn(S.used_at)}),e.jsx(Q,{sx:{fontFamily:"monospace"},children:S.used_by_guid||"—"}),e.jsxs(Q,{align:"right",children:[e.jsx(st,{title:"Copy code",children:e.jsx("span",{children:e.jsx(nt,{size:"small",onClick:()=>R(S.code),disabled:!S.code,children:e.jsx(fo,{fontSize:"small"})})})}),e.jsx(st,{title:U?"Only unused codes can be deleted":"Delete code",children:e.jsx("span",{children:e.jsx(nt,{size:"small",onClick:()=>B(S.id),disabled:U,children:e.jsx(mo,{fontSize:"small"})})})})]})]},S.id)})})]})})]})]})}const Ql=es.memo(Xl),Zl=[{value:"all",label:"All"},{value:"pending",label:"Pending"},{value:"approved",label:"Approved"},{value:"completed",label:"Completed"},{value:"denied",label:"Denied"},{value:"expired",label:"Expired"}],ec={pending:"warning",approved:"info",completed:"success",denied:"default",expired:"default"},ro=n=>{if(!n)return"—";const t=new Date(n);return Number.isNaN(t.getTime())?n:t.toLocaleString()},tc=n=>{var o;if(!n)return"—";const t=n.replace(/[^a-f0-9]/gi,"").toLowerCase();return t?((o=t.match(/.{1,4}/g))==null?void 0:o.join(" "))??t:n},Cn=n=>n?n==="completed"?"completed":n.toLowerCase():"pending";function sc(){const[n,t]=s.useState([]),[o,a]=s.useState("all"),[d,u]=s.useState(!1),[r,i]=s.useState(""),[c,p]=s.useState(null),[l,h]=s.useState({}),[f,y]=s.useState(null),[C,I]=s.useState(null),k=s.useCallback(async()=>{u(!0),i("");try{const w=o==="all"?"":`?status=${encodeURIComponent(o)}`,W=await fetch(`/api/admin/device-approvals${w}`,{credentials:"include"});if(!W.ok){const te=await W.json().catch(()=>({}));throw new Error(te.error||`Request failed (${W.status})`)}const F=await W.json();t(Array.isArray(F.approvals)?F.approvals:[])}catch(w){i(w.message||"Unable to load device approvals")}finally{u(!1)}},[o]);s.useEffect(()=>{k()},[k]);const v=s.useMemo(()=>{const w=n.map(te=>({...te,status:Cn(te.status)})).sort((te,ee)=>{const be=new Date(te.created_at||0).getTime(),Re=new Date(ee.created_at||0).getTime();return be-Re});if(o!=="pending")return w;const W=new Set,F=[];for(const te of w){const ee=te.ssl_key_fingerprint_claimed||te.hostname_claimed||te.id;W.has(ee)||(W.add(ee),F.push(te))}return F},[n,o]),j=s.useCallback((w,W)=>{h(F=>({...F,[w]:W}))},[]),B=s.useCallback(async(w,W={})=>{if(w!=null&&w.id){y(w.id),p(null),i("");try{const F=(l[w.id]||"").trim(),te={},ee=W.guid;let be="";typeof ee=="string"?be=ee.trim():ee!=null&&(be=String(ee).trim()),be?te.guid=be:F&&(te.guid=F);const Re=W.conflictResolution||W.resolution;typeof Re=="string"&&Re.trim()&&(te.conflict_resolution=Re.trim().toLowerCase());const Ae=await fetch(`/api/admin/device-approvals/${encodeURIComponent(w.id)}/approve`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(Object.keys(te).length?te:{})}),Le=await Ae.json().catch(()=>({}));if(!Ae.ok){if(Ae.status===409&&Le.error==="conflict_resolution_required"){const V=w.hostname_conflict,O=w.alternate_hostname||(w.hostname_claimed?`${w.hostname_claimed}-1`:"");V&&I({record:w,conflict:V,alternate:O||""});return}throw new Error(Le.error||`Approval failed (${Ae.status})`)}const Fe=(Le.conflict_resolution||te.conflict_resolution||"").toLowerCase();let je="Enrollment approved";Fe==="overwrite"?je="Enrollment approved; existing device overwritten":Fe==="coexist"?je="Enrollment approved; devices will co-exist":Fe==="auto_merge_fingerprint"&&(je="Enrollment approved; device reconnected with its existing identity"),p({type:"success",message:je}),await k()}catch(F){p({type:"error",message:F.message||"Unable to approve request"})}finally{y(null)}}},[l,k]),R=s.useCallback(w=>{if(!(w!=null&&w.id)||Cn(w.status)!=="pending")return;const F=(l[w.id]||"").trim(),te=w.hostname_conflict;if(!!((te==null?void 0:te.requires_prompt)??w.conflict_requires_prompt)&&!F){const be=w.alternate_hostname||(w.hostname_claimed?`${w.hostname_claimed}-1`:"");I({record:w,conflict:te,alternate:be||""});return}B(w)},[l,B]),x=s.useCallback(()=>{I(null)},[]),S=s.useCallback(()=>{if(!(C!=null&&C.record)){I(null);return}const{record:w,conflict:W}=C;I(null);const F=(W==null?void 0:W.guid)!=null?String(W.guid).trim():"";B(w,{guid:F,conflictResolution:"overwrite"})},[C,B]),z=s.useCallback(()=>{if(!(C!=null&&C.record)){I(null);return}const{record:w}=C;I(null),B(w,{conflictResolution:"coexist"})},[C,B]),E=C==null?void 0:C.record,U=C==null?void 0:C.conflict,X=(E==null?void 0:E.hostname_claimed)||(E==null?void 0:E.hostname)||"",ue=(U==null?void 0:U.site_name)||"",Se=U&&ue?`under site ${ue}`:"under site (not assigned)",ce=(C==null?void 0:C.alternate)||(X?`${X}-1`:"hostname-1"),de=(U==null?void 0:U.guid)||"",me=s.useCallback(async w=>{if(!(!(w!=null&&w.id)||!window.confirm("Deny this enrollment request?"))){y(w.id),p(null),i("");try{const F=await fetch(`/api/admin/device-approvals/${encodeURIComponent(w.id)}/deny`,{method:"POST",credentials:"include"});if(!F.ok){const te=await F.json().catch(()=>({}));throw new Error(te.error||`Deny failed (${F.status})`)}p({type:"success",message:"Enrollment denied"}),await k()}catch(F){p({type:"error",message:F.message||"Unable to deny request"})}finally{y(null)}}},[k]);return e.jsxs(m,{sx:{p:3,display:"flex",flexDirection:"column",gap:3},children:[e.jsxs(ds,{direction:"row",alignItems:"center",spacing:2,children:[e.jsx(Ar,{color:"primary"}),e.jsx($,{variant:"h5",children:"Device Approval Queue"})]}),e.jsxs(Qe,{sx:{p:2,display:"flex",flexDirection:"column",gap:2},children:[e.jsxs(ds,{direction:{xs:"column",sm:"row"},spacing:2,alignItems:{xs:"stretch",sm:"center"},children:[e.jsxs(Ht,{size:"small",sx:{minWidth:200},children:[e.jsx(Gt,{id:"approval-status-filter-label",children:"Status"}),e.jsx(wt,{labelId:"approval-status-filter-label",label:"Status",value:o,onChange:w=>a(w.target.value),children:Zl.map(w=>e.jsx(fe,{value:w.value,children:w.label},w.value))})]}),e.jsx(Z,{variant:"outlined",startIcon:e.jsx(Ss,{}),onClick:k,disabled:d,children:"Refresh"})]}),c?e.jsx(rn,{severity:c.type,variant:"outlined",onClose:()=>p(null),children:c.message}):null,r?e.jsx(rn,{severity:"error",variant:"outlined",children:r}):null,e.jsx(bo,{component:Qe,variant:"outlined",sx:{maxHeight:480},children:e.jsxs(Rt,{size:"small",stickyHeader:!0,children:[e.jsx(Bt,{children:e.jsxs(Ue,{children:[e.jsx(Q,{children:"Status"}),e.jsx(Q,{children:"Hostname"}),e.jsx(Q,{children:"Fingerprint"}),e.jsx(Q,{children:"Enrollment Code"}),e.jsx(Q,{children:"Created"}),e.jsx(Q,{children:"Updated"}),e.jsx(Q,{children:"Approved By"}),e.jsx(Q,{align:"right",children:"Actions"})]})}),e.jsx(Nt,{children:d?e.jsx(Ue,{children:e.jsx(Q,{colSpan:8,align:"center",children:e.jsxs(ds,{direction:"row",spacing:1,alignItems:"center",justifyContent:"center",children:[e.jsx(Mt,{size:20}),e.jsx($,{variant:"body2",children:"Loading approvals…"})]})})}):v.length===0?e.jsx(Ue,{children:e.jsx(Q,{colSpan:8,align:"center",children:e.jsx($,{variant:"body2",color:"text.secondary",children:"No enrollment requests match this filter."})})}):v.map(w=>{const W=Cn(w.status),F=W==="pending",te=l[w.id]||"",ee=w.approved_by_username||w.approved_by_user_id;return e.jsxs(Ue,{hover:!0,children:[e.jsx(Q,{children:e.jsx(yo,{size:"small",label:W,color:ec[W]||"default",variant:"outlined"})}),e.jsx(Q,{children:w.hostname_claimed||"—"}),e.jsx(Q,{sx:{fontFamily:"monospace",whiteSpace:"nowrap"},children:tc(w.ssl_key_fingerprint_claimed)}),e.jsx(Q,{sx:{fontFamily:"monospace"},children:w.enrollment_code_id||"—"}),e.jsx(Q,{children:ro(w.created_at)}),e.jsx(Q,{children:ro(w.updated_at)}),e.jsx(Q,{children:ee||"—"}),e.jsx(Q,{align:"right",children:F?e.jsxs(ds,{direction:{xs:"column",sm:"row"},spacing:1,alignItems:"center",children:[e.jsx(Ie,{size:"small",label:"Optional GUID",placeholder:"Leave empty to auto-generate",value:te,onChange:be=>j(w.id,be.target.value),sx:{minWidth:200}}),e.jsxs(ds,{direction:"row",spacing:1,children:[e.jsx(st,{title:"Approve enrollment",children:e.jsx("span",{children:e.jsx(nt,{color:"success",onClick:()=>R(w),disabled:f===w.id,children:f===w.id?e.jsx(Mt,{color:"success",size:20}):e.jsx(Br,{fontSize:"small"})})})}),e.jsx(st,{title:"Deny enrollment",children:e.jsx("span",{children:e.jsx(nt,{color:"error",onClick:()=>me(w),disabled:f===w.id,children:e.jsx(Or,{fontSize:"small"})})})})]})]}):e.jsx($,{variant:"body2",color:"text.secondary",children:"No actions available"})})]},w.id)})})]})})]}),e.jsxs(Ze,{open:!!C,onClose:x,maxWidth:"sm",fullWidth:!0,children:[e.jsx(et,{children:"Hostname Conflict"}),e.jsx(rt,{dividers:!0,children:e.jsxs(ds,{spacing:2,children:[e.jsx($t,{children:X?`Device ${X} already exists in the database ${Se}.`:`A device with this hostname already exists in the database ${Se}.`}),e.jsx($t,{children:"Do you want this device to overwrite the existing device, or allow both to co-exist?"}),e.jsx($t,{children:`Device will be renamed ${ce} if you choose to allow both to co-exist.`}),de?e.jsxs($,{variant:"body2",color:"text.secondary",children:["Existing device GUID: ",de]}):null]})}),e.jsxs(tt,{children:[e.jsx(Z,{onClick:x,children:"Cancel"}),e.jsx(Z,{onClick:z,color:"info",variant:"outlined",children:"Allow Both"}),e.jsx(Z,{onClick:S,color:"primary",variant:"contained",disabled:!de,children:"Overwrite Existing"})]})]})]})}const nc=es.memo(sc);window.BorealisSocket||(window.BorealisSocket=qr(window.location.origin,{transports:["websocket"]}));window.BorealisUpdateRate||(window.BorealisUpdateRate=200);const oc=Object.assign({"./Nodes/Agent/Node_Agent.jsx":Kr,"./Nodes/Agent/Node_Agent_Role_Macro.jsx":sa,"./Nodes/Agent/Node_Agent_Role_Screenshot.jsx":ra,"./Nodes/Alerting/Node_Alert_Sound.jsx":ca,"./Nodes/Data Analysis & Manipulation/Node_Array_Index_Extractor.jsx":pa,"./Nodes/Data Analysis & Manipulation/Node_JSON_Display.jsx":ma,"./Nodes/Data Analysis & Manipulation/Node_JSON_Value_Extractor.jsx":ba,"./Nodes/Data Analysis & Manipulation/Node_OCR_Text_Extraction.jsx":Sa,"./Nodes/Data Analysis & Manipulation/Node_Regex_Replace.jsx":ka,"./Nodes/Data Analysis & Manipulation/Node_Regex_Search.jsx":Na,"./Nodes/Data Analysis & Manipulation/Node_TextArray_Display.jsx":Ba,"./Nodes/Data Collection/Node_API_Request.jsx":Ea,"./Nodes/Data Collection/Node_Upload_Text.jsx":za,"./Nodes/Flow Control/Node_Edge_Toggle.jsx":$a,"./Nodes/General Purpose/Node_Data.jsx":Va,"./Nodes/General Purpose/Node_Logical_Operators.jsx":qa,"./Nodes/General Purpose/Node_Math_Operation.jsx":Ka,"./Nodes/Image Processing/Node_Adjust_Contrast.jsx":Za,"./Nodes/Image Processing/Node_BW_Threshold.jsx":si,"./Nodes/Image Processing/Node_Convert_to_Grayscale.jsx":ri,"./Nodes/Image Processing/Node_Export_Image.jsx":li,"./Nodes/Image Processing/Node_Image_Viewer.jsx":ui,"./Nodes/Image Processing/Node_Upload_Image.jsx":hi,"./Nodes/Organization/Node_Backdrop_Group_Box.jsx":gi,"./Nodes/Reporting/Node_Export_to_CSV.jsx":ji,"./Nodes/Templates/Node_Template.jsx":Si}),Ao={},zs={};Object.entries(oc).forEach(([n,t])=>{const o=t.default;if(!o)return;const{type:a,component:d}=o;if(!a||!d)return;const r=n.replace("./Nodes/","").split("/")[0];zs[r]||(zs[r]=[]),zs[r].push(o),Ao[a]=d});const ao=Pr({palette:{mode:"dark",background:{default:"#121212",paper:"#1e1e1e"},text:{primary:"#ffffff"}},components:{MuiTooltip:{styleOverrides:{tooltip:{backgroundColor:"#2a2a2a",color:"#ccc",fontSize:"0.75rem",border:"1px solid #444"},arrow:{color:"#2a2a2a"}}}}}),io="borealis_persistent_state";function rc(){var Ot,_t,Yt,ss;const[n,t]=s.useState([{id:"flow_1",tab_name:"Flow 1",nodes:[],edges:[]}]),[o,a]=s.useState("flow_1"),[d,u]=s.useState("devices"),[r,i]=s.useState(null),[c,p]=s.useState(null),[l,h]=s.useState(!1),[f,y]=s.useState(!1),[C,I]=s.useState(null),[k,v]=s.useState(""),[j,B]=s.useState(null),[R,x]=s.useState(null),S=s.useRef(null),[z,E]=s.useState(null),[U,X]=s.useState(null),[ue,Se]=s.useState(null),[ce,de]=s.useState(null),[me,w]=s.useState(0),[W,F]=s.useState(null),[te,ee]=s.useState(!1),be=s.useRef(window.location.pathname+window.location.search),Re=s.useRef(null),[Ae,Le]=s.useState(!1),Fe=[{key:"hostname",label:"Hostname",scope:"device",placeholder:"Search Hostname"},{key:"internal_ip",label:"Internal IP",scope:"device",placeholder:"Search Internal IP"},{key:"external_ip",label:"External IP",scope:"device",placeholder:"Search External IP"},{key:"description",label:"Description",scope:"device",placeholder:"Search Description"},{key:"last_user",label:"Last User",scope:"device",placeholder:"Search Last User"},{key:"serial_number",label:"Serial Number (Soon)",scope:"device",placeholder:"Search Serial Number"},{key:"site_name",label:"Site Name",scope:"site",placeholder:"Search Site Name"},{key:"site_description",label:"Site Description",scope:"site",placeholder:"Search Site Description"}],[je,V]=s.useState("hostname"),[O,M]=s.useState(!1),[g,L]=s.useState(""),[we,T]=s.useState(null),[G,ie]=s.useState({devices:[],sites:[],q:"",field:""}),Ce=s.useRef(null),Ee=s.useRef(null),Ne=s.useCallback((A,q)=>{const le=String(A??""),he=String(q??"").trim();if(!he)return le;try{const _=he.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),K=new RegExp(`(${_})`,"ig");return le.split(K).map((re,ke)=>re.toLowerCase()===he.toLowerCase()?e.jsx("span",{style:{backgroundColor:"#243a52",color:"#a7d0ff",borderRadius:2,padding:"0 1px"},children:re},ke):e.jsx("span",{children:re},ke))}catch{return le}},[]),Ke=s.useCallback((A,q={})=>{var le;switch(A){case"login":return"/login";case"sites":return"/sites";case"devices":return"/devices";case"agent_devices":return"/devices/agent";case"ssh_devices":return"/devices/ssh";case"winrm_devices":return"/devices/winrm";case"device_details":{const he=q.device||r||(q.deviceId?{agent_guid:q.deviceId,hostname:q.deviceName||q.deviceId}:null),_=(he==null?void 0:he.agent_guid)||(he==null?void 0:he.guid)||((le=he==null?void 0:he.summary)==null?void 0:le.agent_guid)||(he==null?void 0:he.hostname)||(he==null?void 0:he.id);return _?`/device/${encodeURIComponent(_)}`:"/devices"}case"jobs":return"/scheduling";case"create_job":return"/scheduling/create_job";case"workflows":return"/workflows";case"workflow-editor":return"/workflows/editor";case"assemblies":return"/assemblies";case"scripts":case"ansible_editor":{const he=A==="ansible_editor"?"ansible":"scripts",_=new URLSearchParams;he==="ansible"&&_.set("mode","ansible");const K=q.assemblyState||W;K!=null&&K.path&&_.set("path",K.path);const pe=_.toString();return pe?`/assemblies/editor?${pe}`:"/assemblies/editor"}case"access_credentials":return"/access_management/credentials";case"access_github_token":return"/access_management/github_token";case"access_users":return"/access_management/users";case"server_info":return"/admin/server_info";case"admin_enrollment_codes":return"/admin/enrollment-codes";case"admin_device_approvals":return"/admin/device-approvals";default:return"/devices"}},[W,r]),at=s.useCallback(A=>{try{const q=new URL(A||"/",window.location.origin);let le=q.pathname||"/";le.length>1&&le.endsWith("/")&&(le=le.slice(0,-1));const he=le.split("/").filter(Boolean),_=q.searchParams;if(le==="/login")return{page:"login",options:{}};if(le==="/"||le==="")return{page:"devices",options:{}};if(le==="/devices")return{page:"devices",options:{}};if(le==="/devices/agent")return{page:"agent_devices",options:{}};if(le==="/devices/ssh")return{page:"ssh_devices",options:{}};if(le==="/devices/winrm")return{page:"winrm_devices",options:{}};if(he[0]==="device"&&he[1]){const K=decodeURIComponent(he[1]);return{page:"device_details",options:{device:{agent_guid:K,hostname:K}}}}if(le==="/sites")return{page:"sites",options:{}};if(le==="/scheduling")return{page:"jobs",options:{}};if(le==="/scheduling/create_job")return{page:"create_job",options:{}};if(le==="/workflows")return{page:"workflows",options:{}};if(le==="/workflows/editor")return{page:"workflow-editor",options:{}};if(le==="/assemblies")return{page:"assemblies",options:{}};if(le==="/assemblies/editor"){const K=_.get("mode"),pe=_.get("path")||"",re=pe?{path:pe,mode:K==="ansible"?"ansible":"scripts",nonce:Date.now()}:null;return{page:K==="ansible"?"ansible_editor":"scripts",options:re?{assemblyState:re}:{}}}return le==="/access_management/users"?{page:"access_users",options:{}}:le==="/access_management/github_token"?{page:"access_github_token",options:{}}:le==="/access_management/credentials"?{page:"access_credentials",options:{}}:le==="/admin/server_info"?{page:"server_info",options:{}}:le==="/admin/enrollment-codes"?{page:"admin_enrollment_codes",options:{}}:le==="/admin/device-approvals"?{page:"admin_device_approvals",options:{}}:{page:"devices",options:{}}}catch{return{page:"devices",options:{}}}},[]),ut=s.useCallback((A,q={})=>{if(u(A),A==="device_details"){if(q.device)i(q.device);else if(q.deviceId){const le=q.deviceId,he=q.deviceName||q.deviceId;i(_=>{const K=(_==null?void 0:_.agent_guid)||(_==null?void 0:_.guid)||(_==null?void 0:_.hostname)||"";return K===le||K===he?_:{agent_guid:le,hostname:he}})}}else q.preserveDevice||i(null);(A==="scripts"||A==="ansible_editor")&&q.assemblyState&&F(q.assemblyState)},[F,u,i]),Pe=s.useCallback((A,q={})=>{const{replace:le=!1,allowUnauthenticated:he=!1,suppressPending:_=!1}=q,K=Ke(A,q);if(!he&&!z&&A!=="login"){!_&&K&&(Re.current=K),ut("login",{});const pe="/login",re=le?"replaceState":"pushState",ke=window.location.pathname+window.location.search;(le||ke!==pe)&&window.history[re]({},"",pe);return}if(A==="login"){ut("login",{});const pe="/login",re=le?"replaceState":"pushState",ke=window.location.pathname+window.location.search;(le||ke!==pe)&&window.history[re]({},"",pe);return}if(Re.current=null,ut(A,q),K){const pe=le?"replaceState":"pushState",re=window.location.pathname+window.location.search;(le||re!==K)&&window.history[pe]({},"",K)}},[Ke,ut,z]),gt=s.useCallback((A,{replace:q=!1,allowUnauthenticated:le=!1}={})=>{const{page:he,options:_}=at(A);Pe(he,{..._||{},replace:q,allowUnauthenticated:le})},[at,Pe]),bt=s.useRef(Pe),vt=s.useRef(gt);s.useEffect(()=>{bt.current=Pe,vt.current=gt},[Pe,gt]);const Ut=es.useMemo(()=>{const A=[];switch(d){case"sites":A.push({label:"Sites",page:"sites"}),A.push({label:"Site List",page:"sites"});break;case"devices":A.push({label:"Inventory",page:"devices"}),A.push({label:"Devices",page:"devices"});break;case"device_details":A.push({label:"Devices",page:"devices"}),A.push({label:"Device List",page:"devices"}),A.push({label:"Device Details"});break;case"jobs":A.push({label:"Automation",page:"jobs"}),A.push({label:"Scheduled Jobs",page:"jobs"});break;case"create_job":A.push({label:"Automation",page:"jobs"}),A.push({label:"Scheduled Jobs",page:"jobs"}),A.push({label:ce?"Edit Job":"Create Job",page:"create_job"});break;case"workflows":A.push({label:"Automation",page:"jobs"}),A.push({label:"Workflows",page:"workflows"});break;case"workflow-editor":A.push({label:"Automation",page:"jobs"}),A.push({label:"Workflows",page:"workflows"}),A.push({label:"Flow Editor"});break;case"scripts":A.push({label:"Automation",page:"jobs"}),A.push({label:"Scripts",page:"scripts"});break;case"ansible_editor":A.push({label:"Automation",page:"jobs"}),A.push({label:"Ansible Playbooks",page:"assemblies"}),A.push({label:"Playbook Editor"});break;case"assemblies":A.push({label:"Automation",page:"jobs"}),A.push({label:"Assemblies",page:"assemblies"});break;case"community":A.push({label:"Automation",page:"jobs"}),A.push({label:"Community Content",page:"community"});break;case"agent_devices":A.push({label:"Inventory",page:"devices"}),A.push({label:"Devices",page:"devices"}),A.push({label:"Agent Devices",page:"agent_devices"});break;case"ssh_devices":A.push({label:"Inventory",page:"devices"}),A.push({label:"Devices",page:"devices"}),A.push({label:"SSH Devices",page:"ssh_devices"});break;case"winrm_devices":A.push({label:"Inventory",page:"devices"}),A.push({label:"Devices",page:"devices"}),A.push({label:"WinRM Devices",page:"winrm_devices"});break;case"access_credentials":A.push({label:"Access Management",page:"access_credentials"}),A.push({label:"Credentials",page:"access_credentials"});break;case"access_github_token":A.push({label:"Access Management",page:"access_credentials"}),A.push({label:"GitHub API Token",page:"access_github_token"});break;case"access_users":A.push({label:"Access Management",page:"access_credentials"}),A.push({label:"Users",page:"access_users"});break;case"server_info":A.push({label:"Admin Settings"}),A.push({label:"Server Info",page:"server_info"});break;case"admin_enrollment_codes":A.push({label:"Admin Settings",page:"server_info"}),A.push({label:"Installer Codes",page:"admin_enrollment_codes"});break;case"admin_device_approvals":A.push({label:"Admin Settings",page:"server_info"}),A.push({label:"Device Approvals",page:"admin_device_approvals"});break;case"filters":A.push({label:"Filters & Groups",page:"filters"}),A.push({label:"Filters",page:"filters"});break;case"groups":A.push({label:"Filters & Groups",page:"filters"}),A.push({label:"Groups",page:"groups"});break;default:d&&A.push({label:String(d)})}return A},[d,r,ce]);s.useEffect(()=>{let A=!1;return(async()=>{const le=localStorage.getItem("borealis_session");if(le)try{const he=JSON.parse(le);Date.now()-he.timestamp<3600*1e3?A||(E(he.username),X(he.role||null),Se(he.display_name||he.username)):localStorage.removeItem("borealis_session")}catch{localStorage.removeItem("borealis_session")}try{const he=await fetch("/api/auth/me",{credentials:"include"});if(he.ok){const _=await he.json();A||(E(_.username),X(_.role||null),Se(_.display_name||_.username)),localStorage.setItem("borealis_session",JSON.stringify({username:_.username,display_name:_.display_name||_.username,role:_.role,timestamp:Date.now()}))}}catch{}A||ee(!0)})(),()=>{A=!0}},[]),s.useEffect(()=>{if(!te)return;const A=bt.current,q=vt.current;if(z){const le=be.current,he=window.location.pathname+window.location.search;q(le&&le!=="/login"?le:he==="/login"||he===""?"/devices":he,{replace:!0,allowUnauthenticated:!0}),be.current=null,Re.current=null}else{const le=be.current,he=window.location.pathname+window.location.search,_=le&&!le.startsWith("/login")?le:he.startsWith("/login")?null:he;_&&(Re.current=_),A("login",{replace:!0,allowUnauthenticated:!0,suppressPending:!0})}},[te,z]),s.useEffect(()=>{if(!te)return;const A=()=>{const q=window.location.pathname+window.location.search;if(!z){q.startsWith("/login")||(Re.current=q),bt.current("login",{replace:!0,allowUnauthenticated:!0,suppressPending:!0});return}vt.current(q,{replace:!0,allowUnauthenticated:!0})};return window.addEventListener("popstate",A),()=>window.removeEventListener("popstate",A)},[te,z]);const It=s.useCallback((A,q)=>{const le=String(q||"").trim();if(le.length<3){ie({devices:[],sites:[],q:le,field:A});return}const he=new URLSearchParams({field:A,q:le,limit:"5"});fetch(`/api/search/suggest?${he.toString()}`).then(_=>_.ok?_.json():{devices:[],sites:[],q:le,field:A}).then(_=>ie(_)).catch(()=>ie({devices:[],sites:[],q:le,field:A}))},[]);s.useEffect(()=>{if(O)return Ee.current&&clearTimeout(Ee.current),Ee.current=setTimeout(()=>{It(je,g)},220),()=>{Ee.current&&clearTimeout(Ee.current)}},[O,je,g,It]);const yt=s.useCallback(async(A,q,le=!0)=>{var _;if((Fe.find(K=>K.key===A)||Fe[0]).scope==="site"){try{localStorage.setItem("site_list_initial_filters",JSON.stringify(A==="site_name"?{name:q}:{description:q}))}catch{}le&&Pe("sites")}else{const pe={hostname:"hostname",description:"description",last_user:"lastUser",internal_ip:"internalIp",external_ip:"externalIp",serial_number:"serialNumber"}[A]||"hostname",re=String(q||"").toLowerCase(),ke=(G.devices||[]).find(N=>String(N.hostname||N.value||"").toLowerCase()===re);if(ke&&(ke.hostname||"").trim()){const N={hostname:ke.hostname.trim()};le?Pe("device_details",{device:N}):i(N)}else if(A==="hostname")try{const N=await fetch(`/api/device/details/${encodeURIComponent(q)}`);if(N.ok){const H=await N.json();if(H&&((_=H.summary)!=null&&_.hostname||Object.keys(H).length>0)){const Y={hostname:q};le?Pe("device_details",{device:Y}):i(Y)}else{try{localStorage.setItem("device_list_initial_filters",JSON.stringify({[pe]:q}))}catch{}le&&Pe("devices")}}else{try{localStorage.setItem("device_list_initial_filters",JSON.stringify({[pe]:q}))}catch{}le&&Pe("devices")}}catch{try{localStorage.setItem("device_list_initial_filters",JSON.stringify({[pe]:q}))}catch{}le&&Pe("devices")}else{try{const N=pe==="serialNumber"?{}:{[pe]:q};localStorage.setItem("device_list_initial_filters",JSON.stringify(N))}catch{}le&&Pe("devices")}}M(!1)},[Fe,Pe,G.devices]),pt=({username:A,role:q})=>{E(A),X(q||null),Se(A),localStorage.setItem("borealis_session",JSON.stringify({username:A,display_name:A,role:q||null,timestamp:Date.now()})),(async()=>{try{const le=await fetch("/api/auth/me",{credentials:"include"});if(le.ok){const he=await le.json();Se(he.display_name||he.username),localStorage.setItem("borealis_session",JSON.stringify({username:he.username,display_name:he.display_name||he.username,role:he.role,timestamp:Date.now()}))}}catch{}})(),Re.current?(gt(Re.current,{replace:!0,allowUnauthenticated:!0}),Re.current=null):Pe("devices",{replace:!0,allowUnauthenticated:!0})};s.useEffect(()=>{const A=localStorage.getItem(io);if(A)try{const q=JSON.parse(A);Array.isArray(q.tabs)&&q.activeTabId&&(t(q.tabs),a(q.activeTabId))}catch(q){console.warn("Failed to parse saved state:",q)}},[]),s.useEffect(()=>{const A=setTimeout(()=>{const q=JSON.stringify({tabs:n,activeTabId:o});localStorage.setItem(io,q)},1e3);return()=>clearTimeout(A)},[n,o]);const St=s.useCallback((A,q)=>{const le=q||o;t(he=>he.map(_=>_.id===le?{..._,nodes:typeof A=="function"?A(_.nodes):A}:_))},[o]),ct=s.useCallback((A,q)=>{const le=q||o;t(he=>he.map(_=>_.id===le?{..._,edges:typeof A=="function"?A(_.edges):A}:_))},[o]),oe=A=>p(A.currentTarget),_e=()=>p(null),$e=async()=>{try{await fetch("/api/auth/logout",{method:"POST",credentials:"include"})}catch{}try{localStorage.removeItem("borealis_session")}catch{}E(null),X(null),Se(null),Pe("login",{replace:!0,allowUnauthenticated:!0,suppressPending:!0})},Xe=(A,q)=>{A.preventDefault(),B({x:A.clientX,y:A.clientY}),x(q)},We=()=>{t(A=>{const q=A.filter(le=>le.id!==R);if(q.length===0){const le={id:"flow_1",tab_name:"Flow 1",nodes:[],edges:[]};return a(le.id),[le]}return o===R&&a(q[0].id),q}),B(null)},Je=()=>{const A=n.find(q=>q.id===R);A&&(I(R),v(A.tab_name),y(!0)),B(null)},ft=()=>{t(A=>A.map(q=>q.id===C?{...q,tab_name:k}:q)),y(!1)},ht=s.useCallback(()=>{const A=n.find(pe=>pe.id===o);if(!A)return;const q={tab_name:A.tab_name,nodes:A.nodes,edges:A.edges},le=`${A.tab_name||"workflow"}.json`,he=new Blob([JSON.stringify(q,null,2)],{type:"application/json"}),_=URL.createObjectURL(he),K=document.createElement("a");K.href=_,K.download=le,K.click(),URL.revokeObjectURL(_)},[n,o]),Jt=s.useCallback(()=>{S.current&&(S.current.value=null,S.current.click())},[]),Ct=s.useCallback(A=>{const q=A.target.files&&A.target.files[0];if(!q)return;const le=new FileReader;le.onload=()=>{try{const he=JSON.parse(le.result),_="flow_"+Date.now();t(K=>[...K,{id:_,tab_name:he.tab_name||he.name||q.name.replace(/\.json$/i,""),nodes:he.nodes||[],edges:he.edges||[]}]),a(_),Pe("workflow-editor")}catch(he){console.error("Failed to import workflow:",he)}},le.readAsText(q),A.target.value=""},[Pe,t]),Wt=s.useCallback(async A=>{const q=n.find(he=>he.id===o);if(!q||!A)return;const le={path:q.folderPath?`${q.folderPath}/${A}`:A,workflow:{tab_name:q.tab_name,nodes:q.nodes,edges:q.edges}};try{const he={island:"workflows",kind:"file",path:le.path,content:le.workflow};await fetch("/api/assembly/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(he)}),t(_=>_.map(K=>K.id===o?{...K,tab_name:A}:K))}catch(he){console.error("Failed to save workflow:",he)}},[n,o]),lt=String(U||"").toLowerCase()==="admin";s.useEffect(()=>{!lt&&(d==="server_info"||d==="admin_enrollment_codes"||d==="admin_device_approvals"||d==="access_credentials"||d==="access_github_token"||d==="access_users"||d==="ssh_devices"||d==="winrm_devices"||d==="agent_devices")&&(Le(!0),Pe("devices",{replace:!0,suppressPending:!0}))},[d,lt,Pe]);const Dt=()=>{var A;switch(d){case"sites":return e.jsx(Ji,{onOpenDevicesForSite:q=>{try{localStorage.setItem("device_list_initial_site_filter",String(q||""))}catch{}Pe("devices")}});case"devices":return e.jsx(_o,{onSelectDevice:q=>{Pe("device_details",{device:q})}});case"agent_devices":return e.jsx(tl,{onSelectDevice:q=>{Pe("device_details",{device:q})}});case"ssh_devices":return e.jsx(ko,{});case"winrm_devices":return e.jsx(nl,{});case"device_details":return e.jsx(el,{device:r,onBack:()=>{Pe("devices"),i(null)}});case"jobs":return e.jsx(Sl,{onCreateJob:()=>{de(null),Pe("create_job")},onEditJob:q=>{de(q),Pe("create_job")},refreshToken:me});case"create_job":return e.jsx(Tl,{initialJob:ce,onCancel:()=>{Pe("jobs"),de(null)},onCreated:()=>{Pe("jobs"),de(null),w(Date.now())}});case"workflows":return e.jsx(Xn,{onOpenWorkflow:async(q,le,he)=>{const _="flow_"+Date.now();if(q&&q.rel_path){const K=q.rel_path.split("/").slice(0,-1).join("/");try{const pe=await fetch(`/api/assembly/load?island=workflows&path=${encodeURIComponent(q.rel_path)}`);if(!pe.ok)throw new Error(`HTTP ${pe.status}`);const re=await pe.json();t([{id:_,tab_name:re.tab_name||q.name||q.file_name||"Workflow",nodes:re.nodes||[],edges:re.edges||[],folderPath:K}])}catch(pe){console.error("Failed to load workflow:",pe),t([{id:_,tab_name:(q==null?void 0:q.name)||"Workflow",nodes:[],edges:[],folderPath:K}])}}else t([{id:_,tab_name:he||"Flow",nodes:[],edges:[],folderPath:le||""}]);a(_),Pe("workflow-editor")},onOpenScript:(q,le,he)=>{const _=Date.now();F({path:q||"",mode:le,context:he?{...he,nonce:_}:null,nonce:_}),Pe(le==="ansible"?"ansible_editor":"scripts",{assemblyState:{path:q||"",mode:le,context:he?{...he,nonce:_}:null,nonce:_}})}});case"assemblies":return e.jsx(Xn,{onOpenWorkflow:async(q,le,he)=>{const _="flow_"+Date.now();if(q&&q.rel_path){const K=q.rel_path.split("/").slice(0,-1).join("/");try{const pe=await fetch(`/api/assembly/load?island=workflows&path=${encodeURIComponent(q.rel_path)}`);if(!pe.ok)throw new Error(`HTTP ${pe.status}`);const re=await pe.json();t([{id:_,tab_name:re.tab_name||q.name||q.file_name||"Workflow",nodes:re.nodes||[],edges:re.edges||[],folderPath:K}])}catch(pe){console.error("Failed to load workflow:",pe),t([{id:_,tab_name:(q==null?void 0:q.name)||"Workflow",nodes:[],edges:[],folderPath:K}])}}else t([{id:_,tab_name:he||"Flow",nodes:[],edges:[],folderPath:le||""}]);a(_),Pe("workflow-editor")},onOpenScript:(q,le,he)=>{const _=Date.now();F({path:q||"",mode:le,context:he?{...he,nonce:_}:null,nonce:_}),Pe(le==="ansible"?"ansible_editor":"scripts",{assemblyState:{path:q||"",mode:le,context:he?{...he,nonce:_}:null,nonce:_}})}});case"scripts":return e.jsx(Zn,{mode:"scripts",initialPath:(W==null?void 0:W.mode)==="scripts"&&(W==null?void 0:W.path)||"",initialContext:(W==null?void 0:W.mode)==="scripts"?W==null?void 0:W.context:null,onConsumeInitialData:()=>F(q=>q&&q.mode==="scripts"?null:q),onSaved:()=>Pe("assemblies")});case"ansible_editor":return e.jsx(Zn,{mode:"ansible",initialPath:(W==null?void 0:W.mode)==="ansible"&&(W==null?void 0:W.path)||"",initialContext:(W==null?void 0:W.mode)==="ansible"?W==null?void 0:W.context:null,onConsumeInitialData:()=>F(q=>q&&q.mode==="ansible"?null:q),onSaved:()=>Pe("assemblies")});case"access_credentials":return e.jsx(zl,{isAdmin:lt});case"access_github_token":return e.jsx(Gl,{isAdmin:lt});case"access_users":return e.jsx(Wl,{isAdmin:lt});case"server_info":return e.jsx(ql,{isAdmin:lt});case"admin_enrollment_codes":return e.jsx(Ql,{});case"admin_device_approvals":return e.jsx(nc,{});case"workflow-editor":return e.jsxs(m,{sx:{display:"flex",flexDirection:"column",flexGrow:1,overflow:"hidden"},children:[e.jsxs(m,{sx:{display:"flex",flexGrow:1,overflow:"hidden"},children:[e.jsx(Vi,{categorizedNodes:zs,handleExportFlow:ht,handleImportFlow:Jt,handleSaveFlow:Wt,handleOpenCloseAllDialog:()=>h(!0),fileInputRef:S,onFileInputChange:Ct,currentTabName:(A=n.find(q=>q.id===o))==null?void 0:A.tab_name}),e.jsxs(m,{sx:{display:"flex",flexDirection:"column",flexGrow:1,overflow:"hidden"},children:[e.jsx(Li,{tabs:n,activeTabId:o,onTabChange:a,onAddTab:()=>{},onTabRightClick:Xe}),e.jsx(m,{sx:{flexGrow:1,position:"relative"},children:n.map(q=>e.jsx(m,{sx:{position:"absolute",top:0,bottom:0,left:0,right:0,display:q.id===o?"block":"none"},children:e.jsx(Do,{id:q.id,children:e.jsx(Wi,{flowId:q.id,nodes:q.nodes,edges:q.edges,setNodes:le=>St(le,q.id),setEdges:le=>ct(le,q.id),nodeTypes:Ao,categorizedNodes:zs})})},q.id))})]})]}),e.jsx(Gi,{})]});default:return e.jsx(m,{sx:{p:2},children:e.jsx($,{children:"Select a section from navigation."})})}};return z?e.jsxs($n,{theme:ao,children:[e.jsx(Un,{}),e.jsxs(m,{sx:{width:"100vw",height:"100vh",display:"flex",flexDirection:"column",overflow:"hidden"},children:[e.jsx(Er,{position:"static",sx:{bgcolor:"#16191d"},children:e.jsxs(Mr,{sx:{minHeight:"36px",position:"relative"},children:[e.jsx(m,{component:"img",src:"/Borealis_Logo_Full.png",alt:"Borealis Logo",sx:{height:"52px",marginRight:"8px"}}),e.jsx(m,{sx:{position:"absolute",left:"calc(260px + 550px)",bottom:6,display:"flex",alignItems:"flex-end",pointerEvents:"none"},children:e.jsx(Dr,{separator:e.jsx(zr,{fontSize:"inherit",sx:{color:"#6b6b6b"}}),"aria-label":"breadcrumb",sx:{color:"#9aa0a6",fontSize:"0.825rem","& .MuiBreadcrumbs-separator":{mx:.6},pointerEvents:"auto"},children:Ut.map((A,q)=>A.page?e.jsx(Z,{onClick:()=>Pe(A.page),size:"small",sx:{color:"#7db7ff",textTransform:"none",minWidth:0,p:0,fontSize:"0.825rem"},children:A.label},q):e.jsx($,{component:"span",sx:{color:"#e0e0e0",fontSize:"0.825rem"},children:A.label},q))})}),e.jsx(Fr,{onClickAway:()=>M(!1),children:e.jsxs(m,{sx:{display:"flex",alignItems:"center",gap:.5,ml:2},children:[e.jsx(Z,{variant:"outlined",size:"small",onClick:A=>T(A.currentTarget),endIcon:we?e.jsx(Lr,{}):e.jsx($r,{}),sx:{height:32,color:"#ddd",left:-11,bottom:-6,borderColor:"#3a3f44",textTransform:"none",bgcolor:"#1e2328","&:hover":{borderColor:"#4b5158",bgcolor:"#22272e"},minWidth:160,justifyContent:"space-between"},children:(Fe.find(A=>A.key===je)||{}).label||"Hostname"}),e.jsx(Et,{anchorEl:we,open:!!we,onClose:()=>T(null),PaperProps:{sx:{bgcolor:"#1e1e1e",color:"#fff",minWidth:240}},children:Fe.map(A=>e.jsx(fe,{onClick:()=>{V(A.key),T(null),L(""),ie({devices:[],sites:[],q:"",field:""})},children:A.label},A.key))}),e.jsxs(m,{ref:Ce,sx:{position:"relative",left:-2,bottom:-6,display:"flex",alignItems:"center",border:"1px solid #3a3f44",borderRadius:1,height:32,minWidth:320,bgcolor:"#1e2328"},children:[e.jsx("input",{value:g,onChange:A=>{L(A.target.value),M(!0)},onFocus:()=>M(!0),onKeyDown:A=>{A.key==="Enter"?yt(je,g):A.key==="Escape"&&M(!1)},placeholder:(Fe.find(A=>A.key===je)||{}).placeholder||"Search",style:{outline:"none",border:"none",background:"transparent",color:"#e8eaed",paddingLeft:10,paddingRight:28,width:360,height:"100%"}}),e.jsx(Ur,{sx:{position:"absolute",right:6,color:"#8aa0b4",fontSize:18}}),O&&(((Ot=Fe.find(A=>A.key===je))==null?void 0:Ot.scope)==="device"&&(G.devices||[]).length>0||((_t=Fe.find(A=>A.key===je))==null?void 0:_t.scope)==="site"&&(G.sites||[]).length>0)&&e.jsxs(m,{sx:{position:"absolute",top:"100%",left:0,right:0,bgcolor:"#1e2328",border:"1px solid #3a3f44",borderTop:"none",zIndex:1400,borderRadius:"0 0 6px 6px",maxHeight:320,overflowY:"auto"},children:[(G.devices||[]).length>0&&((Yt=Fe.find(A=>A.key===je))==null?void 0:Yt.scope)==="device"&&e.jsxs(m,{sx:{borderBottom:"1px solid #2b2f34"},children:[e.jsx(m,{sx:{display:"flex",alignItems:"center",px:1.2,py:.8,color:"#9aa0a6",fontSize:12},children:"Devices"}),G.devices&&G.devices.length>0?G.devices.map((A,q)=>{const le=je==="hostname"?Ne(A.hostname||A.value,g):A.hostname||A.value;let he="";je==="internal_ip"?he=A.internal_ip||"":je==="external_ip"?he=A.external_ip||"":je==="description"?he=A.description||"":je==="last_user"&&(he=A.last_user||"");const _=je!=="hostname"&&he?Ne(he,g):A.internal_ip||A.external_ip||A.description||A.last_user||"";return e.jsxs(m,{onClick:()=>{Pe("device_details",{device:{hostname:A.hostname||A.value}}),M(!1)},sx:{px:1.2,py:.6,"&:hover":{bgcolor:"#22272e"},cursor:"pointer"},children:[e.jsx($,{variant:"body2",sx:{color:"#e8eaed"},children:le}),e.jsxs($,{variant:"caption",sx:{color:"#9aa0a6"},children:[A.site_name||"",A.site_name&&(he||A.internal_ip||A.external_ip||A.description||A.last_user)?" • ":"",_]})]},q)}):e.jsx(m,{sx:{px:1.2,py:1,color:"#6b737c",fontSize:12},children:je==="serial_number"?"Serial numbers are not tracked yet.":"No matches"})]}),(G.sites||[]).length>0&&((ss=Fe.find(A=>A.key===je))==null?void 0:ss.scope)==="site"&&e.jsxs(m,{children:[e.jsx(m,{sx:{display:"flex",alignItems:"center",px:1.2,py:.8,color:"#9aa0a6",fontSize:12},children:"Sites"}),G.sites&&G.sites.length>0?G.sites.map((A,q)=>e.jsxs(m,{onClick:()=>yt(je,A.value),sx:{px:1.2,py:.6,"&:hover":{bgcolor:"#22272e"},cursor:"pointer"},children:[e.jsx($,{variant:"body2",sx:{color:"#e8eaed"},children:je==="site_name"?Ne(A.site_name,g):A.site_name}),e.jsx($,{variant:"caption",sx:{color:"#9aa0a6"},children:je==="site_description"?Ne(A.site_description||"",g):A.site_description||""})]},q)):e.jsx(m,{sx:{px:1.2,py:1,color:"#6b737c",fontSize:12},children:"No matches"})]})]})]})]})}),e.jsx(m,{sx:{flexGrow:1}}),e.jsx(Z,{color:"inherit",onClick:oe,endIcon:e.jsx(Wr,{}),sx:{height:"36px"},children:ue||z||"User"}),e.jsx(Et,{anchorEl:c,open:!!c,onClose:_e,children:e.jsxs(fe,{onClick:()=>{_e(),$e()},children:[e.jsx(Vr,{sx:{fontSize:18,color:"#ff6b6b",mr:1}})," Logout"]})})]})}),e.jsxs(m,{sx:{display:"flex",flexGrow:1,overflow:"auto",minHeight:0},children:[e.jsx(Fi,{currentPage:d,onNavigate:Pe,isAdmin:lt}),e.jsx(m,{sx:{flexGrow:1,display:"flex",flexDirection:"column",overflow:"auto",minHeight:0,"& > *":{alignSelf:"stretch",minHeight:"calc(100% - 32px)"}},children:Dt()})]})]}),e.jsx(Ci,{open:l,onClose:()=>h(!1),onConfirm:()=>{}}),e.jsx(Ii,{open:f,value:k,onChange:v,onCancel:()=>y(!1),onSave:ft}),e.jsx(Oi,{anchor:j,onClose:()=>B(null),onRename:Je,onCloseTab:We}),e.jsx(_i,{open:Ae,onClose:()=>Le(!1)})]}):e.jsxs($n,{theme:ao,children:[e.jsx(Un,{}),e.jsx(qi,{onLogin:pt})]})}const ac=Oo.createRoot(document.getElementById("root"));ac.render(e.jsx(es.StrictMode,{children:e.jsx(rc,{})}));