import{C as e,D as t,M as n,N as r,P as i,T as a,U as o,V as s,X as c,_t as l,c as u,f as d,h as f,ht as p,i as m,j as h,k as g,l as _,m as v,o as y,p as b,r as x,s as S,u as C,w,x as T,y as E}from"./runtime-core.esm-bundler-CINEgm0a.js";import{a as D,c as O,i as k,l as A,o as j,r as M,t as N}from"./runtime-dom.esm-bundler-B3VeUO8l.js";import{g as P,h as F,m as I,p as L,t as R,v as z,y as B}from"./api-DSaJA91r.js";import{t as ee}from"./system-BwYDm56e.js";import{t as V}from"./dataService-5Ok9aIVh.js";import{n as H,t as U}from"./TxPowerNoticeModal-DJj923Jw.js";import{t as W}from"./Spinner-CMJUE3iy.js";import{c as G,d as K,r as te,s as q}from"./index-Cijj_ZXo.js";import{t as ne}from"./ConfirmDialog-Dv9g-D0s.js";import{t as re}from"./LocationPicker-DihBA-Pb.js";import{n as ie,t as J}from"./CopyLabel-7zw0wWsl.js";import{c as Y,d as X,n as Z,t as Q}from"./formatters-CHyWlnnq.js";var ae={key:0,class:`fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm`},oe={class:`modal-card max-w-md`},se={class:`flex items-start gap-3 mb-4`},$={class:`mt-1 text-sm text-content-secondary dark:text-content-muted`},ce={class:`modal-actions`},le=[`disabled`],ue=[`disabled`],de=[`disabled`],fe=f({__name:`UnsavedChangesModal`,props:{show:{type:Boolean},isSaving:{type:Boolean},label:{}},emits:[`discard`,`save`,`cancel`],setup(e){return(t,n)=>(a(),u(m,{to:`body`},[v(N,{"enter-active-class":`transition-opacity duration-200`,"enter-from-class":`opacity-0`,"leave-active-class":`transition-opacity duration-200`,"leave-to-class":`opacity-0`},{default:r(()=>[e.show?(a(),C(`div`,ae,[S(`div`,oe,[S(`div`,se,[n[4]||=S(`div`,{class:`flex-shrink-0 w-10 h-10 rounded-full bg-amber-100 dark:bg-amber-900/30 flex items-center justify-center`},[S(`svg`,{class:`w-5 h-5 text-amber-600 dark:text-amber-400`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z`})])],-1),S(`div`,null,[n[3]||=S(`h3`,{class:`text-base font-semibold text-content-primary dark:text-content-primary`},` Unsaved Changes `,-1),S(`p`,$,l(e.label?e.label:`Settings`)+` have not been saved. What would you like to do? `,1)])]),S(`div`,ce,[S(`button`,{onClick:n[0]||=e=>t.$emit(`cancel`),disabled:e.isSaving,class:`modal-btn-cancel`},` Keep Editing `,8,le),S(`button`,{onClick:n[1]||=e=>t.$emit(`discard`),disabled:e.isSaving,class:`modal-btn-danger`},` Discard `,8,ue),S(`button`,{onClick:n[2]||=e=>t.$emit(`save`),disabled:e.isSaving,class:`modal-btn-primary`},l(e.isSaving?`Saving…`:`Save Settings`),9,de)])])])):_(``,!0)]),_:1})]))}});function pe(e,t,n,r){let i=o(!1),a=o(null),s=o(null);L((t,n,r)=>{e.value?(i.value=!0,a.value=()=>r(),s.value=()=>r(!1)):r()});function c(t){e.value?(i.value=!0,a.value=t,s.value=null):t()}function l(){n(),i.value=!1,s.value=null,a.value&&=(a.value(),null)}async function u(){await r()&&(i.value=!1,s.value=null,a.value&&=(a.value(),null))}function d(){i.value=!1,s.value&&=(s.value(),null),a.value=null}return{showUnsavedModal:i,requestLeave:c,handleDiscard:l,handleSave:u,handleCancel:d}}var me={class:`space-y-12`},he={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ge={class:`flex items-center gap-2 shrink-0`},_e=[`disabled`],ve=[`disabled`],ye={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},be={class:`text-red-600 dark:text-red-400 text-sm`},xe={class:`cfg-section space-y-3`},Se={class:`w-full max-w-3xl rounded-3xl border border-stroke-subtle dark:border-white/10 bg-white dark:bg-surface-elevated shadow-[0_20px_80px_color-mix(in_srgb,var(--color-shadow-strong)_35%,transparent)] overflow-hidden`},Ce={class:`flex items-start justify-between gap-3 p-5 border-b border-stroke-subtle dark:border-white/10`},we={class:`p-5`},Te={class:`space-y-2 max-h-[60vh] overflow-y-auto pr-1`},Ee=[`onClick`],De={class:`min-w-0`},Oe={class:`flex flex-wrap items-center gap-2`},ke={class:`text-content-primary dark:text-content-primary font-semibold text-sm truncate`},Ae={key:0,class:`inline-flex items-center rounded-full bg-primary/15 text-primary text-[10px] font-semibold px-2 py-0.5`},je={class:`text-content-secondary dark:text-content-muted text-xs mt-1 line-clamp-2`},Me={class:`flex flex-wrap justify-end gap-2 shrink-0 text-[11px] font-mono`},Ne={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Pe={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Fe={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Ie={class:`rounded-full bg-background-mute dark:bg-black/20 px-2 py-1 text-content-secondary dark:text-content-muted`},Le={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Re={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ze={key:1,class:`flex items-center gap-2`},Be={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Ve={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},He={key:1},Ue=[`value`],We={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Ge={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ke={key:1},qe=[`value`],Je={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Ye={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Xe={key:1,class:`flex items-center gap-2`},Ze={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Qe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$e={key:1},et={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},tt={class:`text-content-primary dark:text-content-primary font-mono text-sm`},nt={class:`cfg-section space-y-3`},rt={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},it={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},at={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ot={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},st={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ct=f({__name:`RadioSettings`,setup(e,{expose:n}){let s=P(),u=ee(),d=V(),f=H(),m=y(()=>u.stats?.config?.radio||{}),g=y(()=>u.stats?.config?.radio?.cad??{}),b=o(!1),w=o(!1),T=o(null),E=o(!1),O=o(``),k=o(!1),M=o(!1),F=o(!1),I=o(0),L=o(0),z=o(0),B=o(0),W=o(0),G=o(0),K=o(0),q=[{value:7.8,label:`7.8 kHz`},{value:10.4,label:`10.4 kHz`},{value:15.6,label:`15.6 kHz`},{value:20.8,label:`20.8 kHz`},{value:31.25,label:`31.25 kHz`},{value:41.7,label:`41.7 kHz`},{value:62.5,label:`62.5 kHz`},{value:125,label:`125 kHz`},{value:250,label:`250 kHz`},{value:500,label:`500 kHz`}];h(m,e=>{e&&!b.value&&(L.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,z.value=e.spreading_factor??0,B.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,W.value=e.tx_power??0,G.value=e.coding_rate??0,K.value=e.preamble_length??0)},{immediate:!0});let ne=y(()=>{let e=m.value.frequency;return e?(e/1e6).toFixed(3)+` MHz`:`Not set`}),re=y(()=>{let e=m.value.bandwidth;return e?(e/1e3).toFixed(1)+` kHz`:`Not set`}),ie=y(()=>{let e=m.value.tx_power;return e===void 0?`Not set`:e+` dBm`}),J=y(()=>{let e=m.value.coding_rate;return e?`4/`+e:`Not set`}),Y=y(()=>{let e=m.value.preamble_length;return e?e+` symbols`:`Not set`}),X=y(()=>m.value.spreading_factor??`Not set`),Z=async()=>{f.radioPresets.length===0&&await f.fetchRadioPresets(),b.value=!0,T.value=null,F.value=!1,I.value=W.value},Q=e=>{L.value=e.frequency?Number(Number(e.frequency).toFixed(3)):0,z.value=e.spreading_factor?Number(e.spreading_factor):0,B.value=e.bandwidth?Number(Number(e.bandwidth).toFixed(1)):0,G.value=e.coding_rate?Number(e.coding_rate):0},ae=e=>e.frequency?`${Number(e.frequency).toFixed(3)} MHz`:`Not set`,oe=e=>e.bandwidth?`${Number(e.bandwidth).toFixed(1)} kHz`:`Not set`,se=e=>e.spreading_factor||`Not set`,$=e=>e.coding_rate?`4/${e.coding_rate}`:`Not set`,ce=()=>{T.value=null;let e=f.radioPresets.find(e=>e.title===O.value);e&&Q(e)};h(O,e=>{!b.value||!e||ce()});let le=e=>{O.value=e;let t=f.radioPresets.find(t=>t.title===e);t&&(Q(t),k.value=!1)},ue=()=>{b.value=!1,T.value=null,O.value=``,k.value=!1,M.value=!1,F.value=!1;let e=m.value;L.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,z.value=e.spreading_factor??0,B.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,W.value=e.tx_power??0,G.value=e.coding_rate??0,K.value=e.preamble_length??0},de=async({silent:e=!1}={})=>{w.value=!0,T.value=null;try{if(W.value<-9||W.value>22)return T.value=`TX Power must be between -9 and +22 dBm for SX1262`,!1;let t={};L.value&&(t.frequency=L.value*1e6),z.value&&(t.spreading_factor=z.value),B.value&&(t.bandwidth=B.value*1e3),(W.value||W.value===0)&&(t.tx_power=W.value),G.value&&(t.coding_rate=G.value);let n=(await R.post(`/update_radio_config`,t)).data;if(n.message||n.persisted)return b.value=!1,F.value=!1,await u.fetchStats(),d.invalidate(`radioConfig`),e||(E.value=!0),!0;n.error?T.value=n.error:T.value=`Unknown response from server`}catch(e){console.error(`Failed to update radio settings:`,e),T.value=e.response?.data?.error||`Failed to update settings`}finally{w.value=!1}return!1},ct=y(()=>W.value!==I.value),lt=async({silent:e=!1}={})=>b.value&&ct.value&&!F.value?(M.value=!0,!1):de({silent:e}),ut=async()=>{F.value&&(M.value=!1,await de())},dt=()=>{M.value=!1,F.value=!1},{showUnsavedModal:ft,requestLeave:pt,handleDiscard:mt,handleSave:ht,handleCancel:gt}=pe(b,w,ue,()=>lt());return n({requestLeave:pt,isEditing:b}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:E.value,"onUpdate:modelValue":n[0]||=e=>E.value=e,title:`Radio Settings Changes require a restart.`,message:`Restart Now?`},null,8,[`modelValue`]),v(fe,{show:c(ft),"is-saving":w.value,label:`Radio Settings`,onDiscard:c(mt),onSave:c(ht),onCancel:c(gt)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),v(U,{show:M.value,confirmed:F.value,busy:w.value,"action-label":`I Understand, Save Changes`,"onUpdate:show":n[1]||=e=>e?M.value=!0:dt(),"onUpdate:confirmed":n[2]||=e=>F.value=e,onConfirm:ut},null,8,[`show`,`confirmed`,`busy`]),S(`div`,me,[S(`div`,he,[n[13]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Radio Settings`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure LoRa radio parameters and frequency presets`)],-1),S(`div`,ge,[b.value?(a(),C(x,{key:1},[S(`button`,{onClick:n[3]||=e=>k.value=!k.value,class:`cfg-btn-secondary`},` Prefill Preset `),S(`button`,{onClick:ue,disabled:w.value,class:`cfg-btn-secondary`},` Cancel `,8,_e),S(`button`,{onClick:n[4]||=e=>lt(),disabled:w.value,class:`cfg-btn-primary`},l(w.value?`Saving...`:`Save Changes`),9,ve)],64)):(a(),C(`button`,{key:0,onClick:Z,class:`cfg-btn-primary`},` Edit Settings `))])]),T.value?(a(),C(`div`,ye,[S(`p`,be,l(T.value),1)])):_(``,!0),S(`div`,xe,[v(N,{name:`fade`},{default:r(()=>[b.value&&k.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`,onClick:n[6]||=A(e=>k.value=!1,[`self`])},[S(`div`,Se,[S(`div`,Ce,[n[14]||=S(`div`,null,[S(`div`,{class:`text-content-primary dark:text-content-primary font-semibold text-base`},` Prefill from preset `),S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mt-1`},` Pick a preset to load its radio values into the form. `)],-1),S(`button`,{type:`button`,class:`cfg-btn-secondary`,onClick:n[5]||=e=>k.value=!1},` Close `)]),S(`div`,we,[S(`div`,Te,[(a(!0),C(x,null,t(c(f).radioPresets,e=>(a(),C(`button`,{key:e.title,type:`button`,onClick:t=>le(e.title),class:p([`w-full text-left rounded-[18px] border px-4 py-3 transition-all duration-200 flex items-center justify-between gap-4`,O.value===e.title?`border-primary/60 bg-primary/10 shadow-sm shadow-primary/10`:`border-stroke-subtle dark:border-white/10 bg-white/60 dark:bg-white/5 hover:border-primary/30 hover:bg-stroke-subtle/60 dark:hover:bg-white/10`])},[S(`div`,De,[S(`div`,Oe,[S(`div`,ke,l(e.title),1),O.value===e.title?(a(),C(`span`,Ae,` Selected `)):_(``,!0)]),S(`div`,je,l(e.description),1)]),S(`div`,Me,[S(`span`,Ne,` Freq `+l(ae(e)),1),S(`span`,Pe,` SF `+l(se(e)),1),S(`span`,Fe,` BW `+l(oe(e)),1),S(`span`,Ie,` CR `+l($(e)),1)])],10,Ee))),128))])])])])):_(``,!0)]),_:1}),S(`div`,Le,[n[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Frequency`,-1),b.value?(a(),C(`div`,ze,[i(S(`input`,{"onUpdate:modelValue":n[7]||=e=>L.value=e,type:`number`,step:`0.001`,min:`100`,max:`1000`,class:`cfg-input w-32`},null,512),[[j,L.value,void 0,{number:!0}]]),n[15]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`MHz`,-1)])):(a(),C(`div`,Re,l(ne.value),1))]),S(`div`,Be,[n[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Spreading Factor`,-1),b.value?(a(),C(`div`,He,[i(S(`select`,{"onUpdate:modelValue":n[8]||=e=>z.value=e,class:`cfg-select`},[(a(),C(x,null,t([5,6,7,8,9,10,11,12],e=>S(`option`,{key:e,value:e},l(e),9,Ue)),64))],512),[[D,z.value,void 0,{number:!0}]])])):(a(),C(`div`,Ve,l(X.value),1))]),S(`div`,We,[n[18]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bandwidth`,-1),b.value?(a(),C(`div`,Ke,[i(S(`select`,{"onUpdate:modelValue":n[9]||=e=>B.value=e,class:`cfg-select`},[(a(),C(x,null,t(q,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,qe)),64))],512),[[D,B.value,void 0,{number:!0}]])])):(a(),C(`div`,Ge,l(re.value),1))]),S(`div`,Je,[n[20]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TX Power`,-1),b.value?(a(),C(`div`,Xe,[i(S(`input`,{"onUpdate:modelValue":n[10]||=e=>W.value=e,type:`number`,min:`-9`,max:`22`,class:`cfg-input w-20`},null,512),[[j,W.value,void 0,{number:!0}]]),n[19]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`dBm`,-1)])):(a(),C(`div`,Ye,l(ie.value),1))]),S(`div`,Ze,[n[22]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Coding Rate`,-1),b.value?(a(),C(`div`,$e,[i(S(`select`,{"onUpdate:modelValue":n[11]||=e=>G.value=e,class:`cfg-select`},[...n[21]||=[S(`option`,{value:5},`4/5`,-1),S(`option`,{value:6},`4/6`,-1),S(`option`,{value:7},`4/7`,-1),S(`option`,{value:8},`4/8`,-1)]],512),[[D,G.value,void 0,{number:!0}]])])):(a(),C(`div`,Qe,l(J.value),1))]),S(`div`,et,[n[23]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Preamble Length`,-1),S(`span`,tt,l(Y.value),1)])]),S(`div`,nt,[S(`div`,rt,[n[24]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`CAD Calibration`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Channel Activity Detection: Run Calibration to update`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mt-1`},`These settings tune the receivers ability to detect channel status prior to transmission`)],-1),S(`button`,{onClick:n[12]||=e=>c(s).push(`/cad-calibration`),class:`cfg-btn-secondary shrink-0`},` Run Calibration `)]),n[27]||=S(`div`,{class:`pt-2`},null,-1),S(`div`,it,[n[25]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Peak Threshold`,-1),S(`span`,at,l(g.value.peak_threshold??`Not calibrated`),1)]),S(`div`,ot,[n[26]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Min Threshold`,-1),S(`span`,st,l(g.value.min_threshold??`Not calibrated`),1)])])])],64))}}),lt={class:`space-y-12`},ut={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},dt={class:`flex items-center gap-2 shrink-0`},ft=[`disabled`],pt=[`disabled`],mt={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},ht={class:`cfg-section space-y-3`},gt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},_t={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},vt={key:1,class:`w-full sm:w-80`},yt=[`value`],bt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},xt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},St={key:1,class:`w-full sm:w-80 space-y-2`},Ct={class:`flex gap-2`},wt=[`disabled`],Tt=[`value`],Et=[`value`],Dt=[`disabled`],Ot=[`value`],kt=[`value`],At=[`disabled`],jt={class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-muted`},Mt={key:2,class:`text-xs text-red-600 dark:text-red-400`},Nt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},Pt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ft={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},It={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},Lt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},Rt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},zt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},Bt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Vt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},Ht={class:`w-full sm:w-96 space-y-2`},Ut={class:`flex gap-2`},Wt=[`value`],Gt=[`disabled`],Kt={key:0,class:`text-xs text-red-600 dark:text-red-400`},qt={class:`grid grid-cols-1 sm:grid-cols-2 gap-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},Jt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Yt={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Xt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Zt={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Qt={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},$t={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},en={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},tn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},nn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},rn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},an={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},on={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},sn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},cn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},ln={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},un={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},dn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},fn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},pn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},mn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},hn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},gn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},_n={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},vn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},yn={key:3,class:`grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm`},bn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},xn={class:`text-content-primary dark:text-content-primary font-mono`},Sn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Cn={class:`text-content-primary dark:text-content-primary font-mono`},wn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Tn={class:`text-content-primary dark:text-content-primary font-mono`},En={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Dn={class:`text-content-primary dark:text-content-primary font-mono`},On={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},kn={class:`text-content-primary dark:text-content-primary font-mono`},An={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},jn={class:`text-content-primary dark:text-content-primary font-mono`},Mn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Nn={class:`text-content-primary dark:text-content-primary font-mono`},Pn={class:`rounded-lg border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5 p-3`},Fn={class:`text-content-primary dark:text-content-primary font-mono`},In={class:`grid grid-cols-1 sm:grid-cols-2 gap-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},Ln={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Rn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},zn={class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},Bn={key:1,class:`block text-content-primary dark:text-content-primary font-mono text-sm mt-1`},Vn=f({__name:`RadioHardwareSettings`,setup(n,{expose:r}){let s=ee(),u=[{value:`sx1262`,label:`sx1262`,detail:`Linux spidev + system GPIO`},{value:`sx1262_ch341`,label:`sx1262_ch341`,detail:`CH341 USB-to-SPI`},{value:`kiss`,label:`kiss`,detail:`KISS-modem over serial`},{value:`pymc_tcp`,label:`pymc_tcp`,detail:`pymc_tcp firmware modem over Wi-Fi/TCP`},{value:`pymc_usb`,label:`pymc_usb`,detail:`pymc_usb firmware modem over USB-CDC`},{value:`none`,label:`none`,detail:`Disable radio hardware (no RF I/O)`}],d=y(()=>{let e=s.stats;if(!e)return{};let t=e.config??{};return{...e,...t}}),f=o(!1),p=o(!1),m=o(``),g=o(!1),w=o(`none`),T=o([]),E=o(!1),O=o(``),k=o(!1),A=o([]),N=o(!1),P=o(``),F=o(``),I=o(``),L=o(9600),z=o(``),B=o(921600),V=o(``),H=o(5055),U=o(``),W=o(0),G=o(0),K=o(21),q=o(18),ne=o(20),re=o(16),ie=o(-1),J=o(-1),Y=o(-1),X=o(``),Z=o(-1),Q=o(-1),ae=o(6790),oe=o(21778);function se(e,t=``){return e==null?t:String(e)}function $(e,t){let n=Number(e);return Number.isFinite(n)?n:t}function ce(e){if(e==null)return`none`;let t=String(e).trim().toLowerCase();return!t||[`none`,`null`,`disabled`,`off`,`no_radio`].includes(t)?`none`:t===`kiss-modem`?`kiss`:t===`sx1262`?`sx1262`:t===`sx1262_ch341`?`sx1262_ch341`:t===`kiss`?`kiss`:t===`pymc_tcp`?`pymc_tcp`:t===`pymc_usb`?`pymc_usb`:`none`}function le(e){let t=e.config?.radio_type;return t==null||t===``?`sx1262`:ce(t)}let ue=y(()=>w.value!==`sx1262`&&w.value!==`sx1262_ch341`?[]:A.value.filter(e=>le(e)===w.value));function de(e){let t=A.value.find(t=>t.key===e);if(!t||!t.config)return;let n=t.config;W.value=$(n.bus_id,W.value),G.value=$(n.cs_id,G.value),K.value=$(n.cs_pin,K.value),q.value=$(n.reset_pin,q.value),ne.value=$(n.busy_pin,ne.value),re.value=$(n.irq_pin,re.value),ie.value=$(n.txen_pin,ie.value),J.value=$(n.rxen_pin,J.value),Y.value=$(n.en_pin,Y.value),Array.isArray(n.en_pins)?X.value=n.en_pins.map(e=>Number(e)).filter(e=>Number.isFinite(e)).join(`, `):X.value=``,Z.value=$(n.txled_pin,Z.value),Q.value=$(n.rxled_pin,Q.value),w.value===`sx1262_ch341`&&(ae.value=$(n.vid,ae.value),oe.value=$(n.pid,oe.value))}h(d,e=>{if(!f.value){w.value=ce(e.radio_type);let t=e.kiss??{},n=e.pymc_usb??{},r=e.pymc_tcp??{},i=e.sx1262??{},a=e.ch341??{};I.value=se(t.port,`/dev/ttyUSB0`),L.value=$(t.baud_rate,9600),z.value=se(n.port,`/dev/ttyACM0`),B.value=$(n.baudrate,921600),V.value=se(r.host,``),H.value=$(r.port,5055),U.value=se(r.token,``),W.value=$(i.bus_id,0),G.value=$(i.cs_id,0),K.value=$(i.cs_pin,21),q.value=$(i.reset_pin,18),ne.value=$(i.busy_pin,20),re.value=$(i.irq_pin,16),ie.value=$(i.txen_pin,-1),J.value=$(i.rxen_pin,-1),Y.value=$(i.en_pin,-1),Array.isArray(i.en_pins)?X.value=i.en_pins.map(e=>Number(e)).filter(e=>Number.isFinite(e)).join(`, `):X.value=``,Z.value=$(i.txled_pin,-1),Q.value=$(i.rxled_pin,-1),ae.value=$(a.vid,6790),oe.value=$(a.pid,21778),F.value=``}},{immediate:!0});let me=y(()=>ce(d.value.radio_type)),he=y(()=>{let e=u.find(e=>e.value===me.value);return e?`${e.label} - ${e.detail}`:`none - Disable radio hardware (no RF I/O)`});function ge(){w.value=me.value,f.value=!0,m.value=``}function _e(){w.value=me.value,f.value=!1,m.value=``,k.value=!1,F.value=``}function ve(e){return e.split(`,`).map(e=>Number(e.trim())).filter(e=>Number.isFinite(e))}async function ye(){N.value=!0,P.value=``;try{let e=await R.get(`hardware_options`),t=e.hardware;if(Array.isArray(t)){A.value=t;return}if(e.success&&Array.isArray(e.data)){A.value=e.data;return}A.value=[],P.value=e.error||`Could not load hardware presets`}catch(e){let t=e;A.value=[],P.value=t.message||`Could not load hardware presets`}finally{N.value=!1}}async function be(){E.value=!0,O.value=``;try{let e=await R.getSerialPorts();e.success&&Array.isArray(e.data)?T.value=e.data:(T.value=[],O.value=e.error||`Could not load USB serial devices`)}catch(e){let t=e;T.value=[],O.value=t.message||`Could not load USB serial devices`}finally{E.value=!1}}async function xe(){p.value=!0,m.value=``;try{if(w.value===`pymc_tcp`&&!V.value.trim())return m.value=`TCP modem host is required for pymc_tcp`,!1;let e={radio_type:w.value===`none`?null:w.value};if(w.value===`kiss`&&(e.kiss={port:I.value.trim()||`/dev/ttyUSB0`,baud_rate:$(L.value,9600)}),w.value===`pymc_usb`&&(e.pymc_usb={port:z.value.trim()||`/dev/ttyACM0`,baudrate:$(B.value,921600)}),w.value===`pymc_tcp`&&(e.pymc_tcp={host:V.value.trim(),port:$(H.value,5055),token:U.value}),w.value===`sx1262`||w.value===`sx1262_ch341`){let t=ve(X.value);e.sx1262={bus_id:$(W.value,0),cs_id:$(G.value,0),cs_pin:$(K.value,21),reset_pin:$(q.value,18),busy_pin:$(ne.value,20),irq_pin:$(re.value,16),txen_pin:$(ie.value,-1),rxen_pin:$(J.value,-1),...t.length>0?{en_pins:t}:{en_pin:$(Y.value,-1)},txled_pin:$(Z.value,-1),rxled_pin:$(Q.value,-1)}}w.value===`sx1262_ch341`&&(e.ch341={vid:$(ae.value,6790),pid:$(oe.value,21778)});let t=await R.importConfig(e);return t.success?(f.value=!1,await s.fetchStats(),g.value=!0,!0):(m.value=t.error||`Failed to save settings`,!1)}catch(e){let t=e;return m.value=t.response?.data?.error||t.message||`Failed to save settings`,!1}finally{p.value=!1}}let Se=y(()=>w.value===`kiss`||w.value===`pymc_usb`),Ce=y(()=>w.value===`pymc_tcp`),we=y(()=>w.value===`sx1262`||w.value===`sx1262_ch341`),Te=y(()=>w.value===`sx1262_ch341`),{showUnsavedModal:Ee,requestLeave:De,handleDiscard:Oe,handleSave:ke,handleCancel:Ae}=pe(f,p,_e,async()=>xe());return r({requestLeave:De,isEditing:f}),e(()=>{be(),ye()}),h([f,w],([e,t])=>{e&&(t===`kiss`||t===`pymc_usb`)&&be(),e&&(t===`sx1262`||t===`sx1262_ch341`)&&ye(),F.value=``},{immediate:!1}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:g.value,"onUpdate:modelValue":n[0]||=e=>g.value=e,title:`Radio Hardware change requires a restart.`,message:`Restart now?`},null,8,[`modelValue`]),v(fe,{show:c(Ee),"is-saving":p.value,label:`Radio Hardware settings`,onDiscard:c(Oe),onSave:c(ke),onCancel:c(Ae)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,lt,[S(`div`,ut,[n[28]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Radio Hardware `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Select which radio hardware backend this repeater should use `)],-1),S(`div`,dt,[f.value?(a(),C(x,{key:1},[S(`button`,{onClick:_e,disabled:p.value,class:`cfg-btn-secondary`},` Cancel `,8,ft),S(`button`,{onClick:xe,disabled:p.value,class:`cfg-btn-primary`},l(p.value?`Saving...`:`Save Changes`),9,pt)],64)):(a(),C(`button`,{key:0,onClick:ge,class:`cfg-btn-primary`},` Edit Settings `))])]),m.value?(a(),C(`div`,mt,l(m.value),1)):_(``,!0),S(`div`,ht,[S(`div`,gt,[n[29]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Radio Type`,-1),f.value?(a(),C(`div`,vt,[i(S(`select`,{"onUpdate:modelValue":n[1]||=e=>w.value=e,class:`cfg-select`},[(a(),C(x,null,t(u,e=>S(`option`,{key:e.value,value:e.value},l(e.label)+` - `+l(e.detail),9,yt)),64))],512),[[D,w.value]])])):(a(),C(`div`,_t,l(he.value),1))]),Se.value?(a(),C(x,{key:0},[S(`div`,bt,[n[31]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Serial Port `,-1),f.value?(a(),C(`div`,St,[S(`div`,Ct,[w.value===`kiss`?i((a(),C(`select`,{key:0,"onUpdate:modelValue":n[2]||=e=>I.value=e,class:`cfg-select flex-1`,disabled:k.value},[I.value&&!T.value.some(e=>e.device===I.value)?(a(),C(`option`,{key:0,value:I.value},l(I.value)+` (current) `,9,Tt)):_(``,!0),(a(!0),C(x,null,t(T.value,e=>(a(),C(`option`,{key:`kiss-${e.device}`,value:e.device},l(e.description||e.device),9,Et))),128))],8,wt)),[[D,I.value]]):i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[3]||=e=>z.value=e,class:`cfg-select flex-1`,disabled:k.value},[z.value&&!T.value.some(e=>e.device===z.value)?(a(),C(`option`,{key:0,value:z.value},l(z.value)+` (current) `,9,Ot)):_(``,!0),(a(!0),C(x,null,t(T.value,e=>(a(),C(`option`,{key:`usb-${e.device}`,value:e.device},l(e.description||e.device),9,kt))),128))],8,Dt)),[[D,z.value]]),S(`button`,{type:`button`,class:`cfg-btn-secondary`,disabled:E.value,onClick:be},l(E.value?`...`:`Refresh`),9,At)]),S(`label`,jt,[i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>k.value=e,type:`checkbox`},null,512),[[M,k.value]]),n[30]||=b(` Enter custom device path `,-1)]),k.value&&w.value===`kiss`?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[5]||=e=>I.value=e,type:`text`,class:`cfg-input`,placeholder:`/dev/ttyUSB0`},null,512)),[[j,I.value]]):_(``,!0),k.value&&w.value!==`kiss`?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[6]||=e=>z.value=e,type:`text`,class:`cfg-input`,placeholder:`/dev/ttyACM0`},null,512)),[[j,z.value]]):_(``,!0),O.value?(a(),C(`p`,Mt,l(O.value),1)):_(``,!0)])):(a(),C(`div`,xt,l(w.value===`kiss`?I.value:z.value),1))]),S(`div`,Nt,[n[32]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Baud Rate `,-1),f.value?(a(),C(x,{key:1},[w.value===`kiss`?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[7]||=e=>L.value=e,type:`number`,min:`1`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,L.value,void 0,{number:!0}]]):i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[8]||=e=>B.value=e,type:`number`,min:`1`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,B.value,void 0,{number:!0}]])],64)):(a(),C(`div`,Pt,l(w.value===`kiss`?L.value:B.value),1))])],64)):_(``,!0),Ce.value?(a(),C(x,{key:1},[S(`div`,Ft,[n[33]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Host`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[9]||=e=>V.value=e,type:`text`,class:`cfg-input w-full sm:w-72`,placeholder:`pymc-3e2834.local`},null,512)),[[j,V.value]]):(a(),C(`div`,It,l(V.value||`Not set`),1))]),S(`div`,Lt,[n[34]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Port`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[10]||=e=>H.value=e,type:`number`,min:`1`,max:`65535`,class:`cfg-input w-full sm:w-40`},null,512)),[[j,H.value,void 0,{number:!0}]]):(a(),C(`div`,Rt,l(H.value),1))]),S(`div`,zt,[n[35]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TCP Token`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[11]||=e=>U.value=e,type:`text`,class:`cfg-input w-full sm:w-72`,placeholder:`Optional`},null,512)),[[j,U.value]]):(a(),C(`div`,Bt,l(U.value?`Configured`:`Not set`),1))])],64)):_(``,!0),we.value&&f.value?(a(),C(x,{key:2},[S(`div`,Vt,[n[38]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Board Preset (Quick Apply)`,-1),S(`div`,Ht,[S(`div`,Ut,[i(S(`select`,{"onUpdate:modelValue":n[12]||=e=>F.value=e,class:`cfg-select flex-1`,onChange:n[13]||=e=>de(F.value)},[n[36]||=S(`option`,{value:``},`Leave current pin values unchanged`,-1),(a(!0),C(x,null,t(ue.value,e=>(a(),C(`option`,{key:e.key,value:e.key},l(e.name||e.key),9,Wt))),128))],544),[[D,F.value]]),S(`button`,{type:`button`,class:`cfg-btn-secondary`,disabled:N.value,onClick:ye},l(N.value?`...`:`Refresh`),9,Gt)]),P.value?(a(),C(`p`,Kt,l(P.value),1)):_(``,!0),n[37]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Optional: selecting a preset fills the pin fields below for quick setup changes. `,-1)])]),n[51]||=S(`div`,{class:`pt-2 text-xs text-content-muted dark:text-content-muted`},`SX1262 Board Pin Configuration`,-1),S(`div`,qt,[S(`label`,Jt,[n[39]||=b(`SPI Bus ID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[14]||=e=>W.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,W.value,void 0,{number:!0}]]):(a(),C(`span`,Yt,l(W.value),1))]),S(`label`,Xt,[n[40]||=b(`SPI CS ID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[15]||=e=>G.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,G.value,void 0,{number:!0}]]):(a(),C(`span`,Zt,l(G.value),1))]),S(`label`,Qt,[n[41]||=b(`CS Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[16]||=e=>K.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,K.value,void 0,{number:!0}]]):(a(),C(`span`,$t,l(K.value),1))]),S(`label`,en,[n[42]||=b(`Reset Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[17]||=e=>q.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,q.value,void 0,{number:!0}]]):(a(),C(`span`,tn,l(q.value),1))]),S(`label`,nn,[n[43]||=b(`Busy Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[18]||=e=>ne.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ne.value,void 0,{number:!0}]]):(a(),C(`span`,rn,l(ne.value),1))]),S(`label`,an,[n[44]||=b(`IRQ Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[19]||=e=>re.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,re.value,void 0,{number:!0}]]):(a(),C(`span`,on,l(re.value),1))]),S(`label`,sn,[n[45]||=b(`TX Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[20]||=e=>ie.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ie.value,void 0,{number:!0}]]):(a(),C(`span`,cn,l(ie.value),1))]),S(`label`,ln,[n[46]||=b(`RX Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[21]||=e=>J.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,J.value,void 0,{number:!0}]]):(a(),C(`span`,un,l(J.value),1))]),S(`label`,dn,[n[47]||=b(`Power Enable Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[22]||=e=>Y.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Y.value,void 0,{number:!0}]]):(a(),C(`span`,fn,l(Y.value),1))]),S(`label`,pn,[n[48]||=b(`Power Enable Pins (array) `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[23]||=e=>X.value=e,type:`text`,class:`cfg-input mt-1`,placeholder:`26, 23`},null,512)),[[j,X.value]]):(a(),C(`span`,mn,l(X.value||`Not set`),1))]),S(`label`,hn,[n[49]||=b(`TX LED Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[24]||=e=>Z.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Z.value,void 0,{number:!0}]]):(a(),C(`span`,gn,l(Z.value),1))]),S(`label`,_n,[n[50]||=b(`RX LED Pin `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[25]||=e=>Q.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,Q.value,void 0,{number:!0}]]):(a(),C(`span`,vn,l(Q.value),1))])])],64)):we.value?(a(),C(`div`,yn,[S(`div`,bn,[n[52]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current SPI bus`,-1),S(`div`,xn,l(W.value),1)]),S(`div`,Sn,[n[53]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current SPI CS`,-1),S(`div`,Cn,l(G.value),1)]),S(`div`,wn,[n[54]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current CS pin`,-1),S(`div`,Tn,l(K.value),1)]),S(`div`,En,[n[55]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current reset pin`,-1),S(`div`,Dn,l(q.value),1)]),S(`div`,On,[n[56]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current busy pin`,-1),S(`div`,kn,l(ne.value),1)]),S(`div`,An,[n[57]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current IRQ pin`,-1),S(`div`,jn,l(re.value),1)]),S(`div`,Mn,[n[58]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current power enable pin`,-1),S(`div`,Nn,l(Y.value),1)]),S(`div`,Pn,[n[59]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs mb-1`},`Current power enable pins`,-1),S(`div`,Fn,l(X.value||`Not set`),1)])])):_(``,!0),Te.value?(a(),C(x,{key:4},[n[62]||=S(`div`,{class:`pt-2 text-xs text-content-muted dark:text-content-muted`},`CH341 Adapter Configuration`,-1),S(`div`,In,[S(`label`,Ln,[n[60]||=b(`CH341 VID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[26]||=e=>ae.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,ae.value,void 0,{number:!0}]]):(a(),C(`span`,Rn,l(ae.value),1))]),S(`label`,zn,[n[61]||=b(`CH341 PID `,-1),f.value?i((a(),C(`input`,{key:0,"onUpdate:modelValue":n[27]||=e=>oe.value=e,type:`number`,class:`cfg-input mt-1`},null,512)),[[j,oe.value,void 0,{number:!0}]]):(a(),C(`span`,Bn,l(oe.value),1))])])],64)):_(``,!0),n[63]||=S(`div`,{class:`py-2 text-xs text-content-muted dark:text-content-muted`},` Switching hardware saves immediately and requires a service restart to apply. `,-1)])])],64))}}),Hn={class:`space-y-12`},Un={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Wn={class:`flex items-center gap-2 flex-shrink-0`},Gn=[`disabled`],Kn=[`disabled`],qn={key:0,class:`bg-green-100 dark:bg-green-500/10 border border-green-300 dark:border-green-500/30 rounded-lg p-3`},Jn={class:`text-green-700 dark:text-green-400 text-sm`},Yn={key:1,class:`bg-red-100 dark:bg-red-500/10 border border-red-300 dark:border-red-500/30 rounded-lg p-3`},Xn={class:`text-red-700 dark:text-red-400 text-sm`},Zn={class:`cfg-section space-y-3`},Qn={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},$n={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},er={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},tr={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all`},nr={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},rr={class:`flex items-center gap-2 min-w-0 sm:justify-end`},ir={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all sm:text-right min-w-0`},ar={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},or={class:`text-content-primary dark:text-content-primary font-mono text-sm`},sr={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},cr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},lr={class:`flex flex-col py-2 gap-2`},ur={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},dr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},fr={key:1,class:`flex items-center gap-2`},pr={class:`cfg-section space-y-3`},mr={class:`pb-2`},hr={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},gr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},_r={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},vr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},yr={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] shadow-2xl w-full max-w-md p-6 space-y-4`},br={class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},xr=[`maxlength`,`disabled`],Sr={key:0,class:`text-red-500 text-xs mt-1`},Cr={key:1,class:`text-content-muted dark:text-content-muted text-xs mt-1`},wr=[`disabled`],Tr={key:0,class:`mt-2 bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Er={key:0,class:`flex items-center gap-3 bg-blue-500/10 border border-blue-500/30 rounded-lg p-3`},Dr={class:`text-blue-700 dark:text-blue-400 text-xs font-medium`},Or={class:`text-blue-600 dark:text-blue-500 text-xs mt-0.5`},kr={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3`},Ar={class:`text-red-600 dark:text-red-400 text-sm`},jr={key:2,class:`bg-green-500/10 border border-green-600/40 dark:border-green-500/30 rounded-lg p-3 space-y-2`},Mr={class:`text-green-600 dark:text-green-400 text-sm font-medium`},Nr={class:`font-mono text-xs break-all text-content-primary dark:text-content-primary`},Pr={key:3,class:`bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},Fr={class:`flex gap-2 mt-3`},Ir=[`disabled`],Lr=[`disabled`],Rr={class:`flex justify-end gap-3 mt-6`},zr=[`disabled`],Br=[`disabled`],Vr=f({__name:`RepeaterSettings`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config||{}),s=y(()=>r.value.repeater||{}),d=y(()=>n.stats),f=o(!1),g=o(!1),w=o(null),E=o(null),O=o(!1),k=o(``),M=o(0),N=o(0),P=o(0),F=o(1),I=y(()=>r.value.mesh||{});h([r,s,I],()=>{if(!f.value){k.value=r.value.node_name||``,M.value=s.value.latitude||0,N.value=s.value.longitude||0,P.value=s.value.send_advert_interval_hours||0;let e=I.value.path_hash_mode;F.value=e===0||e===1||e===2?e+1:1}},{immediate:!0});let L=y(()=>r.value.node_name||`Not set`),z=y(()=>d.value?.local_hash||`Not available`),B=y(()=>{let e=d.value?.public_key;return!e||e===`Not set`?`Not set`:e}),V=y(()=>{let e=s.value.latitude;return e&&e!==0?e.toFixed(6):`Not set`}),H=y(()=>{let e=s.value.longitude;return e&&e!==0?e.toFixed(6):`Not set`}),U=y(()=>{let e=s.value.mode;return e?e===`no_tx`?`No TX`:e.charAt(0).toUpperCase()+e.slice(1):`Not set`}),W=y(()=>{let e=s.value.send_advert_interval_hours;return e===void 0?`Not set`:e===0?`Disabled`:e+` hour`+(e===1?``:`s`)}),G=y(()=>{let e=I.value.path_hash_mode;return e===0||e===1||e===2?e+1+(e===0?` byte`:` bytes`):`Not set`}),K=()=>{f.value=!0,w.value=null,E.value=null},te=()=>{f.value=!1,w.value=null,k.value=r.value.node_name||``,M.value=s.value.latitude||0,N.value=s.value.longitude||0,P.value=s.value.send_advert_interval_hours||0;let e=I.value.path_hash_mode;F.value=e===0||e===1||e===2?e+1:1},q=async()=>{g.value=!0,w.value=null,E.value=null;try{let e={};k.value&&(e.node_name=k.value),e.latitude=M.value,e.longitude=N.value,e.flood_advert_interval_hours=P.value,e.path_hash_mode=F.value-1;let t=(await R.post(`/update_radio_config`,e)).data;t.message||t.persisted?(E.value=t.message||`Settings saved successfully`,f.value=!1,await n.fetchStats(),setTimeout(()=>{E.value=null},3e3)):t.error?w.value=t.error:w.value=`Unknown response from server`}catch(e){console.error(`Failed to update repeater settings:`,e),w.value=e.response?.data?.error||`Failed to update settings`}finally{g.value=!1}},ne=()=>{O.value=!0},ie=e=>{M.value=e.latitude,N.value=e.longitude},J=o(!1),Y=o(``),X=o(!1),Z=o(null),Q=o(null),ae=o(!1),oe=o(!1),se=o(!1),$=o(0),ce=null,le=y(()=>se.value?8:4),ue=y(()=>{let e=Y.value.trim();return!e||e.length>le.value?!1:/^[0-9a-fA-F]+$/.test(e)}),de=y(()=>{let e=Y.value.trim().length;return e===0?``:e===1?`Very fast — ~16 attempts on average`:e===2?`Fast — ~256 attempts on average`:e===3?`Moderate — ~4,096 attempts, a few seconds`:e===4?`Slow — ~65,536 attempts, may take 10-30 seconds`:e===5?`Very slow — ~1 million attempts, could take minutes`:e===6?`Extremely slow — ~16 million attempts, could take a very long time`:e===7?`Extreme — ~268 million attempts, may not complete`:`Extreme — ~4 billion attempts, extremely unlikely to complete`}),me=()=>{$.value=0,ce=setInterval(()=>{$.value++},1e3)},he=()=>{ce&&=(clearInterval(ce),null)};T(()=>he());let ge=()=>{Y.value=``,Z.value=null,Q.value=null,ae.value=!1,se.value=!1,J.value=!0},_e=async()=>{X.value=!0,Q.value=null,Z.value=null,me();try{let e=await R.generateVanityKey(Y.value.trim());e.success&&e.data?Z.value=e.data:Q.value=e.error||`Generation failed`}catch(e){let t=e;Q.value=t.response?.data?.error||t.message||`Generation failed`}finally{he(),X.value=!1}},ve=async()=>{if(Z.value){oe.value=!0,Q.value=null;try{let e=await R.generateVanityKey(Y.value.trim(),!0);e.success&&e.data?(Z.value=e.data,ae.value=!1,J.value=!1,E.value=`New identity key applied. Restart the repeater for the change to take effect.`,await n.fetchStats(),setTimeout(()=>{E.value=null},8e3)):Q.value=e.error||`Failed to apply key`}catch(e){let t=e;Q.value=t.response?.data?.error||t.message||`Failed to apply key`}finally{oe.value=!1}}},{showUnsavedModal:ye,requestLeave:be,handleDiscard:xe,handleSave:Se,handleCancel:Ce}=pe(f,g,te,async()=>(await q(),!f.value));return t({requestLeave:be,isEditing:f}),(e,t)=>(a(),C(x,null,[v(fe,{show:c(ye),"is-saving":g.value,label:`Repeater Settings`,onDiscard:c(xe),onSave:c(Se),onCancel:c(Ce)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Hn,[S(`div`,Un,[t[13]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Repeater Settings`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure repeater identity, location, and network settings`)],-1),S(`div`,Wn,[f.value?(a(),C(x,{key:1},[S(`button`,{onClick:te,disabled:g.value,class:`cfg-btn-secondary`},` Cancel `,8,Gn),S(`button`,{onClick:q,disabled:g.value,class:`cfg-btn-primary`},l(g.value?`Saving...`:`Save Changes`),9,Kn)],64)):(a(),C(`button`,{key:0,onClick:K,class:`cfg-btn-primary`},` Edit Settings `))])]),E.value?(a(),C(`div`,qn,[S(`p`,Jn,l(E.value),1)])):_(``,!0),w.value?(a(),C(`div`,Yn,[S(`p`,Xn,l(w.value),1)])):_(``,!0),S(`div`,Zn,[t[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary pb-2`},`General Settings`,-1),S(`div`,Qn,[t[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Node Name`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>k.value=e,type:`text`,maxlength:`50`,class:`cfg-input w-full sm:w-64`,placeholder:`Enter node name`},null,512)),[[j,k.value]]):(a(),C(`div`,$n,l(L.value),1))]),S(`div`,er,[t[15]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Local Hash`,-1),S(`span`,tr,l(z.value),1)]),S(`div`,nr,[t[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm flex-shrink-0`},`Public Key`,-1),S(`div`,rr,[S(`span`,ir,l(B.value),1),f.value?(a(),C(`button`,{key:0,onClick:ge,class:`flex-shrink-0 px-2 py-1 text-xs bg-primary/10 hover:bg-primary/20 text-content-secondary dark:text-content-muted rounded border border-primary/30 transition-colors whitespace-nowrap`},` Generate New Key `)):_(``,!0)])]),S(`div`,ar,[t[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Mode`,-1),S(`span`,or,l(U.value),1)]),S(`div`,sr,[t[19]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Path hash length`,-1),f.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>F.value=e,class:`cfg-select w-full sm:w-32`},[...t[18]||=[S(`option`,{value:1},`1 byte`,-1),S(`option`,{value:2},`2 bytes`,-1),S(`option`,{value:3},`3 bytes`,-1)]],512)),[[D,F.value,void 0,{number:!0}]]):(a(),C(`div`,cr,l(G.value),1))]),S(`div`,lr,[S(`div`,ur,[t[21]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Periodic Advertisement Interval`,-1),f.value?(a(),C(`div`,fr,[i(S(`input`,{"onUpdate:modelValue":t[2]||=e=>P.value=e,type:`number`,min:`0`,max:`48`,class:`cfg-input w-20`},null,512),[[j,P.value,void 0,{number:!0}]]),t[20]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,dr,l(W.value),1))]),t[22]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`How often the repeater sends an advertisement packet (0 = disabled, 3-48 hours)`,-1)])]),S(`div`,pr,[S(`div`,mr,[t[25]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-3`},`Location Settings`,-1),f.value?(a(),C(`button`,{key:0,onClick:ne,class:`btn-primary flex items-center gap-2`,title:`Pick location on map`},[...t[24]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z`}),S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 11a3 3 0 11-6 0 3 3 0 016 0z`})],-1),b(` Pick Location on Map `,-1)]])):_(``,!0)]),S(`div`,hr,[t[26]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Latitude`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[3]||=e=>M.value=e,type:`number`,step:`0.000001`,min:`-90`,max:`90`,class:`cfg-input w-full sm:w-48`},null,512)),[[j,M.value,void 0,{number:!0}]]):(a(),C(`div`,gr,l(V.value),1))]),S(`div`,_r,[t[27]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Manual Longitude`,-1),f.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[4]||=e=>N.value=e,type:`number`,step:`0.000001`,min:`-180`,max:`180`,class:`cfg-input w-full sm:w-48`},null,512)),[[j,N.value,void 0,{number:!0}]]):(a(),C(`div`,vr,l(H.value),1))])]),v(re,{"is-open":O.value,latitude:M.value,longitude:N.value,onClose:t[5]||=e=>O.value=!1,onSelect:ie},null,8,[`is-open`,`latitude`,`longitude`]),(a(),u(m,{to:`body`},[J.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:t[12]||=A(e=>J.value=!1,[`self`])},[S(`div`,yr,[t[35]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Generate Vanity Identity Key `,-1),t[36]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Generate a new Ed25519 identity key whose public key starts with your chosen hex prefix (0-9, A-F). Longer prefixes take more time to find. `,-1),S(`div`,null,[S(`label`,br,`Hex Prefix (1-`+l(le.value)+` characters)`,1),i(S(`input`,{"onUpdate:modelValue":t[6]||=e=>Y.value=e,type:`text`,maxlength:le.value,placeholder:`e.g. F8A1`,disabled:X.value,class:`cfg-input py-2 placeholder-gray-400 dark:placeholder-white/40 font-mono uppercase disabled:opacity-50`},null,8,xr),[[j,Y.value]]),Y.value&&!ue.value?(a(),C(`p`,Sr,` Enter 1-`+l(le.value)+` valid hex characters (0-9, A-F) `,1)):de.value?(a(),C(`p`,Cr,l(de.value),1)):_(``,!0)]),S(`div`,null,[S(`button`,{onClick:t[7]||=e=>se.value=!se.value,disabled:X.value,class:`text-xs text-content-muted dark:text-content-muted hover:text-content-secondary dark:hover:text-content-secondary transition-colors disabled:opacity-50 flex items-center gap-1`},[(a(),C(`svg`,{class:p([`w-3 h-3 transition-transform`,{"rotate-90":se.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...t[28]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),t[29]||=b(` Advanced `,-1)],8,wr),se.value?(a(),C(`div`,Tr,[...t[30]||=[S(`p`,{class:`text-amber-600 dark:text-amber-400 text-xs font-medium`},` Extended prefix mode (up to 8 characters) `,-1),S(`p`,{class:`text-amber-600 dark:text-amber-500 text-xs mt-1`},` Prefixes longer than 4 characters require exponentially more attempts and can take a very long time or may not complete at all. The request may time out. `,-1)]])):_(``,!0)]),X.value?(a(),C(`div`,Er,[t[31]||=S(`svg`,{class:`animate-spin h-5 w-5 text-blue-500 flex-shrink-0`,xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`},[S(`circle`,{class:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,"stroke-width":`4`}),S(`path`,{class:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`})],-1),S(`div`,null,[S(`p`,Dr,` Searching for key with prefix "`+l(Y.value.toUpperCase())+`"... `,1),S(`p`,Or,` Elapsed: `+l($.value)+`s `,1)])])):_(``,!0),Q.value?(a(),C(`div`,kr,[S(`p`,Ar,l(Q.value),1)])):_(``,!0),Z.value?(a(),C(`div`,jr,[S(`p`,Mr,` Key found in `+l(Z.value.attempts.toLocaleString())+` attempts `,1),S(`div`,null,[t[32]||=S(`span`,{class:`text-xs text-content-muted dark:text-content-muted`},`Public Key:`,-1),S(`p`,Nr,l(Z.value.public_hex),1)])])):_(``,!0),ae.value&&Z.value?(a(),C(`div`,Pr,[t[33]||=S(`p`,{class:`text-amber-600 dark:text-amber-400 text-sm font-medium`},` Warning: This will replace your current identity key. `,-1),t[34]||=S(`p`,{class:`text-amber-600 dark:text-amber-500 text-xs mt-1`},` Your node address and public key will change. Other nodes will need to re-discover you. This cannot be undone unless you have a backup. `,-1),S(`div`,Fr,[S(`button`,{onClick:ve,disabled:oe.value,class:`px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-lg text-xs transition-colors disabled:opacity-50`},l(oe.value?`Applying...`:`Confirm Replace Key`),9,Ir),S(`button`,{onClick:t[8]||=e=>ae.value=!1,disabled:oe.value,class:`px-3 py-1.5 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 text-xs transition-colors`},` Cancel `,8,Lr)])])):_(``,!0),S(`div`,Rr,[S(`button`,{onClick:t[9]||=e=>J.value=!1,disabled:X.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/10 transition-colors`},` Close `,8,zr),Z.value?(a(),C(x,{key:1},[S(`button`,{onClick:t[10]||=e=>{Z.value=null,Q.value=null},class:`btn-primary`},` Try Again `),ae.value?_(``,!0):(a(),C(`button`,{key:0,onClick:t[11]||=e=>ae.value=!0,class:`px-4 py-2 bg-red-600/20 hover:bg-red-600/30 text-red-600 dark:text-red-400 rounded-lg border border-red-500/50 text-sm transition-colors`},` Apply Key `))],64)):(a(),C(`button`,{key:0,onClick:_e,disabled:!ue.value||X.value,class:`btn-primary`},l(X.value?`Generating...`:`Generate`),9,Br))])])])):_(``,!0)]))])],64))}}),Hr={class:`space-y-12`},Ur={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Wr={class:`flex items-center gap-2 flex-shrink-0`},Gr=[`disabled`],Kr=[`disabled`],qr={key:0,class:`bg-green-100 dark:bg-green-500/20 border border-green-500 dark:border-green-500/50 rounded-lg p-3 text-green-700 dark:text-green-400 text-sm`},Jr={key:1,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},Yr={class:`cfg-section`},Xr={class:`space-y-3`},Zr={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Qr={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$r={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},ei={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ti=f({__name:`DutyCycle`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config?.duty_cycle||{}),s=y(()=>{let e=r.value.max_airtime_percent;return typeof e==`number`?e.toFixed(1)+`%`:e&&typeof e==`object`&&`parsedValue`in e?(e.parsedValue||0).toFixed(1)+`%`:`Not set`}),u=y(()=>r.value.enforcement_enabled?`Enabled`:`Disabled`),d=o(!1),f=o(!1),p=o(``),m=o(``),h=o(0),g=o(!0),b=()=>{let e=r.value.max_airtime_percent;typeof e==`number`?h.value=e:e&&typeof e==`object`&&`parsedValue`in e?h.value=e.parsedValue||0:h.value=6,g.value=r.value.enforcement_enabled!==!1,d.value=!0,p.value=``,m.value=``},w=()=>{d.value=!1,p.value=``,m.value=``},{showUnsavedModal:T,requestLeave:E,handleDiscard:O,handleSave:k,handleCancel:A}=pe(d,f,w,async()=>(await M(),!d.value));t({requestLeave:E,isEditing:d});let M=async()=>{f.value=!0,m.value=``,p.value=``;try{let e=(await R.post(`/update_duty_cycle_config`,{max_airtime_percent:h.value,enforcement_enabled:g.value})).data;e?.message||e?.persisted?(p.value=e?.message||`Settings saved successfully`,d.value=!1,await n.fetchStats(),setTimeout(()=>{p.value=``},3e3)):m.value=e?.error||`Failed to save settings`}catch(e){console.error(`Failed to save duty cycle settings:`,e),m.value=e.response?.data?.error||`Failed to save settings`}finally{f.value=!1}};return(e,t)=>(a(),C(x,null,[v(fe,{show:c(T),"is-saving":f.value,label:`Duty Cycle settings`,onDiscard:c(O),onSave:c(k),onCancel:c(A)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Hr,[S(`div`,Ur,[t[2]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Duty Cycle`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure duty cycle limits for channel activity`)],-1),S(`div`,Wr,[d.value?(a(),C(x,{key:1},[S(`button`,{onClick:w,disabled:f.value,class:`cfg-btn-secondary`},` Cancel `,8,Gr),S(`button`,{onClick:M,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving...`:`Save Changes`),9,Kr)],64)):(a(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),p.value?(a(),C(`div`,qr,l(p.value),1)):_(``,!0),m.value?(a(),C(`div`,Jr,l(m.value),1)):_(``,!0),S(`div`,Yr,[S(`div`,Xr,[S(`div`,Zr,[t[3]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Airtime %`,-1),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>h.value=e,type:`number`,step:`0.1`,min:`0.1`,max:`100`,class:`cfg-input w-full sm:w-32`},null,512)),[[j,h.value,void 0,{number:!0}]]):(a(),C(`div`,Qr,l(s.value),1))]),S(`div`,$r,[t[5]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Enforcement`,-1),d.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>g.value=e,class:`cfg-select w-full sm:w-32`},[...t[4]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[D,g.value]]):(a(),C(`div`,ei,l(u.value),1))])])])])],64))}}),ni={class:`space-y-12`},ri={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ii={class:`flex items-center gap-2 flex-shrink-0`},ai=[`disabled`],oi=[`disabled`],si={key:0,class:`bg-green-100 dark:bg-green-500/20 border border-green-500 dark:border-green-500/50 rounded-lg p-3 text-green-700 dark:text-green-400 text-sm`},ci={key:1,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},li={class:`cfg-section space-y-3`},ui={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-3`},di={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},fi={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between py-2 gap-3`},pi={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm flex-shrink-0`},mi=f({__name:`TransmissionDelays`,setup(e,{expose:t}){let n=ee(),r=y(()=>n.stats?.config?.delays||{}),s=y(()=>{let e=r.value.tx_delay_factor;if(typeof e==`number`)return e.toFixed(2)+`x`;if(e&&typeof e==`object`&&`parsedValue`in e){let t=e.parsedValue;if(typeof t==`number`)return t.toFixed(2)+`x`}return`Not set`}),u=y(()=>{let e=r.value.direct_tx_delay_factor;return typeof e==`number`?e.toFixed(2)+`s`:`Not set`}),d=o(!1),f=o(!1),p=o(``),m=o(``),h=o(0),g=o(0),b=()=>{let e=r.value.tx_delay_factor;e&&typeof e==`object`&&`parsedValue`in e?h.value=e.parsedValue||1:typeof e==`number`?h.value=e:h.value=1;let t=r.value.direct_tx_delay_factor;g.value=typeof t==`number`?t:.5,d.value=!0,p.value=``,m.value=``},w=()=>{d.value=!1,p.value=``,m.value=``},T=async()=>{f.value=!0,m.value=``,p.value=``;try{let e=(await R.post(`/update_radio_config`,{tx_delay_factor:h.value,direct_tx_delay_factor:g.value})).data,t=e?.data??e;e?.success||t?.persisted||t?.message?(p.value=t?.message||`Settings saved successfully`,d.value=!1,await n.fetchStats(),setTimeout(()=>{p.value=``},3e3)):m.value=t?.error||`Failed to save settings`}catch(e){console.error(`Failed to save delay settings:`,e),m.value=e.response?.data?.error||`Failed to save settings`}finally{f.value=!1}},{showUnsavedModal:E,requestLeave:D,handleDiscard:O,handleSave:k,handleCancel:A}=pe(d,f,w,async()=>(await T(),!d.value));return t({requestLeave:D,isEditing:d}),(e,t)=>(a(),C(x,null,[v(fe,{show:c(E),"is-saving":f.value,label:`TX Delay settings`,onDiscard:c(O),onSave:c(k),onCancel:c(A)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,ni,[S(`div`,ri,[t[2]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`TX Delays`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure transmission delay factors for flood and direct packets`)],-1),S(`div`,ii,[d.value?(a(),C(x,{key:1},[S(`button`,{onClick:w,disabled:f.value,class:`cfg-btn-secondary`},` Cancel `,8,ai),S(`button`,{onClick:T,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving...`:`Save Changes`),9,oi)],64)):(a(),C(`button`,{key:0,onClick:b,class:`cfg-btn-primary`},` Edit Settings `))])]),p.value?(a(),C(`div`,si,l(p.value),1)):_(``,!0),m.value?(a(),C(`div`,ci,l(m.value),1)):_(``,!0),S(`div`,li,[S(`div`,ui,[t[3]||=S(`div`,{class:`flex flex-col gap-1`},[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Flood TX Delay Factor`),S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Scales the airtime-based random transmit window for flood packets. Higher values increase delay spread for collision avoidance.`)],-1),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>h.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[j,h.value,void 0,{number:!0}]]):(a(),C(`div`,di,l(s.value),1))]),S(`div`,fi,[t[4]||=S(`div`,{class:`flex flex-col gap-1`},[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Direct TX Delay Factor`),S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Fixed delay in seconds before transmitting direct-routed packets. Applied as-is with no randomisation.`)],-1),d.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":t[1]||=e=>g.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`cfg-input w-full sm:w-32 flex-shrink-0`},null,512)),[[j,g.value,void 0,{number:!0}]]):(a(),C(`div`,pi,l(u.value),1))])])])],64))}}),hi=z(`treeState`,()=>{let e=s(new Set),t=s({value:null}),n=t=>{e.add(t)},r=t=>{e.delete(t)};return{expandedNodes:e,selectedNodeId:t,addExpandedNode:n,removeExpandedNode:r,isNodeExpanded:t=>e.has(t),setSelectedNode:e=>{t.value=e},toggleExpanded:t=>{e.has(t)?r(t):n(t)}}}),gi={class:`select-none`},_i={class:`flex-shrink-0`},vi={key:0,class:`w-3.5 h-3.5 sm:w-4 sm:h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},yi={key:1,class:`w-3.5 h-3.5 sm:w-4 sm:h-4 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},bi={key:0,class:`hidden sm:flex items-center gap-1 ml-2`},xi={class:`relative group`},Si=[`title`],Ci={key:0,class:`text-xs font-mono text-content-secondary dark:text-white/50 bg-stroke-subtle/40 dark:bg-white/5 px-1.5 py-0.5 rounded border border-stroke-subtle dark:border-white/10`},wi={class:`flex justify-between items-start mb-4`},Ti={class:`bg-black/20 border border-white/10 rounded-md p-4 mb-4`},Ei={class:`text-sm font-mono text-white/80 break-all leading-relaxed`},Di={class:`flex justify-end`},Oi={class:`flex items-center gap-2 sm:gap-3 ml-auto flex-shrink-0`},ki={key:0,class:`hidden sm:flex items-center gap-1`},Ai=[`title`],ji={key:1,class:`hidden sm:flex items-center gap-1`},Mi={key:3,class:`hidden sm:inline-block px-2 py-1 bg-stroke-subtle dark:bg-white/10 text-content-secondary dark:text-white/60 text-xs rounded-full ml-1`},Ni={key:0,class:`space-y-1`},Pi=K(f({__name:`TreeNode`,props:{node:{},selectedNodeId:{},level:{},disabled:{type:Boolean},unlocked:{type:Boolean}},emits:[`select`,`edit`,`delete`],setup(e,{emit:n}){let i=e,s=n,d=hi(),f=o(!1),m=y({get:()=>d.isNodeExpanded(i.node.id),set:e=>{e?d.addExpandedNode(i.node.id):d.removeExpandedNode(i.node.id)}}),h=y(()=>i.node.children.length>0);function b(){i.unlocked&&T(),h.value&&w()}function w(){h.value&&(m.value=!m.value)}function T(){s(`select`,i.node.id)}function E(e){s(`select`,e)}function D(e){s(`edit`,e)}function O(e){s(`delete`,e)}function k(e){e.stopPropagation(),f.value=!f.value}let{copy:j,copied:M}=ie();function P(e){e.stopPropagation(),i.node.transport_key&&j(i.node.transport_key)}return(n,o)=>{let d=g(`TreeNode`,!0);return a(),C(`div`,gi,[S(`div`,{class:p([`flex flex-wrap sm:flex-nowrap items-start sm:items-center gap-1 sm:gap-2 py-2 px-2 sm:px-3 rounded-lg border transition-colors duration-150`,i.disabled?`opacity-50`:``,i.unlocked&&e.selectedNodeId===e.node.id?`bg-primary/10 border-primary/30 text-content-primary dark:text-white`:`cfg-card text-content-primary dark:text-white/80`,i.unlocked&&e.selectedNodeId!==e.node.id?`hover:bg-stroke-subtle/40 dark:hover:bg-white/5 hover:border-stroke dark:hover:border-white/15`:``,h.value&&!i.disabled?`cursor-pointer`:``,`ml-${e.level*4}`]),onClick:o[5]||=A(e=>!i.disabled&&b(),[`stop`])},[S(`div`,{class:`flex-shrink-0 w-3 h-3 sm:w-4 sm:h-4 flex items-center justify-center`,onClick:A(w,[`stop`])},[h.value?(a(),C(`svg`,{key:0,class:p([`w-2.5 h-2.5 sm:w-3 sm:h-3 transition-transform duration-200`,m.value?`rotate-90`:`rotate-0`]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...o[6]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)):_(``,!0)]),S(`div`,_i,[i.node.name.startsWith(`#`)?(a(),C(`svg`,vi,[...o[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(a(),C(`svg`,yi,[...o[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`},null,-1)]]))]),S(`span`,{class:p([`font-mono text-xs sm:text-sm transition-colors duration-200 break-all`,e.selectedNodeId===e.node.id?`text-primary font-medium`:``])},l(e.node.name.startsWith(`#`)?e.node.name.slice(1):e.node.name),3),e.node.transport_key?(a(),C(`div`,bi,[S(`div`,xi,[S(`button`,{onClick:k,class:`p-1 rounded hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors`,title:f.value?`Hide full key`:`Show full key`},[...o[9]||=[S(`svg`,{class:`w-3 h-3 text-content-muted dark:text-white/60 hover:text-content-secondary dark:hover:text-white/80`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 12a3 3 0 11-6 0 3 3 0 016 0z`}),S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z`})],-1)]],8,Si),f.value?_(``,!0):(a(),C(`span`,Ci,l(c(X)(e.node.transport_key)),1)),f.value?(a(),C(`div`,{key:1,class:`fixed inset-0 z-[300] flex items-center justify-center bg-black/70 backdrop-blur-md`,onClick:o[2]||=e=>f.value=!1},[S(`div`,{class:`bg-black/20 border border-white/20 rounded-lg shadow-lg p-6 max-w-2xl w-full mx-4`,onClick:o[1]||=A(()=>{},[`stop`])},[S(`div`,wi,[o[11]||=S(`h3`,{class:`text-lg font-semibold text-white`},`Transport Key`,-1),S(`button`,{onClick:o[0]||=e=>f.value=!1,class:`text-white/60 hover:text-white transition-colors`},[...o[10]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`div`,Ti,[S(`div`,Ei,l(e.node.transport_key),1)]),S(`div`,Di,[S(`button`,{onClick:P,class:p([`flex items-center gap-2 transition-colors`,c(M)?`btn-primary`:`btn-success`])},[o[12]||=S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),v(J,{copied:c(M),label:`Copy Key`},null,8,[`copied`])],2)])])])):_(``,!0)])])):_(``,!0),S(`div`,Oi,[e.node.last_used?(a(),C(`div`,ki,[o[13]||=S(`span`,{class:`text-xs text-content-muted dark:text-white/40`},`Last Heard:`,-1),S(`span`,{class:`text-xs text-content-secondary dark:text-white/50`,title:e.node.last_used.toLocaleString()},l(c(Y)(e.node.last_used)),9,Ai)])):(a(),C(`div`,ji,[...o[14]||=[S(`span`,{class:`text-xs text-content-muted dark:text-white/30`},`Last Heard:`,-1),S(`span`,{class:`text-xs text-content-muted dark:text-white/30 italic`},`Never`,-1)]])),S(`span`,{class:p([`text-[10px] sm:text-xs`,e.node.floodPolicy===`allow`?`text-accent-green/80`:`text-accent-red/80`])},` Flood: `+l(e.node.floodPolicy===`allow`?`Allow`:`Deny`),3),i.unlocked?(a(),C(x,{key:2},[S(`button`,{onClick:o[3]||=A(t=>s(`edit`,e.node.id),[`stop`]),class:`px-2 py-0.5 text-[10px] sm:text-xs bg-primary/10 hover:bg-primary/20 text-content-secondary dark:text-content-muted rounded border border-primary/30 transition-colors whitespace-nowrap`},` Edit `),S(`button`,{onClick:o[4]||=A(t=>s(`delete`,e.node.id),[`stop`]),class:`p-1 text-accent-red/50 hover:text-accent-red transition-colors`,title:`Delete`},[...o[15]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})],-1)]])],64)):_(``,!0),h.value&&!i.unlocked?(a(),C(`span`,Mi,l(e.node.children.length),1)):_(``,!0)])],2),v(N,{"enter-active-class":`transition-all duration-300 ease-out`,"enter-from-class":`opacity-0 max-h-0 overflow-hidden`,"enter-to-class":`opacity-100 max-h-screen overflow-visible`,"leave-active-class":`transition-all duration-300 ease-in`,"leave-from-class":`opacity-100 max-h-screen overflow-visible`,"leave-to-class":`opacity-0 max-h-0 overflow-hidden`},{default:r(()=>[m.value&&e.node.children.length>0?(a(),C(`div`,Ni,[(a(!0),C(x,null,t(e.node.children,t=>(a(),u(d,{key:t.id,node:t,"selected-node-id":e.selectedNodeId,level:e.level+1,disabled:i.disabled,unlocked:i.unlocked,onSelect:E,onEdit:D,onDelete:O},null,8,[`node`,`selected-node-id`,`level`,`disabled`,`unlocked`]))),128))])):_(``,!0)]),_:1})])}}}),[[`__scopeId`,`data-v-1b1421f8`]]);function Fi(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name===`Uint8Array`&&`BYTES_PER_ELEMENT`in e&&e.BYTES_PER_ELEMENT===1}function Ii(e,t,n=``){let r=Fi(e),i=e?.length,a=t!==void 0;if(!r||a&&i!==t){let o=n&&`"${n}" `,s=a?` of length ${t}`:``,c=r?`length=${i}`:`type=${typeof e}`,l=o+`expected Uint8Array`+s+`, got `+c;throw r?RangeError(l):TypeError(l)}return e}function Li(e,t=!0){if(e.destroyed)throw Error(`Hash instance has been destroyed`);if(t&&e.finished)throw Error(`Hash#digest() has already been called`)}function Ri(e,t){Ii(e,void 0,`digestInto() output`);let n=t.outputLen;if(e.length=`+n)}function zi(...e){for(let t=0;t>>t}new Uint8Array(new Uint32Array([287454020]).buffer)[0],typeof Uint8Array.from([]).toHex==`function`&&Uint8Array.fromHex;function Hi(e,t={}){let n=(t,n)=>e(n).update(t).digest(),r=e(void 0);return n.outputLen=r.outputLen,n.blockLen=r.blockLen,n.canXOF=r.canXOF,n.create=t=>e(t),Object.assign(n,t),Object.freeze(n)}var Ui=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});function Wi(e,t,n){return e&t^~e&n}function Gi(e,t,n){return e&t^e&n^t&n}var Ki=class{blockLen;outputLen;canXOF=!1;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(e,t,n,r){this.blockLen=e,this.outputLen=t,this.padOffset=n,this.isLE=r,this.buffer=new Uint8Array(e),this.view=Bi(this.buffer)}update(e){Li(this),Ii(e);let{view:t,buffer:n,blockLen:r}=this,i=e.length;for(let a=0;ar-a&&(this.process(n,0),a=0);for(let e=a;el.length)throw Error(`_sha2: outputLen bigger than state`);for(let e=0;e>Yi&Ji)}:{h:Number(e>>Yi&Ji)|0,l:Number(e&Ji)|0}}function Zi(e,t=!1){let n=e.length,r=new Uint32Array(n),i=new Uint32Array(n);for(let a=0;a>>3;$i[e]=(Vi(n,17)^Vi(n,19)^n>>>10)+$i[e-7]+r+$i[e-16]|0}let{A:n,B:r,C:i,D:a,E:o,F:s,G:c,H:l}=this;for(let e=0;e<64;e++){let t=Vi(o,6)^Vi(o,11)^Vi(o,25),u=l+t+Wi(o,s,c)+Qi[e]+$i[e]|0,d=(Vi(n,2)^Vi(n,13)^Vi(n,22))+Gi(n,r,i)|0;l=c,c=s,s=o,o=a+u|0,a=i,i=r,r=n,n=u+d|0}n=n+this.A|0,r=r+this.B|0,i=i+this.C|0,a=a+this.D|0,o=o+this.E|0,s=s+this.F|0,c=c+this.G|0,l=l+this.H|0,this.set(n,r,i,a,o,s,c,l)}roundClean(){zi($i)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),zi(this.buffer)}},ta=class extends ea{A=qi[0]|0;B=qi[1]|0;C=qi[2]|0;D=qi[3]|0;E=qi[4]|0;F=qi[5]|0;G=qi[6]|0;H=qi[7]|0;constructor(){super(32)}},na=Zi(`0x428a2f98d728ae22.0x7137449123ef65cd.0xb5c0fbcfec4d3b2f.0xe9b5dba58189dbbc.0x3956c25bf348b538.0x59f111f1b605d019.0x923f82a4af194f9b.0xab1c5ed5da6d8118.0xd807aa98a3030242.0x12835b0145706fbe.0x243185be4ee4b28c.0x550c7dc3d5ffb4e2.0x72be5d74f27b896f.0x80deb1fe3b1696b1.0x9bdc06a725c71235.0xc19bf174cf692694.0xe49b69c19ef14ad2.0xefbe4786384f25e3.0x0fc19dc68b8cd5b5.0x240ca1cc77ac9c65.0x2de92c6f592b0275.0x4a7484aa6ea6e483.0x5cb0a9dcbd41fbd4.0x76f988da831153b5.0x983e5152ee66dfab.0xa831c66d2db43210.0xb00327c898fb213f.0xbf597fc7beef0ee4.0xc6e00bf33da88fc2.0xd5a79147930aa725.0x06ca6351e003826f.0x142929670a0e6e70.0x27b70a8546d22ffc.0x2e1b21385c26c926.0x4d2c6dfc5ac42aed.0x53380d139d95b3df.0x650a73548baf63de.0x766a0abb3c77b2a8.0x81c2c92e47edaee6.0x92722c851482353b.0xa2bfe8a14cf10364.0xa81a664bbc423001.0xc24b8b70d0f89791.0xc76c51a30654be30.0xd192e819d6ef5218.0xd69906245565a910.0xf40e35855771202a.0x106aa07032bbd1b8.0x19a4c116b8d2d0c8.0x1e376c085141ab53.0x2748774cdf8eeb99.0x34b0bcb5e19b48a8.0x391c0cb3c5c95a63.0x4ed8aa4ae3418acb.0x5b9cca4f7763e373.0x682e6ff3d6b2b8a3.0x748f82ee5defb2fc.0x78a5636f43172f60.0x84c87814a1f0ab72.0x8cc702081a6439ec.0x90befffa23631e28.0xa4506cebde82bde9.0xbef9a3f7b2c67915.0xc67178f2e372532b.0xca273eceea26619c.0xd186b8c721c0c207.0xeada7dd6cde0eb1e.0xf57d4f7fee6ed178.0x06f067aa72176fba.0x0a637dc5a2c898a6.0x113f9804bef90dae.0x1b710b35131c471b.0x28db77f523047d84.0x32caab7b40c72493.0x3c9ebe0a15c9bebc.0x431d67c49c100d4c.0x4cc5d4becb3e42b6.0x597f299cfc657e2a.0x5fcb6fab3ad6faec.0x6c44198c4a475817`.split(`.`).map(e=>BigInt(e)));na[0],na[1];var ra=Hi(()=>new ta,Ui(1)),ia={class:`flex items-center justify-between mb-6`},aa={class:`text-xl font-semibold text-content-primary dark:text-content-primary`},oa={key:0,class:`text-content-secondary dark:text-content-muted text-sm mt-1`},sa={class:`text-primary font-mono`},ca={key:0,class:`mb-4 text-sm text-content-secondary dark:text-content-muted`},la={key:1,class:`mb-4 text-sm text-content-secondary dark:text-content-muted`},ua={class:`pb-2`},da={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},fa={class:`modal-field-label`},pa={class:`flex items-center`},ma={key:0,class:`px-3 py-2 bg-secondary/10 border border-r-0 border-secondary/30 rounded-l-md text-secondary text-sm font-mono`},ha=[`placeholder`],ga={key:0,class:`text-content-muted text-xs mt-1`},_a={key:1,class:`mt-3`},va={class:`flex items-center justify-between mb-1`},ya=[`value`],ba={key:0,class:`text-xs text-amber-500 dark:text-amber-400 mt-1`},xa={key:0,class:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-3`},Sa={class:`flex items-center justify-between`},Ca={class:`text-right`},wa={class:`text-sm text-content-secondary dark:text-content-muted`},Ta={class:`text-xs text-content-muted dark:text-content-muted`},Ea={class:`pt-1 border-t border-stroke-subtle dark:border-stroke/10`},Da={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5`},Oa={class:`modal-actions`},ka=[`disabled`],Aa=f({name:`KeyModal`,__name:`KeyModal`,props:{show:{type:Boolean},node:{},selectedParentId:{},allNodes:{}},emits:[`close`,`add`,`save`],setup(e,{emit:r}){let s=e,d=r,f=y(()=>s.node===null),g=o(``),w=o(`allow`),T=o(`region`),E=y(()=>T.value===`region`),D=y(()=>({type:E.value?`Region`:`Private Key`}));h(()=>s.node,e=>{if(e){let t=e.name.startsWith(`#`);T.value=t?`region`:`privateKey`,g.value=t?e.name.slice(1):e.name,w.value=e.floodPolicy}else g.value=``,w.value=`allow`,T.value=`region`},{immediate:!0});function O(e,t){for(let n of e){if(n.id===t)return n;let e=O(n.children,t);if(e)return e}return null}function k(e,t){for(let n of e){if(n.id===t)return[n];let e=k(n.children,t);if(e.length)return[n,...e]}return[]}let M=y(()=>{let e=f.value?s.selectedParentId:s.node?.parent_id;return e?k(s.allNodes,e):[]}),N=y(()=>{let e=g.value.trim();return e?E.value?`#${e}`:e:s.node?.name||``}),P=y(()=>s.node?s.node.name.startsWith(`#`)?s.node.name.slice(1):s.node.name:``),F=y(()=>g.value.trim()!==P.value);function I(e){let t=e.startsWith(`#`)?e:`#${e}`,n=ra(new TextEncoder().encode(t)).slice(0,16),r=``;return n.forEach(e=>{r+=String.fromCharCode(e)}),btoa(r)}let L=o(null);n(()=>{if(f.value){L.value=null;return}let e=g.value.trim();if(!E.value||!e){L.value=null;return}L.value=I(e)});let{copy:R,copied:z}=ie(),B=y(()=>f.value?g.value.trim().length>0:g.value.trim().length>0&&s.node!==null),ee=()=>{if(!B.value)return;let e=E.value?`#${g.value.trim()}`:g.value.trim();if(f.value)d(`add`,{name:e,floodPolicy:w.value,parentId:s.selectedParentId}),g.value=``,w.value=`allow`,T.value=`region`;else{let t=E.value&&F.value?L.value??I(g.value.trim()):void 0;d(`save`,{id:s.node.id,name:e,floodPolicy:w.value,transportKey:t}),d(`close`)}},V=()=>{f.value&&(g.value=``,w.value=`allow`,T.value=`region`),d(`close`)};return(n,r)=>(a(),u(m,{to:`body`},[e.show?(a(),C(`div`,{key:0,class:`modal-backdrop`,onClick:A(V,[`self`])},[S(`div`,{class:p([`modal-card`,f.value?`max-w-md`:`max-w-lg`])},[S(`div`,ia,[S(`div`,null,[S(`h3`,aa,l(f.value?`Add New Entry`:`Edit Entry`),1),f.value?_(``,!0):(a(),C(`p`,oa,[r[6]||=b(` Modify `,-1),S(`span`,sa,l(N.value),1)]))]),S(`button`,{onClick:V,class:`text-content-muted hover:text-content-primary transition-colors`},[...r[7]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),M.value.length>0?(a(),C(`div`,ca,[S(`span`,null,l(f.value?`Adding under:`:`Parent:`),1),(a(!0),C(x,null,t(M.value,(e,t)=>(a(),C(`span`,{key:e.id},[r[8]||=S(`span`,{class:`text-content-muted dark:text-content-muted`},` / `,-1),S(`span`,{class:p(t===M.value.length-1?`text-primary font-mono`:`font-mono`)},l(e.name),3)]))),128))])):f.value?(a(),C(`div`,la,` Adding at root level `)):_(``,!0),S(`form`,{onSubmit:A(ee,[`prevent`]),class:`modal-form`},[S(`div`,ua,[r[9]||=S(`label`,{class:`modal-field-label`},`Entry Type`,-1),S(`div`,da,[S(`button`,{type:`button`,onClick:r[0]||=e=>T.value=`region`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,T.value===`region`?`bg-secondary/20 text-secondary border border-secondary/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},`REGION`,2),S(`button`,{type:`button`,onClick:r[1]||=e=>T.value=`privateKey`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,T.value===`privateKey`?`bg-accent-green/20 text-accent-green border border-accent-green/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},`PRIVATE KEY`,2)])]),S(`div`,null,[S(`label`,fa,l(D.value.type)+` Name`,1),S(`div`,pa,[E.value?(a(),C(`span`,ma,`#`)):_(``,!0),i(S(`input`,{"onUpdate:modelValue":r[2]||=e=>g.value=e,type:`text`,placeholder:E.value?`e.g., uk, au, us`:`Enter key name`,class:p([`modal-input`,E.value?`rounded-l-none`:``]),autocomplete:`off`},null,10,ha),[[j,g.value]])]),E.value?(a(),C(`p`,ga,` The # prefix is added automatically for regions. `)):_(``,!0),!f.value&&E.value&&e.node?.transport_key?(a(),C(`div`,_a,[S(`div`,va,[r[11]||=S(`span`,{class:`modal-field-label mb-0 mt-0`},`Transport Key`,-1),F.value?_(``,!0):(a(),C(`button`,{key:0,type:`button`,onClick:r[3]||=t=>c(R)(e.node.transport_key||``),class:p([`text-xs flex items-center gap-1 transition-colors`,c(z)?`text-accent-green`:`text-content-muted hover:text-accent-green`])},[r[10]||=S(`svg`,{class:`w-3 h-3`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),v(J,{copied:c(z)},null,8,[`copied`])],2))]),S(`input`,{value:L.value??e.node.transport_key,readonly:``,class:`modal-input-readonly w-full text-xs`},null,8,ya),F.value?(a(),C(`p`,ba,` Updated for "`+l(N.value)+`" `,1)):_(``,!0)])):_(``,!0)]),!f.value&&e.node?.last_used?(a(),C(`div`,xa,[S(`div`,Sa,[r[12]||=S(`div`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4 text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})]),S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Last Used`)],-1),S(`div`,Ca,[S(`div`,wa,l(e.node.last_used.toLocaleDateString())+` at `+l(e.node.last_used.toLocaleTimeString()),1),S(`div`,Ta,l(c(Y)(e.node.last_used)),1)])])])):_(``,!0),S(`div`,Ea,[r[13]||=S(`label`,{class:`modal-field-label pt-4`},`Flood Policy`,-1),S(`div`,Da,[S(`button`,{type:`button`,onClick:r[4]||=e=>w.value=`allow`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,w.value===`allow`?`bg-accent-green/10 text-accent-green border border-accent-green/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},`ALLOW`,2),S(`button`,{type:`button`,onClick:r[5]||=e=>w.value=`deny`,class:p([`flex-1 px-3 py-1.5 text-xs font-medium rounded transition-colors`,w.value===`deny`?`bg-accent-red/10 text-accent-red border border-accent-red/20`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},`DENY`,2)])]),S(`div`,Oa,[S(`button`,{type:`button`,class:`modal-btn-cancel`,onClick:V},`Cancel`),S(`button`,{type:`submit`,disabled:!B.value,class:p([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,B.value?`bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green`:`bg-background-mute dark:bg-stroke/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted cursor-not-allowed`])},l(f.value?`Add ${D.value.type}`:`Done`),11,ka)])],32)],2)])):_(``,!0)]))}}),ja={class:`modal-card max-w-lg`},Ma={class:`flex items-center gap-3 mb-6`},Na={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Pa={class:`text-accent-red font-mono`},Fa={key:0,class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},Ia={class:`flex items-start gap-3`},La={class:`flex-1`},Ra={class:`text-accent-red font-medium text-sm mb-2`},za={class:`space-y-1 max-h-32 overflow-y-auto`},Ba={key:0,class:`w-3 h-3 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Va={key:1,class:`w-3 h-3 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Ha={class:`font-mono`},Ua={key:0,class:`text-content-secondary dark:text-content-muted text-xs`},Wa={key:1,class:`mb-6`},Ga={class:`mb-3`},Ka={class:`relative`},qa={class:`space-y-2 max-h-40 overflow-y-auto border border-stroke-subtle dark:border-stroke/20 rounded-lg p-3 bg-gray-50 dark:bg-white/5`},Ja={key:0,class:`text-center py-4 text-content-secondary dark:text-content-muted text-sm`},Ya={class:`relative`},Xa=[`value`],Za={class:`flex items-center gap-2 flex-1`},Qa={class:`text-content-primary dark:text-content-primary font-mono text-sm`},$a={key:0,class:`ml-auto px-2 py-0.5 bg-background-mute dark:bg-stroke/10 text-content-secondary dark:text-content-muted text-xs rounded-full`},eo={class:`flex gap-3`},to=f({__name:`DeleteConfirmModal`,props:{show:{type:Boolean},node:{},allNodes:{}},emits:[`close`,`delete-all`,`move-children`],setup(e,{emit:n}){let r=e,s=n,c=o(null),d=o(``),f=e=>{let t=[],n=e=>{for(let r of e.children)t.push(r),n(r)};return n(e),t},h=y(()=>r.node?f(r.node):[]),g=y(()=>{if(!r.node)return[];let e=new Set([r.node.id,...h.value.map(e=>e.id)]),t=n=>{let r=[];for(let i of n)i.name.startsWith(`#`)&&!e.has(i.id)&&r.push(i),i.children.length>0&&r.push(...t(i.children));return r};return t(r.allNodes)}),v=y(()=>{if(!d.value.trim())return g.value;let e=d.value.toLowerCase();return g.value.filter(t=>t.name.toLowerCase().includes(e))}),w=()=>{r.node&&(s(`delete-all`,r.node.id),E())},T=()=>{!r.node||!c.value||(s(`move-children`,{nodeId:r.node.id,targetParentId:c.value}),E())},E=()=>{c.value=null,d.value=``,s(`close`)};return(n,r)=>(a(),u(m,{to:`body`},[e.show&&e.node?(a(),C(`div`,{key:0,onClick:r[2]||=A(e=>E(),[`self`]),class:`modal-backdrop-heavy`},[S(`div`,ja,[S(`div`,Ma,[r[6]||=S(`svg`,{class:`w-6 h-6 text-accent-red`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,null,[r[4]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Confirm Deletion `,-1),S(`p`,Na,[r[3]||=b(` Deleting `,-1),S(`span`,Pa,l(e.node?.name),1)])]),S(`button`,{onClick:E,class:`ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...r[5]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),h.value.length>0?(a(),C(`div`,Fa,[S(`div`,Ia,[r[9]||=S(`svg`,{class:`w-5 h-5 text-accent-red flex-shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),S(`div`,La,[S(`h4`,Ra,` This will affect `+l(h.value.length)+` child `+l(h.value.length===1?`entry`:`entries`)+`: `,1),S(`div`,za,[(a(!0),C(x,null,t(h.value.slice(0,10),e=>(a(),C(`div`,{key:e.id,class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-primary/80`},[e.name.startsWith(`#`)?(a(),C(`svg`,Ba,[...r[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(a(),C(`svg`,Va,[...r[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1721 9z`},null,-1)]])),S(`span`,Ha,l(e.name),1),S(`span`,{class:p([`px-1 py-0.5 text-xs rounded`,e.floodPolicy===`allow`?`bg-accent-green/20 text-accent-green`:`bg-accent-red/20 text-accent-red`])},l(e.floodPolicy),3)]))),128)),h.value.length>10?(a(),C(`div`,Ua,` ...and `+l(h.value.length-10)+` more `,1)):_(``,!0)])])])])):_(``,!0),h.value.length>0&&g.value.length>0?(a(),C(`div`,Wa,[r[13]||=S(`h4`,{class:`text-content-primary dark:text-content-primary font-medium text-sm mb-3`},` Move children to another region: `,-1),S(`div`,Ga,[S(`div`,Ka,[r[10]||=S(`svg`,{class:`absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-content-muted dark:text-content-muted`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z`})],-1),i(S(`input`,{"onUpdate:modelValue":r[0]||=e=>d.value=e,type:`text`,placeholder:`Search regions...`,class:`modal-input pl-9`},null,512),[[j,d.value]])])]),S(`div`,qa,[v.value.length===0?(a(),C(`div`,Ja,l(d.value?`No regions match your search`:`No available regions`),1)):_(``,!0),(a(!0),C(x,null,t(v.value,e=>(a(),C(`label`,{key:e.id,class:`flex items-center gap-3 p-2 rounded cursor-pointer hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors group`},[S(`div`,Ya,[i(S(`input`,{type:`radio`,value:e.id,"onUpdate:modelValue":r[1]||=e=>c.value=e,class:`sr-only peer`},null,8,Xa),[[k,c.value]]),r[11]||=S(`div`,{class:`w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-hover:border-stroke dark:group-hover:border-stroke/50 peer-checked:border-primary peer-checked:bg-primary/20 transition-all`},[S(`div`,{class:`w-2 h-2 rounded-full bg-primary scale-0 peer-checked:scale-100 transition-transform absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2`})],-1)]),S(`div`,Za,[r[12]||=S(`svg`,{class:`w-4 h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`})],-1),S(`span`,Qa,l(e.name),1),e.children.length>0?(a(),C(`span`,$a,l(e.children.length),1)):_(``,!0)])]))),128))])])):_(``,!0),S(`div`,eo,[S(`button`,{onClick:E,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `),h.value.length>0&&c.value?(a(),C(`button`,{key:0,onClick:T,class:`modal-btn-primary`},` Move & Delete `)):_(``,!0),S(`button`,{onClick:w,class:`modal-btn-danger`},l(h.value.length>0?`Delete All`:`Delete`),1)])])])):_(``,!0)]))}}),no={class:`space-y-12`},ro={class:`cfg-page-heading flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3`},io={class:`flex items-center gap-2 flex-shrink-0`},ao=[`disabled`],oo=[`disabled`],so=[`disabled`],co={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},lo={class:`text-red-600 dark:text-red-400 text-sm`},uo={class:`cfg-section`},fo={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},po={key:0,class:`text-xs text-content-muted dark:text-content-muted pb-1`},mo={key:1,class:`flex items-center justify-center py-8`},ho={key:2,class:`text-center py-8`},go={class:`text-content-secondary dark:text-content-muted text-sm`},_o={key:3,class:`text-center py-8`},vo={key:4,class:`space-y-2`},yo=f({name:`TransportKeys`,__name:`TransportKeys`,setup(n,{expose:r}){let i=hi(),s=ee(),d=o(!1),f=o(!1),m=o(null),g=-1;function w(){return g--}let T=o(`deny`),E=`deny`;h(y(()=>s.stats?.config?.mesh?.unscoped_flood_allow??null),e=>{e!==null&&!d.value&&(T.value=e?`allow`:`deny`)},{immediate:!0});let D=o([]),O=null,k=o(!1),A=o(null),j=o(!1),M=o(!1),N=o(!1),P=o(null),F=o(null);function I(e){return e.map(e=>({...e,children:I(e.children)}))}function L(e,t){let n=[];for(let r of e)n.push({node:r,parentId:t}),n.push(...L(r.children,r.id));return n}function z(e,t){for(let n of e){if(n.id===t)return n;let e=z(n.children,t);if(e)return e}return null}function B(e,t){let n=e.findIndex(e=>e.id===t);if(n!==-1)return e.splice(n,1),!0;for(let n of e)if(B(n.children,t))return!0;return!1}let V=e=>{let t=new Map,n=[];return e.forEach(e=>{t.set(e.id,{id:e.id,name:e.name,floodPolicy:e.flood_policy,transport_key:e.transport_key,last_used:e.last_used?new Date(e.last_used*1e3):void 0,parent_id:e.parent_id,children:[]})}),t.forEach(e=>{e.parent_id&&t.has(e.parent_id)?t.get(e.parent_id).children.push(e):n.push(e)}),n},H=async()=>{k.value=!0,A.value=null;try{let e=await R.getTransportKeys();e.success&&e.data?D.value=V(e.data):A.value=e.error||`Failed to load regions`}catch(e){A.value=e instanceof Error?e.message:`Unknown error occurred`}finally{k.value=!1}};e(H);function U(){O=I(D.value),E=T.value,d.value=!0,m.value=null}function G(){O&&(D.value=I(O)),T.value=E,O=null,d.value=!1,m.value=null,i.setSelectedNode(null)}async function K(){f.value=!0,m.value=null;try{let e=L(D.value),t=O?L(O):[],n=new Map(t.map(({node:e})=>[e.id,e])),r=e.filter(({node:e})=>e.id>0),a=e.filter(({node:e})=>e.id<0),o=new Set(r.map(({node:e})=>e.id));for(let{node:e}of t)o.has(e.id)||await R.deleteTransportKey(e.id);let c=new Map,l=[...a],u=l.length*2;for(;l.length&&u-- >0;){let e=l.findIndex(({parentId:e})=>e===void 0||e>0||e<0&&c.has(e));if(e===-1)break;let{node:t,parentId:n}=l.splice(e,1)[0],r=n===void 0?void 0:n>0?n:c.get(n),i=await R.createTransportKey(t.name,t.floodPolicy,t.transport_key,r);i.success&&i.data?.id&&c.set(t.id,i.data.id)}for(let{node:e}of r){let t=n.get(e.id);t&&(e.name!==t.name||e.floodPolicy!==t.floodPolicy||e.transport_key!==t.transport_key)&&await R.updateTransportKey(e.id,e.name,e.floodPolicy,e.transport_key)}T.value!==E&&await R.updateUnscopedFloodPolicy(T.value===`allow`),await H(),await s.fetchStats(),O=null,d.value=!1,i.setSelectedNode(null)}catch(e){m.value=e instanceof Error?e.message:`Save failed`}finally{f.value=!1}}function te(e){i.setSelectedNode(e)}function q(){j.value=!0}function ne(e){let t={id:w(),name:e.name,floodPolicy:e.floodPolicy,children:[]};if(e.parentId){let n=z(D.value,e.parentId);n?n.children.push(t):D.value.push(t)}else D.value.push(t);j.value=!1}function re(e){let t=z(D.value,e);t&&(P.value=t,M.value=!0)}function ie(e){let t=z(D.value,e.id);t&&(t.name=e.name,t.floodPolicy=e.floodPolicy,e.transportKey!==void 0&&(t.transport_key=e.transportKey)),M.value=!1,P.value=null}function J(){M.value=!1,P.value=null}function Y(e){let t=z(D.value,e);t&&(F.value=t,N.value=!0)}function X(e){B(D.value,e),i.setSelectedNode(null),N.value=!1,F.value=null}function Z(e){let t=z(D.value,e.nodeId);if(t?.children.length){let n=z(D.value,e.targetParentId);n?n.children.push(...t.children):D.value.push(...t.children)}B(D.value,e.nodeId),i.setSelectedNode(null),N.value=!1,F.value=null}function Q(e){T.value=e}let{showUnsavedModal:ae,requestLeave:oe,handleDiscard:se,handleSave:$,handleCancel:ce}=pe(d,f,G,async()=>(await K(),!d.value));return r({requestLeave:oe,isEditing:d}),(e,n)=>(a(),C(x,null,[v(fe,{show:c(ae),"is-saving":f.value,label:`Region Configuration`,onDiscard:c(se),onSave:c($),onCancel:c(ce)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,no,[S(`div`,ro,[n[6]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Region Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Manage regional key hierarchy `)],-1),S(`div`,io,[d.value?(a(),C(`button`,{key:0,onClick:q,class:`cfg-btn-secondary flex items-center gap-1.5`,disabled:f.value},[...n[5]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Add Region `,-1)]],8,ao)):_(``,!0),d.value?(a(),C(x,{key:2},[S(`button`,{onClick:G,disabled:f.value,class:`cfg-btn-secondary`},`Cancel`,8,oo),S(`button`,{onClick:K,disabled:f.value,class:`cfg-btn-primary`},l(f.value?`Saving…`:`Save Changes`),9,so)],64)):(a(),C(`button`,{key:1,onClick:U,class:`cfg-btn-primary`},`Edit Settings`))])]),m.value?(a(),C(`div`,co,[S(`p`,lo,l(m.value),1)])):_(``,!0),S(`div`,uo,[S(`div`,fo,[n[7]||=S(`div`,null,[S(`h4`,{class:`text-xs sm:text-sm font-medium text-content-primary dark:text-content-primary mb-1`},` Unscoped Flood Policy (*) `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-[10px] sm:text-xs`},` Allow or Deny unscoped flood packets `)],-1),S(`div`,{class:p([`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5 sm:p-1`,d.value?``:`opacity-50 pointer-events-none`])},[S(`button`,{onClick:n[0]||=e=>Q(`deny`),class:p([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,T.value===`deny`?`bg-accent-red/20 text-accent-red border border-accent-red/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` DENY `,2),S(`button`,{onClick:n[1]||=e=>Q(`allow`),class:p([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,T.value===`allow`?`bg-accent-green/20 text-accent-green border border-accent-green/50`:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-secondary`])},` ALLOW `,2)],2)])]),S(`div`,{class:`cfg-section space-y-4`,onClick:n[2]||=e=>d.value&&c(i).setSelectedNode(null)},[n[11]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},`Regions`,-1),d.value?(a(),C(`p`,po,` To add a child region, click on a region to select it, then click "Add Region". `)):_(``,!0),k.value?(a(),C(`div`,mo,[v(W),n[8]||=S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading regions…`,-1)])):A.value?(a(),C(`div`,ho,[n[9]||=S(`div`,{class:`text-accent-red mb-2`},`⚠️ Error loading regions`,-1),S(`div`,go,l(A.value),1),S(`button`,{onClick:H,class:`btn-success mt-4`},` Retry `)])):D.value.length===0?(a(),C(`div`,_o,[...n[10]||=[S(`div`,{class:`text-content-muted dark:text-content-muted mb-2`},`No regions found`,-1),S(`div`,{class:`text-content-muted dark:text-content-muted/60 text-sm`},` Click "Edit Settings" then "Add Region" to get started `,-1)]])):(a(),C(`div`,vo,[(a(!0),C(x,null,t(D.value,e=>(a(),u(Pi,{key:e.id,node:e,"selected-node-id":c(i).selectedNodeId.value,level:0,unlocked:d.value,onSelect:te,onEdit:re,onDelete:Y},null,8,[`node`,`selected-node-id`,`unlocked`]))),128))]))]),v(Aa,{show:j.value,node:null,"selected-parent-id":c(i).selectedNodeId.value||void 0,"all-nodes":D.value,onClose:n[3]||=e=>j.value=!1,onAdd:ne},null,8,[`show`,`selected-parent-id`,`all-nodes`]),v(Aa,{show:M.value,node:P.value,"all-nodes":D.value,onClose:J,onSave:ie},null,8,[`show`,`node`,`all-nodes`]),v(to,{show:N.value,node:F.value,"all-nodes":D.value,onClose:n[4]||=e=>{N.value=!1,F.value=null},onDeleteAll:X,onMoveChildren:Z},null,8,[`show`,`node`,`all-nodes`])])],64))}}),bo={class:`space-y-12`},xo={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},So={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-4`},Co={class:`flex items-center gap-2 text-red-600 dark:text-red-400`},wo={key:1,class:`flex items-center justify-center py-12`},To={class:`text-center`},Eo={key:2,class:`space-y-3`},Do={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},Oo={class:`flex-1`},ko={class:`flex items-center gap-2 sm:gap-3`},Ao={class:`min-w-0 flex-1`},jo={class:`text-content-primary dark:text-content-primary font-medium text-sm sm:text-base break-all`},Mo={class:`flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-1 text-xs text-content-secondary dark:text-content-muted`},No={class:`truncate`},Po={class:`truncate`},Fo=[`onClick`,`disabled`],Io={key:3,class:`text-center py-12`},Lo={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-6 max-w-md w-full shadow-2xl`},Ro={class:`space-y-4`},zo={class:`flex justify-end gap-3 mt-6`},Bo=[`disabled`],Vo=[`disabled`],Ho={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-6 max-w-lg w-full shadow-2xl`},Uo={class:`space-y-4`},Wo={class:`flex gap-2`},Go=[`value`],Ko={key:0,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},qo={key:1,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Jo={class:`cfg-card p-4`},Yo={class:`code-block`},Xo=f({name:`APITokens`,__name:`APITokens`,setup(n){let r=o([]),s=o(!1),u=o(null),f=o(!1),m=o(``),h=o(null),g=o(!1),w=o(!1),T=o(null),E=async()=>{s.value=!0,u.value=null;try{let e=await R.get(`/auth/tokens`);r.value=(e.data||e).tokens||[]}catch(e){console.error(`Failed to fetch API tokens:`,e),u.value=e instanceof Error?e.message:`Failed to fetch tokens`}finally{s.value=!1}},D=async()=>{if(!m.value.trim()){u.value=`Token name is required`;return}s.value=!0,u.value=null;try{let e=await R.post(`/auth/tokens`,{name:m.value.trim()});h.value=(e.data||e).token||null,f.value=!1,g.value=!0,m.value=``,await E()}catch(e){console.error(`Failed to create API token:`,e),u.value=e instanceof Error?e.message:`Failed to create token`}finally{s.value=!1}},k=(e,t)=>{T.value={id:e,name:t},w.value=!0},M=async()=>{if(T.value){s.value=!0,u.value=null;try{await R.delete(`/auth/tokens/${T.value.id}`),await E(),w.value=!1,T.value=null}catch(e){console.error(`Failed to revoke API token:`,e),u.value=e instanceof Error?e.message:`Failed to revoke token`}finally{s.value=!1}}},N=()=>{f.value=!1,m.value=``,u.value=null},P=()=>{g.value=!1,h.value=null},{copy:F,copied:I}=ie(),L=()=>{h.value&&F(h.value)},z=e=>e?new Date(e*1e3).toLocaleString():`Never`,B=y(()=>`${window.location.origin}/api/stats`);return e(()=>{E()}),(e,n)=>(a(),C(x,null,[S(`div`,bo,[S(`div`,xo,[n[5]||=S(`div`,null,[S(`h2`,{class:`text-lg sm:text-xl font-semibold text-content-primary dark:text-content-primary`},` API Tokens `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mt-1`},` Manage API tokens for machine-to-machine authentication `)],-1),S(`button`,{onClick:n[0]||=e=>f.value=!0,class:`cfg-btn-primary flex items-center justify-center gap-2`},[...n[4]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Create Token `,-1)]])]),n[21]||=d(`

API tokens are used for machine-to-machine authentication. Include the token in the X-API-Key header when making API requests.

Tokens are only shown once at creation. Store them securely.

`,1),u.value?(a(),C(`div`,So,[S(`div`,Co,[n[6]||=S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),b(` `+l(u.value),1)])])):_(``,!0),s.value&&r.value.length===0?(a(),C(`div`,wo,[S(`div`,To,[v(W,{class:`mx-auto mb-4`}),n[7]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading tokens...`,-1)])])):r.value.length>0?(a(),C(`div`,Eo,[(a(!0),C(x,null,t(r.value,e=>(a(),C(`div`,{key:e.id,class:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-3 sm:p-4 hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors`},[S(`div`,Do,[S(`div`,Oo,[S(`div`,ko,[n[8]||=S(`svg`,{class:`w-4 h-4 sm:w-5 sm:h-5 text-primary flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})],-1),S(`div`,Ao,[S(`h3`,jo,l(e.name),1),S(`div`,Mo,[S(`span`,No,`Created: `+l(z(e.created_at)),1),S(`span`,Po,`Last used: `+l(z(e.last_used)),1)])])])]),S(`button`,{onClick:t=>k(e.id,e.name),disabled:s.value,class:`w-full sm:w-auto px-3 py-1.5 bg-red-100 dark:bg-red-500/20 hover:bg-red-500/30 text-red-600 dark:text-red-400 rounded-lg border border-red-500/50 transition-colors disabled:opacity-50 text-sm`},` Revoke `,8,Fo)])]))),128))])):(a(),C(`div`,Io,[n[9]||=S(`svg`,{class:`w-16 h-16 text-content-muted dark:text-content-muted/40 mx-auto mb-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})],-1),n[10]||=S(`h3`,{class:`text-content-primary dark:text-content-primary font-medium mb-2`},`No API Tokens`,-1),n[11]||=S(`p`,{class:`text-content-secondary dark:text-content-muted text-sm mb-4`},` Create a token to enable API access `,-1),S(`button`,{onClick:n[1]||=e=>f.value=!0,class:`cfg-btn-primary`},` Create Your First Token `)])),f.value?(a(),C(`div`,{key:4,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(N,[`self`])},[S(`div`,Lo,[n[14]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Create API Token `,-1),S(`div`,Ro,[S(`div`,null,[n[12]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Token Name`,-1),i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>m.value=e,type:`text`,placeholder:`e.g., Production Server, CI/CD Pipeline`,class:`cfg-input placeholder-gray-400 dark:placeholder-white/40`,onKeydown:O(D,[`enter`])},null,544),[[j,m.value]]),n[13]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted mt-1`},` Give your token a descriptive name to identify its purpose `,-1)]),S(`div`,zo,[S(`button`,{onClick:N,disabled:s.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/10 transition-colors disabled:opacity-50`},` Cancel `,8,Bo),S(`button`,{onClick:D,disabled:s.value||!m.value.trim(),class:`btn-primary`},l(s.value?`Creating...`:`Create Token`),9,Vo)])])])])):_(``,!0),g.value&&h.value?(a(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(P,[`self`])},[S(`div`,Ho,[n[20]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Token Created Successfully `,-1),S(`div`,Uo,[n[19]||=d(`
Save this token now! For security reasons, it will not be shown again.
`,1),S(`div`,null,[n[17]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Your API Token`,-1),S(`div`,Wo,[S(`input`,{value:h.value,readonly:``,class:`modal-input-readonly flex-1 text-sm`},null,8,Go),S(`button`,{onClick:L,class:p([`flex items-center gap-2 transition-colors`,c(I)?`btn-success`:`btn-primary`])},[c(I)?(a(),C(`svg`,qo,[...n[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(a(),C(`svg`,Ko,[...n[15]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`},null,-1)]])),v(J,{copied:c(I)},null,8,[`copied`])],2)])]),S(`div`,Jo,[n[18]||=S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted mb-2`},[S(`strong`,null,`Usage Example:`)],-1),S(`code`,Yo,` curl -H "X-API-Key: `+l(h.value)+`" `+l(B.value),1)]),S(`div`,{class:`flex justify-end mt-6`},[S(`button`,{onClick:P,class:`btn-primary`},` Done `)])])])])):_(``,!0)]),v(ne,{show:w.value,title:`Revoke API Token`,message:`Are you sure you want to revoke the token '${T.value?.name}'? This action cannot be undone.`,"confirm-text":`Revoke`,"cancel-text":`Cancel`,variant:`danger`,onConfirm:M,onClose:n[3]||=e=>w.value=!1},null,8,[`show`,`message`])],64))}}),Zo={class:`space-y-12`},Qo={class:`cfg-section`},$o={class:`space-y-4`},es=[`disabled`],ts={class:`cfg-section`},ns={class:`space-y-4`},rs={class:`flex items-center justify-between`},is=[`disabled`],as={class:`cfg-section`},os={class:`space-y-4`},ss={class:`space-y-3`},cs=[`checked`,`disabled`],ls=[`checked`,`disabled`],us={class:`flex items-start gap-3`},ds={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400 flex-shrink-0 mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},fs={key:1,class:`w-5 h-5 text-accent-cyan flex-shrink-0 mt-0.5`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ps={class:`flex-1`},ms={class:`text-sm font-medium text-content-primary dark:text-content-primary`},hs={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-1`},gs={key:1,class:`p-4 bg-amber-500/10 border border-amber-500/30 rounded-lg`},_s={class:`flex items-start justify-between gap-3`},vs=[`disabled`],ys={key:0,class:`animate-spin h-4 w-4`,fill:`none`,viewBox:`0 0 24 24`},bs={key:1,class:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},xs={class:`flex items-center space-x-2`},Ss={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},Cs={key:1,class:`w-5 h-5 text-red-600 dark:text-red-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},ws=f({name:`WebSettings`,__name:`WebSettings`,setup(t){let{stats:n}=B(ee()),r=o(!1),c=o(``),u=o(!1),f=o(!1),m=o(!1),h=o(!1),g=o(!0),v=s({cors_enabled:!1,use_default_frontend:!0,site_name:``}),w=y(()=>u.value?`bg-green-500/10 border-green-600/40 dark:border-green-500/30`:`bg-red-500/10 border-red-500/30`);async function T(){try{g.value=!0;let e=await R.get(`/check_pymc_console`);e.success&&e.data&&(h.value=e.data.exists)}catch(e){console.error(`Failed to check PyMC Console:`,e),h.value=!1}finally{g.value=!1}}function E(){let e=n.value?.config?.web||{};v.cors_enabled=e.cors_enabled===!0;let t=e.web_path;v.use_default_frontend=!t||t===``,v.site_name=typeof n.value?.site_name==`string`?n.value.site_name:``}async function D(){r.value=!0,c.value=``;try{let e={web:{cors_enabled:v.cors_enabled,site_name:v.site_name.trim()}};v.use_default_frontend?e.web.web_path=null:e.web.web_path=`/opt/pymc_console/web/html`;let t=await R.post(`/update_web_config`,e);t.success?(M(`Settings saved successfully`,!0),f.value=!0):M(t.error||`Failed to save settings`,!1)}catch(e){console.error(`Failed to save web settings:`,e),M(e.message||`Failed to save settings`,!1)}finally{r.value=!1}}async function O(){v.cors_enabled=!v.cors_enabled,await D()}async function k(){v.use_default_frontend=!0,await D()}async function A(){if(!h.value){M(`PyMC Console is not installed. Please install it before switching.`,!1);return}v.use_default_frontend=!1,await D()}function M(e,t){c.value=e,u.value=t,setTimeout(()=>{c.value=``},5e3)}async function N(){m.value=!0,c.value=``;try{let e=await R.post(`/restart_service`,{});e.success?(M(`Service restart initiated. Page will reload...`,!0),f.value=!1,setTimeout(()=>{window.location.reload()},2e3)):M(e.error||`Failed to restart service`,!1)}catch(e){e.code===`ERR_NETWORK`||e.message?.includes(`Network error`)?(M(`Service restarting... Page will reload`,!0),f.value=!1,setTimeout(()=>{window.location.reload()},3e3)):(console.error(`Failed to restart service:`,e),M(e.message||`Failed to restart service`,!1))}finally{m.value=!1}}return e(()=>{E(),T()}),(e,t)=>(a(),C(`div`,Zo,[t[18]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Web Options`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure site identification, CORS policy and web frontend selection`)])],-1),S(`div`,Qo,[t[3]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Site Identification `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Customise the browser tab title and login page caption `)])],-1),S(`div`,$o,[S(`div`,null,[t[1]||=S(`label`,{for:`site-name`,class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Site Name `,-1),i(S(`input`,{id:`site-name`,"onUpdate:modelValue":t[0]||=e=>v.site_name=e,type:`text`,maxlength:`80`,placeholder:`e.g. Base Station Alpha`,class:`w-full px-3 py-2 rounded-lg bg-background-mute dark:bg-background/40 border border-stroke-subtle dark:border-stroke/20 text-sm text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/30 focus:outline-none focus:border-primary/50 transition-colors`,onChange:D,disabled:r.value},null,40,es),[[j,v.site_name]]),t[2]||=S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1.5`},` Shown in the browser tab and above the login form. Leave blank to use the default title. `,-1)])])]),S(`div`,ts,[t[5]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` CORS Settings `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Control cross-origin resource sharing for API access `)])],-1),S(`div`,ns,[S(`div`,rs,[t[4]||=S(`div`,null,[S(`label`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enable CORS`),S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1`},` Allow web frontends from different origins to access the API `)],-1),S(`button`,{onClick:O,disabled:r.value,class:p([`relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2`,v.cors_enabled?`bg-cyan-600 dark:bg-teal-500 border-cyan-600 dark:border-teal-500`:`bg-gray-400 dark:bg-gray-600 border-gray-400 dark:border-gray-600`,r.value?`opacity-50 cursor-not-allowed`:`cursor-pointer`])},[S(`span`,{class:p([`inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg`,v.cors_enabled?`translate-x-5`:`translate-x-0.5`])},null,2)],10,is)])])]),S(`div`,as,[t[15]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Web Frontend `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Choose which web interface to use `)])],-1),S(`div`,os,[S(`div`,ss,[S(`label`,{class:p([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all`,v.use_default_frontend?`border-accent-cyan bg-accent-cyan/10`:`border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50`])},[S(`input`,{type:`radio`,name:`frontend`,checked:v.use_default_frontend,onChange:k,disabled:r.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,cs),t[6]||=S(`div`,{class:`flex-1`},[S(`div`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Default Frontend `),S(`div`,{class:`text-xs text-content-secondary dark:text-content-muted mt-1`},` Built-in Repeater web interface `),S(`div`,{class:`text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono`},` Built-in `)],-1)],2),S(`label`,{class:p([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 transition-all`,h.value?`cursor-pointer`:`opacity-50 cursor-not-allowed`,v.use_default_frontend?`border-stroke-subtle dark:border-stroke/10 hover:border-accent-cyan/50`:`border-accent-cyan bg-accent-cyan/10`])},[S(`input`,{type:`radio`,name:`frontend`,checked:!v.use_default_frontend,onChange:A,disabled:r.value||!h.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,ls),t[7]||=d(`
PyMC Console
@Treehouse⚡
Alternative web interface for Repeater
/opt/pymc_console/web/html
`,1)],2)]),g.value?_(``,!0):(a(),C(`div`,{key:0,class:p([`p-4 rounded-lg border`,h.value?`bg-green-500/5 border-green-500/20`:`bg-accent-cyan/5 border-accent-cyan/20`])},[S(`div`,us,[h.value?(a(),C(`svg`,ds,[...t[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])):(a(),C(`svg`,fs,[...t[9]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])),S(`div`,ps,[S(`h4`,ms,l(h.value?`PyMC Console has been detected`:`PyMC Console Not Installed`),1),h.value?(a(),C(`p`,hs,[...t[10]||=[b(` PyMC Console is installed at `,-1),S(`code`,{class:`text-green-700 dark:text-green-300`},`/opt/pymc_console/web/html`,-1)]])):(a(),C(x,{key:1},[t[11]||=d(`

PyMC Console must be installed at /opt/pymc_console/web/html before selecting this option.

PyMC Console Install Instructions `,2)],64))])])],2)),f.value?(a(),C(`div`,gs,[S(`div`,_s,[t[14]||=d(`

Service restart required

Web frontend changes will take effect after restarting the pymc-repeater service.

`,1),S(`button`,{onClick:N,disabled:m.value,class:`px-4 py-2 bg-amber-500 hover:bg-amber-600 disabled:bg-amber-500/50 text-white font-medium rounded-lg transition-colors disabled:cursor-not-allowed flex items-center gap-2 whitespace-nowrap`},[m.value?(a(),C(`svg`,ys,[...t[12]||=[S(`circle`,{class:`opacity-25`,cx:`12`,cy:`12`,r:`10`,stroke:`currentColor`,"stroke-width":`4`},null,-1),S(`path`,{class:`opacity-75`,fill:`currentColor`,d:`M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z`},null,-1)]])):(a(),C(`svg`,bs,[...t[13]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`},null,-1)]])),b(` `+l(m.value?`Restarting...`:`Restart Now`),1)],8,vs)])])):_(``,!0)])]),c.value?(a(),C(`div`,{key:0,class:p([`p-4 rounded-lg border`,w.value])},[S(`div`,xs,[u.value?(a(),C(`svg`,Ss,[...t[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(a(),C(`svg`,Cs,[...t[17]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`},null,-1)]])),S(`span`,{class:p(u.value?`text-green-600 dark:text-green-400`:`text-red-600 dark:text-red-400`)},l(c.value),3)])],2)):_(``,!0)]))}}),Ts={ref:`rootEl`,class:`space-y-12`},Es={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Ds={class:`flex items-center gap-2 flex-shrink-0`},Os=[`disabled`],ks=[`disabled`],As={key:0,class:`bg-accent-green/20 border border-accent-green/50 rounded-lg p-3 text-accent-green text-sm`},js={key:1,class:`bg-accent-red/20 border border-accent-red/50 rounded-lg p-3 text-accent-red text-sm`},Ms={class:`cfg-section space-y-3`},Ns={key:0,class:`flex items-center justify-center py-4`},Ps={key:1,class:`text-center py-4`},Fs={class:`grid grid-cols-2 sm:grid-cols-4 gap-3`},Is={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Ls={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Rs={class:`text-lg font-mono text-content-primary dark:text-content-primary`},zs={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Bs={class:`text-lg font-mono text-accent-green`},Vs={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Hs={class:`text-lg font-mono text-accent-red`},Us={key:0,class:`mt-2 p-2 bg-accent-red/10 rounded-lg border border-accent-red/20`},Ws={key:1,class:`mt-2 p-2 bg-secondary/10 rounded-lg border border-secondary/20`},Gs={class:`font-medium`},Ks={class:`font-mono text-[10px] opacity-70`},qs={class:`text-[10px]`},Js={class:`cfg-section space-y-3`},Ys={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Xs={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Zs={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Qs={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$s={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},ec={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},tc={key:1,class:`flex items-center gap-2`},nc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},rc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},ic={key:1,class:`flex items-center gap-2`},ac={class:`cfg-section space-y-3`},oc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},sc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},cc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},lc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},uc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},dc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},fc={key:1,class:`flex items-center gap-2`},pc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},mc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},hc={key:1,class:`flex items-center gap-2`},gc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},_c={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},vc={key:1,class:`flex items-center gap-2`},yc={class:`cfg-section space-y-3`},bc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},xc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Sc={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Cc={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},wc={key:1,class:`flex items-center gap-2`},Tc={class:`py-2`},Ec={class:`grid grid-cols-3 gap-2 mt-2`},Dc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Oc={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},kc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Ac={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},jc={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg border border-stroke-subtle dark:border-white/10`},Mc={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},Nc={class:`p-6 space-y-4`},Pc={class:`flex justify-between items-start`},Fc={class:`flex justify-end pt-4 border-t border-stroke-subtle dark:border-stroke/20`},Ic=f({__name:`AdvertSettings`,setup(n,{expose:r}){let s=ee(),u=y(()=>s.stats?.config?.repeater||{}),f=y(()=>u.value.advert_rate_limit||{}),m=y(()=>u.value.advert_penalty_box||{}),g=y(()=>u.value.advert_adaptive||{}),w=y(()=>g.value.thresholds||{}),T=o(!1),O=o(!1),k=o(``),M=o(``),N=o(!1),P=o(!1),F=o(null),I=o(!0),L=o(2),z=o(1),B=o(10),V=o(60),H=o(!0),U=o(2),G=o(12),K=o(6),te=o(2),q=o(24),ne=o(!0),re=o(.1),ie=o(5),J=o(.05),Y=o(.2),X=o(.5),Z=async()=>{P.value=!0;try{let e=await R.get(`/advert_rate_limit_stats`);e.success&&(F.value=e.data)}catch(e){console.error(`Failed to fetch rate limit stats:`,e)}finally{P.value=!1}};h([f,m,g],()=>{T.value||(I.value=f.value.enabled??!1,L.value=f.value.bucket_capacity??2,z.value=f.value.refill_tokens??1,B.value=Math.round((f.value.refill_interval_seconds??36e3)/3600),V.value=Math.round((f.value.min_interval_seconds??0)/60),H.value=m.value.enabled??!1,U.value=m.value.violation_threshold??2,G.value=Math.round((m.value.violation_decay_seconds??43200)/3600),K.value=Math.round((m.value.base_penalty_seconds??21600)/3600),te.value=m.value.penalty_multiplier??2,q.value=Math.round((m.value.max_penalty_seconds??86400)/3600),ne.value=g.value.enabled??!1,re.value=g.value.ewma_alpha??.1,ie.value=Math.round((g.value.hysteresis_seconds??300)/60),J.value=w.value.quiet_max??.05,Y.value=w.value.normal_max??.2,X.value=w.value.busy_max??.5)},{immediate:!0}),e(()=>{Z()});let Q=()=>{I.value=f.value.enabled??!1,L.value=f.value.bucket_capacity??2,z.value=f.value.refill_tokens??1,B.value=Math.round((f.value.refill_interval_seconds??36e3)/3600),V.value=Math.round((f.value.min_interval_seconds??0)/60),H.value=m.value.enabled??!1,U.value=m.value.violation_threshold??2,G.value=Math.round((m.value.violation_decay_seconds??43200)/3600),K.value=Math.round((m.value.base_penalty_seconds??21600)/3600),te.value=m.value.penalty_multiplier??2,q.value=Math.round((m.value.max_penalty_seconds??86400)/3600),ne.value=g.value.enabled??!1,re.value=g.value.ewma_alpha??.1,ie.value=Math.round((g.value.hysteresis_seconds??300)/60),J.value=w.value.quiet_max??.05,Y.value=w.value.normal_max??.2,X.value=w.value.busy_max??.5},ae=()=>{T.value=!0,k.value=``,M.value=``},oe=()=>{T.value=!1,k.value=``,M.value=``,Q()},se=async()=>{O.value=!0,M.value=``,k.value=``;try{let e={rate_limit_enabled:I.value,bucket_capacity:L.value,refill_tokens:z.value,refill_interval_seconds:B.value*3600,min_interval_seconds:V.value*60,penalty_enabled:H.value,violation_threshold:U.value,violation_decay_seconds:G.value*3600,base_penalty_seconds:K.value*3600,penalty_multiplier:te.value,max_penalty_seconds:q.value*3600,adaptive_enabled:ne.value,ewma_alpha:re.value,hysteresis_seconds:ie.value*60,quiet_max:J.value,normal_max:Y.value,busy_max:X.value},t=await R.post(`/update_advert_rate_limit_config`,e),n=t.data;t.success?(k.value=n?.message||`Settings saved successfully`,await s.fetchStats(),await Z(),await E(),Q(),T.value=!1,setTimeout(()=>{k.value=``},3e3)):(M.value=n?.error||`Failed to save settings`,console.error(`[AdvertSettings] Save failed:`,n?.error))}catch(e){console.error(`Failed to save advert settings:`,e),M.value=e.response?.data?.error||`Failed to save settings`}finally{O.value=!1}},{showUnsavedModal:$,requestLeave:ce,handleDiscard:le,handleSave:ue,handleCancel:de}=pe(T,O,oe,async()=>(await se(),!T.value));r({requestLeave:ce,isEditing:T});let me=y(()=>F.value?.adaptive?.current_tier||`unknown`),he=y(()=>{switch(me.value){case`quiet`:return`bg-accent-green/20 text-accent-green border-accent-green/50`;case`normal`:return`bg-accent-cyan/20 text-accent-cyan border-accent-cyan/50`;case`busy`:return`bg-secondary/20 text-secondary border-secondary/50`;case`congested`:return`bg-accent-red/20 text-accent-red border-accent-red/50`;default:return`bg-background-mute text-content-muted border-stroke-subtle`}});return(e,n)=>(a(),C(x,null,[v(fe,{show:c($),"is-saving":O.value,label:`Advert Limit settings`,onDiscard:c(le),onSave:c(ue),onCancel:c(de)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,Ts,[S(`div`,Es,[n[20]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Advert Limits`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Configure advertisement rate limiting and adaptive controls`)],-1),S(`div`,Ds,[S(`button`,{onClick:n[0]||=e=>N.value=!0,class:`self-stretch flex items-center justify-center px-3 text-xs bg-primary/10 hover:bg-primary/20 text-primary rounded-lg border border-primary/30 transition-colors`,title:`How rate limiting works`},[...n[19]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})],-1)]]),T.value?(a(),C(x,{key:1},[S(`button`,{onClick:oe,disabled:O.value,class:`cfg-btn-secondary`},` Cancel `,8,Os),S(`button`,{onClick:se,disabled:O.value,class:`cfg-btn-primary`},l(O.value?`Saving...`:`Save Changes`),9,ks)],64)):(a(),C(`button`,{key:0,onClick:ae,class:`cfg-btn-primary`},` Edit Settings `))])]),k.value?(a(),C(`div`,As,l(k.value),1)):_(``,!0),M.value?(a(),C(`div`,js,l(M.value),1)):_(``,!0),S(`div`,Ms,[n[29]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary`},` Current Status `,-1),P.value&&!F.value?(a(),C(`div`,Ns,[v(W,{size:`sm`}),n[21]||=S(`span`,{class:`ml-2 text-sm text-content-muted`},`Loading stats...`,-1)])):F.value?(a(),C(x,{key:2},[S(`div`,Fs,[S(`div`,Is,[n[23]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Mesh Tier`,-1),S(`div`,{class:p([`mt-1 px-2 py-0.5 rounded border text-xs font-medium inline-block`,he.value])},l(me.value.toUpperCase()),3)]),S(`div`,Ls,[n[24]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Adverts/min`,-1),S(`div`,Rs,l(F.value.metrics?.adverts_per_min_ewma?.toFixed(2)||`0.00`),1)]),S(`div`,zs,[n[25]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Allowed`,-1),S(`div`,Bs,l(F.value.stats?.adverts_allowed||0),1)]),S(`div`,Vs,[n[26]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Dropped`,-1),S(`div`,Hs,l(F.value.stats?.adverts_dropped||0),1)])]),Object.keys(F.value.active_penalties||{}).length>0?(a(),C(`div`,Us,[n[27]||=S(`div`,{class:`text-xs font-medium text-accent-red mb-1`},` Active Penalties `,-1),(a(!0),C(x,null,t(F.value.active_penalties,(e,t)=>(a(),C(`div`,{key:t,class:`text-xs font-mono text-accent-red`},l(t)+`... - `+l(Math.round(e))+`s remaining `,1))),128))])):_(``,!0),F.value.recent_drops&&F.value.recent_drops.length>0?(a(),C(`div`,Ws,[n[28]||=S(`div`,{class:`text-xs font-medium text-secondary mb-1`},` Recently Dropped Adverts `,-1),(a(!0),C(x,null,t(F.value.recent_drops,(e,t)=>(a(),C(`div`,{key:t,class:`text-xs text-secondary py-0.5`},[S(`span`,Gs,l(e.name),1),S(`span`,Ks,`(`+l(e.pubkey)+`...)`,1),S(`span`,qs,` - `+l(e.reason)+` (`+l(e.seconds_ago)+`s ago)`,1)]))),128))])):_(``,!0)],64)):(a(),C(`div`,Ps,[...n[22]||=[S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Stats not available. Click "Refresh Stats" to load. `,-1)]])),n[30]||=d(`

There are three layers of advert rate limit control: Each layer can be enabled/disabled independently and the others will still function.

  • Rate Limiting OFF: All limiting disabled — adverts pass through freely
  • Adaptive OFF: Token bucket uses fixed limits (no tier scaling), penalty box still works
  • Penalty Box OFF: Token bucket still applies, but no escalating cooldowns for repeat offenders

Decision flow when all enabled: Adaptive tier check → Penalty box check → Token bucket check → Violation recording (triggers penalty box)

Activity tiers:Quiet (bypass limiting) → Normal (lighter: 0.5x intervals) → Busy (base: 1.0x intervals) → Congested (stricter: 2.0x intervals)

Note: Adaptive mode scales refill/min-interval timing; bucket capacity stays at the configured base value.

`,1)]),S(`div`,Js,[n[38]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z`})]),b(` Token Bucket Rate Limiting `)],-1),n[39]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Controls how many adverts each pubkey can send in a given time period. `,-1),S(`div`,Ys,[n[32]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Rate Limiting`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[1]||=e=>I.value=e,class:`cfg-select w-full sm:w-32`},[...n[31]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[D,I.value]]):(a(),C(`div`,Xs,l(I.value?`Enabled`:`Disabled`),1))]),S(`div`,Zs,[n[33]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bucket Capacity`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Max burst size (adverts)`)],-1),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[2]||=e=>L.value=e,type:`number`,min:`1`,max:`10`,class:`cfg-input w-full sm:w-24`},null,512)),[[j,L.value,void 0,{number:!0}]]):(a(),C(`div`,Qs,l(L.value),1))]),S(`div`,$s,[n[35]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Refill Interval`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Time between token refills `)],-1),T.value?(a(),C(`div`,tc,[i(S(`input`,{"onUpdate:modelValue":n[3]||=e=>B.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[j,B.value,void 0,{number:!0}]]),n[34]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,ec,l(B.value)+` hours `,1))]),S(`div`,nc,[n[37]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Minimum Interval`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Hard minimum between adverts `)],-1),T.value?(a(),C(`div`,ic,[i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>V.value=e,type:`number`,min:`0`,max:`1440`,class:`cfg-input w-20`},null,512),[[j,V.value,void 0,{number:!0}]]),n[36]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(a(),C(`div`,rc,l(V.value)+` min `,1))])]),S(`div`,ac,[n[49]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636`})]),b(` Penalty Box (Repeat Offenders) `)],-1),n[50]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Applies escalating cooldowns to pubkeys that repeatedly violate limits. `,-1),S(`div`,oc,[n[41]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Box`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[5]||=e=>H.value=e,class:`cfg-select w-full sm:w-32`},[...n[40]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[D,H.value]]):(a(),C(`div`,sc,l(H.value?`Enabled`:`Disabled`),1))]),S(`div`,cc,[n[42]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Violation Threshold`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Violations before penalty `)],-1),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[6]||=e=>U.value=e,type:`number`,min:`1`,max:`10`,class:`cfg-input w-full sm:w-24`},null,512)),[[j,U.value,void 0,{number:!0}]]):(a(),C(`div`,lc,l(U.value),1))]),S(`div`,uc,[n[44]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Base Penalty Duration`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`First penalty duration`)],-1),T.value?(a(),C(`div`,fc,[i(S(`input`,{"onUpdate:modelValue":n[7]||=e=>K.value=e,type:`number`,min:`1`,max:`48`,class:`cfg-input w-20`},null,512),[[j,K.value,void 0,{number:!0}]]),n[43]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,dc,l(K.value)+` hours `,1))]),S(`div`,pc,[n[46]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Multiplier`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Escalation factor`)],-1),T.value?(a(),C(`div`,hc,[i(S(`input`,{"onUpdate:modelValue":n[8]||=e=>te.value=e,type:`number`,min:`1`,max:`5`,step:`0.5`,class:`cfg-input w-20`},null,512),[[j,te.value,void 0,{number:!0}]]),n[45]||=S(`span`,{class:`text-content-muted text-sm`},`x`,-1)])):(a(),C(`div`,mc,l(te.value)+`x `,1))]),S(`div`,gc,[n[48]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Penalty Duration`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Maximum cooldown cap`)],-1),T.value?(a(),C(`div`,vc,[i(S(`input`,{"onUpdate:modelValue":n[9]||=e=>q.value=e,type:`number`,min:`1`,max:`168`,class:`cfg-input w-20`},null,512),[[j,q.value,void 0,{number:!0}]]),n[47]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(a(),C(`div`,_c,l(q.value)+` hours `,1))])]),S(`div`,yc,[n[60]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z`})]),b(` Adaptive Rate Limiting `)],-1),S(`div`,bc,[n[52]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Adaptive Mode`,-1),T.value?i((a(),C(`select`,{key:1,"onUpdate:modelValue":n[10]||=e=>ne.value=e,class:`cfg-select w-full sm:w-32`},[...n[51]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[D,ne.value]]):(a(),C(`div`,xc,l(ne.value?`Enabled`:`Disabled`),1))]),S(`div`,Sc,[n[54]||=S(`div`,null,[S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Tier Change Delay`),S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},`Prevents tier flapping`)],-1),T.value?(a(),C(`div`,wc,[i(S(`input`,{"onUpdate:modelValue":n[11]||=e=>ie.value=e,type:`number`,min:`0`,max:`60`,class:`cfg-input w-20`},null,512),[[j,ie.value,void 0,{number:!0}]]),n[53]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(a(),C(`div`,Cc,l(ie.value)+` min `,1))]),S(`div`,Tc,[n[58]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm mb-2 block`},`Activity Tier Thresholds (adverts/min)`,-1),S(`div`,Ec,[S(`div`,Dc,[n[55]||=S(`div`,{class:`text-xs text-accent-green mb-1`},`Quiet Max`,-1),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[12]||=e=>J.value=e,type:`number`,min:`0`,max:`1`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[j,J.value,void 0,{number:!0}]]):(a(),C(`div`,Oc,l(J.value),1))]),S(`div`,kc,[n[56]||=S(`div`,{class:`text-xs text-accent-cyan mb-1`},`Normal Max`,-1),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[13]||=e=>Y.value=e,type:`number`,min:`0`,max:`5`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[j,Y.value,void 0,{number:!0}]]):(a(),C(`div`,Ac,l(Y.value),1))]),S(`div`,jc,[n[57]||=S(`div`,{class:`text-xs text-secondary mb-1`},`Busy Max`,-1),T.value?i((a(),C(`input`,{key:1,"onUpdate:modelValue":n[14]||=e=>X.value=e,type:`number`,min:`0`,max:`10`,step:`0.01`,class:`cfg-input w-full py-1 text-center`},null,512)),[[j,X.value,void 0,{number:!0}]]):(a(),C(`div`,Mc,l(X.value),1))])]),n[59]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted mt-2`},` Above Busy Max = Congested tier (strictest limiting) `,-1)])]),N.value?(a(),C(`div`,{key:2,class:`fixed inset-0 bg-black/50 flex items-start justify-center z-50 p-4 overflow-y-auto`,onClick:n[18]||=A(e=>N.value=!1,[`self`])},[S(`div`,{class:`bg-background dark:bg-background-dark rounded-lg shadow-xl max-w-3xl w-full my-8`,onClick:n[17]||=A(()=>{},[`stop`])},[S(`div`,Nc,[S(`div`,Pc,[n[62]||=S(`h2`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` How Advert Rate Limiting Works `,-1),S(`button`,{onClick:n[15]||=e=>N.value=!1,class:`text-content-muted hover:text-content-primary dark:text-content-muted dark:hover:text-content-primary`},[...n[61]||=[S(`svg`,{class:`w-6 h-6`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),n[63]||=d(`

Why you may see the same advert more than once

Mesh traffic can reach your repeater through different paths, so duplicate advert packets are expected.

  • First copy arrives and is forwarded
  • Second copy arrives through another repeater path
  • Later copies may be dropped once limits are hit

This is normal behavior and helps prevent repeated rebroadcasts from flooding the mesh.

Token Bucket Rate Limiting

Each sender has a token bucket. Every forwarded advert uses one token.

  • Bucket Capacity: How many adverts can pass in a burst.
  • Refill Rate: How quickly tokens come back over time.
  • Min Interval: Optional gap between adverts from the same sender (usually set to 0).
Example (capacity 2):
- Copy 1 forwarded (2 → 1 tokens)
- Copy 2 forwarded (1 → 0 tokens)
- Copy 3 dropped (no tokens left)

Penalty Box (Repeat Offenders)

If a sender keeps hitting the limit, it is temporarily blocked.

  • Violation Threshold: How many hits before penalty starts.
  • Base Penalty: First block duration.
  • Multiplier: Repeated penalties get longer.
  • Decay Time: Violations age out after stable behavior.

Adaptive Mesh Activity Tiers

Adaptive mode adjusts limits based on recent advert activity.

How Congestion is Measured:
  • What is counted: Advert packets only (not chat/data traffic)
  • Smoothing: 60-second EWMA to avoid reacting to short spikes
  • Score: Tier is based on adverts per minute
  • Hysteresis: Tier changes must hold for 5 minutes
QUIET
Activity < 0.05/min
No rate limiting
NORMAL
Activity 0.05-0.20/min
Light limiting (50%)
BUSY
Activity 0.20-0.50/min
Standard limiting (100%)
CONGESTED
Activity > 0.50/min
Aggressive (200%)
Quick examples:
- 0.02 adverts/min → QUIET (bypass)
- 0.35 adverts/min → BUSY (tighter limits)
- 0.68 adverts/min → CONGESTED (strict limits)

Recommended starting settings

  • Min Interval: 0 (disabled), let adaptive mode do the work
  • Bucket Capacity: 2-3 tokens for normal mesh propagation
  • Adaptive Mode: On
  • Penalty Box: On
`,5),S(`div`,Fc,[S(`button`,{onClick:n[16]||=e=>N.value=!1,class:`btn-primary`},` Got it! `)])])])])):_(``,!0)],512)],64))}}),Lc={class:`modal-card max-w-2xl w-full max-h-[90vh] overflow-y-auto`},Rc={class:`flex items-center justify-between mb-7`},zc={class:`text-xl font-semibold text-content-primary dark:text-content-primary`},Bc={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Vc={class:`grid grid-cols-2 gap-5 items-end`},Hc={class:`flex items-center gap-3 pb-1.5`},Uc={key:0,class:`grid grid-cols-2 gap-5`},Wc={class:`grid grid-cols-2 gap-5 items-end`},Gc={class:`flex items-center gap-3 pb-1.5`},Kc={class:`grid grid-cols-2 gap-x-5 gap-y-0`},qc=[`aria-hidden`],Jc={class:`grid grid-cols-2 gap-5 items-center pt-4`},Yc={class:`flex items-center gap-3`},Xc={class:`flex items-center gap-6`},Zc={class:`flex items-center gap-3`},Qc={class:`flex items-center gap-3`},$c={class:`flex flex-wrap gap-2`},el=[`onClick`],tl={class:`modal-actions`},nl=[`disabled`],rl=f({__name:`BrokerEditModal`,props:{show:{type:Boolean},broker:{},isNew:{type:Boolean}},emits:[`done`,`cancel`],setup(e,{emit:n}){let s=[`REQ`,`RESPONSE`,`TXT_MSG`,`ACK`,`ADVERT`,`GRP_TXT`,`GRP_DATA`,`ANON_REQ`,`PATH`,`TRACE`,`RAW_CUSTOM`],c=e,d=n;function f(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let g=o({_id:0,enabled:!0,name:``,host:``,port:443,format:`letsmesh`,use_jwt_auth:!1,transport:`websockets`,disallowedInput:[],retain_status:!1,tls:{enabled:!0,insecure:!1}});h(()=>c.broker,e=>{e&&(g.value=f(e))},{immediate:!0});let w=y(()=>{let e=g.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});function T(){let e=g.value;(!e.audience||e.audience===e.host)&&(e.audience=e.host)}function E(e){g.value.disallowedInput||(g.value.disallowedInput=[]);let t=g.value.disallowedInput.indexOf(e);t===-1?g.value.disallowedInput.push(e):g.value.disallowedInput.splice(t,1)}function O(){w.value&&d(`done`,f(g.value))}function k(){d(`cancel`)}return(n,o)=>(a(),u(m,{to:`body`},[v(N,{"enter-active-class":`transition-opacity duration-200`,"enter-from-class":`opacity-0`,"leave-active-class":`transition-opacity duration-200`,"leave-to-class":`opacity-0`},{default:r(()=>[e.show&&e.broker?(a(),C(`div`,{key:0,class:`modal-backdrop`,onClick:o[14]||=A(e=>k(),[`self`])},[S(`div`,Lc,[S(`div`,Rc,[S(`div`,null,[S(`h3`,zc,l(e.isNew?`Add Broker`:`Edit Broker`),1),S(`p`,Bc,l(e.isNew?`Configure a new MQTT broker`:`Editing ${e.broker.name||`(unnamed)`}`),1)]),S(`button`,{onClick:k,class:`text-content-secondary dark:text-white/60 hover:text-content-primary dark:hover:text-white transition-colors`},[...o[15]||=[S(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`form`,{onSubmit:A(O,[`prevent`]),class:`modal-form`},[S(`div`,null,[o[16]||=S(`label`,{class:`modal-field-label`},[b(` Name `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`input`,{"onUpdate:modelValue":o[0]||=e=>g.value.name=e,type:`text`,placeholder:`Broker Name`,class:`modal-input`},null,512),[[j,g.value.name]])]),S(`div`,Vc,[S(`div`,null,[o[18]||=S(`label`,{class:`modal-field-label`},[b(` Format `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`select`,{"onUpdate:modelValue":o[1]||=e=>g.value.format=e,class:`modal-select`},[...o[17]||=[S(`option`,{value:`meshcoretomqtt`},`Meshcoretomqtt`,-1),S(`option`,{value:`letsmesh`},`Letsmesh`,-1),S(`option`,{value:`waev`},`Waev`,-1),S(`option`,{value:`mqtt`},`pyMC`,-1)]],512),[[D,g.value.format]])]),S(`div`,Hc,[S(`button`,{type:`button`,onClick:o[2]||=e=>g.value.enabled=!g.value.enabled,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,g.value.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),o[19]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enabled`,-1)])]),g.value.format===`mqtt`?(a(),C(`div`,Uc,[S(`div`,null,[o[20]||=S(`label`,{class:`modal-field-label`},[b(` MQTT Base Topic `),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(e.g. meshcore/repeater)`)],-1),i(S(`input`,{"onUpdate:modelValue":o[3]||=e=>g.value.base_topic=e,placeholder:`meshcore/repeater`,class:`modal-input`},null,512),[[j,g.value.base_topic]])]),o[21]||=S(`div`,null,null,-1)])):_(``,!0),S(`div`,Wc,[S(`div`,null,[o[23]||=S(`label`,{class:`modal-field-label`},[b(` Transport `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`select`,{"onUpdate:modelValue":o[4]||=e=>g.value.transport=e,class:`modal-select`},[...o[22]||=[S(`option`,{value:`websockets`},`Websockets`,-1),S(`option`,{value:`tcp`},`TCP`,-1)]],512),[[D,g.value.transport]])]),S(`div`,Gc,[S(`button`,{type:`button`,onClick:o[5]||=e=>g.value.use_jwt_auth=!g.value.use_jwt_auth,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.use_jwt_auth?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,g.value.use_jwt_auth?`translate-x-4`:`translate-x-0`])},null,2)],2),o[24]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Use JWT Auth`,-1)])]),S(`div`,Kc,[S(`div`,null,[o[25]||=S(`label`,{class:`modal-field-label`},[b(` Host `),S(`span`,{class:`text-red-500`},`*`)],-1),i(S(`input`,{"onUpdate:modelValue":o[6]||=e=>g.value.host=e,type:`text`,placeholder:`mqtt.myserver.com`,onBlur:T,class:`modal-input font-mono`},null,544),[[j,g.value.host]])]),S(`div`,null,[g.value.use_jwt_auth?(a(),C(x,{key:0},[o[26]||=S(`label`,{class:`modal-field-label`},[b(` Audience `),S(`span`,{class:`text-red-500`},`*`),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(usually same as host)`)],-1),i(S(`input`,{"onUpdate:modelValue":o[7]||=e=>g.value.audience=e,type:`text`,placeholder:`mqtt.myserver.com`,class:`modal-input font-mono`},null,512),[[j,g.value.audience]])],64)):(a(),C(x,{key:1},[o[27]||=S(`label`,{class:`modal-field-label`},[b(` Username `),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(blank = anonymous)`)],-1),o[28]||=S(`input`,{type:`text`,autocomplete:`username`,style:{display:`none`}},null,-1),i(S(`input`,{autocomplete:`username`,"onUpdate:modelValue":o[8]||=e=>g.value.username=e,type:`text`,placeholder:`username`,class:`modal-input`},null,512),[[j,g.value.username]])],64))]),S(`div`,null,[o[29]||=S(`label`,{class:`modal-field-label`},[b(` Port `),S(`span`,{class:`text-red-500`},`*`),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(443 WS, 1883 TCP)`)],-1),i(S(`input`,{"onUpdate:modelValue":o[9]||=e=>g.value.port=e,type:`number`,min:`0`,max:`65535`,class:`modal-input font-mono`},null,512),[[j,g.value.port,void 0,{number:!0}]])]),S(`div`,{class:p(g.value.use_jwt_auth?`invisible pointer-events-none`:``),"aria-hidden":g.value.use_jwt_auth?`true`:void 0},[o[30]||=S(`label`,{class:`modal-field-label`},`Password`,-1),o[31]||=S(`input`,{type:`password`,autocomplete:`current-password`,style:{display:`none`}},null,-1),i(S(`input`,{autocomplete:`new-password`,"onUpdate:modelValue":o[10]||=e=>g.value.password=e,type:`password`,readonly:``,onfocus:`this.removeAttribute('readonly');`,onblur:`this.setAttribute('readonly', true);`,class:`modal-input`},null,512),[[j,g.value.password]])],10,qc)]),S(`div`,Jc,[S(`div`,Yc,[S(`button`,{type:`button`,onClick:o[11]||=e=>g.value.retain_status=!g.value.retain_status,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.retain_status?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,g.value.retain_status?`translate-x-4`:`translate-x-0`])},null,2)],2),o[32]||=S(`div`,null,[S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Retain Status`),S(`span`,{class:`text-xs text-content-muted dark:text-content-muted/60 ml-1`},`(MQTT retained)`)],-1)]),S(`div`,Xc,[S(`div`,Zc,[S(`button`,{type:`button`,onClick:o[12]||=e=>g.value.tls.enabled=!g.value.tls.enabled,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.tls.enabled?`bg-primary`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,g.value.tls.enabled?`translate-x-4`:`translate-x-0`])},null,2)],2),o[33]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`TLS`,-1)]),S(`div`,Qc,[S(`button`,{type:`button`,onClick:o[13]||=e=>g.value.tls.insecure=!g.value.tls.insecure,class:p([`relative inline-flex h-5 w-9 flex-shrink-0 cursor-pointer rounded-full transition-colors duration-200 ease-in-out focus:outline-none`,g.value.tls.insecure?`bg-amber-500`:`bg-gray-200 dark:bg-white/15`])},[S(`span`,{class:p([`pointer-events-none absolute top-0.5 left-0.5 inline-block h-4 w-4 transform rounded-full bg-white shadow transition duration-200 ease-in-out`,g.value.tls.insecure?`translate-x-4`:`translate-x-0`])},null,2)],2),o[34]||=S(`span`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Insecure`,-1)])])]),S(`div`,null,[o[35]||=S(`label`,{class:`modal-field-label`},[b(` Block Packet Types `),S(`span`,{class:`text-content-secondary dark:text-content-muted font-normal text-xs ml-1`},`(prevent publishing to broker)`)],-1),S(`div`,$c,[(a(),C(x,null,t(s,e=>S(`button`,{key:e,type:`button`,onClick:t=>E(e),class:p([`px-2.5 py-1 rounded text-xs font-mono font-medium border transition-colors`,g.value.disallowedInput?.includes(e)?`bg-red-100 dark:bg-red-900/30 border-red-300 dark:border-red-700/50 text-red-700 dark:text-red-400`:`bg-background-mute dark:bg-white/5 border-stroke-subtle dark:border-stroke/10 text-content-secondary dark:text-content-muted hover:border-primary/40`])},l(e),11,el)),64))]),o[36]||=S(`p`,{class:`mt-2 text-xs text-content-secondary dark:text-content-muted`},[S(`span`,{class:`text-red-600 dark:text-red-400 font-medium`},`Red = blocked.`),b(` Leave all unselected to publish all packet types. `)],-1)]),S(`div`,tl,[S(`button`,{type:`button`,onClick:k,class:`modal-btn-cancel`},` Cancel `),S(`button`,{type:`submit`,disabled:!w.value,class:p([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,w.value?`bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green`:`bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 text-content-muted dark:text-content-muted/70 cursor-not-allowed`])},` Done `,10,nl)])],32)])])):_(``,!0)]),_:1})]))}}),il={class:`space-y-12`},al={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},ol={class:`flex items-center gap-2 flex-shrink-0`},sl=[`disabled`],cl=[`disabled`],ll={key:0,class:`bg-red-100 dark:bg-red-500/20 border border-red-500 dark:border-red-500/50 rounded-lg p-3 text-red-700 dark:text-red-400 text-sm`},ul={class:`cfg-section`},dl={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},fl={key:1,class:`space-y-3`},pl={class:`flex items-center gap-2`},ml={key:0,class:`space-y-2`},hl=[`title`],gl={key:1,class:`text-sm text-content-muted dark:text-content-muted/60 italic`},_l={class:`cfg-card p-6`},vl={key:0,class:`grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3`},yl={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},bl={class:`text-content-primary dark:text-content-primary font-mono text-sm mt-0.5`},xl={class:`flex flex-col py-1 border-b border-stroke-subtle dark:border-stroke/10`},Sl={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Cl={class:`flex flex-col py-1`},wl={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Tl={class:`flex flex-col py-1`},El={class:`text-content-primary dark:text-content-primary text-sm mt-0.5`},Dl={key:1,class:`space-y-3`},Ol={class:`grid grid-cols-1 sm:grid-cols-2 gap-3`},kl={class:`cfg-card p-6`},Al={class:`flex items-start justify-between mb-4`},jl={key:0,class:`flex items-center gap-2 flex-shrink-0 ml-4`},Ml={class:`relative`},Nl={key:0,class:`absolute right-0 top-full mt-1 z-20 w-72 rounded-lg shadow-lg border border-stroke-subtle dark:border-stroke/20 bg-white dark:bg-[var(--color-surface)] overflow-hidden`},Pl={key:0,class:`px-3 py-3 text-xs text-content-secondary dark:text-content-muted italic`},Fl={key:1,class:`px-3 py-3 text-xs text-red-600 dark:text-red-400`},Il={key:2,class:`px-3 py-3 text-xs text-content-secondary dark:text-content-muted italic`},Ll={key:3,class:`py-1`},Rl=[`onClick`],zl={class:`min-w-0 flex-1`},Bl={class:`text-sm font-medium text-content-primary dark:text-content-primary group-hover:text-primary transition-colors`},Vl={class:`text-xs text-content-secondary dark:text-content-muted`},Hl=[`onClick`,`title`],Ul=[`href`],Wl={key:0,class:`bg-background-mute/40 dark:bg-background/20 border-t border-stroke-subtle dark:border-stroke/10`},Gl=[`onClick`],Kl={class:`min-w-0 flex-1`},ql={class:`text-xs font-medium text-content-primary dark:text-content-primary truncate`},Jl={class:`text-[11px] font-mono text-content-secondary dark:text-content-muted truncate`},Yl={key:0,class:`flex flex-col items-center justify-center py-8 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted`},Xl={key:0,class:`text-xs mt-0.5 opacity-70`},Zl={key:1,class:`space-y-2`},Ql={class:`flex items-center gap-3 px-4 py-2.5`},$l={class:`min-w-0 flex-1 flex items-center gap-2 flex-wrap`},eu={class:`text-sm font-medium text-content-primary dark:text-content-primary`},tu={class:`text-xs font-mono text-content-secondary dark:text-content-muted`},nu={key:0,class:`flex items-center gap-1.5 flex-shrink-0`},ru=[`onClick`],iu=[`onClick`],au=K(f({__name:`LetsMeshSettings`,setup(n,{expose:s}){let u=ee(),d=y(()=>u.stats?.config?.mqtt_brokers||{}),f=o([]),m=o(!1),g=o(``),T=o(null);function E(e){return{...e,tls:{...e.tls},disallowedInput:[...e.disallowedInput??[]]}}let D=o(!1),O=o(!1),k=o(``),M=o(!1),P=o(null),F=o(!1),I=o(``),L=o(300),z=o(``),B=o(``),V=o([]),H=o(null),U=o(!1),W=o(null),G=o({_id:0,enabled:!0,name:``,host:``,port:443,format:`letsmesh`,use_jwt_auth:!1,transport:`websockets`,disallowedInput:[],retain_status:!1,tls:{enabled:!0,insecure:!1}}),K=o(!1),q=o(null),ne=o(!1);async function re(){if(!ne.value){ne.value=!0;try{let e=await R.get(`/mqtt_status`);e.success&&(q.value=e.data)}catch{}finally{ne.value=!1}}}let ie=1;function J(e={}){return{_id:ie++,enabled:e.enabled??!0,name:e.name??``,host:e.host??``,port:e.port??0,audience:e.audience??``,format:e.format??`letsmesh`,use_jwt_auth:e.use_jwt_auth??!1,username:e.username??``,password:e.password??``,transport:e.transport??`websockets`,disallowedInput:Array.isArray(e.disallowedInput)?[...e.disallowedInput]:[],retain_status:e.retain_status??!1,base_topic:e.base_topic??``,tls:{enabled:e.tls?.enabled??!1,insecure:e.tls?.insecure??!1}}}function Y(){let e=d.value;I.value=e.iata_code??``,L.value=e.status_interval??300,z.value=e.owner??``,B.value=e.email??``,V.value=Array.isArray(e.brokers)?e.brokers.map(e=>J(e)):[]}h(d,()=>{D.value||Y()},{immediate:!0});function X(){return{iata_code:I.value,status_interval:L.value,owner:z.value,email:B.value,brokers:V.value.map(e=>{let t={name:e.name,enabled:e.enabled,transport:e.transport,host:e.host,port:e.port,use_jwt_auth:e.use_jwt_auth,format:e.format,disallowed_packet_types:e.disallowedInput,base_topic:e.base_topic,retain_status:e.retain_status,tls:{enabled:e.tls?.enabled??!1,insecure:e.tls?.insecure??!1}};return e.use_jwt_auth?{...t,audience:e.audience}:{...t,username:e.username,password:e.password}})}}async function Z(){try{let e=await R.post(`/update_mqtt_config`,X());return e.success?(await u.fetchStats(),await re(),{success:!0}):{success:!1,error:e.error||`Save failed`}}catch(e){let t=e;return{success:!1,error:t?.response?.data?.error||t?.message||`Request failed`}}}function Q(){Y(),P.value={iata:I.value,interval:L.value,owner:z.value,email:B.value,brokers:V.value.map(E)},D.value=!0,k.value=``}function ae(){P.value&&(I.value=P.value.iata,L.value=P.value.interval,z.value=P.value.owner,B.value=P.value.email,V.value=P.value.brokers.map(E)),H.value=null,U.value=!1,W.value=null,F.value=!1,D.value=!1,P.value=null,k.value=``}async function oe(){if(H.value!==null){let e=G.value;if(!e.name.trim()||!e.host.trim()){k.value=`Please complete or cancel the open broker edit before saving.`;return}le()}O.value=!0,k.value=``;let e=await Z();O.value=!1,e.success?(D.value=!1,F.value=!1,P.value=null,M.value=!0):k.value=e.error}function se(){H.value!==null&&ce();let e=J();V.value.push(e),W.value=null,U.value=!0,G.value=E(e),H.value=e._id}function $(e){H.value!==null&&H.value!==e._id&&ce(),W.value=E(e),U.value=!1,G.value=E(e),H.value=e._id}function ce(){if(U.value&&H.value!==null)V.value=V.value.filter(e=>e._id!==H.value);else if(W.value){let e=V.value.findIndex(e=>e._id===W.value._id);e!==-1&&V.value.splice(e,1,E(W.value))}H.value=null,U.value=!1,W.value=null}function le(){let e=G.value,t=V.value.findIndex(t=>t._id===e._id);t!==-1&&V.value.splice(t,1,E(e)),H.value=null,U.value=!1,W.value=null}function ue(e){G.value=e,le()}function de(e){V.value=V.value.filter(t=>t._id!==e),H.value===e&&(H.value=null,U.value=!1,W.value=null)}function me(e){K.value=!1,T.value=null,H.value!==null&&ce(),e.brokers.forEach(e=>V.value.push(J(e)))}function he(e){K.value=!1,T.value=null,H.value!==null&&ce(),V.value.push(J(e))}function ge(e){T.value=T.value===e?null:e}async function _e(){m.value=!0,g.value=``;try{let e=await R.get(`/broker_presets`);e.success&&Array.isArray(e.data)?f.value=e.data:(f.value=[],g.value=e.error||`Failed to load broker presets`)}catch(e){f.value=[],e?.response?.status===404?g.value=``:g.value=`Could not reach repeater for broker presets`}finally{m.value=!1}}let ve=y(()=>{let e=G.value;return e.name.trim()!==``&&e.host.trim()!==``&&e.port>=1&&e.port<=65535&&(!e.use_jwt_auth||(e.audience?.trim()??``)!==``)});async function ye(){H.value!==null&&ve.value&&le(),O.value=!0,k.value=``;let e=await Z();return O.value=!1,e.success?(D.value=!1,F.value=!1,P.value=null,M.value=!0,!0):(k.value=e.error??`Save failed`,!1)}let{showUnsavedModal:be,requestLeave:xe,handleDiscard:Se,handleSave:Ce,handleCancel:we}=pe(D,O,ae,ye);s({requestLeave:xe,isEditing:D});let Te=null;return e(()=>{re(),_e(),Te=setInterval(re,5e3)}),w(()=>{Te&&clearInterval(Te)}),(e,n)=>(a(),C(x,null,[v(te,{modelValue:M.value,"onUpdate:modelValue":n[0]||=e=>M.value=e,message:`Broker settings have been saved. A service restart is required for the changes to take effect.`},null,8,[`modelValue`]),v(rl,{show:H.value!==null,broker:H.value===null?null:G.value,"is-new":U.value,onDone:ue,onCancel:ce},null,8,[`show`,`broker`,`is-new`]),v(fe,{show:c(be),"is-saving":O.value,label:`Broker settings`,onDiscard:c(Se),onSave:c(Ce),onCancel:c(we)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,il,[S(`div`,al,[n[8]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Observer Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Configure LetsMesh observer settings, MQTT brokers, and connection status `)],-1),S(`div`,ol,[D.value?(a(),C(x,{key:1},[S(`button`,{onClick:ae,disabled:O.value,class:`px-3 sm:px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},` Cancel `,8,sl),S(`button`,{onClick:oe,disabled:O.value,class:`btn-primary`},l(O.value?`Saving…`:`Save Settings`),9,cl)],64)):(a(),C(`button`,{key:0,onClick:Q,class:`btn-primary`},` Edit Settings `))])]),k.value?(a(),C(`div`,ll,l(k.value),1)):_(``,!0),S(`div`,ul,[n[10]||=S(`div`,{class:`mb-4`},[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Observer Status`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`Live LetsMesh broker connection state`)],-1),q.value?(a(),C(`div`,fl,[S(`div`,pl,[n[9]||=S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36`},`Handler`,-1),S(`span`,{class:p([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,q.value.handler_active?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:`bg-gray-100 dark:bg-gray-800/50 text-gray-500 dark:text-gray-400`])},[S(`span`,{class:p([`w-1.5 h-1.5 rounded-full`,q.value.handler_active?`bg-green-500`:`bg-gray-400`])},null,2),b(` `+l(q.value.handler_active?`Active`:`Inactive`),1)],2)]),q.value.brokers.length?(a(),C(`div`,ml,[(a(!0),C(x,null,t(q.value.brokers,e=>(a(),C(`div`,{key:e.host,class:`flex items-center gap-2`},[S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36 truncate`,title:e.name},l(e.name),9,hl),S(`span`,{class:p([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,e.status.connected?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:e.status.reconnecting?`bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400`:`bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400`])},[S(`span`,{class:p([`w-1.5 h-1.5 rounded-full`,e.status.connected?`bg-green-500`:e.status.reconnecting?`bg-amber-500`:`bg-red-500`])},null,2),b(` `+l(e.status.connected?`Connected`:e.status.reconnecting?`Reconnecting…`:`Disconnected`),1)],2)]))),128))])):(a(),C(`div`,gl,`No broker connections configured.`))])):(a(),C(`div`,dl,` Status unavailable — service may not be running. `))]),S(`div`,_l,[n[19]||=S(`div`,{class:`mb-4`},[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Observer Setup`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`IATA code, status interval, and owner details`)],-1),S(`div`,null,[D.value?_(``,!0):(a(),C(`div`,vl,[S(`div`,yl,[n[11]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`IATA Code`,-1),S(`span`,bl,l(d.value.iata_code||`—`),1)]),S(`div`,xl,[n[12]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Status Interval`,-1),S(`span`,Sl,l(d.value.status_interval??300)+`s`,1)]),S(`div`,Cl,[n[13]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Owner`,-1),S(`span`,wl,l(d.value.owner||`—`),1)]),S(`div`,Tl,[n[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Email`,-1),S(`span`,El,l(d.value.email||`—`),1)])])),D.value?(a(),C(`div`,Dl,[S(`div`,Ol,[S(`div`,null,[n[15]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},[b(` IATA Code `),S(`span`,{class:`text-content-muted dark:text-content-muted/60 text-xs`},`(e.g. SFO, LHR)`)],-1),i(S(`input`,{"onUpdate:modelValue":n[1]||=e=>I.value=e,type:`text`,maxlength:`10`,placeholder:`TEST`,class:`cfg-input font-mono`},null,512),[[j,I.value]])]),S(`div`,null,[n[16]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},[b(` Status Interval `),S(`span`,{class:`text-content-muted dark:text-content-muted/60 text-xs`},`(seconds, min 60)`)],-1),i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>L.value=e,type:`number`,min:`60`,max:`3600`,class:`cfg-input font-mono`},null,512),[[j,L.value,void 0,{number:!0}]])]),S(`div`,null,[n[17]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Owner Companion Pubkey`,-1),i(S(`input`,{"onUpdate:modelValue":n[3]||=e=>z.value=e,type:`text`,placeholder:`Optional`,class:`cfg-input`},null,512),[[j,z.value]])]),S(`div`,null,[n[18]||=S(`label`,{class:`block text-xs sm:text-sm text-content-secondary dark:text-content-muted mb-1`},`Email`,-1),i(S(`input`,{"onUpdate:modelValue":n[4]||=e=>B.value=e,type:`email`,placeholder:`Optional`,class:`cfg-input`},null,512),[[j,B.value]])])])])):_(``,!0)])]),S(`div`,kl,[S(`div`,Al,[n[27]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},`Broker Settings`),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},`MQTT brokers for observer publishing`)],-1),D.value?(a(),C(`div`,jl,[S(`div`,Ml,[S(`button`,{onClick:n[5]||=e=>K.value=!K.value,class:`inline-flex items-center gap-1.5 px-3 sm:px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors text-sm`},[n[21]||=b(` From Template `,-1),(a(),C(`svg`,{class:p([`w-3 h-3 transition-transform`,K.value?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[20]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))]),v(N,{name:`dropdown`},{default:r(()=>[K.value?(a(),C(`div`,Nl,[n[25]||=S(`div`,{class:`px-3 py-2 border-b border-stroke-subtle dark:border-stroke/10`},[S(`p`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Known Networks`)],-1),m.value?(a(),C(`div`,Pl,` Loading presets… `)):g.value?(a(),C(`div`,Fl,l(g.value),1)):f.value.length?(a(),C(`div`,Ll,[(a(!0),C(x,null,t(f.value,e=>(a(),C(`div`,{key:e.id,class:`border-b border-stroke-subtle dark:border-stroke/10 last:border-b-0`},[S(`div`,{class:`flex items-center gap-2 px-3 py-2.5 hover:bg-background-mute dark:hover:bg-background/30 cursor-pointer group`,onClick:t=>me(e)},[S(`div`,zl,[S(`p`,Bl,l(e.name),1),S(`p`,Vl,l(e.brokers.length)+` broker`+l(e.brokers.length===1?``:`s`),1)]),e.brokers.length>1?(a(),C(`button`,{key:0,onClick:A(t=>ge(e.id),[`stop`]),title:T.value===e.id?`Hide individual brokers`:`Pick individual brokers`,class:`flex-shrink-0 p-1 rounded hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-primary transition-colors`},[(a(),C(`svg`,{class:p([`w-3.5 h-3.5 transition-transform`,T.value===e.id?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[22]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))],8,Hl)):_(``,!0),e.website?(a(),C(`a`,{key:1,href:e.website,target:`_blank`,rel:`noopener noreferrer`,title:`Visit website`,class:`flex-shrink-0 p-1 rounded hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-primary transition-colors`,onClick:n[6]||=A(()=>{},[`stop`])},[...n[23]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14`})],-1)]],8,Ul)):_(``,!0)],8,Rl),T.value===e.id&&e.brokers.length>1?(a(),C(`div`,Wl,[(a(!0),C(x,null,t(e.brokers,(t,r)=>(a(),C(`div`,{key:`${e.id}-${r}`,class:`flex items-center gap-2 pl-6 pr-3 py-2 hover:bg-background-mute dark:hover:bg-background/30 cursor-pointer`,onClick:e=>he(t)},[S(`div`,Kl,[S(`p`,ql,l(t.name),1),S(`p`,Jl,l(t.host)+`:`+l(t.port),1)]),n[24]||=S(`span`,{class:`flex-shrink-0 inline-flex items-center justify-center w-5 h-5 rounded bg-primary/10 text-primary text-xs font-bold`,title:`Add only this broker`},`+`,-1)],8,Gl))),128))])):_(``,!0)]))),128))])):(a(),C(`div`,Il,` No bundled presets. Use "Add" to configure manually. `))])):_(``,!0)]),_:1}),K.value?(a(),C(`div`,{key:0,class:`fixed inset-0 z-10`,onClick:n[7]||=e=>K.value=!1})):_(``,!0)]),S(`button`,{onClick:se,class:`btn-primary inline-flex items-center gap-1.5`},[...n[26]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 4v16m8-8H4`})],-1),b(` Add `,-1)]])])):_(``,!0)]),V.value.length?(a(),C(`div`,Zl,[(a(!0),C(x,null,t(V.value,e=>(a(),C(`div`,{key:e._id,class:`cfg-card overflow-hidden`},[S(`div`,Ql,[S(`div`,$l,[S(`span`,{class:p([`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium`,e.enabled?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:`bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400`])},[S(`span`,{class:p([`w-1.5 h-1.5 rounded-full`,e.enabled?`bg-green-500`:`bg-red-500`])},null,2),b(` `+l(e.enabled?`Enabled`:`Disabled`),1)],2),S(`span`,eu,l(e.name||`(unnamed)`),1),S(`span`,tu,l(e.host||`—`)+`:`+l(e.port),1)]),D.value?(a(),C(`div`,nu,[S(`button`,{onClick:t=>$(e),class:`px-2.5 py-1 text-xs bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded border border-primary/50 transition-colors`},` Edit `,8,ru),S(`button`,{onClick:t=>de(e._id),title:`Remove`,class:`p-1.5 rounded hover:bg-red-500/10 dark:hover:bg-red-900/20 text-content-secondary dark:text-content-muted hover:text-red-600 dark:hover:text-red-400 transition-colors`},[...n[30]||=[S(`svg`,{class:`w-3.5 h-3.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})],-1)]],8,iu)])):_(``,!0)])]))),128))])):(a(),C(`div`,Yl,[n[28]||=S(`svg`,{class:`w-7 h-7 mb-2 opacity-40`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`1.5`,d:`M5 12h14M5 12l4-4m-4 4l4 4`})],-1),n[29]||=S(`p`,{class:`text-sm`},`No brokers configured`,-1),D.value?(a(),C(`p`,Xl,`Use Add or From Template above`)):_(``,!0)]))])])],64))}}),[[`__scopeId`,`data-v-45cb296d`]]),ou={class:`space-y-12`},su={key:0,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-100 dark:bg-red-500/10 p-4`},cu={class:`cfg-section`},lu=[`disabled`],uu={key:0,class:`flex items-center gap-2`},du={key:1,class:`flex items-center gap-2`},fu={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-2`},pu={key:1,class:`text-xs text-red-500 dark:text-red-400 mt-2`},mu={class:`cfg-section`},hu={key:0},gu={key:1,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-4`},_u={class:`flex items-start gap-3`},vu={class:`flex-1`},yu={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},bu={class:`flex gap-2 mt-3`},xu=[`disabled`],Su=[`disabled`],Cu={key:2,class:`text-xs text-green-600 dark:text-green-400 mt-2`},wu={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Tu={class:`cfg-section`},Eu={class:`space-y-3`},Du={class:`flex items-center gap-3 cursor-pointer px-4 py-3 bg-background-mute dark:bg-background/30 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 hover:border-cyan-500/50 dark:hover:border-primary/50 transition-colors`},Ou={class:`text-sm text-content-secondary dark:text-content-muted`},ku={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10`},Au={key:0,class:`text-xs text-content-secondary dark:text-content-muted space-y-1 mb-3`},ju={class:`font-mono`},Mu={class:`font-mono`},Nu={key:0,class:`text-amber-600 dark:text-amber-400 font-medium`},Pu={key:1,class:`text-content-muted`},Fu={class:`text-xs text-content-secondary dark:text-content-muted`},Iu={class:`font-mono`},Lu={key:1},Ru={key:2,class:`rounded-lg border-2 border-amber-500/50 dark:border-amber-400/40 bg-amber-50 dark:bg-amber-500/10 p-4`},zu={class:`flex items-start gap-3`},Bu={class:`flex-1`},Vu={class:`text-xs text-amber-700 dark:text-amber-300/80 mt-1`},Hu={class:`flex gap-2 mt-3`},Uu=[`disabled`],Wu=[`disabled`],Gu={key:3,class:`text-xs text-green-600 dark:text-green-400 mt-2`},Ku={key:4,class:`text-xs text-red-500 dark:text-red-400 mt-2`},qu={class:`cfg-section`},Ju={key:0},Yu={key:1,class:`rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-4`},Xu={class:`flex items-start gap-3`},Zu={class:`flex-1`},Qu={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},$u={class:`flex gap-2 mt-3`},ed=[`disabled`],td=[`disabled`],nd={key:2,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10 space-y-2`},rd={class:`flex items-center justify-between`},id={class:`text-xs text-content-secondary dark:text-content-muted space-y-1`},ad={class:`font-mono`},od={key:0},sd={class:`font-mono`},cd={key:1},ld={class:`font-mono text-[10px] break-all`},ud={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},dd=f({__name:`BackupRestore`,setup(e){let t=y(()=>window.location.protocol===`http:`),n=o(!1),r=o(``),i=o(``);async function s(){n.value=!0,r.value=``,i.value=``;try{let e=await R.exportConfig(!1);if(!e.success||!e.data){i.value=e.error||`Export failed`;return}let t=new Blob([JSON.stringify(e.data,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),a=document.createElement(`a`);a.href=n,a.download=`pymc-repeater-settings-${(e.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,`-`)}.json`,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n),r.value=`Settings exported successfully (secrets redacted).`}catch(e){i.value=e instanceof Error?e.message:`Export failed`}finally{n.value=!1}}let c=o(!1),u=o(!1),f=o(``),p=o(``);async function m(){u.value=!0,f.value=``,p.value=``;try{let e=await R.exportConfig(!0);if(!e.success||!e.data){p.value=e.error||`Export failed`;return}let t=new Blob([JSON.stringify(e.data,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`pymc-repeater-full-backup-${(e.data.meta?.exported_at||new Date().toISOString()).replace(/[:.]/g,`-`)}.json`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n),f.value=`Full backup exported (includes all secrets).`,c.value=!1}catch(e){p.value=e instanceof Error?e.message:`Export failed`}finally{u.value=!1}}let h=o(null),g=o(null),w=o(!1),T=o(!1),E=o(``),D=o(``),O=o(null),k=y(()=>g.value?.config?Object.keys(g.value.config).join(`, `):``),A=y(()=>{let e=g.value?.meta?.includes_secrets;return e===!0||e===`true`});function j(e){let t=e.target.files?.[0];if(!t)return;h.value=t,g.value=null,w.value=!1,E.value=``,D.value=``;let n=new FileReader;n.onload=e=>{try{let t=JSON.parse(e.target?.result);t.config&&typeof t.config==`object`?g.value={meta:t.meta,config:t.config}:typeof t==`object`&&!Array.isArray(t)?g.value={config:t}:D.value=`Invalid file format — expected a JSON config object.`}catch{D.value=`Invalid JSON file.`}},n.readAsText(t)}function M(){w.value=!1,g.value=null,h.value=null,O.value&&(O.value.value=``)}async function N(){if(g.value?.config){T.value=!0,E.value=``,D.value=``;try{let e=await R.importConfig(g.value.config);if(e.success){let t=e.data,n=e.message||t?.message||`Configuration imported.`;t?.restart_required&&(n+=` A service restart is required for radio changes to take effect.`),E.value=n,w.value=!1,g.value=null,h.value=null,O.value&&(O.value.value=``)}else D.value=e.error||`Import failed`}catch(e){D.value=e instanceof Error?e.message:`Import failed`}finally{T.value=!1}}}let P=o(!1),F=o(!1),I=o(null),L=o(``);async function z(){F.value=!0,L.value=``;try{let e=await R.exportIdentityKey();if(!e.success||!e.data){L.value=e.error||`Export failed`;return}I.value=e.data;let t=new Blob([e.data.identity_key_hex],{type:`text/plain`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`pymc-identity-${e.data.node_address||`key`}.hex`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}catch(e){L.value=e instanceof Error?e.message:`Export failed`}finally{F.value=!1}}return(e,o)=>(a(),C(`div`,ou,[o[39]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Backup & Restore`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Export, import, and restore your repeater configuration`)])],-1),t.value?(a(),C(`div`,su,[...o[6]||=[d(`

Unencrypted Connection

This page is served over HTTP, not HTTPS. Exported data (including identity keys) will be transmitted in plain text. Only use these features on a trusted local network.

`,1)]])):_(``,!0),S(`div`,cu,[o[9]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Export Settings `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},[b(` Download the current configuration as a JSON file. Passwords, JWT secrets, and identity keys are `),S(`strong`,null,`redacted`),b(`. Safe to share or use as a template for other devices. `)])])],-1),S(`button`,{onClick:s,disabled:n.value,class:`cfg-btn-primary`},[n.value?(a(),C(`span`,uu,[v(W,{size:`sm`,color:`current`,class:`inline-block`}),o[7]||=b(` Exporting… `,-1)])):(a(),C(`span`,du,[...o[8]||=[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4`})],-1),b(` Export Settings `,-1)]]))],8,lu),r.value?(a(),C(`p`,fu,l(r.value),1)):_(``,!0),i.value?(a(),C(`p`,pu,l(i.value),1)):_(``,!0)]),S(`div`,mu,[o[15]||=d(`

Full Backup

Download a complete backup including all passwords, JWT secrets, and identity keys. Required for restoring to a new device or recovering from a failed SD card.

Contains sensitive data. The backup file will include plain-text passwords and private keys. Store it securely and never share it.

`,2),c.value?_(``,!0):(a(),C(`div`,hu,[S(`button`,{onClick:o[0]||=e=>c.value=!0,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm`},[...o[10]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z`})]),b(` Full Backup `)],-1)]])])),c.value?(a(),C(`div`,gu,[S(`div`,_u,[o[14]||=S(`svg`,{class:`w-5 h-5 text-red-600 dark:text-red-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,vu,[o[13]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},` Confirm Full Backup `,-1),S(`p`,yu,[o[11]||=b(` This will export `,-1),o[12]||=S(`strong`,null,`all secrets in plain text`,-1),b(` including admin/guest passwords, JWT secret, and your repeater's private identity key`+l(t.value?` over an unencrypted HTTP connection`:``)+`. `,1)]),S(`div`,bu,[S(`button`,{onClick:m,disabled:u.value,class:`px-4 py-2 bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},l(u.value?`Exporting…`:`Yes, Export Full Backup`),9,xu),S(`button`,{onClick:o[1]||=e=>c.value=!1,disabled:u.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,Su)])])])])):_(``,!0),f.value?(a(),C(`p`,Cu,l(f.value),1)):_(``,!0),p.value?(a(),C(`p`,wu,l(p.value),1)):_(``,!0)]),S(`div`,Tu,[o[29]||=S(`div`,{class:`flex items-start justify-between mb-4`},[S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Import Configuration `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},[b(` Restore configuration from a previously exported JSON file. Importing a `),S(`strong`,null,`full backup`),b(` will also restore passwords and identity keys. Importing a `),S(`strong`,null,`settings export`),b(` will only update non-sensitive settings. `)])])],-1),S(`div`,Eu,[S(`label`,Du,[o[16]||=S(`svg`,{class:`w-5 h-5 text-content-secondary dark:text-content-muted`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12`})],-1),S(`span`,Ou,l(h.value?h.value.name:`Choose a config JSON file…`),1),S(`input`,{ref_key:`fileInputRef`,ref:O,type:`file`,accept:`.json,application/json`,class:`hidden`,onChange:j},null,544)]),g.value?(a(),C(`div`,ku,[o[20]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Import Preview `,-1),g.value.meta?(a(),C(`div`,Au,[S(`p`,null,[o[17]||=b(` Exported: `,-1),S(`span`,ju,l(g.value.meta.exported_at),1)]),S(`p`,null,[o[18]||=b(` Version: `,-1),S(`span`,Mu,l(g.value.meta.version),1)]),g.value.meta.includes_secrets===`true`||g.value.meta.includes_secrets===!0?(a(),C(`p`,Nu,` ⚠ Full backup — will restore passwords and identity keys `)):(a(),C(`p`,Pu,` Settings only — existing secrets will not be changed `))])):_(``,!0),S(`p`,Fu,[o[19]||=b(` Sections: `,-1),S(`span`,Iu,l(k.value),1)])])):_(``,!0),g.value&&!w.value?(a(),C(`div`,Lu,[S(`button`,{onClick:o[2]||=e=>w.value=!0,class:`px-4 py-2 bg-amber-500/20 dark:bg-amber-400/20 hover:bg-amber-500/30 dark:hover:bg-amber-400/30 text-amber-900 dark:text-amber-200 rounded-lg border border-amber-500/50 dark:border-amber-400/40 transition-colors text-sm`},` Review & Import `)])):_(``,!0),w.value?(a(),C(`div`,Ru,[S(`div`,zu,[o[28]||=S(`svg`,{class:`w-5 h-5 text-amber-600 dark:text-amber-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,Bu,[o[27]||=S(`h4`,{class:`text-sm font-semibold text-amber-800 dark:text-amber-300`},` Confirm Import `,-1),S(`p`,Vu,[o[24]||=b(` This will overwrite current settings for: `,-1),S(`strong`,null,l(k.value),1),o[25]||=b(`. `,-1),A.value?(a(),C(x,{key:0},[o[21]||=b(` This is a full backup — `,-1),o[22]||=S(`strong`,null,`passwords, JWT secrets, and identity keys will also be overwritten`,-1),o[23]||=b(`. `,-1)],64)):(a(),C(x,{key:1},[b(` Passwords and identity keys will not be changed. `)],64)),o[26]||=b(` Some changes (radio settings) require a service restart. `,-1)]),S(`div`,Hu,[S(`button`,{onClick:N,disabled:T.value,class:`px-4 py-2 bg-amber-600 hover:bg-amber-700 dark:bg-amber-500 dark:hover:bg-amber-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},l(T.value?`Importing…`:`Yes, Import`),9,Uu),S(`button`,{onClick:M,disabled:T.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,Wu)])])])])):_(``,!0),E.value?(a(),C(`p`,Gu,l(E.value),1)):_(``,!0),D.value?(a(),C(`p`,Ku,l(D.value),1)):_(``,!0)])]),S(`div`,qu,[o[38]||=d(`

Export Identity Key

Download the repeater's private identity key for backup. This key determines the node's address and cryptographic identity on the mesh.

Sensitive data. The identity key is the repeater's private key. Anyone with this key can impersonate your node. Store the exported file securely and never share it.

`,2),P.value?_(``,!0):(a(),C(`div`,Ju,[S(`button`,{onClick:o[3]||=e=>P.value=!0,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm`},[...o[30]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z`})]),b(` Export Identity Key `)],-1)]])])),P.value&&!I.value?(a(),C(`div`,Yu,[S(`div`,Xu,[o[32]||=S(`svg`,{class:`w-5 h-5 text-red-600 dark:text-red-400 shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,Zu,[o[31]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},`Are you sure?`,-1),S(`p`,Qu,` This will transmit your private key `+l(t.value?`over an unencrypted HTTP connection. `:``)+` and download it as a file. `,1),S(`div`,$u,[S(`button`,{onClick:z,disabled:F.value,class:`px-4 py-2 bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600 text-white rounded-lg transition-colors text-sm disabled:opacity-50`},l(F.value?`Exporting…`:`Yes, Export Key`),9,ed),S(`button`,{onClick:o[4]||=e=>P.value=!1,disabled:F.value,class:`px-4 py-2 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-primary dark:text-content-primary rounded-lg transition-colors text-sm`},` Cancel `,8,td)])])])])):_(``,!0),I.value?(a(),C(`div`,nd,[S(`div`,rd,[o[33]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Key Exported `,-1),S(`button`,{onClick:o[5]||=e=>{I.value=null,P.value=!1},class:`text-xs text-content-muted hover:text-content-secondary transition-colors`},` Dismiss `)]),S(`div`,id,[S(`p`,null,[o[34]||=b(` Key length: `,-1),S(`span`,ad,l(I.value.key_length_bytes)+` bytes`,1)]),I.value.node_address?(a(),C(`p`,od,[o[35]||=b(` Node address: `,-1),S(`span`,sd,l(I.value.node_address),1)])):_(``,!0),I.value.public_key_hex?(a(),C(`p`,cd,[o[36]||=b(` Public key: `,-1),S(`span`,ld,l(I.value.public_key_hex),1)])):_(``,!0)]),o[37]||=S(`p`,{class:`text-xs text-green-600 dark:text-green-400`},`File downloaded successfully.`,-1)])):_(``,!0),L.value?(a(),C(`p`,ud,l(L.value),1)):_(``,!0)])]))}}),fd={class:`space-y-12`},pd={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},md={class:`flex items-center gap-2 flex-shrink-0`},hd={class:`cfg-section`},gd={class:`flex items-start justify-between mb-4`},_d=[`disabled`],vd={key:0,class:`flex items-center gap-1.5`},yd={key:1},bd={key:0,class:`grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6`},xd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Sd={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Cd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},wd={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Td={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Ed={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Dd={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Od={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},kd={key:1,class:`flex items-center justify-center py-12`},Ad={class:`text-center`},jd={key:2,class:`rounded-lg border border-red-500/30 dark:border-red-400/30 bg-red-50 dark:bg-red-500/10 p-3 mb-4`},Md={class:`text-xs text-red-700 dark:text-red-400`},Nd={key:3},Pd={class:`overflow-x-auto`},Fd={class:`w-full text-sm`},Id={class:`py-2.5 pr-4`},Ld={class:`font-mono text-content-primary dark:text-content-primary`},Rd={class:`py-2.5 pr-4 text-right`},zd={class:`font-mono text-content-secondary dark:text-content-muted`},Bd={class:`py-2.5 pr-4 text-right hidden sm:table-cell`},Vd={key:0,class:`text-xs text-content-muted`},Hd={class:`text-content-muted/60 ml-1`},Ud={key:1,class:`text-xs text-content-muted/50`},Wd={key:2,class:`text-xs text-content-muted/50`},Gd={class:`py-2.5 text-right`},Kd=[`onClick`,`disabled`],qd={key:0,class:`flex items-center gap-1`},Jd={key:1},Yd={key:1,class:`text-xs text-content-muted/50`},Xd={class:`flex items-start gap-3 mb-5`},Zd={class:`flex-1 min-w-0`},Qd={class:`text-lg font-semibold text-content-primary dark:text-content-primary`},$d={class:`text-sm text-content-secondary dark:text-content-muted mt-1`},ef={class:`text-content-primary dark:text-content-primary`},tf={class:`text-content-primary dark:text-content-primary font-mono`},nf={class:`flex gap-3`},rf=[`disabled`],af=[`disabled`],of={class:`cfg-section`},sf={class:`flex flex-wrap gap-3`},cf=[`disabled`],lf=[`disabled`],uf={class:`flex items-center gap-2`},df={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-3`},ff={key:1,class:`text-xs text-green-600 dark:text-green-400 mt-3`},pf=f({__name:`DatabaseManagement`,setup(n){let r=new Set([`packets`,`adverts`,`noise_floor`,`crc_errors`,`room_messages`,`room_client_sync`,`companion_contacts`,`companion_channels`,`companion_messages`,`companion_prefs`]),i=o(!1),s=o(!1),d=o(``),f=o(null),p=o({}),h=o(null),g=o(``),w=o(!1),T=o(``),E=y(()=>f.value?f.value.tables.reduce((e,t)=>e+t.row_count,0):0);function D(e){return r.has(e)}function O(e,t){return!e||!t?0:Math.max(1,Math.round((t-e)/86400))}async function k(){s.value=!0,d.value=``;try{let e=await R.getDbStats();e.success&&e.data?f.value=e.data:d.value=e.error||`Failed to load database stats`}catch(e){d.value=e instanceof Error?e.message:`Failed to load database stats`}finally{s.value=!1}}function j(e,t){g.value=``,h.value={table:e,rowCount:t,executing:!1}}async function M(){if(!h.value)return;let{table:e}=h.value;h.value.executing=!0,g.value=``;try{let t=e===`all`?`all`:[e];e!==`all`&&(p.value[e]=!0);let n=await R.purgeTable(t);if(n.success){let t=n.data||{};g.value=`Deleted ${Object.values(t).reduce((e,t)=>e+(t.deleted||0),0).toLocaleString()} rows${e===`all`?` from all tables`:` from ${e}`}.`,h.value=null,await k()}else d.value=n.error||`Purge failed`,h.value=null}catch(e){d.value=e instanceof Error?e.message:`Purge failed`,h.value=null}finally{e!==`all`&&(p.value[e]=!1)}}async function N(){w.value=!0,T.value=``,d.value=``;try{let e=await R.vacuumDb();if(e.success&&e.data){let t=e.data.freed_bytes;T.value=t>0?`Compacted database — freed ${Q(t)} (${Q(e.data.size_before)} → ${Q(e.data.size_after)}).`:`Database already compact (${Q(e.data.size_after)}).`,await k()}else d.value=e.error||`Vacuum failed`}catch(e){d.value=e instanceof Error?e.message:`Vacuum failed`}finally{w.value=!1}}return e(k),(e,n)=>(a(),C(`div`,fd,[S(`div`,pd,[n[5]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Database`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`View database statistics and perform maintenance`)],-1),S(`div`,md,[S(`button`,{onClick:n[0]||=e=>i.value=!i.value,class:`cfg-btn-primary`},l(i.value?`Lock`:`Unlock`),1)])]),S(`div`,hd,[S(`div`,gd,[n[7]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Database Overview `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Storage usage and table statistics for the repeater database. `)],-1),S(`button`,{onClick:k,disabled:s.value,class:`cfg-btn-secondary`},[s.value?(a(),C(`span`,vd,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[6]||=b(` Loading… `,-1)])):(a(),C(`span`,yd,`Refresh`))],8,_d)]),f.value?(a(),C(`div`,bd,[S(`div`,xd,[n[8]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Database Size`,-1),S(`p`,Sd,l(c(Q)(f.value.database_size_bytes)),1)]),S(`div`,Cd,[n[9]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`RRD Metrics`,-1),S(`p`,wd,l(c(Q)(f.value.rrd_size_bytes)),1)]),S(`div`,Td,[n[10]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Size`,-1),S(`p`,Ed,l(c(Q)(f.value.database_size_bytes+f.value.rrd_size_bytes)),1)]),S(`div`,Dd,[n[11]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Rows`,-1),S(`p`,Od,l(E.value.toLocaleString()),1)])])):_(``,!0),s.value&&!f.value?(a(),C(`div`,kd,[S(`div`,Ad,[v(W,{class:`mx-auto mb-4`}),n[12]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading database info…`,-1)])])):_(``,!0),d.value?(a(),C(`div`,jd,[S(`p`,Md,l(d.value),1)])):_(``,!0),f.value&&f.value.tables.length>0?(a(),C(`div`,Nd,[S(`div`,Pd,[S(`table`,Fd,[n[14]||=S(`thead`,null,[S(`tr`,{class:`border-b border-stroke-subtle dark:border-stroke/10`},[S(`th`,{class:`text-left py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider`},` Table `),S(`th`,{class:`text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider`},` Rows `),S(`th`,{class:`text-right py-2 pr-4 text-xs font-medium text-content-muted uppercase tracking-wider hidden sm:table-cell`},` Date Range `),S(`th`,{class:`text-right py-2 text-xs font-medium text-content-muted uppercase tracking-wider`},` Actions `)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(f.value.tables,e=>(a(),C(`tr`,{key:e.name,class:`border-b border-stroke-subtle/50 dark:border-stroke/5`},[S(`td`,Id,[S(`span`,Ld,l(e.name),1)]),S(`td`,Rd,[S(`span`,zd,l(e.row_count.toLocaleString()),1)]),S(`td`,Bd,[e.has_timestamp&&e.row_count>0?(a(),C(`span`,Vd,[b(l(c(Z)(e.oldest_timestamp))+` — `+l(c(Z)(e.newest_timestamp))+` `,1),S(`span`,Hd,`(`+l(O(e.oldest_timestamp,e.newest_timestamp))+`d)`,1)])):e.row_count===0?(a(),C(`span`,Ud,`—`)):(a(),C(`span`,Wd,`n/a`))]),S(`td`,Gd,[i.value&&D(e.name)&&e.row_count>0?(a(),C(`button`,{key:0,onClick:t=>j(e.name,e.row_count),disabled:p.value[e.name],class:`px-2.5 py-1 bg-red-500/10 dark:bg-red-400/10 hover:bg-red-500/20 dark:hover:bg-red-400/20 text-red-700 dark:text-red-400 rounded border border-red-500/30 dark:border-red-400/20 transition-colors text-xs disabled:opacity-50`},[p.value[e.name]?(a(),C(`span`,qd,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[13]||=b(` Purging… `,-1)])):(a(),C(`span`,Jd,`Empty`))],8,Kd)):D(e.name)?_(``,!0):(a(),C(`span`,Yd,`—`))])]))),128))])])])])):_(``,!0)]),(a(),u(m,{to:`body`},[h.value?(a(),C(`div`,{key:0,class:`modal-backdrop-heavy`,onClick:n[3]||=A(e=>!h.value.executing&&(h.value=null),[`self`])},[S(`div`,{class:`modal-card max-w-lg`,onClick:n[2]||=A(()=>{},[`stop`])},[S(`div`,Xd,[n[20]||=S(`div`,{class:`flex-shrink-0 w-10 h-10 rounded-full bg-red-500/15 flex items-center justify-center`},[S(`svg`,{class:`w-5 h-5 text-red-500 dark:text-red-400`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})])],-1),S(`div`,Zd,[S(`h3`,Qd,l(h.value.table===`all`?`Purge All Tables`:`Purge "${h.value.table}"`),1),S(`p`,$d,[h.value.table===`all`?(a(),C(x,{key:0},[n[15]||=b(` This will permanently delete `,-1),n[16]||=S(`strong`,{class:`text-content-primary dark:text-content-primary`},`all data`,-1),b(` from every data table (`+l(E.value.toLocaleString())+` rows total). This cannot be undone. `,1)],64)):(a(),C(x,{key:1},[n[17]||=b(` This will permanently delete `,-1),S(`strong`,ef,l(h.value.rowCount.toLocaleString())+` rows`,1),n[18]||=b(` from `,-1),S(`strong`,tf,l(h.value.table),1),n[19]||=b(`. This cannot be undone. `,-1)],64))])])]),S(`div`,nf,[S(`button`,{onClick:n[1]||=e=>h.value=null,disabled:h.value.executing,class:`flex-1 px-4 py-3 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary rounded-lg transition-colors`},` Cancel `,8,rf),S(`button`,{onClick:M,disabled:h.value.executing,class:`flex-1 px-4 py-3 bg-red-500/20 hover:bg-red-500/30 border border-red-500/50 text-red-600 dark:text-red-400 rounded-lg transition-colors font-medium disabled:opacity-50`},l(h.value.executing?`Purging…`:`Yes, Delete Data`),9,af)])])])):_(``,!0)])),S(`div`,of,[n[23]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Maintenance `,-1),S(`div`,sf,[S(`button`,{onClick:n[4]||=e=>j(`all`,E.value),disabled:!f.value||E.value===0||!i.value,class:`px-4 py-2 bg-red-500/20 dark:bg-red-400/20 hover:bg-red-500/30 dark:hover:bg-red-400/30 text-red-900 dark:text-red-200 rounded-lg border border-red-500/50 dark:border-red-400/40 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},[...n[21]||=[S(`span`,{class:`flex items-center gap-2`},[S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16`})]),b(` Purge All Data `)],-1)]],8,cf),S(`button`,{onClick:N,disabled:w.value||!f.value,class:`cfg-btn-primary`},[S(`span`,uf,[n[22]||=S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15`})],-1),b(` `+l(w.value?`Compacting…`:`Compact Database`),1)])],8,lf)]),T.value?(a(),C(`p`,df,l(T.value),1)):_(``,!0),g.value?(a(),C(`p`,ff,l(g.value),1)):_(``,!0)])]))}}),mf={class:`space-y-12`},hf={class:`cfg-section`},gf={class:`flex items-start justify-between mb-4`},_f={class:`flex items-center gap-2`},vf=[`disabled`],yf={key:0,class:`flex items-center gap-1.5`},bf={key:1},xf=[`disabled`],Sf={key:0,class:`flex items-center gap-1.5`},Cf={key:1},wf={key:0,class:`mb-4 p-3 rounded-lg bg-red-500/10 border border-red-500/30 text-red-600 dark:text-red-400 text-sm`},Tf={key:1,class:`mb-4`},Ef={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10 inline-block`},Df={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Of={key:2,class:`p-4 rounded-lg bg-cyan-500/10 dark:bg-primary/10 border border-cyan-400/30 dark:border-primary/30`},kf={key:3},Af=[`innerHTML`],jf={class:`font-semibold text-sm`},Mf={class:`text-sm mt-0.5 opacity-80`},Nf={class:`grid grid-cols-2 sm:grid-cols-3 gap-3 mb-6`},Pf={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Ff={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},If={key:1,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Lf={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Rf={key:2,class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},zf={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Bf={key:0,class:`mb-6`},Vf={class:`space-y-2`},Hf={class:`flex items-start justify-between gap-3`},Uf={class:`flex items-center gap-2 min-w-0`},Wf={class:`shrink-0 text-xs font-medium text-content-muted w-5 text-right`},Gf={class:`text-right shrink-0`},Kf={class:`text-xs text-content-muted`},qf={class:`mt-1.5 ml-7`},Jf={class:`text-xs font-mono text-content-secondary dark:text-content-muted break-all`},Yf={key:0,class:`text-xs text-content-muted mt-0.5`},Xf={key:1,class:`mb-6 p-4 rounded-lg bg-green-500/10 border border-green-500/30 text-sm flex items-center gap-3`},Zf={key:2},Qf={key:0,class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/10`},$f={class:`w-full text-sm`},ep={class:`px-3 py-2 text-content-muted font-mono text-xs`},tp={class:`px-3 py-2 text-content-primary dark:text-content-primary font-mono text-xs break-all`},np={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted whitespace-nowrap`},rp={class:`px-3 py-2 text-right font-mono text-xs text-content-secondary dark:text-content-muted`},ip={key:4,class:`py-8 text-center text-content-muted text-sm`},ap=K(f({__name:`MemoryDebug`,setup(n){let i=o(!1),s=o(!1),c=o(``),u=o(null),f=o(!1),m=o(null),h=o(!1),g=y(()=>u.value&&(u.value.current_top_20||u.value.growth_since_baseline));async function w(){i.value=!0,c.value=``;try{let e=await R.get(`memory_debug`);e.success&&e.data?(f.value=!!e.data.tracing,m.value=e.data.rss_mb??null,(e.data.current_top_20||e.data.growth_since_baseline)&&(u.value=e.data)):c.value=e.error||`Failed to fetch memory status`}catch(e){c.value=e instanceof Error?e.message:`Failed to fetch memory status`}finally{i.value=!1}}async function T(){s.value=!0,c.value=``;let e=f.value?`stop`:`start`;try{let t=await R.post(`memory_debug`,{action:e});t.success&&t.data?(f.value=!!t.data.tracing,e===`stop`&&(u.value=null,m.value=null)):c.value=t.error||`Failed to ${e} tracing`}catch(t){c.value=t instanceof Error?t.message:`Failed to ${e} tracing`}finally{s.value=!1,f.value&&await w()}}function E(e){return e.size_diff_kb>=100?`critical`:e.size_diff_kb>=10?`warning`:e.size_diff_kb>=1?`low`:`ok`}function D(e){let t=E(e);return t===`critical`?`Investigate`:t===`warning`?`Watch`:t===`low`?`Minor`:`Normal`}function O(e){let t=E(e);return t===`critical`?`bg-red-500/20 text-red-700 dark:text-red-400 border border-red-500/30`:t===`warning`?`bg-amber-500/20 text-amber-700 dark:text-amber-400 border border-amber-500/30`:t===`low`?`bg-blue-500/15 text-blue-600 dark:text-blue-400 border border-blue-500/20`:`bg-green-500/15 text-green-700 dark:text-green-400 border border-green-500/20`}function k(e){let t=E(e);return t===`critical`?`border-red-500/40 dark:border-red-500/30 bg-red-500/5 dark:bg-red-500/5`:t===`warning`?`border-amber-500/40 dark:border-amber-500/30 bg-amber-500/5 dark:bg-amber-500/5`:t===`low`?`border-stroke-subtle dark:border-stroke/10 bg-background-mute/50 dark:bg-background/20`:`border-stroke-subtle/50 dark:border-stroke/5 bg-background-mute/30 dark:bg-background/10 opacity-60`}function A(e){let t=E(e);return t===`critical`?`text-red-600 dark:text-red-400`:t===`warning`?`text-amber-600 dark:text-amber-400`:t===`low`?`text-blue-600 dark:text-blue-400`:`text-green-600 dark:text-green-500`}function j(e){return e>=1024?`${(e/1024).toFixed(1)} MB`:e>=10?`${Math.round(e)} KB`:`${e.toFixed(1)} KB`}function M(e){return e.replace(/.*\/site-packages\//,``).replace(/.*\/lib\/python[^/]*\//,``).replace(/.*\/repeater\//,`repeater/`)}let P=y(()=>u.value?.growth_since_baseline?u.value.growth_since_baseline.reduce((e,t)=>e+t.size_diff_kb,0):0),F=y(()=>P.value>=500?`critical`:P.value>=50?`warning`:P.value>=5?`low`:`ok`),I=y(()=>{let e=F.value;return e===`critical`?`border-red-500/40 dark:border-red-500/30 bg-red-500/10 dark:bg-red-500/10 text-red-800 dark:text-red-300`:e===`warning`?`border-amber-500/40 dark:border-amber-500/30 bg-amber-500/10 dark:bg-amber-500/10 text-amber-800 dark:text-amber-300`:e===`low`?`border-blue-500/30 bg-blue-500/10 dark:bg-blue-500/10 text-blue-800 dark:text-blue-300`:`border-green-500/30 bg-green-500/10 dark:bg-green-500/10 text-green-800 dark:text-green-300`}),L=y(()=>{let e=F.value;return e===`critical`?``:e===`warning`?``:e===`low`?``:``}),z=y(()=>{let e=F.value;return e===`critical`?`Significant memory growth detected`:e===`warning`?`Some memory growth detected`:e===`low`?`Minor memory growth — likely normal`:`Memory looks healthy`}),B=y(()=>{let e=j(P.value),t=F.value;return t===`critical`?`Total growth: ${e}. Red items below need attention.`:t===`warning`?`Total growth: ${e}. Orange items below may need attention over time.`:t===`low`?`Total growth: ${e}. Nothing to worry about right now.`:`No significant growth since tracing started.`});return e(w),(e,n)=>(a(),C(`div`,mf,[n[15]||=S(`div`,{class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},[S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},`Memory`),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Diagnose memory usage and trace allocations`)])],-1),S(`div`,hf,[S(`div`,gf,[n[2]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Memory Diagnostics `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Trace memory allocations to find leaks. Tracing adds overhead — only enable when needed. `)],-1),S(`div`,_f,[f.value&&g.value?(a(),C(`button`,{key:0,onClick:w,disabled:i.value,class:`cfg-btn-secondary`},[i.value?(a(),C(`span`,yf,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),n[1]||=b(` Checking… `,-1)])):(a(),C(`span`,bf,`Check Again`))],8,vf)):_(``,!0),S(`button`,{onClick:T,disabled:s.value,class:p([`px-3 py-1.5 rounded-lg border text-sm transition-colors disabled:opacity-50`,f.value?`bg-red-500/20 hover:bg-red-500/30 text-red-700 dark:text-red-400 border-red-500/50`:`bg-green-500/20 hover:bg-green-500/30 text-green-700 dark:text-green-400 border-green-500/50`])},[s.value?(a(),C(`span`,Sf,[v(W,{size:`xs`,color:`current`,class:`inline-block`}),b(` `+l(f.value?`Stopping…`:`Starting…`),1)])):(a(),C(`span`,Cf,l(f.value?`Stop Tracing`:`Start Tracing`),1))],10,xf)])]),c.value?(a(),C(`div`,wf,l(c.value),1)):_(``,!0),!f.value&&m.value!==null&&!i.value?(a(),C(`div`,Tf,[S(`div`,Ef,[n[3]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Current Memory (RSS)`,-1),S(`p`,Df,l(m.value)+` MB`,1)])])):_(``,!0),f.value&&!g.value&&!i.value?(a(),C(`div`,Of,[...n[4]||=[d(`
Tracing active

Memory tracing is running. Let the repeater run for a few minutes, then click Check Again to see which parts of the code are using more memory.

`,2)]])):_(``,!0),u.value&&g.value?(a(),C(`div`,kf,[S(`div`,{class:p([`mb-5 p-4 rounded-lg border flex items-start gap-3`,I.value])},[S(`div`,{class:`mt-0.5`,innerHTML:L.value},null,8,Af),S(`div`,null,[S(`p`,jf,l(z.value),1),S(`p`,Mf,l(B.value),1)])],2),S(`div`,Nf,[u.value.rss_mb===void 0?_(``,!0):(a(),C(`div`,Pf,[n[5]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Memory Used`,-1),S(`p`,Ff,l(u.value.rss_mb)+` MB`,1)])),u.value.traced_current_mb===void 0?_(``,!0):(a(),C(`div`,If,[n[6]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Tracked Now`,-1),S(`p`,Lf,l(u.value.traced_current_mb)+` MB`,1)])),u.value.traced_peak_mb===void 0?_(``,!0):(a(),C(`div`,Rf,[n[7]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Peak Tracked`,-1),S(`p`,zf,l(u.value.traced_peak_mb)+` MB`,1)]))]),u.value.growth_since_baseline&&u.value.growth_since_baseline.length>0?(a(),C(`div`,Bf,[n[8]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary mb-1`},`Memory Growth Breakdown`,-1),n[9]||=S(`p`,{class:`text-xs text-content-muted mb-3`},` Items at the top with red/orange tags are the most likely cause of memory issues. Green items are normal and can be ignored. `,-1),S(`div`,Vf,[(a(!0),C(x,null,t(u.value.growth_since_baseline,(e,t)=>(a(),C(`div`,{key:t,class:p([`rounded-lg border p-3 transition-colors`,k(e)])},[S(`div`,Hf,[S(`div`,Uf,[S(`span`,Wf,l(t+1),1),S(`span`,{class:p([`shrink-0 inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold`,O(e)])},l(D(e)),3)]),S(`div`,Gf,[S(`span`,{class:p([`font-mono text-sm font-semibold`,A(e)])},`+`+l(j(e.size_diff_kb)),3),S(`p`,Kf,l(j(e.current_size_kb))+` total`,1)])]),S(`div`,qf,[S(`p`,Jf,l(M(e.file)),1),e.count_diff===0?_(``,!0):(a(),C(`p`,Yf,l(e.count_diff>0?`+`:``)+l(e.count_diff)+` new allocation`+l(Math.abs(e.count_diff)===1?``:`s`),1))])],2))),128))])])):u.value.growth_since_baseline&&u.value.growth_since_baseline.length===0?(a(),C(`div`,Xf,[...n[10]||=[S(`svg`,{class:`w-5 h-5 text-green-600 dark:text-green-400 shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z`})],-1),S(`span`,{class:`text-green-700 dark:text-green-400`},`No memory growth detected. Everything looks healthy.`,-1)]])):_(``,!0),u.value.current_top_20&&u.value.current_top_20.length>0?(a(),C(`div`,Zf,[S(`button`,{onClick:n[0]||=e=>h.value=!h.value,class:`flex items-center gap-2 text-sm font-semibold text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors mb-3`},[(a(),C(`svg`,{class:p([`w-4 h-4 transition-transform`,{"rotate-90":h.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),n[12]||=b(` Advanced: Current Top Allocations `,-1)]),v(N,{name:`expand`},{default:r(()=>[h.value?(a(),C(`div`,Qf,[S(`table`,$f,[n[13]||=S(`thead`,null,[S(`tr`,{class:`bg-background-mute dark:bg-background/30 text-left`},[S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted`},`#`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted`},`Location`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted text-right`},`Size`),S(`th`,{class:`px-3 py-2 text-xs font-medium text-content-muted text-right`},`Count`)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(u.value.current_top_20,(e,t)=>(a(),C(`tr`,{key:t,class:`border-t border-stroke-subtle/50 dark:border-stroke/5 hover:bg-background-mute/50 dark:hover:bg-background/20 transition-colors`},[S(`td`,ep,l(t+1),1),S(`td`,tp,l(M(e.file)),1),S(`td`,np,l(j(e.size_kb)),1),S(`td`,rp,l(e.count),1)]))),128))])])])):_(``,!0)]),_:1})])):_(``,!0)])):_(``,!0),!i.value&&!s.value&&!f.value&&!g.value&&!c.value&&m.value===null?(a(),C(`div`,ip,[...n[14]||=[b(` Click `,-1),S(`strong`,null,`Start Tracing`,-1),b(` to enable memory diagnostics. `,-1),S(`br`,null,null,-1),S(`span`,{class:`text-xs`},`Tracing uses extra memory — remember to stop it when done.`,-1)]])):_(``,!0)])]))}}),[[`__scopeId`,`data-v-00e540ed`]]),op={class:`space-y-6`},sp={class:`cfg-page-heading flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},cp={class:`flex items-center gap-2 flex-shrink-0`},lp=[`disabled`],up=[`disabled`],dp=[`disabled`],fp={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3 text-red-600 dark:text-red-400 text-sm`},pp={key:1,class:`bg-emerald-500/10 border border-emerald-500/30 rounded-lg p-3 text-emerald-700 dark:text-emerald-400 text-sm`},mp={key:2,class:`bg-blue-500/10 border border-blue-500/30 rounded-lg p-3 text-blue-700 dark:text-blue-300 text-sm`},hp={key:3,class:`flex items-center justify-center py-10`},gp={class:`cfg-section`},_p={class:`flex flex-wrap items-center gap-2`},vp={key:0,class:`space-y-4`},yp={class:`cfg-section space-y-4`},bp={class:`grid grid-cols-1 xl:grid-cols-2 gap-4 items-stretch`},xp={class:`rounded-xl border border-stroke-subtle dark:border-stroke/20 bg-background-mute/50 dark:bg-white/5 px-4 py-4 flex items-center justify-between gap-4`},Sp={class:`inline-flex items-center gap-3 rounded-full border border-stroke-subtle dark:border-stroke/20 bg-background-main dark:bg-surface-900 px-3 py-2 text-sm font-medium text-content-primary dark:text-content-primary shadow-sm`},Cp=[`disabled`],wp={class:`rounded-xl border border-stroke-subtle dark:border-stroke/20 bg-background-mute/50 dark:bg-white/5 px-4 py-4 flex flex-col justify-between gap-3`},Tp=[`disabled`],Ep=[`value`],Dp={class:`space-y-3`},Op={class:`flex flex-wrap items-center justify-between gap-2`},kp={class:`flex items-center gap-2`},Ap=[`disabled`],jp=[`disabled`],Mp={class:`overflow-x-auto rounded-2xl border border-stroke-subtle dark:border-stroke/20 bg-background-main dark:bg-surface-900 shadow-sm`},Np={class:`w-full min-w-[980px] table-fixed text-sm`},Pp={class:`px-3 py-3 text-xs font-medium text-content-secondary dark:text-content-secondary`},Fp={class:`px-3 py-3`},Ip=[`title`],Lp={class:`px-3 py-3 text-content-primary dark:text-content-primary`},Rp=[`title`],zp={class:`px-3 py-3 text-xs text-content-secondary dark:text-content-secondary`},Bp=[`title`],Vp={class:`px-3 py-3`},Hp=[`title`],Up={class:`px-3 py-3 text-right`},Wp={class:`inline-flex flex-wrap items-center justify-end gap-1`},Gp=[`disabled`,`onClick`],Kp=[`disabled`,`onClick`],qp=[`disabled`,`onClick`],Jp=[`disabled`,`onClick`],Yp={key:0},Xp={key:0,class:`space-y-2`},Zp=[`disabled`],Qp={class:`flex justify-end`},$p=[`disabled`],em={class:`flex flex-wrap items-center gap-2 justify-end`},tm=[`disabled`],nm={key:1,class:`space-y-4`},rm={class:`cfg-section`},im={class:`flex flex-wrap items-center gap-2`},am={class:`grid grid-cols-1 lg:grid-cols-12 gap-4`},om={class:`cfg-section lg:col-span-4 space-y-4`},sm={class:`flex items-center justify-between`},cm={class:`text-xs text-content-muted dark:text-content-muted`},lm={class:`space-y-2 max-h-[360px] overflow-auto pr-1`},um=[`onClick`],dm={class:`flex items-start justify-between gap-2`},fm={class:`text-sm font-medium text-content-primary dark:text-content-primary`},pm={class:`text-xs text-content-muted dark:text-content-muted mt-1`},mm={class:`text-[11px] text-content-muted dark:text-content-muted`},hm={key:0,class:`text-xs text-content-muted dark:text-content-muted py-8 text-center border border-dashed border-stroke-subtle dark:border-stroke/30 rounded-lg`},gm={class:`pt-2 border-t border-stroke-subtle dark:border-stroke/20 space-y-2`},_m=[`disabled`],vm=[`disabled`],ym=[`disabled`],bm={class:`cfg-section lg:col-span-8 space-y-4`},xm={class:`flex items-center justify-between`},Sm={class:`text-sm font-semibold text-content-primary dark:text-content-primary`},Cm=[`disabled`],wm={key:0,class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},Tm={class:`w-full text-sm`},Em={class:`px-3 py-2 text-content-primary dark:text-content-primary`},Dm={class:`px-3 py-2 font-mono text-xs text-content-secondary dark:text-content-secondary`},Om={class:`px-3 py-2 text-right`},km=[`disabled`,`onClick`],Am={key:0},jm={key:1,class:`text-xs text-content-muted dark:text-content-muted py-8 text-center border border-dashed border-stroke-subtle dark:border-stroke/30 rounded-lg`},Mm={key:2,class:`pt-2 border-t border-stroke-subtle dark:border-stroke/20 space-y-2`},Nm={class:`grid grid-cols-1 md:grid-cols-2 gap-2`},Pm=[`disabled`],Fm=[`disabled`,`placeholder`],Im=[`disabled`],Lm={class:`bg-surface dark:bg-surface-elevated border border-stroke-subtle dark:border-stroke/20 rounded-[15px] p-5 max-w-5xl w-full max-h-[90vh] overflow-y-auto shadow-2xl space-y-4`},Rm={class:`flex items-start justify-between gap-3`},zm={class:`text-lg font-semibold text-content-primary dark:text-content-primary`},Bm={class:`text-xs text-content-muted dark:text-content-muted mt-1`},Vm={class:`flex items-center gap-2`},Hm={key:0,class:`rounded-lg border border-primary/30 bg-primary/5 p-3 space-y-2`},Um={class:`flex items-center justify-between`},Wm={class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},Gm={class:`w-full min-w-[840px] text-xs`},Km={class:`px-2 py-1.5`},qm={class:`px-2 py-1.5`},Jm={class:`px-2 py-1.5`},Ym={class:`px-2 py-1.5`},Xm={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-2 text-red-600 dark:text-red-400 text-xs`},Zm={class:`grid grid-cols-1 md:grid-cols-4 gap-3`},Qm={class:`md:col-span-2`},$m=[`value`],eh={class:`inline-flex items-center gap-2 text-sm text-content-primary dark:text-content-primary`},th={class:`space-y-2`},nh={key:0,class:`rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs text-amber-800 dark:text-amber-200`},rh={class:`overflow-x-auto rounded-lg border border-stroke-subtle dark:border-stroke/20`},ih={class:`w-full min-w-[980px] text-sm`},ah={class:`bg-background-mute dark:bg-white/5`},oh={key:0,class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},sh=[`onDragover`],ch={class:`px-2 py-2 w-[58px]`},lh=[`onDragstart`],uh={class:`px-2 py-2 min-w-[170px]`},dh=[`onUpdate:modelValue`,`onChange`],fh=[`value`],ph={class:`px-2 py-2 min-w-[160px]`},mh=[`onUpdate:modelValue`],hh=[`value`],gh={key:0,class:`px-2 py-2 min-w-[140px]`},_h=[`onUpdate:modelValue`,`disabled`],vh={key:0,value:`group`},yh={class:`px-2 py-2 min-w-[230px]`},bh={key:0,class:`grid grid-cols-2 gap-1`},xh=[`onUpdate:modelValue`],Sh=[`value`],Ch=[`onUpdate:modelValue`],wh=[`value`],Th={key:1,class:`space-y-1`},Eh=[`onChange`],Dh=[`value`],Oh=[`onUpdate:modelValue`,`placeholder`],kh=[`onUpdate:modelValue`,`placeholder`],Ah={key:3,class:`text-[11px] text-slate-500 dark:text-slate-400`},jh={class:`px-2 py-2 min-w-[110px]`},Mh=[`onUpdate:modelValue`,`disabled`],Nh=[`value`],Ph={class:`px-2 py-2 text-right`},Fh={class:`inline-flex items-center gap-1`},Ih=[`disabled`,`onClick`],Lh=[`disabled`,`onClick`],Rh=[`onClick`],zh=[`colspan`],Bh=f({name:`PolicyEngineSettings`,__name:`PolicyEngineSettings`,setup(n,{expose:r}){let s=o(!1),u=o(!1),d=o(!1),f=o(null),m=o(null),g=null,w=o(`policy`),T=o({enabled:!1,default_action:`allow`,rules:[],objects:{}}),E=o({channel_hashes:[],pubkeys:[]}),O=o({enabled:!1,default_action:`allow`,rules:[],objects:{}}),k=o({channel_hashes:[],pubkeys:[]}),N=o(`[]`),P=o(!1),F=o([]),I=o(null),L=o(!1),z=o(null),B=o(null),ee=o(null),V=o(!1),H=o(null),U=o(null),G=o(`channel_hashes`),K=o(``),te=o({friendly_name:``,description:``}),q=o({friendly_name:``,value:``}),ne=[{label:`Allow`,value:`allow`},{label:`Drop`,value:`drop`},{label:`Log Only`,value:`log_only`}],re=[{label:`Equals`,value:`equals`},{label:`Not Equals`,value:`not_equals`},{label:`Greater Than`,value:`greater_than`},{label:`Greater or Equal`,value:`greater_or_equal`},{label:`Less Than`,value:`less_than`},{label:`Less or Equal`,value:`less_or_equal`},{label:`Contains`,value:`contains`},{label:`In List`,value:`in`},{label:`Intersects`,value:`intersects`},{label:`Starts With`,value:`starts_with`},{label:`Ends With`,value:`ends_with`}],ie=[{value:`route_type`,label:`Route Type`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`payload_type`,label:`Payload Type`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`payload_length`,label:`Payload Length`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`path_hash_size`,label:`Path Hash Size`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`hop_count`,label:`Hop Count`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`rssi`,label:`RSSI`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`snr`,label:`SNR`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`]},{value:`mode`,label:`Mode`,valueTypes:[`string`],operators:[`equals`,`not_equals`,`in`]},{value:`local_transmission`,label:`Local Transmission`,valueTypes:[`boolean`],operators:[`equals`,`not_equals`]},{value:`path_hashes`,label:`Path Hashes`,valueTypes:[`string`],operators:[`contains`,`intersects`]},{value:`channel_hash`,label:`Channel Hash`,valueTypes:[`string`],operators:[`equals`,`not_equals`,`in`],groupKinds:[`channel_hashes`]},{value:`channel_decryptable`,label:`Channel Decryptable`,valueTypes:[`boolean`],operators:[`equals`,`not_equals`]},{value:`channel_message_body`,label:`Channel Message Body`,valueTypes:[`string`],operators:[`contains`,`starts_with`,`ends_with`,`equals`,`not_equals`]},{value:`payload_hex`,label:`Payload Hex`,valueTypes:[`string`],operators:[`contains`,`starts_with`,`ends_with`,`equals`,`not_equals`]},{value:`transport_code_0`,label:`Transport Code 0`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]},{value:`transport_code_1`,label:`Transport Code 1`,valueTypes:[`number`],operators:[`equals`,`not_equals`,`greater_than`,`less_than`]}],J=y(()=>{let e={};for(let t of ie)e[t.value]=t;return e}),Y=y(()=>ie.some(e=>Array.isArray(e.groupKinds)&&e.groupKinds.length>0)),X=y(()=>Y.value?8:7);function Z(e){return JSON.parse(JSON.stringify(e))}function Q(e,t){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``)||t}function ae(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n+=1;return`${e}_${n}`}function oe(e){O.value=Z(e.policy_engine),k.value=Z(e.groups)}function se(){T.value=Z(O.value),E.value=Z(k.value),N.value=JSON.stringify(T.value.rules,null,2),F.value=T.value.rules.map((e,t)=>qe(e,t))}function $(){f.value=null,m.value=null,I.value=null,u.value=!0}function ce(e){f.value=e,g&&clearTimeout(g),g=setTimeout(()=>{f.value=null,g=null},3e3)}function le(){se(),u.value=!1,f.value=null,m.value=null,I.value=null,te.value={friendly_name:``,description:``},q.value={friendly_name:``,value:``},at()}function ue(e){return{channel_hash_groups:Object.fromEntries(e.channel_hashes.map(e=>[e.id,e.entries.map(e=>e.value)])),pubkey_groups:Object.fromEntries(e.pubkeys.map(e=>[e.id,e.entries.map(e=>e.value)]))}}function de(){return{...Z(T.value.objects||{}),...ue(E.value)}}let{showUnsavedModal:me,requestLeave:he,handleDiscard:ge,handleSave:_e,handleCancel:ve}=pe(u,d,le,async()=>xt());r({requestLeave:he,isEditing:u});function ye(e,t){let n=e instanceof Error?e.message:t;return n.includes(`404`)?`Policy API not available on the connected backend. Update/restart pyMC_Repeater so /api/policy, /api/policy_groups, and /api/policy_group_entries are exposed.`:n||t}let be=y(()=>E.value[G.value]??[]),xe=y(()=>be.value.find(e=>e.id===K.value)??null);h([G,be],()=>{if(!be.value.length){K.value=``;return}be.value.find(e=>e.id===K.value)||(K.value=be.value[0].id)});function Se(e){return J.value[e]?.label||e}function Ce(e){return re.find(t=>t.value===e)?.label||e}function we(e){return J.value[e]?.operators||[`equals`,`not_equals`]}function Te(e){return J.value[e]?.valueTypes||[`string`]}function Ee(e){return J.value[e]?.groupKinds||[]}function De(e){return e&&E.value[e]||[]}function Oe(e){return Ee(e).length>0}function ke(e){if(e.valueType===`boolean`)return[{label:`true`,value:`true`},{label:`false`,value:`false`}];switch(e.field){case`mode`:return[{label:`Forward`,value:`forward`},{label:`Monitor`,value:`monitor`},{label:`No TX`,value:`no_tx`}];case`route_type`:return[{label:`0 - Transport Flood`,value:`0`},{label:`1 - Flood`,value:`1`},{label:`2 - Direct`,value:`2`},{label:`3 - Transport Direct`,value:`3`}];case`path_hash_size`:return[{label:`1 byte`,value:`1`},{label:`2 bytes`,value:`2`},{label:`3 bytes`,value:`3`}];case`payload_type`:return[{label:`0 - REQ`,value:`0`},{label:`1 - RESPONSE`,value:`1`},{label:`2 - TXT_MSG`,value:`2`},{label:`3 - ACK`,value:`3`},{label:`4 - ADVERT`,value:`4`},{label:`5 - GRP_TXT`,value:`5`},{label:`6 - GRP_DATA`,value:`6`},{label:`7 - ANON_REQ`,value:`7`},{label:`8 - PATH`,value:`8`},{label:`9 - TRACE`,value:`9`},{label:`10 - MULTIPART`,value:`10`},{label:`15 - RAW_CUSTOM`,value:`15`}];default:return[]}}function Ae(e,t){t&&(e.value=t)}function je(e){return e===`path_hashes`}function Me(e){return e===`channel_hash`}function Ne(e){let t=e.trim();if(!t)throw Error(`Channel hash value is required`);let n=t.replace(/^0x/i,``);if(/^[0-9a-fA-F]+$/.test(n)){if(n.length%2!=0)throw Error(`Channel hash/secret must have an even number of hex characters.`);return n.length===32||n.length===64?`0x${n.toUpperCase()}`:n.length<=2?`0x${Number.parseInt(n,16).toString(16).toUpperCase().padStart(2,`0`)}`:`0x${n.toUpperCase()}`}let r;if(/^[0-9]+$/.test(t))r=Number.parseInt(t,10);else throw Error(`Invalid channel hash value: ${e}`);if(!Number.isFinite(r)||Number.isNaN(r)||r<0)throw Error(`Invalid channel hash value: ${e}`);if(r>255)throw Error(`Decimal channel hash must be within 0-255. Use hex secret key for full channel keys.`);return`0x${r.toString(16).toUpperCase().padStart(2,`0`)}`}function Pe(e){let t=e.trim();if(!t)throw Error(`Path hash value is required`);let n=t.replace(/^0x/i,``);if(!n)throw Error(`Path hash value is required`);if(!/^[0-9a-fA-F]+$/.test(n))throw Error(`Invalid path hash value: ${e}`);if(n.length%2!=0)throw Error(`Path hash must have an even number of hex characters: ${e}`);if(![2,4,6].includes(n.length))throw Error(`Path hash must be 1, 2, or 3 bytes: ${e}`);return`0x${n.toUpperCase()}`}function Fe(e){let t=e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean);if(!t.length)throw Error(`At least one path hash is required`);let n=t.map(Pe);if(new Set(n.map(e=>e.replace(/^0x/i,``).length)).size>1)throw Error(`Path hashes in one condition must all use the same byte length.`);return n}function Ie(e,t){return je(e)&&Array.isArray(t)?t.map(e=>Pe(String(e))).join(` `):t==null?``:typeof t==`string`?t:typeof t==`number`||typeof t==`boolean`?String(t):JSON.stringify(t)}function Le(e){let t=e.value.trim();if(je(e.field)){let n=Fe(t);if(e.op===`contains`){if(n.length!==1)throw Error(`Path Hashes with Contains expects one hash. Use Intersects for multiple hashes.`);return n[0]}return n}return Me(e.field)?Ne(t):Ve(t,e.valueType)}function Re(e){return je(e.field)?e.op===`contains`?`Single hash, e.g. 0x42, 0x0042, or 0x000042`:`One hash per line or comma-separated; all must be the same size`:Me(e.field)?`1-byte channel hash (0x11) or full channel secret key`:e.valueType===`boolean`?`true/false`:`value`}function ze(e){return je(e.field)&&e.valueSource===`literal`}function Be(e){return typeof e==`number`?`number`:typeof e==`boolean`?`boolean`:`string`}function Ve(e,t){if(t===`number`){let t=Number(e);if(!Number.isFinite(t))throw Error(`Invalid numeric value: ${e}`);return t}if(t===`boolean`){let t=e.trim().toLowerCase();if(t===`true`)return!0;if(t===`false`)return!1;throw Error(`Invalid boolean value: ${e}. Use true or false.`)}return e}function He(e){return{id:e,field:`hop_count`,op:`greater_than`,valueType:`number`,valueSource:`literal`,value:`2`}}function Ue(e){return{id:e,name:`Rule ${e}`,enabled:!0,matchMode:`all`,conditions:[He(1)],action:`drop`}}function We(){return F.value.length?Math.max(...F.value.map(e=>Number(e.id)||0))+1:1}function Ge(e){return e.conditions.length?Math.max(...e.conditions.map(e=>e.id))+1:1}function Ke(e){let t=we(e.field);t.includes(e.op)||(e.op=t[0]);let n=Te(e.field);n.includes(e.valueType)||(e.valueType=n[0]);let r=Ee(e.field);if(!r.length){e.valueSource=`literal`,e.groupKind=void 0,e.groupId=void 0;return}if(e.valueSource===`group`){(!e.groupKind||!r.includes(e.groupKind))&&(e.groupKind=r[0]),Me(e.field)&&e.op!==`in`&&(e.op=`in`);let t=De(e.groupKind);t.find(t=>t.id===e.groupId)||(e.groupId=t[0]?.id)}}function qe(e,t){let n=e.if??{},r=`all`,i=[];Array.isArray(n.any)?(r=`any`,i=n.any):Array.isArray(n.all)?(r=`all`,i=n.all):`field`in n&&(i=[n]),i.length||(i=[{field:`hop_count`,op:`greater_than`,value:2}]);let a=i.map((e,t)=>{let n=String(e.field??`hop_count`),r=String(e.op??`equals`),i=we(n),a=i.includes(r)?r:i[0],o=e.value;if(typeof o==`string`&&o.startsWith(`@`)){let[e,r]=o.slice(1).split(`.`,2),i=e===`channel_hash_groups`?`channel_hashes`:e===`pubkey_groups`?`pubkeys`:void 0,s={id:t+1,field:n,op:a,valueType:`string`,valueSource:`group`,value:r||``,groupKind:i,groupId:r};return Ke(s),s}let s=Be(o),c={id:t+1,field:n,op:a,valueType:Te(n).includes(s)?s:Te(n)[0],valueSource:`literal`,value:Ie(n,o)};return Ke(c),c}),o=e.then??{},s=String(o.action??e.action??`allow`),c=ne.some(e=>e.value===s)?s:`allow`;return{id:Number(e.id??t+1),name:String(e.name??`Rule ${t+1}`),enabled:!!(e.enabled??!0),matchMode:r,conditions:a,action:c}}function Je(e,t){let n=e.conditions.map(t=>{let n;if(t.valueSource===`group`){if(!t.groupKind||!t.groupId)throw Error(`Condition ${t.id} in ${e.name} is missing group selection`);n=`@${t.groupKind===`channel_hashes`?`channel_hash_groups`:`pubkey_groups`}.${t.groupId}`}else n=Le(t);return{field:t.field,op:t.op,value:n}});return{id:Number(e.id)||t+1,name:e.name.trim()||`Rule ${t+1}`,enabled:!!e.enabled,if:{[e.matchMode]:n},then:{action:e.action}}}function Ye(){let e=F.value.map((e,t)=>Je(e,t));N.value=JSON.stringify(e,null,2)}function Xe(){let e=JSON.parse(N.value);if(!Array.isArray(e))throw Error(`Rules must be a JSON array`);return e}function Ze(){F.value=Xe().map((e,t)=>qe(e,t))}function Qe(){return P.value?Xe():F.value.map((e,t)=>Je(e,t))}function $e(e){if(e.valueSource===`group`)return`${Se(e.field)} ${Ce(e.op)} ${e.groupKind}:${e.groupId||`unset`}`;if(je(e.field)){let t=e.value.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean).length;return`${Se(e.field)} ${Ce(e.op)} ${t} hash${t===1?``:`es`}`}return`${Se(e.field)} ${Ce(e.op)} ${e.value}`}function et(e){let t=e.matchMode===`all`?` AND `:` OR `;return e.conditions.map(e=>$e(e)).join(t)}function tt(e){return e===`log_only`?`Log Only`:e.charAt(0).toUpperCase()+e.slice(1)}function nt(e){return e===`drop`?`border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-300`:e===`log_only`?`border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300`:`border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300`}function rt(){z.value=null,B.value=Ue(We()),ee.value=null,L.value=!0}function it(e){let t=F.value[e];t&&(z.value=e,B.value=JSON.parse(JSON.stringify(t)),ee.value=null,L.value=!0)}function at(){L.value=!1,B.value=null,z.value=null,ee.value=null,V.value=!1,H.value=null,U.value=null}function ot(){if(!B.value)return;let e=He(Ge(B.value));B.value.conditions.push(e)}function st(e){B.value&&(B.value.conditions.length<=1||B.value.conditions.splice(e,1))}function ct(e,t){if(!B.value)return;let n=e+t;if(n<0||n>=B.value.conditions.length)return;let r=B.value.conditions[e];B.value.conditions[e]=B.value.conditions[n],B.value.conditions[n]=r}function lt(e,t){H.value=e,U.value=e,t.dataTransfer&&(t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,String(e)))}function ut(e,t){if(H.value===null)return;t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect=`move`);let n=t.currentTarget;if(!n)return;let r=n.getBoundingClientRect();U.value=t.clientYt&&--n,n===t){H.value=null,U.value=null;return}let r=B.value.conditions.splice(t,1)[0];if(!r){H.value=null,U.value=null;return}B.value.conditions.splice(n,0,r),H.value=null,U.value=null}function ft(){H.value=null,U.value=null}function pt(e){Ke(e)}function mt(e){if(!e.conditions.some(e=>e.field===`channel_message_body`))return null;let t=e.conditions.findIndex(e=>e.field===`channel_message_body`);return t<=0?`For best results, move Channel Message Body lower in the list. Put Channel Decryptable == true or Channel Hash above it.`:e.conditions.slice(0,t).some(e=>e.field===`channel_decryptable`&&e.op===`equals`?e.value.trim().toLowerCase()===`true`:e.field===`channel_hash`)?null:`Change the order: put Channel Decryptable == true or Channel Hash before Channel Message Body.`}function ht(){if(B.value){ee.value=null;try{if(!B.value.name.trim())throw Error(`Rule name is required`);if(!B.value.conditions.length)throw Error(`At least one condition is required`);for(let e of B.value.conditions)if(Ke(e),e.valueSource===`group`){if(!e.groupKind||!e.groupId)throw Error(`Select a group for ${Se(e.field)}`)}else{if(!e.value.trim())throw Error(`Condition value is required for ${Se(e.field)}`);Le(e)}let e=JSON.parse(JSON.stringify(B.value));z.value===null?F.value.push(e):F.value.splice(z.value,1,e),Ye(),at()}catch(e){ee.value=e instanceof Error?e.message:`Failed to save rule`}}}function gt(e){F.value.splice(e,1),Ye()}function _t(e,t){let n=e+t;if(n<0||n>=F.value.length)return;let r=F.value[e];F.value[e]=F.value[n],F.value[n]=r,Ye()}function vt(e){let t={policy_engine:{enabled:!1,default_action:`allow`,rules:[],objects:{}},groups:{channel_hashes:[],pubkeys:[]}};if(!e||typeof e!=`object`)return t;let n=e,r=n.policy_engine??{},i=n.groups??{},a={channel_hashes:Array.isArray(i.channel_hashes)?i.channel_hashes:[],pubkeys:Array.isArray(i.pubkeys)?i.pubkeys:[]};return{policy_file:typeof n.policy_file==`string`?n.policy_file:void 0,exists:!!n.exists,policy_engine:{enabled:!!r.enabled,default_action:typeof r.default_action==`string`?r.default_action:`allow`,rules:Array.isArray(r.rules)?r.rules:[],objects:r.objects&&typeof r.objects==`object`?r.objects:{}},groups:a}}async function yt(){s.value=!0,m.value=null,f.value=null;try{let e=await R.getPolicyDocument();if(!e.success||!e.data)throw Error(e.error||`Failed to load policy document`);oe(vt(e.data)),se()}catch(e){m.value=ye(e,`Failed to load policy`)}finally{s.value=!1}}async function bt(){m.value=null,f.value=null,I.value=null;try{let e=Qe(),t=await R.validatePolicyDocument({policy_engine:{enabled:T.value.enabled,default_action:T.value.default_action,rules:e,objects:de()}});if(!t.success||!t.data)throw Error(t.error||`Validation failed`);if(t.data.valid){let n=t.data.effective;I.value=`Valid policy. Enabled=${n?.enabled?`yes`:`no`}, default=${n?.default_action||T.value.default_action}, rules=${n?.rule_count??e.length}`;return}throw Error(t.data.error||`Invalid policy payload`)}catch(e){m.value=ye(e,`Validation failed`)}}async function xt(){d.value=!0,m.value=null,f.value=null,I.value=null;try{let e=Qe(),t={policy_engine:{enabled:T.value.enabled,default_action:T.value.default_action,rules:e,objects:de()},groups:E.value},n=await R.updatePolicyDocument(t);if(!n.success)throw Error(n.error||`Failed to save policy`);let r=n.message||`Settings saved successfully`;return await yt(),u.value=!1,ce(r),!0}catch(e){return m.value=ye(e,`Failed to save policy`),!1}finally{d.value=!1}}function St(){m.value=null,f.value=null;let e=te.value.friendly_name.trim();if(!e){m.value=`Group friendly name is required`;return}let t=E.value[G.value],n=ae(Q(e,`${G.value}_group`),t.map(e=>e.id));t.push({id:n,friendly_name:e,description:te.value.description.trim()||void 0,entries:[]}),K.value=n,te.value={friendly_name:``,description:``},I.value=null}function Ct(e){m.value=null,f.value=null,E.value[G.value]=E.value[G.value].filter(t=>t.id!==e),I.value=null}function wt(){if(m.value=null,f.value=null,!xe.value){m.value=`Select a group first`;return}let e=q.value.friendly_name.trim(),t=q.value.value.trim();if(!e||!t){m.value=`Entry friendly name and value are required`;return}let n=ae(Q(e||t,`entry`),xe.value.entries.map(e=>e.id));xe.value.entries.push({id:n,friendly_name:e,value:t}),q.value={friendly_name:``,value:``},I.value=null}function Tt(e){if(m.value=null,f.value=null,!xe.value){m.value=`Select a group first`;return}xe.value.entries=xe.value.entries.filter(t=>t.id!==e),I.value=null}return e(yt),(e,n)=>(a(),C(x,null,[v(fe,{show:c(me),"is-saving":d.value,label:`Policy Engine settings`,onDiscard:c(ge),onSave:c(_e),onCancel:c(ve)},null,8,[`show`,`is-saving`,`onDiscard`,`onSave`,`onCancel`]),S(`div`,op,[S(`div`,sp,[n[22]||=S(`div`,null,[S(`h3`,{class:`text-base sm:text-lg font-semibold text-content-primary dark:text-content-primary mb-1 sm:mb-2`},` Policy Engine `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Policy and object management with chained rule conditions `)],-1),S(`div`,cp,[u.value?(a(),C(x,{key:1},[S(`button`,{class:`cfg-btn-secondary`,disabled:d.value,onClick:le},` Cancel `,8,up),S(`button`,{class:`cfg-btn-primary`,disabled:d.value,onClick:xt},l(d.value?`Saving…`:`Save Changes`),9,dp)],64)):(a(),C(`button`,{key:0,class:`cfg-btn-primary`,disabled:s.value,onClick:$},` Edit Settings `,8,lp))])]),m.value?(a(),C(`div`,fp,l(m.value),1)):_(``,!0),f.value?(a(),C(`div`,pp,l(f.value),1)):_(``,!0),I.value?(a(),C(`div`,mp,l(I.value),1)):_(``,!0),s.value?(a(),C(`div`,hp,[v(W),n[23]||=S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading policy…`,-1)])):(a(),C(x,{key:4},[S(`div`,gp,[S(`div`,_p,[S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,w.value===`policy`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary`]),onClick:n[0]||=e=>w.value=`policy`},` Policy `,2),S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,w.value===`objects`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary`]),onClick:n[1]||=e=>w.value=`objects`},` Objects `,2)])]),w.value===`policy`?(a(),C(`div`,vp,[S(`div`,yp,[S(`div`,bp,[S(`div`,xp,[n[25]||=S(`div`,null,[S(`label`,{class:`cfg-label`},`Policy Engine Enabled`),S(`p`,{class:`mt-1 text-xs text-content-muted dark:text-content-muted`},`Enable policy enforcement for incoming packets.`)],-1),S(`label`,Sp,[i(S(`input`,{"onUpdate:modelValue":n[2]||=e=>T.value.enabled=e,type:`checkbox`,disabled:!u.value||d.value,class:`h-4 w-4 rounded border-stroke-subtle dark:border-stroke/30 accent-primary`},null,8,Cp),[[M,T.value.enabled]]),n[24]||=S(`span`,null,`Enable policy enforcement`,-1)])]),S(`div`,wp,[n[26]||=S(`div`,null,[S(`label`,{class:`cfg-label`},`Default Action`),S(`p`,{class:`mt-1 text-xs text-content-muted dark:text-content-muted`},`Applied when no policy rule matches.`)],-1),i(S(`select`,{"onUpdate:modelValue":n[3]||=e=>T.value.default_action=e,class:`cfg-select w-full md:max-w-sm`,disabled:!u.value||d.value},[(a(),C(x,null,t(ne,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,Ep)),64))],8,Tp),[[D,T.value.default_action]])])]),S(`div`,Dp,[S(`div`,Op,[n[27]||=S(`label`,{class:`cfg-label`},`Policy Rules`,-1),S(`div`,kp,[S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:!u.value||d.value,onClick:rt},`Add Rule`,8,Ap),S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:d.value,onClick:n[4]||=e=>P.value=!P.value},l(P.value?`Hide JSON`:`Advanced JSON`),9,jp)])]),S(`div`,Mp,[S(`table`,Np,[n[29]||=S(`thead`,{class:`bg-background-mute/80 dark:bg-white/5 backdrop-blur`},[S(`tr`,null,[S(`th`,{class:`w-16 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Order`),S(`th`,{class:`w-14 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`On`),S(`th`,{class:`w-44 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Name`),S(`th`,{class:`px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Logic`),S(`th`,{class:`w-28 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Action`),S(`th`,{class:`w-48 px-3 py-2 text-right text-[11px] font-semibold uppercase tracking-[0.18em] text-content-muted dark:text-content-muted`},`Controls`)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(F.value,(e,t)=>(a(),C(`tr`,{key:`${e.id}-${t}`,class:`border-t border-stroke-subtle/70 dark:border-stroke/15 odd:bg-background-mute/20 dark:odd:bg-white/[0.02] hover:bg-primary/5 dark:hover:bg-white/[0.04] transition-colors`},[S(`td`,Pp,l(t+1),1),S(`td`,Fp,[S(`span`,{class:p([`inline-flex h-5 w-5 items-center justify-center rounded-md border text-[10px] font-semibold`,e.enabled?`border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-300`:`border-stroke-subtle/70 bg-background-mute text-content-muted dark:border-stroke/20 dark:bg-white/5 dark:text-content-muted`]),title:e.enabled?`Enabled`:`Disabled`},l(e.enabled?`✓`:`—`),11,Ip)]),S(`td`,Lp,[S(`span`,{class:`block truncate font-medium`,title:e.name},l(e.name),9,Rp)]),S(`td`,zp,[S(`span`,{class:`block truncate font-mono leading-5`,title:et(e)},l(et(e)),9,Bp)]),S(`td`,Vp,[S(`span`,{class:p([`inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-semibold uppercase tracking-wide`,nt(e.action)]),title:e.action},l(tt(e.action)),11,Hp)]),S(`td`,Up,[S(`div`,Wp,[S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>_t(t,-1)},`▲`,8,Gp),S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>_t(t,1)},`▼`,8,Kp),S(`button`,{class:`cfg-btn-secondary text-xs px-2 py-1`,disabled:!u.value||d.value,onClick:e=>it(t)},`Edit`,8,qp),S(`button`,{class:`text-xs px-2 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10 disabled:opacity-40`,disabled:!u.value||d.value,onClick:e=>gt(t)},`Del`,8,Jp)])])]))),128)),F.value.length?_(``,!0):(a(),C(`tr`,Yp,[...n[28]||=[S(`td`,{colspan:`6`,class:`px-3 py-8 text-center text-xs text-content-muted dark:text-content-muted`},`No rules yet. Add your first rule.`,-1)]]))])])]),n[31]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Rules are evaluated top to bottom. First matching rule wins. `,-1),P.value?(a(),C(`div`,Xp,[n[30]||=S(`label`,{class:`cfg-label`},`Advanced JSON Editor`,-1),i(S(`textarea`,{"onUpdate:modelValue":n[5]||=e=>N.value=e,rows:`12`,spellcheck:`false`,disabled:!u.value||d.value,class:`cfg-textarea font-mono text-xs`,placeholder:`[{"id":1,"if":{"all":[{"field":"hop_count","op":"greater_than","value":4}]},"then":{"action":"drop"}}]`},null,8,Zp),[[j,N.value]]),S(`div`,Qp,[S(`button`,{class:`cfg-btn-secondary text-xs`,disabled:!u.value||d.value,onClick:Ze},`Apply JSON To Table`,8,$p)])])):_(``,!0)]),S(`div`,em,[S(`button`,{class:`cfg-btn-secondary`,disabled:d.value||!u.value,onClick:bt},`Validate`,8,tm)])])])):(a(),C(`div`,nm,[S(`div`,rm,[S(`div`,im,[S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,G.value===`channel_hashes`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted`]),onClick:n[6]||=e=>G.value=`channel_hashes`},` Channel Hash Groups `,2),S(`button`,{class:p([`px-3 py-1.5 text-xs sm:text-sm rounded-md border transition-colors`,G.value===`pubkeys`?`border-primary/60 text-primary bg-primary/10`:`border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted`]),onClick:n[7]||=e=>G.value=`pubkeys`},` Pubkey Groups `,2)])]),S(`div`,am,[S(`div`,om,[S(`div`,sm,[n[32]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Groups`,-1),S(`span`,cm,l(be.value.length)+` total`,1)]),S(`div`,lm,[(a(!0),C(x,null,t(be.value,e=>(a(),C(`button`,{key:e.id,class:p([`w-full text-left rounded-lg border p-3 transition-colors`,K.value===e.id?`border-primary/60 bg-primary/10`:`border-stroke-subtle dark:border-stroke/20 bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10`]),onClick:t=>K.value=e.id},[S(`div`,dm,[S(`div`,null,[S(`p`,fm,l(e.friendly_name),1),S(`p`,pm,l(e.id),1)]),S(`span`,mm,l(e.entries.length),1)])],10,um))),128)),be.value.length?_(``,!0):(a(),C(`div`,hm,` No groups yet `))]),S(`div`,gm,[n[33]||=S(`h5`,{class:`text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Create Group`,-1),i(S(`input`,{"onUpdate:modelValue":n[8]||=e=>te.value.friendly_name=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Friendly name`},null,8,_m),[[j,te.value.friendly_name]]),i(S(`input`,{"onUpdate:modelValue":n[9]||=e=>te.value.description=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Description (optional)`},null,8,vm),[[j,te.value.description]]),S(`button`,{class:`cfg-btn-primary w-full`,disabled:!u.value||d.value,onClick:St},`Add Group`,8,ym)])]),S(`div`,bm,[S(`div`,xm,[S(`h4`,Sm,l(xe.value?xe.value.friendly_name:`Entries`),1),xe.value?(a(),C(`button`,{key:0,class:`text-xs px-2.5 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,disabled:!u.value||d.value,onClick:n[10]||=e=>Ct(xe.value.id)},` Delete Group `,8,Cm)):_(``,!0)]),xe.value?(a(),C(`div`,wm,[S(`table`,Tm,[n[35]||=S(`thead`,{class:`bg-background-mute dark:bg-white/5`},[S(`tr`,null,[S(`th`,{class:`text-left px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Name`),S(`th`,{class:`text-left px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value`),S(`th`,{class:`text-right px-3 py-2 text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Actions`)])],-1),S(`tbody`,null,[(a(!0),C(x,null,t(xe.value.entries,e=>(a(),C(`tr`,{key:e.id,class:`border-t border-stroke-subtle dark:border-stroke/15`},[S(`td`,Em,l(e.friendly_name),1),S(`td`,Dm,l(e.value),1),S(`td`,Om,[S(`button`,{class:`text-xs px-2.5 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,disabled:!u.value||d.value,onClick:t=>Tt(e.id)},` Remove `,8,km)])]))),128)),xe.value.entries.length?_(``,!0):(a(),C(`tr`,Am,[...n[34]||=[S(`td`,{colspan:`3`,class:`px-3 py-8 text-center text-xs text-content-muted dark:text-content-muted`},`No entries in this group`,-1)]]))])])])):(a(),C(`div`,jm,` Select a group to manage entries `)),xe.value?(a(),C(`div`,Mm,[n[36]||=S(`h5`,{class:`text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Add Entry`,-1),S(`div`,Nm,[i(S(`input`,{"onUpdate:modelValue":n[11]||=e=>q.value.friendly_name=e,class:`cfg-input`,disabled:!u.value||d.value,placeholder:`Friendly name`},null,8,Pm),[[j,q.value.friendly_name]]),i(S(`input`,{"onUpdate:modelValue":n[12]||=e=>q.value.value=e,class:`cfg-input font-mono`,disabled:!u.value||d.value,placeholder:G.value===`channel_hashes`?`0x...`:`0xaabbccdd`},null,8,Fm),[[j,q.value.value]])]),S(`button`,{class:`cfg-btn-primary`,disabled:!u.value||d.value,onClick:wt},`Add Entry`,8,Im)])):_(``,!0)])])]))],64)),L.value&&B.value?(a(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:A(at,[`self`])},[S(`div`,Lm,[S(`div`,Rm,[S(`div`,null,[S(`h3`,zm,l(z.value===null?`Add Policy Rule`:`Edit Policy Rule`),1),S(`p`,Bm,` Choose match logic, then add one or more conditions. `+l(B.value.matchMode===`all`?`ALL`:`ANY`)+` conditions must match. `,1)]),S(`div`,Vm,[S(`button`,{class:p([`w-7 h-7 rounded-full border border-stroke-subtle dark:border-stroke/30 text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary hover:bg-background-mute dark:hover:bg-white/10 text-sm font-semibold`,V.value?`bg-primary/10 text-primary border-primary/50`:``]),title:`Match Field Logic Matrix`,onClick:n[13]||=e=>V.value=!V.value},` i `,2),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:at},`Close`)])]),V.value?(a(),C(`div`,Hm,[S(`div`,Um,[n[37]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Match Field Logic Matrix`,-1),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:n[14]||=e=>V.value=!1},`Hide`)]),S(`div`,Wm,[S(`table`,Gm,[n[38]||=S(`thead`,{class:`bg-background-mute dark:bg-white/5`},[S(`tr`,null,[S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Field`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value Types`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Operators`),S(`th`,{class:`px-2 py-2 text-left font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Group Sources`)])],-1),S(`tbody`,null,[(a(),C(x,null,t(ie,e=>S(`tr`,{key:e.value,class:`border-t border-stroke-subtle dark:border-stroke/15`},[S(`td`,Km,l(e.label),1),S(`td`,qm,l(e.valueTypes.join(`, `)),1),S(`td`,Jm,l(e.operators.map(Ce).join(`, `)),1),S(`td`,Ym,l(e.groupKinds?.join(`, `)||`None`),1)])),64))])])])])):_(``,!0),ee.value?(a(),C(`div`,Xm,l(ee.value),1)):_(``,!0),S(`div`,Zm,[S(`div`,Qm,[n[39]||=S(`label`,{class:`cfg-label`},`Rule Name`,-1),i(S(`input`,{"onUpdate:modelValue":n[15]||=e=>B.value.name=e,class:`cfg-input mt-1`,placeholder:`Block noisy channel route`},null,512),[[j,B.value.name]])]),S(`div`,null,[n[41]||=S(`label`,{class:`cfg-label`},`Match Logic`,-1),i(S(`select`,{"onUpdate:modelValue":n[16]||=e=>B.value.matchMode=e,class:`cfg-select mt-1`},[...n[40]||=[S(`option`,{value:`all`},`ALL conditions (AND)`,-1),S(`option`,{value:`any`},`ANY condition (OR)`,-1)]],512),[[D,B.value.matchMode]])]),S(`div`,null,[n[42]||=S(`label`,{class:`cfg-label`},`Action`,-1),i(S(`select`,{"onUpdate:modelValue":n[17]||=e=>B.value.action=e,class:`cfg-select mt-1`},[(a(),C(x,null,t(ne,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,$m)),64))],512),[[D,B.value.action]])])]),S(`label`,eh,[i(S(`input`,{"onUpdate:modelValue":n[18]||=e=>B.value.enabled=e,type:`checkbox`},null,512),[[M,B.value.enabled]]),n[43]||=b(` Rule enabled `,-1)]),S(`div`,th,[S(`div`,{class:`flex items-center justify-between`},[n[44]||=S(`h4`,{class:`text-sm font-semibold text-content-primary dark:text-content-primary`},`Conditions`,-1),S(`button`,{class:`cfg-btn-secondary text-xs`,onClick:ot},`Add Condition`)]),mt(B.value)?(a(),C(`div`,nh,l(mt(B.value)),1)):_(``,!0),S(`div`,rh,[S(`table`,ih,[S(`thead`,ah,[S(`tr`,null,[n[45]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Drag`,-1),n[46]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Field`,-1),n[47]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Operator`,-1),Y.value?(a(),C(`th`,oh,`Source`)):_(``,!0),n[48]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Value`,-1),n[49]||=S(`th`,{class:`px-2 py-2 text-left text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Type`,-1),n[50]||=S(`th`,{class:`px-2 py-2 text-right text-xs font-semibold uppercase tracking-wide text-content-muted dark:text-content-muted`},`Action`,-1)])]),S(`tbody`,null,[(a(!0),C(x,null,t(B.value.conditions,(e,r)=>(a(),C(`tr`,{key:e.id,class:p([`border-t border-stroke-subtle dark:border-stroke/15 transition-colors`,{"opacity-60":H.value===r,"!border-t-2 !border-primary":U.value===r&&H.value!==null}]),onDragover:e=>ut(r,e),onDrop:n[19]||=e=>dt(e)},[S(`td`,ch,[S(`button`,{type:`button`,draggable:`true`,class:`h-8 w-8 inline-flex items-center justify-center rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 cursor-grab active:cursor-grabbing`,title:`Drag to reorder`,onDragstart:e=>lt(r,e),onDragend:ft},` ☰ `,40,lh)]),S(`td`,uh,[i(S(`select`,{"onUpdate:modelValue":t=>e.field=t,class:`cfg-select h-8 text-xs`,onChange:t=>pt(e)},[(a(),C(x,null,t(ie,e=>S(`option`,{key:e.value,value:e.value},l(e.label),9,fh)),64))],40,dh),[[D,e.field]])]),S(`td`,ph,[i(S(`select`,{"onUpdate:modelValue":t=>e.op=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(we(e.field),e=>(a(),C(`option`,{key:e,value:e},l(Ce(e)),9,hh))),128))],8,mh),[[D,e.op]])]),Y.value?(a(),C(`td`,gh,[i(S(`select`,{"onUpdate:modelValue":t=>e.valueSource=t,class:`cfg-select h-8 text-xs`,disabled:!Oe(e.field)},[n[51]||=S(`option`,{value:`literal`},`Literal`,-1),Oe(e.field)?(a(),C(`option`,vh,`Group`)):_(``,!0)],8,_h),[[D,e.valueSource]])])):_(``,!0),S(`td`,yh,[Y.value&&e.valueSource===`group`&&Oe(e.field)?(a(),C(`div`,bh,[i(S(`select`,{"onUpdate:modelValue":t=>e.groupKind=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(Ee(e.field),e=>(a(),C(`option`,{key:e,value:e},l(e),9,Sh))),128))],8,xh),[[D,e.groupKind]]),i(S(`select`,{"onUpdate:modelValue":t=>e.groupId=t,class:`cfg-select h-8 text-xs`},[(a(!0),C(x,null,t(De(e.groupKind),e=>(a(),C(`option`,{key:e.id,value:e.id},l(e.friendly_name),9,wh))),128))],8,Ch),[[D,e.groupId]])])):(a(),C(`div`,Th,[ke(e).length?(a(),C(`select`,{key:0,class:`cfg-select h-8 text-xs`,onChange:t=>Ae(e,String(t.target.value))},[n[52]||=S(`option`,{value:``},`Lookup value...`,-1),(a(!0),C(x,null,t(ke(e),t=>(a(),C(`option`,{key:`${e.id}-${t.value}`,value:t.value},l(t.label),9,Dh))),128))],40,Eh)):_(``,!0),ze(e)?i((a(),C(`textarea`,{key:1,"onUpdate:modelValue":t=>e.value=t,class:`cfg-input min-h-[72px] text-xs font-mono py-2`,placeholder:Re(e)},null,8,Oh)),[[j,e.value]]):i((a(),C(`input`,{key:2,"onUpdate:modelValue":t=>e.value=t,class:`cfg-input h-8 text-xs font-mono`,placeholder:Re(e)},null,8,kh)),[[j,e.value]]),je(e.field)?(a(),C(`p`,Ah," Use hex only. All hashes in one condition must be the same width: 1 byte (`0x42`), 2 bytes (`0x0042`), or 3 bytes (`0x000042`). ")):_(``,!0)]))]),S(`td`,jh,[i(S(`select`,{"onUpdate:modelValue":t=>e.valueType=t,class:`cfg-select h-8 text-xs`,disabled:Y.value&&e.valueSource===`group`},[(a(!0),C(x,null,t(Te(e.field),e=>(a(),C(`option`,{key:e,value:e},l(e),9,Nh))),128))],8,Mh),[[D,e.valueType]])]),S(`td`,Ph,[S(`div`,Fh,[S(`button`,{class:`text-xs px-2 py-1 rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 disabled:opacity-40`,disabled:r===0,title:`Move condition up`,"aria-label":`Move condition up`,onClick:e=>ct(r,-1)},` ▲ `,8,Ih),S(`button`,{class:`text-xs px-2 py-1 rounded border border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:bg-background-mute dark:hover:bg-white/10 disabled:opacity-40`,disabled:r===B.value.conditions.length-1,title:`Move condition down`,"aria-label":`Move condition down`,onClick:e=>ct(r,1)},` ▼ `,8,Lh),S(`button`,{class:`text-xs px-2 py-1 rounded border border-red-500/50 text-red-600 dark:text-red-400 hover:bg-red-500/10`,onClick:e=>st(r)},`Del`,8,Rh)])])],42,sh))),128)),H.value!==null&&U.value===B.value.conditions.length?(a(),C(`tr`,{key:0,class:`border-t-2 border-primary`,onDragover:n[20]||=A(()=>{},[`prevent`]),onDrop:n[21]||=e=>dt(e)},[S(`td`,{colspan:X.value,class:`px-2 py-0`},[...n[53]||=[S(`div`,{class:`h-0`},null,-1)]],8,zh)],32)):_(``,!0)])])])]),S(`div`,{class:`flex justify-end gap-2`},[S(`button`,{class:`cfg-btn-secondary`,onClick:at},`Cancel`),S(`button`,{class:`cfg-btn-primary`,onClick:ht},`Save Rule`)])])])):_(``,!0)])],64))}}),Vh={class:`p-3 sm:p-6 space-y-4 sm:space-y-6`},Hh={class:`flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3`},Uh={class:`glass-card rounded-[15px] p-3 sm:p-6 mt-4 sm:mt-6`},Wh={key:0,class:`flex items-center justify-center py-12`},Gh={class:`text-center`},Kh={key:1,class:`flex items-center justify-center py-12`},qh={class:`text-center`},Jh={class:`text-content-secondary dark:text-content-muted text-sm mb-4`},Yh={key:2,class:`min-h-[400px]`},Xh=`radio`,Zh=f({name:`ConfigurationView`,__name:`Configuration`,setup(t){let n=F(),i=ee(),s=V(),d=o(q(`configuration_activeTab`,Xh)),f=o(!1),p=o(null),m=o(null),y=o(null),b=o(null),x=o(null),w=o(null),T=o(null),E=o(null),D={radio:p,"radio-hardware":m,repeater:y,advert:b,duty:x,delays:w,transport:T,observer:E};function O(){let e=D[d.value]?.value;if(!e)return!1;let t=e.isEditing;return typeof t==`boolean`?t:t.value}function k(e){let t=D[d.value]?.value;t?t.requestLeave(e):e()}let A=new Set([`radio`,`radio-hardware`,`repeater`,`duty`,`delays`,`advert`,`transport`,`api-tokens`,`web`,`observer`,`policy-engine`,`backup`,`database`,`memory`]);function j(e){return e&&A.has(e)?e:q(`configuration_activeTab`,Xh)}return d.value=j(n.query.tab),h(d,e=>G(`configuration_activeTab`,e)),I((e,t,n)=>{let r=j(e.query.tab);if(r===d.value){n();return}if(O()){k(()=>{d.value=r,n()});return}d.value=r,n()}),e(async()=>{if(i.stats)f.value=!0;else try{await s.ensure(`stats`)}catch(e){console.error(`Failed to load configuration data:`,e)}finally{f.value=!0}}),(e,t)=>{let n=g(`router-link`);return a(),C(`div`,Vh,[S(`div`,Hh,[t[2]||=S(`div`,null,[S(`h1`,{class:`text-xl sm:text-2xl font-bold text-content-primary dark:text-content-primary`},` Configuration `),S(`p`,{class:`text-content-secondary dark:text-content-muted mt-1 sm:mt-2 text-sm sm:text-base`},` System configuration and settings `)],-1),f.value&&!(c(i).stats?.config?.radio)?.cad?.peak_threshold?(a(),u(n,{key:0,to:`/cad-calibration`,class:`flex-shrink-0 flex items-center gap-4 px-5 py-3 min-w-[280px] rounded-xl border border-primary/30 bg-primary/10 text-primary hover:bg-primary/20 transition-colors`},{default:r(()=>[...t[1]||=[S(`svg`,{class:`w-5 h-5 flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M13 10V3L4 14h7v7l9-11h-7z`})],-1),S(`div`,null,[S(`div`,{class:`text-sm font-semibold`},`CAD Calibration Available`),S(`div`,{class:`text-xs text-primary/70`},`Optimise CAD settings →`)],-1)]]),_:1})):_(``,!0)]),S(`div`,Uh,[!f.value&&c(i).isLoading?(a(),C(`div`,Wh,[S(`div`,Gh,[v(W,{class:`mx-auto mb-4`}),t[3]||=S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading configuration...`,-1)])])):f.value&&!c(i).stats?(a(),C(`div`,Kh,[S(`div`,qh,[t[4]||=S(`div`,{class:`text-accent-red mb-2`},`Failed to load configuration`,-1),S(`div`,Jh,l(c(i).error),1),S(`button`,{onClick:t[0]||=e=>c(i).fetchStats(),class:`btn-primary`},`Retry`)])])):(a(),C(`div`,Yh,[d.value===`radio`?(a(),u(ct,{ref_key:`radioRef`,ref:p,key:`radio-settings`},null,512)):_(``,!0),d.value===`radio-hardware`?(a(),u(Vn,{ref_key:`radioHardwareRef`,ref:m,key:`radio-hardware-settings`},null,512)):_(``,!0),d.value===`repeater`?(a(),u(Vr,{ref_key:`repeaterRef`,ref:y,key:`repeater-settings`},null,512)):_(``,!0),d.value===`advert`?(a(),u(Ic,{ref_key:`advertRef`,ref:b,key:`advert-settings`},null,512)):_(``,!0),d.value===`duty`?(a(),u(ti,{ref_key:`dutyRef`,ref:x,key:`duty-cycle`},null,512)):_(``,!0),d.value===`delays`?(a(),u(mi,{ref_key:`delaysRef`,ref:w,key:`transmission-delays`},null,512)):_(``,!0),d.value===`transport`?(a(),u(yo,{ref_key:`transportRef`,ref:T,key:`transport-keys`},null,512)):_(``,!0),d.value===`api-tokens`?(a(),u(Xo,{key:`api-tokens`})):_(``,!0),d.value===`web`?(a(),u(ws,{key:`web-settings`})):_(``,!0),d.value===`observer`?(a(),u(au,{ref_key:`letsMeshRef`,ref:E,key:`letsmesh-settings`},null,512)):_(``,!0),d.value===`policy-engine`?(a(),u(Bh,{key:`policy-engine`})):_(``,!0),d.value===`backup`?(a(),u(dd,{key:`backup-restore`})):_(``,!0),d.value===`database`?(a(),u(pf,{key:`database-management`})):_(``,!0),d.value===`memory`?(a(),u(ap,{key:`memory-debug`})):_(``,!0)]))])])}}});export{Zh as default};