@xenon-device-management/xenon 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/package.json +1 -1
- package/lib/public/assets/{ApiKeyGate-BSN8crwz.js → ApiKeyGate-BousCIQZ.js} +1 -1
- package/lib/public/assets/{BugReportButton-DNja1wQ1.js → BugReportButton-Gw4lnGnV.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-DVk1IpIR.js → DeviceMosaicView-BX2hfhBf.js} +2 -2
- package/lib/public/assets/{EmptyState-CqQ21n-H.js → EmptyState-CPOfuV3O.js} +1 -1
- package/lib/public/assets/{FieldGroup-DE3u01Nu.js → FieldGroup-C5UkCHbe.js} +1 -1
- package/lib/public/assets/{Modal-BJcFdiBP.js → Modal-MMGhL8eW.js} +1 -1
- package/lib/public/assets/{SegmentedControl-CSHjmrvy.js → SegmentedControl-CZfAicws.js} +1 -1
- package/lib/public/assets/{SettingCard-M-lFn_Wm.js → SettingCard-Dp7XIdcl.js} +1 -1
- package/lib/public/assets/{Table-B3EUgBi6.js → Table-DsN_IX6J.js} +1 -1
- package/lib/public/assets/{activity-DK3R5GAb.js → activity-DCBAvxuo.js} +1 -1
- package/lib/public/assets/ai-settings-yNS_bU1m.js +21 -0
- package/lib/public/assets/api-keys-CQ9g1g1b.js +1 -0
- package/lib/public/assets/apps-Bqh1eav9.js +21 -0
- package/lib/public/assets/apps-CTrGClro.css +1 -0
- package/lib/public/assets/{arrow-left-9933DNlF.js → arrow-left-GX0vzYtn.js} +1 -1
- package/lib/public/assets/{arrow-up-right-B7q_1mXs.js → arrow-up-right-DePHHOby.js} +1 -1
- package/lib/public/assets/auth-shell-BBGlC6i3.js +1 -0
- package/lib/public/assets/builds-page-Czf7RsmD.js +6 -0
- package/lib/public/assets/{button-lkxVyarW.js → button-ybNY3GYx.js} +1 -1
- package/lib/public/assets/{check-BkT38An9.js → check-BZMx8AhR.js} +1 -1
- package/lib/public/assets/{chevron-right-WELZ1Z8v.js → chevron-right-WL_bcB02.js} +1 -1
- package/lib/public/assets/{circle-check--2DSsfaI.js → circle-check-CI2xUlDo.js} +1 -1
- package/lib/public/assets/{circle-x-x7R8vTBo.js → circle-x-De3thbcr.js} +1 -1
- package/lib/public/assets/{clock-DIpGd4Pn.js → clock-BFVLE7wW.js} +1 -1
- package/lib/public/assets/{copy-CEcFYYHm.js → copy-ve3lNhva.js} +1 -1
- package/lib/public/assets/device-explorer-elRO7T00.css +1 -0
- package/lib/public/assets/device-explorer-vzZxT4-Y.js +210 -0
- package/lib/public/assets/{download-CaKkGvKw.js → download-BDZj44ke.js} +1 -1
- package/lib/public/assets/forgot-password-BSYQX2oR.js +1 -0
- package/lib/public/assets/{funnel-D2rLIKlM.js → funnel-CptlpFZ9.js} +1 -1
- package/lib/public/assets/index-BW3kENYH.css +1 -0
- package/lib/public/assets/{index-BrVV0Kla.js → index-PtnKslHU.js} +12 -12
- package/lib/public/assets/{layers-DZwF8z_0.js → layers-DRpwoKhI.js} +1 -1
- package/lib/public/assets/{lock-CVUUnm1V.js → lock-CrQhC34I.js} +1 -1
- package/lib/public/assets/login-DaJOt8Qz.js +1 -0
- package/lib/public/assets/maintenance-settings-D629C2IC.js +6 -0
- package/lib/public/assets/{mouse-pointer-2-n4xUMxHJ.js → mouse-pointer-2-Dpcc76zN.js} +1 -1
- package/lib/public/assets/overview-CGEKYX62.js +11 -0
- package/lib/public/assets/{page-header-C0pnt4xz.js → page-header-CSvuGbSO.js} +1 -1
- package/lib/public/assets/{plus-BObE-_z6.js → plus-vJJF9g79.js} +1 -1
- package/lib/public/assets/profile-page-CF7ZQNQz.js +6 -0
- package/lib/public/assets/reset-password-BgpjbCac.js +1 -0
- package/lib/public/assets/runbook-page-Dxuzftyv.js +124 -0
- package/lib/public/assets/selector-detail-page-B_puCd9g.js +1 -0
- package/lib/public/assets/{selector-health-DraY2a4b.js → selector-health-BjMHf106.js} +1 -1
- package/lib/public/assets/selector-health-page-Du_bGD2p.js +16 -0
- package/lib/public/assets/session-detail-page-lQTe5_B1.js +13 -0
- package/lib/public/assets/settings-Cxx_aYWT.css +1 -0
- package/lib/public/assets/settings-DhxWGUzy.js +1 -0
- package/lib/public/assets/{shield-BBc4qisQ.js → shield-JGzamJo5.js} +1 -1
- package/lib/public/assets/{shield-alert-BfoPJ8q_.js → shield-alert-DzE36jcb.js} +1 -1
- package/lib/public/assets/status-pill-outline-50aN0wRU.js +1 -0
- package/lib/public/assets/{tablet-CaOqzQv_.js → tablet-DHY88mxw.js} +1 -1
- package/lib/public/assets/teams-EOAIPbZC.js +1 -0
- package/lib/public/assets/time-B8FIgwPE.js +1 -0
- package/lib/public/assets/{trash-2-CE5TRHb2.js → trash-2-BrTSfFh5.js} +1 -1
- package/lib/public/assets/{useSocket-Bkt5i-U6.js → useSocket-BRto9a5m.js} +1 -1
- package/lib/public/assets/users-Dd44jLAB.js +11 -0
- package/lib/public/assets/webhook-settings-DBYmqim_.js +1 -0
- package/lib/public/assets/{webhook-settings-DEZQtSgr.css → webhook-settings-tW1oXXrJ.css} +1 -1
- package/lib/public/assets/{zap-BzdRuL9F.js → zap-JUbOoK3o.js} +1 -1
- package/lib/public/index.html +2 -2
- package/lib/src/app/routers/auth.js +19 -2
- package/lib/src/scripts/run-migrations.js +14 -3
- package/lib/test/unit/auth-me-auth-disabled.test.js +77 -0
- package/lib/test/unit/run-migrations-fail-fast.test.js +87 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/lib/public/assets/ai-settings-AKMDh8pd.js +0 -21
- package/lib/public/assets/api-keys-B5Q1EkGN.js +0 -1
- package/lib/public/assets/apps-CWWrkTZW.js +0 -21
- package/lib/public/assets/apps-Dt5dUIag.css +0 -1
- package/lib/public/assets/builds-page-DgWXOgh5.js +0 -6
- package/lib/public/assets/device-explorer-3H1hf8ld.css +0 -1
- package/lib/public/assets/device-explorer-nV6L3w7x.js +0 -210
- package/lib/public/assets/forgot-password-CsAF11d2.js +0 -1
- package/lib/public/assets/index-Dz1K6OJU.css +0 -1
- package/lib/public/assets/login-BavGkTli.js +0 -1
- package/lib/public/assets/maintenance-settings-Vr_u8hoR.js +0 -6
- package/lib/public/assets/overview-DVgoOoYF.js +0 -11
- package/lib/public/assets/profile-page-DNKD4MS2.js +0 -1
- package/lib/public/assets/reset-password-C2gSMy8a.js +0 -1
- package/lib/public/assets/runbook-page-BRxjWJVQ.js +0 -104
- package/lib/public/assets/selector-detail-page-DcV8jQuX.js +0 -1
- package/lib/public/assets/selector-health-page-tb5e3CXy.js +0 -16
- package/lib/public/assets/session-detail-page-CEtQr37W.js +0 -13
- package/lib/public/assets/settings-CpRbubta.css +0 -1
- package/lib/public/assets/settings-Cr-YjLbX.js +0 -1
- package/lib/public/assets/status-pill-outline-Cc4PF7Mg.js +0 -1
- package/lib/public/assets/teams-B3Tt_9i2.js +0 -1
- package/lib/public/assets/users-BIvjvjM6.js +0 -11
- package/lib/public/assets/webhook-settings-dAp8wwEB.js +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{g as W,r as d,X as _,m as D,j as e,L as B,p as Y,c as Q,u as q}from"./index-PtnKslHU.js";import{u as Z,h as ee,a as te,d as re,p as se,o as ae,f as ne,S as ie}from"./status-pill-outline-50aN0wRU.js";import{B as oe,P as j}from"./BugReportButton-Gw4lnGnV.js";import{A as le}from"./arrow-left-GX0vzYtn.js";import{C as $}from"./chevron-right-WL_bcB02.js";import{C as L}from"./copy-ve3lNhva.js";import{A as ce}from"./arrow-up-right-DePHHOby.js";import{E as O}from"./EmptyState-CPOfuV3O.js";import{T as de,a as xe,b as M,c as S,d as me,e as R}from"./Table-DsN_IX6J.js";import{u as ue}from"./useSocket-BRto9a5m.js";import{M as fe}from"./Modal-MMGhL8eW.js";import{D as pe}from"./download-BDZj44ke.js";import"./time-B8FIgwPE.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const he=[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]],ve=W("network",he);/**
|
|
7
|
+
* @license lucide-react v0.555.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const be=[["path",{d:"M10.66 6H14a2 2 0 0 1 2 2v2.5l5.248-3.062A.5.5 0 0 1 22 7.87v8.196",key:"w8jjjt"}],["path",{d:"M16 16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2",key:"1xawa7"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],ge=W("video-off",be);function je(t){const[r,s]=d.useState(null),[i,n]=d.useState([]),[l,c]=d.useState([]),[a,x]=d.useState([]),[u,f]=d.useState([]),[p,v]=d.useState(!0),[y,N]=d.useState(null),[w,g]=d.useState(!1),[C,E]=d.useState(0);return d.useEffect(()=>{if(!t){s(null),n([]),c([]),x([]),f([]),g(!1),v(!1);return}let h=!0;return v(!0),Promise.all([_.getSession(t),_.getSessionLogs(t),_.getDeviceLogs(t),_.getDebugLogs(t),_.getProfilingData(t).catch(()=>[])]).then(([o,b,k,m,T])=>{if(!h)return;const H=o&&typeof o=="object"&&typeof o.id=="string"&&typeof o.status=="string";s(H?o:null),H?(g(!1),N(null)):(g(!!o&&typeof o=="object"&&(o.error===!0||typeof o.message=="string")),N(typeof(o==null?void 0:o.message)=="string"?o.message:"Session not found")),n(Array.isArray(b)?b:[]),c(Array.isArray(k)?k:[]),x(Array.isArray(m)?m:[]),f(Array.isArray(T)?T:[])}).catch(o=>{h&&N(o instanceof Error?o.message:String(o))}).finally(()=>{h&&v(!1)}),()=>{h=!1}},[t,C]),{session:r,sessionLogs:i,deviceLogs:l,debugLogs:a,profiling:u,loading:p,error:y,notFound:w,refresh:()=>E(h=>h+1)}}const U=({buildId:t,buildName:r,sessionId:s})=>{const{toast:i}=D(),n=async()=>{try{await navigator.clipboard.writeText(s),i("Session ID copied","success")}catch{i("Failed to copy (clipboard unavailable)","error")}};return e.jsxs("header",{className:"flex items-center gap-2 px-4 py-3 border-b border-[var(--border)] bg-[var(--surface)]",children:[e.jsxs(B,{to:`/builds/${t}`,className:"inline-flex items-center gap-1.5 text-xs text-[var(--text-muted)] hover:text-[var(--text)] transition-colors",children:[e.jsx(le,{className:"h-3.5 w-3.5"}),"Builds"]}),e.jsx($,{className:"h-3 w-3 text-[var(--text-dim)]"}),e.jsx(B,{to:`/builds/${t}`,className:"text-[10px] uppercase tracking-widest font-mono text-[var(--green)] hover:underline",children:r}),e.jsx($,{className:"h-3 w-3 text-[var(--text-dim)]"}),e.jsx("span",{className:"text-[10px] uppercase tracking-widest text-[var(--text-dim)]",children:"Sessions"}),e.jsx($,{className:"h-3 w-3 text-[var(--text-dim)]"}),e.jsxs("span",{className:"font-mono text-xs text-[var(--text)]",title:s,children:["#",s]}),e.jsx("button",{type:"button",onClick:n,"aria-label":"Copy session ID",className:"p-1 rounded text-[var(--text-dim)] hover:text-[var(--text)] hover:bg-[var(--surface-2)] transition-colors",children:e.jsx(L,{className:"h-3 w-3"})}),e.jsx("div",{className:"ml-auto",children:e.jsx(oe,{sessionId:s,mode:"full",variant:"inline"})})]})},Ne={default:"text-[var(--text)]",red:"text-[var(--red)]",green:"text-[var(--green)]",amber:"text-[var(--amber)]"},A=({label:t,rows:r})=>e.jsxs("div",{className:"flex-1 min-w-0 p-4",children:[e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-3",children:t}),e.jsx("dl",{className:"space-y-2",children:r.map((s,i)=>e.jsxs("div",{className:"flex items-baseline justify-between gap-3",children:[e.jsx("dt",{className:"text-[10px] font-mono uppercase tracking-wider text-[var(--text-dim)] shrink-0",children:s.label}),e.jsx("dd",{className:`text-xs text-right truncate min-w-0 ${s.mono?"font-mono":""} ${Ne[s.tone??"default"]}`,children:s.value})]},`${s.label}-${i}`))})]}),ye=({identity:t,run:r,result:s})=>e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 rounded-lg border border-[var(--border)] bg-[var(--surface)] divide-y md:divide-y-0 md:divide-x divide-[var(--border)]",children:[e.jsx(A,{label:"Identity",rows:t}),e.jsx(A,{label:"Run",rows:r}),e.jsx(A,{label:"Result",rows:s})]});function we(t){if(!t||t.length===0)return null;const r=t.find(s=>s.is_success===!1);return r||(t[t.length-1]??null)}function ke(t,r=8){if(!t)return[];const s=t.split(/\r?\n/),i=[];for(const n of s){const l=n.trim();if(/^at\s+/.test(l)&&(i.push(l),i.length>=r))break}return i}function F(t){return t?t.split(/[_\s]+/).filter(Boolean).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(" "):""}function I(t){if(!t)return{};try{const r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}catch{return{}}}function J(t,r=200){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{const s=JSON.stringify(t);return s.length>r?s.slice(0,r)+"…":s}catch{return String(t)}}function Se(t,r,s,i,n){var u;const l=F(t.failure_category),c=((u=t.device_name)==null?void 0:u.trim())||"Unknown Device",a=t.device_version?` ${t.device_version}`:"",x=(n==null?void 0:n.message)||(n?JSON.stringify(n).slice(0,200):"(no logs captured)");return[`**Session:** ${t.id}`,`**Build:** ${r} (#${s})`,`**Device:** ${c} (${t.node_id||"unknown-node"}) · ${t.device_platform||"unknown"}${a}`,`**Duration:** ${i}`,`**Failure category:** ${l||"(uncategorized)"}`,`**Failure reason:** ${t.failure_reason||"(not set)"}`,`**First error:** ${x}`].join(`
|
|
12
|
+
`)}const Re=({session:t,buildName:r,buildId:s,allLogs:i,durationText:n})=>{const{toast:l}=D(),c=F(t.failure_category),a=we(i),x=ke(t.failure_reason),u=x.length>0,f=async()=>{const v=Se(t,r,s,n,a);try{await navigator.clipboard.writeText(v),l("Failure report copied","success")}catch{l("Clipboard unavailable","error")}},p=t.failure_category?`/xenon/runbooks/${encodeURIComponent(t.failure_category.toLowerCase())}`:void 0;return e.jsxs("section",{className:"rounded-lg border border-[var(--red)]/30 bg-[var(--surface)] overflow-hidden",children:[e.jsxs("header",{className:"flex items-center justify-between gap-4 px-4 py-3 border-b border-[var(--border)] bg-[var(--red)]/5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Y,{className:"h-4 w-4 text-[var(--red)]"}),e.jsx("span",{className:"text-sm font-semibold text-[var(--red)]",children:"Failure summary"}),c&&e.jsx("span",{className:"text-[10px] font-mono uppercase tracking-widest text-[var(--text-dim)] ml-2",children:c})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:f,className:"inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md border border-[var(--border)] text-xs text-[var(--text)] hover:border-[var(--border-strong)] hover:bg-[var(--surface-2)] transition-colors",children:[e.jsx(L,{className:"h-3 w-3"}),"Copy"]}),e.jsxs("a",{...p?{href:p,target:"_blank",rel:"noreferrer"}:{"aria-disabled":!0,onClick:v=>v.preventDefault()},className:`inline-flex items-center gap-1.5 h-7 px-2.5 rounded-md border border-[var(--border)] text-xs text-[var(--text)] hover:border-[var(--border-strong)] hover:bg-[var(--surface-2)] transition-colors ${p?"":"opacity-50 cursor-not-allowed"}`,title:p?"Open runbook in new tab":"No runbook — failure category not set",children:[e.jsx(ce,{className:"h-3 w-3"}),"Open runbook"]})]})]}),e.jsxs("div",{className:"px-4 py-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1",children:"Reason"}),e.jsx("div",{className:"text-sm text-[var(--text)]",children:t.failure_reason||e.jsx("span",{className:"text-[var(--text-dim)]",children:"(not set)"})})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1",children:"First error"}),e.jsx("div",{className:"text-sm text-[var(--text-muted)] min-w-0",children:a!=null&&a.message?e.jsx("span",{className:"break-words",children:a.message}):a?e.jsxs("dl",{className:"space-y-1 text-xs",children:[e.jsxs("div",{className:"flex gap-2 min-w-0",children:[e.jsx("dt",{className:"text-[var(--text-dim)] shrink-0 uppercase text-[10px] tracking-widest",children:"Command"}),e.jsx("dd",{className:"font-mono break-all",children:a.command_name||a.title||"—"})]}),a.subtitle&&e.jsxs("div",{className:"flex gap-2 min-w-0",children:[e.jsx("dt",{className:"text-[var(--text-dim)] shrink-0 uppercase text-[10px] tracking-widest",children:"Target"}),e.jsx("dd",{className:"font-mono break-all",children:a.subtitle})]}),a.response&&e.jsxs("div",{className:"flex gap-2 min-w-0",children:[e.jsx("dt",{className:"text-[var(--text-dim)] shrink-0 uppercase text-[10px] tracking-widest",children:"Response"}),e.jsx("dd",{className:"font-mono break-all",children:String(a.response).slice(0,400)})]})]}):e.jsx("span",{className:"text-[var(--text-dim)]",children:"(no logs captured before failure)"})})]}),u&&e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)] mb-1",children:"Stack trace"}),e.jsx("pre",{className:"rounded-md border border-[var(--border)] bg-[var(--bg)] p-3 font-mono text-[11px] leading-relaxed text-[var(--green)] overflow-x-auto",children:x.join(`
|
|
13
|
+
`)})]})]})]})},_e=({session:t})=>{const r=t.status==="running",s=!!t.video_recording;return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] overflow-hidden",children:[e.jsxs("header",{className:"px-3 py-2 border-b border-[var(--border)] flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] font-mono font-semibold uppercase tracking-widest text-[var(--text-dim)]",children:"Recording"}),r&&e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-widest text-[var(--red)]",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[var(--red)] pulse-dot"}),"Live"]})]}),e.jsx("div",{className:"aspect-video bg-[var(--bg)] flex items-center justify-center",children:r&&t.has_live_video?e.jsx("img",{src:_.getSessionLiveVideoUrl(t.id),alt:`Live view of session ${t.id}`,className:"w-full h-full object-contain"}):s?e.jsx("video",{controls:!0,src:_.getAssetUrl(t.video_recording),className:"w-full h-full object-contain"}):e.jsxs("div",{className:"flex flex-col items-center text-center px-6 py-8 gap-2",children:[e.jsx("div",{className:"h-10 w-10 rounded-full bg-[var(--surface-2)] border border-[var(--border)] flex items-center justify-center",children:e.jsx(ge,{className:"h-5 w-5 text-[var(--text-dim)]"})}),e.jsx("div",{className:"text-sm text-[var(--text)] font-medium",children:"No video available"}),e.jsx("div",{className:"text-xs text-[var(--text-dim)] max-w-xs",children:t.status==="failed"?"Session failed before recording started.":t.video_recording_enabled===!1?"Recording was disabled for this session.":"No recording was captured."})]})})]})},Ce=({session:t})=>{const[r,s]=d.useState("desired"),i=I(t.desired_capabilities),n=I(t.session_capabilities),c=Object.entries(r==="desired"?i:n);return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] overflow-hidden",children:[e.jsx("header",{className:"flex items-center border-b border-[var(--border)]",children:["desired","session"].map(a=>e.jsx("button",{type:"button",onClick:()=>s(a),"aria-pressed":r===a,className:`flex-1 h-9 text-[10px] font-mono font-semibold uppercase tracking-widest transition-colors border-b-2 ${r===a?"border-[var(--green)] text-[var(--text)]":"border-transparent text-[var(--text-muted)] hover:text-[var(--text)]"}`,children:a},a))}),c.length===0?e.jsxs("div",{className:"px-3 py-6 text-center text-xs text-[var(--text-dim)]",children:["No ",r," capabilities reported for this session."]}):e.jsx("dl",{className:"divide-y divide-[var(--border)]",children:c.map(([a,x])=>e.jsxs("div",{className:"flex items-baseline justify-between gap-3 px-3 py-2",children:[e.jsx("dt",{className:"text-xs text-[var(--text-muted)] truncate shrink-0 max-w-[45%]",children:a}),e.jsx("dd",{className:"font-mono text-xs text-[var(--text)] truncate text-right min-w-0",title:J(x,500),children:J(x)})]},a))})]})},Te=({tabs:t,active:r,onChange:s,errorsOnly:i,onErrorsOnlyChange:n})=>{const l=t.filter(c=>!(c.hideWhenEmpty&&c.count===0));return e.jsxs("div",{className:"flex items-center justify-between gap-4 px-3 border-b border-[var(--border)] bg-[var(--surface)]",children:[e.jsx("div",{className:"flex items-center gap-1 overflow-x-auto",children:l.map(c=>{const a=c.key===r;return e.jsxs("button",{type:"button",onClick:()=>s(c.key),"aria-pressed":a,className:`relative inline-flex items-center gap-1.5 h-9 px-3 text-xs whitespace-nowrap transition-colors ${a?"text-[var(--text)]":"text-[var(--text-muted)] hover:text-[var(--text)]"}`,children:[e.jsx("span",{children:c.label}),e.jsx("span",{className:`font-mono text-[10px] ${a?"text-[var(--text-muted)]":"text-[var(--text-dim)]"}`,children:c.count}),a&&e.jsx("span",{className:"absolute left-2 right-2 bottom-0 h-[2px] bg-[var(--green)] rounded-t"})]},c.key)})}),e.jsxs("label",{className:"inline-flex items-center gap-2 text-[11px] text-[var(--text-muted)] cursor-pointer select-none whitespace-nowrap",children:[e.jsx("input",{type:"checkbox",checked:i,onChange:c=>n(c.target.checked),"aria-label":"Show only error rows"}),"Errors only"]})]})};function X(t){const r=t.timestamp;if(!r){const c=t.createdAt;return c?X({timestamp:c}):"--:--:--"}const s=typeof r=="number"?new Date(r):new Date(String(r));if(Number.isNaN(s.getTime()))return"--:--:--";const i=String(s.getHours()).padStart(2,"0"),n=String(s.getMinutes()).padStart(2,"0"),l=String(s.getSeconds()).padStart(2,"0");return`${i}:${n}:${l}`}function $e(t){if(t.healed===!0)return{label:String(t.command_name||"healed"),tone:"amber"};if(t.is_success===!1)return{label:String(t.command_name||t.title||"error"),tone:"red"};if(t.is_success===!0)return{label:String(t.command_name||t.title||"ok"),tone:"green"};const r=t.title||t.event||t.command_name;return typeof r=="string"?/stop|fail|error/i.test(r)?{label:r,tone:"red"}:/start|begin|init/i.test(r)?{label:r,tone:"green"}:{label:r,tone:"blue"}:{label:"log",tone:"neutral"}}function De(t){if(t==null)return"";if(typeof t=="string")try{return JSON.stringify(JSON.parse(t),null,2)}catch{return t}try{return JSON.stringify(t,null,2)}catch{return String(t)}}function Le(t){if(!t||typeof t!="string")return[{text:String(t??""),kind:"plain"}];const r=[],s=/("(?:\\.|[^"\\])*")(\s*:)|("(?:\\.|[^"\\])*")|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|\b(true|false)\b|\b(null)\b|([{}[\],])/g;let i=0,n;for(;(n=s.exec(t))!==null;)n.index>i&&r.push({text:t.slice(i,n.index),kind:"plain"}),n[1]&&n[2]!==void 0?(r.push({text:n[1],kind:"key"}),r.push({text:n[2],kind:"punct"})):n[3]?r.push({text:n[3],kind:"string"}):n[4]?r.push({text:n[4],kind:"number"}):n[5]?r.push({text:n[5],kind:"boolean"}):n[6]?r.push({text:n[6],kind:"null"}):n[7]&&r.push({text:n[7],kind:"punct"}),i=s.lastIndex;return i<t.length&&r.push({text:t.slice(i),kind:"plain"}),r}function Ee(t){const r=t,s=typeof r.title=="string"&&r.title.trim()?r.title.trim():null,i=typeof r.command_name=="string"&&r.command_name.trim()?r.command_name.trim():null;return s??i??"Command"}function V(t){const r=t.subtitle;return typeof r=="string"&&r.trim()?r.trim():null}function Oe(t,r){return r?t.filter(s=>s.is_success===!1):t}const Ae={key:"text-[var(--blue)]",string:"text-[var(--green)]",number:"text-[var(--amber)]",boolean:"text-[var(--amber)]",null:"text-[var(--text-dim)] italic",punct:"text-[var(--text-muted)]",plain:"text-[var(--text)]"},Fe=({value:t,maxHeightPx:r})=>{const s=De(t);if(!s)return e.jsx("span",{className:"text-[var(--text-dim)] text-xs",children:"(empty)"});let i;try{i=Le(s)}catch{i=[{text:s,kind:"plain"}]}return e.jsx("pre",{className:"font-mono text-[11px] leading-relaxed bg-[var(--bg)] border border-[var(--border)] rounded-md p-3 overflow-x-auto whitespace-pre",style:r?{maxHeight:r,overflowY:"auto"}:void 0,children:i.map((n,l)=>e.jsx("span",{className:Ae[n.kind],children:n.text},l))})},Pe={green:"bg-[var(--green)]",red:"bg-[var(--red)]",amber:"bg-[var(--amber)]",blue:"bg-[var(--blue)]",neutral:"bg-[var(--text-dim)]"},He={green:"text-[var(--green)]",red:"text-[var(--red)]",amber:"text-[var(--amber)]",blue:"text-[var(--blue)]",neutral:"text-[var(--text-muted)]"},Be=({log:t})=>{const[r,s]=d.useState(!1),{toast:i}=D(),n=X(t),l=$e(t),c=async a=>{a.stopPropagation();try{const x=t.body??t,u=typeof x=="string"?x:JSON.stringify(x,null,2);await navigator.clipboard.writeText(u),i("Log entry copied","success")}catch{i("Clipboard unavailable","error")}};return e.jsxs("div",{className:"border-b border-[var(--border)] last:border-b-0",children:[e.jsxs("button",{type:"button",onClick:()=>s(a=>!a),"aria-expanded":r,className:"group w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-[var(--surface-2)]/60 transition-colors",children:[e.jsx($,{className:`h-3 w-3 text-[var(--text-dim)] transition-transform shrink-0 ${r?"rotate-90":""}`}),e.jsx("span",{className:"font-mono text-[11px] text-[var(--text-muted)] w-[64px] shrink-0",children:n}),e.jsx("span",{className:`h-1.5 w-1.5 rounded-full shrink-0 ${Pe[l.tone]}`}),e.jsx("span",{className:`font-mono text-[11px] font-medium shrink-0 ${He[l.tone]}`,children:l.label}),e.jsxs("span",{className:"min-w-0 flex-1 flex items-baseline gap-2 truncate",children:[e.jsx("span",{className:"text-[12px] text-[var(--text)] shrink-0",children:Ee(t)}),V(t)&&e.jsx("span",{className:"font-mono text-[11px] text-[var(--text-dim)] truncate min-w-0",children:V(t)})]}),e.jsx("span",{role:"button",tabIndex:0,onClick:c,onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&c(a)},"aria-label":"Copy log entry",className:"opacity-0 group-hover:opacity-100 p-1 rounded text-[var(--text-dim)] hover:text-[var(--text)] transition-opacity shrink-0",children:e.jsx(L,{className:"h-3 w-3"})})]}),r&&e.jsx("div",{className:"px-3 pb-3 pl-9",children:e.jsx(Fe,{value:t.body??t,maxHeightPx:400})})]})},Me=({sessionLogs:t,deviceLogs:r,debugLogs:s,profiling:i})=>{const[n,l]=d.useState("text"),[c,a]=d.useState(!1),x=d.useMemo(()=>[{key:"text",label:"Text Logs",count:t.length},{key:"performance",label:"Performance Trace",count:0},{key:"evidence",label:"Evidence",count:0},{key:"device",label:"Device Logs",count:r.length},{key:"debug",label:"Debug Logs",count:s.length},{key:"profiling",label:"System Profiling",count:i.length,hideWhenEmpty:!0}],[t.length,r.length,s.length,i.length]),u=d.useMemo(()=>{let f=[];return n==="text"?f=t:n==="device"?f=r:n==="debug"?f=s:n==="profiling"&&(f=i),Oe(f,c)},[n,t,r,s,i,c]);return e.jsxs("section",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] flex flex-col min-h-[280px]",children:[e.jsx(Te,{tabs:x,active:n,onChange:l,errorsOnly:c,onErrorsOnlyChange:a}),e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[n==="performance"&&e.jsx("div",{className:"px-4 py-10 text-center text-xs text-[var(--text-dim)]",children:"Performance Trace will be wired up once a session emits trace data."}),n==="evidence"&&e.jsx("div",{className:"px-4 py-10 text-center text-xs text-[var(--text-dim)]",children:"Evidence (screenshots) will be wired up alongside the screenshot service."}),(n==="text"||n==="device"||n==="debug"||n==="profiling")&&(u.length===0?e.jsx("div",{className:"px-4 py-10 text-center text-xs text-[var(--text-dim)]",children:c?"No error rows in this tab.":"No log entries in this tab."}):u.map((f,p)=>e.jsx(Be,{log:f},f.id??p)))]})]})},Ue=({header:t,footer:r,action:s,padded:i=!0,className:n,children:l})=>e.jsxs("div",{className:`card${n?" "+n:""}`,children:[(t||s)&&e.jsxs("div",{className:"card-header",children:[e.jsx("div",{className:"card-header-title",children:t}),s&&e.jsx("div",{className:"card-header-action",children:s})]}),e.jsx("div",{className:i?"card-body":"card-body-flush",children:l}),r&&e.jsx("div",{className:"card-footer",children:r})]});function G(t){if(!t)return"failed";switch(t){case"HTTPS_CLIENT_ERROR":case"HTTPS_SERVER_ERROR":case"OPEN_HTTPS_SERVER_ERROR":case"ON_CONNECT_ERROR":return"tls";case"PROXY_TO_SERVER_REQUEST_ERROR":return"net";default:return"failed"}}const P="/xenon/api/interceptor";async function Ie(t){const r=await fetch(`${P}/sessions/${encodeURIComponent(t)}/requests`);if(r.status===404){const i=await r.json().catch(()=>({}));return{active:!1,error:i==null?void 0:i.error}}return r.ok?{active:!0,requests:(await r.json()).requests||[]}:{active:!1,error:`request failed (${r.status})`}}async function Je(t,r){const s=await fetch(`${P}/sessions/${encodeURIComponent(t)}/requests/${encodeURIComponent(r)}`);return s.ok?s.json():null}function Ve(t){return`${P}/sessions/${encodeURIComponent(t)}/har`}function Ke(t){return t>=200&&t<300?"ready":t>=300&&t<400?"neutral":t>=400&&t<500?"busy":t>=500?"error":"neutral"}const K=({headers:t})=>{const r=Object.entries(t||{});return r.length===0?e.jsx("div",{className:"text-xs text-[var(--text-dim)]",children:"No headers"}):e.jsx("div",{className:"space-y-0.5 font-mono text-xs",children:r.map(([s,i])=>e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("span",{className:"text-[var(--text-dim)] shrink-0",children:[s,":"]}),e.jsx("span",{className:"break-all",children:i})]},s))})},z=({body:t})=>{if(t==null||t==="")return e.jsx("div",{className:"text-xs text-[var(--text-dim)]",children:"No body"});let r=t;try{r=JSON.stringify(JSON.parse(t),null,2)}catch{}return e.jsx("pre",{className:"font-mono text-xs whitespace-pre-wrap break-all bg-[var(--surface-2,var(--surface))] rounded p-2 max-h-64 overflow-auto",children:r})},ze=({request:t,onClose:r})=>{if(!t)return null;const s=e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(j,{tone:"accent",children:t.method}),t.failed?e.jsx(j,{tone:"error",children:G(t.failureKind)}):e.jsx(j,{tone:Ke(t.resStatus),children:t.resStatus||"—"}),e.jsx("span",{className:"font-mono text-xs truncate",title:t.url,children:t.url})]});return e.jsx(fe,{open:!!t,title:s,onClose:r,width:720,children:e.jsxs("div",{className:"space-y-4 text-xs",children:[t.failed&&e.jsxs("div",{className:"border border-[var(--red,#dc2626)] rounded p-2 bg-[var(--red-soft,rgba(220,38,38,0.08))]",children:[e.jsx("div",{className:"text-[var(--red,#dc2626)] uppercase tracking-wide text-[10px] mb-1",children:"Failure"}),e.jsx("div",{className:"text-xs",children:t.failureReason||"Request failed"}),t.failureKind&&e.jsx("div",{className:"font-mono text-[10px] text-[var(--text-dim)] mt-1",children:t.failureKind})]}),!t.failed&&e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Duration"}),e.jsxs("div",{className:"font-mono",children:[t.durationMs," ms"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Flags"}),e.jsxs("div",{className:"flex gap-1",children:[t.mocked&&e.jsx(j,{tone:"accent",children:"mocked"}),t.modified&&e.jsx(j,{tone:"busy",children:"modified"}),!t.mocked&&!t.modified&&e.jsx("span",{className:"text-[var(--text-dim)]",children:"passthrough"})]})]})]}),t.commandHint&&e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Triggered by"}),e.jsx("div",{className:"font-mono",children:t.commandHint.commandName})]}),!t.failed&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Request Headers"}),e.jsx(K,{headers:t.reqHeaders})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Request Body"}),e.jsx(z,{body:t.reqBody})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Response Headers"}),e.jsx(K,{headers:t.resHeaders})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[var(--text-dim)] uppercase tracking-wide text-[10px] mb-1",children:"Response Body"}),e.jsx(z,{body:t.resBody})]})]})]})})};function We(t){return t?new Date(t).toLocaleTimeString(void 0,{hour12:!1}):"—"}function Xe(t){return t>=200&&t<300?"ready":t>=300&&t<400?"neutral":t>=400&&t<500?"busy":t>=500?"error":"neutral"}const Ge=({sessionId:t,sessionEnded:r})=>{const[s,i]=d.useState(null),[n,l]=d.useState(null),[c,a]=d.useState([]),[x,u]=d.useState(!0),[f,p]=d.useState(null),v=d.useRef(new Set),{on:y,isConnected:N}=ue();d.useEffect(()=>{let o=!0;return u(!0),Ie(t).then(b=>{if(!o)return;i(b.active),l(b.error||null);const k=b.requests||[];a(k),v.current=new Set(k.map(m=>m.id))}).finally(()=>{o&&u(!1)}),()=>{o=!1}},[t]),d.useEffect(()=>{if(r)return;const o=y("interceptor_request",m=>{!m||m.sessionId!==t||v.current.has(m.id)||(v.current.add(m.id),a(T=>[m,...T]),i(!0))}),b=y("interceptor_session_started",m=>{(m==null?void 0:m.sessionId)===t&&i(!0)}),k=y("interceptor_session_stopped",m=>{(m==null?void 0:m.sessionId)===t&&i(!1)});return()=>{o(),b(),k()}},[y,t,r,N]);const w=d.useMemo(()=>[...c].sort((o,b)=>b.ts-o.ts),[c]),g=async o=>{if(p(o),s){const b=await Je(t,o.id);b&&p(b)}},C=s&&c.length>0?e.jsxs("a",{href:Ve(t),className:"inline-flex items-center gap-1 text-xs text-[var(--text-dim)] hover:text-[var(--text)]",title:"Download HAR",children:[e.jsx(pe,{className:"h-3 w-3"}),"HAR"]}):null,E=e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ve,{className:"h-3.5 w-3.5 text-[var(--text-dim)]"}),e.jsx("span",{children:"Network"}),s&&c.length>0&&e.jsxs("span",{className:"text-xs text-[var(--text-dim)]",children:["(",c.length,")"]})]});let h;return x?h=e.jsx("div",{className:"p-4 text-xs text-[var(--text-dim)]",children:"Loading…"}):s===!1&&r?h=e.jsx(O,{title:"No network capture",description:"Network interception was not enabled for this session."}):s===!1?h=e.jsx(O,{title:"Network interception disabled",description:"Enable interceptor.enabled in plugin config to capture requests for Android sessions."}):n?h=e.jsxs("div",{className:"p-4 text-xs text-[var(--red)]",children:["Failed to load requests: ",n]}):w.length===0?h=e.jsx(O,{title:"Waiting for requests",description:r?"No HTTP traffic was captured during this session.":"Captured requests will appear here as the device makes calls."}):h=e.jsx("div",{className:"overflow-auto max-h-96",children:e.jsxs(de,{children:[e.jsx(xe,{children:e.jsxs(M,{children:[e.jsx(S,{style:{width:80},children:"Time"}),e.jsx(S,{style:{width:70},children:"Method"}),e.jsx(S,{style:{width:70},children:"Status"}),e.jsx(S,{children:"Host"}),e.jsx(S,{children:"Path"}),e.jsx(S,{style:{width:80},children:"Duration"}),e.jsx(S,{style:{width:90},children:"Flags"})]})}),e.jsx(me,{children:w.map(o=>e.jsxs(M,{onClick:()=>g(o),style:{cursor:"pointer"},title:o.failed?o.failureReason:void 0,children:[e.jsx(R,{className:"font-mono text-[11px]",children:We(o.ts)}),e.jsx(R,{children:e.jsx(j,{tone:"accent",children:o.method})}),e.jsx(R,{children:o.failed?e.jsx(j,{tone:"error",children:G(o.failureKind)}):e.jsx(j,{tone:Xe(o.resStatus),children:o.resStatus||"—"})}),e.jsx(R,{className:"font-mono text-[11px] truncate",title:o.host,children:o.host}),e.jsx(R,{className:"font-mono text-[11px] truncate",title:o.path,children:o.failed?"—":o.path}),e.jsx(R,{className:"font-mono text-[11px]",children:o.failed?"—":`${o.durationMs}ms`}),e.jsx(R,{children:e.jsxs("div",{className:"flex gap-1",children:[o.mocked&&e.jsx(j,{tone:"accent",children:"mock"}),o.modified&&e.jsx(j,{tone:"busy",children:"mod"})]})})]},o.id))})]})}),e.jsxs(e.Fragment,{children:[e.jsx(Ue,{header:E,action:C,padded:!1,children:h}),e.jsx(ze,{request:f,onClose:()=>p(null)})]})};function Ye(t){return t==="running"?{label:"RUNNING",tone:"running"}:t==="failed"?{label:"FAILED",tone:"failed"}:t==="ended"||t==="passed"?{label:"PASSED",tone:"passed"}:{label:((typeof t=="string"?t:"")||"UNKNOWN").toUpperCase(),tone:"offline"}}const dt=()=>{const{buildId:t="",sessionId:r=""}=Q(),{toast:s}=D(),i=q(),n=Z(),l=je(r||null),c=d.useMemo(()=>{const g=n.builds.find(C=>C.id===t);return(g==null?void 0:g.name)||"Build"},[n.builds,t]);if(d.useEffect(()=>{!l.loading&&l.notFound&&(s("Session not available — it may belong to a team you are not on.","info"),i("/builds",{replace:!0}))},[l.loading,l.notFound,i,s]),l.loading)return e.jsx("div",{className:"p-6 text-xs text-[var(--text-dim)]",children:"Loading session…"});if(l.error||!l.session)return e.jsxs("div",{className:"p-6 space-y-2",children:[e.jsx(U,{buildId:t,buildName:c,sessionId:r}),e.jsx("div",{className:"mt-6 rounded-md border border-[var(--red)]/30 bg-[var(--surface)] p-4 text-xs text-[var(--red)]",children:l.error||"Session not found."})]});const a=l.session,x=Ye(a.status),u=ee(te(a)),f=[...l.sessionLogs,...l.deviceLogs,...l.debugLogs],p=async()=>{try{await navigator.clipboard.writeText(a.id),s("Session ID copied","success")}catch{s("Clipboard unavailable","error")}},v=[{label:"Device",value:re(a)},{label:"Node ID",value:a.node_id||"—",mono:!0},{label:"Platform",value:se(a)},{label:"OS Version",value:a.device_version?ae(a):"—",mono:!0}],y=[{label:"Session ID",value:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"truncate",title:a.id,children:a.id}),e.jsx("button",{type:"button",onClick:p,"aria-label":"Copy session ID",className:"p-0.5 rounded text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(L,{className:"h-3 w-3"})})]}),mono:!0},{label:"Start Time",value:ne(a.startTime),mono:!0},{label:"Duration",value:u,mono:!0}],N=a.status==="failed",w=[{label:"Status",value:e.jsx(ie,{label:x.label,tone:x.tone})}];if(N&&a.failure_category){const g=F(a.failure_category);w.push({label:"Category",value:e.jsx("a",{href:`/xenon/runbooks/${encodeURIComponent(a.failure_category.toLowerCase())}`,target:"_blank",rel:"noreferrer",className:"text-[var(--red)] hover:underline",children:g})})}return N&&a.failure_reason&&w.push({label:"Failure Reason",value:a.failure_reason,tone:"red"}),e.jsxs("div",{className:"flex flex-col h-full min-h-0",children:[e.jsx(U,{buildId:t,buildName:c,sessionId:a.id}),e.jsx("div",{className:"flex-1 overflow-y-auto overflow-x-hidden",children:e.jsxs("div",{className:"px-4 py-4 space-y-4",children:[e.jsx(ye,{identity:v,run:y,result:w}),N&&e.jsx(Re,{session:a,buildName:c,buildId:t,allLogs:f,durationText:u}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1fr_340px] gap-4",children:[e.jsx("div",{className:"min-w-0",children:e.jsx(Me,{sessionLogs:l.sessionLogs,deviceLogs:l.deviceLogs,debugLogs:l.debugLogs,profiling:l.profiling})}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(_e,{session:a}),e.jsx(Ce,{session:a})]})]}),e.jsx(Ge,{sessionId:a.id,sessionEnded:a.status!=="running"})]})})]})};export{dt as SessionDetailPage,dt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.settings-container{padding:24px 32px;max-width:1440px;margin:0 auto;color:var(--text);animation:fadeIn .3s ease;min-height:calc(100vh - 40px);display:flex;flex-direction:column;font-family:Inter,-apple-system,sans-serif;position:relative;background:var(--bg);width:100%}.settings-container>header{padding-left:0;padding-right:0}.settings-header{margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid var(--border)}.settings-header h2{margin:0;font-size:1.75rem;font-weight:700;font-family:Outfit,sans-serif;color:var(--text);letter-spacing:-.01em;text-transform:uppercase}.settings-title-group{display:flex;align-items:center;gap:12px}.settings-title-group .settings-icon{color:var(--text-muted);flex-shrink:0}.settings-subtitle{color:var(--text-muted);font-size:.85rem;margin-top:6px;line-height:1.5}.settings-subtitle span{font-family:JetBrains Mono,monospace;font-size:.75rem;color:var(--text-dim)}.badge-elite{font-size:10px;padding:3px 8px;border-radius:4px;background:#00ff8814;color:var(--green);border:1px solid rgba(0,255,136,.25);font-family:JetBrains Mono,monospace;font-weight:500;text-transform:uppercase;letter-spacing:.08em}.status-pill{display:inline-flex;align-items:center;gap:8px;padding:4px 12px;border-radius:6px;font-size:11px;font-weight:800;font-family:JetBrains Mono,monospace;background:#0006;border:1px solid var(--border);text-transform:uppercase;letter-spacing:.05em}.status-pill.success{border-color:#00ff884d;color:var(--green)}.status-pill.error{border-color:#ff44444d;color:var(--status-error-fg)}.locked-indicator{display:flex;align-items:center;gap:8px;font-size:.75rem;color:var(--text-dim);font-family:JetBrains Mono,monospace;margin-top:var(--space-4)}.locked-indicator code{background:#ffffff0d;color:var(--text-muted);padding:2px 6px;border-radius:4px}.settings-content{display:flex;flex-direction:column;gap:var(--space-8);flex-grow:1}.settings-section h3{display:flex;align-items:center;gap:var(--space-2);font-size:1.125rem;color:var(--text);font-weight:700;margin-bottom:var(--space-2)}.settings-content{display:flex;flex-direction:column;gap:var(--space-8);flex-grow:1;position:relative}.settings-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--space-6);margin-bottom:var(--space-6)}.settings-grid>*{grid-column:span 12}@media (min-width: 1024px){.settings-grid{grid-template-columns:repeat(3,1fr)}.settings-grid>*{grid-column:span 1}}.settings-grid--three{display:grid;grid-template-columns:1fr;gap:var(--space-5);margin-bottom:var(--space-6);align-items:stretch}.settings-grid--three>*{grid-column:auto}@media (min-width: 1024px){.settings-grid--three{grid-template-columns:repeat(3,minmax(0,1fr))}}.settings-grid--two-equal{display:grid;grid-template-columns:1fr;gap:var(--space-5);margin-bottom:var(--space-6);align-items:stretch}.settings-grid--two-equal>*{grid-column:auto}@media (min-width: 1024px){.settings-grid--two-equal{grid-template-columns:repeat(2,minmax(0,1fr))}}.card-spacer{flex-grow:1;min-height:24px}.section-description{color:var(--text-muted);font-size:.875rem;margin-bottom:var(--space-6);max-width:640px;line-height:1.6}.input-group{display:flex;align-items:center;gap:8px;background:var(--bg);border-radius:6px;padding:0 12px;height:42px;border:1px solid var(--border);transition:all .2s ease;position:relative}.input-group:hover{border-color:var(--border-strong)}.mesh-gradient-infra .input-group:focus-within,.mesh-gradient-ai .input-group:focus-within{border-color:var(--green);background:#00ff8808;box-shadow:0 0 0 1px var(--green)}.input-group input,.input-group select{background:transparent;border:none;color:var(--text);font-size:.95rem;width:100%;height:100%;outline:none;font-family:JetBrains Mono,monospace;font-weight:500}.input-group input::placeholder{color:var(--text-dim);opacity:.5}.input-group select{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 0 center;padding-right:2rem}.input-group .code-font{color:var(--text-dim);font-size:.7rem;font-weight:500;letter-spacing:1px;font-family:JetBrains Mono,monospace}.health-monitor-alert{display:flex;align-items:center;gap:12px;background:#ffb8000f;border:1px solid rgba(255,184,0,.2);padding:12px 16px;border-radius:6px;color:var(--status-busy-fg);font-size:11px;font-weight:500;font-family:JetBrains Mono,monospace;text-transform:uppercase}.status-banner{display:flex;align-items:center;gap:10px;padding:12px 16px;border-radius:6px;font-size:11px;animation:slideIn .3s ease;margin-top:16px;font-family:JetBrains Mono,monospace;text-transform:uppercase;font-weight:500}@keyframes slideIn{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}.status-banner.success{background:#00ff880f;border:1px solid rgba(0,255,136,.25);color:var(--green)}.status-banner.error{background:#ff44440f;border:1px solid rgba(255,68,68,.25);color:var(--status-error-fg)}.cron-presets{margin-top:24px;padding-top:16px;border-top:1px solid var(--border)}.presets-label{display:flex;align-items:center;gap:6px;font-size:10px;font-weight:500;color:var(--text-dim);text-transform:uppercase;letter-spacing:.1em;margin-bottom:10px}.preset-chip{padding:5px 12px;margin:2px;background:var(--bg);border:1px solid var(--border);color:var(--text-muted);font-size:10px;font-weight:500;border-radius:4px;cursor:pointer;transition:all .2s ease;text-transform:uppercase;letter-spacing:.05em;font-family:JetBrains Mono,monospace;white-space:nowrap}.preset-chip:hover{background:var(--surface-2);color:var(--text);border-color:var(--border-strong)}.preset-chip.active{background:#00ff8814;color:var(--green);border-color:#00ff884d}.settings-footer{position:sticky;bottom:0;background:var(--surface);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border-top:1px solid var(--border-strong);padding:16px 32px;display:flex;justify-content:space-between;align-items:center;margin-top:auto;z-index:1000}.footer-left{display:flex;align-items:center;gap:16px}.footer-right{display:flex;gap:16px}.footer-dirty{display:inline-flex;align-items:center;gap:8px;color:var(--amber);font-family:Inter,sans-serif;font-size:13px;font-weight:500}.footer-dirty__dot{width:8px;height:8px;border-radius:50%;background:var(--amber);box-shadow:0 0 6px #f59e0b8c;animation:dirty-pulse 2s ease-in-out infinite}@keyframes dirty-pulse{0%,to{opacity:1}50%{opacity:.55}}.footer-divider{width:1px;height:18px;background:var(--border-strong)}.save-btn{background:var(--green);color:var(--bg);padding:10px 24px;border-radius:6px;font-weight:600;font-size:11px;border:none;transition:all .2s;display:flex;align-items:center;gap:6px;text-transform:uppercase;font-family:JetBrains Mono,monospace}.save-btn:hover:not(:disabled){background:var(--green-dim);transform:translateY(-1px);box-shadow:0 0 30px var(--accent-subtle)}.save-btn:active:not(:disabled){transform:translateY(0)}.reset-btn{background:transparent;border:1px solid var(--border);color:var(--text-muted);padding:9px 20px;border-radius:6px;font-weight:500;font-size:11px;transition:all .2s;text-transform:uppercase;font-family:JetBrains Mono,monospace}.reset-btn:hover:not(:disabled){background:var(--surface-2);color:var(--text);border-color:var(--border-strong)}.reset-to-defaults-btn{background:transparent;border:1px solid rgba(255,68,68,.2);color:#f44;padding:9px 20px;border-radius:6px;font-size:10px;font-weight:500;display:flex;align-items:center;gap:6px;transition:all .2s;text-transform:uppercase;font-family:JetBrains Mono,monospace}.reset-to-defaults-btn:hover:not(:disabled){background:#ff4d4d0d;border-color:#ff4d4d}.save-btn:disabled,.reset-btn:disabled,.reset-to-defaults-btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;filter:grayscale(.2)}.setting-field{display:flex;flex-direction:column;gap:var(--space-2);width:100%}.setting-input-wrapper{display:flex;align-items:center;gap:var(--space-4);background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:8px 12px;transition:border-color .15s,box-shadow .15s}.setting-input-wrapper:focus-within{border-color:var(--green);box-shadow:0 0 0 2px #3fb95066}.setting-input-wrapper input,.setting-input-wrapper select{background:transparent;border:none;color:var(--text);font-size:.875rem;width:100%;outline:none}.settings-loading{height:400px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-4);color:var(--text-muted)}.animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (max-width: 640px){.settings-container{padding:var(--space-6)}.settings-footer{flex-direction:column;gap:var(--space-3);padding:var(--space-6)}.footer-left,.footer-right{width:100%;display:flex;flex-direction:column;gap:var(--space-2)}.reset-btn,.save-btn,.reset-to-defaults-btn{width:100%;justify-content:center;white-space:nowrap}}.save-btn,.reset-btn,.reset-to-defaults-btn{white-space:nowrap}.glow-error{box-shadow:0 0 15px #ef444426;border-color:#ef444466!important;animation:pulse-error 2s infinite}@keyframes pulse-error{0%{box-shadow:0 0 10px #ef44441a}50%{box-shadow:0 0 20px #ef444440}to{box-shadow:0 0 10px #ef44441a}}.critical-alert-card{background:#7f1d1d4d;border:2px solid var(--status-error-fg);border-radius:var(--radius-lg);overflow:hidden;margin-top:var(--space-8);box-shadow:0 10px 30px #dc262666;animation:shake-entry .4s ease-out}@keyframes shake-entry{0%{transform:translate(0)}25%{transform:translate(-5px)}50%{transform:translate(5px)}75%{transform:translate(-5px)}to{transform:translate(0)}}.critical-header{background:var(--status-error-fg);color:var(--text);padding:16px 24px;display:flex;align-items:center;gap:12px;font-weight:700;font-size:1.1rem;letter-spacing:.02em}.setting-input-wrapper select{background:transparent;color:var(--text);font-family:Inter,sans-serif;font-weight:500;cursor:pointer;padding-right:32px;-moz-appearance:none;appearance:none;-webkit-appearance:none;color-scheme:dark}.setting-input-wrapper{position:relative}.setting-input-wrapper:after{content:"";position:absolute;right:12px;top:50%;transform:translateY(-50%);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid var(--text-dim);pointer-events:none}.setting-input-wrapper:hover:after{border-top-color:var(--green)}.setting-input-wrapper select option{background-color:var(--surface);color:var(--text);padding:12px}.critical-body{padding:24px;color:#fca5a5}.critical-body p{margin:0 0 16px;line-height:1.6;font-size:.95rem}.terminal-block-critical{background:var(--bg);border:1px solid rgba(127,29,29,.6);border-radius:8px;padding:16px;font-family:JetBrains Mono,monospace;font-size:.85rem;color:#fff;display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:16px}.terminal-block-critical code{color:#a5f3fc;font-weight:600}.copy-btn-critical{background:#ffffff1a;border:1px solid rgba(255,255,255,.2);color:#fff;width:32px;height:32px;border-radius:6px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}.copy-btn-critical:hover{background:#fff3;transform:scale(1.05)}.setting-input-wrapper:focus-within{border-color:var(--green);background:#22c55e08;box-shadow:0 0 0 1px var(--green),0 0 15px #22c55e33,inset 0 0 0 1px #22c55e1a;transform:translateY(-1px)}.live-signal{width:6px;height:6px;background-color:var(--green);border-radius:50%;margin-right:6px;position:relative}.live-signal:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;background:var(--green);animation:ping-signal 1.5s cubic-bezier(0,0,.2,1) infinite}@keyframes ping-signal{75%,to{transform:scale(2.5);opacity:0}}.input-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);height:42px}.status-pill{height:42px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1)}.card-header-dense{border-bottom:1px solid rgba(255,255,255,.05);padding-bottom:16px;margin-bottom:24px}.form-field{display:flex;flex-direction:column;gap:10px}.field-label{font-size:.75rem;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;padding-left:2px}.status-badge{display:flex;align-items:center;gap:8px;padding:0 16px;border-radius:6px;font-size:.8rem;font-weight:600;font-family:JetBrains Mono,monospace;height:42px;width:100%;transition:all .2s}.status-badge.success-filled{background:#22c55e26;color:#4ade80;border:1px solid rgba(34,197,94,.2)}.status-badge.error-filled{background:#ef444426;color:#f87171;border:1px solid rgba(239,68,68,.2)}.ghost-btn{background:transparent;border:1px solid rgba(255,255,255,.1);color:var(--text-muted);padding:0 20px;height:40px;border-radius:6px;font-weight:600;font-size:.85rem;transition:all .2s;display:flex;align-items:center;gap:8px}.ghost-btn:hover{background:#ffffff0d;color:var(--text);border-color:#fff3}.save-btn.primary{height:40px;box-shadow:0 4px 12px #22c55e40}.ai-provider-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--space-4)}.ai-provider-card{display:flex;flex-direction:column;gap:12px;padding:16px 20px;border-radius:8px;border:1px solid rgba(255,255,255,.08);background:#ffffff08;cursor:pointer;transition:all .2s ease;text-align:left;color:var(--text)}.ai-provider-card:hover:not(.disabled){border-color:#fff3;background:#ffffff0f}.ai-provider-card.active{border-color:var(--green);background:#22c55e0f;box-shadow:0 0 0 1px var(--green),0 4px 16px #22c55e1f}.ai-provider-card.disabled{opacity:.4;cursor:not-allowed;filter:grayscale(.5)}.ai-provider-card-header{display:flex;align-items:center;gap:12px}.ai-provider-icon{width:36px;height:36px;border-radius:8px;background:#ffffff0f;display:flex;align-items:center;justify-content:center;color:var(--text-muted);flex-shrink:0}.ai-provider-card.active .ai-provider-icon{background:#22c55e26;color:var(--green)}.ai-provider-info{display:flex;flex-direction:column;gap:2px;min-width:0}.ai-provider-name{font-weight:700;font-size:.95rem;color:var(--text)}.ai-provider-desc{font-size:.75rem;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ai-provider-status{display:flex;align-items:center}.ai-config-display{display:flex;flex-direction:column;gap:1px;background:#ffffff0a;border-radius:8px;overflow:hidden;border:1px solid rgba(255,255,255,.06)}.ai-config-row{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:#02061780}.ai-config-row+.ai-config-row{border-top:1px solid rgba(255,255,255,.04)}.ai-config-label{font-size:.8rem;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em}.ai-config-value{font-size:.9rem;font-weight:500;color:var(--text);display:flex;align-items:center;gap:8px}.ai-config-value.mono{font-family:JetBrains Mono,monospace;font-size:.85rem;color:var(--text)}.ai-config-default{font-size:11px;background:#ffffff0f;color:var(--text-dim);padding:2px 6px;border-radius:4px;font-family:JetBrains Mono,monospace;text-transform:uppercase;letter-spacing:.05em}.toggle-group{display:flex;align-items:center;gap:12px}.switch{position:relative;display:inline-block;width:38px;height:22px;flex-shrink:0}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;top:0;right:0;bottom:0;left:0;background:#ffffff14;border:1px solid var(--border);transition:all .2s ease;cursor:pointer;border-radius:999px}.slider:before{content:"";position:absolute;width:16px;height:16px;left:2px;top:50%;transform:translateY(-50%);background:var(--text-muted);border-radius:50%;transition:all .2s ease}.switch input:checked+.slider{background:#00ff8826;border-color:var(--green);box-shadow:0 0 12px #00ff8826}.switch input:checked+.slider:before{left:calc(100% - 18px);background:var(--green)}.switch input:focus-visible+.slider{outline:2px solid var(--green);outline-offset:2px}.toggle-label{font-family:JetBrains Mono,monospace;font-size:11px;font-weight:700;letter-spacing:.12em;color:var(--text-muted);text-transform:uppercase}.cron-preview{margin-top:12px;padding:10px 12px;background:#00000040;border:1px solid var(--border);border-radius:6px;display:flex;flex-wrap:wrap;align-items:baseline;gap:8px}.cron-preview .preview-label{font-family:JetBrains Mono,monospace;font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim)}.cron-preview .preview-value{font-size:13px;color:var(--text);font-weight:500}.cron-presets{margin-top:12px}.presets-label{display:flex;align-items:center;gap:6px;font-family:JetBrains Mono,monospace;font-size:11px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-bottom:8px}.presets-grid{display:flex;flex-wrap:wrap;gap:8px}.preset-chip{padding:6px 12px;border-radius:6px;border:1px solid var(--border);background:#ffffff08;color:var(--text-muted);font-family:JetBrains Mono,monospace;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;cursor:pointer;transition:all .2s ease}.preset-chip:hover{border-color:var(--border);color:var(--text)}.preset-chip.active{background:#00ff882e;border-color:var(--green);color:var(--green);box-shadow:inset 0 0 0 1px #22c55e59}.preset-chip__check{color:var(--green)}.active-pill{display:inline-flex;align-items:center;gap:5px;margin-left:auto;padding:4px 10px;border-radius:999px;font-family:Inter,sans-serif;font-size:11px;font-weight:600;color:var(--green);background:#22c55e1a;border:1px solid rgba(34,197,94,.3);letter-spacing:.01em}.card-title-row{display:inline-flex;align-items:center;gap:6px}.modified-dot{width:6px;height:6px;border-radius:50%;background:var(--amber);box-shadow:0 0 6px #f59e0b80;display:inline-block}.input-group.has-error{border-color:#ef44448c;background:#ef44440a}.input-group.has-error:focus-within{border-color:var(--red);box-shadow:0 0 0 1px var(--red);background:#ef44440f}.input-status{display:flex;align-items:center;gap:6px;margin-top:4px;font-family:Inter,sans-serif;font-size:12px;font-weight:500;letter-spacing:.01em}.input-status--ok{color:var(--green)}.input-status--error{color:var(--status-error-fg)}.presets-grid--stacked{display:flex;flex-direction:column;gap:8px;align-items:stretch}.presets-grid--stacked .preset-chip{justify-content:flex-start;width:100%}.switch--header{margin-left:auto}.healing-state{font-family:JetBrains Mono,monospace;font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;margin-top:-4px}.healing-state.is-on{color:var(--green)}.healing-state.is-off{color:var(--text-dim)}.healing-events{margin-top:auto;padding:12px;border-radius:var(--radius-md);background:#ffffff06;border:1px solid var(--border);display:flex;flex-direction:column;gap:10px}.healing-events__link{margin-left:auto;display:inline-flex;align-items:center;gap:3px;text-decoration:none;color:var(--green);font-family:JetBrains Mono,monospace;font-size:9.5px;font-weight:600;letter-spacing:.06em;padding:2px 6px;border-radius:4px;border:1px solid rgba(16,185,129,.25);background:#10b9810f;transition:all .15s ease;text-transform:none}.healing-events__link:hover{background:#10b9811f;border-color:#10b98166}.healing-events__header{display:flex;align-items:center;gap:6px;font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.12em;color:var(--text-dim);text-transform:uppercase}.healing-events__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}.healing-events__empty{font-size:11.5px;color:var(--text-dim);line-height:1.45;padding:6px 2px}.healing-event{display:flex;gap:10px;align-items:flex-start}.healing-event__icon{color:var(--green);flex-shrink:0;margin-top:1px}.healing-event__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.healing-event__row{display:flex;justify-content:space-between;align-items:baseline;gap:8px}.healing-event__kind{font-size:12px;font-weight:700;color:var(--text)}.healing-event__when{font-family:JetBrains Mono,monospace;font-size:10px;color:var(--text-dim);white-space:nowrap}.healing-event__message{font-size:11.5px;color:var(--text-muted);line-height:1.4}.settings-footer{animation:dirty-slide-up .2s cubic-bezier(.2,0,0,1)}@keyframes dirty-slide-up{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.page-header-subnote{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-dim);margin-left:8px}.provider-count-pill{display:inline-flex;align-items:center;margin-left:auto;padding:4px 10px;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.provider-count-pill.is-ok{background:#22c55e1a;color:var(--green);border:1px solid rgba(34,197,94,.3)}.provider-count-pill.is-empty{background:#8a938f14;color:var(--text-muted);border:1px solid var(--border-strong)}.provider-list{display:flex;flex-direction:column;gap:10px}.provider-row{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border-radius:var(--radius-md);border:1px solid var(--border);background:#ffffff05;color:var(--text);text-align:left;cursor:pointer;transition:border-color .15s,background .15s,box-shadow .15s;width:100%}.provider-row:hover:not(:disabled):not(.is-active){border-color:var(--border-strong);background:#ffffff0a}.provider-row.is-active{border-color:var(--green);background:#22c55e0f;box-shadow:inset 0 0 0 1px #22c55e66}.provider-row.is-disabled{cursor:not-allowed;opacity:.55}.provider-row__icon{width:36px;height:36px;border-radius:var(--radius-md);display:flex;align-items:center;justify-content:center;background:#ffffff0d;color:var(--text-muted);flex-shrink:0;font-family:Outfit,sans-serif;font-weight:700;font-size:16px}.provider-row.is-active .provider-row__icon{background:#22c55e2e;color:var(--green)}.ai-provider-glyph{font-family:Outfit,sans-serif;font-weight:700;font-size:18px;line-height:1}.provider-row__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.provider-row__name{font-weight:700;font-size:14px;color:var(--text)}.provider-row__desc{font-size:12px;color:var(--text-muted);line-height:1.4}.provider-row__status{margin-top:6px}.provider-status{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;border-radius:4px;font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;border:1px solid transparent}.provider-status--active{color:var(--green);background:#22c55e1f;border-color:#22c55e59}.provider-status--off{color:var(--text-dim);background:#ffffff0a;border-color:var(--border-strong)}.provider-status--ready{color:var(--text-muted);background:#ffffff0a;border-color:var(--border)}.model-params{display:flex;flex-direction:column;gap:14px;margin-top:8px;padding:14px;border-radius:var(--radius-md);background:#ffffff06;border:1px solid var(--border)}.model-params__header{display:flex;align-items:center;gap:8px;color:var(--text);font-family:Outfit,sans-serif;font-size:13px;font-weight:700;letter-spacing:.01em}.model-param{display:flex;flex-direction:column;gap:6px}.model-param__label-row{display:flex;justify-content:space-between;align-items:baseline}.model-param__label-row label{font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.12em;color:var(--text-dim);text-transform:uppercase}.model-param__value{font-family:JetBrains Mono,monospace;font-size:13px;font-weight:700;color:var(--text)}.model-param__slider{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:4px;background:#ffffff14;border-radius:999px;outline:none;cursor:pointer}.model-param__slider::-webkit-slider-runnable-track{height:4px;background:linear-gradient(to right,var(--green) 0%,var(--green) var(--slider-pct, 50%),rgba(255,255,255,.08) var(--slider-pct, 50%),rgba(255,255,255,.08) 100%);border-radius:999px}.model-param__slider::-moz-range-track{height:4px;background:#ffffff14;border-radius:999px}.model-param__slider::-moz-range-progress{height:4px;background:var(--green);border-radius:999px}.model-param__slider::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:14px;height:14px;border-radius:50%;background:var(--green);cursor:pointer;margin-top:-5px;box-shadow:0 0 8px #22c55e80;border:2px solid var(--bg)}.model-param__slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--green);cursor:pointer;box-shadow:0 0 8px #22c55e80;border:2px solid var(--bg)}.test-connection-btn{margin-top:auto;display:flex;align-items:center;justify-content:center;gap:8px;padding:12px 16px;border-radius:var(--radius-md);background:#ffffff0a;border:1px solid var(--border-strong);color:var(--text);font-family:Inter,sans-serif;font-size:13px;font-weight:600;cursor:pointer;transition:background .15s,border-color .15s;width:100%}.test-connection-btn:hover:not(:disabled){background:#22c55e0f;border-color:#22c55e66;color:var(--green)}.test-connection-btn:disabled{opacity:.5;cursor:not-allowed}.ai-config-row .ai-config-default{margin-left:auto}.maintenance-notice{background:#3b82f60d!important;border-color:#3b82f640!important;color:var(--blue)!important;text-transform:none!important;letter-spacing:normal!important}.page-header-action{display:inline-flex;align-items:center;gap:6px;padding:8px 16px;border-radius:var(--radius-md);background:var(--green);color:var(--bg);font-family:Inter,sans-serif;font-size:13px;font-weight:700;border:1px solid transparent;cursor:pointer;transition:filter .15s,transform .15s}.page-header-action:hover:not(:disabled){filter:brightness(1.1);transform:translateY(-1px)}.page-header-action:disabled{opacity:.5;cursor:not-allowed}.page-header-action--ghost{background:transparent;color:var(--text);border-color:var(--border-strong)}.page-header-action--ghost:hover:not(:disabled){background:#ffffff0a;border-color:#22c55e66;color:var(--green)}.stat-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:var(--space-4);margin-bottom:var(--space-5)}.stat-strip__cell{background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-lg);padding:16px 20px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:4px}.stat-strip__value{font-family:Outfit,sans-serif;font-size:28px;font-weight:700;line-height:1.1;color:var(--text);letter-spacing:-.02em}.stat-strip__value--accent{color:var(--green)}.stat-strip__label{font-family:JetBrains Mono,monospace;font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.12em}.data-card{background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);overflow:hidden}.data-card .table-row:hover{background:#ffffff08}.pill-chip{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;font-family:JetBrains Mono,monospace;font-size:10.5px;font-weight:600;letter-spacing:.04em;border:1px solid transparent;line-height:1.4}.pill-chip--shared{background:#ffffff0a;color:var(--text-muted);border-color:var(--border-strong)}.pill-chip--team{background:#22c55e1a;color:var(--green);border-color:#22c55e4d}.pill-chip--scope{background:#3b82f61a;color:var(--blue);border-color:#3b82f64d}.pill-chip--admin{background:#f59e0b1f;color:var(--amber);border-color:#f59e0b59}.scope-chips{display:inline-flex;flex-wrap:wrap;gap:4px}.row-meta-mono{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-dim);margin-top:2px}.row-mono{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--text-muted)}.row-action{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:var(--radius-md);background:transparent;border:1px solid var(--border-strong);color:var(--text-muted);font-family:JetBrains Mono,monospace;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;cursor:pointer;transition:all .15s ease}.row-action:hover:not(:disabled){background:#ffffff0a;border-color:#fff3;color:var(--text)}.row-action--danger{color:var(--status-error-fg);border-color:#ef444440}.row-action--danger:hover:not(:disabled){background:#ef44440f;border-color:#ef444480;color:#fca5a5}.row-action:disabled{opacity:.4;cursor:not-allowed}.empty-state{background:var(--surface);border:1px dashed var(--border-strong);border-radius:var(--radius-lg);padding:56px 32px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:12px}.empty-state__icon{width:56px;height:56px;border-radius:50%;background:#22c55e14;color:var(--green);display:flex;align-items:center;justify-content:center;margin-bottom:4px;border:1px solid rgba(34,197,94,.18)}.empty-state__title{margin:0;font-family:Outfit,sans-serif;font-size:18px;font-weight:700;color:var(--text);letter-spacing:-.005em}.empty-state__copy{margin:0;font-size:13px;color:var(--text-muted);line-height:1.55;max-width:480px}.empty-state__action{margin-top:12px}.team-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--space-4)}.team-card{background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-lg);padding:18px;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;gap:14px;text-align:left;cursor:pointer;transition:border-color .15s,transform .15s,box-shadow .15s;color:var(--text);width:100%}.team-card:hover{border-color:#22c55e66;transform:translateY(-1px);box-shadow:var(--shadow-md)}.team-card__header{display:flex;align-items:flex-start;gap:12px}.team-card__icon{width:36px;height:36px;border-radius:var(--radius-md);background:#22c55e1a;color:var(--green);display:flex;align-items:center;justify-content:center;flex-shrink:0}.team-card__title{flex:1;min-width:0}.team-card__name{font-family:Outfit,sans-serif;font-size:15px;font-weight:700;color:var(--text);letter-spacing:-.005em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.team-card__id{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--text-dim);margin-top:2px}.team-card__delete{flex-shrink:0}.team-card__metrics{display:flex;gap:20px;border-top:1px dashed var(--border);padding-top:12px}.team-card__metric{display:flex;align-items:center;gap:6px;color:var(--text-muted);font-size:12px}.team-card__metric svg{color:var(--text-dim)}.team-card__metric-value{font-family:Outfit,sans-serif;font-size:16px;font-weight:700;color:var(--text)}.team-card__metric-label{color:var(--text-dim);font-size:11px;letter-spacing:.02em}.team-card__footer{margin-top:auto;font-family:JetBrains Mono,monospace;font-size:10.5px;color:var(--text-dim);letter-spacing:.04em}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as R,r as c,X as m,j as e,v as F,C as T,L as B,y as P}from"./index-PtnKslHU.js";/* empty css */import{S as x,A as q}from"./SettingCard-Dp7XIdcl.js";import{P as X}from"./page-header-CSvuGbSO.js";import{u as G}from"./useSocket-BRto9a5m.js";import{S as V,C as O}from"./shield-JGzamJo5.js";import{C as _}from"./circle-check-CI2xUlDo.js";import{C as U}from"./clock-BFVLE7wW.js";import{M as K,F as W}from"./mouse-pointer-2-Dpcc76zN.js";import{C as J}from"./check-BZMx8AhR.js";import{A as Q}from"./activity-DCBAvxuo.js";import{A as Y}from"./arrow-up-right-DePHHOby.js";const f={healthCheckIntervalMs:3e4,healthCheckSchedule:"",enableSelfHealing:!0},j=5e3,Z=[{label:"Battery Saver (2 AM)",value:"0 2 * * *"},{label:"Standard (Hourly)",value:"0 * * * *"},{label:"Operational Coverage (30m)",value:"*/30 * * * *"},{label:"High Performance (10m)",value:"*/10 * * * *"}],S=5;function ee(t){const s=Date.parse(t);if(!Number.isFinite(s))return"";const n=Math.max(0,Date.now()-s),l=Math.floor(n/1e3);if(l<60)return`${l}s ago`;const o=Math.floor(l/60);if(o<60)return`${o}m ago`;const h=Math.floor(o/60);return h<24?`${h}h ago`:`${Math.floor(h/24)}d ago`}function E(t){var h,u;const s=(h=t.originalSelector)==null?void 0:h.trim(),n=(u=t.healedSelector)==null?void 0:u.trim(),l=t.tier&&t.commandName?`${t.commandName}: `:"";if(s&&n&&s!==n)return`${l}${s} → ${n}`;if(n)return`${l}Recovered locator ${n}`;if(s)return`${l}Recovered locator ${s}`;const o=typeof t.confidence=="number"?` (${Math.round(t.confidence*100)}%)`:"";return`${l||""}Self-healed${o}`}function ae(t){return t.tier?t.tier:t.commandName?t.commandName:t.deviceName?t.deviceName:"Self-heal"}const se=(t,s)=>t.healthCheckIntervalMs===s.healthCheckIntervalMs&&t.healthCheckSchedule===s.healthCheckSchedule&&t.enableSelfHealing===s.enableSelfHealing,ge=()=>{const{toast:t}=R(),[s,n]=c.useState(f),[l,o]=c.useState(f),[h,u]=c.useState(!0),[N,C]=c.useState(!1),[y,b]=c.useState([]),[A,H]=c.useState(!1),{on:k}=G();c.useEffect(()=>{I()},[]),c.useEffect(()=>{let a=!1;return m.getRecentHealingEvents(S).then(i=>{if(a||!i)return;const d=Array.isArray(i.events)?i.events.slice(0,S):[];b(d)}).catch(()=>{}).finally(()=>{a||H(!0)}),()=>{a=!0}},[]),c.useEffect(()=>{const a=k("healing_event",i=>{const d=i;!d||!d.id||b(p=>p.some(D=>D.id===d.id)?p:[d,...p].slice(0,S))});return()=>{a&&a()}},[k]);const I=async()=>{u(!0);try{const a=await m.getGlobalConfig(),i={healthCheckIntervalMs:a.healthCheckIntervalMs||3e4,healthCheckSchedule:a.healthCheckSchedule||"",enableSelfHealing:a.enableSelfHealing!==void 0?a.enableSelfHealing:!0};n(i),o(i)}catch(a){console.error("Failed to load settings",a),t("Failed to access infrastructure parameters.","error")}finally{u(!1)}},g=!se(s,l),r=Number.isNaN(s.healthCheckIntervalMs)||s.healthCheckIntervalMs<j?`Below minimum safe value of ${j}ms.`:null,w=g&&!r,v={interval:s.healthCheckIntervalMs!==l.healthCheckIntervalMs,schedule:s.healthCheckSchedule!==l.healthCheckSchedule,healing:s.enableSelfHealing!==l.enableSelfHealing},M=async a=>{const i=a??s;if(!a&&r){t(r,"error");return}C(!0);try{await m.updateGlobalConfig(i),o(i),n(i),t("Infrastructure parameters synchronized across fleet.","success")}catch(d){console.error("Failed to save settings",d),t("Synchronization failed. Check network integrity.","error")}finally{C(!1)}},$=async()=>{n(f),await M(f);try{await m.resetMetrics()}catch(a){console.error("Failed to reset metrics",a)}},z=()=>{n(l)},L=s.healthCheckSchedule!=="";return h?e.jsxs("div",{className:"settings-loading",children:[e.jsx(F,{className:"animate-spin",size:32}),e.jsx("span",{children:"Synchronizing Global Infrastructure..."})]}):e.jsxs("div",{className:"settings-container",children:[e.jsx(X,{icon:V,title:"Settings",subtitle:"Manage core farm parameters, heartbeat frequency, and maintenance orchestrations across the global registry."}),e.jsx("div",{className:"settings-content",children:e.jsxs("div",{className:"settings-grid settings-grid--three",children:[e.jsxs(x,{icon:e.jsx(U,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Idle Health Frequency",v.interval&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),description:"Frequency of passive health pings when the system is in idle state.",hint:"Minimum safe value: 5000ms. Note: This frequency is overridden when a schedule is active.",children:[e.jsx("div",{className:"card-spacer"}),e.jsxs("div",{className:`input-group ${r?"has-error":""}`,children:[e.jsx("input",{type:"number",value:s.healthCheckIntervalMs,onChange:a=>n({...s,healthCheckIntervalMs:parseInt(a.target.value,10)}),min:j,step:5e3,"aria-invalid":!!r,"aria-describedby":r?"interval-error":"interval-status"}),e.jsx("span",{className:"code-font",children:"MS"})]}),r?e.jsxs("div",{id:"interval-error",className:"input-status input-status--error",role:"alert",children:[e.jsx(T,{size:12}),e.jsx("span",{children:r})]}):e.jsxs("div",{id:"interval-status",className:"input-status input-status--ok",children:[e.jsx(_,{size:12}),e.jsx("span",{children:"Valid frequency"})]})]}),e.jsxs(x,{icon:e.jsx(O,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["Deep Diagnostic Schedule",v.schedule&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),titleExtra:L?e.jsxs("span",{className:"active-pill",children:[e.jsx(Q,{size:11}),e.jsx("span",{children:"Active"})]}):null,description:"Execute intensive reliability bursts (WDA restarts, Cache purges) using standardized Cron syntax.",children:[e.jsx("div",{className:"setting-input-wrapper",children:e.jsx("input",{type:"text",placeholder:"e.g. 0 * * * * (hourly, at minute 0)",value:s.healthCheckSchedule,onChange:a=>n({...s,healthCheckSchedule:a.target.value})})}),e.jsxs("div",{className:"cron-presets",children:[e.jsxs("div",{className:"presets-label",children:[e.jsx(K,{size:12}),e.jsx("span",{children:"Intent-Based Presets"})]}),e.jsx("div",{className:"presets-grid presets-grid--stacked",children:Z.map(a=>{const i=s.healthCheckSchedule===a.value;return e.jsxs("button",{type:"button",className:`preset-chip ${i?"active":""}`,onClick:()=>n({...s,healthCheckSchedule:a.value}),"aria-pressed":i,children:[i&&e.jsx(J,{size:11,className:"preset-chip__check"}),e.jsx("span",{children:a.label})]},a.label)})})]})]}),e.jsxs(x,{icon:e.jsx(P,{size:16}),title:e.jsxs("span",{className:"card-title-row",children:["AI Self-Healing",v.healing&&e.jsx("span",{className:"modified-dot","aria-label":"Modified"})]}),titleExtra:e.jsxs("label",{className:"switch switch--header",children:[e.jsx("input",{type:"checkbox",checked:s.enableSelfHealing,onChange:a=>n({...s,enableSelfHealing:a.target.checked}),"aria-label":"Toggle AI Self-Healing"}),e.jsx("span",{className:"slider round"})]}),children:[e.jsx("div",{className:`healing-state ${s.enableSelfHealing?"is-on":"is-off"}`,children:s.enableSelfHealing?"ENABLED":"DISABLED"}),e.jsx("p",{className:"setting-card-description",children:"Automatically intercept and recover from failing locators using Xenon's 6-tier strategy: etalon recovery, native retry, fuzzy XML, OCR, visual AI, and LLM — before failing a test."}),s.enableSelfHealing&&e.jsxs("div",{className:"healing-events",children:[e.jsxs("div",{className:"healing-events__header",children:[e.jsx(W,{size:11}),e.jsx("span",{children:"Recent Healing Events"}),e.jsxs(B,{to:"/selector-health",className:"healing-events__link",children:["Selector Health ",e.jsx(Y,{size:10})]})]}),y.length>0?e.jsx("ul",{className:"healing-events__list",children:y.map(a=>e.jsxs("li",{className:"healing-event",children:[e.jsx(_,{size:14,className:"healing-event__icon"}),e.jsxs("div",{className:"healing-event__body",children:[e.jsxs("div",{className:"healing-event__row",children:[e.jsx("span",{className:"healing-event__kind",children:ae(a)}),e.jsx("span",{className:"healing-event__when",children:ee(a.createdAt)})]}),e.jsx("div",{className:"healing-event__message",title:E(a),children:E(a)})]})]},a.id))}):e.jsx("div",{className:"healing-events__empty",children:A?"No healing events recorded yet — the dashboard will populate as locators are recovered.":"Loading recent events…"})]})]})]})}),(g||N)&&e.jsx(q,{onSave:()=>M(),onDiscard:z,onRestoreDefaults:$,isSaving:N,isValidating:!!r,isDirty:g,saveLabel:w?"Save Configuration":"Resolve errors to save"})]})};export{ge as Settings};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as n,X as v,j as x}from"./index-PtnKslHU.js";import{u as y}from"./useSocket-BRto9a5m.js";import{f as E}from"./time-B8FIgwPE.js";const _=3e3;function L(){const[e,t]=n.useState([]),[r,o]=n.useState([]),[i,u]=n.useState(null),[d,p]=n.useState(""),[b,S]=n.useState(!0),[h,m]=n.useState(null),c=n.useRef(!0),{on:l}=y(),a=n.useCallback(async()=>{try{const[s,f]=await Promise.all([v.getBuilds(),i?v.getSessions({buildId:i,query:d}):Promise.resolve([])]);if(!c.current)return;t(Array.isArray(s)?s:[]),o(Array.isArray(f)?f:[]),m(null)}catch(s){if(!c.current)return;m(s instanceof Error?s.message:String(s))}finally{c.current&&S(!1)}},[i,d]);return n.useEffect(()=>{c.current=!0,a();const s=setInterval(a,_);return()=>{c.current=!1,clearInterval(s)}},[a]),n.useEffect(()=>{const s=()=>a(),f=[l("session_started",s),l("session_stopped",s),l("device_added",s),l("device_removed",s)];return()=>{for(const g of f)g()}},[l,a]),{builds:e,selectedBuildId:i,sessions:r,loading:b,error:h,selectBuild:u,searchQuery:d,setSearchQuery:p,refresh:a}}function T(e){const t={all:e.length,passed:0,failed:0,running:0};for(const r of e)r.status==="ended"||r.status==="passed"?t.passed+=1:r.status==="failed"?t.failed+=1:r.status==="running"&&(t.running+=1);return t}function k(e){var r;const t=(r=e.device_name)==null?void 0:r.trim();return t&&t.length>0?t:"Unknown Device"}function w(e){const t=e.device_platform??"";if(!t)return"—";const r=t.toLowerCase();return r==="ios"?"iOS":r==="tvos"?"tvOS":r.charAt(0).toUpperCase()+r.slice(1)}function B(e){return e.device_version?`v${e.device_version}`:""}function F(e){return E(e)}function N(e){if(!e.startTime)return null;const t=Date.parse(e.startTime);if(!Number.isFinite(t))return null;const r=e.endTime?Date.parse(e.endTime):Date.now();return Number.isFinite(r)?Math.max(0,r-t):null}function C(e){if(e==null||!Number.isFinite(e)||e<0)return"—";const t=e/1e3,r=Math.floor(t/3600),o=Math.floor(t%3600/60),u=(t-r*3600-o*60).toFixed(1);return r>0?`${r}h ${o}m ${u}s`:o>0?`${o}m ${u}s`:`${u}s`}function M(e,t=10,r=4){return e?e.length<=t+r+1?e:`${e.slice(0,t)}…${e.slice(-r)}`:""}const $={ready:"border-[var(--green)]/40 text-[var(--green)]",passed:"border-[var(--green)]/40 text-[var(--green)]",running:"border-[var(--amber)]/40 text-[var(--amber)]",failed:"border-[var(--red)]/40 text-[var(--red)]",offline:"border-[var(--text-dim)]/40 text-[var(--text-dim)]"},R=({label:e,tone:t})=>x.jsx("span",{className:`inline-flex items-center justify-center h-6 px-2.5 rounded border text-[10px] font-mono font-semibold tracking-wider ${$[t]}`,children:e});export{R as S,N as a,T as b,k as d,F as f,C as h,B as o,w as p,M as s,L as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as D,r as n,j as e,v as z,z as f,S as B}from"./index-PtnKslHU.js";/* empty css */import{a as $}from"./time-B8FIgwPE.js";import{T as E,a as M,b as T,c as u,d as R,e as j}from"./Table-DsN_IX6J.js";import{F as Y}from"./FieldGroup-C5UkCHbe.js";import{P as U}from"./page-header-CSvuGbSO.js";import{M as K}from"./Modal-MMGhL8eW.js";import{l as Q}from"./users-cwrwUhwo.js";import{S as V}from"./shield-alert-DzE36jcb.js";import{P as N}from"./plus-vJJF9g79.js";import{A as W}from"./arrow-left-GX0vzYtn.js";import{T as F}from"./trash-2-BrTSfFh5.js";const P={SUPER_ADMIN:"Super Admin",ADMIN:"Admin",MEMBER:"Member"};async function p(i,r){const t=await fetch(i,{credentials:"include",...r});if(!t.ok){const l=await t.json().catch(()=>({}));throw Object.assign(new Error(l.error||`HTTP ${t.status}`),{status:t.status})}return t.json()}const xe=()=>{const{toast:i}=D(),[r,t]=n.useState([]),[l,m]=n.useState(!0),[c,h]=n.useState(!1),[x,d]=n.useState(!1),[_,S]=n.useState(null),v=async()=>{m(!0);try{const a=await p("/xenon/api/teams");t(a),h(!1)}catch(a){a.status===403?h(!0):i(`Failed to load teams: ${a.message}`,"error")}finally{m(!1)}};if(n.useEffect(()=>{v()},[]),l)return e.jsxs("div",{className:"settings-loading",children:[e.jsx(z,{className:"animate-spin",size:32}),e.jsx("span",{children:"Loading teams…"})]});if(c)return e.jsx("div",{className:"settings-container",children:e.jsx(U,{icon:V,title:"Teams",subtitle:e.jsxs(e.Fragment,{children:["Your key lacks the ",e.jsx("code",{children:"admin"})," scope. Ask an administrator to promote your key before you can manage teams."]})})});if(_)return e.jsx(ee,{team:_,onBack:()=>{S(null),v()}});const C=r.reduce((a,o)=>a+o.deviceCount,0),y=r.reduce((a,o)=>a+o.memberCount,0);return e.jsxs("div",{className:"settings-container",children:[e.jsx(U,{icon:f,title:"Teams",subtitle:"Group devices and members by team. Devices with no team assignment stay in the shared pool — visible to every authenticated user.",action:r.length>0?e.jsxs("button",{type:"button",className:"page-header-action",onClick:()=>d(!0),children:[e.jsx(N,{size:16}),e.jsx("span",{children:"New team"})]}):void 0}),e.jsxs("div",{className:"settings-content",children:[r.length>0&&e.jsxs("div",{className:"stat-strip",children:[e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value stat-strip__value--accent",children:r.length}),e.jsx("div",{className:"stat-strip__label",children:"Teams"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:y}),e.jsx("div",{className:"stat-strip__label",children:"Members"})]}),e.jsxs("div",{className:"stat-strip__cell",children:[e.jsx("div",{className:"stat-strip__value",children:C}),e.jsx("div",{className:"stat-strip__label",children:"Devices assigned"})]})]}),r.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx("div",{className:"empty-state__icon",children:e.jsx(f,{size:28})}),e.jsx("h3",{className:"empty-state__title",children:"No teams yet"}),e.jsx("p",{className:"empty-state__copy",children:"Every device is in the shared pool until you create a team and assign it. Teams let you scope an API key to a subset of devices — useful for separating CI runners, staging fleets, or per-team device pools."}),e.jsxs("button",{type:"button",className:"page-header-action empty-state__action",onClick:()=>d(!0),children:[e.jsx(N,{size:16}),e.jsx("span",{children:"Create your first team"})]})]}):e.jsx("div",{className:"team-grid",children:r.map(a=>e.jsxs("button",{type:"button",className:"team-card",onClick:()=>S(a),children:[e.jsxs("div",{className:"team-card__header",children:[e.jsx("div",{className:"team-card__icon",children:e.jsx(f,{size:16})}),e.jsxs("div",{className:"team-card__title",children:[e.jsx("div",{className:"team-card__name",children:a.name}),e.jsx("div",{className:"team-card__id",children:a.id.slice(0,8)})]}),e.jsx("span",{className:"team-card__delete",role:"button",tabIndex:0,onClick:o=>o.stopPropagation(),children:e.jsx(Z,{team:a,onDeleted:v})})]}),e.jsxs("div",{className:"team-card__metrics",children:[e.jsxs("div",{className:"team-card__metric",children:[e.jsx(B,{size:13}),e.jsx("span",{className:"team-card__metric-value",children:a.deviceCount}),e.jsx("span",{className:"team-card__metric-label",children:"devices"})]}),e.jsxs("div",{className:"team-card__metric",children:[e.jsx(f,{size:13}),e.jsx("span",{className:"team-card__metric-value",children:a.memberCount}),e.jsx("span",{className:"team-card__metric-label",children:"members"})]})]}),e.jsxs("div",{className:"team-card__footer",children:["Created ",$(a.createdAt)]})]},a.id))})]}),x&&e.jsx(X,{onClose:()=>d(!1),onCreated:()=>{d(!1),v()}})]})},X=({onClose:i,onCreated:r})=>{const{toast:t}=D(),[l,m]=n.useState(""),[c,h]=n.useState(!1),x=async()=>{if(!l.trim())return t("Name required","error");h(!0);try{await p("/xenon/api/teams",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:l.trim()})}),t("Team created","success"),r()}catch(d){t(d.message,"error")}finally{h(!1)}};return e.jsx(K,{open:!0,onClose:i,title:"New team",footer:e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"reset-btn",onClick:i,disabled:c,children:"Cancel"}),e.jsxs("button",{className:"save-btn",onClick:x,disabled:c,children:[c?e.jsx(z,{className:"animate-spin",size:18}):e.jsx(N,{size:18}),c?"Creating…":"Create"]})]}),children:e.jsx("div",{style:{display:"flex",flexDirection:"column"},children:e.jsx(Y,{label:"Name",htmlFor:"team-name",children:e.jsx("input",{id:"team-name",type:"text",value:l,onChange:d=>m(d.target.value),placeholder:"android-team, qa-ios, …",style:w,autoFocus:!0})})})})},Z=({team:i,onDeleted:r})=>{const{toast:t}=D(),[l,m]=n.useState(!1),c=async h=>{if(h.stopPropagation(),!!window.confirm(`Delete team "${i.name}"? It must have no devices and no members.`)){m(!0);try{await p(`/xenon/api/teams/${i.id}`,{method:"DELETE"}),t("Team deleted","success"),r()}catch(x){t(x.message,"error")}finally{m(!1)}}};return e.jsxs("button",{className:"reset-btn",disabled:l,onClick:c,style:{color:"var(--status-error-fg)"},children:[e.jsx(F,{size:14}),l?"Deleting…":"Delete"]})},ee=({team:i,onBack:r})=>{const{toast:t}=D(),[l,m]=n.useState([]),[c,h]=n.useState([]),[x,d]=n.useState([]),[_,S]=n.useState([]),[v,C]=n.useState(!0),[y,a]=n.useState(""),[o,k]=n.useState(""),b=async()=>{C(!0);try{const[s,g,G]=await Promise.all([p(`/xenon/api/teams/${i.id}/members`),Q(),p("/xenon/api/device")]);m(s),h(g);const I=G;d(I.filter(A=>A.teamId===i.id)),S(I.filter(A=>!A.teamId))}catch(s){t(`Failed to load team detail: ${s.message}`,"error")}finally{C(!1)}};n.useEffect(()=>{b()},[i.id]);const L=async()=>{if(y)try{await p(`/xenon/api/teams/${i.id}/members`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:y})}),t("Member added","success"),a(""),b()}catch(s){t(s.message,"error")}},O=async s=>{if(window.confirm("Remove this member from the team?"))try{await p(`/xenon/api/teams/${i.id}/members/${encodeURIComponent(s)}`,{method:"DELETE"}),t("Member removed","success"),b()}catch(g){t(g.message,"error")}},H=async()=>{if(o)try{await p(`/xenon/api/device/${encodeURIComponent(o)}/team`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({teamId:i.id})}),t("Device assigned","success"),k(""),b()}catch(s){t(s.message,"error")}},J=async s=>{if(window.confirm("Return this device to the shared pool?"))try{await p(`/xenon/api/device/${encodeURIComponent(s)}/team`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({teamId:null})}),t("Device unassigned","success"),b()}catch(g){t(g.message,"error")}},q=c.filter(s=>!l.some(g=>g.userId===s.id));return e.jsxs("div",{className:"settings-container mesh-gradient-infra",children:[e.jsxs("div",{className:"settings-header",children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:12},children:[e.jsx("button",{onClick:r,className:"reset-btn",style:{padding:"4px 8px"},"aria-label":"Back",children:e.jsx(W,{size:18})}),e.jsxs("div",{className:"settings-title-group",children:[e.jsx(f,{className:"settings-icon infra-icon",size:28}),e.jsx("h2",{children:i.name})]})]}),e.jsx("p",{className:"settings-subtitle",children:'Manage members and devices assigned to this team. To add a device, go to Devices and use "Assign to team."'})]}),v?e.jsx("div",{className:"settings-loading",children:e.jsx(z,{className:"animate-spin",size:32})}):e.jsxs("div",{className:"settings-content",style:{display:"flex",flexDirection:"column",gap:24},children:[e.jsxs("section",{children:[e.jsxs("h3",{style:{marginBottom:12},children:["Members (",l.length,")"]}),e.jsxs("div",{className:"surface-card",style:{padding:12},children:[e.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12},children:[e.jsxs("select",{value:y,onChange:s=>a(s.target.value),style:{...w,flex:1},children:[e.jsx("option",{value:"",children:"Select a user to add…"}),q.map(s=>e.jsxs("option",{value:s.id,children:[s.name," (",s.email,") — ",P[s.role]]},s.id))]}),e.jsxs("button",{className:"save-btn",onClick:L,disabled:!y,children:[e.jsx(N,{size:16})," Add"]})]}),l.length===0?e.jsx("p",{style:{opacity:.6,textAlign:"center",padding:24},children:"No members yet. Add a user above."}):e.jsxs(E,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(u,{children:"Name"}),e.jsx(u,{children:"Email"}),e.jsx(u,{children:"Role"}),e.jsx(u,{children:"Added"}),e.jsx(u,{style:{textAlign:"right"},children:"Action"})]})}),e.jsx(R,{children:l.map(s=>e.jsxs(T,{children:[e.jsx(j,{children:s.name}),e.jsx(j,{children:e.jsx("code",{style:{fontSize:"11px",color:"var(--text-muted)"},children:s.email})}),e.jsx(j,{children:P[s.role]}),e.jsx(j,{children:$(s.addedAt)}),e.jsx(j,{style:{textAlign:"right"},children:e.jsx("button",{className:"reset-btn",onClick:()=>O(s.userId),style:{color:"var(--status-error-fg)"},"aria-label":"Remove member",title:"Remove member",children:e.jsx(F,{size:14})})})]},s.userId))})]})]})]}),e.jsxs("section",{children:[e.jsxs("h3",{style:{marginBottom:12},children:["Devices (",x.length,")"]}),e.jsxs("div",{className:"surface-card",style:{padding:12},children:[e.jsxs("div",{style:{display:"flex",gap:8,marginBottom:12},children:[e.jsxs("select",{value:o,onChange:s=>k(s.target.value),style:{...w,flex:1},children:[e.jsx("option",{value:"",children:"Select a shared-pool device to assign…"}),_.map(s=>e.jsxs("option",{value:s.udid,children:[s.name," (",s.platform,") — ",s.udid.slice(0,12),"…"]},s.udid))]}),e.jsxs("button",{className:"save-btn",onClick:H,disabled:!o,children:[e.jsx(N,{size:16})," Assign"]})]}),x.length===0?e.jsx("p",{style:{opacity:.6,textAlign:"center",padding:24},children:"No devices assigned. Use the Devices page to move devices into this team."}):e.jsxs(E,{children:[e.jsx(M,{children:e.jsxs(T,{children:[e.jsx(u,{children:"Name"}),e.jsx(u,{children:"Platform"}),e.jsx(u,{children:"UDID"}),e.jsx(u,{style:{textAlign:"right"},children:"Actions"})]})}),e.jsx(R,{children:x.map(s=>e.jsxs(T,{children:[e.jsxs(j,{children:[e.jsx(B,{size:14,style:{marginRight:6,verticalAlign:"middle"}}),s.name]}),e.jsx(j,{children:s.platform}),e.jsx(j,{children:e.jsxs("code",{style:{fontSize:"11px"},children:[s.udid.slice(0,14),"…"]})}),e.jsx(j,{style:{textAlign:"right"},children:e.jsx("button",{className:"reset-btn",onClick:()=>J(s.udid),children:"Return to shared pool"})})]},s.udid))})]})]})]})]})]})},w={width:"100%",padding:"8px 12px",background:"rgba(0,0,0,0.3)",border:"1px solid rgba(255,255,255,0.1)",borderRadius:6,color:"inherit",fontSize:"0.95em",boxSizing:"border-box"};export{xe as Teams};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(t){if(!t)return"";const e=Date.parse(t);if(!Number.isFinite(e))return"";const n=Math.max(0,Date.now()-e),r=Math.floor(n/1e3);if(r<60)return`${r}s ago`;const a=Math.floor(r/60);if(a<60)return`${a}m ago`;const o=Math.floor(a/60);return o<24?`${o}h ago`:`${Math.floor(o/24)}d ago`}const u=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function i(t){if(t==null||t==="")return"—";const e=t instanceof Date?t:new Date(t);if(Number.isNaN(e.getTime()))return"—";const n=r=>String(r).padStart(2,"0");return`${u[e.getMonth()]} ${e.getDate()}, ${n(e.getHours())}:${n(e.getMinutes())}:${n(e.getSeconds())}`}function g(t){if(t==null||t==="")return"—";const e=t instanceof Date?t:new Date(t);return Number.isNaN(e.getTime())?"—":`${u[e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`}export{g as a,c as b,i as f};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as E}from"./index-BrVV0Kla.js";const m=Object.create(null);m.open="0";m.close="1";m.ping="2";m.pong="3";m.message="4";m.upgrade="5";m.noop="6";const R=Object.create(null);Object.keys(m).forEach(n=>{R[m[n]]=n});const q={type:"error",data:"parser error"},j=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",G=typeof ArrayBuffer=="function",Z=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n&&n.buffer instanceof ArrayBuffer,M=({type:n,data:e},t,s)=>j&&e instanceof Blob?t?s(e):Y(e,s):G&&(e instanceof ArrayBuffer||Z(e))?t?s(e):Y(new Blob([e]),s):s(m[n]+(e||"")),Y=(n,e)=>{const t=new FileReader;return t.onload=function(){const s=t.result.split(",")[1];e("b"+(s||""))},t.readAsDataURL(n)};function z(n){return n instanceof Uint8Array?n:n instanceof ArrayBuffer?new Uint8Array(n):new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}let N;function ue(n,e){if(j&&n.data instanceof Blob)return n.data.arrayBuffer().then(z).then(e);if(G&&(n.data instanceof ArrayBuffer||Z(n.data)))return e(z(n.data));M(n,!1,t=>{N||(N=new TextEncoder),e(N.encode(t))})}const J="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",k=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let n=0;n<J.length;n++)k[J.charCodeAt(n)]=n;const fe=n=>{let e=n.length*.75,t=n.length,s,i=0,r,o,a,c;n[n.length-1]==="="&&(e--,n[n.length-2]==="="&&e--);const l=new ArrayBuffer(e),f=new Uint8Array(l);for(s=0;s<t;s+=4)r=k[n.charCodeAt(s)],o=k[n.charCodeAt(s+1)],a=k[n.charCodeAt(s+2)],c=k[n.charCodeAt(s+3)],f[i++]=r<<2|o>>4,f[i++]=(o&15)<<4|a>>2,f[i++]=(a&3)<<6|c&63;return l},le=typeof ArrayBuffer=="function",H=(n,e)=>{if(typeof n!="string")return{type:"message",data:ee(n,e)};const t=n.charAt(0);return t==="b"?{type:"message",data:pe(n.substring(1),e)}:R[t]?n.length>1?{type:R[t],data:n.substring(1)}:{type:R[t]}:q},pe=(n,e)=>{if(le){const t=fe(n);return ee(t,e)}else return{base64:!0,data:n}},ee=(n,e)=>{switch(e){case"blob":return n instanceof Blob?n:new Blob([n]);case"arraybuffer":default:return n instanceof ArrayBuffer?n:n.buffer}},te="",de=(n,e)=>{const t=n.length,s=new Array(t);let i=0;n.forEach((r,o)=>{M(r,!1,a=>{s[o]=a,++i===t&&e(s.join(te))})})},ye=(n,e)=>{const t=n.split(te),s=[];for(let i=0;i<t.length;i++){const r=H(t[i],e);if(s.push(r),r.type==="error")break}return s};function ge(){return new TransformStream({transform(n,e){ue(n,t=>{const s=t.length;let i;if(s<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,s);else if(s<65536){i=new Uint8Array(3);const r=new DataView(i.buffer);r.setUint8(0,126),r.setUint16(1,s)}else{i=new Uint8Array(9);const r=new DataView(i.buffer);r.setUint8(0,127),r.setBigUint64(1,BigInt(s))}n.data&&typeof n.data!="string"&&(i[0]|=128),e.enqueue(i),e.enqueue(t)})}})}let L;function A(n){return n.reduce((e,t)=>e+t.length,0)}function T(n,e){if(n[0].length===e)return n.shift();const t=new Uint8Array(e);let s=0;for(let i=0;i<e;i++)t[i]=n[0][s++],s===n[0].length&&(n.shift(),s=0);return n.length&&s<n[0].length&&(n[0]=n[0].slice(s)),t}function me(n,e){L||(L=new TextDecoder);const t=[];let s=0,i=-1,r=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(s===0){if(A(t)<1)break;const c=T(t,1);r=(c[0]&128)===128,i=c[0]&127,i<126?s=3:i===126?s=1:s=2}else if(s===1){if(A(t)<2)break;const c=T(t,2);i=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),s=3}else if(s===2){if(A(t)<8)break;const c=T(t,8),l=new DataView(c.buffer,c.byteOffset,c.length),f=l.getUint32(0);if(f>Math.pow(2,21)-1){a.enqueue(q);break}i=f*Math.pow(2,32)+l.getUint32(4),s=3}else{if(A(t)<i)break;const c=T(t,i);a.enqueue(H(r?c:L.decode(c),e)),s=0}if(i===0||i>n){a.enqueue(q);break}}}})}const se=4;function u(n){if(n)return _e(n)}function _e(n){for(var e in u.prototype)n[e]=u.prototype[e];return n}u.prototype.on=u.prototype.addEventListener=function(n,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+n]=this._callbacks["$"+n]||[]).push(e),this};u.prototype.once=function(n,e){function t(){this.off(n,t),e.apply(this,arguments)}return t.fn=e,this.on(n,t),this};u.prototype.off=u.prototype.removeListener=u.prototype.removeAllListeners=u.prototype.removeEventListener=function(n,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+n];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+n],this;for(var s,i=0;i<t.length;i++)if(s=t[i],s===e||s.fn===e){t.splice(i,1);break}return t.length===0&&delete this._callbacks["$"+n],this};u.prototype.emit=function(n){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+n],s=1;s<arguments.length;s++)e[s-1]=arguments[s];if(t){t=t.slice(0);for(var s=0,i=t.length;s<i;++s)t[s].apply(this,e)}return this};u.prototype.emitReserved=u.prototype.emit;u.prototype.listeners=function(n){return this._callbacks=this._callbacks||{},this._callbacks["$"+n]||[]};u.prototype.hasListeners=function(n){return!!this.listeners(n).length};const B=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,t)=>t(e,0),p=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),be="arraybuffer";function ne(n,...e){return e.reduce((t,s)=>(n.hasOwnProperty(s)&&(t[s]=n[s]),t),{})}const we=p.setTimeout,Ee=p.clearTimeout;function x(n,e){e.useNativeTimers?(n.setTimeoutFn=we.bind(p),n.clearTimeoutFn=Ee.bind(p)):(n.setTimeoutFn=p.setTimeout.bind(p),n.clearTimeoutFn=p.clearTimeout.bind(p))}const ve=1.33;function ke(n){return typeof n=="string"?Ae(n):Math.ceil((n.byteLength||n.size)*ve)}function Ae(n){let e=0,t=0;for(let s=0,i=n.length;s<i;s++)e=n.charCodeAt(s),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(s++,t+=4);return t}function ie(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function Te(n){let e="";for(let t in n)n.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(n[t]));return e}function Re(n){let e={},t=n.split("&");for(let s=0,i=t.length;s<i;s++){let r=t[s].split("=");e[decodeURIComponent(r[0])]=decodeURIComponent(r[1])}return e}class Oe extends Error{constructor(e,t,s){super(e),this.description=t,this.context=s,this.type="TransportError"}}class K extends u{constructor(e){super(),this.writable=!1,x(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,t,s){return super.emitReserved("error",new Oe(e,t,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){const t=H(e,this.socket.binaryType);this.onPacket(t)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,t={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}_hostname(){const e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){const t=Te(e);return t.length?"?"+t:""}}class Se extends K{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";const t=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let s=0;this._polling&&(s++,this.once("pollComplete",function(){--s||t()})),this.writable||(s++,this.once("drain",function(){--s||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){const t=s=>{if(this.readyState==="opening"&&s.type==="open"&&this.onOpen(),s.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(s)};ye(e,this.socket.binaryType).forEach(t),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){const e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,de(e,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const e=this.opts.secure?"https":"http",t=this.query||{};return this.opts.timestampRequests!==!1&&(t[this.opts.timestampParam]=ie()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let re=!1;try{re=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const Ce=re;function Be(){}class xe extends Se{constructor(e){if(super(e),typeof location<"u"){const t=location.protocol==="https:";let s=location.port;s||(s=t?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||s!==e.port}}doWrite(e,t){const s=this.request({method:"POST",data:e});s.on("success",t),s.on("error",(i,r)=>{this.onError("xhr post error",i,r)})}doPoll(){const e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(t,s)=>{this.onError("xhr poll error",t,s)}),this.pollXhr=e}}class g extends u{constructor(e,t,s){super(),this.createRequest=e,x(this,s),this._opts=s,this._method=s.method||"GET",this._uri=t,this._data=s.data!==void 0?s.data:null,this._create()}_create(){var e;const t=ne(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(t);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let i in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(i)&&s.setRequestHeader(i,this._opts.extraHeaders[i])}}catch{}if(this._method==="POST")try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{s.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var i;s.readyState===3&&((i=this._opts.cookieJar)===null||i===void 0||i.parseCookies(s.getResponseHeader("set-cookie"))),s.readyState===4&&(s.status===200||s.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof s.status=="number"?s.status:0)},0))},s.send(this._data)}catch(i){this.setTimeoutFn(()=>{this._onError(i)},0);return}typeof document<"u"&&(this._index=g.requestsCount++,g.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=Be,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete g.requests[this._index],this._xhr=null}}_onLoad(){const e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}g.requestsCount=0;g.requests={};if(typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",X);else if(typeof addEventListener=="function"){const n="onpagehide"in p?"pagehide":"unload";addEventListener(n,X,!1)}}function X(){for(let n in g.requests)g.requests.hasOwnProperty(n)&&g.requests[n].abort()}const Ne=function(){const n=oe({xdomain:!1});return n&&n.responseType!==null}();class Le extends xe{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=Ne&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new g(oe,this.uri(),e)}}function oe(n){const e=n.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||Ce))return new XMLHttpRequest}catch{}if(!e)try{return new p[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const ae=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class Pe extends K{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,s=ae?{}:ne(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,s)}catch(i){return this.emitReserved("error",i)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],i=t===e.length-1;M(s,this.supportsBinary,r=>{try{this.doWrite(s,r)}catch{}i&&B(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=ie()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const P=p.WebSocket||p.MozWebSocket;class qe extends Pe{createSocket(e,t,s){return ae?new P(e,t,s):t?new P(e,t):new P(e)}doWrite(e,t){this.ws.send(t)}}class De extends K{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{const t=me(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=e.readable.pipeThrough(t).getReader(),i=ge();i.readable.pipeTo(e.writable),this._writer=i.writable.getWriter();const r=()=>{s.read().then(({done:a,value:c})=>{a||(this.onPacket(c),r())}).catch(a=>{})};r();const o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],i=t===e.length-1;this._writer.write(s).then(()=>{i&&B(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const Ie={websocket:qe,webtransport:De,polling:Le},Ue=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Fe=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function D(n){if(n.length>8e3)throw"URI too long";const e=n,t=n.indexOf("["),s=n.indexOf("]");t!=-1&&s!=-1&&(n=n.substring(0,t)+n.substring(t,s).replace(/:/g,";")+n.substring(s,n.length));let i=Ue.exec(n||""),r={},o=14;for(;o--;)r[Fe[o]]=i[o]||"";return t!=-1&&s!=-1&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=Ve(r,r.path),r.queryKey=Me(r,r.query),r}function Ve(n,e){const t=/\/{2,9}/g,s=e.replace(t,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&s.splice(0,1),e.slice(-1)=="/"&&s.splice(s.length-1,1),s}function Me(n,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(s,i,r){i&&(t[i]=r)}),t}const I=typeof addEventListener=="function"&&typeof removeEventListener=="function",O=[];I&&addEventListener("offline",()=>{O.forEach(n=>n())},!1);class _ extends u{constructor(e,t){if(super(),this.binaryType=be,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(t=e,e=null),e){const s=D(e);t.hostname=s.host,t.secure=s.protocol==="https"||s.protocol==="wss",t.port=s.port,s.query&&(t.query=s.query)}else t.host&&(t.hostname=D(t.host).host);x(this,t),this.secure=t.secure!=null?t.secure:typeof location<"u"&&location.protocol==="https:",t.hostname&&!t.port&&(t.port=this.secure?"443":"80"),this.hostname=t.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=t.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},t.transports.forEach(s=>{const i=s.prototype.name;this.transports.push(i),this._transportsByName[i]=s}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=Re(this.opts.query)),I&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},O.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=se,t.transport=e,this.id&&(t.sid=this.id);const s=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](s)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}const e=this.opts.rememberUpgrade&&_.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";const t=this.createTransport(e);t.open(),this.setTransport(t)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",_.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const t=new Error("server error");t.code=e.data,this._onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let s=0;s<this.writeBuffer.length;s++){const i=this.writeBuffer[s].data;if(i&&(t+=ke(i)),s>0&&t>this._maxPayload)return this.writeBuffer.slice(0,s);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,B(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,t,s){return this._sendPacket("message",e,t,s),this}send(e,t,s){return this._sendPacket("message",e,t,s),this}_sendPacket(e,t,s,i){if(typeof t=="function"&&(i=t,t=void 0),typeof s=="function"&&(i=s,s=null),this.readyState==="closing"||this.readyState==="closed")return;s=s||{},s.compress=s.compress!==!1;const r={type:e,data:t,options:s};this.emitReserved("packetCreate",r),this.writeBuffer.push(r),i&&this.once("flush",i),this.flush()}close(){const e=()=>{this._onClose("forced close"),this.transport.close()},t=()=>{this.off("upgrade",t),this.off("upgradeError",t),e()},s=()=>{this.once("upgrade",t),this.once("upgradeError",t)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():e()}):this.upgrading?s():e()),this}_onError(e){if(_.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),I&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const s=O.indexOf(this._offlineEventListener);s!==-1&&O.splice(s,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}_.protocol=se;class He extends _{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e<this._upgrades.length;e++)this._probe(this._upgrades[e])}_probe(e){let t=this.createTransport(e),s=!1;_.priorWebsocketSuccess=!1;const i=()=>{s||(t.send([{type:"ping",data:"probe"}]),t.once("packet",d=>{if(!s)if(d.type==="pong"&&d.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",t),!t)return;_.priorWebsocketSuccess=t.name==="websocket",this.transport.pause(()=>{s||this.readyState!=="closed"&&(f(),this.setTransport(t),t.send([{type:"upgrade"}]),this.emitReserved("upgrade",t),t=null,this.upgrading=!1,this.flush())})}else{const b=new Error("probe error");b.transport=t.name,this.emitReserved("upgradeError",b)}}))};function r(){s||(s=!0,f(),t.close(),t=null)}const o=d=>{const b=new Error("probe error: "+d);b.transport=t.name,r(),this.emitReserved("upgradeError",b)};function a(){o("transport closed")}function c(){o("socket closed")}function l(d){t&&d.name!==t.name&&r()}const f=()=>{t.removeListener("open",i),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",l)};t.once("open",i),t.once("error",o),t.once("close",a),this.once("close",c),this.once("upgrading",l),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{s||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){const t=[];for(let s=0;s<e.length;s++)~this.transports.indexOf(e[s])&&t.push(e[s]);return t}}let Ke=class extends He{constructor(e,t={}){const s=typeof e=="object"?e:t;(!s.transports||s.transports&&typeof s.transports[0]=="string")&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(i=>Ie[i]).filter(i=>!!i)),super(e,s)}};function We(n,e="",t){let s=n;t=t||typeof location<"u"&&location,n==null&&(n=t.protocol+"//"+t.host),typeof n=="string"&&(n.charAt(0)==="/"&&(n.charAt(1)==="/"?n=t.protocol+n:n=t.host+n),/^(https?|wss?):\/\//.test(n)||(typeof t<"u"?n=t.protocol+"//"+n:n="https://"+n),s=D(n)),s.port||(/^(http|ws)$/.test(s.protocol)?s.port="80":/^(http|ws)s$/.test(s.protocol)&&(s.port="443")),s.path=s.path||"/";const r=s.host.indexOf(":")!==-1?"["+s.host+"]":s.host;return s.id=s.protocol+"://"+r+":"+s.port+e,s.href=s.protocol+"://"+r+(t&&t.port===s.port?"":":"+s.port),s}const $e=typeof ArrayBuffer=="function",Ye=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n.buffer instanceof ArrayBuffer,ce=Object.prototype.toString,ze=typeof Blob=="function"||typeof Blob<"u"&&ce.call(Blob)==="[object BlobConstructor]",Je=typeof File=="function"||typeof File<"u"&&ce.call(File)==="[object FileConstructor]";function W(n){return $e&&(n instanceof ArrayBuffer||Ye(n))||ze&&n instanceof Blob||Je&&n instanceof File}function S(n,e){if(!n||typeof n!="object")return!1;if(Array.isArray(n)){for(let t=0,s=n.length;t<s;t++)if(S(n[t]))return!0;return!1}if(W(n))return!0;if(n.toJSON&&typeof n.toJSON=="function"&&arguments.length===1)return S(n.toJSON(),!0);for(const t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&S(n[t]))return!0;return!1}function Xe(n){const e=[],t=n.data,s=n;return s.data=U(t,e),s.attachments=e.length,{packet:s,buffers:e}}function U(n,e){if(!n)return n;if(W(n)){const t={_placeholder:!0,num:e.length};return e.push(n),t}else if(Array.isArray(n)){const t=new Array(n.length);for(let s=0;s<n.length;s++)t[s]=U(n[s],e);return t}else if(typeof n=="object"&&!(n instanceof Date)){const t={};for(const s in n)Object.prototype.hasOwnProperty.call(n,s)&&(t[s]=U(n[s],e));return t}return n}function Qe(n,e){return n.data=F(n.data,e),delete n.attachments,n}function F(n,e){if(!n)return n;if(n&&n._placeholder===!0){if(typeof n.num=="number"&&n.num>=0&&n.num<e.length)return e[n.num];throw new Error("illegal attachments")}else if(Array.isArray(n))for(let t=0;t<n.length;t++)n[t]=F(n[t],e);else if(typeof n=="object")for(const t in n)Object.prototype.hasOwnProperty.call(n,t)&&(n[t]=F(n[t],e));return n}const je=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var h;(function(n){n[n.CONNECT=0]="CONNECT",n[n.DISCONNECT=1]="DISCONNECT",n[n.EVENT=2]="EVENT",n[n.ACK=3]="ACK",n[n.CONNECT_ERROR=4]="CONNECT_ERROR",n[n.BINARY_EVENT=5]="BINARY_EVENT",n[n.BINARY_ACK=6]="BINARY_ACK"})(h||(h={}));class Ge{constructor(e){this.replacer=e}encode(e){return(e.type===h.EVENT||e.type===h.ACK)&&S(e)?this.encodeAsBinary({type:e.type===h.EVENT?h.BINARY_EVENT:h.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===h.BINARY_EVENT||e.type===h.BINARY_ACK)&&(t+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(t+=e.nsp+","),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){const t=Xe(e),s=this.encodeAsString(t.packet),i=t.buffers;return i.unshift(s),i}}class $ extends u{constructor(e){super(),this.reviver=e}add(e){let t;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");t=this.decodeString(e);const s=t.type===h.BINARY_EVENT;s||t.type===h.BINARY_ACK?(t.type=s?h.EVENT:h.ACK,this.reconstructor=new Ze(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(W(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved("decoded",t));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let t=0;const s={type:Number(e.charAt(0))};if(h[s.type]===void 0)throw new Error("unknown packet type "+s.type);if(s.type===h.BINARY_EVENT||s.type===h.BINARY_ACK){const r=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(r,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");s.attachments=Number(o)}if(e.charAt(t+1)==="/"){const r=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););s.nsp=e.substring(r,t)}else s.nsp="/";const i=e.charAt(t+1);if(i!==""&&Number(i)==i){const r=t+1;for(;++t;){const o=e.charAt(t);if(o==null||Number(o)!=o){--t;break}if(t===e.length)break}s.id=Number(e.substring(r,t+1))}if(e.charAt(++t)){const r=this.tryParse(e.substr(t));if($.isPayloadValid(s.type,r))s.data=r;else throw new Error("invalid payload")}return s}tryParse(e){try{return JSON.parse(e,this.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case h.CONNECT:return Q(t);case h.DISCONNECT:return t===void 0;case h.CONNECT_ERROR:return typeof t=="string"||Q(t);case h.EVENT:case h.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&je.indexOf(t[0])===-1);case h.ACK:case h.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ze{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){const t=Qe(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}function Q(n){return Object.prototype.toString.call(n)==="[object Object]"}const et=Object.freeze(Object.defineProperty({__proto__:null,Decoder:$,Encoder:Ge,get PacketType(){return h}},Symbol.toStringTag,{value:"Module"}));function y(n,e,t){return n.on(e,t),function(){n.off(e,t)}}const tt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class he extends u{constructor(e,t,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const e=this.io;this.subs=[y(e,"open",this.onopen.bind(this)),y(e,"packet",this.onpacket.bind(this)),y(e,"error",this.onerror.bind(this)),y(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...t){var s,i,r;if(tt.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;const o={type:h.EVENT,data:t};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof t[t.length-1]=="function"){const f=this.ids++,d=t.pop();this._registerAckCallback(f,d),o.id=f}const a=(i=(s=this.io.engine)===null||s===void 0?void 0:s.transport)===null||i===void 0?void 0:i.writable,c=this.connected&&!(!((r=this.io.engine)===null||r===void 0)&&r._hasPingExpired());return this.flags.volatile&&!a||(c?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(e,t){var s;const i=(s=this.flags.timeout)!==null&&s!==void 0?s:this._opts.ackTimeout;if(i===void 0){this.acks[e]=t;return}const r=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let a=0;a<this.sendBuffer.length;a++)this.sendBuffer[a].id===e&&this.sendBuffer.splice(a,1);t.call(this,new Error("operation has timed out"))},i),o=(...a)=>{this.io.clearTimeoutFn(r),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((s,i)=>{const r=(o,a)=>o?i(o):s(a);r.withError=!0,t.push(r),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]=="function"&&(t=e.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((i,...r)=>(this._queue[0],i!==null?s.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(i)):(this._queue.shift(),t&&t(null,...r)),s.pending=!1,this._drainQueue())),this._queue.push(s),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;const t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:h.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(s=>String(s.id)===e)){const s=this.acks[e];delete this.acks[e],s.withError&&s.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case h.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case h.EVENT:case h.BINARY_EVENT:this.onevent(e);break;case h.ACK:case h.BINARY_ACK:this.onack(e);break;case h.DISCONNECT:this.ondisconnect();break;case h.CONNECT_ERROR:this.destroy();const s=new Error(e.data.message);s.data=e.data.data,this.emitReserved("connect_error",s);break}}onevent(e){const t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){const t=this._anyListeners.slice();for(const s of t)s.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){const t=this;let s=!1;return function(...i){s||(s=!0,t.packet({type:h.ACK,id:e,data:i}))}}onack(e){const t=this.acks[e.id];typeof t=="function"&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:h.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){const t=this._anyListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}prependAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}offAnyOutgoing(e){if(!this._anyOutgoingListeners)return this;if(e){const t=this._anyOutgoingListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const t=this._anyOutgoingListeners.slice();for(const s of t)s.apply(this,e.data)}}}function w(n){n=n||{},this.ms=n.min||100,this.max=n.max||1e4,this.factor=n.factor||2,this.jitter=n.jitter>0&&n.jitter<=1?n.jitter:0,this.attempts=0}w.prototype.duration=function(){var n=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*n);n=Math.floor(e*10)&1?n+t:n-t}return Math.min(n,this.max)|0};w.prototype.reset=function(){this.attempts=0};w.prototype.setMin=function(n){this.ms=n};w.prototype.setMax=function(n){this.max=n};w.prototype.setJitter=function(n){this.jitter=n};class V extends u{constructor(e,t){var s;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(t=e,e=void 0),t=t||{},t.path=t.path||"/socket.io",this.opts=t,x(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor((s=t.randomizationFactor)!==null&&s!==void 0?s:.5),this.backoff=new w({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const i=t.parser||et;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)===null||t===void 0||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)===null||t===void 0||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)===null||t===void 0||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new Ke(this.uri,this.opts);const t=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const i=y(t,"open",function(){s.onopen(),e&&e()}),r=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=y(t,"error",r);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{i(),r(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(i),this.subs.push(o),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const e=this.engine;this.subs.push(y(e,"ping",this.onping.bind(this)),y(e,"data",this.ondata.bind(this)),y(e,"error",this.onerror.bind(this)),y(e,"close",this.onclose.bind(this)),y(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(t){this.onclose("parse error",t)}}ondecoded(e){B(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,t){let s=this.nsps[e];return s?this._autoConnect&&!s.active&&s.connect():(s=new he(this,e,t),this.nsps[e]=s),s}_destroy(e){const t=Object.keys(this.nsps);for(const s of t)if(this.nsps[s].active)return;this._close()}_packet(e){const t=this.encoder.encode(e);for(let s=0;s<t.length;s++)this.engine.write(t[s],e.options)}cleanup(){this.subs.forEach(e=>e()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,t){var s;this.cleanup(),(s=this.engine)===null||s===void 0||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const t=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(i=>{i?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",i)):e.onreconnect()}))},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}const v={};function C(n,e){typeof n=="object"&&(e=n,n=void 0),e=e||{};const t=We(n,e.path||"/socket.io"),s=t.source,i=t.id,r=t.path,o=v[i]&&r in v[i].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new V(s,e):(v[i]||(v[i]=new V(s,e)),c=v[i]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(C,{Manager:V,Socket:he,io:C,connect:C});const it=()=>{const[n,e]=E.useState(null),[t,s]=E.useState(!1),i=E.useRef(new Map);E.useEffect(()=>{const o=window.location.origin,a=C(o,{path:"/socket.io",reconnection:!0,withCredentials:!0});e(a),a.on("connect",()=>{console.log("[Socket] Connected to Hub"),s(!0),a.emit("register_dashboard")}),a.on("disconnect",()=>{console.log("[Socket] Disconnected from Hub"),s(!1)});const c=(l,f)=>{const d=i.current.get(l);d&&d.forEach(b=>b(f))};return a.onAny((l,f)=>{c(l,f)}),()=>{a.close()}},[]);const r=E.useCallback((o,a)=>{var c;return i.current.has(o)||i.current.set(o,[]),(c=i.current.get(o))==null||c.push(a),()=>{const l=i.current.get(o);l&&i.current.set(o,l.filter(f=>f!==a))}},[]);return{socket:n,isConnected:t,on:r}};export{it as u};
|
|
1
|
+
import{r as E}from"./index-PtnKslHU.js";const m=Object.create(null);m.open="0";m.close="1";m.ping="2";m.pong="3";m.message="4";m.upgrade="5";m.noop="6";const R=Object.create(null);Object.keys(m).forEach(n=>{R[m[n]]=n});const q={type:"error",data:"parser error"},j=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",G=typeof ArrayBuffer=="function",Z=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n&&n.buffer instanceof ArrayBuffer,M=({type:n,data:e},t,s)=>j&&e instanceof Blob?t?s(e):Y(e,s):G&&(e instanceof ArrayBuffer||Z(e))?t?s(e):Y(new Blob([e]),s):s(m[n]+(e||"")),Y=(n,e)=>{const t=new FileReader;return t.onload=function(){const s=t.result.split(",")[1];e("b"+(s||""))},t.readAsDataURL(n)};function z(n){return n instanceof Uint8Array?n:n instanceof ArrayBuffer?new Uint8Array(n):new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}let N;function ue(n,e){if(j&&n.data instanceof Blob)return n.data.arrayBuffer().then(z).then(e);if(G&&(n.data instanceof ArrayBuffer||Z(n.data)))return e(z(n.data));M(n,!1,t=>{N||(N=new TextEncoder),e(N.encode(t))})}const J="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",k=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let n=0;n<J.length;n++)k[J.charCodeAt(n)]=n;const fe=n=>{let e=n.length*.75,t=n.length,s,i=0,r,o,a,c;n[n.length-1]==="="&&(e--,n[n.length-2]==="="&&e--);const l=new ArrayBuffer(e),f=new Uint8Array(l);for(s=0;s<t;s+=4)r=k[n.charCodeAt(s)],o=k[n.charCodeAt(s+1)],a=k[n.charCodeAt(s+2)],c=k[n.charCodeAt(s+3)],f[i++]=r<<2|o>>4,f[i++]=(o&15)<<4|a>>2,f[i++]=(a&3)<<6|c&63;return l},le=typeof ArrayBuffer=="function",H=(n,e)=>{if(typeof n!="string")return{type:"message",data:ee(n,e)};const t=n.charAt(0);return t==="b"?{type:"message",data:pe(n.substring(1),e)}:R[t]?n.length>1?{type:R[t],data:n.substring(1)}:{type:R[t]}:q},pe=(n,e)=>{if(le){const t=fe(n);return ee(t,e)}else return{base64:!0,data:n}},ee=(n,e)=>{switch(e){case"blob":return n instanceof Blob?n:new Blob([n]);case"arraybuffer":default:return n instanceof ArrayBuffer?n:n.buffer}},te="",de=(n,e)=>{const t=n.length,s=new Array(t);let i=0;n.forEach((r,o)=>{M(r,!1,a=>{s[o]=a,++i===t&&e(s.join(te))})})},ye=(n,e)=>{const t=n.split(te),s=[];for(let i=0;i<t.length;i++){const r=H(t[i],e);if(s.push(r),r.type==="error")break}return s};function ge(){return new TransformStream({transform(n,e){ue(n,t=>{const s=t.length;let i;if(s<126)i=new Uint8Array(1),new DataView(i.buffer).setUint8(0,s);else if(s<65536){i=new Uint8Array(3);const r=new DataView(i.buffer);r.setUint8(0,126),r.setUint16(1,s)}else{i=new Uint8Array(9);const r=new DataView(i.buffer);r.setUint8(0,127),r.setBigUint64(1,BigInt(s))}n.data&&typeof n.data!="string"&&(i[0]|=128),e.enqueue(i),e.enqueue(t)})}})}let L;function A(n){return n.reduce((e,t)=>e+t.length,0)}function T(n,e){if(n[0].length===e)return n.shift();const t=new Uint8Array(e);let s=0;for(let i=0;i<e;i++)t[i]=n[0][s++],s===n[0].length&&(n.shift(),s=0);return n.length&&s<n[0].length&&(n[0]=n[0].slice(s)),t}function me(n,e){L||(L=new TextDecoder);const t=[];let s=0,i=-1,r=!1;return new TransformStream({transform(o,a){for(t.push(o);;){if(s===0){if(A(t)<1)break;const c=T(t,1);r=(c[0]&128)===128,i=c[0]&127,i<126?s=3:i===126?s=1:s=2}else if(s===1){if(A(t)<2)break;const c=T(t,2);i=new DataView(c.buffer,c.byteOffset,c.length).getUint16(0),s=3}else if(s===2){if(A(t)<8)break;const c=T(t,8),l=new DataView(c.buffer,c.byteOffset,c.length),f=l.getUint32(0);if(f>Math.pow(2,21)-1){a.enqueue(q);break}i=f*Math.pow(2,32)+l.getUint32(4),s=3}else{if(A(t)<i)break;const c=T(t,i);a.enqueue(H(r?c:L.decode(c),e)),s=0}if(i===0||i>n){a.enqueue(q);break}}}})}const se=4;function u(n){if(n)return _e(n)}function _e(n){for(var e in u.prototype)n[e]=u.prototype[e];return n}u.prototype.on=u.prototype.addEventListener=function(n,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+n]=this._callbacks["$"+n]||[]).push(e),this};u.prototype.once=function(n,e){function t(){this.off(n,t),e.apply(this,arguments)}return t.fn=e,this.on(n,t),this};u.prototype.off=u.prototype.removeListener=u.prototype.removeAllListeners=u.prototype.removeEventListener=function(n,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var t=this._callbacks["$"+n];if(!t)return this;if(arguments.length==1)return delete this._callbacks["$"+n],this;for(var s,i=0;i<t.length;i++)if(s=t[i],s===e||s.fn===e){t.splice(i,1);break}return t.length===0&&delete this._callbacks["$"+n],this};u.prototype.emit=function(n){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),t=this._callbacks["$"+n],s=1;s<arguments.length;s++)e[s-1]=arguments[s];if(t){t=t.slice(0);for(var s=0,i=t.length;s<i;++s)t[s].apply(this,e)}return this};u.prototype.emitReserved=u.prototype.emit;u.prototype.listeners=function(n){return this._callbacks=this._callbacks||{},this._callbacks["$"+n]||[]};u.prototype.hasListeners=function(n){return!!this.listeners(n).length};const B=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,t)=>t(e,0),p=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),be="arraybuffer";function ne(n,...e){return e.reduce((t,s)=>(n.hasOwnProperty(s)&&(t[s]=n[s]),t),{})}const we=p.setTimeout,Ee=p.clearTimeout;function x(n,e){e.useNativeTimers?(n.setTimeoutFn=we.bind(p),n.clearTimeoutFn=Ee.bind(p)):(n.setTimeoutFn=p.setTimeout.bind(p),n.clearTimeoutFn=p.clearTimeout.bind(p))}const ve=1.33;function ke(n){return typeof n=="string"?Ae(n):Math.ceil((n.byteLength||n.size)*ve)}function Ae(n){let e=0,t=0;for(let s=0,i=n.length;s<i;s++)e=n.charCodeAt(s),e<128?t+=1:e<2048?t+=2:e<55296||e>=57344?t+=3:(s++,t+=4);return t}function ie(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}function Te(n){let e="";for(let t in n)n.hasOwnProperty(t)&&(e.length&&(e+="&"),e+=encodeURIComponent(t)+"="+encodeURIComponent(n[t]));return e}function Re(n){let e={},t=n.split("&");for(let s=0,i=t.length;s<i;s++){let r=t[s].split("=");e[decodeURIComponent(r[0])]=decodeURIComponent(r[1])}return e}class Oe extends Error{constructor(e,t,s){super(e),this.description=t,this.context=s,this.type="TransportError"}}class K extends u{constructor(e){super(),this.writable=!1,x(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,t,s){return super.emitReserved("error",new Oe(e,t,s)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){const t=H(e,this.socket.binaryType);this.onPacket(t)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,t={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(t)}_hostname(){const e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){const t=Te(e);return t.length?"?"+t:""}}class Se extends K{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";const t=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let s=0;this._polling&&(s++,this.once("pollComplete",function(){--s||t()})),this.writable||(s++,this.once("drain",function(){--s||t()}))}else t()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){const t=s=>{if(this.readyState==="opening"&&s.type==="open"&&this.onOpen(),s.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(s)};ye(e,this.socket.binaryType).forEach(t),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){const e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,de(e,t=>{this.doWrite(t,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){const e=this.opts.secure?"https":"http",t=this.query||{};return this.opts.timestampRequests!==!1&&(t[this.opts.timestampParam]=ie()),!this.supportsBinary&&!t.sid&&(t.b64=1),this.createUri(e,t)}}let re=!1;try{re=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}const Ce=re;function Be(){}class xe extends Se{constructor(e){if(super(e),typeof location<"u"){const t=location.protocol==="https:";let s=location.port;s||(s=t?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||s!==e.port}}doWrite(e,t){const s=this.request({method:"POST",data:e});s.on("success",t),s.on("error",(i,r)=>{this.onError("xhr post error",i,r)})}doPoll(){const e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(t,s)=>{this.onError("xhr poll error",t,s)}),this.pollXhr=e}}class g extends u{constructor(e,t,s){super(),this.createRequest=e,x(this,s),this._opts=s,this._method=s.method||"GET",this._uri=t,this._data=s.data!==void 0?s.data:null,this._create()}_create(){var e;const t=ne(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");t.xdomain=!!this._opts.xd;const s=this._xhr=this.createRequest(t);try{s.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){s.setDisableHeaderCheck&&s.setDisableHeaderCheck(!0);for(let i in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(i)&&s.setRequestHeader(i,this._opts.extraHeaders[i])}}catch{}if(this._method==="POST")try{s.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{s.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(s),"withCredentials"in s&&(s.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(s.timeout=this._opts.requestTimeout),s.onreadystatechange=()=>{var i;s.readyState===3&&((i=this._opts.cookieJar)===null||i===void 0||i.parseCookies(s.getResponseHeader("set-cookie"))),s.readyState===4&&(s.status===200||s.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof s.status=="number"?s.status:0)},0))},s.send(this._data)}catch(i){this.setTimeoutFn(()=>{this._onError(i)},0);return}typeof document<"u"&&(this._index=g.requestsCount++,g.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=Be,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete g.requests[this._index],this._xhr=null}}_onLoad(){const e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}}g.requestsCount=0;g.requests={};if(typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",X);else if(typeof addEventListener=="function"){const n="onpagehide"in p?"pagehide":"unload";addEventListener(n,X,!1)}}function X(){for(let n in g.requests)g.requests.hasOwnProperty(n)&&g.requests[n].abort()}const Ne=function(){const n=oe({xdomain:!1});return n&&n.responseType!==null}();class Le extends xe{constructor(e){super(e);const t=e&&e.forceBase64;this.supportsBinary=Ne&&!t}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new g(oe,this.uri(),e)}}function oe(n){const e=n.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||Ce))return new XMLHttpRequest}catch{}if(!e)try{return new p[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}const ae=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative";class Pe extends K{get name(){return"websocket"}doOpen(){const e=this.uri(),t=this.opts.protocols,s=ae?{}:ne(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(s.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,t,s)}catch(i){return this.emitReserved("error",i)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],i=t===e.length-1;M(s,this.supportsBinary,r=>{try{this.doWrite(s,r)}catch{}i&&B(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){const e=this.opts.secure?"wss":"ws",t=this.query||{};return this.opts.timestampRequests&&(t[this.opts.timestampParam]=ie()),this.supportsBinary||(t.b64=1),this.createUri(e,t)}}const P=p.WebSocket||p.MozWebSocket;class qe extends Pe{createSocket(e,t,s){return ae?new P(e,t,s):t?new P(e,t):new P(e)}doWrite(e,t){this.ws.send(t)}}class De extends K{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{const t=me(Number.MAX_SAFE_INTEGER,this.socket.binaryType),s=e.readable.pipeThrough(t).getReader(),i=ge();i.readable.pipeTo(e.writable),this._writer=i.writable.getWriter();const r=()=>{s.read().then(({done:a,value:c})=>{a||(this.onPacket(c),r())}).catch(a=>{})};r();const o={type:"open"};this.query.sid&&(o.data=`{"sid":"${this.query.sid}"}`),this._writer.write(o).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let t=0;t<e.length;t++){const s=e[t],i=t===e.length-1;this._writer.write(s).then(()=>{i&&B(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}const Ie={websocket:qe,webtransport:De,polling:Le},Ue=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Fe=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];function D(n){if(n.length>8e3)throw"URI too long";const e=n,t=n.indexOf("["),s=n.indexOf("]");t!=-1&&s!=-1&&(n=n.substring(0,t)+n.substring(t,s).replace(/:/g,";")+n.substring(s,n.length));let i=Ue.exec(n||""),r={},o=14;for(;o--;)r[Fe[o]]=i[o]||"";return t!=-1&&s!=-1&&(r.source=e,r.host=r.host.substring(1,r.host.length-1).replace(/;/g,":"),r.authority=r.authority.replace("[","").replace("]","").replace(/;/g,":"),r.ipv6uri=!0),r.pathNames=Ve(r,r.path),r.queryKey=Me(r,r.query),r}function Ve(n,e){const t=/\/{2,9}/g,s=e.replace(t,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&s.splice(0,1),e.slice(-1)=="/"&&s.splice(s.length-1,1),s}function Me(n,e){const t={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(s,i,r){i&&(t[i]=r)}),t}const I=typeof addEventListener=="function"&&typeof removeEventListener=="function",O=[];I&&addEventListener("offline",()=>{O.forEach(n=>n())},!1);class _ extends u{constructor(e,t){if(super(),this.binaryType=be,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(t=e,e=null),e){const s=D(e);t.hostname=s.host,t.secure=s.protocol==="https"||s.protocol==="wss",t.port=s.port,s.query&&(t.query=s.query)}else t.host&&(t.hostname=D(t.host).host);x(this,t),this.secure=t.secure!=null?t.secure:typeof location<"u"&&location.protocol==="https:",t.hostname&&!t.port&&(t.port=this.secure?"443":"80"),this.hostname=t.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=t.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},t.transports.forEach(s=>{const i=s.prototype.name;this.transports.push(i),this._transportsByName[i]=s}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},t),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=Re(this.opts.query)),I&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},O.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){const t=Object.assign({},this.opts.query);t.EIO=se,t.transport=e,this.id&&(t.sid=this.id);const s=Object.assign({},this.opts,{query:t,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](s)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}const e=this.opts.rememberUpgrade&&_.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";const t=this.createTransport(e);t.open(),this.setTransport(t)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",t=>this._onClose("transport close",t))}onOpen(){this.readyState="open",_.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":const t=new Error("server error");t.code=e.data,this._onError(t);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);const e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){const e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let t=1;for(let s=0;s<this.writeBuffer.length;s++){const i=this.writeBuffer[s].data;if(i&&(t+=ke(i)),s>0&&t>this._maxPayload)return this.writeBuffer.slice(0,s);t+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;const e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,B(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,t,s){return this._sendPacket("message",e,t,s),this}send(e,t,s){return this._sendPacket("message",e,t,s),this}_sendPacket(e,t,s,i){if(typeof t=="function"&&(i=t,t=void 0),typeof s=="function"&&(i=s,s=null),this.readyState==="closing"||this.readyState==="closed")return;s=s||{},s.compress=s.compress!==!1;const r={type:e,data:t,options:s};this.emitReserved("packetCreate",r),this.writeBuffer.push(r),i&&this.once("flush",i),this.flush()}close(){const e=()=>{this._onClose("forced close"),this.transport.close()},t=()=>{this.off("upgrade",t),this.off("upgradeError",t),e()},s=()=>{this.once("upgrade",t),this.once("upgradeError",t)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?s():e()}):this.upgrading?s():e()),this}_onError(e){if(_.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,t){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),I&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){const s=O.indexOf(this._offlineEventListener);s!==-1&&O.splice(s,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,t),this.writeBuffer=[],this._prevBufferLen=0}}}_.protocol=se;class He extends _{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e<this._upgrades.length;e++)this._probe(this._upgrades[e])}_probe(e){let t=this.createTransport(e),s=!1;_.priorWebsocketSuccess=!1;const i=()=>{s||(t.send([{type:"ping",data:"probe"}]),t.once("packet",d=>{if(!s)if(d.type==="pong"&&d.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",t),!t)return;_.priorWebsocketSuccess=t.name==="websocket",this.transport.pause(()=>{s||this.readyState!=="closed"&&(f(),this.setTransport(t),t.send([{type:"upgrade"}]),this.emitReserved("upgrade",t),t=null,this.upgrading=!1,this.flush())})}else{const b=new Error("probe error");b.transport=t.name,this.emitReserved("upgradeError",b)}}))};function r(){s||(s=!0,f(),t.close(),t=null)}const o=d=>{const b=new Error("probe error: "+d);b.transport=t.name,r(),this.emitReserved("upgradeError",b)};function a(){o("transport closed")}function c(){o("socket closed")}function l(d){t&&d.name!==t.name&&r()}const f=()=>{t.removeListener("open",i),t.removeListener("error",o),t.removeListener("close",a),this.off("close",c),this.off("upgrading",l)};t.once("open",i),t.once("error",o),t.once("close",a),this.once("close",c),this.once("upgrading",l),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{s||t.open()},200):t.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){const t=[];for(let s=0;s<e.length;s++)~this.transports.indexOf(e[s])&&t.push(e[s]);return t}}let Ke=class extends He{constructor(e,t={}){const s=typeof e=="object"?e:t;(!s.transports||s.transports&&typeof s.transports[0]=="string")&&(s.transports=(s.transports||["polling","websocket","webtransport"]).map(i=>Ie[i]).filter(i=>!!i)),super(e,s)}};function We(n,e="",t){let s=n;t=t||typeof location<"u"&&location,n==null&&(n=t.protocol+"//"+t.host),typeof n=="string"&&(n.charAt(0)==="/"&&(n.charAt(1)==="/"?n=t.protocol+n:n=t.host+n),/^(https?|wss?):\/\//.test(n)||(typeof t<"u"?n=t.protocol+"//"+n:n="https://"+n),s=D(n)),s.port||(/^(http|ws)$/.test(s.protocol)?s.port="80":/^(http|ws)s$/.test(s.protocol)&&(s.port="443")),s.path=s.path||"/";const r=s.host.indexOf(":")!==-1?"["+s.host+"]":s.host;return s.id=s.protocol+"://"+r+":"+s.port+e,s.href=s.protocol+"://"+r+(t&&t.port===s.port?"":":"+s.port),s}const $e=typeof ArrayBuffer=="function",Ye=n=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(n):n.buffer instanceof ArrayBuffer,ce=Object.prototype.toString,ze=typeof Blob=="function"||typeof Blob<"u"&&ce.call(Blob)==="[object BlobConstructor]",Je=typeof File=="function"||typeof File<"u"&&ce.call(File)==="[object FileConstructor]";function W(n){return $e&&(n instanceof ArrayBuffer||Ye(n))||ze&&n instanceof Blob||Je&&n instanceof File}function S(n,e){if(!n||typeof n!="object")return!1;if(Array.isArray(n)){for(let t=0,s=n.length;t<s;t++)if(S(n[t]))return!0;return!1}if(W(n))return!0;if(n.toJSON&&typeof n.toJSON=="function"&&arguments.length===1)return S(n.toJSON(),!0);for(const t in n)if(Object.prototype.hasOwnProperty.call(n,t)&&S(n[t]))return!0;return!1}function Xe(n){const e=[],t=n.data,s=n;return s.data=U(t,e),s.attachments=e.length,{packet:s,buffers:e}}function U(n,e){if(!n)return n;if(W(n)){const t={_placeholder:!0,num:e.length};return e.push(n),t}else if(Array.isArray(n)){const t=new Array(n.length);for(let s=0;s<n.length;s++)t[s]=U(n[s],e);return t}else if(typeof n=="object"&&!(n instanceof Date)){const t={};for(const s in n)Object.prototype.hasOwnProperty.call(n,s)&&(t[s]=U(n[s],e));return t}return n}function Qe(n,e){return n.data=F(n.data,e),delete n.attachments,n}function F(n,e){if(!n)return n;if(n&&n._placeholder===!0){if(typeof n.num=="number"&&n.num>=0&&n.num<e.length)return e[n.num];throw new Error("illegal attachments")}else if(Array.isArray(n))for(let t=0;t<n.length;t++)n[t]=F(n[t],e);else if(typeof n=="object")for(const t in n)Object.prototype.hasOwnProperty.call(n,t)&&(n[t]=F(n[t],e));return n}const je=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var h;(function(n){n[n.CONNECT=0]="CONNECT",n[n.DISCONNECT=1]="DISCONNECT",n[n.EVENT=2]="EVENT",n[n.ACK=3]="ACK",n[n.CONNECT_ERROR=4]="CONNECT_ERROR",n[n.BINARY_EVENT=5]="BINARY_EVENT",n[n.BINARY_ACK=6]="BINARY_ACK"})(h||(h={}));class Ge{constructor(e){this.replacer=e}encode(e){return(e.type===h.EVENT||e.type===h.ACK)&&S(e)?this.encodeAsBinary({type:e.type===h.EVENT?h.BINARY_EVENT:h.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let t=""+e.type;return(e.type===h.BINARY_EVENT||e.type===h.BINARY_ACK)&&(t+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(t+=e.nsp+","),e.id!=null&&(t+=e.id),e.data!=null&&(t+=JSON.stringify(e.data,this.replacer)),t}encodeAsBinary(e){const t=Xe(e),s=this.encodeAsString(t.packet),i=t.buffers;return i.unshift(s),i}}class $ extends u{constructor(e){super(),this.reviver=e}add(e){let t;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");t=this.decodeString(e);const s=t.type===h.BINARY_EVENT;s||t.type===h.BINARY_ACK?(t.type=s?h.EVENT:h.ACK,this.reconstructor=new Ze(t),t.attachments===0&&super.emitReserved("decoded",t)):super.emitReserved("decoded",t)}else if(W(e)||e.base64)if(this.reconstructor)t=this.reconstructor.takeBinaryData(e),t&&(this.reconstructor=null,super.emitReserved("decoded",t));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let t=0;const s={type:Number(e.charAt(0))};if(h[s.type]===void 0)throw new Error("unknown packet type "+s.type);if(s.type===h.BINARY_EVENT||s.type===h.BINARY_ACK){const r=t+1;for(;e.charAt(++t)!=="-"&&t!=e.length;);const o=e.substring(r,t);if(o!=Number(o)||e.charAt(t)!=="-")throw new Error("Illegal attachments");s.attachments=Number(o)}if(e.charAt(t+1)==="/"){const r=t+1;for(;++t&&!(e.charAt(t)===","||t===e.length););s.nsp=e.substring(r,t)}else s.nsp="/";const i=e.charAt(t+1);if(i!==""&&Number(i)==i){const r=t+1;for(;++t;){const o=e.charAt(t);if(o==null||Number(o)!=o){--t;break}if(t===e.length)break}s.id=Number(e.substring(r,t+1))}if(e.charAt(++t)){const r=this.tryParse(e.substr(t));if($.isPayloadValid(s.type,r))s.data=r;else throw new Error("invalid payload")}return s}tryParse(e){try{return JSON.parse(e,this.reviver)}catch{return!1}}static isPayloadValid(e,t){switch(e){case h.CONNECT:return Q(t);case h.DISCONNECT:return t===void 0;case h.CONNECT_ERROR:return typeof t=="string"||Q(t);case h.EVENT:case h.BINARY_EVENT:return Array.isArray(t)&&(typeof t[0]=="number"||typeof t[0]=="string"&&je.indexOf(t[0])===-1);case h.ACK:case h.BINARY_ACK:return Array.isArray(t)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class Ze{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){const t=Qe(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}function Q(n){return Object.prototype.toString.call(n)==="[object Object]"}const et=Object.freeze(Object.defineProperty({__proto__:null,Decoder:$,Encoder:Ge,get PacketType(){return h}},Symbol.toStringTag,{value:"Module"}));function y(n,e,t){return n.on(e,t),function(){n.off(e,t)}}const tt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1});class he extends u{constructor(e,t,s){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=t,s&&s.auth&&(this.auth=s.auth),this._opts=Object.assign({},s),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;const e=this.io;this.subs=[y(e,"open",this.onopen.bind(this)),y(e,"packet",this.onpacket.bind(this)),y(e,"error",this.onerror.bind(this)),y(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...t){var s,i,r;if(tt.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(t.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(t),this;const o={type:h.EVENT,data:t};if(o.options={},o.options.compress=this.flags.compress!==!1,typeof t[t.length-1]=="function"){const f=this.ids++,d=t.pop();this._registerAckCallback(f,d),o.id=f}const a=(i=(s=this.io.engine)===null||s===void 0?void 0:s.transport)===null||i===void 0?void 0:i.writable,c=this.connected&&!(!((r=this.io.engine)===null||r===void 0)&&r._hasPingExpired());return this.flags.volatile&&!a||(c?(this.notifyOutgoingListeners(o),this.packet(o)):this.sendBuffer.push(o)),this.flags={},this}_registerAckCallback(e,t){var s;const i=(s=this.flags.timeout)!==null&&s!==void 0?s:this._opts.ackTimeout;if(i===void 0){this.acks[e]=t;return}const r=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let a=0;a<this.sendBuffer.length;a++)this.sendBuffer[a].id===e&&this.sendBuffer.splice(a,1);t.call(this,new Error("operation has timed out"))},i),o=(...a)=>{this.io.clearTimeoutFn(r),t.apply(this,a)};o.withError=!0,this.acks[e]=o}emitWithAck(e,...t){return new Promise((s,i)=>{const r=(o,a)=>o?i(o):s(a);r.withError=!0,t.push(r),this.emit(e,...t)})}_addToQueue(e){let t;typeof e[e.length-1]=="function"&&(t=e.pop());const s={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((i,...r)=>(this._queue[0],i!==null?s.tryCount>this._opts.retries&&(this._queue.shift(),t&&t(i)):(this._queue.shift(),t&&t(null,...r)),s.pending=!1,this._drainQueue())),this._queue.push(s),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;const t=this._queue[0];t.pending&&!e||(t.pending=!0,t.tryCount++,this.flags=t.flags,this.emit.apply(this,t.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:h.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,t){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,t),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(s=>String(s.id)===e)){const s=this.acks[e];delete this.acks[e],s.withError&&s.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case h.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case h.EVENT:case h.BINARY_EVENT:this.onevent(e);break;case h.ACK:case h.BINARY_ACK:this.onack(e);break;case h.DISCONNECT:this.ondisconnect();break;case h.CONNECT_ERROR:this.destroy();const s=new Error(e.data.message);s.data=e.data.data,this.emitReserved("connect_error",s);break}}onevent(e){const t=e.data||[];e.id!=null&&t.push(this.ack(e.id)),this.connected?this.emitEvent(t):this.receiveBuffer.push(Object.freeze(t))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){const t=this._anyListeners.slice();for(const s of t)s.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){const t=this;let s=!1;return function(...i){s||(s=!0,t.packet({type:h.ACK,id:e,data:i}))}}onack(e){const t=this.acks[e.id];typeof t=="function"&&(delete this.acks[e.id],t.withError&&e.data.unshift(null),t.apply(this,e.data))}onconnect(e,t){this.id=e,this.recovered=t&&this._pid===t,this._pid=t,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:h.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){const t=this._anyListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyListeners=[];return this}listenersAny(){return this._anyListeners||[]}onAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.push(e),this}prependAnyOutgoing(e){return this._anyOutgoingListeners=this._anyOutgoingListeners||[],this._anyOutgoingListeners.unshift(e),this}offAnyOutgoing(e){if(!this._anyOutgoingListeners)return this;if(e){const t=this._anyOutgoingListeners;for(let s=0;s<t.length;s++)if(e===t[s])return t.splice(s,1),this}else this._anyOutgoingListeners=[];return this}listenersAnyOutgoing(){return this._anyOutgoingListeners||[]}notifyOutgoingListeners(e){if(this._anyOutgoingListeners&&this._anyOutgoingListeners.length){const t=this._anyOutgoingListeners.slice();for(const s of t)s.apply(this,e.data)}}}function w(n){n=n||{},this.ms=n.min||100,this.max=n.max||1e4,this.factor=n.factor||2,this.jitter=n.jitter>0&&n.jitter<=1?n.jitter:0,this.attempts=0}w.prototype.duration=function(){var n=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),t=Math.floor(e*this.jitter*n);n=Math.floor(e*10)&1?n+t:n-t}return Math.min(n,this.max)|0};w.prototype.reset=function(){this.attempts=0};w.prototype.setMin=function(n){this.ms=n};w.prototype.setMax=function(n){this.max=n};w.prototype.setJitter=function(n){this.jitter=n};class V extends u{constructor(e,t){var s;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(t=e,e=void 0),t=t||{},t.path=t.path||"/socket.io",this.opts=t,x(this,t),this.reconnection(t.reconnection!==!1),this.reconnectionAttempts(t.reconnectionAttempts||1/0),this.reconnectionDelay(t.reconnectionDelay||1e3),this.reconnectionDelayMax(t.reconnectionDelayMax||5e3),this.randomizationFactor((s=t.randomizationFactor)!==null&&s!==void 0?s:.5),this.backoff=new w({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(t.timeout==null?2e4:t.timeout),this._readyState="closed",this.uri=e;const i=t.parser||et;this.encoder=new i.Encoder,this.decoder=new i.Decoder,this._autoConnect=t.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var t;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(t=this.backoff)===null||t===void 0||t.setMin(e),this)}randomizationFactor(e){var t;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(t=this.backoff)===null||t===void 0||t.setJitter(e),this)}reconnectionDelayMax(e){var t;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(t=this.backoff)===null||t===void 0||t.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new Ke(this.uri,this.opts);const t=this.engine,s=this;this._readyState="opening",this.skipReconnect=!1;const i=y(t,"open",function(){s.onopen(),e&&e()}),r=a=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",a),e?e(a):this.maybeReconnectOnOpen()},o=y(t,"error",r);if(this._timeout!==!1){const a=this._timeout,c=this.setTimeoutFn(()=>{i(),r(new Error("timeout")),t.close()},a);this.opts.autoUnref&&c.unref(),this.subs.push(()=>{this.clearTimeoutFn(c)})}return this.subs.push(i),this.subs.push(o),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");const e=this.engine;this.subs.push(y(e,"ping",this.onping.bind(this)),y(e,"data",this.ondata.bind(this)),y(e,"error",this.onerror.bind(this)),y(e,"close",this.onclose.bind(this)),y(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(t){this.onclose("parse error",t)}}ondecoded(e){B(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,t){let s=this.nsps[e];return s?this._autoConnect&&!s.active&&s.connect():(s=new he(this,e,t),this.nsps[e]=s),s}_destroy(e){const t=Object.keys(this.nsps);for(const s of t)if(this.nsps[s].active)return;this._close()}_packet(e){const t=this.encoder.encode(e);for(let s=0;s<t.length;s++)this.engine.write(t[s],e.options)}cleanup(){this.subs.forEach(e=>e()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,t){var s;this.cleanup(),(s=this.engine)===null||s===void 0||s.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,t),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;const e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{const t=this.backoff.duration();this._reconnecting=!0;const s=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(i=>{i?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",i)):e.onreconnect()}))},t);this.opts.autoUnref&&s.unref(),this.subs.push(()=>{this.clearTimeoutFn(s)})}}onreconnect(){const e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}const v={};function C(n,e){typeof n=="object"&&(e=n,n=void 0),e=e||{};const t=We(n,e.path||"/socket.io"),s=t.source,i=t.id,r=t.path,o=v[i]&&r in v[i].nsps,a=e.forceNew||e["force new connection"]||e.multiplex===!1||o;let c;return a?c=new V(s,e):(v[i]||(v[i]=new V(s,e)),c=v[i]),t.query&&!e.query&&(e.query=t.queryKey),c.socket(t.path,e)}Object.assign(C,{Manager:V,Socket:he,io:C,connect:C});const it=()=>{const[n,e]=E.useState(null),[t,s]=E.useState(!1),i=E.useRef(new Map);E.useEffect(()=>{const o=window.location.origin,a=C(o,{path:"/socket.io",reconnection:!0,withCredentials:!0});e(a),a.on("connect",()=>{console.log("[Socket] Connected to Hub"),s(!0),a.emit("register_dashboard")}),a.on("disconnect",()=>{console.log("[Socket] Disconnected from Hub"),s(!1)});const c=(l,f)=>{const d=i.current.get(l);d&&d.forEach(b=>b(f))};return a.onAny((l,f)=>{c(l,f)}),()=>{a.close()}},[]);const r=E.useCallback((o,a)=>{var c;return i.current.has(o)||i.current.set(o,[]),(c=i.current.get(o))==null||c.push(a),()=>{const l=i.current.get(o);l&&i.current.set(o,l.filter(f=>f!==a))}},[]);return{socket:n,isConnected:t,on:r}};export{it as u};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{g,b as w,r as s,j as e,z as S,f as E}from"./index-PtnKslHU.js";import{l as k,d as M,c as C,u as R}from"./users-cwrwUhwo.js";import{f as A}from"./time-B8FIgwPE.js";import{P as I}from"./page-header-CSvuGbSO.js";import{P}from"./plus-vJJF9g79.js";import{T as D}from"./trash-2-BrTSfFh5.js";/**
|
|
2
|
+
* @license lucide-react v0.555.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const U=[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]],z=g("key-round",U);/**
|
|
7
|
+
* @license lucide-react v0.555.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const B=[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]],L=g("square-pen",B),N={SUPER_ADMIN:"Super Admin",ADMIN:"Admin",MEMBER:"Member"};function O(){const{me:r}=w(),[v,p]=s.useState([]),[c,f]=s.useState(!0),[n,j]=s.useState(null),[u,b]=s.useState(!1),[m,o]=s.useState(null),[i,x]=s.useState(null);async function h(){f(!0),j(null);try{p(await k())}catch(t){j(t.message||"Failed to load")}finally{f(!1)}}s.useEffect(()=>{h()},[]);async function l(t){if(confirm(`Delete ${t.email}? This cannot be undone.`))try{await M(t.id),p(d=>d.filter(y=>y.id!==t.id))}catch(d){alert(d.message)}}async function a(t){if(confirm(`Send a password-reset link to ${t.email}?`))try{await E(t.email),alert(`Reset link sent (or logged) for ${t.email}.`)}catch(d){alert(d.message)}}return e.jsxs("div",{children:[e.jsx(I,{icon:S,title:"Users",subtitle:"Dashboard accounts, roles, and access status.",action:e.jsxs("button",{type:"button",className:"page-header-action",onClick:()=>b(!0),children:[e.jsx(P,{size:16}),e.jsx("span",{children:"Invite user"})]})}),e.jsxs("div",{className:"px-6 py-6",children:[n&&e.jsx("div",{className:"text-sm text-[var(--red)] mb-4",children:n}),c?e.jsx("div",{className:"text-sm text-[var(--text-dim)]",children:"Loading…"}):v.length===0?e.jsx("div",{className:"text-sm text-[var(--text-dim)] py-8 text-center border border-dashed border-[var(--border)] rounded-md",children:"No users to show — invite the first one above."}):e.jsx("div",{className:"rounded-lg border border-[var(--border)] bg-[var(--surface)] overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-[11px] text-[var(--text-dim)] uppercase tracking-wide",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left py-2.5 px-4",children:"Name"}),e.jsx("th",{className:"text-left py-2.5 px-4",children:"Email"}),e.jsx("th",{className:"text-left py-2.5 px-4",children:"Role"}),e.jsx("th",{className:"text-left py-2.5 px-4",children:"Status"}),e.jsx("th",{className:"text-left py-2.5 px-4",children:"Last Login"}),e.jsx("th",{className:"w-px"})]})}),e.jsx("tbody",{children:v.map(t=>{const d=(r==null?void 0:r.userId)===t.id;return e.jsxs("tr",{className:"border-t border-[var(--border)]",children:[e.jsx("td",{className:"py-2.5 px-4",children:t.name}),e.jsx("td",{className:"py-2.5 px-4 text-[var(--text-muted)]",children:t.email}),e.jsx("td",{className:"py-2.5 px-4",children:N[t.role]}),e.jsx("td",{className:"py-2.5 px-4",children:t.status==="ACTIVE"?e.jsx("span",{className:"text-[var(--green)]",children:"Active"}):e.jsx("span",{className:"text-[var(--text-dim)]",children:"Inactive"})}),e.jsx("td",{className:"py-2.5 px-4 text-[var(--text-muted)]",children:A(t.lastLoginAt)}),e.jsx("td",{className:"py-2.5 px-4",children:e.jsxs("div",{className:"flex items-center justify-end gap-2 whitespace-nowrap",children:[e.jsx("button",{onClick:()=>o(t),disabled:d,title:d?"Use a different super-admin to manage your own account":"Edit","aria-label":"Edit user",className:"text-[var(--text-dim)] hover:text-[var(--text)] disabled:opacity-30",children:e.jsx(L,{size:14})}),e.jsx("button",{onClick:()=>a(t),title:"Send password-reset link","aria-label":"Send password-reset link",className:"text-[var(--text-dim)] hover:text-[var(--text)]",children:e.jsx(z,{size:14})}),e.jsx("button",{onClick:()=>l(t),disabled:d,title:d?"Use a different super-admin to manage your own account":"Delete","aria-label":"Delete user",className:"text-[var(--red)] hover:opacity-80 disabled:opacity-30",children:e.jsx(D,{size:14})})]})})]},t.id)})})]})})]}),u&&e.jsx(_,{onClose:()=>b(!1),onCreated:t=>{b(!1),t.temporaryPassword&&x({email:t.email,password:t.temporaryPassword}),h()},callerRole:(r==null?void 0:r.role)??"MEMBER"}),m&&e.jsx(T,{user:m,onClose:()=>o(null),onSaved:()=>{o(null),h()}}),i&&e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("div",{className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-base font-semibold mb-2",children:"User created"}),e.jsxs("p",{className:"text-xs text-[var(--text-dim)] mb-3",children:["Temporary password for ",i.email,". Copy now — it will not be shown again."]}),e.jsx("code",{className:"block break-all px-3 py-2 rounded bg-[var(--surface)] border border-[var(--border)] text-xs mb-3",children:i.password}),e.jsx("div",{className:"flex justify-end",children:e.jsx("button",{onClick:()=>x(null),className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium",children:"Done"})})]})})]})}function _({onClose:r,onCreated:v,callerRole:p}){const[c,f]=s.useState(""),[n,j]=s.useState(""),[u,b]=s.useState("MEMBER"),[m,o]=s.useState(!1),[i,x]=s.useState(null),h=p==="SUPER_ADMIN"?["SUPER_ADMIN","ADMIN","MEMBER"]:["MEMBER"];async function l(a){a.preventDefault(),o(!0),x(null);try{const t=await C({email:c,name:n,role:u});v({email:t.email,temporaryPassword:t.temporaryPassword})}catch(t){x(t.message)}finally{o(!1)}}return e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("form",{onSubmit:l,className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Invite User"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Email"}),e.jsx("input",{type:"email",value:c,onChange:a=>f(a.target.value),autoFocus:!0,required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Name"}),e.jsx("input",{value:n,onChange:a=>j(a.target.value),required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Role"}),e.jsx("select",{value:u,onChange:a=>b(a.target.value),className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:h.map(a=>e.jsx("option",{value:a,children:N[a]},a))}),i&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-2",children:i}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:r,className:"h-9 px-3 rounded-md border border-[var(--border)] text-sm",children:"Cancel"}),e.jsx("button",{type:"submit",disabled:m||!c||!n,className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium disabled:opacity-50",children:m?"Creating…":"Create"})]})]})})}function T({user:r,onClose:v,onSaved:p}){const[c,f]=s.useState(r.name),[n,j]=s.useState(r.role),[u,b]=s.useState(r.status),[m,o]=s.useState(!1),[i,x]=s.useState(null);async function h(l){l.preventDefault(),o(!0),x(null);try{await R(r.id,{name:c,role:n,status:u}),p()}catch(a){x(a.message)}finally{o(!1)}}return e.jsx("div",{className:"fixed inset-0 z-30 bg-black/50 flex items-center justify-center",role:"dialog",children:e.jsxs("form",{onSubmit:h,className:"bg-[var(--bg)] border border-[var(--border)] rounded-lg w-full max-w-md p-6",children:[e.jsxs("h3",{className:"text-lg font-semibold mb-4",children:["Edit User — ",r.email]}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Name"}),e.jsx("input",{value:c,onChange:l=>f(l.target.value),required:!0,className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm"}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Role"}),e.jsxs("select",{value:n,onChange:l=>j(l.target.value),className:"w-full mb-3 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:[e.jsx("option",{value:"SUPER_ADMIN",children:"Super Admin"}),e.jsx("option",{value:"ADMIN",children:"Admin"}),e.jsx("option",{value:"MEMBER",children:"Member"})]}),e.jsx("label",{className:"block text-xs text-[var(--text-dim)] mb-1",children:"Status"}),e.jsxs("select",{value:u,onChange:l=>b(l.target.value),className:"w-full mb-4 h-10 px-3 rounded-md bg-[var(--surface)] border border-[var(--border)] text-sm",children:[e.jsx("option",{value:"ACTIVE",children:"Active"}),e.jsx("option",{value:"INACTIVE",children:"Inactive"})]}),i&&e.jsx("div",{className:"text-xs text-[var(--red)] mb-2",children:i}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:v,className:"h-9 px-3 rounded-md border border-[var(--border)] text-sm",children:"Cancel"}),e.jsx("button",{type:"submit",disabled:m,className:"h-9 px-4 rounded-md bg-[var(--green)] text-black text-sm font-medium disabled:opacity-50",children:m?"Saving…":"Save"})]})]})})}export{O as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{m as P,r,X as c,j as e,x as u,v as b,C as U,H as D}from"./index-PtnKslHU.js";/* empty css */import{F as S}from"./FieldGroup-C5UkCHbe.js";import{P as H}from"./page-header-CSvuGbSO.js";import{T as O}from"./trash-2-BrTSfFh5.js";import{P as x}from"./plus-vJJF9g79.js";import{C as V}from"./circle-x-De3thbcr.js";import{C as B}from"./circle-check-CI2xUlDo.js";import{Z as I}from"./zap-JUbOoK3o.js";import{A as X}from"./activity-DCBAvxuo.js";const C=[{id:"device_offline",label:"Device Offline",icon:U,tone:"red"},{id:"device_new",label:"New Device",icon:x,tone:"green"},{id:"session_failed",label:"Session Failed",icon:V,tone:"amber"},{id:"selector_health_digest",label:"Selector Health Digest",icon:D,tone:"green"}],J=["udid","host","name","sessionId","failureReason","eventType","platform"],ae=()=>{const{toast:o}=P(),[g,T]=r.useState([]),[A,w]=r.useState(!0),[l,j]=r.useState(""),[d,k]=r.useState(["device_offline","session_failed"]),[h,f]=r.useState(!1),[v,N]=r.useState(!1),[n,_]=r.useState(!1),[y,m]=r.useState("");r.useEffect(()=>{p()},[]);const p=async()=>{w(!0);try{const s=await c.getWebhookConfigs();T(s||[])}catch(s){console.error("Failed to load webhook configs",s),o("Failed to load webhooks.","error")}finally{w(!1)}},z=async()=>{if(!l.trim()){o("Webhook URL is required.","error");return}if(d.length===0){o("Select at least one trigger event.","error");return}f(!0);try{await c.addWebhookConfig(l.trim(),d,"slack",y||void 0),j(""),m(""),_(!1),k(["device_offline","session_failed"]),await p(),o("Webhook saved.","success")}catch(s){console.error("Failed to add webhook",s),o(`Failed to add webhook: ${s.message||"unknown error"}`,"error")}finally{f(!1)}},E=async(s,t)=>{if(window.confirm(`Remove webhook for "${t}"?`))try{await c.deleteWebhookConfig(s),await p(),o("Webhook removed.","success")}catch(a){console.error("Failed to delete webhook",a),o(`Failed to delete: ${a.message||"unknown error"}`,"error")}},L=async()=>{if(l.trim()){N(!0);try{await c.testWebhook(l.trim(),"slack"),o("Test payload delivered.","success")}catch(s){o(`Test failed: ${s.message||"check the URL"}`,"error")}finally{N(!1)}}},$=s=>{k(t=>t.includes(s)?t.filter(a=>a!==s):[...t,s])},F=s=>{m(t=>t+`{{${s}}} `)};return e.jsxs("div",{className:"settings-container",children:[e.jsx(H,{icon:u,title:"Notifications",subtitle:"Configure Slack or generic webhooks to receive alerts for critical infrastructure events."}),e.jsxs("div",{className:"settings-content",children:[A?e.jsxs("div",{className:"settings-loading",style:{height:200},children:[e.jsx(b,{className:"animate-spin",size:28}),e.jsx("span",{children:"Loading webhooks…"})]}):g.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx("div",{className:"empty-state__icon",children:e.jsx(u,{size:28})}),e.jsx("h3",{className:"empty-state__title",children:"No webhooks configured"}),e.jsx("p",{className:"empty-state__copy",children:"Wire up a Slack incoming webhook or any HTTPS endpoint to receive alerts when devices go offline, new devices register, or sessions fail. Configure your first webhook below."})]}):e.jsx("div",{className:"webhook-list-grid",children:g.map(s=>{const t=(()=>{try{return JSON.parse(s.events)}catch{return[]}})();return e.jsxs("div",{className:"webhook-row-card",children:[e.jsxs("div",{className:"webhook-row-card__header",children:[e.jsx("span",{className:`pill-chip ${s.payloadTemplate?"pill-chip--admin":"pill-chip--scope"}`,children:s.payloadTemplate?"CUSTOM":"SLACK"}),e.jsx("span",{className:"webhook-row-card__url",title:s.url,children:s.url}),e.jsxs("button",{type:"button",className:"row-action row-action--danger",onClick:()=>E(s.id,s.url),"aria-label":`Remove webhook for ${s.url}`,children:[e.jsx(O,{size:13}),e.jsx("span",{children:"Remove"})]})]}),e.jsx("div",{className:"webhook-row-card__events",children:t.length===0?e.jsx("span",{className:"webhook-row-card__no-events",children:"No triggers"}):t.map(a=>{const i=C.find(W=>W.id===a),R=(i==null?void 0:i.icon)??u;return e.jsxs("span",{className:`event-pill event-pill--${(i==null?void 0:i.tone)||"gray"}`,children:[e.jsx(R,{size:11}),(i==null?void 0:i.label)||a]},a)})})]},s.id)})}),e.jsxs("div",{className:"add-webhook-card",children:[e.jsxs("div",{className:"add-webhook-card__header",children:[e.jsx(x,{size:14}),e.jsx("span",{children:"Add a new webhook"})]}),e.jsxs("div",{className:"add-webhook-card__body",children:[e.jsx(S,{label:"Webhook URL",description:"The endpoint we POST webhook events to.",htmlFor:"webhook-url",children:e.jsx("div",{className:"setting-input-wrapper",children:e.jsx("input",{id:"webhook-url",type:"url",placeholder:"https://hooks.slack.com/services/...",value:l,onChange:s=>j(s.target.value)})})}),e.jsx(S,{label:"Trigger Events",children:e.jsx("div",{className:"event-toggle-grid",children:C.map(s=>{const t=d.includes(s.id),a=s.icon;return e.jsxs("button",{type:"button",role:"checkbox","aria-checked":t,className:`event-toggle event-toggle--${s.tone} ${t?"is-selected":""}`,onClick:()=>$(s.id),children:[e.jsx(a,{size:14,className:"event-toggle__lead"}),e.jsx("span",{children:s.label}),t&&e.jsx(B,{size:14,className:"event-toggle__check"})]},s.id)})})}),e.jsxs("div",{className:"template-section",children:[e.jsxs("button",{type:"button",className:"template-section__toggle",onClick:()=>_(!n),"aria-expanded":n,children:[e.jsx(I,{size:14,className:n?"tone-amber":"tone-dim"}),e.jsx("span",{children:"Use custom payload (optional)"}),e.jsx("span",{className:"template-section__indicator",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"template-editor",children:[e.jsx("p",{className:"template-editor__hint",children:"Define a JSON or text template. Click a variable below to insert it."}),e.jsx("div",{className:"template-editor__chips",children:J.map(s=>e.jsx("button",{type:"button",className:"template-editor__chip",onClick:()=>F(s),children:`{{${s}}}`},s))}),e.jsx("textarea",{className:"template-editor__textarea",placeholder:'Example: { "text": "Alert: Device {{udid}} is offline!" }',value:y,onChange:s=>m(s.target.value),rows:4})]})]})]}),e.jsxs("div",{className:"add-webhook-card__footer",children:[e.jsxs("button",{type:"button",className:"page-header-action page-header-action--ghost",onClick:L,disabled:!l.trim()||v,children:[v?e.jsx(b,{size:14,className:"animate-spin"}):e.jsx(X,{size:14}),e.jsx("span",{children:"Test payload"})]}),e.jsxs("button",{type:"button",className:"page-header-action",onClick:z,disabled:h||!l.trim(),children:[h?e.jsx(b,{size:14,className:"animate-spin"}):e.jsx(x,{size:14}),e.jsx("span",{children:h?"Saving…":"Save webhook"})]})]})]})]})]})};export{ae as WebhookSettings};
|