mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-07-13 21:31:31 +02:00
65 lines
87 KiB
JavaScript
65 lines
87 KiB
JavaScript
import{r as e}from"./chunk-DECur_0Z.js";import{E as t,H as n,N as r,O as i,P as a,T as o,Y as s,b as c,c as l,f as u,g as d,gt as f,ht as p,i as m,j as h,l as g,m as _,mt as v,o as y,p as b,r as x,s as S,u as C,w}from"./runtime-core.esm-bundler-BiwffnQU.js";import{t as T}from"./api-DRn_D8oU.js";import{t as E}from"./system-DN2LtoaR.js";import{n as D,r as O,t as k}from"./dataService-C7SHAYZL.js";import{t as A}from"./_plugin-vue_export-helper-TcpyXLsZ.js";import{_ as j,h as M,m as N,p as P,u as F}from"./index-Bwi6QvPf.js";import{t as I}from"./leaflet-src-h-Ags50K.js";/* empty css */import{a as L,i as R,l as z,o as B,r as ee,s as V,u as H}from"./formatters-7ihR6KRV.js";import{n as U,t as W}from"./preferences-BlQds_au.js";import{t as G}from"./useSignalQuality-gmzVl2Tz.js";var K={class:`modal-card max-w-md`},te={class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mb-6`},q={class:`flex items-center gap-3`},ne={class:`flex-1 min-w-0`},re={class:`text-content-primary dark:text-content-primary font-medium truncate`},ie={class:`text-content-secondary dark:text-content-muted text-sm font-mono`},ae={key:0,class:`text-white/50 text-xs`},oe={key:1,class:`text-white/50 text-xs`},se=d({__name:`DeleteNeighborModal`,props:{show:{type:Boolean},neighbor:{}},emits:[`close`,`delete`],setup(e,{emit:n}){let r=e,i=n,a=()=>{r.neighbor&&(i(`delete`,r.neighbor.id),o())},o=()=>{i(`close`)};return(n,r)=>(t(),l(m,{to:`body`},[e.show&&e.neighbor?(t(),C(`div`,{key:0,onClick:r[0]||=j(e=>o(),[`self`]),class:`modal-backdrop-heavy`},[S(`div`,K,[S(`div`,{class:`flex items-center gap-3 mb-6`},[r[2]||=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),r[3]||=S(`div`,null,[S(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Delete Neighbor `),S(`p`,{class:`text-content-secondary dark:text-content-muted text-sm mt-1`},` Are you sure you want to delete this neighbor? `)],-1),S(`button`,{onClick:o,class:`ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...r[1]||=[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`,te,[S(`div`,q,[S(`div`,ne,[S(`div`,re,f(e.neighbor?.node_name||e.neighbor?.long_name||e.neighbor?.short_name||`Unknown`),1),S(`div`,ie,` ID: `+f(e.neighbor?.node_num_hex||e.neighbor?.node_num||e.neighbor?.id||`N/A`),1),e.neighbor?.contact_type?(t(),C(`div`,ae,f(e.neighbor.contact_type),1)):g(``,!0),e.neighbor?.hw_model?(t(),C(`div`,oe,f(e.neighbor.hw_model),1)):g(``,!0)])])]),r[4]||=S(`div`,{class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},[S(`div`,{class:`flex items-center gap-2 text-accent-red text-sm`},[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 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z`})]),S(`span`,null,`This action cannot be undone`)])],-1),S(`div`,{class:`flex gap-3`},[S(`button`,{onClick:o,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`,{onClick:a,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`},` Delete `)])])])):g(``,!0)]))}}),ce={class:`bg-gradient-to-r from-primary/20 to-accent-cyan/20 border-b border-stroke-subtle dark:border-stroke/10 px-6 py-4`},le={class:`flex items-center justify-between`},ue={class:`flex items-center gap-3`},J={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},de={class:`p-6`},fe={key:0,class:`text-center py-8`},pe={key:1,class:`text-center py-8`},me={class:`text-content-secondary dark:text-content-muted text-sm`},he={key:2,class:`space-y-4`},ge={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},_e={class:`flex items-center justify-between mb-2`},ve={class:`flex items-baseline gap-2`},ye={class:`text-3xl font-bold text-content-primary dark:text-content-primary`},be={class:`grid grid-cols-2 gap-3`},xe={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},Se={class:`flex items-center gap-2 mb-2`},Ce={class:`flex gap-0.5`},we={class:`flex items-baseline gap-1`},Te={class:`text-xl font-bold text-content-primary dark:text-content-primary`},Ee={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},De={class:`flex items-baseline gap-1`},Oe={class:`text-xl font-bold text-content-primary dark:text-content-primary`},ke={key:0,class:`flex items-start gap-3 bg-amber-500/10 border border-amber-500/30 rounded-[12px] p-3`},Ae={class:`text-xs leading-relaxed`},je={class:`font-semibold text-amber-600 dark:text-amber-400 mb-0.5`},Me={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},Ne={class:`relative`},Pe={class:`flex items-center gap-2 overflow-x-auto pb-2`},Fe={key:0,class:`relative flex items-center`},Ie={key:0,class:`absolute left-1/2 -translate-x-1/2 animate-pulse`},Le={class:`text-content-muted dark:text-content-muted text-xs mt-2 flex items-center justify-between`},Re={key:0,class:`text-cyan-500 dark:text-primary animate-pulse`},ze={class:`flex items-center justify-between text-xs text-content-muted dark:text-content-muted pt-2`},Be=A(d({__name:`PingResultModal`,props:{show:{type:Boolean},nodeName:{default:null},result:{default:null},error:{default:null},loading:{type:Boolean,default:!1}},emits:[`close`],setup(e,{emit:a}){let o=e,s=a,c=E(),{getSignalQuality:u}=G(),d=n(0),p=n(!1),b=y(()=>{let e=c.stats?.config?.radio?.spreading_factor??7,t=c.stats?.config?.radio?.bandwidth??125,n=c.stats?.config?.radio?.coding_rate??5;return 2**e/t*(8+4.25*(n-4)+20)}),w=y(()=>{if(!o.result)return{color:`text-gray-400`,label:`Unknown`};let e=o.result.rtt_ms,t=b.value,n=o.result.path.length,r=2*t*n+500*n;return e<r*2.5?{color:`text-green-600 dark:text-green-400`,label:`Excellent`}:e<r*4?{color:`text-yellow-600 dark:text-yellow-400`,label:`Good`}:e<r*7?{color:`text-orange-600 dark:text-orange-400`,label:`Fair`}:{color:`text-red-600 dark:text-red-400`,label:`Poor`}}),T=y(()=>{if(!o.result)return{bars:0,color:`text-gray-400`};let e=u(o.result.rssi);return{bars:e.bars,color:e.color}}),D=y(()=>{if(!o.result)return 0;if(o.result.path_hash_mode!==void 0)return o.result.path_hash_mode;let e=o.result.path.reduce((e,t)=>{let n=t.replace(/^0x/i,``);return Math.max(e,n.length)},0);return e>4?2:e>2?1:0}),O=y(()=>D.value>0),k=y(()=>({0:`1-byte`,1:`2-byte`,2:`3-byte`})[D.value]??`1-byte`);h(()=>o.result,e=>{if(e&&!p.value){p.value=!0,d.value=0;let t=e.path.length,n=1500/(t*2),r=0,i=t*2-2,a=()=>{r<=i?(d.value=r/i,r++,setTimeout(a,n)):(p.value=!1,d.value=1)};setTimeout(a,100)}},{immediate:!0});let A=y(()=>{if(!o.result||!p.value)return-1;let e=o.result.path.length;if(e<=1)return-1;let t=d.value,n=.5;if(t<=n)return t/n*(e-1);{let r=(t-n)/n;return(e-1)*(1-r)}}),M=()=>{s(`close`)};return(n,a)=>(t(),l(m,{to:`body`},[_(F,{name:`modal`},{default:r(()=>[e.show?(t(),C(`div`,{key:0,class:`fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[300] p-4`,onClick:j(M,[`self`])},[S(`div`,{class:`glass-card backdrop-blur-xl border border-stroke-subtle dark:border-white/20 rounded-[20px] shadow-2xl w-full max-w-md overflow-hidden`,onClick:a[0]||=j(()=>{},[`stop`])},[S(`div`,ce,[S(`div`,le,[S(`div`,ue,[a[2]||=S(`div`,{class:`p-2 bg-cyan-400/20 dark:bg-primary/20 rounded-lg`},[S(`svg`,{class:`w-5 h-5 text-cyan-500 dark:text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[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.393c5.857-5.857 15.355-5.857 21.213 0`})])],-1),S(`div`,null,[a[1]||=S(`h2`,{class:`text-xl font-bold text-content-primary dark:text-content-primary`},` Ping Result `,-1),e.nodeName?(t(),C(`p`,J,f(e.nodeName),1)):g(``,!0)])]),S(`button`,{onClick:M,class:`p-2 hover:bg-stroke-subtle dark:hover:bg-white/10 rounded-lg transition-colors text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary`},[...a[3]||=[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`,de,[e.loading?(t(),C(`div`,fe,[...a[4]||=[S(`div`,{class:`animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4`},null,-1),S(`p`,{class:`text-content-secondary dark:text-content-muted`},`Sending ping...`,-1),S(`p`,{class:`text-content-muted dark:text-content-muted text-sm mt-1`},` Waiting for response... `,-1)]])):e.error?(t(),C(`div`,pe,[a[5]||=S(`div`,{class:`p-3 bg-accent-red/10 rounded-full w-16 h-16 mx-auto mb-4 flex items-center justify-center`},[S(`svg`,{class:`w-8 h-8 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-3L13.732 4c-.77-1.333-1.964-1.333-2.732 0L3.268 16c-.77 1.333.192 3 1.732 3z`})])],-1),a[6]||=S(`h3`,{class:`text-accent-red font-semibold mb-2`},`Ping Failed`,-1),S(`p`,me,f(e.error),1)])):e.result?(t(),C(`div`,he,[S(`div`,ge,[S(`div`,_e,[a[7]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`Round-Trip Time`,-1),S(`span`,{class:v([`text-xs font-medium px-2 py-1 rounded-full`,w.value.color,`bg-current/10`])},f(w.value.label),3)]),S(`div`,ve,[S(`span`,ye,f(e.result.rtt_ms.toFixed(2)),1),a[8]||=S(`span`,{class:`text-content-secondary dark:text-content-muted`},`ms`,-1)])]),S(`div`,be,[S(`div`,xe,[S(`div`,Se,[a[9]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`RSSI`,-1),S(`div`,Ce,[(t(),C(x,null,i(5,e=>S(`div`,{key:e,class:v([`w-1 h-3 rounded-sm`,e<=T.value.bars?T.value.color:`bg-stroke-subtle dark:bg-stroke/10`])},null,2)),64))])]),S(`div`,we,[S(`span`,Te,f(e.result.rssi),1),a[10]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs`},`dBm`,-1)])]),S(`div`,Ee,[a[12]||=S(`div`,{class:`text-content-secondary dark:text-content-muted text-sm mb-2`},`SNR`,-1),S(`div`,De,[S(`span`,Oe,f(e.result.snr_db),1),a[11]||=S(`span`,{class:`text-content-secondary dark:text-content-muted text-xs`},`dB`,-1)])])]),O.value?(t(),C(`div`,ke,[a[14]||=S(`svg`,{class:`w-5 h-5 text-amber-500 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.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-1.964-1.333-2.732 0L3.268 16c-.77 1.333.192 3 1.732 3z`})],-1),S(`div`,Ae,[S(`p`,je,f(k.value)+` path hashes active `,1),a[13]||=S(`p`,{class:`text-content-secondary dark:text-content-muted`},` This result uses multi-byte path hashes. The repeater being traced must be running firmware that supports multi-byte path hashes. Repeaters on older firmware will not respond to or correctly route these trace packets. `,-1)])])):g(``,!0),S(`div`,Me,[a[17]||=S(`div`,{class:`text-content-secondary dark:text-content-muted text-sm mb-3`},` Network Path `,-1),S(`div`,Ne,[S(`div`,Pe,[(t(!0),C(x,null,i(e.result.path,(n,i)=>(t(),C(`div`,{key:i,class:`flex items-center gap-2 flex-shrink-0 relative`},[S(`div`,{class:v([`bg-cyan-400/20 dark:bg-primary/20 text-cyan-600 dark:text-primary border border-cyan-400/40 dark:border-primary/30 px-3 py-1.5 rounded-lg text-sm font-mono transition-all duration-300`,p.value&&Math.floor(A.value)===i?`ring-2 ring-cyan-400/50 dark:ring-primary/50 scale-105`:``])},f(n),3),i<e.result.path.length-1?(t(),C(`div`,Fe,[a[16]||=S(`svg`,{class:`w-4 h-4 text-white/40 flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`})],-1),_(F,{name:`packet`},{default:r(()=>[p.value&&A.value>=i&&A.value<i+1?(t(),C(`div`,Ie,[...a[15]||=[S(`svg`,{class:`w-3 h-3 text-cyan-500 dark:text-primary drop-shadow-[0_0_6px_rgba(6,182,212,0.8)] dark:drop-shadow-[0_0_6px_rgba(59,130,246,0.8)]`,fill:`currentColor`,viewBox:`0 0 24 24`},[S(`circle`,{cx:`12`,cy:`12`,r:`8`})],-1)]])):g(``,!0)]),_:2},1024)])):g(``,!0)]))),128))])]),S(`div`,Le,[S(`span`,null,f(e.result.path.length)+` hop`+f(e.result.path.length===1?``:`s`),1),p.value?(t(),C(`span`,Re,`● Tracing route...`)):g(``,!0)])]),S(`div`,ze,[S(`span`,null,`Target: `+f(e.result.target_id),1),S(`span`,null,`Tag: #`+f(e.result.tag),1)])])):g(``,!0)]),S(`div`,{class:`border-t border-stroke-subtle dark:border-stroke/10 px-6 py-4`},[S(`button`,{onClick:M,class:`w-full py-2.5 bg-gradient-to-r from-cyan-400 to-cyan-500 text-white hover:from-cyan-500 hover:to-cyan-600 dark:bg-primary/20 dark:text-primary dark:border dark:border-primary/30 dark:hover:bg-primary/30 dark:from-transparent dark:to-transparent rounded-lg font-medium transition-all shadow-[0_2px_12px_rgba(6,182,212,0.3)] dark:shadow-none`},` Close `)])])])):g(``,!0)]),_:1})]))}}),[[`__scopeId`,`data-v-023c1904`]]),Y=e(I(),1),Ve={class:`bg-white dark:bg-surface-elevated backdrop-blur-xl rounded-[20px] shadow-2xl border border-stroke-subtle dark:border-white/20 flex flex-col h-full overflow-hidden`},He={class:`flex items-center justify-between p-8 pb-4 flex-shrink-0`},Ue={class:`flex-1 min-w-0`},We={class:`text-2xl font-bold text-content-primary dark:text-content-primary mb-1`},Ge={class:`text-content-secondary dark:text-content-muted text-sm font-mono break-all`},Ke={class:`flex items-center gap-2`},qe={class:`flex-1 overflow-y-auto custom-scrollbar px-8`},Je={class:`mb-6`},Ye={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},Xe={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Ze={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Qe={class:`text-content-primary dark:text-content-primary font-medium`},$e={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},et={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},tt={class:`text-content-primary dark:text-content-primary font-medium`},nt={class:`mb-6`},rt={class:`grid grid-cols-1 md:grid-cols-3 gap-4`},it={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},at={class:`text-content-primary dark:text-content-primary font-medium`},ot={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},st={class:`text-content-primary dark:text-content-primary font-medium`},ct={key:0,class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},lt={class:`flex items-center gap-2`},ut={class:`flex items-end gap-0.5`},dt={class:`mb-6`},ft={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},pt={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},mt={class:`text-content-primary dark:text-content-primary text-sm`},ht={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},gt={class:`text-content-primary dark:text-content-primary text-sm`},_t={key:0,class:`mb-6`},vt={class:`grid grid-cols-1 md:grid-cols-3 gap-4 mb-4`},yt={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},bt={class:`text-content-primary dark:text-content-primary font-mono text-sm`},xt={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},St={class:`text-content-primary dark:text-content-primary font-mono text-sm`},Ct={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},wt={class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},Tt={key:0,class:`text-content-primary dark:text-content-primary font-medium`},Et={class:`p-8 pt-4 border-t border-stroke-subtle dark:border-white/10 flex-shrink-0`},Dt=A(d({name:`NeighborDetailsModal`,__name:`NeighborDetailsModal`,props:{neighbor:{},isOpen:{type:Boolean},baseLatitude:{default:null},baseLongitude:{default:null}},emits:[`close`],setup(e,{emit:a}){let{getSignalQuality:o}=G(),c=n(`Copy`),u=e,d=a,w=n(),T=null,E=e=>({Unknown:`Unknown`,"Chat Node":`Chat Node`,Repeater:`Repeater`,"Room Server":`Room Server`,"Hybrid Node":`Hybrid Node`})[e]||e,D=e=>({Unknown:`text-gray-600 dark:text-gray-400`,"Chat Node":`text-blue-600 dark:text-blue-400`,Repeater:`text-emerald-600 dark:text-emerald-400`,"Room Server":`text-purple-600 dark:text-purple-400`,"Hybrid Node":`text-amber-600 dark:text-amber-400`})[e]||`text-gray-600 dark:text-gray-400`,O=async()=>{if(!u.neighbor?.latitude||!u.neighbor?.longitude)return;let e=`${u.neighbor.latitude.toFixed(6)}, ${u.neighbor.longitude.toFixed(6)}`;try{await navigator.clipboard.writeText(e),c.value=`Copied!`,setTimeout(()=>{c.value=`Copy`},2e3)}catch(e){console.error(`Failed to copy coordinates:`,e),c.value=`Failed`,setTimeout(()=>{c.value=`Copy`},2e3)}},k=y(()=>{if(!u.neighbor?.latitude||!u.neighbor?.longitude||!u.baseLatitude||!u.baseLongitude)return null;let e=(u.neighbor.latitude-u.baseLatitude)*Math.PI/180,t=(u.neighbor.longitude-u.baseLongitude)*Math.PI/180,n=Math.sin(e/2)*Math.sin(e/2)+Math.cos(u.baseLatitude*Math.PI/180)*Math.cos(u.neighbor.latitude*Math.PI/180)*Math.sin(t/2)*Math.sin(t/2);return 6371*(2*Math.atan2(Math.sqrt(n),Math.sqrt(1-n)))}),A=y(()=>u.neighbor?.latitude!==null&&u.neighbor?.longitude!==null&&u.neighbor?.latitude!==0&&u.neighbor?.longitude!==0&&Math.abs(u.neighbor?.latitude??0)<=90&&Math.abs(u.neighbor?.longitude??0)<=180),M=()=>{if(!w.value||!u.neighbor||!A.value)return;T&&=(T.remove(),null);let e=document.documentElement.classList.contains(`dark`);T=Y.default.map(w.value,{center:[u.neighbor.latitude,u.neighbor.longitude],zoom:13,zoomControl:!0,attributionControl:!1});let t=e?`https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png`:`https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png`;Y.default.tileLayer(t,{maxZoom:19,attribution:`© OpenStreetMap © CARTO`}).addTo(T);let n=Y.default.divIcon({className:`custom-marker`,html:`<div class="w-8 h-8 rounded-full bg-blue-500 border-2 border-white shadow-lg flex items-center justify-center text-white font-bold text-xs">${u.neighbor.node_name?.charAt(0)||`?`}</div>`,iconSize:[32,32],iconAnchor:[16,16]});if(Y.default.marker([u.neighbor.latitude,u.neighbor.longitude],{icon:n}).addTo(T).bindPopup(`<b>${u.neighbor.node_name||`Unknown`}</b><br>${u.neighbor.pubkey.slice(0,8)}...`),u.baseLatitude!==null&&u.baseLongitude!==null&&u.baseLatitude!==0&&u.baseLongitude!==0&&Math.abs(u.baseLatitude)<=90&&Math.abs(u.baseLongitude)<=180){let e=Y.default.divIcon({className:`custom-marker`,html:`<div class="w-8 h-8 rounded-full bg-green-500 border-2 border-white shadow-lg flex items-center justify-center text-white font-bold text-xs">B</div>`,iconSize:[32,32],iconAnchor:[16,16]});Y.default.marker([u.baseLatitude,u.baseLongitude],{icon:e}).addTo(T).bindPopup(`<b>Base Station</b>`),Y.default.polyline([[u.baseLatitude,u.baseLongitude],[u.neighbor.latitude,u.neighbor.longitude]],{color:`#3b82f6`,weight:2,opacity:.6,dashArray:`5, 10`}).addTo(T);let t=Y.default.latLngBounds([u.baseLatitude,u.baseLongitude],[u.neighbor.latitude,u.neighbor.longitude]);T.fitBounds(t,{padding:[50,50]})}},N=e=>{e.key===`Escape`&&d(`close`)},P=e=>{e.target===e.currentTarget&&d(`close`)};h(()=>u.isOpen,e=>{e?(document.body.style.overflow=`hidden`,setTimeout(()=>{A.value&&M()},100)):(document.body.style.overflow=``,T&&=(T.remove(),null))},{immediate:!0});let I=y(()=>u.neighbor?o(u.neighbor.rssi):null);return(n,a)=>(t(),l(m,{to:`body`},[_(F,{name:`modal`,appear:``},{default:r(()=>[e.isOpen&&e.neighbor?(t(),C(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 overflow-hidden`,onClick:P,onKeydown:N,tabindex:`0`},[a[21]||=S(`div`,{class:`absolute inset-0 bg-black/60 backdrop-blur-md pointer-events-none`},null,-1),S(`div`,{class:`relative w-full max-w-4xl max-h-[90vh] flex flex-col`,onClick:a[2]||=j(()=>{},[`stop`])},[S(`div`,Ve,[S(`div`,He,[S(`div`,Ue,[S(`h2`,We,f(e.neighbor.node_name||`Unknown Node`),1),S(`p`,Ge,f(e.neighbor.pubkey),1)]),S(`div`,Ke,[S(`button`,{onClick:a[0]||=e=>d(`close`),class:`w-8 h-8 flex items-center justify-center rounded-full bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors duration-200 text-gray-700 dark:text-white hover:text-gray-900 dark:hover:text-white`},[...a[3]||=[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`,qe,[S(`div`,Je,[a[8]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Basic Information `,-1),S(`div`,Ye,[S(`div`,Xe,[a[4]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Contact Type `,-1),S(`div`,{class:v([`font-medium`,D(e.neighbor.contact_type)])},f(E(e.neighbor.contact_type)),3)]),S(`div`,Ze,[a[5]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Route Type `,-1),S(`div`,Qe,f(s(B)(e.neighbor.route_type)),1)]),S(`div`,$e,[a[6]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Zero Hop `,-1),S(`div`,{class:v([`font-medium`,e.neighbor.zero_hop?`text-green-600 dark:text-green-400`:`text-gray-600 dark:text-gray-400`])},f(e.neighbor.zero_hop?`Yes`:`No`),3)]),S(`div`,et,[a[7]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Advert Count `,-1),S(`div`,tt,f(e.neighbor.advert_count.toLocaleString()),1)])])]),S(`div`,nt,[a[13]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Signal Quality `,-1),S(`div`,rt,[S(`div`,it,[a[9]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` RSSI `,-1),S(`div`,at,f(s(L)(e.neighbor.rssi)),1)]),S(`div`,ot,[a[10]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` SNR `,-1),S(`div`,st,f(s(V)(e.neighbor.snr)),1)]),I.value?(t(),C(`div`,ct,[a[12]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Signal Strength `,-1),S(`div`,lt,[S(`div`,ut,[(t(),C(x,null,i(5,e=>S(`div`,{key:e,class:v([`w-1 transition-colors`,e<=I.value.bars?I.value.color:`text-gray-600 dark:text-gray-700`]),style:p({height:`${4+e*2}px`})},[...a[11]||=[S(`div`,{class:`w-full h-full bg-current rounded-sm`},null,-1)]],6)),64))]),S(`span`,{class:v([`text-sm font-medium`,I.value.color])},f(I.value.quality),3)])])):g(``,!0)])]),S(`div`,dt,[a[16]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Timeline `,-1),S(`div`,ft,[S(`div`,pt,[a[14]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` First Seen `,-1),S(`div`,mt,f(s(z)(e.neighbor.first_seen)),1)]),S(`div`,ht,[a[15]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Last Seen `,-1),S(`div`,gt,f(s(z)(e.neighbor.last_seen)),1)])])]),A.value?(t(),C(`div`,_t,[a[20]||=S(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Location `,-1),S(`div`,vt,[S(`div`,yt,[a[17]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Latitude `,-1),S(`div`,bt,f(e.neighbor.latitude?.toFixed(6)),1)]),S(`div`,xt,[a[18]||=S(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Longitude `,-1),S(`div`,St,f(e.neighbor.longitude?.toFixed(6)),1)]),S(`div`,Ct,[S(`div`,wt,f(k.value===null?`Coordinates`:`Distance`),1),k.value===null?(t(),C(`button`,{key:1,onClick:O,class:`w-full px-3 py-1.5 bg-primary hover:bg-primary/90 dark:bg-gray-700 dark:hover:bg-gray-600 text-white text-sm font-medium rounded-lg transition-colors flex items-center justify-center gap-1.5`},[a[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:`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(` `+f(c.value),1)])):(t(),C(`div`,Tt,f(`${k.value.toFixed(2)} km`),1))])]),S(`div`,{ref_key:`mapContainer`,ref:w,class:`w-full h-96 rounded-[12px] overflow-hidden border border-stroke-subtle dark:border-white/10`},null,512)])):g(``,!0)]),S(`div`,Et,[S(`button`,{onClick:a[1]||=e=>d(`close`),class:`w-full px-4 py-2.5 bg-primary hover:bg-primary/90 dark:bg-gray-700 dark:hover:bg-gray-600 text-white font-medium rounded-lg transition-colors`},` Close `)])])])],32)):g(``,!0)]),_:1})]))}}),[[`__scopeId`,`data-v-8b010f09`]]),Ot=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],kt=1,X=8,At=class e{static from(t){if(!(t instanceof ArrayBuffer))throw Error(`Data must be an instance of ArrayBuffer.`);let[n,r]=new Uint8Array(t,0,2);if(n!==219)throw Error(`Data does not appear to be in a KDBush format.`);let i=r>>4;if(i!==kt)throw Error(`Got v${i} data when expected v${kt}.`);let a=Ot[r&15];if(!a)throw Error(`Unrecognized array type.`);let[o]=new Uint16Array(t,2,1),[s]=new Uint32Array(t,4,1);return new e(s,o,a,t)}constructor(e,t=64,n=Float64Array,r){if(isNaN(e)||e<0)throw Error(`Unpexpected numItems value: ${e}.`);this.numItems=+e,this.nodeSize=Math.min(Math.max(+t,2),65535),this.ArrayType=n,this.IndexArrayType=e<65536?Uint16Array:Uint32Array;let i=Ot.indexOf(this.ArrayType),a=e*2*this.ArrayType.BYTES_PER_ELEMENT,o=e*this.IndexArrayType.BYTES_PER_ELEMENT,s=(8-o%8)%8;if(i<0)throw Error(`Unexpected typed array class: ${n}.`);r&&r instanceof ArrayBuffer?(this.data=r,this.ids=new this.IndexArrayType(this.data,X,e),this.coords=new this.ArrayType(this.data,X+o+s,e*2),this._pos=e*2,this._finished=!0):(this.data=new ArrayBuffer(X+a+o+s),this.ids=new this.IndexArrayType(this.data,X,e),this.coords=new this.ArrayType(this.data,X+o+s,e*2),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,(kt<<4)+i]),new Uint16Array(this.data,2,1)[0]=t,new Uint32Array(this.data,4,1)[0]=e)}add(e,t){let n=this._pos>>1;return this.ids[n]=n,this.coords[this._pos++]=e,this.coords[this._pos++]=t,n}finish(){let e=this._pos>>1;if(e!==this.numItems)throw Error(`Added ${e} items when expected ${this.numItems}.`);return jt(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(e,t,n,r){if(!this._finished)throw Error(`Data not yet indexed - call index.finish().`);let{ids:i,coords:a,nodeSize:o}=this,s=[0,i.length-1,0],c=[];for(;s.length;){let l=s.pop()||0,u=s.pop()||0,d=s.pop()||0;if(u-d<=o){for(let o=d;o<=u;o++){let s=a[2*o],l=a[2*o+1];s>=e&&s<=n&&l>=t&&l<=r&&c.push(i[o])}continue}let f=d+u>>1,p=a[2*f],m=a[2*f+1];p>=e&&p<=n&&m>=t&&m<=r&&c.push(i[f]),(l===0?e<=p:t<=m)&&(s.push(d),s.push(f-1),s.push(1-l)),(l===0?n>=p:r>=m)&&(s.push(f+1),s.push(u),s.push(1-l))}return c}within(e,t,n){if(!this._finished)throw Error(`Data not yet indexed - call index.finish().`);let{ids:r,coords:i,nodeSize:a}=this,o=[0,r.length-1,0],s=[],c=n*n;for(;o.length;){let l=o.pop()||0,u=o.pop()||0,d=o.pop()||0;if(u-d<=a){for(let n=d;n<=u;n++)Ft(i[2*n],i[2*n+1],e,t)<=c&&s.push(r[n]);continue}let f=d+u>>1,p=i[2*f],m=i[2*f+1];Ft(p,m,e,t)<=c&&s.push(r[f]),(l===0?e-n<=p:t-n<=m)&&(o.push(d),o.push(f-1),o.push(1-l)),(l===0?e+n>=p:t+n>=m)&&(o.push(f+1),o.push(u),o.push(1-l))}return s}};function jt(e,t,n,r,i,a){if(i-r<=n)return;let o=r+i>>1;Mt(e,t,o,r,i,a),jt(e,t,n,r,o-1,1-a),jt(e,t,n,o+1,i,1-a)}function Mt(e,t,n,r,i,a){for(;i>r;){if(i-r>600){let o=i-r+1,s=n-r+1,c=Math.log(o),l=.5*Math.exp(2*c/3),u=.5*Math.sqrt(c*l*(o-l)/o)*(s-o/2<0?-1:1);Mt(e,t,n,Math.max(r,Math.floor(n-s*l/o+u)),Math.min(i,Math.floor(n+(o-s)*l/o+u)),a)}let o=t[2*n+a],s=r,c=i;for(Nt(e,t,r,n),t[2*i+a]>o&&Nt(e,t,r,i);s<c;){for(Nt(e,t,s,c),s++,c--;t[2*s+a]<o;)s++;for(;t[2*c+a]>o;)c--}t[2*r+a]===o?Nt(e,t,r,c):(c++,Nt(e,t,c,i)),c<=n&&(r=c+1),n<=c&&(i=c-1)}}function Nt(e,t,n,r){Pt(e,n,r),Pt(t,2*n,2*r),Pt(t,2*n+1,2*r+1)}function Pt(e,t,n){let r=e[t];e[t]=e[n],e[n]=r}function Ft(e,t,n,r){let i=e-n,a=t-r;return i*i+a*a}var It={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:e=>e},Lt=Math.fround||(e=>(t=>(e[0]=+t,e[0])))(new Float32Array(1)),Z=2,Q=3,Rt=4,$=5,zt=6,Bt=class{constructor(e){this.options=Object.assign(Object.create(It),e),this.trees=Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(e){let{log:t,minZoom:n,maxZoom:r}=this.options;t&&console.time(`total time`);let i=`prepare ${e.length} points`;t&&console.time(i),this.points=e;let a=[];for(let t=0;t<e.length;t++){let n=e[t];if(!n.geometry)continue;let[r,i]=n.geometry.coordinates,o=Lt(Ut(r)),s=Lt(Wt(i));a.push(o,s,1/0,t,-1,1),this.options.reduce&&a.push(0)}let o=this.trees[r+1]=this._createTree(a);t&&console.timeEnd(i);for(let e=r;e>=n;e--){let n=+Date.now();o=this.trees[e]=this._createTree(this._cluster(o,e)),t&&console.log(`z%d: %d clusters in %dms`,e,o.numItems,+Date.now()-n)}return t&&console.timeEnd(`total time`),this}getClusters(e,t){let n=((e[0]+180)%360+360)%360-180,r=Math.max(-90,Math.min(90,e[1])),i=e[2]===180?180:((e[2]+180)%360+360)%360-180,a=Math.max(-90,Math.min(90,e[3]));if(e[2]-e[0]>=360)n=-180,i=180;else if(n>i){let e=this.getClusters([n,r,180,a],t),o=this.getClusters([-180,r,i,a],t);return e.concat(o)}let o=this.trees[this._limitZoom(t)],s=o.range(Ut(n),Wt(a),Ut(i),Wt(r)),c=o.data,l=[];for(let e of s){let t=this.stride*e;l.push(c[t+$]>1?Vt(c,t,this.clusterProps):this.points[c[t+Q]])}return l}getChildren(e){let t=this._getOriginId(e),n=this._getOriginZoom(e),r=`No cluster with the specified id.`,i=this.trees[n];if(!i)throw Error(r);let a=i.data;if(t*this.stride>=a.length)throw Error(r);let o=this.options.radius/(this.options.extent*2**(n-1)),s=a[t*this.stride],c=a[t*this.stride+1],l=i.within(s,c,o),u=[];for(let t of l){let n=t*this.stride;a[n+Rt]===e&&u.push(a[n+$]>1?Vt(a,n,this.clusterProps):this.points[a[n+Q]])}if(u.length===0)throw Error(r);return u}getLeaves(e,t,n){t||=10,n||=0;let r=[];return this._appendLeaves(r,e,t,n,0),r}getTile(e,t,n){let r=this.trees[this._limitZoom(e)],i=2**e,{extent:a,radius:o}=this.options,s=o/a,c=(n-s)/i,l=(n+1+s)/i,u={features:[]};return this._addTileFeatures(r.range((t-s)/i,c,(t+1+s)/i,l),r.data,t,n,i,u),t===0&&this._addTileFeatures(r.range(1-s/i,c,1,l),r.data,i,n,i,u),t===i-1&&this._addTileFeatures(r.range(0,c,s/i,l),r.data,-1,n,i,u),u.features.length?u:null}getClusterExpansionZoom(e){let t=this._getOriginZoom(e)-1;for(;t<=this.options.maxZoom;){let n=this.getChildren(e);if(t++,n.length!==1)break;e=n[0].properties.cluster_id}return t}_appendLeaves(e,t,n,r,i){let a=this.getChildren(t);for(let t of a){let a=t.properties;if(a&&a.cluster?i+a.point_count<=r?i+=a.point_count:i=this._appendLeaves(e,a.cluster_id,n,r,i):i<r?i++:e.push(t),e.length===n)break}return i}_createTree(e){let t=new At(e.length/this.stride|0,this.options.nodeSize,Float32Array);for(let n=0;n<e.length;n+=this.stride)t.add(e[n],e[n+1]);return t.finish(),t.data=e,t}_addTileFeatures(e,t,n,r,i,a){for(let o of e){let e=o*this.stride,s=t[e+$]>1,c,l,u;if(s)c=Ht(t,e,this.clusterProps),l=t[e],u=t[e+1];else{let n=this.points[t[e+Q]];c=n.properties;let[r,i]=n.geometry.coordinates;l=Ut(r),u=Wt(i)}let d={type:1,geometry:[[Math.round(this.options.extent*(l*i-n)),Math.round(this.options.extent*(u*i-r))]],tags:c},f;f=s||this.options.generateId?t[e+Q]:this.points[t[e+Q]].id,f!==void 0&&(d.id=f),a.features.push(d)}}_limitZoom(e){return Math.max(this.options.minZoom,Math.min(Math.floor(+e),this.options.maxZoom+1))}_cluster(e,t){let{radius:n,extent:r,reduce:i,minPoints:a}=this.options,o=n/(r*2**t),s=e.data,c=[],l=this.stride;for(let n=0;n<s.length;n+=l){if(s[n+Z]<=t)continue;s[n+Z]=t;let r=s[n],u=s[n+1],d=e.within(s[n],s[n+1],o),f=s[n+$],p=f;for(let e of d){let n=e*l;s[n+Z]>t&&(p+=s[n+$])}if(p>f&&p>=a){let e=r*f,a=u*f,o,m=-1,h=((n/l|0)<<5)+(t+1)+this.points.length;for(let r of d){let c=r*l;if(s[c+Z]<=t)continue;s[c+Z]=t;let u=s[c+$];e+=s[c]*u,a+=s[c+1]*u,s[c+Rt]=h,i&&(o||(o=this._map(s,n,!0),m=this.clusterProps.length,this.clusterProps.push(o)),i(o,this._map(s,c)))}s[n+Rt]=h,c.push(e/p,a/p,1/0,h,-1,p),i&&c.push(m)}else{for(let e=0;e<l;e++)c.push(s[n+e]);if(p>1)for(let e of d){let n=e*l;if(!(s[n+Z]<=t)){s[n+Z]=t;for(let e=0;e<l;e++)c.push(s[n+e])}}}}return c}_getOriginId(e){return e-this.points.length>>5}_getOriginZoom(e){return(e-this.points.length)%32}_map(e,t,n){if(e[t+$]>1){let r=this.clusterProps[e[t+zt]];return n?Object.assign({},r):r}let r=this.points[e[t+Q]].properties,i=this.options.map(r);return n&&i===r?Object.assign({},i):i}};function Vt(e,t,n){return{type:`Feature`,id:e[t+Q],properties:Ht(e,t,n),geometry:{type:`Point`,coordinates:[Gt(e[t]),Kt(e[t+1])]}}}function Ht(e,t,n){let r=e[t+$],i=r>=1e4?`${Math.round(r/1e3)}k`:r>=1e3?`${Math.round(r/100)/10}k`:r,a=e[t+zt],o=a===-1?{}:Object.assign({},n[a]);return Object.assign(o,{cluster:!0,cluster_id:e[t+Q],point_count:r,point_count_abbreviated:i})}function Ut(e){return e/360+.5}function Wt(e){let t=Math.sin(e*Math.PI/180),n=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return n<0?0:n>1?1:n}function Gt(e){return(e-.5)*360}function Kt(e){let t=(180-e*360)*Math.PI/180;return 360*Math.atan(Math.exp(t))/Math.PI-90}var qt={class:`map-container`},Jt={key:0,class:`flex items-center justify-center h-96 glass-card backdrop-blur border border-black/6 dark:border-white/10 rounded-[12px] shadow-sm dark:shadow-none`},Yt={key:0,class:`flex items-center gap-2 text-content-secondary dark:text-content-muted`},Xt={key:1,class:`text-center text-content-primary dark:text-content-primary`},Zt={class:`hidden sm:inline`},Qt={key:3,class:`map-legend`},$t={class:`legend-footer`},en={key:4,class:`map-attribution`},tn=A(d({__name:`NetworkMap`,props:{adverts:{},baseLatitude:{default:null},baseLongitude:{default:null},statsLoading:{type:Boolean,default:!1},showLegend:{type:Boolean,default:!0}},emits:[`update:showLegend`],setup(e,{expose:r,emit:i}){typeof window<`u`&&!window.chrome&&(window.chrome={runtime:{}});let a=e,s=i,l=()=>{s(`update:showLegend`,!a.showLegend)},d=n(),p=null,m=n(new Map),_=null,v=n(new Map),b=n([]),x=n(!0),T=n(60),E=n(14),D=n(document.documentElement.classList.contains(`dark`)),O=new MutationObserver(()=>{let e=document.documentElement.classList.contains(`dark`);e!==D.value&&(D.value=e,p&&M())}),k=y(()=>a.baseLatitude!==null&&a.baseLongitude!==null&&typeof a.baseLatitude==`number`&&typeof a.baseLongitude==`number`&&a.baseLatitude!==0&&a.baseLongitude!==0&&Math.abs(a.baseLatitude)<=90&&Math.abs(a.baseLongitude)<=180),A=(e,t,n,r)=>{let i=(n-e)*Math.PI/180,a=(r-t)*Math.PI/180,o=Math.sin(i/2)*Math.sin(i/2)+Math.cos(e*Math.PI/180)*Math.cos(n*Math.PI/180)*Math.sin(a/2)*Math.sin(a/2);return 6371*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))},j=()=>{p&&=(b.value.forEach(e=>{p&&e.remove()}),b.value.length=0,p.remove(),null),m.value.clear(),v.value.clear(),_=null},M=async()=>{let e=p?.getZoom()||11,t=p?.getCenter()||(k.value?[a.baseLatitude,a.baseLongitude]:[0,0]);j(),await c(),await F(),p&&p.setView(t,e)},N=e=>{let t=new Map;return e.filter(e=>e.latitude!==null&&e.longitude!==null).map(e=>{let n=e.latitude,r=e.longitude,i=`${n.toFixed(6)}_${r.toFixed(6)}`,a=t.get(i)||0;if(t.set(i,a+1),a>0){let e=.001,t=a*60*(Math.PI/180);n+=Math.sin(t)*e*(a*.5),r+=Math.cos(t)*e*(a*.5)}return{type:`Feature`,properties:{advert:{...e,jittered_latitude:n,jittered_longitude:r}},geometry:{type:`Point`,coordinates:[r,n]}}})},P=e=>{_=new Bt({radius:T.value,maxZoom:E.value,minPoints:2}),_.load(e)},F=async()=>{if(!d.value||!k.value){console.warn(`Cannot initialize map: missing container or coordinates`);return}j(),await c();let e=a.baseLatitude,t=a.baseLongitude;p=Y.default.map(d.value,{center:[e,t],zoom:11,zoomControl:!0,attributionControl:!1,preferCanvas:!1});try{let e=D.value?`https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png`:`https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png`,t=D.value?`https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png`:`https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png`,n=Y.default.tileLayer(e,{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==`}),r=Y.default.tileLayer(t,{maxZoom:19,attribution:``,errorTileUrl:`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==`});n.addTo(p),r.addTo(p)}catch(e){console.warn(`Error loading tiles:`,e)}try{let n=(e,t=!1)=>{let n=t?16:12;return Y.default.divIcon({className:`custom-div-icon`,html:`<div style="background-color: ${e}; width: ${n}px; height: ${n}px; border-radius: 50%; border: 2px solid white; box-shadow: 0 2px 4px rgba(0,0,0,0.5);"></div>`,iconSize:[n+4,n+4],iconAnchor:[(n+4)/2,(n+4)/2]})},r=e=>{let t=e<10?30:e<100?40:50;return Y.default.divIcon({className:`custom-cluster-icon`,html:`
|
|
<div style="
|
|
width: ${t}px;
|
|
height: ${t}px;
|
|
background: rgba(170, 232, 232, 0.2);
|
|
border: 2px solid #AAE8E8;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
backdrop-filter: blur(10px);
|
|
box-shadow: 0 4px 12px rgba(170, 232, 232, 0.3);
|
|
color: #ffffff;
|
|
font-size: ${t<35?`11px`:`13px`};
|
|
font-weight: bold;
|
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
|
">
|
|
${e}
|
|
</div>
|
|
`,iconSize:[t,t],iconAnchor:[t/2,t/2]})},i=n(`#ef4444`,!0);Y.default.marker([e,t],{icon:i}).addTo(p).bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: #ef4444;">Base Station</strong><br>
|
|
<span class="text-sm" style="color: #9CA3AF;">Base Station</span><br>
|
|
<span class="text-xs" style="color: #6B7280;">${e.toFixed(6)}, ${t.toFixed(6)}</span>
|
|
</div>
|
|
`);let o={Unknown:`#9CA3AF`,"Chat Node":`#60A5FA`,Repeater:`#A5E5B6`,"Room Server":`#EBA0FC`,"Hybrid Node":`#FFC246`},s=(e,t,n,r,i=0)=>{if(!p||e.zero_hop!==!0)return;let a=e.jittered_latitude||e.latitude,o=e.jittered_longitude||e.longitude;if(a===null||o===null)return;let s=e.route_type||0,c=r,l=3,u=.7,d;s===2?(c=`#A5E5B6`,l=4,u=.9):s===1?(c=`#FFC246`,d=`10, 5`,u=.8):s===3?(c=`#059669`,l=5,u=.95):s===0?(c=`#ea580c`,d=`12, 6`,u=.8):(c=`#9CA3AF`,d=`2, 5`,u=.6);let f=[t,n],m=[a,o],h=Y.default.polyline([f,m],{color:c,weight:l,opacity:0,dashArray:d,className:`connection-line`}).addTo(p),g=Y.default.polyline([f,f],{color:c,weight:l,opacity:0,dashArray:d,className:`connection-line animated-line`}).addTo(p);setTimeout(()=>{let i=0;g.setStyle({opacity:u+.2});let s=()=>{i++;let c=i/30,d=f[0]+(m[0]-f[0])*c,_=f[1]+(m[1]-f[1])*c;g.setLatLngs([f,[d,_]]),i<30?setTimeout(s,30):setTimeout(()=>{p&&g&&g.remove(),h.setStyle({opacity:u}),h.on(`mouseover`,()=>{h.setStyle({weight:l+2,opacity:Math.min(u+.3,1)})}),h.on(`mouseout`,()=>{h.setStyle({weight:l,opacity:u})});let i=A(t,n,a,o);h.bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: ${r}">Connection to ${e.node_name||`Unknown Node`}</strong><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Distance: ${i.toFixed(2)} km</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Route: ${B(e.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Signal: ${L(e.rssi)} / ${V(e.snr)}</span>
|
|
</div>
|
|
`),b.value.push(h)},200)};s()},i)},c=()=>{if(!p||!_)return;let i=p.getBounds(),a=Math.floor(p.getZoom());v.value.forEach(e=>{p&&e.remove()}),v.value.clear(),b.value.forEach(e=>{p&&e.remove()}),b.value.length=0,_.getClusters([i.getWest(),i.getSouth(),i.getEast(),i.getNorth()],a).forEach(i=>{let[a,c]=i.geometry.coordinates,l=i.properties;if(l.cluster){let n=Y.default.marker([c,a],{icon:r(l.point_count||0)}).addTo(p);n.on(`click`,()=>{if(p&&_){let e=_.getClusterExpansionZoom(l.cluster_id);p.setView([c,a],e)}});let i=_.getLeaves(l.cluster_id,1/0).map(e=>`<div style="margin: 2px 0; color: ${o[e.properties.advert.contact_type]||o.Unknown};">
|
|
• ${e.properties.advert.node_name||`Unknown Node`} (${e.properties.advert.contact_type})
|
|
</div>`).join(``);n.bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: #AAE8E8;">Cluster: ${l.point_count} nodes</strong><br>
|
|
<div style="max-height: 200px; overflow-y: auto; margin-top: 8px;">
|
|
${i}
|
|
</div>
|
|
<div style="margin-top: 8px; font-size: 11px; color: #ffffff99;">
|
|
Click to zoom in and separate nodes
|
|
</div>
|
|
</div>
|
|
`),v.value.set(`cluster-${l.cluster_id}`,n);let u=A(e,t,c,a),d=Math.min(Math.floor(u*5),200);s({node_name:`Cluster of ${l.point_count} nodes`,contact_type:`Cluster`,route_type:2,rssi:null,snr:null,jittered_latitude:c,jittered_longitude:a,latitude:c,longitude:a},e,t,`#AAE8E8`,d)}else{let r=l.advert,i=o[r.contact_type]||o.Unknown,u=n(i),d=c,f=a,h=A(e,t,d,f),g=Y.default.marker([d,f],{icon:u}).addTo(p).bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: ${i}">${r.node_name||`Unknown Node`}</strong><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Type: ${r.contact_type}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Distance: ${h.toFixed(2)} km</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Signal: ${L(r.rssi)} / ${V(r.snr)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Route: ${B(r.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${z(r.last_seen)}</span>
|
|
${r.jittered_latitude?`<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>`:``}
|
|
</div>
|
|
`);m.value.set(r.pubkey,g),v.value.set(`node-${r.pubkey}`,g);let _=Math.min(Math.floor(h*5),200);s({...r,jittered_latitude:d,jittered_longitude:f},e,t,i,_)}})},l=(e,t)=>{let r=0;N(a.adverts).forEach(i=>{let a=i.properties.advert;if(a.latitude!==null&&a.longitude!==null){let i=o[a.contact_type]||o.Unknown,c=n(i),l=a.jittered_latitude||a.latitude,u=a.jittered_longitude||a.longitude,d=Y.default.marker([l,u],{icon:c}).addTo(p).bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: ${i}">${a.node_name||`Unknown Node`}</strong><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Type: ${a.contact_type}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Distance: ${A(e,t,l,u).toFixed(2)} km</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Signal: ${L(a.rssi)} / ${V(a.snr)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Route: ${B(a.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${z(a.last_seen)}</span>
|
|
${a.jittered_latitude?`<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>`:``}
|
|
</div>
|
|
`);m.value.set(a.pubkey,d);let f=d.getElement();f&&(f.style.opacity=`0`,f.style.transition=`opacity 0.5s ease-out`),s(a,e,t,i,r),setTimeout(()=>{f&&(f.style.opacity=`1`)},r+1e3),r+=100}})};if(x.value&&a.adverts.length>0)try{P(N(a.adverts));let n=Math.min(14,p.getZoom());p.setZoom(n),setTimeout(()=>{try{c()}catch(n){console.warn(`Error updating clusters:`,n),l(e,t)}},100),p.on(`moveend`,()=>{try{c()}catch(e){console.warn(`Error updating clusters on move:`,e)}}),p.on(`zoomend`,()=>{try{c()}catch(e){console.warn(`Error updating clusters on zoom:`,e)}})}catch(n){console.warn(`Error initializing clustering:`,n),l(e,t)}else l(e,t);setTimeout(()=>{p&&p.invalidateSize()},1e3)}catch(e){console.error(`Error initializing map:`,e)}};return r({highlightNode:e=>{let t=m.value.get(e);if(t){let e=t.getElement();if(e){let t=e.querySelector(`div`);t&&t.classList.add(`marker-highlight`)}}},unhighlightNode:e=>{let t=m.value.get(e);if(t){let e=t.getElement();if(e){let t=e.querySelector(`div`);t&&t.classList.remove(`marker-highlight`)}}},initializeOpenStreetMap:F}),h(()=>a.adverts,()=>{p&&k.value&&setTimeout(()=>{F()},100)},{immediate:!1}),h(k,e=>{e&&a.adverts.length>0&&!p&&c(()=>F())}),w(()=>{O.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`]}),k.value&&a.adverts.length>0&&setTimeout(()=>{F()},300)}),o(()=>{O.disconnect(),j()}),(n,r)=>(t(),C(`div`,qt,[k.value?(t(),C(`div`,{key:1,ref_key:`mapContainer`,ref:d,class:`leaflet-map-container h-96 w-full glass-card backdrop-blur border border-black/6 dark:border-white/10 rounded-[12px] overflow-hidden shadow-sm dark:shadow-none`,style:{"min-height":`384px`,position:`relative`}},null,512)):(t(),C(`div`,Jt,[a.statsLoading?(t(),C(`div`,Yt,[...r[0]||=[S(`div`,{class:`animate-spin rounded-full h-3 w-3 border-b-2 border-primary`},null,-1),S(`p`,{class:`text-xs sm:text-sm`},`Fetching base station location…`,-1)]])):(t(),C(`div`,Xt,[...r[1]||=[S(`svg`,{class:`w-8 h-8 mx-auto mb-2 text-content-muted dark:text-content-muted`,fill:`currentColor`,viewBox:`0 0 20 20`},[S(`path`,{d:`M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z`})],-1),S(`p`,{class:`text-sm text-content-primary dark:text-content-primary`},` No valid coordinates available `,-1),S(`p`,{class:`text-xs text-content-secondary dark:text-content-muted`},` Configure base station location to view map `,-1)]]))])),k.value&&e.adverts.length>0?(t(),C(`button`,{key:2,onClick:l,class:`absolute bottom-3 right-3 z-[200] flex items-center gap-2 px-3 py-2 bg-black/40 border border-white/10 rounded-lg text-white/80 hover:bg-white/10 hover:text-white transition-colors text-sm backdrop-blur-sm`},[r[2]||=S(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z`})],-1),S(`span`,Zt,f(e.showLegend?`Hide`:`Show`),1)])):g(``,!0),k.value&&e.adverts.length>0&&e.showLegend?(t(),C(`div`,Qt,[r[3]||=u(`<div class="legend-section" data-v-b3cb7479><div class="legend-subtitle" data-v-b3cb7479>Node Types</div><div class="legend-items" data-v-b3cb7479><div class="legend-item" data-v-b3cb7479><div class="legend-icon" style="background-color:#ef4444;" data-v-b3cb7479></div><span data-v-b3cb7479>Base Station</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-icon" style="background-color:#60a5fa;" data-v-b3cb7479></div><span data-v-b3cb7479>Chat Node</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-icon" style="background-color:#a5e5b6;" data-v-b3cb7479></div><span data-v-b3cb7479>Repeater</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-icon" style="background-color:#eba0fc;" data-v-b3cb7479></div><span data-v-b3cb7479>Room Server</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-icon" style="background-color:#ffc246;" data-v-b3cb7479></div><span data-v-b3cb7479>Hybrid Node</span></div></div></div><div class="legend-section" data-v-b3cb7479><div class="legend-subtitle" data-v-b3cb7479>Route Types</div><div class="legend-items" data-v-b3cb7479><div class="legend-item" data-v-b3cb7479><div class="legend-line" style="background:#a5e5b6;height:3px;" data-v-b3cb7479></div><span data-v-b3cb7479>Direct</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-line" style="background:#059669;height:4px;" data-v-b3cb7479></div><span data-v-b3cb7479>Transport Direct</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-line legend-line-dashed" style="background:#ffc246;" data-v-b3cb7479></div><span data-v-b3cb7479>Flood</span></div><div class="legend-item" data-v-b3cb7479><div class="legend-line legend-line-dashed" style="background:#ea580c;" data-v-b3cb7479></div><span data-v-b3cb7479>Transport Flood</span></div></div></div>`,2),S(`div`,$t,f(e.adverts.length)+` node`+f(e.adverts.length===1?``:`s`)+` visible `,1)])):g(``,!0),k.value?(t(),C(`div`,en,` © OpenStreetMap contributors © CARTO `)):g(``,!0)]))}}),[[`__scopeId`,`data-v-b3cb7479`]]),nn={class:`relative`,"data-menu-container":``},rn=d({__name:`NeighborMenu`,props:{neighbor:{},canPing:{type:Boolean}},emits:[`ping`,`delete`,`show-details`],setup(e,{emit:r}){let i=window.__neighborMenuManager||{activeMenu:null,setActiveMenu:e=>{if(i.activeMenu&&i.activeMenu!==e)try{i.activeMenu.closeMenu()}catch(e){console.warn(`Error closing previous menu:`,e)}i.activeMenu=e}};window.__neighborMenuManager=i;let a=e,s=r,u=n(!1),d=n(),f=n({top:0,left:0}),h=()=>{u.value=!1,document.removeEventListener(`click`,w,!0),document.removeEventListener(`keydown`,T),i.activeMenu===_&&(i.activeMenu=null)},_={closeMenu:h},y=()=>{h(),s(`ping`,a.neighbor)},b=()=>{h(),s(`show-details`,a.neighbor)},x=()=>{h(),s(`delete`,a.neighbor)},w=e=>{e.target.closest(`[data-menu-container]`)||h()},T=e=>{e.key===`Escape`&&h()},E=async()=>{if(!u.value&&d.value){i.setActiveMenu(_);let e=d.value.getBoundingClientRect(),t=window.innerWidth,n=t<1024,r=e.left+144>t-16,a=e.left;n&&r&&(a=e.right-144),a=Math.max(8,a),f.value={top:e.bottom+4,left:a},u.value=!0,await c(),document.addEventListener(`click`,w,!0),document.addEventListener(`keydown`,T)}else h()};return o(()=>{h()}),(e,n)=>(t(),C(`div`,nn,[S(`button`,{ref_key:`buttonRef`,ref:d,onClick:E,class:v([`p-1 rounded hover:bg-stroke-subtle dark:hover:bg-white/10 transition-colors text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary/80`,{"bg-background-mute dark:bg-stroke/10 text-content-primary dark:text-content-primary/80":u.value}]),"data-menu-container":``},[...n[0]||=[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 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z`})],-1)]],2),(t(),l(m,{to:`body`},[u.value?(t(),C(`div`,{key:0,class:`fixed w-36 bg-white dark:bg-surface-elevated backdrop-blur-lg border border-stroke-subtle dark:border-white/20 rounded-[15px] shadow-2xl z-[450]`,style:p({top:f.value.top+`px`,left:f.value.left+`px`}),"data-menu-container":``},[S(`div`,{class:`py-2`},[S(`button`,{onClick:b,class:`flex items-center gap-3 w-full px-4 py-3 text-sm text-content-primary dark:text-content-primary hover:bg-primary/10 transition-colors border-b border-stroke-subtle dark:border-white/10`},[...n[1]||=[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(`span`,{class:`font-medium`},`Details`,-1)]]),S(`button`,{onClick:y,class:`flex items-center gap-3 w-full px-4 py-3 text-sm text-content-primary dark:text-content-primary hover:bg-primary/10 transition-colors border-b border-stroke-subtle dark:border-white/10`},[...n[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:`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.393c5.857-5.857 15.355-5.857 21.213 0`})],-1),S(`span`,{class:`font-medium`},`Ping`,-1)]]),S(`button`,{onClick:x,class:`flex items-center gap-3 w-full px-4 py-3 text-sm text-accent-red hover:bg-accent-red/10 transition-colors`},[...n[3]||=[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`})],-1),S(`span`,{class:`font-medium`},`Delete`,-1)]])])],4)):g(``,!0)]))]))}}),an={class:`glass-card/30 backdrop-blur border border-stroke-subtle dark:border-white/10 rounded-[12px] p-6 shadow-sm dark:shadow-none`},on={class:`flex items-center justify-between mb-4`},sn={class:`flex items-center gap-3`},cn={class:`text-content-primary dark:text-content-primary text-lg font-semibold`},ln={class:`bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary text-xs px-2 py-1 rounded-full`},un={key:0,class:`text-content-muted dark:text-content-muted`},dn={key:0,class:`hidden lg:flex bg-background-mute dark:bg-surface-elevated/30 backdrop-blur rounded-lg border border-stroke-subtle dark:border-stroke/10 p-1`},fn={class:`hidden lg:block overflow-x-auto`},pn={class:`w-full`},mn={class:`bg-background-mute dark:bg-transparent`},hn={class:`flex items-center gap-1`},gn={class:`flex items-center gap-1`},_n={class:`flex items-center gap-1`},vn={class:`flex items-center gap-1`},yn={class:`flex items-center gap-1`},bn={class:`flex items-center gap-1`},xn={class:`flex items-center gap-1`},Sn={class:`flex items-center gap-1`},Cn={class:`flex items-center gap-1`},wn={class:`bg-surface/50 dark:bg-transparent`},Tn=[`onMouseenter`,`onMouseleave`,`onClick`],En=[`onClick`,`title`],Dn={key:0,class:`ml-1 text-xs`},On={key:0,class:`flex items-center gap-3`},kn={class:`text-content-secondary dark:text-content-muted`},An={class:`flex gap-1`},jn=[`onClick`],Mn=[`onClick`],Nn={key:1,class:`text-content-muted`},Pn={class:`flex items-center gap-2`},Fn={class:`flex items-end gap-0.5`},In={class:`flex items-center gap-2`},Ln=[`title`],Rn=[`title`],zn={class:`lg:hidden space-y-3`},Bn=[`onClick`],Vn={class:`flex items-center justify-between mb-3`},Hn={class:`flex items-center gap-3`},Un={class:`text-content-primary dark:text-content-primary font-medium text-base`},Wn={class:`flex items-center gap-2`},Gn={class:`grid grid-cols-1 gap-3`},Kn={class:`grid grid-cols-2 gap-4`},qn=[`onClick`,`title`],Jn={key:0,class:`ml-1 text-xs`},Yn={class:`flex items-center gap-2 justify-end`},Xn={class:`flex items-end gap-0.5`},Zn={class:`grid grid-cols-2 gap-4`},Qn={class:`flex items-center gap-2`},$n=[`title`],er={class:`text-content-primary dark:text-content-primary text-sm block text-right`},tr={key:0,class:`border-t border-white/10 pt-3`},nr={class:`flex items-center justify-between`},rr={class:`text-content-secondary dark:text-content-muted text-sm font-mono`},ir={class:`flex gap-2`},ar=[`onClick`],or=[`onClick`],sr={class:`grid grid-cols-3 gap-4 pt-3 border-t border-white/10`},cr={class:`text-center`},lr={class:`text-content-primary dark:text-content-primary text-sm font-medium`},ur={class:`text-center`},dr={class:`text-content-primary dark:text-content-primary text-sm font-medium`},fr={class:`text-center`},pr=[`title`],mr=d({__name:`NeighborTable`,props:{contactType:{},contactTypeKey:{},adverts:{},originalCount:{default:0},color:{},baseLatitude:{default:null},baseLongitude:{default:null},isCompactView:{type:Boolean,default:!1},isFirstTable:{type:Boolean,default:!1},showViewToggle:{type:Boolean,default:!1}},emits:[`highlight-node`,`unhighlight-node`,`menu-ping`,`menu-delete`,`show-details`,`toggle-view`],setup(e,{emit:r}){let a=n(null),{getSignalQuality:o}=G(),c=n(`advert_count`),l=n(`desc`),u=e,d=r,m=(e,t,n,r)=>{let i=(n-e)*Math.PI/180,a=(r-t)*Math.PI/180,o=Math.sin(i/2)*Math.sin(i/2)+Math.cos(e*Math.PI/180)*Math.cos(n*Math.PI/180)*Math.sin(a/2)*Math.sin(a/2);return 6371*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))},h=e=>u.baseLatitude===null||u.baseLongitude===null||e.latitude===null||e.longitude===null?`N/A`:ee(m(u.baseLatitude,u.baseLongitude,e.latitude,e.longitude)),w=async e=>{try{return await navigator.clipboard.writeText(e),!0}catch{let t=document.createElement(`textarea`);return t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),document.body.removeChild(t),!0}},T=e=>{let t=Date.now()-e*1e3,n=Math.floor(t/1e3),r=Math.floor(n/60),i=Math.floor(r/60),a=Math.floor(i/24);return n<60?`${n}s ago`:r<60?`${r}m ago`:i<24?`${i}h ago`:`${a}d ago`},E=e=>{let t=Date.now()-e*1e3,n=Math.floor(t/(1e3*60*60));return n<1?{color:`text-green-600 dark:text-green-400`}:n<26?{color:`text-yellow-600 dark:text-yellow-400`}:{color:`text-red-600 dark:text-red-400`}},D=async(e,t)=>{await w(`${e.toFixed(6)}, ${t.toFixed(6)}`)},O=(e,t)=>{let n=`https://www.google.com/maps?q=${e},${t}`;window.open(n,`_blank`)},k=async e=>{await w(e),a.value=e,setTimeout(()=>{a.value=null},2e3)},A=e=>{let t=o(e);return{bars:t.bars,color:t.color}},M=()=>u.isCompactView?`py-2 px-2`:`py-4 px-3`,N=()=>{d(`toggle-view`)},P=e=>{d(`highlight-node`,e)},F=e=>{d(`unhighlight-node`,e)},I=e=>{d(`menu-ping`,e)},B=e=>{d(`show-details`,e)},U=e=>{d(`menu-delete`,e)},W=e=>{c.value===e?l.value=l.value===`asc`?`desc`:`asc`:(c.value=e,l.value=typeof u.adverts[0]?.[e]==`number`?`desc`:`asc`)},K=y(()=>c.value?[...u.adverts].sort((e,t)=>{let n=e[c.value],r=t[c.value];if(n==null)return 1;if(r==null)return-1;let i=0;return typeof n==`string`&&typeof r==`string`?i=n.localeCompare(r):typeof n==`number`&&typeof r==`number`?i=n-r:typeof n==`boolean`&&typeof r==`boolean`&&(i=n===r?0:n?1:-1),l.value===`asc`?i:-i}):u.adverts);return(n,r)=>(t(),C(`div`,an,[S(`div`,on,[S(`div`,sn,[S(`div`,{class:`w-3 h-3 rounded-full border border-white/20`,style:p({backgroundColor:e.color})},null,4),S(`h3`,cn,f(e.contactType),1),S(`span`,ln,[b(f(e.adverts.length)+` `,1),e.originalCount>0&&e.adverts.length<e.originalCount?(t(),C(`span`,un,` / `+f(e.originalCount),1)):g(``,!0)])]),e.isFirstTable&&e.showViewToggle?(t(),C(`div`,dn,[S(`button`,{onClick:N,class:v([`p-2 rounded-md transition-colors`,e.isCompactView?`text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10`:`bg-primary/20 text-primary border border-primary/30`]),title:`Comfortable view`},[...r[10]||=[S(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`3`,y:`3`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`12`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2),S(`button`,{onClick:N,class:v([`p-2 rounded-md transition-colors`,e.isCompactView?`bg-primary/20 text-primary border border-primary/30`:`text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10`]),title:`Compact view`},[...r[11]||=[S(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`3`,y:`3`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`10`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`17`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2)])):g(``,!0)]),S(`div`,fn,[S(`table`,pn,[S(`thead`,null,[S(`tr`,mn,[S(`th`,{class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},null,2),S(`th`,{onClick:r[0]||=e=>W(`node_name`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,hn,[r[13]||=b(` Node Name `,-1),c.value===`node_name`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[12]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[1]||=e=>W(`pubkey`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,gn,[r[15]||=b(` Public Key `,-1),c.value===`pubkey`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[14]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},` Location `,2),S(`th`,{class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},` Distance `,2),S(`th`,{onClick:r[2]||=e=>W(`route_type`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,_n,[r[17]||=b(` Route Type `,-1),c.value===`route_type`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[16]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[3]||=e=>W(`zero_hop`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,vn,[r[19]||=b(` Zero Hop `,-1),c.value===`zero_hop`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[18]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[4]||=e=>W(`rssi`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,yn,[r[21]||=b(` RSSI `,-1),c.value===`rssi`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[20]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[5]||=e=>W(`snr`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,bn,[r[23]||=b(` SNR `,-1),c.value===`snr`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[22]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[6]||=e=>W(`last_seen`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,xn,[r[25]||=b(` Last Seen `,-1),c.value===`last_seen`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[24]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[7]||=e=>W(`first_seen`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,Sn,[r[27]||=b(` First Seen `,-1),c.value===`first_seen`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[26]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2),S(`th`,{onClick:r[8]||=e=>W(`advert_count`),class:v(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${M().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[S(`div`,Cn,[r[29]||=b(` Advert Count `,-1),c.value===`advert_count`?(t(),C(`svg`,{key:0,class:v([`w-3 h-3`,l.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...r[28]||=[S(`path`,{"fill-rule":`evenodd`,d:`M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z`,"clip-rule":`evenodd`},null,-1)]],2)):g(``,!0)])],2)])]),S(`tbody`,wn,[(t(!0),C(x,null,i(K.value,e=>(t(),C(`tr`,{key:e.id,class:`hover:bg-background-mute/50 dark:hover:bg-white/5 transition-colors cursor-pointer`,onMouseenter:t=>P(e.pubkey),onMouseleave:t=>F(e.pubkey),onClick:t=>B(e)},[S(`td`,{class:v(M()),onClick:r[9]||=j(()=>{},[`stop`])},[_(rn,{neighbor:e,onPing:I,onShowDetails:B,onDelete:U},null,8,[`neighbor`])],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},f(e.node_name||`Unknown`),3),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm font-mono`)},[S(`button`,{onClick:j(t=>k(e.pubkey),[`stop`]),class:v([`text-content-primary dark:text-content-primary hover:text-primary-light transition-colors cursor-pointer underline underline-offset-2 decoration-gray-400 dark:decoration-white/30 hover:decoration-primary-light/60`,a.value===e.pubkey?`text-green-600 dark:text-green-400 decoration-green-400/60`:``]),title:a.value===e.pubkey?`Copied!`:`Click to copy full public key`},[b(f(s(R)(e.pubkey))+` `,1),a.value===e.pubkey?(t(),C(`span`,Dn,`✓`)):g(``,!0)],10,En)],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[e.latitude!==null&&e.longitude!==null?(t(),C(`div`,On,[S(`span`,kn,f(e.latitude.toFixed(4))+`, `+f(e.longitude.toFixed(4)),1),S(`div`,An,[S(`button`,{onClick:j(t=>D(e.latitude,e.longitude),[`stop`]),class:`text-content-muted dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors cursor-pointer`,title:`Copy coordinates to clipboard`},[...r[30]||=[S(`svg`,{width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`,ry:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`path`,{d:`M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,jn),S(`button`,{onClick:j(t=>O(e.latitude,e.longitude),[`stop`]),class:`text-white/60 hover:text-blue-600 dark:text-blue-400 transition-colors cursor-pointer`,title:`Open in Google Maps`},[...r[31]||=[S(`svg`,{width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`path`,{d:`M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z`,stroke:`currentColor`,"stroke-width":`2`}),S(`circle`,{cx:`12`,cy:`10`,r:`3`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,Mn)])])):(t(),C(`span`,Nn,`Unknown`))],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},f(h(e)),3),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[S(`span`,{class:v([`inline-block px-2 py-1 rounded-full text-xs border transition-colors`,s(H)(e.route_type).bgColor,s(H)(e.route_type).borderColor,s(H)(e.route_type).textColor])},f(s(H)(e.route_type).text),3)],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[S(`span`,{class:v([`inline-block px-2 py-1 rounded-full text-xs border transition-colors`,e.zero_hop?`bg-green-100 dark:bg-green-500/20 border-green-500 dark:border-green-400/30 text-green-600 dark:text-green-400`:`bg-orange-100 dark:bg-orange-500/20 border-orange-500 dark:border-orange-400/30 text-orange-600 dark:text-orange-400`])},f(e.zero_hop?`Zero Hop`:`Multi-Hop`),3)],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[S(`div`,Pn,[S(`div`,Fn,[(t(),C(x,null,i(5,t=>S(`div`,{key:t,class:v([`w-1 transition-colors`,t<=A(e.rssi).bars?A(e.rssi).color:`text-gray-600`]),style:p({height:`${4+t*2}px`})},[...r[32]||=[S(`div`,{class:`w-full h-full bg-current rounded-sm`},null,-1)]],6)),64))]),S(`span`,{class:v(A(e.rssi).color)},f(s(L)(e.rssi)),3)])],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},f(s(V)(e.snr)),3),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[S(`div`,In,[S(`div`,{class:v([`w-2 h-2 rounded-full`,E(e.last_seen).color===`text-green-600 dark:text-green-400`?`bg-green-400`:``,E(e.last_seen).color===`text-yellow-600 dark:text-yellow-400`?`bg-yellow-400`:``,E(e.last_seen).color===`text-red-600 dark:text-red-400`?`bg-red-400`:``])},null,2),S(`span`,{class:v([E(e.last_seen).color,`cursor-help`]),title:s(z)(e.last_seen)},f(T(e.last_seen)),11,Ln)])],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm`)},[S(`span`,{title:s(z)(e.first_seen),class:`cursor-help`},f(T(e.first_seen)),9,Rn)],2),S(`td`,{class:v(`${M()} text-content-primary dark:text-content-primary text-sm text-center`)},f(e.advert_count),3)],40,Tn))),128))])])]),S(`div`,zn,[(t(!0),C(x,null,i(K.value,e=>(t(),C(`div`,{key:e.id,class:`bg-surface/50 dark:bg-transparent border border-stroke-subtle dark:border-white/10 rounded-lg p-4 hover:bg-background-mute/50 dark:hover:bg-white/5 transition-colors`,onClick:t=>P(e.pubkey)},[S(`div`,Vn,[S(`div`,Hn,[S(`h4`,Un,f(e.node_name||`Unknown Node`),1),S(`div`,Wn,[S(`span`,{class:v([`inline-block px-2 py-1 rounded-full text-xs border`,s(H)(e.route_type).bgColor,s(H)(e.route_type).borderColor,s(H)(e.route_type).textColor])},f(s(H)(e.route_type).text),3),S(`span`,{class:v([`inline-block px-2 py-1 rounded-full text-xs border`,e.zero_hop?`bg-green-100 dark:bg-green-500/20 border-green-500 dark:border-green-400/30 text-green-600 dark:text-green-400`:`bg-orange-100 dark:bg-orange-500/20 border-orange-500 dark:border-orange-400/30 text-orange-600 dark:text-orange-400`])},f(e.zero_hop?`Zero Hop`:`Multi-Hop`),3)])]),_(rn,{neighbor:e,onPing:I,onShowDetails:B,onDelete:U},null,8,[`neighbor`])]),S(`div`,Gn,[S(`div`,Kn,[S(`div`,null,[r[33]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Public Key`,-1),S(`button`,{onClick:t=>k(e.pubkey),class:v([`text-content-primary dark:text-content-primary hover:text-primary-light transition-colors cursor-pointer font-mono text-sm underline underline-offset-2 decoration-gray-400 dark:decoration-white/30 hover:decoration-primary-light/60 break-all`,a.value===e.pubkey?`text-green-600 dark:text-green-400 decoration-green-400/60`:``]),title:a.value===e.pubkey?`Copied!`:`Click to copy full public key`},[b(f(s(R)(e.pubkey))+` `,1),a.value===e.pubkey?(t(),C(`span`,Jn,`✓`)):g(``,!0)],10,qn)]),S(`div`,null,[r[35]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Signal`,-1),S(`div`,Yn,[S(`div`,Xn,[(t(),C(x,null,i(5,t=>S(`div`,{key:t,class:v([`w-1.5 transition-colors`,t<=A(e.rssi).bars?A(e.rssi).color:`text-gray-600`]),style:p({height:`${6+t*2}px`})},[...r[34]||=[S(`div`,{class:`w-full h-full bg-current rounded-sm`},null,-1)]],6)),64))]),S(`span`,{class:v(`${A(e.rssi).color} text-sm font-medium`)},f(s(L)(e.rssi)),3)])])]),S(`div`,Zn,[S(`div`,null,[r[36]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Last Seen`,-1),S(`div`,Qn,[S(`div`,{class:v([`w-2 h-2 rounded-full`,E(e.last_seen).color===`text-green-600 dark:text-green-400`?`bg-green-400`:``,E(e.last_seen).color===`text-yellow-600 dark:text-yellow-400`?`bg-yellow-400`:``,E(e.last_seen).color===`text-red-600 dark:text-red-400`?`bg-red-400`:``])},null,2),S(`span`,{class:v(`${E(e.last_seen).color} text-sm`),title:s(z)(e.last_seen)},f(T(e.last_seen)),11,$n)])]),S(`div`,null,[r[37]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Distance`,-1),S(`span`,er,f(h(e)),1)])]),e.latitude!==null&&e.longitude!==null?(t(),C(`div`,tr,[r[40]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Location`,-1),S(`div`,nr,[S(`span`,rr,f(e.latitude.toFixed(4))+`, `+f(e.longitude.toFixed(4)),1),S(`div`,ir,[S(`button`,{onClick:t=>D(e.latitude,e.longitude),class:`text-content-muted dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors p-2 hover:bg-stroke-subtle dark:hover:bg-white/10 rounded-lg`,title:`Copy coordinates`},[...r[38]||=[S(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`,ry:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`path`,{d:`M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,ar),S(`button`,{onClick:t=>O(e.latitude,e.longitude),class:`text-white/60 hover:text-blue-600 dark:text-blue-400 transition-colors p-2 hover:bg-white/10 rounded-lg`,title:`Open in Maps`},[...r[39]||=[S(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`path`,{d:`M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z`,stroke:`currentColor`,"stroke-width":`2`}),S(`circle`,{cx:`12`,cy:`10`,r:`3`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,or)])])])):g(``,!0),S(`div`,sr,[S(`div`,cr,[r[41]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`SNR`,-1),S(`span`,lr,f(s(V)(e.snr)),1)]),S(`div`,ur,[r[42]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`Adverts`,-1),S(`span`,dr,f(e.advert_count),1)]),S(`div`,fr,[r[43]||=S(`div`,{class:`text-content-muted text-xs mb-1`},`First Seen`,-1),S(`span`,{class:`text-content-primary dark:text-content-primary text-sm`,title:s(z)(e.first_seen)},f(T(e.first_seen)),9,pr)])])])],8,Bn))),128))])]))}}),hr={class:`space-y-6`},gr={key:0,class:`flex items-center justify-center py-12`},_r={key:1,class:`bg-red-50 dark:bg-accent-red/10 border border-red-300 dark:border-accent-red/20 rounded-[15px] p-6`},vr={class:`flex items-center gap-3`},yr={class:`text-red-500 dark:text-accent-red/80 text-sm`},br={key:0,class:``},xr={class:`flex items-center justify-between`},Sr={class:`flex items-center gap-3`},Cr={class:`hidden lg:flex bg-background-mute dark:bg-surface-elevated/30 backdrop-blur rounded-lg border border-stroke-subtle dark:border-stroke/10 mb p-1`},wr={class:`flex items-center gap-2`},Tr=[`value`,`disabled`],Er=[`value`],Dr={class:`flex items-center gap-2`},Or={key:0,class:`ml-1 bg-accent-cyan/20 text-accent-cyan border border-accent-cyan/30 text-xs px-1.5 py-0.5 rounded-full font-medium`},kr={class:`bg-background dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mt-4 space-y-4`},Ar={class:`grid grid-cols-1 md:grid-cols-3 gap-4`},jr={key:1,class:`text-center py-12`},Mr={key:2,class:`text-center py-12`},Nr=d({name:`NeighborsView`,__name:`Neighbors`,setup(e){let r=E(),o=O(),s=k(),c=D,l={0:`#6b7280`,1:`#60a5fa`,2:`#34d399`,3:`#a855f7`,4:`#f59e0b`},d=y(()=>o.advertsByType),p=y(()=>o.isLoading),m=n(null),A=n(o.currentHours),j=[{label:`2 Days`,value:48},{label:`7 Days`,value:168},{label:`14 Days`,value:336},{label:`30 Days`,value:720}],F=async e=>{A.value=e,await o.fetchAll(e)},I=n(W(`neighbors_compactView`,!1)),L=n(W(`neighbors_showMapLegend`,typeof window<`u`?window.innerWidth>=1024:!0)),R=n(W(`neighbors_showAllMapContacts`,!1)),z=n(W(`neighbors_showFilters`,!1)),B=n(W(`neighbors_filters`,{zeroHop:`true`,routeType:`all`,searchText:``}));h(I,e=>U(`neighbors_compactView`,e)),h(L,e=>U(`neighbors_showMapLegend`,e)),h(R,e=>U(`neighbors_showAllMapContacts`,e)),h(z,e=>U(`neighbors_showFilters`,e)),h(B,e=>U(`neighbors_filters`,e),{deep:!0});let ee=n(!1),V=n(!1),H=n(!1),G=n(null),K=n(null),te=n(null),q=n(null),ne=n(!1),re=n(null),ie=y(()=>{if(!q.value)return null;let e=q.value;return{id:e.id,pubkey:e.pubkey,node_name:e.node_name,contact_type:e.contact_type,latitude:e.latitude,longitude:e.longitude,rssi:e.rssi,snr:e.snr,route_type:e.route_type,last_seen:e.last_seen,first_seen:e.first_seen,advert_count:e.advert_count,timestamp:e.timestamp,is_repeater:e.is_repeater,is_new_neighbor:e.is_new_neighbor,zero_hop:e.zero_hop}}),ae=y(()=>r.stats?.config?.repeater?.latitude),oe=y(()=>r.stats?.config?.repeater?.longitude),ce=y(()=>r.stats===null&&r.isLoading),le=e=>e.filter(e=>{if(B.value.zeroHop!==`all`){let t=e.zero_hop;if(B.value.zeroHop===`true`&&!t||B.value.zeroHop===`false`&&t)return!1}if(B.value.routeType!==`all`){let t=e.route_type;if(B.value.routeType===`direct`&&t!==2||B.value.routeType===`transport_direct`&&t!==3||B.value.routeType===`flood`&&t!==1||B.value.routeType===`transport_flood`&&t!==0)return!1}if(B.value.searchText){let t=B.value.searchText.toLowerCase(),n=e.node_name?.toLowerCase()||``,r=e.pubkey.toLowerCase();if(!n.includes(t)&&!r.includes(t))return!1}return!0}),ue=()=>{B.value={zeroHop:`all`,routeType:`all`,searchText:``}},J=y(()=>B.value.zeroHop!==`all`||B.value.routeType!==`all`||B.value.searchText!==``),de=y(()=>{let e={};for(let[t,n]of Object.entries(d.value))e[t]=le(n);return e}),fe=y(()=>Object.entries(c).filter(([e])=>de.value[e]?.length>0).sort(([e],[t])=>parseInt(e)-parseInt(t))),pe=y(()=>Object.values(d.value).flat().filter(e=>{let t=e.latitude,n=e.longitude;return t!=null&&t!==0&&n!=null&&n!==0&&typeof t==`number`&&typeof n==`number`&&!isNaN(t)&&!isNaN(n)&&(R.value||e.zero_hop===!0)})),me=()=>o.fetchAll(A.value),he=n(),ge=e=>{he.value?.highlightNode(e)},_e=e=>{he.value?.unhighlightNode(e)},ve=async e=>{let t=e;G.value=null,K.value=null,H.value=!0,te.value=t.node_name||`Unknown Node`,V.value=!0;try{let e=r.stats?.config?.mesh?.path_hash_mode??0,n=(e===2?3:e===1?2:1)*2,i=`0x${parseInt(t.pubkey.substring(0,n),16).toString(16).padStart(n,`0`)}`,a=await T.pingNeighbor(i,10);a.success&&a.data?G.value=a.data:(K.value=a.error||`Unknown error occurred`,console.error(`Failed to ping neighbor:`,a.error))}catch(e){console.error(`Error pinging neighbor:`,e),K.value=e instanceof Error?e.message:`Unknown error occurred`}finally{H.value=!1}},ye=()=>{V.value=!1,G.value=null,K.value=null,te.value=null},be=e=>{q.value=e,ee.value=!0},xe=e=>{re.value=e,ne.value=!0},Se=()=>{ne.value=!1,re.value=null},Ce=()=>{ee.value=!1,q.value=null},we=async e=>{try{await T.deleteAdvert(e),await o.fetchAll(A.value),Ce()}catch(e){console.error(`Error deleting neighbor:`,e)}};return w(()=>{s.ensure(`neighbors`)}),(e,n)=>(t(),C(`div`,hr,[p.value?(t(),C(`div`,gr,[...n[9]||=[S(`div`,{class:`text-center`},[S(`div`,{class:`animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4`}),S(`p`,{class:`text-content-secondary dark:text-content-muted`},`Loading neighbor data...`)],-1)]])):m.value?(t(),C(`div`,_r,[S(`div`,vr,[n[11]||=S(`svg`,{class:`w-5 h-5 text-red-600 dark: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 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z`})],-1),S(`div`,null,[n[10]||=S(`h3`,{class:`text-red-600 dark:text-accent-red font-medium`},`Error Loading Neighbors`,-1),S(`p`,yr,f(m.value),1)])])])):(t(),C(x,{key:2},[_(tn,{ref_key:`networkMapRef`,ref:he,adverts:pe.value,"base-latitude":ae.value,"base-longitude":oe.value,"stats-loading":ce.value,"show-legend":L.value,"onUpdate:showLegend":n[0]||=e=>L.value=e},null,8,[`adverts`,`base-latitude`,`base-longitude`,`stats-loading`,`show-legend`]),Object.keys(d.value).length>0?(t(),C(`div`,br,[S(`div`,xr,[n[16]||=S(`span`,{class:`text-content-primary dark:text-content-primary text-lg font-semibold`},null,-1),S(`div`,Sr,[S(`div`,Cr,[S(`button`,{onClick:n[1]||=e=>I.value=!1,class:v([`p-2 rounded-md transition-colors`,I.value?`text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10`:`bg-primary/20 text-primary border border-primary/30`]),title:`Comfortable view`},[...n[12]||=[S(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`3`,y:`3`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`12`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2),S(`button`,{onClick:n[2]||=e=>I.value=!0,class:v([`p-2 rounded-md transition-colors`,I.value?`bg-primary/20 text-primary border border-primary/30`:`text-content-secondary dark:text-content-muted hover:text-primary hover:bg-primary/10`]),title:`Compact view`},[...n[13]||=[S(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[S(`rect`,{x:`3`,y:`3`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`10`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),S(`rect`,{x:`3`,y:`17`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2)]),S(`div`,wr,[S(`select`,{value:A.value,onChange:n[3]||=e=>F(+e.target.value),disabled:p.value,class:`text-xs px-2 py-1.5 rounded-lg bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border border-stroke-subtle dark:border-stroke/20 focus:outline-none focus:border-primary/50 disabled:opacity-50`},[(t(),C(x,null,i(j,e=>S(`option`,{key:e.value,value:e.value},f(e.label),9,Er)),64))],40,Tr)]),S(`div`,Dr,[S(`button`,{onClick:n[4]||=e=>R.value=!R.value,class:v([`px-3 py-1.5 text-xs rounded-lg transition-colors border`,R.value?`bg-primary/20 text-primary border-primary/30`:`bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-white/20`])},` Map: `+f(R.value?`All Contacts`:`Zero Hop`),3),S(`button`,{onClick:n[5]||=e=>z.value=!z.value,class:v([`px-3 py-1.5 text-xs rounded-lg transition-colors border`,J.value?`bg-primary/20 text-primary border-primary/30`:`bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-white/20`])},[n[14]||=S(`svg`,{class:`w-4 h-4 inline mr-1`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[S(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707v6.586a1 1 0 01-1.447.894l-4-2A1 1 0 717 18.586V13.414a1 1 0 00-.293-.707L.293 6.293A1 1 0 010 5.586V3a1 1 0 011-1z`})],-1),n[15]||=b(` Filters `,-1),J.value?(t(),C(`span`,Or,` Active `)):g(``,!0)],2),J.value?(t(),C(`button`,{key:0,onClick:ue,class:`px-3 py-1.5 text-xs rounded-lg bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary border border-stroke-subtle dark:border-stroke/20 hover:bg-stroke-subtle dark:hover:bg-white/20 transition-colors`},` Clear Filters `)):g(``,!0)])])]),a(S(`div`,kr,[S(`div`,Ar,[S(`div`,null,[n[18]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Zero Hop`,-1),a(S(`select`,{"onUpdate:modelValue":n[6]||=e=>B.value.zeroHop=e,class:`w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none`},[...n[17]||=[S(`option`,{value:`all`},`All Nodes`,-1),S(`option`,{value:`true`},`Zero Hop Only`,-1),S(`option`,{value:`false`},`Multi-Hop Only`,-1)]],512),[[P,B.value.zeroHop]])]),S(`div`,null,[n[20]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Route Type`,-1),a(S(`select`,{"onUpdate:modelValue":n[7]||=e=>B.value.routeType=e,class:`w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none`},[...n[19]||=[u(`<option value="all">All Types</option><option value="direct">Direct</option><option value="transport_direct">Transport Direct</option><option value="flood">Flood</option><option value="transport_flood">Transport Flood</option>`,5)]],512),[[P,B.value.routeType]])]),S(`div`,null,[n[21]||=S(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Search`,-1),a(S(`input`,{"onUpdate:modelValue":n[8]||=e=>B.value.searchText=e,type:`text`,placeholder:`Node name or pubkey...`,class:`w-full bg-surface dark:bg-surface/50 border border-stroke-subtle dark:border-stroke/20 rounded-lg px-3 py-2 text-content-primary dark:text-content-primary text-sm focus:border-primary/50 focus:outline-none placeholder-gray-400 dark:placeholder-white/40`},null,512),[[N,B.value.searchText]])])])],512),[[M,z.value]])])):g(``,!0),(t(!0),C(x,null,i(fe.value,([e,n])=>(t(),C(`div`,{key:e,class:`space-y-6`},[_(mr,{"contact-type":n,"contact-type-key":e,adverts:de.value[e],"original-count":d.value[e]?.length||0,color:l[parseInt(e)],"base-latitude":ae.value,"base-longitude":oe.value,"is-compact-view":I.value,"is-first-table":!1,"show-view-toggle":!1,onHighlightNode:ge,onUnhighlightNode:_e,onMenuPing:ve,onMenuDelete:be,onShowDetails:xe},null,8,[`contact-type`,`contact-type-key`,`adverts`,`original-count`,`color`,`base-latitude`,`base-longitude`,`is-compact-view`])]))),128)),fe.value.length===0&&Object.keys(d.value).length===0?(t(),C(`div`,jr,[n[22]||=u(`<div class="text-content-secondary dark:text-content-muted mb-4"><svg class="w-16 h-16 mx-auto mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg></div><h3 class="text-content-primary dark:text-content-primary text-lg font-medium mb-2"> No Neighbors Found </h3><p class="text-content-secondary dark:text-content-muted"> No mesh neighbors have been discovered in your area yet. </p>`,3),S(`button`,{onClick:me,class:`mt-4 px-4 py-2 bg-primary/20 text-primary border border-primary/30 rounded-lg hover:bg-primary/30 transition-colors`},` Refresh `)])):fe.value.length===0&&J.value?(t(),C(`div`,Mr,[n[23]||=u(`<div class="text-content-secondary dark:text-content-muted mb-4"><svg class="w-16 h-16 mx-auto mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg></div><h3 class="text-content-primary dark:text-content-primary text-lg font-medium mb-2"> No neighbors match your filters </h3><p class="text-content-secondary dark:text-content-muted mb-4"> Try adjusting your filter criteria to see more results. </p>`,3),S(`button`,{onClick:ue,class:`px-4 py-2 bg-primary/20 text-primary border border-primary/30 rounded-lg hover:bg-primary/30 transition-colors`},` Clear Filters `)])):g(``,!0)],64)),_(se,{show:ee.value,neighbor:ie.value,onClose:Ce,onDelete:we},null,8,[`show`,`neighbor`]),_(Be,{show:V.value,"node-name":te.value,result:G.value,error:K.value,loading:H.value,onClose:ye},null,8,[`show`,`node-name`,`result`,`error`,`loading`]),_(Dt,{"is-open":ne.value,neighbor:re.value,"base-latitude":ae.value,"base-longitude":oe.value,onClose:Se},null,8,[`is-open`,`neighbor`,`base-latitude`,`base-longitude`])]))}});export{Nr as default}; |