mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-07-05 17:32:33 +02:00
2 lines
204 KiB
JavaScript
2 lines
204 KiB
JavaScript
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/leaflet-src-BtX0-WJ4.js","assets/chunk-DECur_0Z.js"])))=>i.map(i=>d[i]);
|
||
import{r as e}from"./chunk-DECur_0Z.js";import{A as t,C as n,D as r,E as i,R as a,S as o,W as s,b as c,c as l,dt as u,f as d,g as f,i as p,j as m,k as h,l as g,lt as _,m as v,o as y,p as b,r as x,s as S,u as C,w,x as T,z as E}from"./runtime-core.esm-bundler-IofF4kUm.js";import{n as D}from"./pinia-BrpcNUEi.js";import{i as O,n as k,t as A}from"./api-CiSov_eM.js";import{t as j}from"./system-Bocs8bSU.js";import{t as M}from"./_plugin-vue_export-helper-V-yks4gF.js";import{d as N,f as P,l as F,m as I,p as L,s as R,u as z}from"./index-BPH8UrxU.js";import{t as B}from"./ConfirmDialog-BafURQpE.js";/* empty css */import{n as V,t as H}from"./preferences-N3Pls1rF.js";var U={class:`space-y-4`},W={key:0,class:`bg-green-100 dark:bg-green-500/20 border border-green-500/50 rounded-lg p-3`},G={class:`text-green-600 dark:text-green-400 text-sm`},ee={key:1,class:`bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg p-3`},te={class:`text-red-600 dark:text-red-400 text-sm`},ne={class:`flex justify-end gap-2`},re=[`disabled`],K=[`disabled`],q={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},J={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`},Y={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},X={key:1,class:`flex items-center gap-2`},Z={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`},Q={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},$={key:1},ie=[`value`],ae={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`},oe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},se={key:1},ce=[`value`],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`},ue={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},de={key:1,class:`flex items-center gap-2`},fe={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`},pe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},me={key:1},he={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},ge={class:`text-content-primary dark:text-content-primary font-mono text-sm`},_e={key:2,class:`bg-yellow-500/10 dark:bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-3`},ve=f({__name:`RadioSettings`,setup(e){let t=j(),n=y(()=>t.stats?.config?.radio||{}),r=E(!1),a=E(!1),o=E(null),s=E(null),c=E(0),l=E(0),d=E(0),f=E(0),p=E(0),_=E(0),v=[{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(n,e=>{e&&!r.value&&(c.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,l.value=e.spreading_factor??0,d.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,f.value=e.tx_power??0,p.value=e.coding_rate??0,_.value=e.preamble_length??0)},{immediate:!0});let T=y(()=>{let e=n.value.frequency;return e?(e/1e6).toFixed(3)+` MHz`:`Not set`}),D=y(()=>{let e=n.value.bandwidth;return e?(e/1e3).toFixed(1)+` kHz`:`Not set`}),O=y(()=>{let e=n.value.tx_power;return e===void 0?`Not set`:e+` dBm`}),k=y(()=>{let e=n.value.coding_rate;return e?`4/`+e:`Not set`}),M=y(()=>{let e=n.value.preamble_length;return e?e+` symbols`:`Not set`}),P=y(()=>n.value.spreading_factor??`Not set`),F=()=>{r.value=!0,o.value=null,s.value=null},I=()=>{r.value=!1,o.value=null;let e=n.value;c.value=e.frequency?Number((e.frequency/1e6).toFixed(3)):0,l.value=e.spreading_factor??0,d.value=e.bandwidth?Number((e.bandwidth/1e3).toFixed(1)):0,f.value=e.tx_power??0,p.value=e.coding_rate??0,_.value=e.preamble_length??0},L=async()=>{a.value=!0,o.value=null,s.value=null;try{let e={};c.value&&(e.frequency=c.value*1e6),l.value&&(e.spreading_factor=l.value),d.value&&(e.bandwidth=d.value*1e3),f.value&&(e.tx_power=f.value),p.value&&(e.coding_rate=p.value);let n=(await A.post(`/update_radio_config`,e)).data;n.message||n.persisted?(s.value=n.message||`Settings saved successfully`,r.value=!1,await t.fetchStats(),setTimeout(()=>{s.value=null},3e3)):n.error?o.value=n.error:o.value=`Unknown response from server`}catch(e){console.error(`Failed to update radio settings:`,e),o.value=e.response?.data?.error||`Failed to update settings`}finally{a.value=!1}};return(e,t)=>(w(),C(`div`,U,[s.value?(w(),C(`div`,W,[S(`p`,G,u(s.value),1)])):g(``,!0),o.value?(w(),C(`div`,ee,[S(`p`,te,u(o.value),1)])):g(``,!0),S(`div`,ne,[r.value?(w(),C(x,{key:1},[S(`button`,{onClick:I,disabled:a.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,re),S(`button`,{onClick:L,disabled:a.value,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},u(a.value?`Saving...`:`Save Changes`),9,K)],64)):(w(),C(`button`,{key:0,onClick:F,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Edit Settings `))]),S(`div`,q,[S(`div`,J,[t[6]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Frequency`,-1),r.value?(w(),C(`div`,X,[m(S(`input`,{"onUpdate:modelValue":t[0]||=e=>c.value=e,type:`number`,step:`0.001`,min:`100`,max:`1000`,class:`w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,c.value,void 0,{number:!0}]]),t[5]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`MHz`,-1)])):(w(),C(`div`,Y,u(T.value),1))]),S(`div`,Z,[t[7]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Spreading Factor`,-1),r.value?(w(),C(`div`,$,[m(S(`select`,{"onUpdate:modelValue":t[1]||=e=>l.value=e,class:`px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[(w(),C(x,null,i([5,6,7,8,9,10,11,12],e=>S(`option`,{key:e,value:e},u(e),9,ie)),64))],512),[[z,l.value,void 0,{number:!0}]])])):(w(),C(`div`,Q,u(P.value),1))]),S(`div`,ae,[t[8]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Bandwidth`,-1),r.value?(w(),C(`div`,se,[m(S(`select`,{"onUpdate:modelValue":t[2]||=e=>d.value=e,class:`px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[(w(),C(x,null,i(v,e=>S(`option`,{key:e.value,value:e.value},u(e.label),9,ce)),64))],512),[[z,d.value,void 0,{number:!0}]])])):(w(),C(`div`,oe,u(D.value),1))]),S(`div`,le,[t[10]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`TX Power`,-1),r.value?(w(),C(`div`,de,[m(S(`input`,{"onUpdate:modelValue":t[3]||=e=>f.value=e,type:`number`,min:`2`,max:`30`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,f.value,void 0,{number:!0}]]),t[9]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`dBm`,-1)])):(w(),C(`div`,ue,u(O.value),1))]),S(`div`,fe,[t[12]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Coding Rate`,-1),r.value?(w(),C(`div`,me,[m(S(`select`,{"onUpdate:modelValue":t[4]||=e=>p.value=e,class:`px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[11]||=[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),[[z,p.value,void 0,{number:!0}]])])):(w(),C(`div`,pe,u(k.value),1))]),S(`div`,he,[t[13]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Preamble Length`,-1),S(`span`,ge,u(M.value),1)])]),r.value?(w(),C(`div`,_e,[...t[14]||=[S(`p`,{class:`text-yellow-700 dark:text-yellow-400 text-xs`},[S(`strong`,null,`Note:`),b(` Radio hardware changes (frequency, bandwidth, spreading factor, coding rate) may require a service restart to apply. `)],-1)]])):g(``,!0)]))}}),ye={class:`glass-card border border-stroke-subtle dark:border-white/20 rounded-[15px] w-full max-w-3xl max-h-[90vh] flex flex-col shadow-2xl`},be={class:`flex-1 relative min-h-[400px]`},xe={class:`p-6 border-t border-stroke-subtle dark:border-stroke/10 space-y-4`},Se={class:`grid grid-cols-2 gap-4`},Ce=M(f({__name:`LocationPicker`,props:{isOpen:{type:Boolean},latitude:{},longitude:{}},emits:[`close`,`select`],setup(t,{emit:r}){let i=t,a=r,o=E(null),s=E(i.latitude||0),l=E(i.longitude||0),u=null,d=null,f=async()=>{if(o.value){p();try{let t=(await O(async()=>{let{default:t}=await import(`./leaflet-src-BtX0-WJ4.js`).then(t=>e(t.t(),1));return{default:t}},__vite__mapDeps([0,1]))).default;delete t.Icon.Default.prototype._getIconUrl,t.Icon.Default.mergeOptions({iconRetinaUrl:`https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png`,iconUrl:`https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png`,shadowUrl:`https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png`}),await c();let n=s.value||0,r=l.value||0,i=n===0&&r===0?2:13;u=t.map(o.value).setView([n,r],i);try{let e=t.tileLayer(`https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png`,{maxZoom:19,attribution:`© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>`,errorTileUrl:`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==`}),n=t.tileLayer(`https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png`,{maxZoom:19,attribution:``,errorTileUrl:`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==`});e.addTo(u),n.addTo(u)}catch(e){console.warn(`Error loading tiles:`,e)}(n!==0||r!==0)&&(d=t.marker([n,r]).addTo(u)),u.on(`click`,e=>{s.value=e.latlng.lat,l.value=e.latlng.lng,d?d.setLatLng(e.latlng):d=t.marker(e.latlng).addTo(u)}),setTimeout(()=>{u?.invalidateSize()},200)}catch(e){console.error(`Failed to initialize map:`,e)}}},p=()=>{u&&(u.remove(),u=null,d=null)};h(()=>i.isOpen,async e=>{e?(await c(),await f()):p()}),h(()=>[i.latitude,i.longitude],([e,t])=>{s.value=e,l.value=t});let _=()=>{a(`select`,{latitude:s.value,longitude:l.value}),a(`close`)},v=()=>{a(`close`)},y=()=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(async t=>{if(s.value=t.coords.latitude,l.value=t.coords.longitude,u){u.setView([s.value,l.value],13);let t=(await O(async()=>{let{default:t}=await import(`./leaflet-src-BtX0-WJ4.js`).then(t=>e(t.t(),1));return{default:t}},__vite__mapDeps([0,1]))).default;d?d.setLatLng([s.value,l.value]):d=t.marker([s.value,l.value]).addTo(u)}},e=>{console.error(`Error getting location:`,e),alert(`Unable to get current location. Please check browser permissions.`)}):alert(`Geolocation is not supported by this browser.`)};return n(()=>{p()}),(e,n)=>t.isOpen?(w(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:I(v,[`self`])},[S(`div`,ye,[S(`div`,{class:`flex items-center justify-between p-6 border-b border-stroke-subtle dark:border-stroke/10`},[n[3]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Select Location `,-1),S(`button`,{onClick:v,class:`text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...n[2]||=[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)]])]),S(`div`,be,[S(`div`,{ref_key:`mapContainer`,ref:o,class:`absolute inset-0 rounded-b-[15px] overflow-hidden`},null,512)]),S(`div`,xe,[S(`div`,Se,[S(`div`,null,[n[4]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Latitude`,-1),m(S(`input`,{"onUpdate:modelValue":n[0]||=e=>s.value=e,type:`number`,step:`0.000001`,class:`w-full px-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary focus:outline-none focus:border-primary`,readonly:``},null,512),[[N,s.value,void 0,{number:!0}]])]),S(`div`,null,[n[5]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Longitude`,-1),m(S(`input`,{"onUpdate:modelValue":n[1]||=e=>l.value=e,type:`number`,step:`0.000001`,class:`w-full px-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary focus:outline-none focus:border-primary`,readonly:``},null,512),[[N,l.value,void 0,{number:!0}]])])]),S(`div`,{class:`flex gap-3`},[S(`button`,{onClick:y,class:`flex-1 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 flex items-center justify-center gap-2`},[...n[6]||=[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(` Use Current Location `,-1)]]),S(`button`,{onClick:v,class:`px-6 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`},` Cancel `),S(`button`,{onClick:_,class:`px-6 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Select Location `)]),n[7]||=S(`p`,{class:`text-content-muted dark:text-content-muted text-xs text-center`},` Click on the map to select a location `,-1)])])])):g(``,!0)}}),[[`__scopeId`,`data-v-fd94857e`]]),we={class:`space-y-4`},Te={key:0,class:`bg-green-100 dark:bg-green-500/10 border border-green-300 dark:border-green-500/30 rounded-lg p-3`},Ee={class:`text-green-700 dark:text-green-400 text-sm`},De={key:1,class:`bg-red-100 dark:bg-red-500/10 border border-red-300 dark:border-red-500/30 rounded-lg p-3`},Oe={class:`text-red-700 dark:text-red-400 text-sm`},ke={class:`flex justify-end gap-2`},Ae=[`disabled`],je=[`disabled`],Me={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},Ne={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`},Pe={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm break-all`},Fe={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`},Ie={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all`},Le={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-1`},Re={class:`flex flex-col items-end gap-1`},ze={class:`text-content-primary dark:text-content-primary font-mono text-xs break-all sm:text-right sm:max-w-xs`},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={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`},Ue={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},We={key:0,class:`flex justify-end`},Ge={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`},Ke={class:`text-content-primary dark:text-content-primary font-mono text-sm`},qe={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`},Je={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ye={class:`flex flex-col py-2 gap-2`},Xe={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},Ze={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},Qe={key:1,class:`flex items-center gap-2`},$e={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`},et={class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},tt=[`maxlength`,`disabled`],nt={key:0,class:`text-red-500 text-xs mt-1`},rt={key:1,class:`text-content-muted dark:text-content-muted text-xs mt-1`},it=[`disabled`],at={key:0,class:`mt-2 bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},ot={key:0,class:`flex items-center gap-3 bg-blue-500/10 border border-blue-500/30 rounded-lg p-3`},st={class:`text-blue-700 dark:text-blue-400 text-xs font-medium`},ct={class:`text-blue-600 dark:text-blue-500 text-xs mt-0.5`},lt={key:1,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-3`},ut={class:`text-red-600 dark:text-red-400 text-sm`},dt={key:2,class:`bg-green-500/10 border border-green-600/40 dark:border-green-500/30 rounded-lg p-3 space-y-2`},ft={class:`text-green-600 dark:text-green-400 text-sm font-medium`},pt={class:`font-mono text-xs break-all text-content-primary dark:text-content-primary`},mt={key:3,class:`bg-amber-500/10 border border-amber-500/30 rounded-lg p-3`},ht={class:`flex gap-2 mt-3`},gt=[`disabled`],_t=[`disabled`],vt={class:`flex justify-end gap-3 mt-6`},yt=[`disabled`],bt=[`disabled`],xt=f({__name:`RepeaterSettings`,setup(e){let t=j(),n=y(()=>t.stats?.config||{}),r=y(()=>n.value.repeater||{}),i=y(()=>t.stats),a=E(!1),o=E(!1),s=E(null),c=E(null),d=E(!1),f=E(``),D=E(0),O=E(0),k=E(0),M=E(1),P=y(()=>n.value.mesh||{});h([n,r,P],()=>{if(!a.value){f.value=n.value.node_name||``,D.value=r.value.latitude||0,O.value=r.value.longitude||0,k.value=r.value.send_advert_interval_hours||0;let e=P.value.path_hash_mode;M.value=e===0||e===1||e===2?e+1:1}},{immediate:!0});let F=y(()=>n.value.node_name||`Not set`),L=y(()=>i.value?.local_hash||`Not available`),R=y(()=>{let e=i.value?.public_key;return!e||e===`Not set`?`Not set`:e}),B=y(()=>{let e=r.value.latitude;return e&&e!==0?e.toFixed(6):`Not set`}),V=y(()=>{let e=r.value.longitude;return e&&e!==0?e.toFixed(6):`Not set`}),H=y(()=>{let e=r.value.mode;return e?e===`no_tx`?`No TX`:e.charAt(0).toUpperCase()+e.slice(1):`Not set`}),U=y(()=>{let e=r.value.send_advert_interval_hours;return e===void 0?`Not set`:e===0?`Disabled`:e+` hour`+(e===1?``:`s`)}),W=y(()=>{let e=P.value.path_hash_mode;return e===0||e===1||e===2?e+1+(e===0?` byte`:` bytes`):`Not set`}),G=()=>{a.value=!0,s.value=null,c.value=null},ee=()=>{a.value=!1,s.value=null,f.value=n.value.node_name||``,D.value=r.value.latitude||0,O.value=r.value.longitude||0,k.value=r.value.send_advert_interval_hours||0;let e=P.value.path_hash_mode;M.value=e===0||e===1||e===2?e+1:1},te=async()=>{o.value=!0,s.value=null,c.value=null;try{let e={};f.value&&(e.node_name=f.value),e.latitude=D.value,e.longitude=O.value,e.flood_advert_interval_hours=k.value,e.path_hash_mode=M.value-1;let n=(await A.post(`/update_radio_config`,e)).data;n.message||n.persisted?(c.value=n.message||`Settings saved successfully`,a.value=!1,await t.fetchStats(),setTimeout(()=>{c.value=null},3e3)):n.error?s.value=n.error:s.value=`Unknown response from server`}catch(e){console.error(`Failed to update repeater settings:`,e),s.value=e.response?.data?.error||`Failed to update settings`}finally{o.value=!1}},ne=()=>{d.value=!0},re=e=>{D.value=e.latitude,O.value=e.longitude},K=E(!1),q=E(``),J=E(!1),Y=E(null),X=E(null),Z=E(!1),Q=E(!1),$=E(!1),ie=E(0),ae=null,oe=y(()=>$.value?8:4),se=y(()=>{let e=q.value.trim();return!e||e.length>oe.value?!1:/^[0-9a-fA-F]+$/.test(e)}),ce=y(()=>{let e=q.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`}),le=()=>{ie.value=0,ae=setInterval(()=>{ie.value++},1e3)},ue=()=>{ae&&=(clearInterval(ae),null)};T(()=>ue());let de=()=>{q.value=``,Y.value=null,X.value=null,Z.value=!1,$.value=!1,K.value=!0},fe=async()=>{J.value=!0,X.value=null,Y.value=null,le();try{let e=await A.generateVanityKey(q.value.trim());e.success&&e.data?Y.value=e.data:X.value=e.error||`Generation failed`}catch(e){let t=e;X.value=t.response?.data?.error||t.message||`Generation failed`}finally{ue(),J.value=!1}},pe=async()=>{if(Y.value){Q.value=!0,X.value=null;try{let e=await A.generateVanityKey(q.value.trim(),!0);e.success&&e.data?(Y.value=e.data,Z.value=!1,K.value=!1,c.value=`New identity key applied. Restart the repeater for the change to take effect.`,await t.fetchStats(),setTimeout(()=>{c.value=null},8e3)):X.value=e.error||`Failed to apply key`}catch(e){let t=e;X.value=t.response?.data?.error||t.message||`Failed to apply key`}finally{Q.value=!1}}};return(e,t)=>(w(),C(`div`,we,[c.value?(w(),C(`div`,Te,[S(`p`,Ee,u(c.value),1)])):g(``,!0),s.value?(w(),C(`div`,De,[S(`p`,Oe,u(s.value),1)])):g(``,!0),S(`div`,ke,[a.value?(w(),C(x,{key:1},[S(`button`,{onClick:ee,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,Ae),S(`button`,{onClick:te,disabled:o.value,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},u(o.value?`Saving...`:`Save Changes`),9,je)],64)):(w(),C(`button`,{key:0,onClick:G,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Edit Settings `))]),S(`div`,Me,[S(`div`,Ne,[t[13]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Node Name`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>f.value=e,type:`text`,maxlength:`50`,class:`w-full sm:w-64 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`,placeholder:`Enter node name`},null,512)),[[N,f.value]]):(w(),C(`div`,Pe,u(F.value),1))]),S(`div`,Fe,[t[14]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Local Hash`,-1),S(`span`,Ie,u(L.value),1)]),S(`div`,Le,[t[15]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm flex-shrink-0`},`Public Key`,-1),S(`div`,Re,[S(`span`,ze,u(R.value),1),S(`button`,{onClick:de,class:`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`},` Generate New Key `)])]),S(`div`,Be,[t[16]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Latitude`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[1]||=e=>D.value=e,type:`number`,step:`0.000001`,min:`-90`,max:`90`,class:`w-full sm:w-48 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,D.value,void 0,{number:!0}]]):(w(),C(`div`,Ve,u(B.value),1))]),S(`div`,He,[t[17]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Longitude`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[2]||=e=>O.value=e,type:`number`,step:`0.000001`,min:`-180`,max:`180`,class:`w-full sm:w-48 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,O.value,void 0,{number:!0}]]):(w(),C(`div`,Ue,u(V.value),1))]),a.value?(w(),C(`div`,We,[S(`button`,{onClick:ne,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm flex items-center gap-2`,title:`Pick location on map`},[...t[18]||=[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)]])])):g(``,!0),S(`div`,Ge,[t[19]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Mode`,-1),S(`span`,Ke,u(H.value),1)]),S(`div`,qe,[t[21]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Path hash length`,-1),a.value?m((w(),C(`select`,{key:1,"onUpdate:modelValue":t[3]||=e=>M.value=e,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[20]||=[S(`option`,{value:1},`1 byte`,-1),S(`option`,{value:2},`2 bytes`,-1),S(`option`,{value:3},`3 bytes`,-1)]],512)),[[z,M.value,void 0,{number:!0}]]):(w(),C(`div`,Je,u(W.value),1))]),S(`div`,Ye,[S(`div`,Xe,[t[23]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Periodic Advertisement Interval`,-1),a.value?(w(),C(`div`,Qe,[m(S(`input`,{"onUpdate:modelValue":t[4]||=e=>k.value=e,type:`number`,min:`0`,max:`48`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,k.value,void 0,{number:!0}]]),t[22]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-sm`},`hours`,-1)])):(w(),C(`div`,Ze,u(U.value),1))]),t[24]||=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)])]),v(Ce,{"is-open":d.value,latitude:D.value,longitude:O.value,onClose:t[5]||=e=>d.value=!1,onSelect:re},null,8,[`is-open`,`latitude`,`longitude`]),(w(),l(p,{to:`body`},[K.value?(w(),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]||=I(e=>K.value=!1,[`self`])},[S(`div`,$e,[t[32]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Generate Vanity Identity Key `,-1),t[33]||=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`,et,`Hex Prefix (1-`+u(oe.value)+` characters)`,1),m(S(`input`,{"onUpdate:modelValue":t[6]||=e=>q.value=e,type:`text`,maxlength:oe.value,placeholder:`e.g. F8A1`,disabled:J.value,class:`w-full px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/40 font-mono text-sm uppercase focus:outline-none focus:border-primary transition-colors disabled:opacity-50`},null,8,tt),[[N,q.value]]),q.value&&!se.value?(w(),C(`p`,nt,` Enter 1-`+u(oe.value)+` valid hex characters (0-9, A-F) `,1)):ce.value?(w(),C(`p`,rt,u(ce.value),1)):g(``,!0)]),S(`div`,null,[S(`button`,{onClick:t[7]||=e=>$.value=!$.value,disabled:J.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`},[(w(),C(`svg`,{class:_([`w-3 h-3 transition-transform`,{"rotate-90":$.value}]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...t[25]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)),t[26]||=b(` Advanced `,-1)],8,it),$.value?(w(),C(`div`,at,[...t[27]||=[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)]])):g(``,!0)]),J.value?(w(),C(`div`,ot,[t[28]||=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`,st,` Searching for key with prefix "`+u(q.value.toUpperCase())+`"... `,1),S(`p`,ct,` Elapsed: `+u(ie.value)+`s `,1)])])):g(``,!0),X.value?(w(),C(`div`,lt,[S(`p`,ut,u(X.value),1)])):g(``,!0),Y.value?(w(),C(`div`,dt,[S(`p`,ft,` Key found in `+u(Y.value.attempts.toLocaleString())+` attempts `,1),S(`div`,null,[t[29]||=S(`span`,{class:`text-xs text-content-muted dark:text-content-muted`},`Public Key:`,-1),S(`p`,pt,u(Y.value.public_hex),1)])])):g(``,!0),Z.value&&Y.value?(w(),C(`div`,mt,[t[30]||=S(`p`,{class:`text-amber-600 dark:text-amber-400 text-sm font-medium`},` Warning: This will replace your current identity key. `,-1),t[31]||=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`,ht,[S(`button`,{onClick:pe,disabled:Q.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`},u(Q.value?`Applying...`:`Confirm Replace Key`),9,gt),S(`button`,{onClick:t[8]||=e=>Z.value=!1,disabled:Q.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,_t)])])):g(``,!0),S(`div`,vt,[S(`button`,{onClick:t[9]||=e=>K.value=!1,disabled:J.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,yt),Y.value?(w(),C(x,{key:1},[S(`button`,{onClick:t[10]||=e=>{Y.value=null,X.value=null},class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 text-sm transition-colors`},` Try Again `),Z.value?g(``,!0):(w(),C(`button`,{key:0,onClick:t[11]||=e=>Z.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)):(w(),C(`button`,{key:0,onClick:fe,disabled:!se.value||J.value,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 text-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed`},u(J.value?`Generating...`:`Generate`),9,bt))])])])):g(``,!0)]))]))}}),St={class:`space-y-4`},Ct={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`},wt={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`},Tt={class:`flex justify-end gap-2`},Et=[`disabled`],Dt=[`disabled`],Ot={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},kt={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={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},jt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Mt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Nt=f({__name:`DutyCycle`,setup(e){let t=j(),n=y(()=>t.stats?.config?.duty_cycle||{}),r=y(()=>{let e=n.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`}),i=y(()=>n.value.enforcement_enabled?`Enabled`:`Disabled`),a=E(!1),o=E(!1),s=E(``),c=E(``),l=E(0),d=E(!0),f=()=>{let e=n.value.max_airtime_percent;typeof e==`number`?l.value=e:e&&typeof e==`object`&&`parsedValue`in e?l.value=e.parsedValue||0:l.value=6,d.value=n.value.enforcement_enabled!==!1,a.value=!0,s.value=``,c.value=``},p=()=>{a.value=!1,s.value=``,c.value=``},h=async()=>{o.value=!0,c.value=``,s.value=``;try{let e=(await k.post(`/api/update_duty_cycle_config`,{max_airtime_percent:l.value,enforcement_enabled:d.value})).data;e.message||e.persisted?(s.value=e.message||`Settings saved successfully`,a.value=!1,await t.fetchStats(),setTimeout(()=>{s.value=``},3e3)):c.value=`Failed to save settings`}catch(e){console.error(`Failed to save duty cycle settings:`,e),c.value=e.response?.data?.error||`Failed to save settings`}finally{o.value=!1}};return(e,t)=>(w(),C(`div`,St,[s.value?(w(),C(`div`,Ct,u(s.value),1)):g(``,!0),c.value?(w(),C(`div`,wt,u(c.value),1)):g(``,!0),S(`div`,Tt,[a.value?(w(),C(x,{key:1},[S(`button`,{onClick:p,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,Et),S(`button`,{onClick:h,disabled:o.value,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},u(o.value?`Saving...`:`Save Changes`),9,Dt)],64)):(w(),C(`button`,{key:0,onClick:f,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Edit Settings `))]),S(`div`,Ot,[S(`div`,kt,[t[2]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Max Airtime %`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>l.value=e,type:`number`,step:`0.1`,min:`0.1`,max:`100`,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,l.value,void 0,{number:!0}]]):(w(),C(`div`,At,u(r.value),1))]),S(`div`,jt,[t[4]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Enforcement`,-1),a.value?m((w(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>d.value=e,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[3]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[z,d.value]]):(w(),C(`div`,Mt,u(i.value),1))])])]))}}),Pt={class:`space-y-4`},Ft={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`},It={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`},Lt={class:`flex justify-end gap-2`},Rt=[`disabled`],zt=[`disabled`],Bt={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},Vt={class:`flex flex-col py-2 border-b border-stroke-subtle dark:border-stroke/10 gap-2`},Ht={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},Ut={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},Wt={class:`flex flex-col py-2 gap-2`},Gt={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-1`},Kt={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm sm:ml-4`},qt=f({__name:`TransmissionDelays`,setup(e){let t=j(),n=y(()=>t.stats?.config?.delays||{}),r=y(()=>{let e=n.value.tx_delay_factor;if(e&&typeof e==`object`&&e&&`parsedValue`in e){let t=e.parsedValue;if(typeof t==`number`)return t.toFixed(2)+`x`}return`Not set`}),i=y(()=>{let e=n.value.direct_tx_delay_factor;return typeof e==`number`?e.toFixed(2)+`s`:`Not set`}),a=E(!1),o=E(!1),s=E(``),c=E(``),l=E(0),d=E(0),f=()=>{let e=n.value.tx_delay_factor;e&&typeof e==`object`&&`parsedValue`in e?l.value=e.parsedValue||1:typeof e==`number`?l.value=e:l.value=1;let t=n.value.direct_tx_delay_factor;d.value=typeof t==`number`?t:.5,a.value=!0,s.value=``,c.value=``},p=()=>{a.value=!1,s.value=``,c.value=``},h=async()=>{o.value=!0,c.value=``,s.value=``;try{let e=(await k.post(`/api/update_radio_config`,{tx_delay_factor:l.value,direct_tx_delay_factor:d.value})).data;e.message||e.persisted?(s.value=e.message||`Settings saved successfully`,a.value=!1,await t.fetchStats(),setTimeout(()=>{s.value=``},3e3)):c.value=`Failed to save settings`}catch(e){console.error(`Failed to save delay settings:`,e),c.value=e.response?.data?.error||`Failed to save settings`}finally{o.value=!1}};return(e,t)=>(w(),C(`div`,Pt,[s.value?(w(),C(`div`,Ft,u(s.value),1)):g(``,!0),c.value?(w(),C(`div`,It,u(c.value),1)):g(``,!0),S(`div`,Lt,[a.value?(w(),C(x,{key:1},[S(`button`,{onClick:p,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,Rt),S(`button`,{onClick:h,disabled:o.value,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},u(o.value?`Saving...`:`Save Changes`),9,zt)],64)):(w(),C(`button`,{key:0,onClick:f,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Edit Settings `))]),S(`div`,Bt,[S(`div`,Vt,[S(`div`,Ht,[t[2]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Flood TX Delay Factor`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[0]||=e=>l.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`w-full sm:w-32 px-3 py-1.5 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,l.value,void 0,{number:!0}]]):(w(),C(`div`,Ut,u(r.value),1))]),t[3]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Multiplier for flood packet transmission delays (collision avoidance)`,-1)]),S(`div`,Wt,[S(`div`,Gt,[t[4]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Direct TX Delay Factor`,-1),a.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[1]||=e=>d.value=e,type:`number`,step:`0.1`,min:`0`,max:`5`,class:`w-full sm:w-32 px-3 py-1.5 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,d.value,void 0,{number:!0}]]):(w(),C(`div`,Kt,u(i.value),1))]),t[5]||=S(`span`,{class:`text-content-muted dark:text-content-muted text-xs`},`Base delay for direct-routed packet transmission (seconds)`,-1)])])]))}}),Jt=D(`treeState`,()=>{let e=a(new Set),t=a({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)}}}),Yt={class:`select-none`},Xt={class:`flex-shrink-0`},Zt={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`},Qt={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`},$t={key:0,class:`hidden sm:flex items-center gap-1 ml-2`},en={class:`relative group`},tn=[`title`],nn={key:0,class:`text-xs font-mono text-white/50 bg-white/5 px-1.5 py-0.5 rounded border border-white/10`},rn={class:`flex justify-between items-start mb-4`},an={class:`bg-black/20 border border-white/10 rounded-md p-4 mb-4`},on={class:`text-sm font-mono text-white/80 break-all leading-relaxed`},sn={class:`flex items-center gap-1 sm:gap-2 ml-auto flex-shrink-0`},cn={key:0,class:`hidden sm:flex items-center gap-1`},ln=[`title`],un={key:1,class:`hidden sm:flex items-center gap-1`},dn={key:2,class:`hidden sm:inline-block px-2 py-1 bg-white/10 text-white/60 text-xs rounded-full ml-1`},fn={key:0,class:`space-y-1`},pn=M(f({__name:`TreeNode`,props:{node:{},selectedNodeId:{},level:{},disabled:{type:Boolean}},emits:[`select`],setup(e,{emit:n}){let a=e,o=n,s=Jt(),c=E(!1),d=y({get:()=>s.isNodeExpanded(a.node.id),set:e=>{e?s.addExpandedNode(a.node.id):s.removeExpandedNode(a.node.id)}}),f=y(()=>a.node.children.length>0);function p(e){if(!e)return`Never`;let t=new Date().getTime()-e.getTime(),n=Math.floor(t/(1e3*60)),r=Math.floor(t/(1e3*60*60)),i=Math.floor(t/(1e3*60*60*24)),a=Math.floor(i/365);return n<60?`${n}m ago`:r<24?`${r}h ago`:i<365?`${i}d ago`:`${a}y ago`}function m(e){return e?e.length<=16?e:`${e.slice(0,8)}...${e.slice(-8)}`:`No key`}function h(){f.value&&(d.value=!d.value)}function T(){o(`select`,a.node.id)}function D(e){o(`select`,e)}function O(e){e.stopPropagation(),c.value=!c.value}function k(e){e.stopPropagation(),a.node.transport_key&&window.navigator?.clipboard&&window.navigator.clipboard.writeText(a.node.transport_key)}return(n,o)=>{let s=r(`TreeNode`,!0);return w(),C(`div`,Yt,[S(`div`,{class:_([`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 cursor-pointer transition-all duration-200`,a.disabled?`opacity-50 cursor-not-allowed`:`hover:bg-white/5`,e.selectedNodeId===e.node.id&&!a.disabled?`bg-primary/20 text-primary`:`text-white/80 hover:text-white`,`ml-${e.level*4}`]),onClick:o[3]||=e=>!a.disabled&&T()},[S(`div`,{class:`flex-shrink-0 w-3 h-3 sm:w-4 sm:h-4 flex items-center justify-center`,onClick:I(h,[`stop`])},[f.value?(w(),C(`svg`,{key:0,class:_([`w-2.5 h-2.5 sm:w-3 sm:h-3 transition-transform duration-200`,d.value?`rotate-90`:`rotate-0`]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...o[4]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`},null,-1)]],2)):g(``,!0)]),S(`div`,Xt,[a.node.name.startsWith(`#`)?(w(),C(`svg`,Zt,[...o[5]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,Qt,[...o[6]||=[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:_([`font-mono text-xs sm:text-sm transition-colors duration-200 break-all`,e.selectedNodeId===e.node.id?`text-primary font-medium`:``])},u(e.node.name),3),e.node.transport_key?(w(),C(`div`,$t,[S(`div`,en,[S(`button`,{onClick:O,class:`p-1 rounded hover:bg-white/10 transition-colors`,title:c.value?`Hide full key`:`Show full key`},[...o[7]||=[S(`svg`,{class:`w-3 h-3 text-white/60 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,tn),c.value?g(``,!0):(w(),C(`span`,nn,u(m(e.node.transport_key)),1)),c.value?(w(),C(`div`,{key:1,class:`fixed inset-0 z-[9998] flex items-center justify-center bg-black/70 backdrop-blur-md`,onClick:o[2]||=e=>c.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]||=I(()=>{},[`stop`])},[S(`div`,rn,[o[9]||=S(`h3`,{class:`text-lg font-semibold text-white`},`Transport Key`,-1),S(`button`,{onClick:o[0]||=e=>c.value=!1,class:`text-white/60 hover:text-white transition-colors`},[...o[8]||=[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`,an,[S(`div`,on,u(e.node.transport_key),1)]),S(`div`,{class:`flex justify-end`},[S(`button`,{onClick:k,class:`px-4 py-2 bg-accent-green/20 hover:bg-accent-green/30 border border-accent-green/50 text-accent-green rounded-lg transition-colors flex items-center gap-2`,title:`Copy to clipboard`},[...o[10]||=[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),b(` Copy Key `,-1)]])])])])):g(``,!0)])])):g(``,!0),S(`div`,sn,[e.node.last_used?(w(),C(`div`,cn,[o[11]||=S(`svg`,{class:`w-3 h-3 text-white/40`,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`})],-1),S(`span`,{class:`text-xs text-white/50`,title:e.node.last_used.toLocaleString()},u(p(e.node.last_used)),9,ln)])):(w(),C(`div`,un,[...o[12]||=[S(`svg`,{class:`w-3 h-3 text-white/30`,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`})],-1),S(`span`,{class:`text-xs text-white/30 italic`},`Never`,-1)]])),S(`span`,{class:_([`px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded-md transition-colors`,e.node.floodPolicy===`allow`?`bg-accent-green/10 text-accent-green/90 border border-accent-green/20`:`bg-accent-red/10 text-accent-red/90 border border-accent-red/20`])},u(e.node.floodPolicy===`allow`?`ALLOW`:`DENY`),3),f.value?(w(),C(`span`,dn,` > `+u(e.node.children.length),1)):g(``,!0)])],2),v(R,{"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:t(()=>[d.value&&e.node.children.length>0?(w(),C(`div`,fn,[(w(!0),C(x,null,i(e.node.children,t=>(w(),l(s,{key:t.id,node:t,"selected-node-id":e.selectedNodeId,level:e.level+1,disabled:a.disabled,onSelect:D},null,8,[`node`,`selected-node-id`,`level`,`disabled`]))),128))])):g(``,!0)]),_:1})])}}}),[[`__scopeId`,`data-v-ed9c8a11`]]),mn={class:`flex items-center justify-between mb-6`},hn={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},gn={key:0},_n={class:`text-primary font-mono`},vn={key:1},yn={for:`keyName`,class:`block text-sm font-medium text-white mb-2`},bn={class:`flex items-center gap-2`},xn={key:0,class:`w-4 h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Sn={key:1,class:`w-4 h-4 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Cn={class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4`},wn={class:`flex items-center gap-3 mb-2`},Tn={class:`flex items-center gap-2`},En={key:0,class:`w-5 h-5 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Dn={key:1,class:`w-5 h-5 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},On={class:`text-content-secondary dark:text-content-muted text-sm`},kn={class:`grid grid-cols-2 gap-3`},An={class:`relative cursor-pointer group`},jn={class:`relative cursor-pointer group`},Mn={class:`flex gap-3 pt-4`},Nn=[`disabled`],Pn=f({__name:`AddKeyModal`,props:{show:{type:Boolean},selectedNodeName:{},selectedNodeId:{}},emits:[`close`,`add`],setup(e,{emit:t}){let n=e,r=t,i=E(``),a=E(``),o=E(`allow`),s=y(()=>i.value.startsWith(`#`)),c=y(()=>({type:s.value?`Region`:`Private Key`,description:s.value?`Regional organizational key`:`Individual assigned key`}));h(s,e=>{e?a.value=`This will create a new region for organizing keys`:a.value=`This will create a new private key entry`},{immediate:!0});let l=y(()=>i.value.trim().length>0),f=()=>{l.value&&(r(`add`,{name:i.value.trim(),floodPolicy:o.value,parentId:n.selectedNodeId}),i.value=``,a.value=``,o.value=`allow`)},p=()=>{i.value=``,a.value=``,o.value=`allow`,r(`close`)},v=e=>{e.target===e.currentTarget&&p()};return(t,r)=>e.show?(w(),C(`div`,{key:0,onClick:v,class:`fixed inset-0 bg-black/40 backdrop-blur-lg z-[99999] flex items-center justify-center p-4`,style:{"backdrop-filter":`blur(8px) saturate(180%)`,position:`fixed`,top:`0`,left:`0`,right:`0`,bottom:`0`}},[S(`div`,{class:`bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-md border border-stroke-subtle dark:border-white/10`,onClick:r[3]||=I(()=>{},[`stop`])},[S(`div`,mn,[S(`div`,null,[r[5]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Add New Entry `,-1),S(`p`,hn,[n.selectedNodeName?(w(),C(`span`,gn,[r[4]||=b(` Add to: `,-1),S(`span`,_n,u(n.selectedNodeName),1)])):(w(),C(`span`,vn,` Add to root level (#uk) `))])]),S(`button`,{onClick:p,class:`text-white/60 hover:text-white transition-colors`},[...r[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:`M6 18L18 6M6 6l12 12`})],-1)]])]),S(`form`,{onSubmit:I(f,[`prevent`]),class:`space-y-4`},[S(`div`,null,[S(`label`,yn,[S(`div`,bn,[s.value?(w(),C(`svg`,xn,[...r[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,Sn,[...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 1121 9z`},null,-1)]])),r[9]||=b(` Region/Key Name `,-1)])]),m(S(`input`,{id:`keyName`,"onUpdate:modelValue":r[0]||=e=>i.value=e,type:`text`,placeholder:`Enter name (prefix with # for regions)`,class:`w-full px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors`,autocomplete:`off`},null,512),[[N,i.value]])]),S(`div`,Cn,[S(`div`,wn,[S(`div`,Tn,[s.value?(w(),C(`svg`,En,[...r[10]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,Dn,[...r[11]||=[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 1221 9z`},null,-1)]])),S(`span`,{class:_([s.value?`text-secondary`:`text-accent-green`,`font-medium`])},u(c.value.type),3)]),S(`div`,{class:_([`flex-1 h-px`,s.value?`bg-secondary/20`:`bg-accent-green/20`])},null,2)]),S(`p`,On,u(c.value.description),1)]),S(`div`,null,[r[14]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-3`},[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:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})]),b(` Flood Policy `)])],-1),S(`div`,kn,[S(`label`,An,[m(S(`input`,{type:`radio`,"onUpdate:modelValue":r[1]||=e=>o.value=e,value:`allow`,class:`sr-only`},null,512),[[F,o.value]]),r[12]||=d(`<div class="flex items-center gap-3 p-3 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-green/50 group-has-[:checked]:bg-accent-green/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-green group-has-[:checked]:bg-accent-green transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg><span class="font-medium text-accent-green text-sm">Allow</span></div><p class="text-content-secondary dark:text-content-muted text-xs mt-1"> Permit flooding </p></div></div>`,1)]),S(`label`,jn,[m(S(`input`,{type:`radio`,"onUpdate:modelValue":r[2]||=e=>o.value=e,value:`deny`,class:`sr-only`},null,512),[[F,o.value]]),r[13]||=d(`<div class="flex items-center gap-3 p-3 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-red/50 group-has-[:checked]:bg-accent-red/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-red group-has-[:checked]:bg-accent-red transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-red" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg><span class="font-medium text-accent-red text-sm">Deny</span></div><p class="text-content-secondary dark:text-content-muted text-xs mt-1"> Block flooding </p></div></div>`,1)])])]),S(`div`,Mn,[S(`button`,{type:`button`,onClick:p,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 `),S(`button`,{type:`submit`,disabled:!l.value,class:_([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,l.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 dark:text-content-muted cursor-not-allowed`])},` Add `+u(c.value.type),11,Nn)])],32)])])):g(``,!0)}}),Fn={class:`flex items-center justify-between mb-6`},In={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},Ln={class:`text-primary font-mono`},Rn={for:`keyName`,class:`block text-sm font-medium text-content-secondary dark:text-content-primary mb-2`},zn={class:`flex items-center gap-2`},Bn={key:0,class:`w-4 h-4 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Vn={key:1,class:`w-4 h-4 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Hn={class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4`},Un={class:`flex items-center gap-3 mb-2`},Wn={class:`flex items-center gap-2`},Gn={key:0,class:`w-5 h-5 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Kn={key:1,class:`w-5 h-5 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},qn={class:`text-content-secondary dark:text-content-muted text-sm`},Jn={key:0,class:`space-y-4`},Yn={key:0,class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4`},Xn={class:`bg-background-mute dark:bg-black/20 border border-stroke-subtle dark:border-stroke/10 rounded-md p-3`},Zn={class:`text-xs font-mono text-content-primary dark:text-content-primary/80 break-all`},Qn={key:1,class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4`},$n={class:`flex items-center justify-between`},er={class:`text-sm text-content-secondary dark:text-content-muted`},tr={class:`text-xs text-content-muted dark:text-content-muted`},nr={class:`grid grid-cols-2 gap-3`},rr={class:`relative cursor-pointer group`},ir={class:`relative cursor-pointer group`},ar={class:`flex gap-3 pt-4`},or=[`disabled`],sr=f({__name:`EditKeyModal`,props:{show:{type:Boolean},node:{}},emits:[`close`,`save`,`request-delete`],setup(e,{emit:t}){let n=e,r=t,i=E(``),a=E(`allow`),o=y(()=>i.value.startsWith(`#`)),s=y(()=>({type:o.value?`Region`:`Private Key`,description:o.value?`Regional organizational key`:`Individual assigned key`}));h(()=>n.node,e=>{e?(i.value=e.name,a.value=e.floodPolicy):(i.value=``,a.value=`allow`)},{immediate:!0});let c=y(()=>i.value.trim().length>0&&n.node),l=e=>{let t=new Date().getTime()-e.getTime(),n=Math.floor(t/(1e3*60)),r=Math.floor(t/(1e3*60*60)),i=Math.floor(t/(1e3*60*60*24)),a=Math.floor(i/365);return n<60?`${n}m ago`:r<24?`${r}h ago`:i<365?`${i}d ago`:`${a}y ago`},f=e=>{window.navigator?.clipboard&&window.navigator.clipboard.writeText(e)},p=()=>{!c.value||!n.node||(r(`save`,{id:n.node.id,name:i.value.trim(),floodPolicy:a.value}),x())},v=()=>{n.node&&(r(`request-delete`,n.node),x())},x=()=>{r(`close`)},T=e=>{e.target===e.currentTarget&&x()};return(t,n)=>e.show?(w(),C(`div`,{key:0,onClick:T,class:`fixed inset-0 bg-black/50 backdrop-blur-lg z-[99999] flex items-center justify-center p-4`,style:{"backdrop-filter":`blur(8px) saturate(180%)`,position:`fixed`,top:`0`,left:`0`,right:`0`,bottom:`0`}},[S(`div`,{class:`bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-lg border border-stroke-subtle dark:border-white/10`,onClick:n[4]||=I(()=>{},[`stop`])},[S(`div`,Fn,[S(`div`,null,[n[6]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Edit Entry `,-1),S(`p`,In,[n[5]||=b(` Modify `,-1),S(`span`,Ln,u(e.node?.name),1)])]),S(`button`,{onClick:x,class:`text-white/60 hover:text-white transition-colors`},[...n[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)]])]),S(`form`,{onSubmit:I(p,[`prevent`]),class:`space-y-4`},[S(`div`,null,[S(`label`,Rn,[S(`div`,zn,[o.value?(w(),C(`svg`,Bn,[...n[8]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,Vn,[...n[9]||=[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)]])),n[10]||=b(` Region/Key Name `,-1)])]),m(S(`input`,{id:`keyName`,"onUpdate:modelValue":n[0]||=e=>i.value=e,type:`text`,placeholder:`Enter name (prefix with # for regions)`,class:`w-full px-4 py-3 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors`,autocomplete:`off`},null,512),[[N,i.value]])]),S(`div`,Hn,[S(`div`,Un,[S(`div`,Wn,[o.value?(w(),C(`svg`,Gn,[...n[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,Kn,[...n[12]||=[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`,{class:_([o.value?`text-secondary`:`text-accent-green`,`font-medium`])},u(s.value.type),3)]),S(`div`,{class:_([`flex-1 h-px`,o.value?`bg-secondary/20`:`bg-accent-green/20`])},null,2)]),S(`p`,qn,u(s.value.description),1)]),e.node?(w(),C(`div`,Jn,[e.node.transport_key?(w(),C(`div`,Yn,[n[14]||=d(`<div class="flex items-center gap-2 mb-3"><svg class="w-4 h-4 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><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"></path></svg><span class="text-sm font-medium text-content-primary dark:text-content-primary">Transport Key</span></div>`,1),S(`div`,Xn,[S(`div`,Zn,u(e.node.transport_key),1),S(`button`,{onClick:n[1]||=t=>f(e.node.transport_key||``),class:`mt-2 text-xs text-accent-green hover:text-accent-green/80 flex items-center gap-1`,title:`Copy to clipboard`},[...n[13]||=[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),b(` Copy Key `,-1)]])])])):g(``,!0),e.node.last_used?(w(),C(`div`,Qn,[n[15]||=S(`div`,{class:`flex items-center gap-2 mb-3`},[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`,$n,[S(`div`,er,u(e.node.last_used.toLocaleDateString())+` at `+u(e.node.last_used.toLocaleTimeString()),1),S(`div`,tr,u(l(e.node.last_used)),1)])])):g(``,!0)])):g(``,!0),S(`div`,null,[n[18]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-primary mb-3`},[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:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`})]),b(` Flood Policy `)])],-1),S(`div`,nr,[S(`label`,rr,[m(S(`input`,{type:`radio`,"onUpdate:modelValue":n[2]||=e=>a.value=e,value:`allow`,class:`sr-only`},null,512),[[F,a.value]]),n[16]||=d(`<div class="flex items-center gap-3 p-3 bg-white/5 border border-white/20 rounded-lg group-has-[:checked]:border-accent-green/50 group-has-[:checked]:bg-accent-green/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-white/30 rounded-full group-has-[:checked]:border-accent-green group-has-[:checked]:bg-accent-green transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg><span class="font-medium text-accent-green text-sm">Allow</span></div><p class="text-content-muted dark:text-content-muted text-xs mt-1"> Permit flooding </p></div></div>`,1)]),S(`label`,ir,[m(S(`input`,{type:`radio`,"onUpdate:modelValue":n[3]||=e=>a.value=e,value:`deny`,class:`sr-only`},null,512),[[F,a.value]]),n[17]||=d(`<div class="flex items-center gap-3 p-3 bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg group-has-[:checked]:border-accent-red/50 group-has-[:checked]:bg-accent-red/10 transition-colors"><div class="flex items-center justify-center w-4 h-4 border-2 border-stroke dark:border-stroke/30 rounded-full group-has-[:checked]:border-accent-red group-has-[:checked]:bg-accent-red transition-all"><div class="w-2 h-2 rounded-full bg-white scale-0 group-has-[:checked]:scale-100 transition-transform"></div></div><div class="flex-1"><div class="flex items-center gap-2"><svg class="w-4 h-4 text-accent-red" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg><span class="font-medium text-accent-red text-sm">Deny</span></div><p class="text-content-muted dark:text-content-muted text-xs mt-1"> Block flooding </p></div></div>`,1)])])]),S(`div`,ar,[S(`button`,{type:`button`,onClick:v,class:`px-4 py-3 bg-accent-red/20 hover:bg-accent-red/30 border border-accent-red/50 text-accent-red rounded-lg transition-colors`},` Delete `),S(`button`,{type:`button`,onClick:x,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 `),S(`button`,{type:`submit`,disabled:!c.value,class:_([`flex-1 px-4 py-3 rounded-lg transition-colors font-medium`,c.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`])},` Save Changes `,10,or)])],32)])])):g(``,!0)}}),cr={class:`flex items-center gap-3 mb-6`},lr={class:`text-content-secondary dark:text-content-muted text-sm mt-1`},ur={class:`text-accent-red font-mono`},dr={key:0,class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},fr={class:`flex items-start gap-3`},pr={class:`flex-1`},mr={class:`text-accent-red font-medium text-sm mb-2`},hr={class:`space-y-1 max-h-32 overflow-y-auto`},gr={key:0,class:`w-3 h-3 text-secondary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},_r={key:1,class:`w-3 h-3 text-accent-green`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},vr={class:`font-mono`},yr={key:0,class:`text-content-secondary dark:text-content-muted text-xs`},br={key:1,class:`mb-6`},xr={class:`mb-3`},Sr={class:`relative`},Cr={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`},wr={key:0,class:`text-center py-4 text-content-secondary dark:text-content-muted text-sm`},Tr={class:`relative`},Er=[`value`],Dr={class:`flex items-center gap-2 flex-1`},Or={class:`text-content-primary dark:text-content-primary font-mono text-sm`},kr={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`},Ar={class:`flex gap-3`},jr=f({__name:`DeleteConfirmModal`,props:{show:{type:Boolean},node:{},allNodes:{}},emits:[`close`,`delete-all`,`move-children`],setup(e,{emit:t}){let n=e,r=t,a=E(null),o=E(``),s=e=>{let t=[],n=e=>{for(let r of e.children)t.push(r),n(r)};return n(e),t},c=y(()=>n.node?s(n.node):[]),l=y(()=>{if(!n.node)return[];let e=new Set([n.node.id,...c.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(n.allNodes)}),d=y(()=>{if(!o.value.trim())return l.value;let e=o.value.toLowerCase();return l.value.filter(t=>t.name.toLowerCase().includes(e))}),f=()=>{n.node&&(r(`delete-all`,n.node.id),h())},p=()=>{!n.node||!a.value||(r(`move-children`,{nodeId:n.node.id,targetParentId:a.value}),h())},h=()=>{a.value=null,o.value=``,r(`close`)},v=e=>{e.target===e.currentTarget&&h()};return(t,n)=>e.show&&e.node?(w(),C(`div`,{key:0,onClick:v,class:`fixed inset-0 bg-black/80 backdrop-blur-lg z-[99999] flex items-center justify-center p-4`,style:{"backdrop-filter":`blur(8px) saturate(180%)`,position:`fixed`,top:`0`,left:`0`,right:`0`,bottom:`0`}},[S(`div`,{class:`bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] p-6 w-full max-w-lg border border-stroke-subtle dark:border-white/10`,onClick:n[2]||=I(()=>{},[`stop`])},[S(`div`,cr,[n[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,[n[4]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Confirm Deletion `,-1),S(`p`,lr,[n[3]||=b(` Deleting `,-1),S(`span`,ur,u(e.node?.name),1)])]),S(`button`,{onClick:h,class:`ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...n[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)]])]),c.value.length>0?(w(),C(`div`,dr,[S(`div`,fr,[n[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`,pr,[S(`h4`,mr,` This will affect `+u(c.value.length)+` child `+u(c.value.length===1?`entry`:`entries`)+`: `,1),S(`div`,hr,[(w(!0),C(x,null,i(c.value.slice(0,10),e=>(w(),C(`div`,{key:e.id,class:`flex items-center gap-2 text-xs text-content-secondary dark:text-content-primary/80`},[e.name.startsWith(`#`)?(w(),C(`svg`,gr,[...n[7]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M7 20l4-16m2 16l4-16M6 9h14M4 15h14`},null,-1)]])):(w(),C(`svg`,_r,[...n[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`,vr,u(e.name),1),S(`span`,{class:_([`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`])},u(e.floodPolicy),3)]))),128)),c.value.length>10?(w(),C(`div`,yr,` ...and `+u(c.value.length-10)+` more `,1)):g(``,!0)])])])])):g(``,!0),c.value.length>0&&l.value.length>0?(w(),C(`div`,br,[n[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`,xr,[S(`div`,Sr,[n[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),m(S(`input`,{"onUpdate:modelValue":n[0]||=e=>o.value=e,type:`text`,placeholder:`Search regions...`,class:`w-full pl-9 pr-4 py-2 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/20 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-500 dark:placeholder-white/50 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-colors text-sm`},null,512),[[N,o.value]])])]),S(`div`,Cr,[d.value.length===0?(w(),C(`div`,wr,u(o.value?`No regions match your search`:`No available regions`),1)):g(``,!0),(w(!0),C(x,null,i(d.value,e=>(w(),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`,Tr,[m(S(`input`,{type:`radio`,value:e.id,"onUpdate:modelValue":n[1]||=e=>a.value=e,class:`sr-only peer`},null,8,Er),[[F,a.value]]),n[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`,Dr,[n[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`,Or,u(e.name),1),e.children.length>0?(w(),C(`span`,kr,u(e.children.length),1)):g(``,!0)])]))),128))])])):g(``,!0),S(`div`,Ar,[S(`button`,{onClick:h,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 `),c.value.length>0&&a.value?(w(),C(`button`,{key:0,onClick:p,class:`flex-1 px-4 py-3 bg-primary/20 hover:bg-primary/30 border border-primary/50 text-primary rounded-lg transition-colors`},` Move & Delete `)):g(``,!0),S(`button`,{onClick:f,class:`flex-1 px-4 py-3 bg-accent-red/20 hover:bg-accent-red/30 border border-accent-red/50 text-accent-red rounded-lg transition-colors font-medium`},u(c.value.length>0?`Delete All`:`Delete`),1)])])])):g(``,!0)}}),Mr={class:`space-y-4 sm:space-y-6`},Nr={class:`flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3`},Pr={class:`flex gap-2 flex-wrap`},Fr=[`disabled`],Ir=[`disabled`],Lr={class:`glass-card rounded-[15px] p-3 sm:p-4 border border-stroke-subtle dark:border-stroke/10 bg-background-mute dark:bg-white/5`},Rr={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},zr={class:`flex items-center gap-2 sm:gap-3`},Br={class:`flex bg-background-mute dark:bg-stroke/5 rounded-lg border border-stroke-subtle dark:border-stroke/20 p-0.5 sm:p-1`},Vr={class:`glass-card rounded-[15px] p-3 sm:p-6 border border-stroke-subtle dark:border-stroke/10`},Hr={key:0,class:`flex items-center justify-center py-8`},Ur={key:1,class:`text-center py-8`},Wr={class:`text-content-secondary dark:text-content-muted text-sm`},Gr={key:2,class:`text-center py-8`},Kr={key:3,class:`space-y-2`},qr=f({name:`TransportKeys`,__name:`TransportKeys`,setup(e){let t=Jt(),n=j(),r=E(!1),a=E(!1),c=E(!1),d=E(null),f=E(null),p=E(`deny`);h(y(()=>n.stats?.config?.mesh?.unscoped_flood_allow??null),e=>{e!==null&&(p.value=e?`allow`:`deny`)},{immediate:!0});let m=E([]),g=E(!1),T=E(null),D=e=>{let t=new Map,n=[];return e.forEach(e=>{let n={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.set(e.id,n)}),t.forEach(e=>{e.parent_id&&t.has(e.parent_id)?t.get(e.parent_id).children.push(e):n.push(e)}),n},O=async()=>{try{g.value=!0,T.value=null;let e=await A.getTransportKeys();e.success&&e.data?m.value=D(e.data):T.value=e.error||`Failed to load transport keys`}catch(e){T.value=e instanceof Error?e.message:`Unknown error occurred`,console.error(`Error loading transport keys:`,e)}finally{g.value=!1}};o(()=>{O()});function k(e,t){for(let n of e){if(n.id===t)return n;if(n.children){let e=k(n.children,t);if(e)return e}}return null}function M(){let e=t.selectedNodeId.value;if(e)return k(m.value,e)?.name}function N(e){t.setSelectedNode(e)}function P(){r.value=!0}function F(){if(t.selectedNodeId.value){let e=k(m.value,t.selectedNodeId.value);e&&(f.value=e,c.value=!0)}}function I(){if(t.selectedNodeId.value){let e=k(m.value,t.selectedNodeId.value);e&&(d.value=e,a.value=!0)}}let L=async e=>{try{let t=await A.createTransportKey(e.name,e.floodPolicy,void 0,e.parentId,void 0);t.success?await O():(console.error(`Failed to add transport key:`,t.error),T.value=t.error||`Failed to add transport key`)}catch(e){console.error(`Error adding transport key:`,e),T.value=e instanceof Error?e.message:`Unknown error occurred`}finally{r.value=!1}};function R(){r.value=!1}async function z(e){try{let t=e===`allow`,r=await A.updateUnscopedFloodPolicy(t);r.success?(p.value=e,await n.fetchStats()):(console.error(`Failed to update unscoped flood policy:`,r.error),T.value=r.error||`Failed to update unscoped flood policy`)}catch(e){console.error(`Error updating unscoped flood policy:`,e),T.value=e instanceof Error?e.message:`Failed to update unscoped flood policy`}}function B(){a.value=!1,d.value=null}async function V(e){try{let t=await A.updateTransportKey(e.id,e.name,e.floodPolicy);t.success?await O():(console.error(`Failed to update transport key:`,t.error),T.value=t.error||`Failed to update transport key`)}catch(e){console.error(`Error updating transport key:`,e),T.value=e instanceof Error?e.message:`Unknown error occurred`}finally{B()}}function H(e){a.value=!1,d.value=null,f.value=e,c.value=!0}function U(){c.value=!1,f.value=null}async function W(e){try{let n=await A.deleteTransportKey(e);n.success?(await O(),t.setSelectedNode(null)):(console.error(`Failed to delete transport key:`,n.error),T.value=n.error||`Failed to delete transport key`)}catch(e){console.error(`Error deleting transport key:`,e),T.value=e instanceof Error?e.message:`Unknown error occurred`}finally{U()}}async function G(e){try{let n=await A.deleteTransportKey(e.nodeId);n.success?(await O(),t.setSelectedNode(null)):(console.error(`Failed to delete transport key:`,n.error),T.value=n.error||`Failed to delete transport key`)}catch(e){console.error(`Error deleting transport key:`,e),T.value=e instanceof Error?e.message:`Unknown error occurred`}finally{U()}}return(e,n)=>(w(),C(`div`,Mr,[S(`div`,Nr,[n[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`},` Regions/Keys `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},` Manage regional key hierarchy `)],-1),S(`div`,Pr,[S(`button`,{onClick:P,class:`flex items-center gap-1.5 sm:gap-2 px-2.5 sm:px-3 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm bg-accent-green/10 hover:bg-accent-green/20 text-accent-green border-accent-green/30`},[...n[2]||=[S(`svg`,{class:`w-3.5 h-3.5 sm:w-4 sm: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(` Add `,-1)]]),S(`button`,{onClick:I,disabled:!s(t).selectedNodeId.value,class:_([`px-2.5 sm:px-4 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm`,s(t).selectedNodeId.value?`bg-accent-green/20 hover:bg-accent-green/30 text-accent-green border-accent-green/50`:`bg-background-mute dark:bg-stroke/10 text-content-muted dark:text-content-muted/70 border-stroke-subtle dark:border-stroke/20 cursor-not-allowed`])},` Edit `,10,Fr),S(`button`,{onClick:F,disabled:!s(t).selectedNodeId.value,class:_([`px-2.5 sm:px-4 py-1.5 sm:py-2 rounded-lg border transition-colors text-xs sm:text-sm`,s(t).selectedNodeId.value?`bg-accent-red/20 hover:bg-accent-red/30 text-accent-red border-accent-red/50`:`bg-background-mute dark:bg-stroke/10 text-content-muted dark:text-content-muted/70 border-stroke-subtle dark:border-stroke/20 cursor-not-allowed`])},` Delete `,10,Ir)])]),S(`div`,Lr,[S(`div`,Rr,[n[4]||=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`,zr,[S(`div`,Br,[S(`button`,{onClick:n[0]||=e=>z(`deny`),class:_([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,p.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=>z(`allow`),class:_([`px-2 sm:px-3 py-1 text-[10px] sm:text-xs font-medium rounded transition-colors`,p.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)])])])]),S(`div`,Vr,[g.value?(w(),C(`div`,Hr,[...n[5]||=[S(`div`,{class:`animate-spin rounded-full h-8 w-8 border-b-2 border-accent-green`},null,-1),S(`span`,{class:`ml-2 text-content-secondary dark:text-content-muted`},`Loading transport keys...`,-1)]])):T.value?(w(),C(`div`,Ur,[n[6]||=S(`div`,{class:`text-accent-red mb-2`},`⚠️ Error loading transport keys`,-1),S(`div`,Wr,u(T.value),1),S(`button`,{onClick:O,class:`mt-4 px-4 py-2 bg-accent-green/20 hover:bg-accent-green/30 text-accent-green border border-accent-green/50 rounded-lg transition-colors`},` Retry `)])):m.value.length===0?(w(),C(`div`,Gr,[...n[7]||=[S(`div`,{class:`text-content-muted dark:text-content-muted mb-2`},` 📝 No transport keys found `,-1),S(`div`,{class:`text-content-muted dark:text-content-muted/60 text-sm`},` Add your first transport key to get started `,-1)]])):(w(),C(`div`,Kr,[(w(!0),C(x,null,i(m.value,e=>(w(),l(pn,{key:e.id,node:e,"selected-node-id":s(t).selectedNodeId.value,level:0,onSelect:N},null,8,[`node`,`selected-node-id`]))),128))]))]),v(Pn,{show:r.value,"selected-node-name":M(),"selected-node-id":s(t).selectedNodeId.value||void 0,onClose:R,onAdd:L},null,8,[`show`,`selected-node-name`,`selected-node-id`]),v(sr,{show:a.value,node:d.value,onClose:B,onSave:V,onRequestDelete:H},null,8,[`show`,`node`]),v(jr,{show:c.value,node:f.value,"all-nodes":m.value,onClose:U,onDeleteAll:W,onMoveChildren:G},null,8,[`show`,`node`,`all-nodes`])]))}}),Jr={class:`space-y-4 sm:space-y-6`},Yr={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},Xr={key:0,class:`bg-red-500/10 border border-red-500/30 rounded-lg p-4`},Zr={class:`flex items-center gap-2 text-red-600 dark:text-red-400`},Qr={key:1,class:`flex items-center justify-center py-12`},$r={key:2,class:`space-y-3`},ei={class:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3`},ti={class:`flex-1`},ni={class:`flex items-center gap-2 sm:gap-3`},ri={class:`min-w-0 flex-1`},ii={class:`text-content-primary dark:text-content-primary font-medium text-sm sm:text-base break-all`},ai={class:`flex flex-col sm:flex-row sm:items-center sm:gap-4 mt-1 text-xs text-content-secondary dark:text-content-muted`},oi={class:`truncate`},si={class:`truncate`},ci=[`onClick`,`disabled`],li={key:3,class:`text-center py-12`},ui={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`},di={class:`space-y-4`},fi={class:`flex justify-end gap-3 mt-6`},pi=[`disabled`],mi=[`disabled`],hi={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`},gi={class:`space-y-4`},_i={class:`flex gap-2`},vi=[`value`],yi={class:`bg-blue-500/10 border border-blue-500/30 rounded-lg p-4`},bi={class:`block bg-blue-500/20 px-3 py-2 rounded text-xs text-blue-100 font-mono overflow-x-auto`},xi=f({name:`APITokens`,__name:`APITokens`,setup(e){let t=E([]),n=E(!1),r=E(null),a=E(!1),s=E(``),c=E(null),l=E(!1),f=E(!1),p=E(null),h=async()=>{n.value=!0,r.value=null;try{let e=await A.get(`/auth/tokens`);t.value=(e.data||e).tokens||[]}catch(e){console.error(`Failed to fetch API tokens:`,e),r.value=e instanceof Error?e.message:`Failed to fetch tokens`}finally{n.value=!1}},_=async()=>{if(!s.value.trim()){r.value=`Token name is required`;return}n.value=!0,r.value=null;try{let e=await A.post(`/auth/tokens`,{name:s.value.trim()});c.value=(e.data||e).token||null,a.value=!1,l.value=!0,s.value=``,await h()}catch(e){console.error(`Failed to create API token:`,e),r.value=e instanceof Error?e.message:`Failed to create token`}finally{n.value=!1}},T=(e,t)=>{p.value={id:e,name:t},f.value=!0},D=async()=>{if(p.value){n.value=!0,r.value=null;try{await A.delete(`/auth/tokens/${p.value.id}`),await h(),f.value=!1,p.value=null}catch(e){console.error(`Failed to revoke API token:`,e),r.value=e instanceof Error?e.message:`Failed to revoke token`}finally{n.value=!1}}},O=()=>{a.value=!1,s.value=``,r.value=null},k=()=>{l.value=!1,c.value=null},j=()=>{c.value&&navigator.clipboard.writeText(c.value)},M=e=>e?new Date(e*1e3).toLocaleString():`Never`,P=y(()=>`${window.location.origin}/api/stats`);return o(()=>{h()}),(e,o)=>(w(),C(x,null,[S(`div`,Jr,[S(`div`,Yr,[o[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:o[0]||=e=>a.value=!0,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors flex items-center justify-center gap-2 text-sm sm:text-base`},[...o[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)]])]),o[20]||=d(`<div class="bg-blue-500/10 border border-blue-500/30 rounded-lg p-3 sm:p-4"><div class="flex gap-2 sm:gap-3"><svg class="w-4 h-4 sm:w-5 sm:h-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg><div class="text-xs sm:text-sm text-blue-700 dark:text-blue-200"><p><strong>API tokens</strong> are used for machine-to-machine authentication. Include the token in the <code class="bg-blue-500/20 px-1 rounded">X-API-Key</code> header when making API requests. </p><p class="mt-2">Tokens are only shown once at creation. Store them securely.</p></div></div></div>`,1),r.value?(w(),C(`div`,Xr,[S(`div`,Zr,[o[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(` `+u(r.value),1)])])):g(``,!0),n.value&&t.value.length===0?(w(),C(`div`,Qr,[...o[7]||=[S(`div`,{class:`text-center`},[S(`div`,{class:`animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-primary rounded-full mx-auto mb-4`}),S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading tokens...`)],-1)]])):t.value.length>0?(w(),C(`div`,$r,[(w(!0),C(x,null,i(t.value,e=>(w(),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`,ei,[S(`div`,ti,[S(`div`,ni,[o[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`,ri,[S(`h3`,ii,u(e.name),1),S(`div`,ai,[S(`span`,oi,`Created: `+u(M(e.created_at)),1),S(`span`,si,`Last used: `+u(M(e.last_used)),1)])])])]),S(`button`,{onClick:t=>T(e.id,e.name),disabled:n.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,ci)])]))),128))])):(w(),C(`div`,li,[o[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),o[10]||=S(`h3`,{class:`text-content-primary dark:text-content-primary font-medium mb-2`},`No API Tokens`,-1),o[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:o[1]||=e=>a.value=!0,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors`},` Create Your First Token `)])),a.value?(w(),C(`div`,{key:4,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:I(O,[`self`])},[S(`div`,ui,[o[14]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Create API Token `,-1),S(`div`,di,[S(`div`,null,[o[12]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Token Name`,-1),m(S(`input`,{"onUpdate:modelValue":o[2]||=e=>s.value=e,type:`text`,placeholder:`e.g., Production Server, CI/CD Pipeline`,class:`w-full px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary placeholder-gray-400 dark:placeholder-white/40 focus:outline-none focus:border-primary transition-colors`,onKeydown:L(_,[`enter`])},null,544),[[N,s.value]]),o[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`,fi,[S(`button`,{onClick:O,disabled:n.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,pi),S(`button`,{onClick:_,disabled:n.value||!s.value.trim(),class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors disabled:opacity-50`},u(n.value?`Creating...`:`Create Token`),9,mi)])])])])):g(``,!0),l.value&&c.value?(w(),C(`div`,{key:5,class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm`,onClick:I(k,[`self`])},[S(`div`,hi,[o[19]||=S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary mb-4`},` Token Created Successfully `,-1),S(`div`,gi,[o[18]||=d(`<div class="bg-yellow-500/10 border border-yellow-500/30 rounded-lg p-4"><div class="flex gap-3"><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div class="text-sm text-yellow-200"><strong>Save this token now!</strong> For security reasons, it will not be shown again. </div></div></div>`,1),S(`div`,null,[o[16]||=S(`label`,{class:`block text-sm font-medium text-content-secondary dark:text-content-muted mb-2`},`Your API Token`,-1),S(`div`,_i,[S(`input`,{value:c.value,readonly:``,class:`flex-1 px-4 py-2 bg-background-mute dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary font-mono text-sm`},null,8,vi),S(`button`,{onClick:j,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors flex items-center gap-2`,title:`Copy to clipboard`},[...o[15]||=[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),b(` Copy `,-1)]])])]),S(`div`,yi,[o[17]||=S(`p`,{class:`text-sm text-blue-200 mb-2`},[S(`strong`,null,`Usage Example:`)],-1),S(`code`,bi,` curl -H "X-API-Key: `+u(c.value)+`" `+u(P.value),1)]),S(`div`,{class:`flex justify-end mt-6`},[S(`button`,{onClick:k,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors`},` Done `)])])])])):g(``,!0)]),v(B,{show:f.value,title:`Revoke API Token`,message:`Are you sure you want to revoke the token '${p.value?.name}'? This action cannot be undone.`,"confirm-text":`Revoke`,"cancel-text":`Cancel`,variant:`danger`,onConfirm:D,onClose:o[3]||=e=>f.value=!1},null,8,[`show`,`message`])],64))}}),Si={class:`space-y-6`},Ci={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},wi={class:`space-y-4`},Ti={class:`flex items-center justify-between`},Ei=[`disabled`],Di={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},Oi={class:`space-y-4`},ki={class:`space-y-3`},Ai=[`checked`,`disabled`],ji=[`checked`,`disabled`],Mi={class:`flex items-start gap-3`},Ni={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`},Pi={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`},Fi={class:`flex-1`},Ii={class:`text-sm font-medium text-content-primary dark:text-content-primary`},Li={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-1`},Ri={key:1,class:`p-4 bg-amber-500/10 border border-amber-500/30 rounded-lg`},zi={class:`flex items-start justify-between gap-3`},Bi=[`disabled`],Vi={key:0,class:`animate-spin h-4 w-4`,fill:`none`,viewBox:`0 0 24 24`},Hi={key:1,class:`w-4 h-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},Ui={class:`flex items-center space-x-2`},Wi={key:0,class:`w-5 h-5 text-green-600 dark:text-green-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},Gi={key:1,class:`w-5 h-5 text-red-600 dark:text-red-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`},Ki=f({name:`WebSettings`,__name:`WebSettings`,setup(e){let t=E(!1),n=E(``),r=E(!1),i=E(!1),s=E(!1),c=E(!1),l=E(!0),f=a({cors_enabled:!1,use_default_frontend:!0}),p=y(()=>r.value?`bg-green-500/10 border-green-600/40 dark:border-green-500/30`:`bg-red-500/10 border-red-500/30`);async function m(){try{l.value=!0;let e=await A.get(`/check_pymc_console`);e.success&&e.data&&(c.value=e.data.exists,console.log(`PyMC Console exists:`,c.value))}catch(e){console.error(`Failed to check PyMC Console:`,e),c.value=!1}finally{l.value=!1}}async function h(){try{let e=await A.get(`/stats`);console.log(`WebSettings: Full response:`,e);let t=null;if(e.success&&e.data?t=e.data:e&&`version`in e&&(t=e),t){let e=t.config?.web||{};console.log(`WebSettings: webConfig:`,e),f.cors_enabled=e.cors_enabled===!0,console.log(`WebSettings: Set cors_enabled to:`,f.cors_enabled);let n=e.web_path;f.use_default_frontend=!n||n===``,console.log(`WebSettings: Set use_default_frontend to:`,f.use_default_frontend,`from web_path:`,n)}}catch(e){console.error(`Failed to load web settings:`,e),k(`Failed to load settings`,!1)}}async function v(){t.value=!0,n.value=``;try{let e={web:{cors_enabled:f.cors_enabled}};f.use_default_frontend?e.web.web_path=null:e.web.web_path=`/opt/pymc_console/web/html`;let t=await A.post(`/update_web_config`,e);t.success?(k(`Settings saved successfully`,!0),i.value=!0):k(t.error||`Failed to save settings`,!1)}catch(e){console.error(`Failed to save web settings:`,e),k(e.message||`Failed to save settings`,!1)}finally{t.value=!1}}async function T(){f.cors_enabled=!f.cors_enabled,await v()}async function D(){f.use_default_frontend=!0,await v()}async function O(){f.use_default_frontend=!1,await v()}function k(e,t){n.value=e,r.value=t,setTimeout(()=>{n.value=``},5e3)}async function j(){s.value=!0,n.value=``;try{let e=await A.post(`/restart_service`,{});e.success?(k(`Service restart initiated. Page will reload...`,!0),i.value=!1,setTimeout(()=>{window.location.reload()},2e3)):k(e.error||`Failed to restart service`,!1)}catch(e){e.code===`ERR_NETWORK`||e.message?.includes(`Network error`)?(k(`Service restarting... Page will reload`,!0),i.value=!1,setTimeout(()=>{window.location.reload()},3e3)):(console.error(`Failed to restart service:`,e),k(e.message||`Failed to restart service`,!1))}finally{s.value=!1}}return o(()=>{h(),m()}),(e,a)=>(w(),C(`div`,Si,[S(`div`,Ci,[a[1]||=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`,wi,[S(`div`,Ti,[a[0]||=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:T,disabled:t.value,class:_([`relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2`,f.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`,t.value?`opacity-50 cursor-not-allowed`:`cursor-pointer`])},[S(`span`,{class:_([`inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg`,f.cors_enabled?`translate-x-5`:`translate-x-0.5`])},null,2)],10,Ei)])])]),S(`div`,Di,[a[11]||=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`,Oi,[S(`div`,ki,[S(`label`,{class:_([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all`,f.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:f.use_default_frontend,onChange:D,disabled:t.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,Ai),a[2]||=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 pyMC 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:_([`flex items-start space-x-3 p-4 bg-background-mute dark:bg-background/30 rounded-lg border-2 cursor-pointer transition-all`,f.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:!f.use_default_frontend,onChange:O,disabled:t.value,class:`mt-1 h-4 w-4 text-accent-cyan focus:ring-accent-cyan focus:ring-offset-background`},null,40,ji),a[3]||=d(`<div class="flex-1"><div class="flex items-center justify-between"><div class="text-sm font-medium text-content-primary dark:text-content-primary"> PyMC Console </div><span class="text-xs bg-orange-100 dark:bg-orange-500/20 text-orange-600 dark:text-orange-400 px-2 py-0.5 rounded-full border border-orange-500/30 font-medium">@Treehouse⚡</span></div><div class="text-xs text-content-secondary dark:text-content-muted mt-1"> Alternative web interface for pyMC Repeater </div><div class="text-xs text-content-muted dark:text-content-muted/60 mt-1 font-mono"> /opt/pymc_console/web/html </div></div>`,1)],2)]),l.value?g(``,!0):(w(),C(`div`,{key:0,class:_([`p-4 rounded-lg border`,c.value?`bg-green-500/5 border-green-500/20`:`bg-accent-cyan/5 border-accent-cyan/20`])},[S(`div`,Mi,[c.value?(w(),C(`svg`,Ni,[...a[4]||=[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)]])):(w(),C(`svg`,Pi,[...a[5]||=[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`,Fi,[S(`h4`,Ii,u(c.value?`PyMC Console has been detected`:`PyMC Console Not Installed`),1),c.value?(w(),C(`p`,Li,[...a[6]||=[b(` PyMC Console is installed at `,-1),S(`code`,{class:`text-green-700 dark:text-green-300`},`/opt/pymc_console/web/html`,-1)]])):(w(),C(x,{key:1},[a[7]||=d(`<p class="text-xs text-content-secondary dark:text-content-muted mt-1 mb-3"> PyMC Console must be installed at <code class="text-accent-cyan">/opt/pymc_console/web/html</code> before selecting this option. </p><a href="https://github.com/dmduran12/pymc_console-dist" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 px-4 py-2 bg-accent-cyan/20 hover:bg-accent-cyan/30 border border-accent-cyan/50 text-accent-cyan rounded-lg text-sm font-medium transition-colors"><svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg> PyMC Console Install Instructions </a>`,2)],64))])])],2)),i.value?(w(),C(`div`,Ri,[S(`div`,zi,[a[10]||=d(`<div class="flex items-start space-x-3 flex-1"><svg class="w-5 h-5 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><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-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div class="flex-1"><h4 class="text-sm font-medium text-amber-600 dark:text-amber-400"> Service restart required </h4><p class="text-xs text-amber-700 dark:text-amber-400/80 mt-1"> Web frontend changes will take effect after restarting the pymc-repeater service. </p></div></div>`,1),S(`button`,{onClick:j,disabled:s.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`},[s.value?(w(),C(`svg`,Vi,[...a[8]||=[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)]])):(w(),C(`svg`,Hi,[...a[9]||=[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(` `+u(s.value?`Restarting...`:`Restart Now`),1)],8,Bi)])])):g(``,!0)])]),n.value?(w(),C(`div`,{key:0,class:_([`p-4 rounded-lg border`,p.value])},[S(`div`,Ui,[r.value?(w(),C(`svg`,Wi,[...a[12]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 13l4 4L19 7`},null,-1)]])):(w(),C(`svg`,Gi,[...a[13]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`},null,-1)]])),S(`span`,{class:_(r.value?`text-green-600 dark:text-green-400`:`text-red-600 dark:text-red-400`)},u(n.value),3)])],2)):g(``,!0)]))}}),qi={class:`space-y-4`},Ji={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`},Yi={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`},Xi={class:`flex justify-between items-center`},Zi={class:`flex gap-2`},Qi=[`disabled`],$i={class:`flex gap-2`},ea=[`disabled`],ta=[`disabled`],na={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},ra={key:0,class:`flex items-center justify-center py-4`},ia={key:1,class:`text-center py-4`},aa={class:`grid grid-cols-2 sm:grid-cols-4 gap-3`},oa={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},sa={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},ca={class:`text-lg font-mono text-content-primary dark:text-content-primary`},la={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},ua={class:`text-lg font-mono text-green-600 dark:text-green-400`},da={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},fa={class:`text-lg font-mono text-red-600 dark:text-red-400`},pa={key:0,class:`mt-2 p-2 bg-red-50 dark:bg-red-500/10 rounded-lg border border-red-200 dark:border-red-500/30`},ma={key:1,class:`mt-2 p-2 bg-orange-50 dark:bg-orange-500/10 rounded-lg border border-orange-200 dark:border-orange-500/30`},ha={class:`font-medium`},ga={class:`font-mono text-[10px] opacity-70`},_a={class:`text-[10px]`},va={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},ya={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`},ba={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},xa={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`},Sa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ca={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`},wa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ta={key:1,class:`flex items-center gap-2`},Ea={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Da={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Oa={key:1,class:`flex items-center gap-2`},ka={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},Aa={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`},ja={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ma={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`},Na={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Pa={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`},Fa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ia={key:1,class:`flex items-center gap-2`},La={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`},Ra={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},za={key:1,class:`flex items-center gap-2`},Ba={class:`flex flex-col sm:flex-row sm:justify-between sm:items-center py-2 gap-1`},Va={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ha={key:1,class:`flex items-center gap-2`},Ua={class:`bg-background-mute dark:bg-white/5 rounded-lg p-3 sm:p-4 space-y-3`},Wa={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`},Ga={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ka={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`},qa={key:0,class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ja={key:1,class:`flex items-center gap-2`},Ya={class:`py-2`},Xa={class:`grid grid-cols-3 gap-2 mt-2`},Za={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},Qa={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},$a={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},eo={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},to={class:`text-center p-2 bg-white dark:bg-white/5 rounded-lg`},no={key:0,class:`font-mono text-sm text-content-primary dark:text-content-primary`},ro={class:`p-6 space-y-4`},io={class:`flex justify-between items-start`},ao={class:`flex justify-end pt-4 border-t border-stroke-subtle dark:border-stroke/20`},oo=f({__name:`AdvertSettings`,setup(e){let t=j(),n=y(()=>t.stats?.config?.repeater||{}),r=y(()=>n.value.advert_rate_limit||{}),a=y(()=>n.value.advert_penalty_box||{}),s=y(()=>n.value.advert_adaptive||{}),l=y(()=>s.value.thresholds||{}),f=E(!1),p=E(!1),v=E(``),T=E(``),D=E(!1),O=E(!1),A=E(null),M=E(!0),P=E(2),F=E(1),L=E(10),R=E(60),B=E(!0),V=E(2),H=E(12),U=E(6),W=E(2),G=E(24),ee=E(!0),te=E(.1),ne=E(5),re=E(.05),K=E(.2),q=E(.5),J=async()=>{O.value=!0;try{let e=await k.get(`/api/advert_rate_limit_stats`);e.data?.success&&(A.value=e.data.data)}catch(e){console.error(`Failed to fetch rate limit stats:`,e)}finally{O.value=!1}};h([r,a,s],()=>{f.value||(M.value=r.value.enabled??!1,P.value=r.value.bucket_capacity??2,F.value=r.value.refill_tokens??1,L.value=Math.round((r.value.refill_interval_seconds??36e3)/3600),R.value=Math.round((r.value.min_interval_seconds??0)/60),B.value=a.value.enabled??!1,V.value=a.value.violation_threshold??2,H.value=Math.round((a.value.violation_decay_seconds??43200)/3600),U.value=Math.round((a.value.base_penalty_seconds??21600)/3600),W.value=a.value.penalty_multiplier??2,G.value=Math.round((a.value.max_penalty_seconds??86400)/3600),ee.value=s.value.enabled??!1,te.value=s.value.ewma_alpha??.1,ne.value=Math.round((s.value.hysteresis_seconds??300)/60),re.value=l.value.quiet_max??.05,K.value=l.value.normal_max??.2,q.value=l.value.busy_max??.5)},{immediate:!0}),o(()=>{J()});let Y=()=>{M.value=r.value.enabled??!1,P.value=r.value.bucket_capacity??2,F.value=r.value.refill_tokens??1,L.value=Math.round((r.value.refill_interval_seconds??36e3)/3600),R.value=Math.round((r.value.min_interval_seconds??0)/60),B.value=a.value.enabled??!1,V.value=a.value.violation_threshold??2,H.value=Math.round((a.value.violation_decay_seconds??43200)/3600),U.value=Math.round((a.value.base_penalty_seconds??21600)/3600),W.value=a.value.penalty_multiplier??2,G.value=Math.round((a.value.max_penalty_seconds??86400)/3600),ee.value=s.value.enabled??!1,te.value=s.value.ewma_alpha??.1,ne.value=Math.round((s.value.hysteresis_seconds??300)/60),re.value=l.value.quiet_max??.05,K.value=l.value.normal_max??.2,q.value=l.value.busy_max??.5},X=()=>{f.value=!0,v.value=``,T.value=``},Z=()=>{f.value=!1,v.value=``,T.value=``,Y()},Q=async()=>{p.value=!0,T.value=``,v.value=``;try{let e={rate_limit_enabled:M.value,bucket_capacity:P.value,refill_tokens:F.value,refill_interval_seconds:L.value*3600,min_interval_seconds:R.value*60,penalty_enabled:B.value,violation_threshold:V.value,violation_decay_seconds:H.value*3600,base_penalty_seconds:U.value*3600,penalty_multiplier:W.value,max_penalty_seconds:G.value*3600,adaptive_enabled:ee.value,ewma_alpha:te.value,hysteresis_seconds:ne.value*60,quiet_max:re.value,normal_max:K.value,busy_max:q.value},n=(await k.post(`/api/update_advert_rate_limit_config`,e)).data;n.success?(v.value=n.data?.message||`Settings saved successfully`,await t.fetchStats(),await J(),await c(),Y(),f.value=!1,setTimeout(()=>{v.value=``},3e3)):(T.value=n.error||`Failed to save settings`,console.error(`[AdvertSettings] Save failed:`,n.error))}catch(e){console.error(`Failed to save advert settings:`,e),T.value=e.response?.data?.error||`Failed to save settings`}finally{p.value=!1}},$=y(()=>A.value?.adaptive?.current_tier||`unknown`),ie=y(()=>{switch($.value){case`quiet`:return`bg-green-100 dark:bg-green-500/20 text-green-700 dark:text-green-400 border-green-500`;case`normal`:return`bg-blue-100 dark:bg-blue-500/20 text-blue-700 dark:text-blue-400 border-blue-500`;case`busy`:return`bg-yellow-100 dark:bg-yellow-500/20 text-yellow-700 dark:text-yellow-400 border-yellow-500`;case`congested`:return`bg-red-100 dark:bg-red-500/20 text-red-700 dark:text-red-400 border-red-500`;default:return`bg-gray-100 dark:bg-gray-500/20 text-gray-700 dark:text-gray-400 border-gray-500`}});return(e,t)=>(w(),C(`div`,qi,[v.value?(w(),C(`div`,Ji,u(v.value),1)):g(``,!0),T.value?(w(),C(`div`,Yi,u(T.value),1)):g(``,!0),S(`div`,Xi,[S(`div`,Zi,[S(`button`,{onClick:J,disabled:O.value,class:`px-3 py-1.5 text-xs bg-background-mute dark:bg-white/5 hover:bg-stroke-subtle dark:hover:bg-white/10 text-content-secondary dark:text-content-muted rounded-lg border border-stroke-subtle dark:border-stroke/20 transition-colors disabled:opacity-50`},u(O.value?`Loading...`:`Refresh Stats`),9,Qi),S(`button`,{onClick:t[0]||=e=>D.value=!0,class:`px-3 py-1.5 text-xs bg-blue-100 dark:bg-blue-500/20 hover:bg-blue-200 dark:hover:bg-blue-500/30 text-blue-700 dark:text-blue-400 rounded-lg border border-blue-500/50 transition-colors`,title:`How rate limiting works`},[...t[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)]])]),S(`div`,$i,[f.value?(w(),C(x,{key:1},[S(`button`,{onClick:Z,disabled:p.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,ea),S(`button`,{onClick:Q,disabled:p.value,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm disabled:opacity-50 disabled:cursor-not-allowed`},u(p.value?`Saving...`:`Save Changes`),9,ta)],64)):(w(),C(`button`,{key:0,onClick:X,class:`px-3 sm:px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors text-sm`},` Edit Settings `))])]),S(`div`,na,[t[28]||=S(`h3`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Current Status `,-1),O.value&&!A.value?(w(),C(`div`,ra,[...t[20]||=[S(`div`,{class:`animate-spin w-5 h-5 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full`},null,-1),S(`span`,{class:`ml-2 text-sm text-content-muted`},`Loading stats...`,-1)]])):A.value?(w(),C(x,{key:2},[S(`div`,aa,[S(`div`,oa,[t[22]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Mesh Tier`,-1),S(`div`,{class:_([`mt-1 px-2 py-0.5 rounded border text-xs font-medium inline-block`,ie.value])},u($.value.toUpperCase()),3)]),S(`div`,sa,[t[23]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Adverts/min`,-1),S(`div`,ca,u(A.value.metrics?.adverts_per_min_ewma?.toFixed(2)||`0.00`),1)]),S(`div`,la,[t[24]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Allowed`,-1),S(`div`,ua,u(A.value.stats?.adverts_allowed||0),1)]),S(`div`,da,[t[25]||=S(`div`,{class:`text-xs text-content-muted dark:text-content-muted`},`Dropped`,-1),S(`div`,fa,u(A.value.stats?.adverts_dropped||0),1)])]),Object.keys(A.value.active_penalties||{}).length>0?(w(),C(`div`,pa,[t[26]||=S(`div`,{class:`text-xs font-medium text-red-700 dark:text-red-400 mb-1`},` Active Penalties `,-1),(w(!0),C(x,null,i(A.value.active_penalties,(e,t)=>(w(),C(`div`,{key:t,class:`text-xs font-mono text-red-600 dark:text-red-400`},u(t)+`... - `+u(Math.round(e))+`s remaining `,1))),128))])):g(``,!0),A.value.recent_drops&&A.value.recent_drops.length>0?(w(),C(`div`,ma,[t[27]||=S(`div`,{class:`text-xs font-medium text-orange-700 dark:text-orange-400 mb-1`},` Recently Dropped Adverts `,-1),(w(!0),C(x,null,i(A.value.recent_drops,(e,t)=>(w(),C(`div`,{key:t,class:`text-xs text-orange-600 dark:text-orange-400 py-0.5`},[S(`span`,ha,u(e.name),1),S(`span`,ga,`(`+u(e.pubkey)+`...)`,1),S(`span`,_a,` - `+u(e.reason)+` (`+u(e.seconds_ago)+`s ago)`,1)]))),128))])):g(``,!0)],64)):(w(),C(`div`,ia,[...t[21]||=[S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Stats not available. Click "Refresh Stats" to load. `,-1)]]))]),S(`div`,va,[t[36]||=S(`h3`,{class:`text-sm font-medium 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),t[37]||=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`,ya,[t[30]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Rate Limiting`,-1),f.value?m((w(),C(`select`,{key:1,"onUpdate:modelValue":t[1]||=e=>M.value=e,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[29]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[z,M.value]]):(w(),C(`div`,ba,u(M.value?`Enabled`:`Disabled`),1))]),S(`div`,xa,[t[31]||=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),f.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[2]||=e=>P.value=e,type:`number`,min:`1`,max:`10`,class:`w-full sm:w-24 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,P.value,void 0,{number:!0}]]):(w(),C(`div`,Sa,u(P.value),1))]),S(`div`,Ca,[t[33]||=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),f.value?(w(),C(`div`,Ta,[m(S(`input`,{"onUpdate:modelValue":t[3]||=e=>L.value=e,type:`number`,min:`1`,max:`48`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,L.value,void 0,{number:!0}]]),t[32]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(w(),C(`div`,wa,u(L.value)+` hours `,1))]),S(`div`,Ea,[t[35]||=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),f.value?(w(),C(`div`,Oa,[m(S(`input`,{"onUpdate:modelValue":t[4]||=e=>R.value=e,type:`number`,min:`0`,max:`1440`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,R.value,void 0,{number:!0}]]),t[34]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(w(),C(`div`,Da,u(R.value)+` min `,1))])]),S(`div`,ka,[t[47]||=S(`h3`,{class:`text-sm font-medium 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),t[48]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted`},` Applies escalating cooldowns to pubkeys that repeatedly violate limits. `,-1),S(`div`,Aa,[t[39]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Penalty Box`,-1),f.value?m((w(),C(`select`,{key:1,"onUpdate:modelValue":t[5]||=e=>B.value=e,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[38]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[z,B.value]]):(w(),C(`div`,ja,u(B.value?`Enabled`:`Disabled`),1))]),S(`div`,Ma,[t[40]||=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),f.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[6]||=e=>V.value=e,type:`number`,min:`1`,max:`10`,class:`w-full sm:w-24 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512)),[[N,V.value,void 0,{number:!0}]]):(w(),C(`div`,Na,u(V.value),1))]),S(`div`,Pa,[t[42]||=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),f.value?(w(),C(`div`,Ia,[m(S(`input`,{"onUpdate:modelValue":t[7]||=e=>U.value=e,type:`number`,min:`1`,max:`48`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,U.value,void 0,{number:!0}]]),t[41]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(w(),C(`div`,Fa,u(U.value)+` hours `,1))]),S(`div`,La,[t[44]||=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),f.value?(w(),C(`div`,za,[m(S(`input`,{"onUpdate:modelValue":t[8]||=e=>W.value=e,type:`number`,min:`1`,max:`5`,step:`0.5`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,W.value,void 0,{number:!0}]]),t[43]||=S(`span`,{class:`text-content-muted text-sm`},`x`,-1)])):(w(),C(`div`,Ra,u(W.value)+`x `,1))]),S(`div`,Ba,[t[46]||=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),f.value?(w(),C(`div`,Ha,[m(S(`input`,{"onUpdate:modelValue":t[9]||=e=>G.value=e,type:`number`,min:`1`,max:`168`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,G.value,void 0,{number:!0}]]),t[45]||=S(`span`,{class:`text-content-muted text-sm`},`hours`,-1)])):(w(),C(`div`,Va,u(G.value)+` hours `,1))])]),S(`div`,Ua,[t[58]||=d(`<h3 class="text-sm font-medium text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg> Adaptive Rate Limiting </h3><div class="p-3 bg-cyan-50 dark:bg-cyan-500/10 border border-cyan-200 dark:border-cyan-500/30 rounded-lg"><p class="text-xs text-cyan-700 dark:text-cyan-300 leading-relaxed"><strong>How the three systems work together:</strong> Each layer can be enabled/disabled independently and the others will still function. </p><ul class="text-xs text-cyan-700 dark:text-cyan-300 mt-2 space-y-1 ml-4 list-disc"><li><strong>Rate Limiting OFF:</strong> All limiting disabled — adverts pass through freely </li><li><strong>Adaptive OFF:</strong> Token bucket uses fixed limits (no tier scaling), penalty box still works </li><li><strong>Penalty Box OFF:</strong> Token bucket still applies, but no escalating cooldowns for repeat offenders </li></ul><p class="text-xs text-cyan-700 dark:text-cyan-300 mt-2"><strong>Decision flow when all enabled:</strong> Adaptive tier check → Penalty box check → Token bucket check → Violation recording (triggers penalty box) </p><p class="text-xs text-cyan-700 dark:text-cyan-300 mt-1"><strong>Activity tiers:</strong><span class="text-green-600 dark:text-green-400 font-medium">Quiet</span> (bypass limiting) → <span class="text-blue-600 dark:text-blue-400 font-medium">Normal</span> (lighter: 0.5x intervals) → <span class="text-yellow-600 dark:text-yellow-400 font-medium">Busy</span> (base: 1.0x intervals) → <span class="text-red-600 dark:text-red-400 font-medium">Congested</span> (stricter: 2.0x intervals) </p><p class="text-xs text-cyan-700 dark:text-cyan-300 mt-1"><strong>Note:</strong> Adaptive mode scales refill/min-interval timing; bucket capacity stays at the configured base value. </p></div>`,2),S(`div`,Wa,[t[50]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs sm:text-sm`},`Adaptive Mode`,-1),f.value?m((w(),C(`select`,{key:1,"onUpdate:modelValue":t[10]||=e=>ee.value=e,class:`w-full sm:w-32 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},[...t[49]||=[S(`option`,{value:!0},`Enabled`,-1),S(`option`,{value:!1},`Disabled`,-1)]],512)),[[z,ee.value]]):(w(),C(`div`,Ga,u(ee.value?`Enabled`:`Disabled`),1))]),S(`div`,Ka,[t[52]||=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),f.value?(w(),C(`div`,Ja,[m(S(`input`,{"onUpdate:modelValue":t[11]||=e=>ne.value=e,type:`number`,min:`0`,max:`60`,class:`w-20 px-3 py-1.5 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg text-content-primary dark:text-content-primary text-sm focus:outline-none focus:border-primary`},null,512),[[N,ne.value,void 0,{number:!0}]]),t[51]||=S(`span`,{class:`text-content-muted text-sm`},`min`,-1)])):(w(),C(`div`,qa,u(ne.value)+` min `,1))]),S(`div`,Ya,[t[56]||=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`,Xa,[S(`div`,Za,[t[53]||=S(`div`,{class:`text-xs text-green-600 dark:text-green-400 mb-1`},`Quiet Max`,-1),f.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[12]||=e=>re.value=e,type:`number`,min:`0`,max:`1`,step:`0.01`,class:`w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary`},null,512)),[[N,re.value,void 0,{number:!0}]]):(w(),C(`div`,Qa,u(re.value),1))]),S(`div`,$a,[t[54]||=S(`div`,{class:`text-xs text-blue-600 dark:text-blue-400 mb-1`},`Normal Max`,-1),f.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[13]||=e=>K.value=e,type:`number`,min:`0`,max:`5`,step:`0.01`,class:`w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary`},null,512)),[[N,K.value,void 0,{number:!0}]]):(w(),C(`div`,eo,u(K.value),1))]),S(`div`,to,[t[55]||=S(`div`,{class:`text-xs text-yellow-600 dark:text-yellow-400 mb-1`},`Busy Max`,-1),f.value?m((w(),C(`input`,{key:1,"onUpdate:modelValue":t[14]||=e=>q.value=e,type:`number`,min:`0`,max:`10`,step:`0.01`,class:`w-full px-2 py-1 bg-white dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded text-content-primary dark:text-content-primary text-sm text-center focus:outline-none focus:border-primary`},null,512)),[[N,q.value,void 0,{number:!0}]]):(w(),C(`div`,no,u(q.value),1))])]),t[57]||=S(`p`,{class:`text-xs text-content-muted dark:text-content-muted mt-2`},` Above Busy Max = Congested tier (strictest limiting) `,-1)])]),D.value?(w(),C(`div`,{key:2,class:`fixed inset-0 bg-black/50 flex items-start justify-center z-50 p-4 overflow-y-auto`,onClick:t[18]||=I(e=>D.value=!1,[`self`])},[S(`div`,{class:`bg-background dark:bg-background-dark rounded-lg shadow-xl max-w-3xl w-full my-8`,onClick:t[17]||=I(()=>{},[`stop`])},[S(`div`,ro,[S(`div`,io,[t[60]||=S(`h2`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` How Advert Rate Limiting Works `,-1),S(`button`,{onClick:t[15]||=e=>D.value=!1,class:`text-content-muted hover:text-content-primary dark:text-content-muted dark:hover:text-content-primary`},[...t[59]||=[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)]])]),t[61]||=d(`<div class="bg-blue-50 dark:bg-blue-500/10 rounded-lg p-4 border border-blue-200 dark:border-blue-500/30"><h3 class="font-semibold text-blue-900 dark:text-blue-400 mb-2"> Why you may see the same advert more than once </h3><p class="text-sm text-blue-800 dark:text-blue-300 leading-relaxed"> Mesh traffic can reach your repeater through different paths, so duplicate advert packets are expected. </p><ul class="text-sm text-blue-800 dark:text-blue-300 mt-2 space-y-1 list-disc list-inside"><li>First copy arrives and is forwarded</li><li>Second copy arrives through another repeater path</li><li>Later copies may be dropped once limits are hit</li></ul><p class="text-sm text-blue-800 dark:text-blue-300 mt-2"> This is normal behavior and helps prevent repeated rebroadcasts from flooding the mesh. </p></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg> Token Bucket Rate Limiting </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> Each sender has a token bucket. Every forwarded advert uses one token. </p><ul class="text-sm text-content-secondary dark:text-content-muted space-y-1 list-disc list-inside ml-4"><li><strong>Bucket Capacity:</strong> How many adverts can pass in a burst.</li><li><strong>Refill Rate:</strong> How quickly tokens come back over time.</li><li><strong>Min Interval:</strong> Optional gap between adverts from the same sender (usually set to 0). </li></ul><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded text-xs font-mono text-content-muted dark:text-content-muted"> Example (capacity 2):<br> - Copy 1 forwarded (2 → 1 tokens)<br> - Copy 2 forwarded (1 → 0 tokens)<br> - Copy 3 dropped (no tokens left) </div></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg> Penalty Box (Repeat Offenders) </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> If a sender keeps hitting the limit, it is temporarily blocked. </p><ul class="text-sm text-content-secondary dark:text-content-muted space-y-1 list-disc list-inside ml-4"><li><strong>Violation Threshold:</strong> How many hits before penalty starts.</li><li><strong>Base Penalty:</strong> First block duration.</li><li><strong>Multiplier:</strong> Repeated penalties get longer.</li><li><strong>Decay Time:</strong> Violations age out after stable behavior.</li></ul></div><div class="space-y-2"><h3 class="font-semibold text-content-primary dark:text-content-primary flex items-center gap-2"><svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg> Adaptive Mesh Activity Tiers </h3><p class="text-sm text-content-secondary dark:text-content-muted leading-relaxed"> Adaptive mode adjusts limits based on recent advert activity. </p><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded-lg text-sm text-content-secondary dark:text-content-muted"><span class="font-semibold">How Congestion is Measured:</span><ul class="mt-1 space-y-1 list-disc list-inside ml-2"><li><strong>What is counted:</strong> Advert packets only (not chat/data traffic) </li><li><strong>Smoothing:</strong> 60-second EWMA to avoid reacting to short spikes </li><li><strong>Score:</strong> Tier is based on adverts per minute</li><li><strong>Hysteresis:</strong> Tier changes must hold for 5 minutes</li></ul></div><div class="grid grid-cols-2 gap-2 mt-2"><div class="p-2 bg-green-50 dark:bg-green-500/10 rounded border border-green-500/30"><div class="text-xs font-semibold text-green-700 dark:text-green-400">QUIET</div><div class="text-xs text-green-600 dark:text-green-500">Activity < 0.05/min</div><div class="text-xs text-green-700 dark:text-green-400 font-medium mt-1"> No rate limiting </div></div><div class="p-2 bg-blue-50 dark:bg-blue-500/10 rounded border border-blue-500/30"><div class="text-xs font-semibold text-blue-700 dark:text-blue-400">NORMAL</div><div class="text-xs text-blue-600 dark:text-blue-500">Activity 0.05-0.20/min</div><div class="text-xs text-blue-700 dark:text-blue-400 font-medium mt-1"> Light limiting (50%) </div></div><div class="p-2 bg-yellow-50 dark:bg-yellow-500/10 rounded border border-yellow-500/30"><div class="text-xs font-semibold text-yellow-700 dark:text-yellow-400">BUSY</div><div class="text-xs text-yellow-600 dark:text-yellow-500"> Activity 0.20-0.50/min </div><div class="text-xs text-yellow-700 dark:text-yellow-400 font-medium mt-1"> Standard limiting (100%) </div></div><div class="p-2 bg-red-50 dark:bg-red-500/10 rounded border border-red-500/30"><div class="text-xs font-semibold text-red-700 dark:text-red-400">CONGESTED</div><div class="text-xs text-red-600 dark:text-red-500">Activity > 0.50/min</div><div class="text-xs text-red-700 dark:text-red-400 font-medium mt-1"> Aggressive (200%) </div></div></div><div class="mt-2 p-3 bg-background-mute dark:bg-white/5 rounded text-xs font-mono text-content-muted dark:text-content-muted"> Quick examples:<br> - 0.02 adverts/min → <span class="text-green-600 dark:text-green-400 font-semibold">QUIET</span> (bypass)<br> - 0.35 adverts/min → <span class="text-yellow-600 dark:text-yellow-400 font-semibold">BUSY</span> (tighter limits)<br> - 0.68 adverts/min → <span class="text-red-600 dark:text-red-400 font-semibold">CONGESTED</span> (strict limits) </div></div><div class="bg-green-50 dark:bg-green-500/10 rounded-lg p-4 border border-green-200 dark:border-green-500/30"><h3 class="font-semibold text-green-900 dark:text-green-400 mb-2"> Recommended starting settings </h3><ul class="text-sm text-green-800 dark:text-green-300 space-y-1 list-disc list-inside"><li><strong>Min Interval:</strong> 0 (disabled), let adaptive mode do the work</li><li><strong>Bucket Capacity:</strong> 2-3 tokens for normal mesh propagation</li><li><strong>Adaptive Mode:</strong> On</li><li><strong>Penalty Box:</strong> On</li></ul></div>`,5),S(`div`,ao,[S(`button`,{onClick:t[16]||=e=>D.value=!1,class:`px-4 py-2 bg-primary/20 hover:bg-primary/30 text-content-primary dark:text-content-primary rounded-lg border border-primary/50 transition-colors`},` Got it! `)])])])])):g(``,!0)]))}}),so={class:`space-y-6`},co={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},lo={class:`flex items-center justify-between mb-4`},uo=[`disabled`],fo={key:0},po={key:1},mo={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},ho={key:1,class:`space-y-3`},go={class:`flex items-center gap-2`},_o={key:0,class:`space-y-2`},vo=[`title`],yo={key:1,class:`text-sm text-content-muted dark:text-content-muted/60 italic`},bo={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},xo={class:`flex items-start justify-between mb-6`},So={key:0,class:`space-y-4`},Co={class:`grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3`},wo={class:`mt-1 text-sm text-content-primary dark:text-content-primary`},To={class:`mt-1 text-sm text-content-primary dark:text-content-primary font-mono`},Eo={class:`mt-1 text-sm text-content-primary dark:text-content-primary`},Do={class:`mt-1 text-sm text-content-primary dark:text-content-primary`},Oo={class:`mt-1 text-sm text-content-primary dark:text-content-primary`},ko={class:`mt-1 text-sm text-content-primary dark:text-content-primary`},Ao={key:0,class:`mt-2 text-sm text-content-muted dark:text-content-muted/60 italic`},jo={key:1,class:`mt-2 space-y-1.5`},Mo={class:`min-w-0 flex-1`},No={class:`text-sm font-medium text-content-primary dark:text-content-primary`},Po={class:`text-xs text-content-secondary dark:text-content-muted ml-2 font-mono`},Fo=[`title`],Io={class:`mt-2 flex flex-wrap gap-1.5`},Lo={key:0,class:`text-sm text-content-muted dark:text-content-muted/60 italic`},Ro={key:1,class:`space-y-5`},zo={class:`flex items-center justify-between p-4 rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10`},Bo={class:`grid grid-cols-1 sm:grid-cols-2 gap-4`},Vo=[`value`],Ho={class:`grid grid-cols-1 sm:grid-cols-2 gap-4`},Uo={class:`flex items-start justify-between mb-3 gap-3`},Wo={class:`flex items-center gap-2 flex-shrink-0`},Go={class:`relative`},Ko={key:0,class:`absolute right-0 top-full mt-1 z-20 w-64 rounded-lg shadow-lg border border-stroke-subtle dark:border-stroke/20 bg-white dark:bg-[var(--color-surface)] overflow-hidden`},qo={class:`py-1`},Jo=[`onClick`],Yo={class:`min-w-0 flex-1`},Xo={class:`text-sm font-medium text-content-primary dark:text-content-primary group-hover:text-cyan-700 dark:group-hover:text-primary transition-colors`},Zo={class:`text-xs text-content-secondary dark:text-content-muted`},Qo=[`href`],$o={key:0,class:`flex flex-col items-center justify-center py-7 rounded-lg border-2 border-dashed border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted`},es={key:1,class:`space-y-2`},ts={key:0,class:`flex items-center gap-3 px-4 py-2.5`},ns={class:`min-w-0 flex-1`},rs={class:`text-sm font-medium text-content-primary dark:text-content-primary`},is={class:`text-xs font-mono text-content-secondary dark:text-content-muted ml-2`},as={key:0,class:`ml-2 text-xs text-red-500 dark:text-red-400`},os={class:`flex items-center gap-0.5 flex-shrink-0`},ss=[`onClick`],cs=[`onClick`],ls={key:1,class:`p-4 space-y-3 bg-background-mute/60 dark:bg-background/20`},us={class:`grid grid-cols-1 sm:grid-cols-2 gap-3`},ds={class:`flex items-center gap-2 pt-1`},fs=[`disabled`],ps=[`onClick`],ms={class:`flex flex-wrap gap-2`},hs=[`onClick`],gs={key:0,class:`p-3 rounded-lg bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-700/30 text-green-700 dark:text-green-400 text-sm`},_s={key:1,class:`p-3 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700/30 text-red-700 dark:text-red-400 text-sm`},vs={class:`flex items-center gap-3 pt-2`},ys=[`disabled`],bs={key:0},xs={key:1},Ss=[`disabled`],Cs=M(f({__name:`LetsMeshSettings`,setup(e){let n=j(),r=y(()=>n.stats?.config?.letsmesh||{}),a=[`REQ`,`RESPONSE`,`TXT_MSG`,`ACK`,`ADVERT`,`GRP_TXT`,`GRP_DATA`,`ANON_REQ`,`PATH`,`TRACE`,`RAW_CUSTOM`],s=[{value:0,label:`Letsmesh Europe only (EU v1)`},{value:1,label:`Letsmesh US West only (US v1)`},{value:-1,label:`All built-in brokers (EU + US)`},{value:-2,label:`Custom brokers only`}],c=[{name:`waev.app`,website:`https://waev.app`,brokers:[{name:`waev.app (Primary)`,host:`mqtt-a.waev.app`,port:443,audience:`mqtt.waev.app`},{name:`waev.app (Secondary)`,host:`mqtt-b.waev.app`,port:443,audience:`mqtt.waev.app`}]},{name:`MeshMapper`,website:`https://meshmapper.net`,brokers:[{name:`MeshMapper`,host:`mqtt.meshmapper.cc`,port:443,audience:`mqtt.meshmapper.cc`}]}],l=E(!1),d=E(!1),f=E(``),p=E(``),T=E(!1),D=E(``),O=E(0),A=E(300),M=E(``),P=E(``),F=E([]),L=E([]),B=E(null),V=E({_id:0,name:``,host:``,port:443,audience:``}),H=E(!1);function U(e){H.value=!1,B.value!==null&&K(),e.brokers.forEach(e=>{let t=G(e);L.value.push(t)})}let W=1;function G(e={}){return{_id:W++,name:e.name??``,host:e.host??``,port:e.port??443,audience:e.audience??``}}function ee(){let e=G();L.value.push(e),V.value={...e},B.value=e._id}function te(e){L.value=L.value.filter(t=>t._id!==e),B.value===e&&(B.value=null)}function ne(e){V.value={...e},B.value=e._id}function re(){B.value=null}function K(){let e=V.value;if(!e.name.trim()||!e.host.trim()||!e.audience.trim())return;let t=L.value.findIndex(t=>t._id===e._id);t!==-1&&L.value.splice(t,1,{...e}),B.value=null}function q(){let e=V.value,t=L.value.find(t=>t._id===e._id);(!e.audience||e.audience===(t?.host??``))&&(e.audience=e.host)}let J=y(()=>{let e={};return L.value.forEach(t=>{t.name.trim()?t.host.trim()?t.audience.trim()?(t.port<1||t.port>65535)&&(e[t._id]=`Port must be 1–65535`):e[t._id]=`Audience required`:e[t._id]=`Host required`:e[t._id]=`Name required`}),e}),Y=y(()=>Object.keys(J.value).length>0),X=E(null),Z=E(!1);async function Q(){Z.value=!0;try{let e=await k.get(`/api/letsmesh_status`);e.data?.success&&(X.value=e.data.data)}catch{}finally{Z.value=!1}}function $(){let e=r.value;T.value=e.enabled??!1,D.value=e.iata_code??``,O.value=e.broker_index??0,A.value=e.status_interval??300,M.value=e.owner??``,P.value=e.email??``,F.value=Array.isArray(e.disallowed_packet_types)?[...e.disallowed_packet_types]:[],L.value=Array.isArray(e.additional_brokers)?e.additional_brokers.map(e=>G(e)):[]}h(r,()=>{l.value||$()},{immediate:!0});function ie(){$(),B.value=null,l.value=!0,f.value=``,p.value=``}function ae(){B.value=null,l.value=!1,f.value=``,p.value=``}function oe(e){let t=F.value.indexOf(e);t===-1?F.value.push(e):F.value.splice(t,1)}async function se(){if(B.value!==null&&K(),Y.value){p.value=`Please fix broker errors before saving.`;return}d.value=!0,p.value=``,f.value=``;try{let e=(await k.post(`/api/update_letsmesh_config`,{enabled:T.value,iata_code:D.value,broker_index:O.value,status_interval:A.value,owner:M.value,email:P.value,disallowed_packet_types:F.value,additional_brokers:L.value.map(({name:e,host:t,port:n,audience:r})=>({name:e,host:t,port:n,audience:r}))})).data;e?.success?(f.value=e.data?.message||`Settings saved`,l.value=!1,await n.fetchStats(),await Q(),setTimeout(()=>{f.value=``},5e3)):p.value=e?.error||`Save failed`}catch(e){let t=e;p.value=t?.response?.data?.error||t?.message||`Request failed`}finally{d.value=!1}}return o(Q),(e,n)=>(w(),C(`div`,so,[S(`div`,co,[S(`div`,lo,[n[13]||=S(`div`,null,[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 broker connection state `)],-1),S(`button`,{onClick:Q,disabled:Z.value,class:`px-3 py-1.5 text-xs rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors disabled:opacity-50`},[Z.value?(w(),C(`span`,fo,`Refreshing…`)):(w(),C(`span`,po,`↻ Refresh`))],8,uo)]),X.value?(w(),C(`div`,ho,[S(`div`,go,[n[14]||=S(`span`,{class:`text-sm text-content-secondary dark:text-content-muted w-36`},`Handler`,-1),S(`span`,{class:_([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,X.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:_([`w-1.5 h-1.5 rounded-full`,X.value.handler_active?`bg-green-500`:`bg-gray-400`])},null,2),b(` `+u(X.value.handler_active?`Active`:`Inactive`),1)],2)]),X.value.brokers.length?(w(),C(`div`,_o,[(w(!0),C(x,null,i(X.value.brokers,e=>(w(),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},u(e.name),9,vo),S(`span`,{class:_([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,e.connected?`bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400`:e.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:_([`w-1.5 h-1.5 rounded-full`,e.connected?`bg-green-500`:e.reconnecting?`bg-amber-500`:`bg-red-500`])},null,2),b(` `+u(e.connected?`Connected`:e.reconnecting?`Reconnecting…`:`Disconnected`),1)],2)]))),128))])):(w(),C(`div`,yo,` No broker connections configured. `))])):(w(),C(`div`,mo,` Status unavailable — service may not be running. `))]),S(`div`,bo,[S(`div`,xo,[n[15]||=S(`div`,null,[S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-1`},` Observer Configuration `),S(`p`,{class:`text-sm text-content-secondary dark:text-content-muted`},` Configure MQTT observer settings `)],-1),l.value?g(``,!0):(w(),C(`button`,{key:0,onClick:ie,class:`px-4 py-2 text-sm rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors`},` Edit `))]),l.value?(w(),C(`div`,Ro,[S(`div`,zo,[n[24]||=S(`div`,null,[S(`label`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Enable Observer`),S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-0.5`},` Publish mesh packets to the MQTT networks `)],-1),S(`button`,{onClick:n[0]||=e=>T.value=!T.value,class:_([`relative inline-flex h-6 w-11 items-center rounded-full transition-colors border-2`,T.value?`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`])},[S(`span`,{class:_([`inline-block h-4 w-4 transform rounded-full bg-white transition-transform shadow-lg`,T.value?`translate-x-5`:`translate-x-0.5`])},null,2)],2)]),S(`div`,Bo,[S(`div`,null,[n[25]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5`},[b(` IATA Code `),S(`span`,{class:`text-content-secondary dark:text-content-muted font-normal text-xs ml-1`},`(e.g. SFO, LHR)`)],-1),m(S(`input`,{"onUpdate:modelValue":n[1]||=e=>D.value=e,type:`text`,maxlength:`10`,placeholder:`TEST`,class:`w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono`},null,512),[[N,D.value]])]),S(`div`,null,[n[26]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5`},`Broker Mode`,-1),m(S(`select`,{"onUpdate:modelValue":n[2]||=e=>O.value=e,class:`w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40`},[(w(),C(x,null,i(s,e=>S(`option`,{key:e.value,value:e.value},u(e.label),9,Vo)),64))],512),[[z,O.value,void 0,{number:!0}]])])]),S(`div`,Ho,[S(`div`,null,[n[27]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5`},`Owner / Callsign`,-1),m(S(`input`,{"onUpdate:modelValue":n[3]||=e=>M.value=e,type:`text`,placeholder:`Optional`,class:`w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40`},null,512),[[N,M.value]])]),S(`div`,null,[n[28]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5`},`Email`,-1),m(S(`input`,{"onUpdate:modelValue":n[4]||=e=>P.value=e,type:`email`,placeholder:`Optional`,class:`w-full px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40`},null,512),[[N,P.value]])])]),S(`div`,null,[n[29]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-1.5`},[b(` Status Heartbeat Interval `),S(`span`,{class:`text-content-secondary dark:text-content-muted font-normal text-xs ml-1`},`(seconds, min 60)`)],-1),m(S(`input`,{"onUpdate:modelValue":n[5]||=e=>A.value=e,type:`number`,min:`60`,max:`3600`,class:`w-32 px-3 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono`},null,512),[[N,A.value,void 0,{number:!0}]])]),S(`div`,null,[S(`div`,Uo,[n[36]||=S(`div`,{class:`min-w-0`},[S(`label`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},`Custom Brokers`),S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted mt-0.5`},` Additional MQTT/WebSocket brokers alongside or instead of built-in ones `)],-1),S(`div`,Wo,[S(`div`,Go,[S(`button`,{onClick:n[6]||=e=>H.value=!H.value,class:`inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-background-mute dark:bg-background/30 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted border border-stroke-subtle dark:border-stroke/20 transition-colors`},[n[31]||=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 11H5m14 0l-4-4m4 4l-4 4`})],-1),n[32]||=b(` From Template `,-1),(w(),C(`svg`,{class:_([`w-3 h-3 ml-0.5 transition-transform`,H.value?`rotate-180`:``]),fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[...n[30]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M19 9l-7 7-7-7`},null,-1)]],2))]),v(R,{name:`dropdown`},{default:t(()=>[H.value?(w(),C(`div`,Ko,[n[34]||=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),S(`div`,qo,[(w(),C(x,null,i(c,e=>S(`div`,{key:e.name,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=>U(e)},[S(`div`,Yo,[S(`p`,Xo,u(e.name),1),S(`p`,Zo,u(e.brokers.length)+` broker`+u(e.brokers.length===1?``:`s`),1)]),S(`a`,{href:e.website,target:`_blank`,rel:`noopener noreferrer`,title:`Visit website`,class:`flex-shrink-0 p-1 rounded hover:bg-cyan-500/10 dark:hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-cyan-700 dark:hover:text-primary transition-colors`,onClick:n[7]||=I(()=>{},[`stop`])},[...n[33]||=[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,Qo)],8,Jo)),64))])])):g(``,!0)]),_:1}),H.value?(w(),C(`div`,{key:0,class:`fixed inset-0 z-10`,onClick:n[8]||=e=>H.value=!1})):g(``,!0)]),S(`button`,{onClick:ee,class:`inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-cyan-500/10 dark:bg-primary/10 hover:bg-cyan-500/20 dark:hover:bg-primary/20 text-cyan-700 dark:text-primary border border-cyan-400/30 dark:border-primary/30 transition-colors`},[...n[35]||=[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)]])])]),L.value.length?(w(),C(`div`,es,[(w(!0),C(x,null,i(L.value,e=>(w(),C(`div`,{key:e._id,class:_([`rounded-lg border overflow-hidden transition-colors`,J.value[e._id]?`border-red-300 dark:border-red-700/50`:`border-stroke-subtle dark:border-stroke/10`])},[B.value===e._id?(w(),C(`div`,ls,[S(`div`,us,[S(`div`,null,[n[40]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},[b(` Name `),S(`span`,{class:`text-red-500`},`*`)],-1),m(S(`input`,{"onUpdate:modelValue":n[9]||=e=>V.value.name=e,type:`text`,placeholder:`My Private Broker`,class:`w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40`},null,512),[[N,V.value.name]])]),S(`div`,null,[n[41]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},[b(` Port `),S(`span`,{class:`text-red-500`},`*`)],-1),m(S(`input`,{"onUpdate:modelValue":n[10]||=e=>V.value.port=e,type:`number`,min:`1`,max:`65535`,placeholder:`443`,class:`w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono`},null,512),[[N,V.value.port,void 0,{number:!0}]])]),S(`div`,null,[n[42]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},[b(` Host `),S(`span`,{class:`text-red-500`},`*`)],-1),m(S(`input`,{"onUpdate:modelValue":n[11]||=e=>V.value.host=e,type:`text`,placeholder:`mqtt.myserver.com`,onInput:q,class:`w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono`},null,544),[[N,V.value.host]])]),S(`div`,null,[n[43]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},[b(` Audience `),S(`span`,{class:`text-red-500`},`*`),S(`span`,{class:`font-normal text-content-muted dark:text-content-muted/60 ml-1`},`(JWT aud — usually same as host)`)],-1),m(S(`input`,{"onUpdate:modelValue":n[12]||=e=>V.value.audience=e,type:`text`,placeholder:`mqtt.myserver.com`,class:`w-full px-3 py-1.5 text-sm rounded-md bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/20 text-content-primary dark:text-content-primary placeholder-content-muted dark:placeholder-content-muted/50 focus:outline-none focus:ring-2 focus:ring-cyan-500/40 dark:focus:ring-primary/40 font-mono`},null,512),[[N,V.value.audience]])])]),S(`div`,ds,[S(`button`,{onClick:K,disabled:!V.value.name.trim()||!V.value.host.trim()||!V.value.audience.trim(),class:`px-3 py-1.5 text-xs font-medium rounded-md bg-cyan-600 dark:bg-teal-600 hover:bg-cyan-700 dark:hover:bg-teal-700 text-white transition-colors disabled:opacity-40 disabled:cursor-not-allowed`},` Done `,8,fs),S(`button`,{onClick:re,class:`px-3 py-1.5 text-xs rounded-md border border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted transition-colors`},` Cancel `),S(`button`,{onClick:t=>te(e._id),class:`ml-auto px-3 py-1.5 text-xs rounded-md border border-red-300/60 dark:border-red-700/30 hover:bg-red-50 dark:hover:bg-red-900/20 text-red-600 dark:text-red-400 transition-colors`},` Remove `,8,ps)])])):(w(),C(`div`,ts,[S(`div`,ns,[S(`span`,rs,u(e.name||`(unnamed)`),1),S(`span`,is,u(e.host||`—`)+`:`+u(e.port),1),J.value[e._id]?(w(),C(`span`,as,u(J.value[e._id]),1)):g(``,!0)]),S(`div`,os,[S(`button`,{onClick:t=>ne(e),title:`Edit`,class:`p-1.5 rounded hover:bg-cyan-500/10 dark:hover:bg-primary/10 text-content-secondary dark:text-content-muted hover:text-cyan-700 dark:hover:text-primary transition-colors`},[...n[38]||=[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:`M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z`})],-1)]],8,ss),S(`button`,{onClick:t=>te(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[39]||=[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,cs)])]))],2))),128))])):(w(),C(`div`,$o,[...n[37]||=[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),S(`p`,{class:`text-sm`},`No custom brokers`,-1),S(`p`,{class:`text-xs mt-0.5 opacity-70`},` Built-in brokers will be used based on the mode above `,-1)]])),n[44]||=S(`p`,{class:`mt-2 text-xs text-content-secondary dark:text-content-muted`},[b(` Set `),S(`span`,{class:`font-medium`},`Broker Mode`),b(` to `),S(`em`,null,`Custom brokers only`),b(` to use exclusively these servers, or leave it on any other mode to use them alongside the built-in ones. `)],-1)]),S(`div`,null,[n[45]||=S(`label`,{class:`block text-sm font-medium text-content-primary dark:text-content-primary mb-2`},[b(` Block Packet Types `),S(`span`,{class:`text-content-secondary dark:text-content-muted font-normal text-xs ml-1`},`(prevent publishing to LetsMesh)`)],-1),S(`div`,ms,[(w(),C(x,null,i(a,e=>S(`button`,{key:e,onClick:t=>oe(e),class:_([`px-2.5 py-1 rounded text-xs font-mono font-medium border transition-colors`,F.value.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-background/30 border-stroke-subtle dark:border-stroke/20 text-content-secondary dark:text-content-muted hover:border-cyan-400/50 dark:hover:border-primary/40`])},u(e),11,hs)),64))]),n[46]||=S(`p`,{class:`mt-1.5 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)]),n[47]||=S(`div`,{class:`flex items-start gap-2 p-3 rounded-lg bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700/30 text-amber-700 dark:text-amber-400 text-xs`},[S(`svg`,{class:`w-4 h-4 mt-0.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:`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`})]),b(` A service restart is required for changes to take effect. `)],-1),f.value?(w(),C(`div`,gs,u(f.value),1)):g(``,!0),p.value?(w(),C(`div`,_s,u(p.value),1)):g(``,!0),S(`div`,vs,[S(`button`,{onClick:se,disabled:d.value||Y.value,class:`px-5 py-2 text-sm font-medium rounded-lg bg-cyan-600 dark:bg-teal-600 hover:bg-cyan-700 dark:hover:bg-teal-700 text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed`},[d.value?(w(),C(`span`,bs,`Saving…`)):(w(),C(`span`,xs,`Save Settings`))],8,ys),S(`button`,{onClick:ae,disabled:d.value,class:`px-4 py-2 text-sm rounded-lg bg-background-mute dark:bg-background/30 hover:bg-stroke-subtle dark:hover:bg-stroke/10 text-content-secondary dark:text-content-muted border border-stroke-subtle dark:border-stroke/20 transition-colors disabled:opacity-50`},` Cancel `,8,Ss)])])):(w(),C(`div`,So,[S(`div`,Co,[S(`div`,null,[n[16]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Enabled`,-1),S(`p`,wo,[S(`span`,{class:_([`inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium`,r.value.enabled?`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`])},u(r.value.enabled?`Yes`:`No`),3)])]),S(`div`,null,[n[17]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`IATA Code`,-1),S(`p`,To,u(r.value.iata_code||`—`),1)]),S(`div`,null,[n[18]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Broker Mode`,-1),S(`p`,Eo,u(s.find(e=>e.value===r.value.broker_index)?.label??`Index ${r.value.broker_index??0}`),1)]),S(`div`,null,[n[19]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Status Interval`,-1),S(`p`,Do,u(r.value.status_interval??300)+`s `,1)]),S(`div`,null,[n[20]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Owner`,-1),S(`p`,Oo,u(r.value.owner||`—`),1)]),S(`div`,null,[n[21]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Email`,-1),S(`p`,ko,u(r.value.email||`—`),1)])]),S(`div`,null,[n[22]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Custom Brokers`,-1),r.value.additional_brokers?.length?(w(),C(`div`,jo,[(w(!0),C(x,null,i(r.value.additional_brokers,e=>(w(),C(`div`,{key:e.host,class:`flex items-center gap-3 px-3 py-2 rounded-lg bg-background-mute dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10`},[S(`div`,Mo,[S(`span`,No,u(e.name),1),S(`span`,Po,u(e.host)+`:`+u(e.port),1)]),S(`span`,{class:`text-xs text-content-secondary dark:text-content-muted font-mono truncate max-w-[140px]`,title:e.audience},u(e.audience),9,Fo)]))),128))])):(w(),C(`div`,Ao,` None configured `))]),S(`div`,null,[n[23]||=S(`span`,{class:`text-xs font-medium text-content-secondary dark:text-content-muted uppercase tracking-wide`},`Blocked Packet Types`,-1),S(`div`,Io,[r.value.disallowed_packet_types?.length?g(``,!0):(w(),C(`span`,Lo,`All types allowed`)),(w(!0),C(x,null,i(r.value.disallowed_packet_types,e=>(w(),C(`span`,{key:e,class:`px-2 py-0.5 rounded text-xs font-mono bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400`},u(e),1))),128))])])]))])]))}}),[[`__scopeId`,`data-v-a170107f`]]),ws={class:`space-y-6`},Ts={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`},Es={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},Ds=[`disabled`],Os={key:0,class:`flex items-center gap-2`},ks={key:1,class:`flex items-center gap-2`},As={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-2`},js={key:1,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Ms={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},Ns={key:0},Ps={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`},Fs={class:`flex items-start gap-3`},Is={class:`flex-1`},Ls={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},Rs={class:`flex gap-2 mt-3`},zs=[`disabled`],Bs=[`disabled`],Vs={key:2,class:`text-xs text-green-600 dark:text-green-400 mt-2`},Hs={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},Us={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},Ws={class:`space-y-3`},Gs={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`},Ks={class:`text-sm text-content-secondary dark:text-content-muted`},qs={key:0,class:`bg-background-mute dark:bg-background/30 rounded-lg p-4 border border-stroke-subtle dark:border-stroke/10`},Js={key:0,class:`text-xs text-content-secondary dark:text-content-muted space-y-1 mb-3`},Ys={class:`font-mono`},Xs={class:`font-mono`},Zs={key:0,class:`text-amber-600 dark:text-amber-400 font-medium`},Qs={key:1,class:`text-content-muted`},$s={class:`text-xs text-content-secondary dark:text-content-muted`},ec={class:`font-mono`},tc={key:1},nc={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`},rc={class:`flex items-start gap-3`},ic={class:`flex-1`},ac={class:`text-xs text-amber-700 dark:text-amber-300/80 mt-1`},oc={class:`flex gap-2 mt-3`},sc=[`disabled`],cc=[`disabled`],lc={key:3,class:`text-xs text-green-600 dark:text-green-400 mt-2`},uc={key:4,class:`text-xs text-red-500 dark:text-red-400 mt-2`},dc={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},fc={key:0},pc={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`},mc={class:`flex items-start gap-3`},hc={class:`flex-1`},gc={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},_c={class:`flex gap-2 mt-3`},vc=[`disabled`],yc=[`disabled`],bc={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`},xc={class:`flex items-center justify-between`},Sc={class:`text-xs text-content-secondary dark:text-content-muted space-y-1`},Cc={class:`font-mono`},wc={key:0},Tc={class:`font-mono`},Ec={key:1},Dc={class:`font-mono text-[10px] break-all`},Oc={key:3,class:`text-xs text-red-500 dark:text-red-400 mt-2`},kc=f({__name:`BackupRestore`,setup(e){let t=y(()=>window.location.protocol===`http:`),n=E(!1),r=E(``),i=E(``);async function a(){n.value=!0,r.value=``,i.value=``;try{let e=await A.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 o=E(!1),s=E(!1),c=E(``),l=E(``);async function f(){s.value=!0,c.value=``,l.value=``;try{let e=await A.exportConfig(!0);if(!e.success||!e.data){l.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),c.value=`Full backup exported (includes all secrets).`,o.value=!1}catch(e){l.value=e instanceof Error?e.message:`Export failed`}finally{s.value=!1}}let p=E(null),m=E(null),h=E(!1),_=E(!1),v=E(``),T=E(``),D=E(null),O=y(()=>m.value?.config?Object.keys(m.value.config).join(`, `):``),k=y(()=>{let e=m.value?.meta?.includes_secrets;return e===!0||e===`true`});function j(e){let t=e.target.files?.[0];if(!t)return;p.value=t,m.value=null,h.value=!1,v.value=``,T.value=``;let n=new FileReader;n.onload=e=>{try{let t=JSON.parse(e.target?.result);t.config&&typeof t.config==`object`?m.value={meta:t.meta,config:t.config}:typeof t==`object`&&!Array.isArray(t)?m.value={config:t}:T.value=`Invalid file format — expected a JSON config object.`}catch{T.value=`Invalid JSON file.`}},n.readAsText(t)}function M(){h.value=!1,m.value=null,p.value=null,D.value&&(D.value.value=``)}async function N(){if(m.value?.config){_.value=!0,v.value=``,T.value=``;try{let e=await A.importConfig(m.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.`),v.value=n,h.value=!1,m.value=null,p.value=null,D.value&&(D.value.value=``)}else T.value=e.error||`Import failed`}catch(e){T.value=e instanceof Error?e.message:`Import failed`}finally{_.value=!1}}}let P=E(!1),F=E(!1),I=E(null),L=E(``);async function R(){F.value=!0,L.value=``;try{let e=await A.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,y)=>(w(),C(`div`,ws,[t.value?(w(),C(`div`,Ts,[...y[6]||=[d(`<div class="flex items-start gap-3"><svg class="w-6 h-6 text-red-600 dark:text-red-400 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg><div><h4 class="text-sm font-semibold text-red-700 dark:text-red-400"> Unencrypted Connection </h4><p class="text-xs text-red-600 dark:text-red-400/80 mt-1"> This page is served over <strong>HTTP</strong>, not HTTPS. Exported data (including identity keys) will be transmitted in <strong>plain text</strong>. Only use these features on a trusted local network. </p></div></div>`,1)]])):g(``,!0),S(`div`,Es,[y[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:a,disabled:n.value,class:`px-4 py-2 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-sm`},[n.value?(w(),C(`span`,Os,[...y[7]||=[S(`span`,{class:`animate-spin w-4 h-4 border-2 border-current border-t-transparent rounded-full inline-block`},null,-1),b(` Exporting… `,-1)]])):(w(),C(`span`,ks,[...y[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,Ds),r.value?(w(),C(`p`,As,u(r.value),1)):g(``,!0),i.value?(w(),C(`p`,js,u(i.value),1)):g(``,!0)]),S(`div`,Ms,[y[15]||=d(`<div class="flex items-start justify-between mb-4"><div><h3 class="text-lg font-semibold text-content-primary dark:text-content-primary mb-1"> Full Backup </h3><p class="text-sm text-content-secondary dark:text-content-muted"> Download a complete backup including <strong>all passwords, JWT secrets, and identity keys</strong>. Required for restoring to a new device or recovering from a failed SD card. </p></div></div><div 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"><p class="text-xs text-red-700 dark:text-red-400"><strong>Contains sensitive data.</strong> The backup file will include plain-text passwords and private keys. Store it securely and never share it. </p></div>`,2),o.value?g(``,!0):(w(),C(`div`,Ns,[S(`button`,{onClick:y[0]||=e=>o.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`},[...y[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)]])])),o.value?(w(),C(`div`,Ps,[S(`div`,Fs,[y[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`,Is,[y[13]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},` Confirm Full Backup `,-1),S(`p`,Ls,[y[11]||=b(` This will export `,-1),y[12]||=S(`strong`,null,`all secrets in plain text`,-1),b(` including admin/guest passwords, JWT secret, and your repeater's private identity key`+u(t.value?` over an unencrypted HTTP connection`:``)+`. `,1)]),S(`div`,Rs,[S(`button`,{onClick:f,disabled:s.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`},u(s.value?`Exporting…`:`Yes, Export Full Backup`),9,zs),S(`button`,{onClick:y[1]||=e=>o.value=!1,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 transition-colors text-sm`},` Cancel `,8,Bs)])])])])):g(``,!0),c.value?(w(),C(`p`,Vs,u(c.value),1)):g(``,!0),l.value?(w(),C(`p`,Hs,u(l.value),1)):g(``,!0)]),S(`div`,Us,[y[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`,Ws,[S(`label`,Gs,[y[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`,Ks,u(p.value?p.value.name:`Choose a config JSON file…`),1),S(`input`,{ref_key:`fileInputRef`,ref:D,type:`file`,accept:`.json,application/json`,class:`hidden`,onChange:j},null,544)]),m.value?(w(),C(`div`,qs,[y[20]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary mb-2`},` Import Preview `,-1),m.value.meta?(w(),C(`div`,Js,[S(`p`,null,[y[17]||=b(` Exported: `,-1),S(`span`,Ys,u(m.value.meta.exported_at),1)]),S(`p`,null,[y[18]||=b(` Version: `,-1),S(`span`,Xs,u(m.value.meta.version),1)]),m.value.meta.includes_secrets===`true`||m.value.meta.includes_secrets===!0?(w(),C(`p`,Zs,` ⚠ Full backup — will restore passwords and identity keys `)):(w(),C(`p`,Qs,` Settings only — existing secrets will not be changed `))])):g(``,!0),S(`p`,$s,[y[19]||=b(` Sections: `,-1),S(`span`,ec,u(O.value),1)])])):g(``,!0),m.value&&!h.value?(w(),C(`div`,tc,[S(`button`,{onClick:y[2]||=e=>h.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 `)])):g(``,!0),h.value?(w(),C(`div`,nc,[S(`div`,rc,[y[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`,ic,[y[27]||=S(`h4`,{class:`text-sm font-semibold text-amber-800 dark:text-amber-300`},` Confirm Import `,-1),S(`p`,ac,[y[24]||=b(` This will overwrite current settings for: `,-1),S(`strong`,null,u(O.value),1),y[25]||=b(`. `,-1),k.value?(w(),C(x,{key:0},[y[21]||=b(` This is a full backup — `,-1),y[22]||=S(`strong`,null,`passwords, JWT secrets, and identity keys will also be overwritten`,-1),y[23]||=b(`. `,-1)],64)):(w(),C(x,{key:1},[b(` Passwords and identity keys will not be changed. `)],64)),y[26]||=b(` Some changes (radio settings) require a service restart. `,-1)]),S(`div`,oc,[S(`button`,{onClick:N,disabled:_.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`},u(_.value?`Importing…`:`Yes, Import`),9,sc),S(`button`,{onClick:M,disabled:_.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,cc)])])])])):g(``,!0),v.value?(w(),C(`p`,lc,u(v.value),1)):g(``,!0),T.value?(w(),C(`p`,uc,u(T.value),1)):g(``,!0)])]),S(`div`,dc,[y[38]||=d(`<div class="flex items-start justify-between mb-4"><div><h3 class="text-lg font-semibold text-content-primary dark:text-content-primary mb-1"> Export Identity Key </h3><p class="text-sm text-content-secondary dark:text-content-muted"> Download the repeater's private identity key for backup. This key determines the node's address and cryptographic identity on the mesh. </p></div></div><div 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"><p class="text-xs text-red-700 dark:text-red-400"><strong>Sensitive data.</strong> 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. </p></div>`,2),P.value?g(``,!0):(w(),C(`div`,fc,[S(`button`,{onClick:y[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`},[...y[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?(w(),C(`div`,pc,[S(`div`,mc,[y[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`,hc,[y[31]||=S(`h4`,{class:`text-sm font-semibold text-red-700 dark:text-red-400`},`Are you sure?`,-1),S(`p`,gc,` This will transmit your private key `+u(t.value?`over an unencrypted HTTP connection. `:``)+` and download it as a file. `,1),S(`div`,_c,[S(`button`,{onClick:R,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`},u(F.value?`Exporting…`:`Yes, Export Key`),9,vc),S(`button`,{onClick:y[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,yc)])])])])):g(``,!0),I.value?(w(),C(`div`,bc,[S(`div`,xc,[y[33]||=S(`h4`,{class:`text-sm font-medium text-content-primary dark:text-content-primary`},` Key Exported `,-1),S(`button`,{onClick:y[5]||=e=>{I.value=null,P.value=!1},class:`text-xs text-content-muted hover:text-content-secondary transition-colors`},` Dismiss `)]),S(`div`,Sc,[S(`p`,null,[y[34]||=b(` Key length: `,-1),S(`span`,Cc,u(I.value.key_length_bytes)+` bytes`,1)]),I.value.node_address?(w(),C(`p`,wc,[y[35]||=b(` Node address: `,-1),S(`span`,Tc,u(I.value.node_address),1)])):g(``,!0),I.value.public_key_hex?(w(),C(`p`,Ec,[y[36]||=b(` Public key: `,-1),S(`span`,Dc,u(I.value.public_key_hex),1)])):g(``,!0)]),y[37]||=S(`p`,{class:`text-xs text-green-600 dark:text-green-400`},`File downloaded successfully.`,-1)])):g(``,!0),L.value?(w(),C(`p`,Oc,u(L.value),1)):g(``,!0)])]))}}),Ac={class:`space-y-6`},jc={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},Mc={class:`flex items-start justify-between mb-4`},Nc=[`disabled`],Pc={key:0,class:`flex items-center gap-1.5`},Fc={key:1},Ic={key:0,class:`grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6`},Lc={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Rc={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},zc={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Bc={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Vc={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Hc={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Uc={class:`bg-background-mute dark:bg-background/30 rounded-lg p-3 border border-stroke-subtle dark:border-stroke/10`},Wc={class:`text-lg font-semibold text-content-primary dark:text-content-primary font-mono`},Gc={key:1,class:`flex items-center justify-center py-12`},Kc={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`},qc={class:`text-xs text-red-700 dark:text-red-400`},Jc={key:3},Yc={class:`overflow-x-auto`},Xc={class:`w-full text-sm`},Zc={class:`py-2.5 pr-4`},Qc={class:`font-mono text-content-primary dark:text-content-primary`},$c={class:`py-2.5 pr-4 text-right`},el={class:`font-mono text-content-secondary dark:text-content-muted`},tl={class:`py-2.5 pr-4 text-right hidden sm:table-cell`},nl={key:0,class:`text-xs text-content-muted`},rl={class:`text-content-muted/60 ml-1`},il={key:1,class:`text-xs text-content-muted/50`},al={key:2,class:`text-xs text-content-muted/50`},ol={class:`py-2.5 text-right`},sl=[`onClick`,`disabled`],cl={key:0,class:`flex items-center gap-1`},ll={key:1},ul={key:1,class:`text-xs text-content-muted/50`},dl={key:0,class:`glass-card rounded-lg border-2 border-red-500/50 dark:border-red-400/40 bg-red-50 dark:bg-red-500/10 p-6`},fl={class:`flex items-start gap-3`},pl={class:`flex-1`},ml={class:`text-sm font-semibold text-red-700 dark:text-red-400`},hl={class:`text-xs text-red-600 dark:text-red-400/80 mt-1`},gl={class:`flex gap-2 mt-3`},_l=[`disabled`],vl=[`disabled`],yl={class:`glass-card rounded-lg border border-stroke-subtle dark:border-stroke/10 p-6`},bl={class:`flex flex-wrap gap-3`},xl=[`disabled`],Sl=[`disabled`],Cl={class:`flex items-center gap-2`},wl={key:0,class:`text-xs text-green-600 dark:text-green-400 mt-3`},Tl={key:1,class:`text-xs text-green-600 dark:text-green-400 mt-3`},El=f({__name:`DatabaseManagement`,setup(e){let t=new Set([`packets`,`adverts`,`noise_floor`,`crc_errors`,`room_messages`,`room_client_sync`,`companion_contacts`,`companion_channels`,`companion_messages`,`companion_prefs`]),n=E(!1),r=E(``),a=E(null),s=E({}),c=E(null),l=E(``),d=E(!1),f=E(``),p=y(()=>a.value?a.value.tables.reduce((e,t)=>e+t.row_count,0):0);function m(e){return t.has(e)}function h(e){if(e===0)return`0 B`;let t=[`B`,`KB`,`MB`,`GB`],n=Math.min(Math.floor(Math.log(e)/Math.log(1024)),t.length-1),r=e/1024**n;return`${r<10?r.toFixed(1):Math.round(r)} ${t[n]}`}function _(e){return e?new Date(e*1e3).toLocaleDateString(void 0,{month:`short`,day:`numeric`,year:`numeric`}):`—`}function v(e,t){return!e||!t?0:Math.max(1,Math.round((t-e)/86400))}async function T(){n.value=!0,r.value=``;try{let e=await A.getDbStats();e.success&&e.data?a.value=e.data:r.value=e.error||`Failed to load database stats`}catch(e){r.value=e instanceof Error?e.message:`Failed to load database stats`}finally{n.value=!1}}function D(e,t){l.value=``,c.value={table:e,rowCount:t,executing:!1}}async function O(){if(!c.value)return;let{table:e}=c.value;c.value.executing=!0,l.value=``;try{let t=e===`all`?`all`:[e];e!==`all`&&(s.value[e]=!0);let n=await A.purgeTable(t);if(n.success){let t=n.data||{};l.value=`Deleted ${Object.values(t).reduce((e,t)=>e+(t.deleted||0),0).toLocaleString()} rows${e===`all`?` from all tables`:` from ${e}`}.`,c.value=null,await T()}else r.value=n.error||`Purge failed`,c.value=null}catch(e){r.value=e instanceof Error?e.message:`Purge failed`,c.value=null}finally{e!==`all`&&(s.value[e]=!1)}}async function k(){d.value=!0,f.value=``,r.value=``;try{let e=await A.vacuumDb();if(e.success&&e.data){let t=e.data.freed_bytes;f.value=t>0?`Compacted database — freed ${h(t)} (${h(e.data.size_before)} → ${h(e.data.size_after)}).`:`Database already compact (${h(e.data.size_after)}).`,await T()}else r.value=e.error||`Vacuum failed`}catch(e){r.value=e instanceof Error?e.message:`Vacuum failed`}finally{d.value=!1}}return o(T),(e,t)=>(w(),C(`div`,Ac,[S(`div`,jc,[S(`div`,Mc,[t[3]||=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:T,disabled:n.value,class:`px-3 py-1.5 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors text-sm disabled:opacity-50`},[n.value?(w(),C(`span`,Pc,[...t[2]||=[S(`span`,{class:`animate-spin w-3.5 h-3.5 border-2 border-current border-t-transparent rounded-full inline-block`},null,-1),b(` Loading… `,-1)]])):(w(),C(`span`,Fc,`Refresh`))],8,Nc)]),a.value?(w(),C(`div`,Ic,[S(`div`,Lc,[t[4]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Database Size`,-1),S(`p`,Rc,u(h(a.value.database_size_bytes)),1)]),S(`div`,zc,[t[5]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`RRD Metrics`,-1),S(`p`,Bc,u(h(a.value.rrd_size_bytes)),1)]),S(`div`,Vc,[t[6]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Size`,-1),S(`p`,Hc,u(h(a.value.database_size_bytes+a.value.rrd_size_bytes)),1)]),S(`div`,Uc,[t[7]||=S(`p`,{class:`text-xs text-content-muted mb-1`},`Total Rows`,-1),S(`p`,Wc,u(p.value.toLocaleString()),1)])])):g(``,!0),n.value&&!a.value?(w(),C(`div`,Gc,[...t[8]||=[S(`div`,{class:`text-center`},[S(`div`,{class:`animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full mx-auto mb-4`}),S(`div`,{class:`text-content-secondary dark:text-content-muted`},`Loading database info…`)],-1)]])):g(``,!0),r.value?(w(),C(`div`,Kc,[S(`p`,qc,u(r.value),1)])):g(``,!0),a.value&&a.value.tables.length>0?(w(),C(`div`,Jc,[S(`div`,Yc,[S(`table`,Xc,[t[10]||=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,[(w(!0),C(x,null,i(a.value.tables,e=>(w(),C(`tr`,{key:e.name,class:`border-b border-stroke-subtle/50 dark:border-stroke/5`},[S(`td`,Zc,[S(`span`,Qc,u(e.name),1)]),S(`td`,$c,[S(`span`,el,u(e.row_count.toLocaleString()),1)]),S(`td`,tl,[e.has_timestamp&&e.row_count>0?(w(),C(`span`,nl,[b(u(_(e.oldest_timestamp))+` — `+u(_(e.newest_timestamp))+` `,1),S(`span`,rl,`(`+u(v(e.oldest_timestamp,e.newest_timestamp))+`d)`,1)])):e.row_count===0?(w(),C(`span`,il,`—`)):(w(),C(`span`,al,`n/a`))]),S(`td`,ol,[m(e.name)&&e.row_count>0?(w(),C(`button`,{key:0,onClick:t=>D(e.name,e.row_count),disabled:s.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`},[s.value[e.name]?(w(),C(`span`,cl,[...t[9]||=[S(`span`,{class:`animate-spin w-3 h-3 border border-current border-t-transparent rounded-full inline-block`},null,-1),b(` Purging… `,-1)]])):(w(),C(`span`,ll,`Empty`))],8,sl)):m(e.name)?g(``,!0):(w(),C(`span`,ul,`—`))])]))),128))])])])])):g(``,!0)]),c.value?(w(),C(`div`,dl,[S(`div`,fl,[t[16]||=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`,pl,[S(`h4`,ml,u(c.value.table===`all`?`Confirm Purge All Tables`:`Confirm Purge "${c.value.table}"`),1),S(`p`,hl,[c.value.table===`all`?(w(),C(x,{key:0},[t[11]||=b(` This will permanently delete `,-1),t[12]||=S(`strong`,null,`all data`,-1),b(` from every data table (`+u(p.value.toLocaleString())+` rows total). This cannot be undone. `,1)],64)):(w(),C(x,{key:1},[t[13]||=b(` This will permanently delete `,-1),S(`strong`,null,u(c.value.rowCount.toLocaleString())+` rows`,1),t[14]||=b(` from `,-1),S(`strong`,null,u(c.value.table),1),t[15]||=b(`. This cannot be undone. `,-1)],64))]),S(`div`,gl,[S(`button`,{onClick:O,disabled:c.value.executing,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`},u(c.value.executing?`Purging…`:`Yes, Delete Data`),9,_l),S(`button`,{onClick:t[0]||=e=>c.value=null,disabled:c.value.executing,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,vl)])])])])):g(``,!0),S(`div`,yl,[t[19]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Maintenance `,-1),S(`div`,bl,[S(`button`,{onClick:t[1]||=e=>D(`all`,p.value),disabled:!a.value||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 disabled:opacity-50 disabled:cursor-not-allowed`},[...t[17]||=[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,xl),S(`button`,{onClick:k,disabled:d.value||!a.value,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 disabled:opacity-50 disabled:cursor-not-allowed`},[S(`span`,Cl,[t[18]||=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(` `+u(d.value?`Compacting…`:`Compact Database`),1)])],8,Sl)]),f.value?(w(),C(`p`,wl,u(f.value),1)):g(``,!0),l.value?(w(),C(`p`,Tl,u(l.value),1)):g(``,!0)])]))}}),Dl={class:`p-3 sm:p-6 space-y-4 sm:space-y-6`},Ol={class:`glass-card rounded-[15px] z-10 p-3 sm:p-4 border border-cyan-400 dark:border-primary/30 bg-cyan-500/10 dark:bg-primary/10`},kl={class:`text-cyan-700 dark:text-primary text-sm sm:text-base`},Al={class:`mt-1 sm:mt-2 text-cyan-600 dark:text-primary/80`},jl={class:`glass-card rounded-[15px] p-3 sm:p-6`},Ml={class:`relative -mx-3 sm:mx-0 mb-4 sm:mb-6`},Nl={key:0,class:`absolute left-0 top-0 bottom-[1px] w-12 z-10 flex items-center`},Pl={key:0,class:`absolute right-0 top-0 bottom-[1px] w-12 z-10 flex items-center justify-end`},Fl=[`onClick`],Il={class:`flex items-center gap-1 sm:gap-2`},Ll={key:0,class:`w-3.5 h-3.5 sm:w-4 sm:h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Rl={key:1,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},zl={key:2,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Bl={key:3,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Vl={key:4,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Hl={key:5,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Ul={key:6,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Wl={key:7,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Gl={key:8,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Kl={key:9,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},ql={key:10,class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},Jl={class:`min-h-[400px]`},Yl={key:0,class:`flex items-center justify-center py-12`},Xl={key:1,class:`flex items-center justify-center py-12`},Zl={class:`text-center`},Ql={class:`text-content-secondary dark:text-content-muted text-sm mb-4`},$l={key:2},eu=M(f({name:`ConfigurationView`,__name:`Configuration`,setup(e){let n=j(),a=E(H(`configuration_activeTab`,`radio`)),l=E(!1),d=E(null),f=E(!1),p=E(!1);function y(){if(!d.value)return;let e=d.value;p.value=e.scrollLeft>4,f.value=e.scrollLeft<e.scrollWidth-e.clientWidth-4}function T(e){d.value&&d.value.scrollBy({left:e===`right`?150:-150,behavior:`smooth`})}h(a,e=>V(`configuration_activeTab`,e));let D=[{id:`radio`,label:`Radio Settings`,icon:`radio`},{id:`repeater`,label:`Repeater Settings`,icon:`repeater`},{id:`advert`,label:`Advert Limits`,icon:`advert`},{id:`duty`,label:`Duty Cycle`,icon:`duty`},{id:`delays`,label:`TX Delays`,icon:`delays`},{id:`transport`,label:`Regions/Keys`,icon:`keys`},{id:`api-tokens`,label:`API Tokens`,icon:`tokens`},{id:`web`,label:`Web Options`,icon:`web`},{id:`observer`,label:`Observer`,icon:`observer`},{id:`backup`,label:`Backup`,icon:`backup`},{id:`database`,label:`Database`,icon:`database`}];o(async()=>{try{await n.fetchStats(),l.value=!0}catch(e){console.error(`Failed to load configuration data:`,e),l.value=!0}c(()=>y())});function O(e){a.value=e}return(e,o)=>{let c=r(`router-link`);return w(),C(`div`,Dl,[o[23]||=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),S(`div`,Ol,[S(`div`,kl,[o[5]||=S(`strong`,null,`CAD Calibration Tool Available`,-1),S(`p`,Al,[o[4]||=b(` Optimize your Channel Activity Detection settings. `,-1),v(c,{to:`/cad-calibration`,class:`underline hover:text-cyan-800 dark:hover:text-primary transition-colors`},{default:t(()=>[...o[3]||=[b(` Launch CAD Calibration Tool → `,-1)]]),_:1})])])]),S(`div`,jl,[S(`div`,Ml,[v(R,{name:`tab-fade`},{default:t(()=>[p.value?(w(),C(`div`,Nl,[o[7]||=S(`div`,{class:`tab-fade-left absolute inset-0 pointer-events-none`},null,-1),S(`button`,{onClick:o[0]||=e=>T(`left`),class:`relative z-10 ml-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-white dark:bg-zinc-900 shadow-md border border-gray-200 dark:border-white/10 text-gray-500 dark:text-gray-300`},[...o[6]||=[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.5`,d:`M15 19l-7-7 7-7`})],-1)]])])):g(``,!0)]),_:1}),v(R,{name:`tab-fade`},{default:t(()=>[f.value?(w(),C(`div`,Pl,[o[9]||=S(`div`,{class:`tab-fade-right absolute inset-0 pointer-events-none`},null,-1),S(`button`,{onClick:o[1]||=e=>T(`right`),class:`relative z-10 mr-1.5 w-6 h-6 flex items-center justify-center rounded-full bg-white dark:bg-zinc-900 shadow-md border border-gray-200 dark:border-white/10 text-gray-500 dark:text-gray-300`},[...o[8]||=[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.5`,d:`M9 5l7 7-7 7`})],-1)]])])):g(``,!0)]),_:1}),S(`div`,{ref_key:`tabsContainer`,ref:d,onScroll:y,class:`flex overflow-x-auto border-b border-stroke-subtle dark:border-stroke/10 px-3 sm:px-0 scrollbar-hide`},[(w(),C(x,null,i(D,e=>S(`button`,{key:e.id,onClick:t=>O(e.id),class:_([`px-3 sm:px-4 py-2 text-xs sm:text-sm font-medium transition-colors duration-200 border-b-2 mr-3 sm:mr-6 whitespace-nowrap flex-shrink-0`,a.value===e.id?`text-cyan-500 dark:text-primary border-cyan-500 dark:border-primary`:`text-content-secondary dark:text-content-muted border-transparent hover:text-content-primary dark:hover:text-content-primary hover:border-stroke-subtle dark:hover:border-stroke/30`])},[S(`div`,Il,[e.icon===`radio`?(w(),C(`svg`,Ll,[...o[10]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.822c5.716-5.716 14.976-5.716 20.692 0`},null,-1)]])):e.icon===`repeater`?(w(),C(`svg`,Rl,[...o[11]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M5 12h14M5 12l4-4m-4 4l4 4`},null,-1)]])):e.icon===`advert`?(w(),C(`svg`,zl,[...o[12]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z`},null,-1)]])):e.icon===`duty`?(w(),C(`svg`,Bl,[...o[13]||=[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`},null,-1)]])):e.icon===`delays`?(w(),C(`svg`,Vl,[...o[14]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z`},null,-1)]])):e.icon===`keys`?(w(),C(`svg`,Hl,[...o[15]||=[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)]])):e.icon===`tokens`?(w(),C(`svg`,Ul,[...o[16]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z`},null,-1)]])):e.icon===`web`?(w(),C(`svg`,Wl,[...o[17]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9`},null,-1)]])):e.icon===`observer`?(w(),C(`svg`,Gl,[...o[18]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z`},null,-1)]])):e.icon===`backup`?(w(),C(`svg`,Kl,[...o[19]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4`},null,-1)]])):e.icon===`database`?(w(),C(`svg`,ql,[...o[20]||=[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4`},null,-1)]])):g(``,!0),b(` `+u(e.label),1)])],10,Fl)),64))],544)]),S(`div`,Jl,[!l.value&&s(n).isLoading?(w(),C(`div`,Yl,[...o[21]||=[S(`div`,{class:`text-center`},[S(`div`,{class:`animate-spin w-8 h-8 border-2 border-stroke-subtle dark:border-stroke/20 border-t-cyan-500 dark:border-t-primary rounded-full mx-auto mb-4`}),S(`div`,{class:`text-content-secondary dark:text-content-muted`},` Loading configuration... `)],-1)]])):s(n).error&&!l.value?(w(),C(`div`,Xl,[S(`div`,Zl,[o[22]||=S(`div`,{class:`text-red-500 dark:text-red-400 mb-2`},`Failed to load configuration`,-1),S(`div`,Ql,u(s(n).error),1),S(`button`,{onClick:o[2]||=e=>s(n).fetchStats(),class:`px-4 py-2 bg-cyan-500/20 dark:bg-primary/20 hover:bg-cyan-500/30 dark:hover:bg-primary/30 text-cyan-900 dark:text-white rounded-lg border border-cyan-500/50 dark:border-primary/50 transition-colors`},` Retry `)])])):(w(),C(`div`,$l,[m(S(`div`,null,[v(ve,{key:`radio-settings`})],512),[[P,a.value===`radio`]]),m(S(`div`,null,[v(xt,{key:`repeater-settings`})],512),[[P,a.value===`repeater`]]),m(S(`div`,null,[v(oo,{key:`advert-settings`})],512),[[P,a.value===`advert`]]),m(S(`div`,null,[v(Nt,{key:`duty-cycle`})],512),[[P,a.value===`duty`]]),m(S(`div`,null,[v(qt,{key:`transmission-delays`})],512),[[P,a.value===`delays`]]),m(S(`div`,null,[v(qr,{key:`transport-keys`})],512),[[P,a.value===`transport`]]),m(S(`div`,null,[v(xi,{key:`api-tokens`})],512),[[P,a.value===`api-tokens`]]),m(S(`div`,null,[v(Ki,{key:`web-settings`})],512),[[P,a.value===`web`]]),m(S(`div`,null,[v(Cs,{key:`letsmesh-settings`})],512),[[P,a.value===`observer`]]),m(S(`div`,null,[v(kc,{key:`backup-restore`})],512),[[P,a.value===`backup`]]),m(S(`div`,null,[v(El,{key:`database-management`})],512),[[P,a.value===`database`]])]))])])])}}}),[[`__scopeId`,`data-v-f5e6ec18`]]);export{eu as default}; |