mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-07-06 09:52:37 +02:00
65 lines
87 KiB
JavaScript
65 lines
87 KiB
JavaScript
import{r as e}from"./chunk-DECur_0Z.js";import{A as t,C as n,E as r,S as i,b as a,c as o,dt as s,f as c,ft as l,g as u,i as d,j as f,k as p,l as m,m as h,o as g,p as _,pt as v,r as y,s as b,u as x,w as S,z as C}from"./runtime-core.esm-bundler-HnidnMFy.js";import{t as w}from"./api-CbM6k1ZB.js";import{t as T}from"./system-BH4r-ii6.js";import{t as E}from"./_plugin-vue_export-helper-B7aGp3iI.js";import{c as D,d as O,f as k,h as A,p as j}from"./index-BFltqMtv.js";import{t as M}from"./leaflet-src-PYB8oVmQ.js";/* empty css */import{n as N,t as P}from"./preferences-Bv8i60GL.js";import{t as F}from"./useSignalQuality-BfZWbBxN.js";var I={class:`bg-gray-50 dark:bg-white/5 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mb-6`},L={class:`flex items-center gap-3`},R={class:`flex-1 min-w-0`},z={class:`text-content-primary dark:text-content-primary font-medium truncate`},B={class:`text-content-secondary dark:text-content-muted text-sm font-mono`},V={key:0,class:`text-white/50 text-xs`},H={key:1,class:`text-white/50 text-xs`},U=u({__name:`DeleteNeighborModal`,props:{show:{type:Boolean},neighbor:{}},emits:[`close`,`delete`],setup(e,{emit:t}){let n=e,r=t,i=()=>{n.neighbor&&(r(`delete`,n.neighbor.id),a())},a=()=>{r(`close`)},o=e=>{e.target===e.currentTarget&&a()};return(t,n)=>e.show&&e.neighbor?(S(),x(`div`,{key:0,onClick:o,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`}},[b(`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:n[0]||=A(()=>{},[`stop`])},[b(`div`,{class:`flex items-center gap-3 mb-6`},[n[2]||=b(`svg`,{class:`w-6 h-6 text-accent-red`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),n[3]||=b(`div`,null,[b(`h3`,{class:`text-xl font-semibold text-content-primary dark:text-content-primary`},` Delete Neighbor `),b(`p`,{class:`text-content-secondary dark:text-content-muted text-sm mt-1`},` Are you sure you want to delete this neighbor? `)],-1),b(`button`,{onClick:a,class:`ml-auto text-content-secondary dark:text-content-muted hover:text-content-primary dark:hover:text-content-primary transition-colors`},[...n[1]||=[b(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])]),b(`div`,I,[b(`div`,L,[b(`div`,R,[b(`div`,z,v(e.neighbor?.node_name||e.neighbor?.long_name||e.neighbor?.short_name||`Unknown`),1),b(`div`,B,` ID: `+v(e.neighbor?.node_num_hex||e.neighbor?.node_num||e.neighbor?.id||`N/A`),1),e.neighbor?.contact_type?(S(),x(`div`,V,v(e.neighbor.contact_type),1)):m(``,!0),e.neighbor?.hw_model?(S(),x(`div`,H,v(e.neighbor.hw_model),1)):m(``,!0)])])]),n[4]||=b(`div`,{class:`bg-accent-red/10 border border-accent-red/30 rounded-lg p-4 mb-6`},[b(`div`,{class:`flex items-center gap-2 text-accent-red text-sm`},[b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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`})]),b(`span`,null,`This action cannot be undone`)])],-1),b(`div`,{class:`flex gap-3`},[b(`button`,{onClick:a,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 `),b(`button`,{onClick:i,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 `)])])])):m(``,!0)}}),W={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`},G={class:`flex items-center justify-between`},K={class:`flex items-center gap-3`},ee={key:0,class:`text-sm text-content-secondary dark:text-content-muted`},te={class:`p-6`},q={key:0,class:`text-center py-8`},ne={key:1,class:`text-center py-8`},re={class:`text-content-secondary dark:text-content-muted text-sm`},ie={key:2,class:`space-y-4`},ae={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},oe={class:`flex items-center justify-between mb-2`},se={class:`flex items-baseline gap-2`},ce={class:`text-3xl font-bold text-content-primary dark:text-content-primary`},le={class:`grid grid-cols-2 gap-3`},ue={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},de={class:`flex items-center gap-2 mb-2`},fe={class:`flex gap-0.5`},pe={class:`flex items-baseline gap-1`},me={class:`text-xl font-bold text-content-primary dark:text-content-primary`},he={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},ge={class:`flex items-baseline gap-1`},_e={class:`text-xl font-bold text-content-primary dark:text-content-primary`},ve={key:0,class:`flex items-start gap-3 bg-amber-500/10 border border-amber-500/30 rounded-[12px] p-3`},ye={class:`text-xs leading-relaxed`},be={class:`font-semibold text-amber-600 dark:text-amber-400 mb-0.5`},xe={class:`bg-background-mute dark:bg-background/50 border border-stroke-subtle dark:border-stroke/10 rounded-[15px] p-4`},Se={class:`relative`},Ce={class:`flex items-center gap-2 overflow-x-auto pb-2`},we={key:0,class:`relative flex items-center`},Te={key:0,class:`absolute left-1/2 -translate-x-1/2 animate-pulse`},Ee={class:`text-content-muted dark:text-content-muted text-xs mt-2 flex items-center justify-between`},De={key:0,class:`text-cyan-500 dark:text-primary animate-pulse`},Oe={class:`flex items-center justify-between text-xs text-content-muted dark:text-content-muted pt-2`},ke=E(u({__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:n}){let i=e,a=n,c=T(),{getSignalQuality:l}=F(),u=C(0),f=C(!1),_=g(()=>{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=g(()=>{if(!i.result)return{color:`text-gray-400`,label:`Unknown`};let e=i.result.rtt_ms,t=_.value,n=i.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`}}),E=g(()=>{if(!i.result)return{bars:0,color:`text-gray-400`};let e=l(i.result.rssi);return{bars:e.bars,color:e.color}}),O=g(()=>{if(!i.result)return 0;if(i.result.path_hash_mode!==void 0)return i.result.path_hash_mode;let e=i.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}),k=g(()=>O.value>0),j=g(()=>({0:`1-byte`,1:`2-byte`,2:`3-byte`})[O.value]??`1-byte`);p(()=>i.result,e=>{if(e&&!f.value){f.value=!0,u.value=0;let t=e.path.length,n=1500/(t*2),r=0,i=t*2-2,a=()=>{r<=i?(u.value=r/i,r++,setTimeout(a,n)):(f.value=!1,u.value=1)};setTimeout(a,100)}},{immediate:!0});let M=g(()=>{if(!i.result||!f.value)return-1;let e=i.result.path.length;if(e<=1)return-1;let t=u.value,n=.5;if(t<=n)return t/n*(e-1);{let r=(t-n)/n;return(e-1)*(1-r)}}),N=()=>{a(`close`)};return(n,i)=>(S(),o(d,{to:`body`},[h(D,{name:`modal`},{default:t(()=>[e.show?(S(),x(`div`,{key:0,class:`fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[99999] p-4`,onClick:A(N,[`self`])},[b(`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:i[0]||=A(()=>{},[`stop`])},[b(`div`,W,[b(`div`,G,[b(`div`,K,[i[2]||=b(`div`,{class:`p-2 bg-cyan-400/20 dark:bg-primary/20 rounded-lg`},[b(`svg`,{class:`w-5 h-5 text-cyan-500 dark:text-primary`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`div`,null,[i[1]||=b(`h2`,{class:`text-xl font-bold text-content-primary dark:text-content-primary`},` Ping Result `,-1),e.nodeName?(S(),x(`p`,ee,v(e.nodeName),1)):m(``,!0)])]),b(`button`,{onClick:N,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`},[...i[3]||=[b(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])])]),b(`div`,te,[e.loading?(S(),x(`div`,q,[...i[4]||=[b(`div`,{class:`animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4`},null,-1),b(`p`,{class:`text-content-secondary dark:text-content-muted`},`Sending ping...`,-1),b(`p`,{class:`text-content-muted dark:text-content-muted text-sm mt-1`},` Waiting for response... `,-1)]])):e.error?(S(),x(`div`,ne,[i[5]||=b(`div`,{class:`p-3 bg-accent-red/10 rounded-full w-16 h-16 mx-auto mb-4 flex items-center justify-center`},[b(`svg`,{class:`w-8 h-8 text-accent-red`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),i[6]||=b(`h3`,{class:`text-accent-red font-semibold mb-2`},`Ping Failed`,-1),b(`p`,re,v(e.error),1)])):e.result?(S(),x(`div`,ie,[b(`div`,ae,[b(`div`,oe,[i[7]||=b(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`Round-Trip Time`,-1),b(`span`,{class:s([`text-xs font-medium px-2 py-1 rounded-full`,w.value.color,`bg-current/10`])},v(w.value.label),3)]),b(`div`,se,[b(`span`,ce,v(e.result.rtt_ms.toFixed(2)),1),i[8]||=b(`span`,{class:`text-content-secondary dark:text-content-muted`},`ms`,-1)])]),b(`div`,le,[b(`div`,ue,[b(`div`,de,[i[9]||=b(`span`,{class:`text-content-secondary dark:text-content-muted text-sm`},`RSSI`,-1),b(`div`,fe,[(S(),x(y,null,r(5,e=>b(`div`,{key:e,class:s([`w-1 h-3 rounded-sm`,e<=E.value.bars?E.value.color:`bg-stroke-subtle dark:bg-stroke/10`])},null,2)),64))])]),b(`div`,pe,[b(`span`,me,v(e.result.rssi),1),i[10]||=b(`span`,{class:`text-content-secondary dark:text-content-muted text-xs`},`dBm`,-1)])]),b(`div`,he,[i[12]||=b(`div`,{class:`text-content-secondary dark:text-content-muted text-sm mb-2`},`SNR`,-1),b(`div`,ge,[b(`span`,_e,v(e.result.snr_db),1),i[11]||=b(`span`,{class:`text-content-secondary dark:text-content-muted text-xs`},`dB`,-1)])])]),k.value?(S(),x(`div`,ve,[i[14]||=b(`svg`,{class:`w-5 h-5 text-amber-500 flex-shrink-0 mt-0.5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`div`,ye,[b(`p`,be,v(j.value)+` path hashes active `,1),i[13]||=b(`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)])])):m(``,!0),b(`div`,xe,[i[17]||=b(`div`,{class:`text-content-secondary dark:text-content-muted text-sm mb-3`},` Network Path `,-1),b(`div`,Se,[b(`div`,Ce,[(S(!0),x(y,null,r(e.result.path,(n,r)=>(S(),x(`div`,{key:r,class:`flex items-center gap-2 flex-shrink-0 relative`},[b(`div`,{class:s([`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`,f.value&&Math.floor(M.value)===r?`ring-2 ring-cyan-400/50 dark:ring-primary/50 scale-105`:``])},v(n),3),r<e.result.path.length-1?(S(),x(`div`,we,[i[16]||=b(`svg`,{class:`w-4 h-4 text-white/40 flex-shrink-0`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M9 5l7 7-7 7`})],-1),h(D,{name:`packet`},{default:t(()=>[f.value&&M.value>=r&&M.value<r+1?(S(),x(`div`,Te,[...i[15]||=[b(`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`},[b(`circle`,{cx:`12`,cy:`12`,r:`8`})],-1)]])):m(``,!0)]),_:2},1024)])):m(``,!0)]))),128))])]),b(`div`,Ee,[b(`span`,null,v(e.result.path.length)+` hop`+v(e.result.path.length===1?``:`s`),1),f.value?(S(),x(`span`,De,`● Tracing route...`)):m(``,!0)])]),b(`div`,Oe,[b(`span`,null,`Target: `+v(e.result.target_id),1),b(`span`,null,`Tag: #`+v(e.result.tag),1)])])):m(``,!0)]),b(`div`,{class:`border-t border-stroke-subtle dark:border-stroke/10 px-6 py-4`},[b(`button`,{onClick:N,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 `)])])])):m(``,!0)]),_:1})]))}}),[[`__scopeId`,`data-v-dacea749`]]),J=e(M(),1),Ae={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`},je={class:`flex items-center justify-between p-8 pb-4 flex-shrink-0`},Me={class:`flex-1 min-w-0`},Ne={class:`text-2xl font-bold text-content-primary dark:text-content-primary mb-1`},Pe={class:`text-content-secondary dark:text-content-muted text-sm font-mono break-all`},Fe={class:`flex items-center gap-2`},Ie={class:`flex-1 overflow-y-auto custom-scrollbar px-8`},Le={class:`mb-6`},Re={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},ze={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Be={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Ve={class:`text-content-primary dark:text-content-primary font-medium`},He={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Ue={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},We={class:`text-content-primary dark:text-content-primary font-medium`},Ge={class:`mb-6`},Ke={class:`grid grid-cols-1 md:grid-cols-3 gap-4`},qe={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Je={class:`text-content-primary dark:text-content-primary font-medium`},Ye={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Xe={class:`text-content-primary dark:text-content-primary font-medium`},Ze={key:0,class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},Qe={class:`flex items-center gap-2`},$e={class:`flex gap-0.5`},et={class:`mb-6`},tt={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},nt={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},rt={class:`text-content-primary dark:text-content-primary text-sm`},it={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},at={class:`text-content-primary dark:text-content-primary text-sm`},ot={key:0,class:`mb-6`},st={class:`grid grid-cols-1 md:grid-cols-3 gap-4 mb-4`},ct={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},lt={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ut={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},dt={class:`text-content-primary dark:text-content-primary font-mono text-sm`},ft={class:`glass-card bg-background-mute dark:bg-black/20 p-4 rounded-[12px]`},pt={class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},mt={key:0,class:`text-content-primary dark:text-content-primary font-medium`},ht={class:`p-8 pt-4 border-t border-stroke-subtle dark:border-white/10 flex-shrink-0`},gt=E(u({name:`NeighborDetailsModal`,__name:`NeighborDetailsModal`,props:{neighbor:{},isOpen:{type:Boolean},baseLatitude:{default:null},baseLongitude:{default:null}},emits:[`close`],setup(e,{emit:n}){let{getSignalQuality:i}=F(),a=C(`Copy`),c=e,l=n,u=C(),f=null,w=e=>new Date(e*1e3).toLocaleString(),T=e=>e?`${e} dBm`:`N/A`,E=e=>e?`${e.toFixed(1)} dB`:`N/A`,O=e=>({0:`Transport Flood`,1:`Flood`,2:`Direct`,3:`Transport Direct`})[e||0]||`Unknown`,k=e=>({Unknown:`Unknown`,"Chat Node":`Chat Node`,Repeater:`Repeater`,"Room Server":`Room Server`,"Hybrid Node":`Hybrid Node`})[e]||e,j=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`,M=async()=>{if(!c.neighbor?.latitude||!c.neighbor?.longitude)return;let e=`${c.neighbor.latitude.toFixed(6)}, ${c.neighbor.longitude.toFixed(6)}`;try{await navigator.clipboard.writeText(e),a.value=`Copied!`,setTimeout(()=>{a.value=`Copy`},2e3)}catch(e){console.error(`Failed to copy coordinates:`,e),a.value=`Failed`,setTimeout(()=>{a.value=`Copy`},2e3)}},N=g(()=>{if(!c.neighbor?.latitude||!c.neighbor?.longitude||!c.baseLatitude||!c.baseLongitude)return null;let e=(c.neighbor.latitude-c.baseLatitude)*Math.PI/180,t=(c.neighbor.longitude-c.baseLongitude)*Math.PI/180,n=Math.sin(e/2)*Math.sin(e/2)+Math.cos(c.baseLatitude*Math.PI/180)*Math.cos(c.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)))}),P=g(()=>c.neighbor?.latitude!==null&&c.neighbor?.longitude!==null&&c.neighbor?.latitude!==0&&c.neighbor?.longitude!==0&&Math.abs(c.neighbor?.latitude??0)<=90&&Math.abs(c.neighbor?.longitude??0)<=180),I=()=>{if(!u.value||!c.neighbor||!P.value)return;f&&=(f.remove(),null);let e=document.documentElement.classList.contains(`dark`);f=J.default.map(u.value,{center:[c.neighbor.latitude,c.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`;J.default.tileLayer(t,{maxZoom:19,attribution:`© OpenStreetMap © CARTO`}).addTo(f);let n=J.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">${c.neighbor.node_name?.charAt(0)||`?`}</div>`,iconSize:[32,32],iconAnchor:[16,16]});if(J.default.marker([c.neighbor.latitude,c.neighbor.longitude],{icon:n}).addTo(f).bindPopup(`<b>${c.neighbor.node_name||`Unknown`}</b><br>${c.neighbor.pubkey.slice(0,8)}...`),c.baseLatitude!==null&&c.baseLongitude!==null&&c.baseLatitude!==0&&c.baseLongitude!==0&&Math.abs(c.baseLatitude)<=90&&Math.abs(c.baseLongitude)<=180){let e=J.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]});J.default.marker([c.baseLatitude,c.baseLongitude],{icon:e}).addTo(f).bindPopup(`<b>Base Station</b>`),J.default.polyline([[c.baseLatitude,c.baseLongitude],[c.neighbor.latitude,c.neighbor.longitude]],{color:`#3b82f6`,weight:2,opacity:.6,dashArray:`5, 10`}).addTo(f);let t=J.default.latLngBounds([c.baseLatitude,c.baseLongitude],[c.neighbor.latitude,c.neighbor.longitude]);f.fitBounds(t,{padding:[50,50]})}},L=e=>{e.key===`Escape`&&l(`close`)},R=e=>{e.target===e.currentTarget&&l(`close`)};p(()=>c.isOpen,e=>{e?(document.body.style.overflow=`hidden`,setTimeout(()=>{P.value&&I()},100)):(document.body.style.overflow=``,f&&=(f.remove(),null))},{immediate:!0});let z=g(()=>c.neighbor?.rssi?i(c.neighbor.rssi):null);return(n,i)=>(S(),o(d,{to:`body`},[h(D,{name:`modal`,appear:``},{default:t(()=>[e.isOpen&&e.neighbor?(S(),x(`div`,{key:0,class:`fixed inset-0 z-50 flex items-center justify-center p-4 overflow-hidden`,onClick:R,onKeydown:L,tabindex:`0`},[i[20]||=b(`div`,{class:`absolute inset-0 bg-black/60 backdrop-blur-md pointer-events-none`},null,-1),b(`div`,{class:`relative w-full max-w-4xl max-h-[90vh] flex flex-col`,onClick:i[2]||=A(()=>{},[`stop`])},[b(`div`,Ae,[b(`div`,je,[b(`div`,Me,[b(`h2`,Ne,v(e.neighbor.node_name||`Unknown Node`),1),b(`p`,Pe,v(e.neighbor.pubkey),1)]),b(`div`,Fe,[b(`button`,{onClick:i[0]||=e=>l(`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`},[...i[3]||=[b(`svg`,{class:`w-5 h-5`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]])])]),b(`div`,Ie,[b(`div`,Le,[i[8]||=b(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Basic Information `,-1),b(`div`,Re,[b(`div`,ze,[i[4]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Contact Type `,-1),b(`div`,{class:s([`font-medium`,j(e.neighbor.contact_type)])},v(k(e.neighbor.contact_type)),3)]),b(`div`,Be,[i[5]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Route Type `,-1),b(`div`,Ve,v(O(e.neighbor.route_type)),1)]),b(`div`,He,[i[6]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Zero Hop `,-1),b(`div`,{class:s([`font-medium`,e.neighbor.zero_hop?`text-green-600 dark:text-green-400`:`text-gray-600 dark:text-gray-400`])},v(e.neighbor.zero_hop?`Yes`:`No`),3)]),b(`div`,Ue,[i[7]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Advert Count `,-1),b(`div`,We,v(e.neighbor.advert_count.toLocaleString()),1)])])]),b(`div`,Ge,[i[12]||=b(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Signal Quality `,-1),b(`div`,Ke,[b(`div`,qe,[i[9]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` RSSI `,-1),b(`div`,Je,v(T(e.neighbor.rssi)),1)]),b(`div`,Ye,[i[10]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` SNR `,-1),b(`div`,Xe,v(E(e.neighbor.snr)),1)]),z.value?(S(),x(`div`,Ze,[i[11]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Signal Strength `,-1),b(`div`,Qe,[b(`div`,$e,[(S(),x(y,null,r(4,e=>b(`div`,{key:e,class:s([`w-1 h-3 rounded-sm`,e<=z.value.bars?z.value.color:`bg-gray-300 dark:bg-gray-700`])},null,2)),64))]),b(`span`,{class:s([`text-sm font-medium`,z.value.color])},v(z.value.quality),3)])])):m(``,!0)])]),b(`div`,et,[i[15]||=b(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Timeline `,-1),b(`div`,tt,[b(`div`,nt,[i[13]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` First Seen `,-1),b(`div`,rt,v(w(e.neighbor.first_seen)),1)]),b(`div`,it,[i[14]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Last Seen `,-1),b(`div`,at,v(w(e.neighbor.last_seen)),1)])])]),P.value?(S(),x(`div`,ot,[i[19]||=b(`h3`,{class:`text-lg font-semibold text-content-primary dark:text-content-primary mb-4`},` Location `,-1),b(`div`,st,[b(`div`,ct,[i[16]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Latitude `,-1),b(`div`,lt,v(e.neighbor.latitude?.toFixed(6)),1)]),b(`div`,ut,[i[17]||=b(`div`,{class:`text-content-muted dark:text-content-muted text-xs uppercase tracking-wide mb-1`},` Longitude `,-1),b(`div`,dt,v(e.neighbor.longitude?.toFixed(6)),1)]),b(`div`,ft,[b(`div`,pt,v(N.value===null?`Coordinates`:`Distance`),1),N.value===null?(S(),x(`button`,{key:1,onClick:M,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`},[i[18]||=b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1),_(` `+v(a.value),1)])):(S(),x(`div`,mt,v(N.value.toFixed(2))+` km `,1))])]),b(`div`,{ref_key:`mapContainer`,ref:u,class:`w-full h-96 rounded-[12px] overflow-hidden border border-stroke-subtle dark:border-white/10`},null,512)])):m(``,!0)]),b(`div`,ht,[b(`button`,{onClick:i[1]||=e=>l(`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)):m(``,!0)]),_:1})]))}}),[[`__scopeId`,`data-v-2fb1fa15`]]),_t=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],vt=1,Y=8,yt=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!==vt)throw Error(`Got v${i} data when expected v${vt}.`);let a=_t[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=_t.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,Y,e),this.coords=new this.ArrayType(this.data,Y+o+s,e*2),this._pos=e*2,this._finished=!0):(this.data=new ArrayBuffer(Y+a+o+s),this.ids=new this.IndexArrayType(this.data,Y,e),this.coords=new this.ArrayType(this.data,Y+o+s,e*2),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,(vt<<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 bt(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++)Ct(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];Ct(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 bt(e,t,n,r,i,a){if(i-r<=n)return;let o=r+i>>1;xt(e,t,o,r,i,a),bt(e,t,n,r,o-1,1-a),bt(e,t,n,o+1,i,1-a)}function xt(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);xt(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(X(e,t,r,n),t[2*i+a]>o&&X(e,t,r,i);s<c;){for(X(e,t,s,c),s++,c--;t[2*s+a]<o;)s++;for(;t[2*c+a]>o;)c--}t[2*r+a]===o?X(e,t,r,c):(c++,X(e,t,c,i)),c<=n&&(r=c+1),n<=c&&(i=c-1)}}function X(e,t,n,r){St(e,n,r),St(t,2*n,2*r),St(t,2*n+1,2*r+1)}function St(e,t,n){let r=e[t];e[t]=e[n],e[n]=r}function Ct(e,t,n,r){let i=e-n,a=t-r;return i*i+a*a}var wt={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:e=>e},Tt=Math.fround||(e=>(t=>(e[0]=+t,e[0])))(new Float32Array(1)),Z=2,Q=3,Et=4,$=5,Dt=6,Ot=class{constructor(e){this.options=Object.assign(Object.create(wt),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=Tt(jt(r)),s=Tt(Mt(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(jt(n),Mt(a),jt(i),Mt(r)),c=o.data,l=[];for(let e of s){let t=this.stride*e;l.push(c[t+$]>1?kt(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+Et]===e&&u.push(a[n+$]>1?kt(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 yt(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=At(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=jt(r),u=Mt(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+Et]=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+Et]=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+Dt]];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 kt(e,t,n){return{type:`Feature`,id:e[t+Q],properties:At(e,t,n),geometry:{type:`Point`,coordinates:[Nt(e[t]),Pt(e[t+1])]}}}function At(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+Dt],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 jt(e){return e/360+.5}function Mt(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 Nt(e){return(e-.5)*360}function Pt(e){let t=(180-e*360)*Math.PI/180;return 360*Math.atan(Math.exp(t))/Math.PI-90}var Ft={class:`map-container`},It={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`},Lt={class:`hidden sm:inline`},Rt={key:3,class:`map-legend`},zt={class:`legend-footer`},Bt={key:4,class:`map-attribution`},Vt=E(u({__name:`NetworkMap`,props:{adverts:{},baseLatitude:{default:null},baseLongitude:{default:null},showLegend:{type:Boolean,default:!0}},emits:[`update:showLegend`],setup(e,{expose:t,emit:r}){typeof window<`u`&&!window.chrome&&(window.chrome={runtime:{}});let o=e,s=r,l=()=>{s(`update:showLegend`,!o.showLegend)},u=C(),d=null,f=C(new Map),h=null,_=C(new Map),y=C([]),w=C(!0),T=C(60),E=C(14),D=C(document.documentElement.classList.contains(`dark`)),O=new MutationObserver(()=>{let e=document.documentElement.classList.contains(`dark`);e!==D.value&&(D.value=e,d&&I())}),k=g(()=>o.baseLatitude!==null&&o.baseLongitude!==null&&typeof o.baseLatitude==`number`&&typeof o.baseLongitude==`number`&&o.baseLatitude!==0&&o.baseLongitude!==0&&Math.abs(o.baseLatitude)<=90&&Math.abs(o.baseLongitude)<=180),A=e=>new Date(e*1e3).toLocaleString(),j=e=>e?`${e} dBm`:`N/A`,M=e=>e?`${e} dB`:`N/A`,N=e=>({0:`Transport Flood`,1:`Flood`,2:`Direct`,3:`Transport Direct`})[e||0]||`Unknown`,P=(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)))},F=()=>{d&&=(y.value.forEach(e=>{d&&e.remove()}),y.value.length=0,d.remove(),null),f.value.clear(),_.value.clear(),h=null},I=async()=>{let e=d?.getZoom()||11,t=d?.getCenter()||(k.value?[o.baseLatitude,o.baseLongitude]:[0,0]);F(),await a(),await z(),d&&d.setView(t,e)},L=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]}}})},R=e=>{h=new Ot({radius:T.value,maxZoom:E.value,minPoints:2}),h.load(e)},z=async()=>{if(!u.value||!k.value){console.warn(`Cannot initialize map: missing container or coordinates`);return}F(),await a();let e=o.baseLatitude,t=o.baseLongitude;d=J.default.map(u.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=J.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=J.default.tileLayer(t,{maxZoom:19,attribution:``,errorTileUrl:`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==`});n.addTo(d),r.addTo(d)}catch(e){console.warn(`Error loading tiles:`,e)}try{let n=(e,t=!1)=>{let n=t?16:12;return J.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 J.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);J.default.marker([e,t],{icon:i}).addTo(d).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 a={Unknown:`#9CA3AF`,"Chat Node":`#60A5FA`,Repeater:`#A5E5B6`,"Room Server":`#EBA0FC`,"Hybrid Node":`#FFC246`},s=(e,t,n,r,i=0)=>{if(!d)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,f;s===2?(c=`#A5E5B6`,l=4,u=.9):s===1?(c=`#FFC246`,f=`10, 5`,u=.8):s===3?(c=`#059669`,l=5,u=.95):s===0?(c=`#ea580c`,f=`12, 6`,u=.8):(c=`#9CA3AF`,f=`2, 5`,u=.6);let p=[t,n],m=[a,o],h=J.default.polyline([p,m],{color:c,weight:l,opacity:0,dashArray:f,className:`connection-line`}).addTo(d),g=J.default.polyline([p,p],{color:c,weight:l,opacity:0,dashArray:f,className:`connection-line animated-line`}).addTo(d);setTimeout(()=>{let i=0;g.setStyle({opacity:u+.2});let s=()=>{i++;let c=i/30,f=p[0]+(m[0]-p[0])*c,_=p[1]+(m[1]-p[1])*c;g.setLatLngs([p,[f,_]]),i<30?setTimeout(s,30):setTimeout(()=>{d&&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=P(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: ${N(e.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Signal: ${j(e.rssi)} / ${M(e.snr)}</span>
|
|
</div>
|
|
`),y.value.push(h)},200)};s()},i)},c=()=>{if(!d||!h)return;let i=d.getBounds(),o=Math.floor(d.getZoom());_.value.forEach(e=>{d&&e.remove()}),_.value.clear(),y.value.forEach(e=>{d&&e.remove()}),y.value.length=0,h.getClusters([i.getWest(),i.getSouth(),i.getEast(),i.getNorth()],o).forEach(i=>{let[o,c]=i.geometry.coordinates,l=i.properties;if(l.cluster){let n=J.default.marker([c,o],{icon:r(l.point_count||0)}).addTo(d);n.on(`click`,()=>{if(d&&h){let e=h.getClusterExpansionZoom(l.cluster_id);d.setView([c,o],e)}});let i=h.getLeaves(l.cluster_id,1/0).map(e=>`<div style="margin: 2px 0; color: ${a[e.properties.advert.contact_type]||a.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>
|
|
`),_.value.set(`cluster-${l.cluster_id}`,n);let u=P(e,t,c,o),f=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:o,latitude:c,longitude:o},e,t,`#AAE8E8`,f)}else{let r=l.advert,i=a[r.contact_type]||a.Unknown,u=n(i),p=c,m=o,h=P(e,t,p,m),g=J.default.marker([p,m],{icon:u}).addTo(d).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: ${j(r.rssi)} / ${M(r.snr)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Route: ${N(r.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${A(r.last_seen)}</span>
|
|
${r.jittered_latitude?`<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>`:``}
|
|
</div>
|
|
`);f.value.set(r.pubkey,g),_.value.set(`node-${r.pubkey}`,g);let v=Math.min(Math.floor(h*5),200);s({...r,jittered_latitude:p,jittered_longitude:m},e,t,i,v)}})},l=(e,t)=>{let r=0;L(o.adverts).forEach(i=>{let o=i.properties.advert;if(o.latitude!==null&&o.longitude!==null){let i=a[o.contact_type]||a.Unknown,c=n(i),l=o.jittered_latitude||o.latitude,u=o.jittered_longitude||o.longitude,p=J.default.marker([l,u],{icon:c}).addTo(d).bindPopup(`
|
|
<div class="p-2">
|
|
<strong style="color: ${i}">${o.node_name||`Unknown Node`}</strong><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Type: ${o.contact_type}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Distance: ${P(e,t,l,u).toFixed(2)} km</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Signal: ${j(o.rssi)} / ${M(o.snr)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Route: ${N(o.route_type)}</span><br>
|
|
<span class="text-sm" style="color: #E5E7EB;">Last Seen: ${A(o.last_seen)}</span>
|
|
${o.jittered_latitude?`<br><span class="text-xs" style="color: #9CA3AF;">Position adjusted to separate overlapping nodes</span>`:``}
|
|
</div>
|
|
`);f.value.set(o.pubkey,p);let m=p.getElement();m&&(m.style.opacity=`0`,m.style.transition=`opacity 0.5s ease-out`),s(o,e,t,i,r),setTimeout(()=>{m&&(m.style.opacity=`1`)},r+1e3),r+=100}})};if(w.value&&o.adverts.length>0)try{R(L(o.adverts));let n=Math.min(14,d.getZoom());d.setZoom(n),setTimeout(()=>{try{c()}catch(n){console.warn(`Error updating clusters:`,n),l(e,t)}},100),d.on(`moveend`,()=>{try{c()}catch(e){console.warn(`Error updating clusters on move:`,e)}}),d.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(()=>{d&&d.invalidateSize()},1e3)}catch(e){console.error(`Error initializing map:`,e)}};return t({highlightNode:e=>{let t=f.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=f.value.get(e);if(t){let e=t.getElement();if(e){let t=e.querySelector(`div`);t&&t.classList.remove(`marker-highlight`)}}},initializeOpenStreetMap:z}),p(()=>o.adverts,()=>{d&&k.value&&setTimeout(()=>{z()},100)},{immediate:!1}),i(()=>{O.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`]}),k.value&&o.adverts.length>0&&setTimeout(()=>{z()},300)}),n(()=>{O.disconnect(),F()}),(t,n)=>(S(),x(`div`,Ft,[k.value?(S(),x(`div`,{key:1,ref_key:`mapContainer`,ref:u,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)):(S(),x(`div`,It,[...n[0]||=[c(`<div class="text-center text-content-primary dark:text-content-primary" data-v-61a18eed><svg class="w-8 h-8 mx-auto mb-2 text-content-muted dark:text-content-muted" fill="currentColor" viewBox="0 0 20 20" data-v-61a18eed><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" data-v-61a18eed></path></svg><p class="text-sm text-content-primary dark:text-content-primary" data-v-61a18eed> No valid coordinates available </p><p class="text-xs text-content-secondary dark:text-content-muted" data-v-61a18eed> Configure base station location to view map </p></div>`,1)]])),k.value&&e.adverts.length>0?(S(),x(`button`,{key:2,onClick:l,class:`absolute bottom-3 right-3 z-[1001] 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`},[n[1]||=b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`span`,Lt,v(e.showLegend?`Hide`:`Show`),1)])):m(``,!0),k.value&&e.adverts.length>0&&e.showLegend?(S(),x(`div`,Rt,[n[2]||=c(`<div class="legend-section" data-v-61a18eed><div class="legend-subtitle" data-v-61a18eed>Node Types</div><div class="legend-items" data-v-61a18eed><div class="legend-item" data-v-61a18eed><div class="legend-icon" style="background-color:#ef4444;" data-v-61a18eed></div><span data-v-61a18eed>Base Station</span></div><div class="legend-item" data-v-61a18eed><div class="legend-icon" style="background-color:#60a5fa;" data-v-61a18eed></div><span data-v-61a18eed>Chat Node</span></div><div class="legend-item" data-v-61a18eed><div class="legend-icon" style="background-color:#a5e5b6;" data-v-61a18eed></div><span data-v-61a18eed>Repeater</span></div><div class="legend-item" data-v-61a18eed><div class="legend-icon" style="background-color:#eba0fc;" data-v-61a18eed></div><span data-v-61a18eed>Room Server</span></div><div class="legend-item" data-v-61a18eed><div class="legend-icon" style="background-color:#ffc246;" data-v-61a18eed></div><span data-v-61a18eed>Hybrid Node</span></div></div></div><div class="legend-section" data-v-61a18eed><div class="legend-subtitle" data-v-61a18eed>Route Types</div><div class="legend-items" data-v-61a18eed><div class="legend-item" data-v-61a18eed><div class="legend-line" style="background:#a5e5b6;height:3px;" data-v-61a18eed></div><span data-v-61a18eed>Direct</span></div><div class="legend-item" data-v-61a18eed><div class="legend-line" style="background:#059669;height:4px;" data-v-61a18eed></div><span data-v-61a18eed>Transport Direct</span></div><div class="legend-item" data-v-61a18eed><div class="legend-line legend-line-dashed" style="background:#ffc246;" data-v-61a18eed></div><span data-v-61a18eed>Flood</span></div><div class="legend-item" data-v-61a18eed><div class="legend-line legend-line-dashed" style="background:#ea580c;" data-v-61a18eed></div><span data-v-61a18eed>Transport Flood</span></div></div></div>`,2),b(`div`,zt,v(e.adverts.length)+` node`+v(e.adverts.length===1?``:`s`)+` visible `,1)])):m(``,!0),k.value?(S(),x(`div`,Bt,` © OpenStreetMap contributors © CARTO `)):m(``,!0)]))}}),[[`__scopeId`,`data-v-61a18eed`]]),Ht={class:`relative`,"data-menu-container":``},Ut=u({__name:`NeighborMenu`,props:{neighbor:{},canPing:{type:Boolean}},emits:[`ping`,`delete`,`show-details`],setup(e,{emit:t}){let r=window.__neighborMenuManager||{activeMenu:null,setActiveMenu:e=>{if(r.activeMenu&&r.activeMenu!==e)try{r.activeMenu.closeMenu()}catch(e){console.warn(`Error closing previous menu:`,e)}r.activeMenu=e}};window.__neighborMenuManager=r;let i=e,c=t,u=C(!1),f=C(),p=C({top:0,left:0}),h=()=>{u.value=!1,document.removeEventListener(`click`,w,!0),document.removeEventListener(`keydown`,T),r.activeMenu===g&&(r.activeMenu=null)},g={closeMenu:h},_=()=>{h(),c(`ping`,i.neighbor)},v=()=>{h(),c(`show-details`,i.neighbor)},y=()=>{h(),c(`delete`,i.neighbor)},w=e=>{e.target.closest(`[data-menu-container]`)||h()},T=e=>{e.key===`Escape`&&h()},E=async()=>{if(!u.value&&f.value){r.setActiveMenu(g);let e=f.value.getBoundingClientRect(),t=window.innerWidth,n=t<1024,i=e.left+144>t-16,o=e.left;n&&i&&(o=e.right-144),o=Math.max(8,o),p.value={top:e.bottom+4,left:o},u.value=!0,await a(),document.addEventListener(`click`,w,!0),document.addEventListener(`keydown`,T)}else h()};return n(()=>{h()}),(e,t)=>(S(),x(`div`,Ht,[b(`button`,{ref_key:`buttonRef`,ref:f,onClick:E,class:s([`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":``},[...t[0]||=[b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),(S(),o(d,{to:`body`},[u.value?(S(),x(`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-[999999]`,style:l({top:p.value.top+`px`,left:p.value.left+`px`}),"data-menu-container":``},[b(`div`,{class:`py-2`},[b(`button`,{onClick:v,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`},[...t[1]||=[b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`span`,{class:`font-medium`},`Details`,-1)]]),b(`button`,{onClick:_,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`},[...t[2]||=[b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`span`,{class:`font-medium`},`Ping`,-1)]]),b(`button`,{onClick:y,class:`flex items-center gap-3 w-full px-4 py-3 text-sm text-accent-red hover:bg-accent-red/10 transition-colors`},[...t[3]||=[b(`svg`,{class:`w-4 h-4`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`span`,{class:`font-medium`},`Delete`,-1)]])])],4)):m(``,!0)]))]))}}),Wt={class:`glass-card/30 backdrop-blur border border-stroke-subtle dark:border-white/10 rounded-[12px] p-6 shadow-sm dark:shadow-none`},Gt={class:`flex items-center justify-between mb-4`},Kt={class:`flex items-center gap-3`},qt={class:`text-content-primary dark:text-content-primary text-lg font-semibold`},Jt={class:`bg-background-mute dark:bg-white/10 text-content-secondary dark:text-content-primary text-xs px-2 py-1 rounded-full`},Yt={key:0,class:`text-content-muted dark:text-content-muted`},Xt={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`},Zt={class:`hidden lg:block overflow-x-auto`},Qt={class:`w-full`},$t={class:`bg-background-mute dark:bg-transparent`},en={class:`flex items-center gap-1`},tn={class:`flex items-center gap-1`},nn={class:`flex items-center gap-1`},rn={class:`flex items-center gap-1`},an={class:`flex items-center gap-1`},on={class:`flex items-center gap-1`},sn={class:`flex items-center gap-1`},cn={class:`flex items-center gap-1`},ln={class:`flex items-center gap-1`},un={class:`bg-surface/50 dark:bg-transparent`},dn=[`onMouseenter`,`onMouseleave`],fn=[`onClick`,`title`],pn={key:0,class:`ml-1 text-xs`},mn={key:0,class:`flex items-center gap-3`},hn={class:`text-content-secondary dark:text-content-muted`},gn={class:`flex gap-1`},_n=[`onClick`],vn=[`onClick`],yn={key:1,class:`text-content-muted`},bn={class:`flex items-center gap-2`},xn={class:`flex items-end gap-0.5`},Sn={class:`flex items-center gap-2`},Cn=[`title`],wn=[`title`],Tn={class:`lg:hidden space-y-3`},En=[`onClick`],Dn={class:`flex items-center justify-between mb-3`},On={class:`flex items-center gap-3`},kn={class:`text-content-primary dark:text-content-primary font-medium text-base`},An={class:`flex items-center gap-2`},jn={class:`grid grid-cols-1 gap-3`},Mn={class:`grid grid-cols-2 gap-4`},Nn=[`onClick`,`title`],Pn={key:0,class:`ml-1 text-xs`},Fn={class:`flex items-center gap-2 justify-end`},In={class:`flex items-end gap-0.5`},Ln={class:`grid grid-cols-2 gap-4`},Rn={class:`flex items-center gap-2`},zn=[`title`],Bn={class:`text-content-primary dark:text-content-primary text-sm block text-right`},Vn={key:0,class:`border-t border-white/10 pt-3`},Hn={class:`flex items-center justify-between`},Un={class:`text-content-secondary dark:text-content-muted text-sm font-mono`},Wn={class:`flex gap-2`},Gn=[`onClick`],Kn=[`onClick`],qn={class:`grid grid-cols-3 gap-4 pt-3 border-t border-white/10`},Jn={class:`text-center`},Yn={class:`text-content-primary dark:text-content-primary text-sm font-medium`},Xn={class:`text-center`},Zn={class:`text-content-primary dark:text-content-primary text-sm font-medium`},Qn={class:`text-center`},$n=[`title`],er=u({__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:t}){let n=C(null),{getSignalQuality:i}=F(),a=C(`advert_count`),o=C(`desc`),c=e,u=t,d=e=>new Date(e*1e3).toLocaleString(),f=e=>`${e.slice(0,4)}...${e.slice(-4)}`,p=e=>{switch(e){case 2:return{text:`Direct`,bgColor:`bg-green-100 dark:bg-green-500/20`,borderColor:`border-green-500 dark:border-green-400/30`,textColor:`text-green-600 dark:text-green-400`};case 3:return{text:`Transport Direct`,bgColor:`bg-green-100 dark:bg-green-600/20`,borderColor:`border-green-600/40 dark:border-green-500/30`,textColor:`text-green-700 dark:text-green-500`};case 1:return{text:`Flood`,bgColor:`bg-yellow-100 dark:bg-yellow-500/20`,borderColor:`border-yellow-500 dark:border-yellow-400/30`,textColor:`text-yellow-600 dark:text-yellow-400`};case 0:return{text:`Transport Flood`,bgColor:`bg-orange-100 dark:bg-orange-500/20`,borderColor:`border-orange-500 dark:border-orange-400/30`,textColor:`text-orange-600 dark:text-orange-400`};default:return{text:`Unknown`,bgColor:`bg-gray-500/20`,borderColor:`border-gray-400/30`,textColor:`text-gray-400`}}},w=e=>e?`${e} dBm`:`N/A`,T=e=>e?`${e} dB`:`N/A`,E=(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)))},D=e=>c.baseLatitude===null||c.baseLongitude===null||e.latitude===null||e.longitude===null?`N/A`:`${E(c.baseLatitude,c.baseLongitude,e.latitude,e.longitude).toFixed(1)} km`,O=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}},k=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`},A=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`}},j=async(e,t)=>{await O(`${e.toFixed(6)}, ${t.toFixed(6)}`)},M=(e,t)=>{let n=`https://www.google.com/maps?q=${e},${t}`;window.open(n,`_blank`)},N=async e=>{await O(e),n.value=e,setTimeout(()=>{n.value=null},2e3)},P=e=>{let t=i(e);return{bars:t.bars,color:t.color}},I=()=>c.isCompactView?`py-2 px-2`:`py-4 px-3`,L=()=>{u(`toggle-view`)},R=e=>{u(`highlight-node`,e)},z=e=>{u(`unhighlight-node`,e)},B=e=>{u(`menu-ping`,e)},V=e=>{u(`show-details`,e)},H=e=>{u(`menu-delete`,e)},U=e=>{a.value===e?o.value=o.value===`asc`?`desc`:`asc`:(a.value=e,o.value=typeof c.adverts[0]?.[e]==`number`?`desc`:`asc`)},W=g(()=>a.value?[...c.adverts].sort((e,t)=>{let n=e[a.value],r=t[a.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),o.value===`asc`?i:-i}):c.adverts);return(t,i)=>(S(),x(`div`,Wt,[b(`div`,Gt,[b(`div`,Kt,[b(`div`,{class:`w-3 h-3 rounded-full border border-white/20`,style:l({backgroundColor:e.color})},null,4),b(`h3`,qt,v(e.contactType),1),b(`span`,Jt,[_(v(e.adverts.length)+` `,1),e.originalCount>0&&e.adverts.length<e.originalCount?(S(),x(`span`,Yt,` / `+v(e.originalCount),1)):m(``,!0)])]),e.isFirstTable&&e.showViewToggle?(S(),x(`div`,Xt,[b(`button`,{onClick:L,class:s([`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`},[...i[9]||=[b(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`3`,y:`3`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`12`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2),b(`button`,{onClick:L,class:s([`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`},[...i[10]||=[b(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`3`,y:`3`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`10`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`17`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2)])):m(``,!0)]),b(`div`,Zt,[b(`table`,Qt,[b(`thead`,null,[b(`tr`,$t,[b(`th`,{class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},null,2),b(`th`,{onClick:i[0]||=e=>U(`node_name`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,en,[i[12]||=_(` Node Name `,-1),a.value===`node_name`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[11]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[1]||=e=>U(`pubkey`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,tn,[i[14]||=_(` Public Key `,-1),a.value===`pubkey`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[13]||=[b(`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)):m(``,!0)])],2),b(`th`,{class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},` Location `,2),b(`th`,{class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5`)},` Distance `,2),b(`th`,{onClick:i[2]||=e=>U(`route_type`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,nn,[i[16]||=_(` Route Type `,-1),a.value===`route_type`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[15]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[3]||=e=>U(`zero_hop`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,rn,[i[18]||=_(` Zero Hop `,-1),a.value===`zero_hop`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[17]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[4]||=e=>U(`rssi`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,an,[i[20]||=_(` RSSI `,-1),a.value===`rssi`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[19]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[5]||=e=>U(`snr`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,on,[i[22]||=_(` SNR `,-1),a.value===`snr`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[21]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[6]||=e=>U(`last_seen`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,sn,[i[24]||=_(` Last Seen `,-1),a.value===`last_seen`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[23]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[7]||=e=>U(`first_seen`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,cn,[i[26]||=_(` First Seen `,-1),a.value===`first_seen`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[25]||=[b(`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)):m(``,!0)])],2),b(`th`,{onClick:i[8]||=e=>U(`advert_count`),class:s(`text-left text-content-secondary dark:text-content-muted text-xs font-medium py-3 ${I().split(` `)[1]} border-b border-stroke-subtle dark:border-white/5 cursor-pointer hover:text-primary transition-colors select-none`)},[b(`div`,ln,[i[28]||=_(` Advert Count `,-1),a.value===`advert_count`?(S(),x(`svg`,{key:0,class:s([`w-3 h-3`,o.value===`asc`?``:`rotate-180`]),fill:`currentColor`,viewBox:`0 0 20 20`},[...i[27]||=[b(`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)):m(``,!0)])],2)])]),b(`tbody`,un,[(S(!0),x(y,null,r(W.value,e=>(S(),x(`tr`,{key:e.id,class:`hover:bg-background-mute/50 dark:hover:bg-white/5 transition-colors`,onMouseenter:t=>R(e.pubkey),onMouseleave:t=>z(e.pubkey)},[b(`td`,{class:s(I())},[h(Ut,{neighbor:e,onPing:B,onShowDetails:V,onDelete:H},null,8,[`neighbor`])],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},v(e.node_name||`Unknown`),3),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm font-mono`)},[b(`button`,{onClick:t=>N(e.pubkey),class:s([`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`,n.value===e.pubkey?`text-green-600 dark:text-green-400 decoration-green-400/60`:``]),title:n.value===e.pubkey?`Copied!`:`Click to copy full public key`},[_(v(f(e.pubkey))+` `,1),n.value===e.pubkey?(S(),x(`span`,pn,`✓`)):m(``,!0)],10,fn)],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[e.latitude!==null&&e.longitude!==null?(S(),x(`div`,mn,[b(`span`,hn,v(e.latitude.toFixed(4))+`, `+v(e.longitude.toFixed(4)),1),b(`div`,gn,[b(`button`,{onClick:t=>j(e.latitude,e.longitude),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`},[...i[29]||=[b(`svg`,{width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`,ry:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`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,_n),b(`button`,{onClick:t=>M(e.latitude,e.longitude),class:`text-white/60 hover:text-blue-600 dark:text-blue-400 transition-colors cursor-pointer`,title:`Open in Google Maps`},[...i[30]||=[b(`svg`,{width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`path`,{d:`M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z`,stroke:`currentColor`,"stroke-width":`2`}),b(`circle`,{cx:`12`,cy:`10`,r:`3`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,vn)])])):(S(),x(`span`,yn,`Unknown`))],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},v(D(e)),3),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[b(`span`,{class:s([`inline-block px-2 py-1 rounded-full text-xs border transition-colors`,p(e.route_type).bgColor,p(e.route_type).borderColor,p(e.route_type).textColor])},v(p(e.route_type).text),3)],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[b(`span`,{class:s([`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`])},v(e.zero_hop?`Zero Hop`:`Multi-Hop`),3)],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[b(`div`,bn,[b(`div`,xn,[(S(),x(y,null,r(5,t=>b(`div`,{key:t,class:s([`w-1 transition-colors`,t<=P(e.rssi).bars?P(e.rssi).color:`text-gray-600`]),style:l({height:`${4+t*2}px`})},[...i[31]||=[b(`div`,{class:`w-full h-full bg-current rounded-sm`},null,-1)]],6)),64))]),b(`span`,{class:s(P(e.rssi).color)},v(w(e.rssi)),3)])],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},v(T(e.snr)),3),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[b(`div`,Sn,[b(`div`,{class:s([`w-2 h-2 rounded-full`,A(e.last_seen).color===`text-green-600 dark:text-green-400`?`bg-green-400`:``,A(e.last_seen).color===`text-yellow-600 dark:text-yellow-400`?`bg-yellow-400`:``,A(e.last_seen).color===`text-red-600 dark:text-red-400`?`bg-red-400`:``])},null,2),b(`span`,{class:s([A(e.last_seen).color,`cursor-help`]),title:d(e.last_seen)},v(k(e.last_seen)),11,Cn)])],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm`)},[b(`span`,{title:d(e.first_seen),class:`cursor-help`},v(k(e.first_seen)),9,wn)],2),b(`td`,{class:s(`${I()} text-content-primary dark:text-content-primary text-sm text-center`)},v(e.advert_count),3)],40,dn))),128))])])]),b(`div`,Tn,[(S(!0),x(y,null,r(W.value,e=>(S(),x(`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=>R(e.pubkey)},[b(`div`,Dn,[b(`div`,On,[b(`h4`,kn,v(e.node_name||`Unknown Node`),1),b(`div`,An,[b(`span`,{class:s([`inline-block px-2 py-1 rounded-full text-xs border`,p(e.route_type).bgColor,p(e.route_type).borderColor,p(e.route_type).textColor])},v(p(e.route_type).text),3),b(`span`,{class:s([`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`])},v(e.zero_hop?`Zero Hop`:`Multi-Hop`),3)])]),h(Ut,{neighbor:e,onPing:B,onShowDetails:V,onDelete:H},null,8,[`neighbor`])]),b(`div`,jn,[b(`div`,Mn,[b(`div`,null,[i[32]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Public Key`,-1),b(`button`,{onClick:t=>N(e.pubkey),class:s([`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`,n.value===e.pubkey?`text-green-600 dark:text-green-400 decoration-green-400/60`:``]),title:n.value===e.pubkey?`Copied!`:`Click to copy full public key`},[_(v(f(e.pubkey))+` `,1),n.value===e.pubkey?(S(),x(`span`,Pn,`✓`)):m(``,!0)],10,Nn)]),b(`div`,null,[i[34]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Signal`,-1),b(`div`,Fn,[b(`div`,In,[(S(),x(y,null,r(5,t=>b(`div`,{key:t,class:s([`w-1.5 transition-colors`,t<=P(e.rssi).bars?P(e.rssi).color:`text-gray-600`]),style:l({height:`${6+t*2}px`})},[...i[33]||=[b(`div`,{class:`w-full h-full bg-current rounded-sm`},null,-1)]],6)),64))]),b(`span`,{class:s(`${P(e.rssi).color} text-sm font-medium`)},v(w(e.rssi)),3)])])]),b(`div`,Ln,[b(`div`,null,[i[35]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Last Seen`,-1),b(`div`,Rn,[b(`div`,{class:s([`w-2 h-2 rounded-full`,A(e.last_seen).color===`text-green-600 dark:text-green-400`?`bg-green-400`:``,A(e.last_seen).color===`text-yellow-600 dark:text-yellow-400`?`bg-yellow-400`:``,A(e.last_seen).color===`text-red-600 dark:text-red-400`?`bg-red-400`:``])},null,2),b(`span`,{class:s(`${A(e.last_seen).color} text-sm`),title:d(e.last_seen)},v(k(e.last_seen)),11,zn)])]),b(`div`,null,[i[36]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Distance`,-1),b(`span`,Bn,v(D(e)),1)])]),e.latitude!==null&&e.longitude!==null?(S(),x(`div`,Vn,[i[39]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Location`,-1),b(`div`,Hn,[b(`span`,Un,v(e.latitude.toFixed(4))+`, `+v(e.longitude.toFixed(4)),1),b(`div`,Wn,[b(`button`,{onClick:t=>j(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`},[...i[37]||=[b(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`,ry:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`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,Gn),b(`button`,{onClick:t=>M(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`},[...i[38]||=[b(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`path`,{d:`M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z`,stroke:`currentColor`,"stroke-width":`2`}),b(`circle`,{cx:`12`,cy:`10`,r:`3`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],8,Kn)])])])):m(``,!0),b(`div`,qn,[b(`div`,Jn,[i[40]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`SNR`,-1),b(`span`,Yn,v(T(e.snr)),1)]),b(`div`,Xn,[i[41]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`Adverts`,-1),b(`span`,Zn,v(e.advert_count),1)]),b(`div`,Qn,[i[42]||=b(`div`,{class:`text-content-muted text-xs mb-1`},`First Seen`,-1),b(`span`,{class:`text-content-primary dark:text-content-primary text-sm`,title:d(e.first_seen)},v(k(e.first_seen)),9,$n)])])])],8,En))),128))])]))}}),tr={class:`space-y-6`},nr={key:0,class:`flex items-center justify-center py-12`},rr={key:1,class:`bg-red-50 dark:bg-accent-red/10 border border-red-300 dark:border-accent-red/20 rounded-[15px] p-6`},ir={class:`flex items-center gap-3`},ar={class:`text-red-500 dark:text-accent-red/80 text-sm`},or={key:0,class:``},sr={class:`flex items-center justify-between`},cr={class:`flex items-center gap-3`},lr={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`},ur={class:`flex items-center gap-2`},dr={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`},fr={class:`bg-background dark:bg-background/30 border border-stroke-subtle dark:border-stroke/10 rounded-lg p-4 mt-4 space-y-4`},pr={class:`grid grid-cols-1 md:grid-cols-3 gap-4`},mr={key:1,class:`text-center py-12`},hr={key:2,class:`text-center py-12`},gr=u({name:`NeighborsView`,__name:`Neighbors`,setup(e){let t=T(),n={0:`Unknown`,1:`Chat Node`,2:`Repeater`,3:`Room Server`,4:`Hybrid Node`},a={0:`#6b7280`,1:`#60a5fa`,2:`#34d399`,3:`#a855f7`,4:`#f59e0b`},o=C({}),l=C(!0),u=C(null),d=C(P(`neighbors_compactView`,!1)),E=C(P(`neighbors_showMapLegend`,typeof window<`u`?window.innerWidth>=1024:!0)),D=C(P(`neighbors_showFilters`,!1)),A=C(P(`neighbors_filters`,{zeroHop:`all`,routeType:`all`,searchText:``}));p(d,e=>N(`neighbors_compactView`,e)),p(E,e=>N(`neighbors_showMapLegend`,e)),p(D,e=>N(`neighbors_showFilters`,e)),p(A,e=>N(`neighbors_filters`,e),{deep:!0});let M=C(!1),F=C(!1),I=C(!1),L=C(null),R=C(null),z=C(null),B=C(null),V=C(!1),H=C(null),W=g(()=>{if(!B.value)return null;let e=B.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}}),G=g(()=>t.stats?.config?.repeater?.latitude),K=g(()=>t.stats?.config?.repeater?.longitude),ee=e=>e.filter(e=>{if(A.value.zeroHop!==`all`){let t=e.zero_hop;if(A.value.zeroHop===`true`&&!t||A.value.zeroHop===`false`&&t)return!1}if(A.value.routeType!==`all`){let t=e.route_type;if(A.value.routeType===`direct`&&t!==2||A.value.routeType===`transport_direct`&&t!==3||A.value.routeType===`flood`&&t!==1||A.value.routeType===`transport_flood`&&t!==0)return!1}if(A.value.searchText){let t=A.value.searchText.toLowerCase(),n=e.node_name?.toLowerCase()||``,r=e.pubkey.toLowerCase();if(!n.includes(t)&&!r.includes(t))return!1}return!0}),te=()=>{A.value={zeroHop:`all`,routeType:`all`,searchText:``}},q=g(()=>A.value.zeroHop!==`all`||A.value.routeType!==`all`||A.value.searchText!==``),ne=g(()=>{let e={};for(let[t,n]of Object.entries(o.value))e[t]=ee(n);return e}),re=g(()=>Object.entries(n).filter(([e])=>ne.value[e]?.length>0).sort(([e],[t])=>parseInt(e)-parseInt(t))),ie=g(()=>Object.values(o.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)&&e.zero_hop===!0})),ae=async e=>{try{let t=await w.get(`/adverts_by_contact_type?contact_type=${encodeURIComponent(e)}&hours=168`);return t.success&&Array.isArray(t.data)?t.data:[]}catch(t){return console.error(`Error fetching adverts for contact type ${e}:`,t),[]}},oe=async()=>{l.value=!0,u.value=null;try{o.value={};for(let[e,t]of Object.entries(n)){let n=await ae(t);n.length>0&&(o.value[e]=n)}}catch(e){console.error(`Error loading adverts:`,e),u.value=e instanceof Error?e.message:`Failed to load neighbor data`}finally{l.value=!1}},se=C(),ce=e=>{se.value?.highlightNode(e)},le=e=>{se.value?.unhighlightNode(e)},ue=async e=>{let n=e;L.value=null,R.value=null,I.value=!0,z.value=n.node_name||`Unknown Node`,F.value=!0;try{let e=t.stats?.config?.mesh?.path_hash_mode??0,r=(e===2?3:e===1?2:1)*2,i=`0x${parseInt(n.pubkey.substring(0,r),16).toString(16).padStart(r,`0`)}`,a=await w.pingNeighbor(i,10);a.success&&a.data?L.value=a.data:(R.value=a.error||`Unknown error occurred`,console.error(`Failed to ping neighbor:`,a.error))}catch(e){console.error(`Error pinging neighbor:`,e),R.value=e instanceof Error?e.message:`Unknown error occurred`}finally{I.value=!1}},de=()=>{F.value=!1,L.value=null,R.value=null,z.value=null},fe=e=>{B.value=e,M.value=!0},pe=e=>{H.value=e,V.value=!0},me=()=>{V.value=!1,H.value=null},he=()=>{M.value=!1,B.value=null},ge=async e=>{try{await w.deleteAdvert(e),await oe(),he()}catch(e){console.error(`Error deleting neighbor:`,e)}};return i(async()=>{await oe()}),(e,t)=>(S(),x(`div`,tr,[l.value?(S(),x(`div`,nr,[...t[7]||=[b(`div`,{class:`text-center`},[b(`div`,{class:`animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4`}),b(`p`,{class:`text-content-secondary dark:text-content-muted`},`Loading neighbor data...`)],-1)]])):u.value?(S(),x(`div`,rr,[b(`div`,ir,[t[9]||=b(`svg`,{class:`w-5 h-5 text-red-600 dark:text-accent-red`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),b(`div`,null,[t[8]||=b(`h3`,{class:`text-red-600 dark:text-accent-red font-medium`},`Error Loading Neighbors`,-1),b(`p`,ar,v(u.value),1)])])])):(S(),x(y,{key:2},[h(Vt,{ref_key:`networkMapRef`,ref:se,adverts:ie.value,"base-latitude":G.value,"base-longitude":K.value,"show-legend":E.value,"onUpdate:showLegend":t[0]||=e=>E.value=e},null,8,[`adverts`,`base-latitude`,`base-longitude`,`show-legend`]),Object.keys(o.value).length>0?(S(),x(`div`,or,[b(`div`,sr,[t[14]||=b(`span`,{class:`text-content-primary dark:text-content-primary text-lg font-semibold`},null,-1),b(`div`,cr,[b(`div`,lr,[b(`button`,{onClick:t[1]||=e=>d.value=!1,class:s([`p-2 rounded-md transition-colors`,d.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`},[...t[10]||=[b(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`3`,y:`3`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`12`,width:`18`,height:`6`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2),b(`button`,{onClick:t[2]||=e=>d.value=!0,class:s([`p-2 rounded-md transition-colors`,d.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`},[...t[11]||=[b(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[b(`rect`,{x:`3`,y:`3`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`10`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`}),b(`rect`,{x:`3`,y:`17`,width:`18`,height:`4`,rx:`2`,stroke:`currentColor`,"stroke-width":`2`})],-1)]],2)]),b(`div`,ur,[b(`button`,{onClick:t[3]||=e=>D.value=!D.value,class:s([`px-3 py-1.5 text-xs rounded-lg transition-colors border`,q.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`])},[t[12]||=b(`svg`,{class:`w-4 h-4 inline mr-1`,fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[b(`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),t[13]||=_(` Filters `,-1),q.value?(S(),x(`span`,dr,` Active `)):m(``,!0)],2),q.value?(S(),x(`button`,{key:0,onClick:te,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 `)):m(``,!0)])])]),f(b(`div`,fr,[b(`div`,pr,[b(`div`,null,[t[16]||=b(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Zero Hop`,-1),f(b(`select`,{"onUpdate:modelValue":t[4]||=e=>A.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`},[...t[15]||=[b(`option`,{value:`all`},`All Nodes`,-1),b(`option`,{value:`true`},`Zero Hop Only`,-1),b(`option`,{value:`false`},`Multi-Hop Only`,-1)]],512),[[O,A.value.zeroHop]])]),b(`div`,null,[t[18]||=b(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Route Type`,-1),f(b(`select`,{"onUpdate:modelValue":t[5]||=e=>A.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`},[...t[17]||=[c(`<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),[[O,A.value.routeType]])]),b(`div`,null,[t[19]||=b(`label`,{class:`block text-xs font-medium text-content-secondary dark:text-content-muted mb-1`},`Search`,-1),f(b(`input`,{"onUpdate:modelValue":t[6]||=e=>A.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),[[k,A.value.searchText]])])])],512),[[j,D.value]])])):m(``,!0),(S(!0),x(y,null,r(re.value,([e,t])=>(S(),x(`div`,{key:e,class:`space-y-6`},[h(er,{"contact-type":t,"contact-type-key":e,adverts:ne.value[e],"original-count":o.value[e]?.length||0,color:a[parseInt(e)],"base-latitude":G.value,"base-longitude":K.value,"is-compact-view":d.value,"is-first-table":!1,"show-view-toggle":!1,onHighlightNode:ce,onUnhighlightNode:le,onMenuPing:ue,onMenuDelete:fe,onShowDetails:pe},null,8,[`contact-type`,`contact-type-key`,`adverts`,`original-count`,`color`,`base-latitude`,`base-longitude`,`is-compact-view`])]))),128)),re.value.length===0&&Object.keys(o.value).length===0?(S(),x(`div`,mr,[t[20]||=c(`<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),b(`button`,{onClick:oe,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 `)])):re.value.length===0&&q.value?(S(),x(`div`,hr,[t[21]||=c(`<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),b(`button`,{onClick:te,class:`px-4 py-2 bg-primary/20 text-primary border border-primary/30 rounded-lg hover:bg-primary/30 transition-colors`},` Clear Filters `)])):m(``,!0)],64)),h(U,{show:M.value,neighbor:W.value,onClose:he,onDelete:ge},null,8,[`show`,`neighbor`]),h(ke,{show:F.value,"node-name":z.value,result:L.value,error:R.value,loading:I.value,onClose:de},null,8,[`show`,`node-name`,`result`,`error`,`loading`]),h(gt,{"is-open":V.value,neighbor:H.value,"base-latitude":G.value,"base-longitude":K.value,onClose:me},null,8,[`is-open`,`neighbor`,`base-latitude`,`base-longitude`])]))}});export{gr as default}; |