diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..557fb6c --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,124 @@ +--- +name: Entangled VPN — Connected Shell +description: Calm signal-bench Operate UI — matte B&W, path-first chroma, dense peer channels. +colors: + bg: "#0a0a0a" + surface: "#111111" + raised: "#181818" + border: "#2a2a2a" + hairline: "#3a3a3a" + muted: "#8a8a8a" + text: "#f0f0f0" + dim: "#5c5c5c" + cta: "#ffffff" + cta-ink: "#0a0a0a" + live: "#2fbf62" + fault: "#e23d3d" + bg-light: "#f5f5f5" + surface-light: "#ececec" + live-light: "#1a8f45" + fault-light: "#c41e1e" +typography: + sans: + fontFamily: "ui-sans-serif, 'Segoe UI', system-ui, sans-serif" + fontSize: "13px" + fontWeight: 400 + lineHeight: 1.45 + mono: + fontFamily: "ui-monospace, 'Cascadia Code', Consolas, monospace" + fontSize: "12px" + fontWeight: 500 + lineHeight: 1.35 + label: + fontFamily: "ui-sans-serif, 'Segoe UI', system-ui, sans-serif" + fontSize: "10px" + fontWeight: 600 + lineHeight: 1.2 + letterSpacing: "0.08em" +rounded: + sm: "4px" + md: "6px" +spacing: + xs: "4px" + sm: "8px" + md: "12px" + lg: "16px" + xl: "24px" +components: + btn: + backgroundColor: "transparent" + textColor: "{colors.text}" + rounded: "{rounded.md}" + padding: "6px 12px" + height: "32px" + btn-cta: + backgroundColor: "{colors.cta}" + textColor: "{colors.cta-ink}" + rounded: "{rounded.md}" + padding: "6px 12px" + height: "32px" +--- + +# Design System: Entangled VPN — Connected Shell + +## Overview + +Connected mode is an Operate surface for a friend LAN. It borrows the *idea* of a signal bench — path quality as the primary instrument — without dressing up as a CRT or Discord clone. Intro (`ConnectView` + starfield) is a separate surface and is not restyled here. + +## Thesis + +Room + VIP + path are the first things you see. Peers are a dense channel list. Chat is available without becoming the product. Green and red are scarce and meaningful. + +## Colors + +Neutrals only for structure. Two chroma roles: + +| Token | Use | +|---|---| +| `--live` | Direct / p2p path only | +| `--fault` | Relay, reconnecting, unread, errors | + +Everything else is black, white, or grey. Light theme inverts neutrals and keeps the same two chroma roles. + +Connected tokens live under `html[data-app="connected"]` so intro keeps `:root` / Bungee / starfield unchanged. + +## Typography + +Connected shell uses system sans for chrome and mono for VIP, IPs, ping, and path. Do not load a second display face for connected mode (intro keeps Bungee). Labels are small uppercase with modest tracking — used as field captions in the header, not as kickers above every pane title. + +## Layout (first viewport) + +1. **Header band** — Entangled wordmark (quiet), active room, copyable VIP, path status (dot + short label), peers count, settings, disconnect +2. **Left rail** — saved networks, create / join +3. **Main** — peers as home (`network`); chat and settings as alternate main panes (keep existing view routing) +4. **Footer** — slim status strip for server / version only (facts already in the header are not repeated loudly) + +No starfield behind the connected shell. Opaque bench surfaces only. + +## Components + +- Ghost / quiet / CTA buttons with 4–6px radius +- 8px path dots (`live` / `fault` / idle grey) +- Peer rows: nick, mono IP, path, ping, ping + chat actions +- Confirm dialogs for destructive actions +- Theme control in settings (and optional header) +- SVG icons only (no Unicode `⋯` / `▼` as chrome) + +## Motion + +Short opacity / border transitions. Honor `prefers-reduced-motion`. No view-transition gimmicks, grain, or glow. + +## Do + +- Derive one `pathAggregate`: `direct` | `relay` | `reconnecting` | `disconnected` +- Ship disconnect in connected chrome +- Keep ConnectView markup and `space.css` frozen +- Add Vite `sim.js` + `?connected=1` for preview +- Prefer deletion of ASCII chrome (`[~]`, `[>]`) in connected views + +## Don't + +- Invent crypto / throughput / engine footers +- Paint green or red for decoration +- Port the previous over-instrumented LED/graticule costume wholesale +- Change intro brand, tagline, or starfield diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 0000000..f2ba992 --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,48 @@ +# Product + + + +## Platform + +web + +## Users + +Small friend group on Windows. Admin Wintun client. Join a named room for a session of games, files, chat. + +## Product Purpose + +Private virtual LAN (`10.242.0.0/24`). Success: in a room, have a VIP, peers reachable (P2P or relay), chat works. + +## Positioning + +Mesh for a handful of people, not a consumer VPN. Rooms, pipe invites, owner delete, in-mesh chat. + +## Operating Context + +Wails v2 desktop. Connect screen first (frozen). After connect: networks, peers, chat, settings. Path: P2P, UDP relay, or WebSocket. Languages: en, ru, zh. Vite sim for frontend preview. + +## Capabilities and Constraints + +- Connected: networks rail, peers home, chat, settings (header only), disconnect, theme, copy VIP, ping, DMs. +- Intro / ConnectView + space.css are out of scope and must keep current look. +- Do not invent crypto claims, server hosts, or fake telemetry. +- Preview: Vite DEV sim with `?connected=1` when `window.go` is absent. + +## Brand Commitments + +- Name: Entangled. Intro stays as-is. +- Connected palette: high-contrast black-and-white. Subtle green only for Direct/p2p. Subtle red only for relay/fault/unread/error. No other chroma. +- Direction: signal-bench Operate shell — path quality first, dense desktop craft, not Discord neon or CRT costume. +- Connected may look different from intro; both must feel like the same product. + +## Product Principles + +- Room and virtual IP are the facts that matter. +- Path quality is the primary chrome signal. +- Density for a desktop window. +- Prefer real status over decorative instruments. + +## Accessibility & Inclusion + +Keyboard focus, `prefers-reduced-motion`, existing i18n keys. No English-only new copy without locale keys. diff --git a/client/frontend/dist/assets/index-5j6ZJn19.js b/client/frontend/dist/assets/index-5j6ZJn19.js deleted file mode 100644 index dae65e4..0000000 --- a/client/frontend/dist/assets/index-5j6ZJn19.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const r of a.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&i(r)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function i(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();function de(){}function Ti(t){return t()}function Gs(){return Object.create(null)}function Le(t){t.forEach(Ti)}function Gl(t){return typeof t=="function"}function dt(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}function Wi(t){return Object.keys(t).length===0}function Vl(t,...e){if(t==null){for(const i of e)i(void 0);return de}const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function on(t){let e;return Vl(t,n=>e=n)(),e}function ve(t,e,n){t.$$.on_destroy.push(Vl(e,n))}function Ze(t,e,n){return t.set(n),e}function l(t,e){t.appendChild(e)}function K(t,e,n){t.insertBefore(e,n||null)}function F(t){t.parentNode&&t.parentNode.removeChild(t)}function c(t){return document.createElement(t)}function g(t){return document.createTextNode(t)}function h(){return g(" ")}function Ul(){return g("")}function W(t,e,n,i){return t.addEventListener(e,n,i),()=>t.removeEventListener(e,n,i)}function Gt(t){return function(e){return e.stopPropagation(),t.call(this,e)}}function s(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function Fi(t){let e;return{p(...n){e=n,e.forEach(i=>t.push(i))},r(){e.forEach(n=>t.splice(t.indexOf(n),1))}}}function Oi(t){return t===""?null:+t}function Ki(t){return Array.from(t.childNodes)}function b(t,e){e=""+e,t.data!==e&&(t.data=e)}function ie(t,e){t.value=e??""}function Vs(t,e,n,i){n==null?t.style.removeProperty(e):t.style.setProperty(e,n,"")}function xn(t,e,n){for(let i=0;ii.call(this,e))}const Kt=[],Vt=[];let Jt=[];const Bs=[],Vi=Promise.resolve();let zl=!1;function Bi(){zl||(zl=!0,Vi.then(qi))}function tl(t){Jt.push(t)}const ql=new Set;let Wt=0;function qi(){if(Wt!==0)return;const t=rn;do{try{for(;Wtt.indexOf(i)===-1?e.push(i):n.push(i)),n.forEach(i=>i()),Jt=e}const el=new Set;let vt;function Ui(){vt={r:0,c:[],p:vt}}function zi(){vt.r||Le(vt.c),vt=vt.p}function Ye(t,e){t&&t.i&&(el.delete(t),t.i(e))}function lt(t,e,n,i){if(t&&t.o){if(el.has(t))return;el.add(t),vt.c.push(()=>{el.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function ft(t){return t?.length!==void 0?t:Array.from(t)}function ll(t,e){t.d(1),e.delete(t.key)}function sl(t,e,n,i,o,a,r,_,d,u,v,f){let m=t.length,j=a.length,w=m;const A={};for(;w--;)A[t[w].key]=w;const p=[],C=new Map,D=new Map,P=[];for(w=j;w--;){const I=f(o,a,w),J=n(I);let B=r.get(J);B?P.push(()=>B.p(I,e)):(B=u(J,I),B.c()),C.set(J,p[w]=B),J in A&&D.set(J,Math.abs(w-A[J]))}const k=new Set,N=new Set;function y(I){Ye(I,1),I.m(_,v),r.set(I.key,I),v=I.first,j--}for(;m&&j;){const I=p[j-1],J=t[m-1],B=I.key,S=J.key;I===J?(v=I.first,m--,j--):C.has(S)?!r.has(B)||k.has(B)?y(I):N.has(S)?m--:D.get(B)>D.get(S)?(N.add(B),y(I)):(k.add(S),m--):(d(J,r),m--)}for(;m--;){const I=t[m];C.has(I.key)||d(I,r)}for(;j;)y(p[j-1]);return Le(P),p}function Bt(t){t&&t.c()}function mt(t,e,n){const{fragment:i,after_update:o}=t.$$;i&&i.m(e,n),tl(()=>{const a=t.$$.on_mount.map(Ti).filter(Gl);t.$$.on_destroy?t.$$.on_destroy.push(...a):Le(a),t.$$.on_mount=[]}),o.forEach(tl)}function ht(t,e){const n=t.$$;n.fragment!==null&&(Hi(n.after_update),Le(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function Xi(t,e){t.$$.dirty[0]===-1&&(Kt.push(t),Bi(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const w=j.length?j[0]:m;return u.ctx&&o(u.ctx[f],u.ctx[f]=w)&&(!u.skip_bound&&u.bound[f]&&u.bound[f](w),v&&Xi(t,f)),m}):[],u.update(),v=!0,Le(u.before_update),u.fragment=i?i(u.ctx):!1,e.target){if(e.hydrate){const f=Ki(e.target);u.fragment&&u.fragment.l(f),f.forEach(F)}else u.fragment&&u.fragment.c();e.intro&&Ye(t.$$.fragment),mt(t,e.target,e.anchor),qi()}an(d)}class wt{$$=void 0;$$set=void 0;$destroy(){ht(this,1),this.$destroy=de}$on(e,n){if(!Gl(n))return de;const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!Wi(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Qi="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(Qi);const Ft=[];function Zi(t,e){return{subscribe:$e(t,e).subscribe}}function $e(t,e=de){let n;const i=new Set;function o(_){if(dt(t,_)&&(t=_,n)){const d=!Ft.length;for(const u of i)u[1](),Ft.push(u,t);if(d){for(let u=0;u{i.delete(u),i.size===0&&n&&(n(),n=null)}}return{set:o,update:a,subscribe:r}}function $i(t,e,n){const i=!Array.isArray(t),o=i?[t]:t;if(!o.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const a=e.length<2;return Zi(n,(r,_)=>{let d=!1;const u=[];let v=0,f=de;const m=()=>{if(v)return;f();const w=e(i?u[0]:u,r,_);a?r(w):f=Gl(w)?w:de},j=o.map((w,A)=>Vl(w,p=>{u[A]=p,v&=~(1<{v|=1<[...i,{id:n,msg:t,type:e}]),setTimeout(()=>{Wl.update(i=>i.filter(o=>o.id!==n))},4e3),e==="error"&&no(t)}function no(t){if(!t){nl.set(null);return}nl.set({id:++to,msg:String(t)})}function un(){nl.set(null)}function Fl(t,e){return t&&t.id?"peer:"+t.id:"room:"+(e||"network")}function _n(){return Fl(on(cn),on(ze).room)}function Ql(t,e,n,i=!1,o="sent",a=!1,r=!1){const _=++eo;let d;a?d=Fl(null,on(ze).room):i?d=_n():r?d="peer:"+t:d=Fl(null,on(ze).room),Hl.update(f=>{const m=f[d]?[...f[d]]:[];return m.push({id:i&&t.startsWith("local_")?t:_,fromID:t,nickname:e,message:n,timestamp:Date.now(),isSelf:i,status:o,system:a}),{...f,[d]:m.length>Ys?m.slice(-Ys):m}});const u=on(Ce),v=_n();!i&&!(u==="chat"&&d===v)&&Xl.update(f=>({...f,[d]:(f[d]||0)+1}))}function lo(t){Ql("system","",t,!1,"sent",!0)}function Kl(t){Xl.update(e=>{const n={...e};return delete n[t],n})}function ln(t,e){const n=_n();Hl.update(i=>{const o=i[n];return o?{...i,[n]:o.map(a=>a.id===t?{...a,status:e}:a)}:i})}const so={subscribe(t){return Hl.subscribe(e=>{t(e[_n()]||[])})}},Jl={brand:"Entangled",tagline:"Private LAN for friends — anywhere.",networks:"Networks",network_count:"{n} network(s)",create_network:"Create Network",join_network:"Join Network",connecting:"Connecting...",peer_count:"{n} peer(s)",offline_click:"Offline — click to connect",saved:"Saved",no_networks:"No saved networks",no_networks_desc:"Create or join a network to get started",settings:"Settings",network_name:"Network name",password_opt:"Password (optional)",cancel:"Cancel",create:"Create",join:"Join",leave:"Leave network",remove:"Remove saved",delete_room:"Delete network",more_actions:"More actions",copy_invite:"Copy invite",paste_invite:"Have an invite?",invite_copied:"Invite copied",invite_placeholder:"server|room|password",server_addr:"Server Address",nickname:"Nickname",server_token:"Server token",server_token_desc:"optional shared secret (ENTANGLED_TOKEN)",connect:"Connect",disconnect:"Disconnect",connected:"Connected",server:"Server",virtual_ip:"Virtual IP",na:"N/A",reconnecting:"Reconnecting...",disconnected:"Disconnected",phase_dialing:"Dialing server…",phase_auth:"Authenticating…",phase_ready:"Ready",phase_error:"Error",room_chat:"Room Chat",chat:"Chat",col_nickname:"Nickname",col_ip:"Virtual IP",col_ping:"Ping",ping_peer:"Ping",ping_sent:"Pinging {name}…",error_ping:"Ping failed: {err}",col_path:"Path",col_status:"Status",status_online:"Online",status_offline:"Offline",path_p2p:"Direct",path_relay:"Relay",path_ws:"Fallback",path_unknown:"—",path_p2p_tip:"Peer-to-peer direct connection",path_relay_tip:"Traffic routed through the server relay",path_ws_tip:"WebSocket fallback path",you:"You",me:"me",no_peers:"No peers connected",no_peers_desc:"Create or join a network, then wait for friends",network:"Network",chat_with:"Chat with {name}",room_chat_title:"Room Chat — {room}",back:"Back",no_messages:"No messages yet",no_messages_desc:"Send a message to start the conversation",type_message:"Type a message...",send:"Send",send_disabled_no_room:"Join a network to chat",msg_truncated:"Message truncated to 1000 characters",retry:"Retry",today:"Today",yesterday:"Yesterday",you_self:"You",status_connected:"Connected",status_disconnected:"Disconnected",status_reconnecting:"Reconnecting…",status_relay_degraded:"Some peers on relay",status_server:"Server: {s}",status_ip:"IP: {ip}",status_network:"Network: {room}",status_peers:"Peers: {n}",version:"Entangled v{v}",settings_title:"Settings",section_connection:"CONNECTION",section_network:"ADVANCED NETWORK",section_system:"SYSTEM",section_appearance:"APPEARANCE",advanced_warn:"Only change these if you know what they do.",reconnect_apply:"Reconnect to apply",auto_connect:"Auto Connect",auto_connect_desc:"connect to last server on startup",auto_join:"Auto Join Last Room",auto_join_desc:"join last open room after connect (password rooms need a manual join after restart)",connection_mode:"Connection",connection_direct:"Direct (P2P)",connection_relay:"Relay (server)",connection_mode_desc:"Direct prefers peer-to-peer and uses relay only when needed. Relay forces all traffic through the server.",mtu:"MTU",mtu_desc:"Packet size. Wrong values can break games or cause lag.",dns_server:"DNS Server",dns_desc:"Optional DNS for the virtual network. Leave blank for system default.",socks5:"SOCKS5 Proxy",socks5_placeholder:"e.g. 127.0.0.1:10808",socks5_desc:"Proxies signaling (WebSocket) only — not peer/relay UDP. Reconnect to apply.",stun_server:"STUN Server",stun_desc:"Helps find your public address for direct links. Reconnect to apply.",start_windows:"Start with Windows",updates:"Updates",check_updates:"Check for updates",apply_update:"Update",update_checking:"Checking for updates…",update_latest:"You are up to date.",update_available:"Update available: v{v}",update_downloading:"Downloading update… the app will restart.",update_failed:"Update failed",confirm_update:"Download and install the update? The app will restart.",error_update_check:"Update check failed: ",error_update:"Update failed: ",notif_updating:"Installing update…",ui_scale:"UI Scale",ui_scale_desc:"Scales the whole interface. Use with window resize or F11 fullscreen.",theme:"Theme",theme_dark:"Dark",theme_light:"Light",language:"Language",save:"SAVE",reset:"RESET TO DEFAULTS",language_en:"English",language_ru:"Russian",language_zh:"Chinese",copied:"Copied",dismiss_error:"Dismiss",field_required:"Required",notif_created:"Network created: {name}",notif_joined:"Joined network: {name}",notif_left:"Left network",notif_removed:"Removed: {name}",notif_deleted:"Network deleted: {name}",notif_connected:"Connected to {addr}",notif_disconnected:"Disconnected",notif_settings_saved:"Settings saved",notif_reconnect_required:"Reconnect to apply proxy / STUN / token changes",notif_auto_join_skipped:'Auto-join skipped for "{name}" — enter the password to join',notif_need_config:"Set server & nickname in Connect page first",notif_room_deleted:"Network was deleted by owner",invite_no_password:"Invite copied without password (not stored). Add it before sharing.",error_create:"Failed to create network: {err}",error_join:"Failed to join: {err}",error_leave:"Failed to leave: {err}",error_remove:"Failed to remove: {err}",error_connect:"Connection failed: {err}",error_disconnect:"Error: {err}",error_send:"Failed to send: {err}",error_not_connected:"Not connected — cannot send message",error_invalid_invite:"Invalid invite: server and room are required",error_save:"Failed to save settings: {err}",confirm_disconnect:"Disconnect from server?",confirm_leave:"Leave the current network? It stays in your saved list.",confirm_leave_remove:"Leave and remove this network from your saved list?",confirm_remove:'Remove "{name}" from saved networks? (does not delete the network for others)',confirm_delete:'Permanently delete network "{name}" for everyone?',confirm_reset:"Reset all settings to defaults?"},io={brand:"Entangled",tagline:"Частная LAN для друзей — где угодно.",networks:"Сети",network_count:"{n} сет(ь/и/ей)",create_network:"Создать сеть",join_network:"Подключиться",connecting:"Подключение...",peer_count:"{n} участник(ов)",offline_click:"Не в сети — нажмите для подключения",saved:"Сохранено",no_networks:"Нет сохранённых сетей",no_networks_desc:"Создайте или войдите в сеть, чтобы начать",settings:"Настройки",network_name:"Название сети",password_opt:"Пароль (опционально)",cancel:"Отмена",create:"Создать",join:"Войти",leave:"Покинуть сеть",remove:"Убрать из списка",delete_room:"Удалить сеть",more_actions:"Ещё действия",copy_invite:"Копировать инвайт",paste_invite:"Есть инвайт?",invite_copied:"Инвайт скопирован",invite_placeholder:"сервер|комната|пароль",server_addr:"Адрес сервера",nickname:"Псевдоним",server_token:"Токен сервера",server_token_desc:"опциональный секрет (ENTANGLED_TOKEN)",connect:"Подключиться",disconnect:"Отключиться",connected:"Подключено",server:"Сервер",virtual_ip:"Виртуальный IP",na:"Н/Д",reconnecting:"Переподключение...",disconnected:"Отключено",phase_dialing:"Подключение к серверу…",phase_auth:"Аутентификация…",phase_ready:"Готово",phase_error:"Ошибка",room_chat:"Чат комнаты",chat:"Чат",col_nickname:"Псевдоним",col_ip:"Виртуальный IP",col_ping:"Пинг",ping_peer:"Пинг",ping_sent:"Пинг {name}…",error_ping:"Пинг не удался: {err}",col_path:"Путь",col_status:"Статус",status_online:"В сети",status_offline:"Не в сети",path_p2p:"Прямой",path_relay:"Релей",path_ws:"Запасной",path_unknown:"—",path_p2p_tip:"Прямое соединение peer-to-peer",path_relay_tip:"Трафик через серверный релей",path_ws_tip:"Запасной путь через WebSocket",you:"Вы",me:"я",no_peers:"Нет подключённых участников",no_peers_desc:"Создайте или войдите в сеть и дождитесь друзей",network:"Сеть",chat_with:"Чат с {name}",room_chat_title:"Чат комнаты — {room}",back:"Назад",no_messages:"Сообщений пока нет",no_messages_desc:"Отправьте сообщение, чтобы начать разговор",type_message:"Введите сообщение...",send:"Отправить",send_disabled_no_room:"Войдите в сеть, чтобы писать",msg_truncated:"Сообщение обрезано до 1000 символов",retry:"Повторить",today:"Сегодня",yesterday:"Вчера",you_self:"Вы",status_connected:"Подключено",status_disconnected:"Отключено",status_reconnecting:"Переподключение…",status_relay_degraded:"Часть пиров через релей",status_server:"Сервер: {s}",status_ip:"IP: {ip}",status_network:"Сеть: {room}",status_peers:"Участники: {n}",version:"Entangled v{v}",settings_title:"Настройки",section_connection:"ПОДКЛЮЧЕНИЕ",section_network:"ДОП. СЕТЬ",section_system:"СИСТЕМА",section_appearance:"ВНЕШНИЙ ВИД",advanced_warn:"Меняйте только если понимаете, что делаете.",reconnect_apply:"Переподключитесь, чтобы применить",auto_connect:"Автоподключение",auto_connect_desc:"подключаться к последнему серверу при запуске",auto_join:"Автовход в комнату",auto_join_desc:"входить в последнюю открытую комнату (с паролем — вручную после перезапуска)",connection_mode:"Соединение",connection_direct:"Прямое (P2P)",connection_relay:"Релей (сервер)",connection_mode_desc:"Прямое предпочитает P2P и использует релей только при необходимости. Релей гонит весь трафик через сервер.",mtu:"MTU",mtu_desc:"Размер пакета. Неверное значение ломает игры или даёт лаги.",dns_server:"DNS-сервер",dns_desc:"Опциональный DNS виртуальной сети. Пусто — системный по умолчанию.",socks5:"SOCKS5-прокси",socks5_placeholder:"напр. 127.0.0.1:10808",socks5_desc:"Только сигнальный WebSocket, не UDP пиров/релея. Переподключитесь, чтобы применить.",stun_server:"STUN-сервер",stun_desc:"Помогает найти публичный адрес. Переподключитесь, чтобы применить.",start_windows:"Запуск с Windows",updates:"Обновления",check_updates:"Проверить обновления",apply_update:"Обновить",update_checking:"Проверка обновлений…",update_latest:"У вас актуальная версия.",update_available:"Доступно обновление: v{v}",update_downloading:"Загрузка обновления… приложение перезапустится.",update_failed:"Ошибка обновления",confirm_update:"Скачать и установить обновление? Приложение перезапустится.",error_update_check:"Не удалось проверить обновления: ",error_update:"Не удалось обновить: ",notif_updating:"Установка обновления…",ui_scale:"Масштаб UI",ui_scale_desc:"Масштабирует весь интерфейс. Вместе с изменением размера окна или F11.",theme:"Тема",theme_dark:"Тёмная",theme_light:"Светлая",language:"Язык",save:"СОХРАНИТЬ",reset:"СБРОСИТЬ",language_en:"Английский",language_ru:"Русский",language_zh:"Китайский",copied:"Скопировано",dismiss_error:"Закрыть",field_required:"Обязательно",notif_created:"Сеть создана: {name}",notif_joined:"Подключились к сети: {name}",notif_left:"Покинули сеть",notif_removed:"Удалено: {name}",notif_deleted:"Сеть удалена: {name}",notif_connected:"Подключились к {addr}",notif_disconnected:"Отключились",notif_settings_saved:"Настройки сохранены",notif_reconnect_required:"Переподключитесь, чтобы применить прокси / STUN / токен",notif_auto_join_skipped:"Автовход пропущен для «{name}» — введите пароль вручную",notif_need_config:"Укажите сервер и псевдоним на странице подключения",notif_room_deleted:"Сеть удалена владельцем",invite_no_password:"Инвайт скопирован без пароля (он не хранится). Добавьте перед отправкой.",error_create:"Не удалось создать сеть: {err}",error_join:"Не удалось подключиться: {err}",error_leave:"Не удалось покинуть: {err}",error_remove:"Не удалось удалить: {err}",error_connect:"Ошибка подключения: {err}",error_disconnect:"Ошибка: {err}",error_send:"Не удалось отправить: {err}",error_not_connected:"Нет подключения — невозможно отправить сообщение",error_invalid_invite:"Неверный инвайт: нужны сервер и комната",error_save:"Не удалось сохранить настройки: {err}",confirm_disconnect:"Отключиться от сервера?",confirm_leave:"Покинуть текущую сеть? Она останется в сохранённых.",confirm_leave_remove:"Покинуть и убрать сеть из сохранённых?",confirm_remove:'Убрать "{name}" из сохранённых? (сеть для других не удалится)',confirm_delete:'Навсегда удалить сеть "{name}" для всех?',confirm_reset:"Сбросить все настройки?"},oo={brand:"Entangled",tagline:"朋友的私人局域网 — 随时随地。",networks:"网络",network_count:"{n} 个网络",create_network:"创建网络",join_network:"加入网络",connecting:"连接中...",peer_count:"{n} 个节点",offline_click:"离线 — 点击连接",saved:"已保存",no_networks:"暂无保存的网络",no_networks_desc:"创建或加入网络以开始",settings:"设置",network_name:"网络名称",password_opt:"密码(可选)",cancel:"取消",create:"创建",join:"加入",leave:"离开网络",remove:"移除已保存",delete_room:"删除网络",more_actions:"更多操作",copy_invite:"复制邀请",paste_invite:"有邀请码?",invite_copied:"邀请已复制",invite_placeholder:"服务器|房间|密码",server_addr:"服务器地址",nickname:"昵称",server_token:"服务器令牌",server_token_desc:"可选共享密钥(ENTANGLED_TOKEN)",connect:"连接",disconnect:"断开",connected:"已连接",server:"服务器",virtual_ip:"虚拟 IP",na:"无",reconnecting:"重新连接...",disconnected:"已断开",phase_dialing:"正在连接服务器…",phase_auth:"正在验证…",phase_ready:"就绪",phase_error:"错误",room_chat:"房间聊天",chat:"聊天",col_nickname:"昵称",col_ip:"虚拟 IP",col_ping:"延迟",ping_peer:"测速",ping_sent:"正在测速 {name}…",error_ping:"测速失败: {err}",col_path:"路径",col_status:"状态",status_online:"在线",status_offline:"离线",path_p2p:"直连",path_relay:"中继",path_ws:"备用",path_unknown:"—",path_p2p_tip:"点对点直连",path_relay_tip:"经服务器中继转发",path_ws_tip:"WebSocket 备用路径",you:"你",me:"我",no_peers:"暂无连接的节点",no_peers_desc:"创建或加入网络,然后等待好友",network:"网络",chat_with:"与 {name} 聊天",room_chat_title:"房间聊天 — {room}",back:"返回",no_messages:"暂无消息",no_messages_desc:"发送一条消息开始对话",type_message:"输入消息...",send:"发送",send_disabled_no_room:"加入网络后才能聊天",msg_truncated:"消息已截断至 1000 个字符",retry:"重试",today:"今天",yesterday:"昨天",you_self:"你",status_connected:"已连接",status_disconnected:"已断开",status_reconnecting:"重新连接…",status_relay_degraded:"部分节点经中继",status_server:"服务器: {s}",status_ip:"IP: {ip}",status_network:"网络: {room}",status_peers:"节点: {n}",version:"Entangled v{v}",settings_title:"设置",section_connection:"连接",section_network:"高级网络",section_system:"系统",section_appearance:"外观",advanced_warn:"仅在了解作用时更改这些选项。",reconnect_apply:"重新连接以生效",auto_connect:"自动连接",auto_connect_desc:"启动时自动连接到上次的服务器",auto_join:"自动加入房间",auto_join_desc:"连接后自动加入上次的开放房间(有密码的房间重启后需手动加入)",connection_mode:"连接方式",connection_direct:"直连 (P2P)",connection_relay:"中继 (服务器)",connection_mode_desc:"直连优先点对点,必要时才用中继。中继模式强制全部流量经服务器。",mtu:"MTU",mtu_desc:"数据包大小。错误值可能导致游戏异常或卡顿。",dns_server:"DNS 服务器",dns_desc:"虚拟网络可选 DNS。留空则使用系统默认。",socks5:"SOCKS5 代理",socks5_placeholder:"例如 127.0.0.1:10808",socks5_desc:"仅代理信令 WebSocket,不含节点/中继 UDP。重新连接以生效。",stun_server:"STUN 服务器",stun_desc:"用于发现公网地址以便直连。重新连接以生效。",start_windows:"开机自启",updates:"更新",check_updates:"检查更新",apply_update:"更新",update_checking:"正在检查更新…",update_latest:"已是最新版本。",update_available:"有可用更新:v{v}",update_downloading:"正在下载更新…应用将重启。",update_failed:"更新失败",confirm_update:"下载并安装更新?应用将重启。",error_update_check:"检查更新失败:",error_update:"更新失败:",notif_updating:"正在安装更新…",ui_scale:"界面缩放",ui_scale_desc:"缩放整个界面。可配合窗口调整大小或 F11 全屏使用。",theme:"主题",theme_dark:"深色",theme_light:"浅色",language:"语言",save:"保存",reset:"重置为默认",language_en:"英语",language_ru:"俄语",language_zh:"中文",copied:"已复制",dismiss_error:"关闭",field_required:"必填",notif_created:"网络已创建: {name}",notif_joined:"已加入网络: {name}",notif_left:"已离开网络",notif_removed:"已删除: {name}",notif_deleted:"网络已删除: {name}",notif_connected:"已连接到 {addr}",notif_disconnected:"已断开连接",notif_settings_saved:"设置已保存",notif_reconnect_required:"请重新连接以使代理 / STUN / 令牌生效",notif_auto_join_skipped:"已跳过自动加入「{name}」— 请输入密码后手动加入",notif_need_config:"请先在连接页面设置服务器和昵称",notif_room_deleted:"网络已被所有者删除",invite_no_password:"邀请已复制但无密码(密码不存储)。分享前请自行添加。",error_create:"创建网络失败: {err}",error_join:"加入失败: {err}",error_leave:"离开失败: {err}",error_remove:"删除失败: {err}",error_connect:"连接失败: {err}",error_disconnect:"错误: {err}",error_send:"发送失败: {err}",error_not_connected:"未连接 — 无法发送消息",error_invalid_invite:"无效邀请:需要服务器和房间名",error_save:"保存设置失败: {err}",confirm_disconnect:"确定断开服务器连接?",confirm_leave:"离开当前网络?仍保留在已保存列表中。",confirm_leave_remove:"离开并从已保存列表中移除?",confirm_remove:'从已保存网络中移除 "{name}"?(不会删除他人的网络)',confirm_delete:'永久删除网络 "{name}"(对所有人)?',confirm_reset:"确定重置所有设置?"},Zl={en:Jl,ru:io,zh:oo};function ao(){const t=localStorage.getItem("entangled_locale");if(t&&Zl[t])return t;const e=navigator.language?.slice(0,2);return e==="ru"?"ru":e==="zh"?"zh":"en"}const $l=$e(ao()),kt=$i($l,t=>{const e=Zl[t]||Jl;return new Proxy(e,{get(n,i){if(typeof i=="string")return n[i]??Jl[i]??i}})});function sn(t){Zl[t]&&(localStorage.setItem("entangled_locale",t),$l.set(t))}function ne(t,e){return t?String(t).replace(/\{(\w+)\}/g,(n,i)=>e&&e[i]!=null?e[i]:`{${i}}`):""}function Hs(t,e,n){const i=t.slice();return i[62]=e[n],i}function Xs(t){let e,n,i=t[16].no_networks+"",o,a,r,_=t[16].no_networks_desc+"",d,u;return{c(){e=c("div"),n=c("div"),o=g(i),a=h(),r=c("div"),d=g(_),u=h(),s(r,"class","empty-desc svelte-1oaanap"),s(e,"class","empty-state svelte-1oaanap")},m(v,f){K(v,e,f),l(e,n),l(n,o),l(e,a),l(e,r),l(r,d),l(e,u)},p(v,f){f[0]&65536&&i!==(i=v[16].no_networks+"")&&b(o,i),f[0]&65536&&_!==(_=v[16].no_networks_desc+"")&&b(d,_)},d(v){v&&F(e)}}}function ro(t){let e=t[16].saved+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].saved+"")&&b(n,e)},d(i){i&&F(n)}}}function co(t){let e=t[16].offline_click+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].offline_click+"")&&b(n,e)},d(i){i&&F(n)}}}function uo(t){let e=ne(t[16].peer_count,{n:t[18].peerCount})+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&327680&&e!==(e=ne(i[16].peer_count,{n:i[18].peerCount})+"")&&b(n,e)},d(i){i&&F(n)}}}function _o(t){let e=t[16].connecting+"",n;return{c(){n=g(e)},m(i,o){K(i,n,o)},p(i,o){o[0]&65536&&e!==(e=i[16].connecting+"")&&b(n,e)},d(i){i&&F(n)}}}function Qs(t){let e,n,i=t[16].copy_invite+"",o,a,r,_,d=t[16].remove+"",u,v,f,m;function j(...C){return t[40](t[62],...C)}let w=t[18].room===t[62].name&&Zs(t);function A(...C){return t[42](t[62],...C)}let p=t[18].room===t[62].name&&t[18].isOwner&&$s(t);return{c(){e=c("div"),n=c("button"),o=g(i),a=h(),w&&w.c(),r=h(),_=c("button"),u=g(d),v=h(),p&&p.c(),s(n,"type","button"),s(n,"role","menuitem"),s(n,"class","menu-item svelte-1oaanap"),s(_,"type","button"),s(_,"role","menuitem"),s(_,"class","menu-item danger svelte-1oaanap"),s(e,"class","overflow-menu svelte-1oaanap"),s(e,"role","menu"),s(e,"tabindex","-1")},m(C,D){K(C,e,D),l(e,n),l(n,o),l(e,a),w&&w.m(e,null),l(e,r),l(e,_),l(_,u),l(e,v),p&&p.m(e,null),f||(m=[W(n,"click",j),W(_,"click",A),W(e,"click",Gt(t[37])),W(e,"keydown",Gt(t[38]))],f=!0)},p(C,D){t=C,D[0]&65536&&i!==(i=t[16].copy_invite+"")&&b(o,i),t[18].room===t[62].name?w?w.p(t,D):(w=Zs(t),w.c(),w.m(e,r)):w&&(w.d(1),w=null),D[0]&65536&&d!==(d=t[16].remove+"")&&b(u,d),t[18].room===t[62].name&&t[18].isOwner?p?p.p(t,D):(p=$s(t),p.c(),p.m(e,null)):p&&(p.d(1),p=null)},d(C){C&&F(e),w&&w.d(),p&&p.d(),f=!1,Le(m)}}}function Zs(t){let e,n=t[16].leave+"",i,o,a;return{c(){e=c("button"),i=g(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item svelte-1oaanap")},m(r,_){K(r,e,_),l(e,i),o||(a=W(e,"click",t[41]),o=!0)},p(r,_){_[0]&65536&&n!==(n=r[16].leave+"")&&b(i,n)},d(r){r&&F(e),o=!1,a()}}}function $s(t){let e,n=t[16].delete_room+"",i,o,a;function r(..._){return t[43](t[62],..._)}return{c(){e=c("button"),i=g(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item danger svelte-1oaanap")},m(_,d){K(_,e,d),l(e,i),o||(a=W(e,"click",r),o=!0)},p(_,d){t=_,d[0]&65536&&n!==(n=t[16].delete_room+"")&&b(i,n)},d(_){_&&F(e),o=!1,a()}}}function xs(t,e){let n,i,o,a,r,_=e[62].name+"",d,u,v,f,m,j,w,A,p,C,D,P,k,N,y,I;function J(V,Q){return V[11]===V[62].name?_o:V[18].room===V[62].name?uo:V[18].connected?ro:co}let B=J(e),S=B(e);function E(...V){return e[39](e[62],...V)}let M=e[13]===e[62].name&&Qs(e);function L(){return e[44](e[62])}function q(...V){return e[45](e[62],...V)}return{key:t,first:null,c(){n=c("div"),i=c("div"),o=h(),a=c("div"),r=c("div"),d=g(_),u=h(),v=c("div"),S.c(),f=h(),m=c("div"),j=c("button"),w=g("⋯"),D=h(),M&&M.c(),P=h(),s(i,"class","network-indicator svelte-1oaanap"),s(i,"aria-hidden","true"),ke(i,"active-dot",e[18].room===e[62].name),s(r,"class","network-name svelte-1oaanap"),s(v,"class","network-meta svelte-1oaanap"),s(a,"class","network-info svelte-1oaanap"),s(j,"type","button"),s(j,"class","menu-btn svelte-1oaanap"),s(j,"aria-haspopup","menu"),s(j,"aria-expanded",A=e[13]===e[62].name),s(j,"aria-label",p=e[16].more_actions),s(j,"title",C=e[16].more_actions),s(m,"class","row-actions svelte-1oaanap"),s(n,"class","network-item svelte-1oaanap"),s(n,"role","button"),s(n,"tabindex","0"),s(n,"aria-current",k=e[18].room===e[62].name?"true":void 0),s(n,"aria-label",N=e[62].name),ke(n,"active",e[18].room===e[62].name),ke(n,"disabled",!e[18].connected&&!e[11]),this.first=n},m(V,Q){K(V,n,Q),l(n,i),l(n,o),l(n,a),l(a,r),l(r,d),l(a,u),l(a,v),S.m(v,null),l(n,f),l(n,m),l(m,j),l(j,w),l(m,D),M&&M.m(m,null),l(n,P),y||(I=[W(j,"click",E),W(n,"click",L),W(n,"keydown",q)],y=!0)},p(V,Q){e=V,Q[0]&262145&&ke(i,"active-dot",e[18].room===e[62].name),Q[0]&1&&_!==(_=e[62].name+"")&&b(d,_),B===(B=J(e))&&S?S.p(e,Q):(S.d(1),S=B(e),S&&(S.c(),S.m(v,null))),Q[0]&8193&&A!==(A=e[13]===e[62].name)&&s(j,"aria-expanded",A),Q[0]&65536&&p!==(p=e[16].more_actions)&&s(j,"aria-label",p),Q[0]&65536&&C!==(C=e[16].more_actions)&&s(j,"title",C),e[13]===e[62].name?M?M.p(e,Q):(M=Qs(e),M.c(),M.m(m,null)):M&&(M.d(1),M=null),Q[0]&262145&&k!==(k=e[18].room===e[62].name?"true":void 0)&&s(n,"aria-current",k),Q[0]&1&&N!==(N=e[62].name)&&s(n,"aria-label",N),Q[0]&262145&&ke(n,"active",e[18].room===e[62].name),Q[0]&264192&&ke(n,"disabled",!e[18].connected&&!e[11])},d(V){V&&F(n),S.d(),M&&M.d(),y=!1,Le(I)}}}function ei(t){let e,n,i,o=t[16].create_network+"",a,r,_,d=t[16].network_name+"",u,v,f,m,j,w,A,p,C=t[16].password_opt+"",D,P,k,N,y,I,J,B,S=t[16].cancel+"",E,M,L,q=t[16].create+"",V,Q,ce,O=t[9]&&ti(t),Y=t[7]&&ni(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=g(o),r=h(),_=c("label"),u=g(d),v=h(),f=c("input"),w=h(),O&&O.c(),A=h(),p=c("label"),D=g(C),P=h(),k=c("input"),y=h(),Y&&Y.c(),I=h(),J=c("div"),B=c("button"),E=g(S),M=h(),L=c("button"),V=g(q),s(i,"id","create-title"),s(i,"class","svelte-1oaanap"),s(_,"class","sr-only svelte-1oaanap"),s(_,"for","create-name"),s(f,"id","create-name"),s(f,"type","text"),s(f,"placeholder",m=t[16].network_name),s(f,"aria-invalid",j=!!t[9]),s(f,"class","svelte-1oaanap"),ke(f,"invalid",t[9]),s(p,"class","sr-only svelte-1oaanap"),s(p,"for","create-pass"),s(k,"id","create-pass"),s(k,"type","password"),s(k,"placeholder",N=t[16].password_opt),s(k,"class","svelte-1oaanap"),s(B,"class","btn svelte-1oaanap"),s(L,"class","btn primary svelte-1oaanap"),s(J,"class","modal-actions svelte-1oaanap"),s(n,"class","modal svelte-1oaanap"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","create-title"),s(e,"class","modal-overlay svelte-1oaanap"),s(e,"role","presentation")},m(U,z){K(U,e,z),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(n,v),l(n,f),ie(f,t[3]),l(n,w),O&&O.m(n,null),l(n,A),l(n,p),l(p,D),l(n,P),l(n,k),ie(k,t[4]),l(n,y),Y&&Y.m(n,null),l(n,I),l(n,J),l(J,B),l(B,E),l(J,M),l(J,L),l(L,V),t[49](n),Q||(ce=[W(f,"input",t[47]),W(k,"input",t[48]),W(B,"click",t[20]),W(L,"click",t[23]),W(n,"click",Gt(t[35])),W(n,"keydown",Gt(t[36])),W(e,"click",t[20]),W(e,"keydown",t[50])],Q=!0)},p(U,z){z[0]&65536&&o!==(o=U[16].create_network+"")&&b(a,o),z[0]&65536&&d!==(d=U[16].network_name+"")&&b(u,d),z[0]&65536&&m!==(m=U[16].network_name)&&s(f,"placeholder",m),z[0]&512&&j!==(j=!!U[9])&&s(f,"aria-invalid",j),z[0]&8&&f.value!==U[3]&&ie(f,U[3]),z[0]&512&&ke(f,"invalid",U[9]),U[9]?O?O.p(U,z):(O=ti(U),O.c(),O.m(n,A)):O&&(O.d(1),O=null),z[0]&65536&&C!==(C=U[16].password_opt+"")&&b(D,C),z[0]&65536&&N!==(N=U[16].password_opt)&&s(k,"placeholder",N),z[0]&16&&k.value!==U[4]&&ie(k,U[4]),U[7]?Y?Y.p(U,z):(Y=ni(U),Y.c(),Y.m(n,I)):Y&&(Y.d(1),Y=null),z[0]&65536&&S!==(S=U[16].cancel+"")&&b(E,S),z[0]&65536&&q!==(q=U[16].create+"")&&b(V,q)},d(U){U&&F(e),O&&O.d(),Y&&Y.d(),t[49](null),Q=!1,Le(ce)}}}function ti(t){let e,n;return{c(){e=c("span"),n=g(t[9]),s(e,"class","field-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&512&&b(n,i[9])},d(i){i&&F(e)}}}function ni(t){let e,n;return{c(){e=c("div"),n=g(t[7]),s(e,"class","modal-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&128&&b(n,i[7])},d(i){i&&F(e)}}}function li(t){let e,n,i,o=t[16].join_network+"",a,r,_,d=t[16].network_name+"",u,v,f,m,j,w,A,p,C=t[16].password_opt+"",D,P,k,N,y,I,J,B,S=t[16].cancel+"",E,M,L,q=t[16].join+"",V,Q,ce,O=t[10]&&si(t),Y=t[8]&&ii(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),a=g(o),r=h(),_=c("label"),u=g(d),v=h(),f=c("input"),w=h(),O&&O.c(),A=h(),p=c("label"),D=g(C),P=h(),k=c("input"),y=h(),Y&&Y.c(),I=h(),J=c("div"),B=c("button"),E=g(S),M=h(),L=c("button"),V=g(q),s(i,"id","join-title"),s(i,"class","svelte-1oaanap"),s(_,"class","sr-only svelte-1oaanap"),s(_,"for","join-name"),s(f,"id","join-name"),s(f,"type","text"),s(f,"placeholder",m=t[16].network_name),s(f,"aria-invalid",j=!!t[10]),s(f,"class","svelte-1oaanap"),ke(f,"invalid",t[10]),s(p,"class","sr-only svelte-1oaanap"),s(p,"for","join-pass"),s(k,"id","join-pass"),s(k,"type","password"),s(k,"placeholder",N=t[16].password_opt),s(k,"class","svelte-1oaanap"),s(B,"class","btn svelte-1oaanap"),s(L,"class","btn primary svelte-1oaanap"),s(J,"class","modal-actions svelte-1oaanap"),s(n,"class","modal svelte-1oaanap"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","join-title"),s(e,"class","modal-overlay svelte-1oaanap"),s(e,"role","presentation")},m(U,z){K(U,e,z),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(n,v),l(n,f),ie(f,t[5]),l(n,w),O&&O.m(n,null),l(n,A),l(n,p),l(p,D),l(n,P),l(n,k),ie(k,t[6]),l(n,y),Y&&Y.m(n,null),l(n,I),l(n,J),l(J,B),l(B,E),l(J,M),l(J,L),l(L,V),t[54](n),Q||(ce=[W(f,"input",t[51]),W(k,"input",t[52]),W(B,"click",t[22]),W(L,"click",t[53]),W(n,"click",Gt(t[33])),W(n,"keydown",Gt(t[34])),W(e,"click",t[22]),W(e,"keydown",t[55])],Q=!0)},p(U,z){z[0]&65536&&o!==(o=U[16].join_network+"")&&b(a,o),z[0]&65536&&d!==(d=U[16].network_name+"")&&b(u,d),z[0]&65536&&m!==(m=U[16].network_name)&&s(f,"placeholder",m),z[0]&1024&&j!==(j=!!U[10])&&s(f,"aria-invalid",j),z[0]&32&&f.value!==U[5]&&ie(f,U[5]),z[0]&1024&&ke(f,"invalid",U[10]),U[10]?O?O.p(U,z):(O=si(U),O.c(),O.m(n,A)):O&&(O.d(1),O=null),z[0]&65536&&C!==(C=U[16].password_opt+"")&&b(D,C),z[0]&65536&&N!==(N=U[16].password_opt)&&s(k,"placeholder",N),z[0]&64&&k.value!==U[6]&&ie(k,U[6]),U[8]?Y?Y.p(U,z):(Y=ii(U),Y.c(),Y.m(n,I)):Y&&(Y.d(1),Y=null),z[0]&65536&&S!==(S=U[16].cancel+"")&&b(E,S),z[0]&65536&&q!==(q=U[16].join+"")&&b(V,q)},d(U){U&&F(e),O&&O.d(),Y&&Y.d(),t[54](null),Q=!1,Le(ce)}}}function si(t){let e,n;return{c(){e=c("span"),n=g(t[10]),s(e,"class","field-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&1024&&b(n,i[10])},d(i){i&&F(e)}}}function ii(t){let e,n;return{c(){e=c("div"),n=g(t[8]),s(e,"class","modal-error svelte-1oaanap"),s(e,"role","alert")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o[0]&256&&b(n,i[8])},d(i){i&&F(e)}}}function fo(t){let e,n,i,o=t[16].networks+"",a,r,_,d=ne(t[16].network_count,{n:t[0].length})+"",u,v,f,m,j=t[16].create_network+"",w,A,p,C,D=t[16].join_network+"",P,k,N,y,I=[],J=new Map,B,S,E,M=t[16].settings+"",L,q,V,Q,ce,O,Y=ft(t[0]);const U=Z=>Z[62].name;for(let Z=0;Zn(16,i=R)),ve(t,Ce,R=>n(17,o=R)),ve(t,ze,R=>n(18,a=R));let r=[],_=!1,d=!1,u="",v="",f="",m="",j="",w="",A="",p="",C="",D="",P="",k="network",N=null,y,I;fn(async()=>{n(0,r=await window.go.main.App.GetSavedRooms());const R=await window.go.main.App.LoadConfig();R.serverAddr&&(C=R.serverAddr),R.nickname&&(D=R.nickname),window.addEventListener("keydown",J),window.addEventListener("click",B)}),Mi(()=>{window.removeEventListener("keydown",J),window.removeEventListener("click",B)});function J(R){if(R.key==="Escape"){if(N){n(13,N=null);return}if(_){M();return}if(d){q();return}}}function B(){n(13,N=null)}async function S(){n(0,r=await window.go.main.App.GetSavedRooms())}function E(){n(7,j=""),n(9,A=""),n(1,_=!0),un()}function M(){n(1,_=!1),n(7,j=""),n(9,A="")}function L(){n(8,w=""),n(10,p=""),n(2,d=!0),un()}function q(){n(2,d=!1),n(8,w=""),n(10,p="")}async function V(){if(n(9,A=""),n(7,j=""),!u.trim()){n(9,A=i.field_required);return}try{await window.go.main.App.CreateRoom(u,v),ee(ne(i.notif_created,{name:u})),Ze(Ce,o="network",o),M(),n(3,u=""),n(4,v=""),await S()}catch(R){n(7,j=ne(i.error_create,{err:R})),ee(j,"error")}}async function Q(R,x){n(10,p=""),n(8,w="");const Se=R||f,Re=x!==void 0?x:m;if(!Se.trim()){n(10,p=i.field_required);return}try{await window.go.main.App.JoinRoom(Se,Re),ee(ne(i.notif_joined,{name:Se})),Ze(Ce,o="network",o),q(),n(5,f=""),n(6,m=""),await S()}catch(we){n(8,w=ne(i.error_join,{err:we})),ee(w,"error"),d||(n(5,f=Se),n(6,m=""),n(2,d=!0))}}async function ce(){if(confirm(i.confirm_leave))try{await window.go.main.App.LeaveRoom(),ee(i.notif_left),await S()}catch(R){ee(ne(i.error_leave,{err:R}),"error")}}async function O(R){const x=a.room===R;if(x){if(!confirm(i.confirm_leave_remove))return}else if(!confirm(ne(i.confirm_remove,{name:R})))return;try{x&&await window.go.main.App.LeaveRoom(),await window.go.main.App.RemoveSavedRoom(R),ee(ne(i.notif_removed,{name:R})),await S()}catch(Se){ee(ne(i.error_remove,{err:Se}),"error")}}async function Y(R){if(confirm(ne(i.confirm_delete,{name:R})))try{await window.go.main.App.DeleteRoom(R),await window.go.main.App.RemoveSavedRoom(R),ee(ne(i.notif_deleted,{name:R})),await S()}catch(x){ee(String(x),"error")}}async function U(R){try{const x=await window.go.main.App.FormatInvite(R.name,R.password||"");await window.go.main.App.CopyText(x);const Se=String(x).split("|"),Re=Se.length>=3&&Se[2]!=="";R.locked&&!Re?ee(i.invite_no_password,"info"):ee(i.invite_copied)}catch(x){ee(String(x),"error")}}async function z(){try{const R=await window.go.main.App.LoadConfig();R.serverAddr&&(C=R.serverAddr),R.nickname&&(D=R.nickname)}catch{}}async function te(R,x,Se){if(!P){n(11,P=R),n(13,N=null);try{await z();const Re=Se||C;if(!a.connected){if(!Re||!D){ee(i.notif_need_config,"error"),Ze(Ce,o="connect",o);return}const we=await window.go.main.App.Connect(Re,D);ze.set(we),await S()}await window.go.main.App.JoinRoom(R,x||""),Ze(Ce,o="network",o),await S()}catch(Re){const we=ne(i.error_join,{err:Re});ee(we,"error"),n(5,f=R),n(6,m=""),n(8,w=we),n(2,d=!0)}finally{n(11,P="")}}}function oe(R,x){(R.key==="Enter"||R.key===" ")&&(R.preventDefault(),te(x.name,x.password,x.server))}function Z(R,x){R.stopPropagation(),n(13,N=N===x?null:x)}function H(R,x){R.stopPropagation(),n(13,N=null),x()}function pe(R){zt.call(this,t,R)}function ue(R){zt.call(this,t,R)}function Ie(R){zt.call(this,t,R)}function Ne(R){zt.call(this,t,R)}function fe(R){zt.call(this,t,R)}function ye(R){zt.call(this,t,R)}const ge=(R,x)=>Z(x,R.name),je=(R,x)=>H(x,()=>U(R)),De=R=>H(R,ce),me=(R,x)=>H(x,()=>O(R.name)),le=(R,x)=>H(x,()=>Y(R.name)),We=R=>te(R.name,R.password,R.server),_e=(R,x)=>oe(x,R),he=()=>{o==="settings"?Ze(Ce,o=k,o):(n(12,k=o),Ze(Ce,o="settings",o))};function be(){u=this.value,n(3,u)}function X(){v=this.value,n(4,v)}function se(R){Vt[R?"unshift":"push"](()=>{y=R,n(14,y)})}const st=R=>R.key==="Escape"&&M();function Fe(){f=this.value,n(5,f)}function rt(){m=this.value,n(6,m)}const it=()=>Q();function re(R){Vt[R?"unshift":"push"](()=>{I=R,n(15,I)})}return[r,_,d,u,v,f,m,j,w,A,p,P,k,N,y,I,i,o,a,E,M,L,q,V,Q,ce,O,Y,U,te,oe,Z,H,pe,ue,Ie,Ne,fe,ye,ge,je,De,me,le,We,_e,he,be,X,se,st,Fe,rt,it,re,R=>R.key==="Escape"&&q()]}class vo extends wt{constructor(e){super(),gt(this,e,po,fo,dt,{},null,[-1,-1,-1])}}function oi(t,e,n){const i=t.slice();return i[24]=e[n],i}function ai(t){let e,n,i=t[5].chat+"",o,a,r,_,d,u=t[3]>0&&ri(t);return{c(){e=c("button"),n=g("[ "),o=g(i),a=g(` ] - `),u&&u.c(),s(e,"class","room-chat-btn svelte-mpjrp9"),s(e,"title",r=t[5].room_chat)},m(v,f){K(v,e,f),l(e,n),l(e,o),l(e,a),u&&u.m(e,null),_||(d=W(e,"click",t[8]),_=!0)},p(v,f){f&32&&i!==(i=v[5].chat+"")&&b(o,i),v[3]>0?u?u.p(v,f):(u=ri(v),u.c(),u.m(e,null)):u&&(u.d(1),u=null),f&32&&r!==(r=v[5].room_chat)&&s(e,"title",r)},d(v){v&&F(e),u&&u.d(),_=!1,d()}}}function ri(t){let e,n;return{c(){e=c("span"),n=g(t[3]),s(e,"class","badge svelte-mpjrp9")},m(i,o){K(i,e,o),l(e,n)},p(i,o){o&8&&b(n,i[3])},d(i){i&&F(e)}}}function ci(t){let e,n=t[5].status_relay_degraded+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","relay-hint svelte-mpjrp9")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&32&&n!==(n=o[5].status_relay_degraded+"")&&b(i,n)},d(o){o&&F(e)}}}function ui(t){let e,n,i,o,a=t[5].no_peers+"",r,_,d,u=t[5].no_peers_desc+"",v,f;return{c(){e=c("div"),n=c("div"),n.textContent="[ . . . ]",i=h(),o=c("div"),r=g(a),_=h(),d=c("div"),v=g(u),f=h(),s(n,"class","empty-icon"),s(o,"class","empty-label svelte-mpjrp9"),s(d,"class","empty-desc svelte-mpjrp9"),s(e,"class","empty-peers svelte-mpjrp9")},m(m,j){K(m,e,j),l(e,n),l(e,i),l(e,o),l(o,r),l(e,_),l(e,d),l(d,v),l(e,f)},p(m,j){j&32&&a!==(a=m[5].no_peers+"")&&b(r,a),j&32&&u!==(u=m[5].no_peers_desc+"")&&b(v,u)},d(m){m&&F(e)}}}function _i(t){let e,n=t[11](t[24].id)+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","badge svelte-mpjrp9")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&16&&n!==(n=o[11](o[24].id)+"")&&b(i,n)},d(o){o&&F(e)}}}function mo(t){let e;return{c(){e=g("...")},m(n,i){K(n,e,i)},p:de,d(n){n&&F(e)}}}function ho(t){let e=t[24].ping+"",n,i;return{c(){n=g(e),i=g("ms")},m(o,a){K(o,n,a),K(o,i,a)},p(o,a){a&16&&e!==(e=o[24].ping+"")&&b(n,e)},d(o){o&&(F(n),F(i))}}}function go(t){let e;return{c(){e=g("-")},m(n,i){K(n,e,i)},p:de,d(n){n&&F(e)}}}function fi(t,e){let n,i,o,a,r,_,d=(e[24].connected?e[5].status_online:e[5].status_offline)+"",u,v,f,m,j=(e[24].nickname||e[24].id)+"",w,A,p=e[11](e[24].id)>0,C,D,P=(e[24].virtualIP||e[5].na)+"",k,N,y,I,J,B=(e[24].path?e[12](e[24].path):e[5].path_unknown)+"",S,E,M,L,q,V,Q,ce,O,Y,U,z,te,oe,Z,H,pe,ue=p&&_i(e);function Ie(){return e[20](e[24])}function Ne(...me){return e[21](e[24],...me)}function fe(me,le){return me[24].connected?me[24].ping>=0&&!me[1][me[24].id]?ho:mo:go}let ye=fe(e),ge=ye(e);function je(){return e[22](e[24])}function De(){return e[23](e[24])}return{key:t,first:null,c(){n=c("div"),i=c("span"),o=c("span"),r=h(),_=c("span"),u=g(d),v=h(),f=c("span"),m=c("span"),w=g(j),A=h(),ue&&ue.c(),C=h(),D=c("span"),k=g(P),N=h(),y=c("span"),ge.c(),I=h(),J=c("span"),S=g(B),M=h(),L=c("span"),q=c("button"),V=g("[~]"),Y=h(),U=c("button"),z=g("[>]"),Z=h(),s(o,"class",a="sq "+(e[24].connected?"sq-online":"sq-offline")+" svelte-mpjrp9"),s(o,"aria-hidden","true"),s(_,"class","status-text svelte-mpjrp9"),s(i,"class","status-cell svelte-mpjrp9"),s(i,"role","cell"),s(m,"class","nickname svelte-mpjrp9"),s(f,"class","col-name"),s(f,"role","cell"),s(D,"class","col-ip clickable svelte-mpjrp9"),s(D,"role","button"),s(D,"tabindex","0"),s(y,"class","col-ping svelte-mpjrp9"),s(y,"role","cell"),ke(y,"probing",e[24].connected&&(e[24].ping<0||e[1][e[24].id])),s(J,"class","col-path svelte-mpjrp9"),s(J,"role","cell"),s(J,"title",E=e[13](e[24].path)),s(q,"class","row-btn svelte-mpjrp9"),q.disabled=Q=!e[24].connected||!!e[1][e[24].id],s(q,"title",ce=e[5].ping_peer),s(q,"aria-label",O=e[5].ping_peer),s(U,"class","row-btn svelte-mpjrp9"),s(U,"title",te=e[5].chat+" "+(e[24].nickname||e[24].id)),s(U,"aria-label",oe=e[5].chat+" "+(e[24].nickname||e[24].id)),s(L,"class","col-action svelte-mpjrp9"),s(L,"role","cell"),s(n,"class","table-row svelte-mpjrp9"),s(n,"role","row"),this.first=n},m(me,le){K(me,n,le),l(n,i),l(i,o),l(i,r),l(i,_),l(_,u),l(n,v),l(n,f),l(f,m),l(m,w),l(f,A),ue&&ue.m(f,null),l(n,C),l(n,D),l(D,k),l(n,N),l(n,y),ge.m(y,null),l(n,I),l(n,J),l(J,S),l(n,M),l(n,L),l(L,q),l(q,V),l(L,Y),l(L,U),l(U,z),l(n,Z),H||(pe=[W(D,"click",Ie),W(D,"keydown",Ne),W(q,"click",je),W(U,"click",De)],H=!0)},p(me,le){e=me,le&16&&a!==(a="sq "+(e[24].connected?"sq-online":"sq-offline")+" svelte-mpjrp9")&&s(o,"class",a),le&48&&d!==(d=(e[24].connected?e[5].status_online:e[5].status_offline)+"")&&b(u,d),le&16&&j!==(j=(e[24].nickname||e[24].id)+"")&&b(w,j),le&16&&(p=e[11](e[24].id)>0),p?ue?ue.p(e,le):(ue=_i(e),ue.c(),ue.m(f,null)):ue&&(ue.d(1),ue=null),le&48&&P!==(P=(e[24].virtualIP||e[5].na)+"")&&b(k,P),ye===(ye=fe(e))&&ge?ge.p(e,le):(ge.d(1),ge=ye(e),ge&&(ge.c(),ge.m(y,null))),le&18&&ke(y,"probing",e[24].connected&&(e[24].ping<0||e[1][e[24].id])),le&48&&B!==(B=(e[24].path?e[12](e[24].path):e[5].path_unknown)+"")&&b(S,B),le&16&&E!==(E=e[13](e[24].path))&&s(J,"title",E),le&18&&Q!==(Q=!e[24].connected||!!e[1][e[24].id])&&(q.disabled=Q),le&32&&ce!==(ce=e[5].ping_peer)&&s(q,"title",ce),le&32&&O!==(O=e[5].ping_peer)&&s(q,"aria-label",O),le&48&&te!==(te=e[5].chat+" "+(e[24].nickname||e[24].id))&&s(U,"title",te),le&48&&oe!==(oe=e[5].chat+" "+(e[24].nickname||e[24].id))&&s(U,"aria-label",oe)},d(me){me&&F(n),ue&&ue.d(),ge.d(),H=!1,Le(pe)}}}function wo(t){let e,n,i,o=(t[0].room||t[5].network)+"",a,r,_,d=(t[0].virtualIP||t[5].na)+"",u,v,f,m,j,w,A,p,C,D,P,k=t[5].col_nickname+"",N,y,I,J=t[5].col_ip+"",B,S,E,M=t[5].col_ping+"",L,q,V,Q=t[5].col_path+"",ce,O,Y,U,z,te,oe,Z,H,pe=t[5].status_online+"",ue,Ie,Ne,fe,ye=(t[6].nickname||t[5].you)+"",ge,je,De,me=t[5].me+"",le,We,_e,he=(t[0].virtualIP||t[5].na)+"",be,X,se,st,Fe,rt,it,re,Ae=[],R=new Map,x,Se,Re,we=t[0].room&&ai(t),Ee=t[2]&&ci(t),Ke=ft(t[4]);const bt=$=>$[24].id;for(let $=0;$n(5,r=E)),ve(t,Xl,E=>n(15,_=E)),ve(t,ze,E=>n(0,d=E)),ve(t,Yl,E=>n(16,u=E)),ve(t,Be,E=>n(6,v=E));let f={};function m(E){cn.set({id:E.id,nickname:E.nickname||E.id}),Kl("peer:"+E.id),Ce.set("chat")}function j(){cn.set(null),Kl("room:"+(d.room||"network")),Ce.set("chat")}async function w(E){if(E)try{await window.go.main.App.CopyText(E),ee(r.copied)}catch{}}async function A(E){if(!(!E?.id||!E.connected||f[E.id])){n(1,f={...f,[E.id]:!0});try{await window.go.main.App.PingPeer(E.id),ee(ne(r.ping_sent,{name:E.nickname||E.id}))}catch(M){ee(ne(r.error_ping,{err:M}),"error")}finally{setTimeout(()=>{const M={...f};delete M[E.id],n(1,f=M)},800)}}}function p(E){return _["peer:"+E]||0}function C(E){return E==="p2p"?r.path_p2p:E==="relay"?r.path_relay:E==="ws"?r.path_ws:r.path_unknown}function D(E){return E==="p2p"?r.path_p2p_tip:E==="relay"?r.path_relay_tip:E==="ws"?r.path_ws_tip:""}function P(E,M){(E.key==="Enter"||E.key===" ")&&(E.preventDefault(),w(M))}const k=()=>w(d.virtualIP),N=()=>w(d.virtualIP),y=E=>P(E,d.virtualIP),I=E=>w(E.virtualIP),J=(E,M)=>P(M,E.virtualIP),B=E=>A(E),S=E=>m(E);return t.$$.update=()=>{t.$$.dirty&65536&&n(4,i=[...u].sort((E,M)=>(E.nickname||"").localeCompare(M.nickname||""))),t.$$.dirty&32769&&n(3,o=_["room:"+(d.room||"network")]||0),t.$$.dirty&65536&&n(2,a=u.some(E=>E.path==="relay"||E.path==="ws"))},[d,f,a,o,i,r,v,m,j,w,A,p,C,D,P,_,u,k,N,y,I,J,B,S]}class bo extends wt{constructor(e){super(),gt(this,e,ko,wo,dt,{})}}function di(t){let e,n=t[2].status_relay_degraded+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","degraded status-item svelte-1pzfkl"),s(e,"title",o=t[2].path_relay_tip)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&4&&n!==(n=a[2].status_relay_degraded+"")&&b(i,n),r&4&&o!==(o=a[2].path_relay_tip)&&s(e,"title",o)},d(a){a&&F(e)}}}function pi(t){let e,n=ne(t[2].status_server,{s:t[3].server})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item status-server svelte-1pzfkl"),s(e,"title",o=t[3].server)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_server,{s:a[3].server})+"")&&b(i,n),r&8&&o!==(o=a[3].server)&&s(e,"title",o)},d(a){a&&F(e)}}}function vi(t){let e,n=ne(t[2].status_ip,{ip:t[3].virtualIP})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item svelte-1pzfkl"),s(e,"title",o=t[3].virtualIP)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_ip,{ip:a[3].virtualIP})+"")&&b(i,n),r&8&&o!==(o=a[3].virtualIP)&&s(e,"title",o)},d(a){a&&F(e)}}}function mi(t){let e,n=ne(t[2].status_network,{room:t[3].room})+"",i,o;return{c(){e=c("span"),i=g(n),s(e,"class","status-item status-room svelte-1pzfkl"),s(e,"title",o=t[3].room)},m(a,r){K(a,e,r),l(e,i)},p(a,r){r&12&&n!==(n=ne(a[2].status_network,{room:a[3].room})+"")&&b(i,n),r&8&&o!==(o=a[3].room)&&s(e,"title",o)},d(a){a&&F(e)}}}function hi(t){let e,n=ne(t[2].status_peers,{n:t[3].peerCount})+"",i;return{c(){e=c("span"),i=g(n),s(e,"class","status-item svelte-1pzfkl")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&12&&n!==(n=ne(o[2].status_peers,{n:o[3].peerCount})+"")&&b(i,n)},d(o){o&&F(e)}}}function yo(t){let e,n,i,o,a,r,_,d,u,v,f,m,j,w,A=ne(t[2].version,{v:t[4]})+"",p,C=t[1]&&t[3].connected&&di(t),D=t[3].server&&pi(t),P=t[3].virtualIP&&vi(t),k=t[3].room&&mi(t),N=t[3].peerCount!==void 0&&hi(t);return{c(){e=c("footer"),n=c("div"),i=c("span"),o=h(),a=c("span"),r=g(t[0]),_=h(),C&&C.c(),d=h(),u=c("div"),D&&D.c(),v=h(),P&&P.c(),f=h(),k&&k.c(),m=h(),N&&N.c(),j=h(),w=c("span"),p=g(A),s(i,"class","sq svelte-1pzfkl"),s(i,"aria-hidden","true"),ke(i,"sq-connected",t[3].connected&&!t[3].reconnecting),ke(i,"sq-warn",t[3].reconnecting),s(a,"class","status-item svelte-1pzfkl"),s(a,"title",t[5]),s(n,"class","status-left svelte-1pzfkl"),s(w,"class","status-item status-ver svelte-1pzfkl"),s(u,"class","status-right svelte-1pzfkl"),s(e,"class","statusbar svelte-1pzfkl"),s(e,"role","status"),s(e,"aria-live","polite")},m(y,I){K(y,e,I),l(e,n),l(n,i),l(n,o),l(n,a),l(a,r),l(n,_),C&&C.m(n,null),l(e,d),l(e,u),D&&D.m(u,null),l(u,v),P&&P.m(u,null),l(u,f),k&&k.m(u,null),l(u,m),N&&N.m(u,null),l(u,j),l(u,w),l(w,p)},p(y,[I]){I&8&&ke(i,"sq-connected",y[3].connected&&!y[3].reconnecting),I&8&&ke(i,"sq-warn",y[3].reconnecting),I&1&&b(r,y[0]),I&32&&s(a,"title",y[5]),y[1]&&y[3].connected?C?C.p(y,I):(C=di(y),C.c(),C.m(n,null)):C&&(C.d(1),C=null),y[3].server?D?D.p(y,I):(D=pi(y),D.c(),D.m(u,v)):D&&(D.d(1),D=null),y[3].virtualIP?P?P.p(y,I):(P=vi(y),P.c(),P.m(u,f)):P&&(P.d(1),P=null),y[3].room?k?k.p(y,I):(k=mi(y),k.c(),k.m(u,m)):k&&(k.d(1),k=null),y[3].peerCount!==void 0?N?N.p(y,I):(N=hi(y),N.c(),N.m(u,j)):N&&(N.d(1),N=null),I&20&&A!==(A=ne(y[2].version,{v:y[4]})+"")&&b(p,A)},i:de,o:de,d(y){y&&F(e),C&&C.d(),D&&D.d(),P&&P.d(),k&&k.d(),N&&N.d()}}}function jo(t,e,n){let i,o,a,r,_,d;ve(t,kt,v=>n(2,r=v)),ve(t,ze,v=>n(3,_=v)),ve(t,Yl,v=>n(6,d=v));let u="1.0.0";return fn(async()=>{try{window.go?.main?.App?.GetVersion&&n(4,u=await window.go.main.App.GetVersion())}catch{}}),t.$$.update=()=>{t.$$.dirty&64&&n(1,i=(d||[]).some(v=>v.path==="relay"||v.path==="ws")),t.$$.dirty&12&&n(0,o=_.reconnecting?r.status_reconnecting:_.connected?r.status_connected:r.status_disconnected),t.$$.dirty&15&&n(5,a=i&&_.connected?r.status_relay_degraded:o)},[o,i,r,_,u,a,d]}class So extends wt{constructor(e){super(),gt(this,e,jo,yo,dt,{})}}function Eo(t){let e,n,i,o,a=t[0].server+"",r,_,d,u=t[1].server+"",v,f,m,j,w=t[0].virtual_ip+"",A,p,C,D=(t[1].virtualIP||t[0].na)+"",P,k,N,y=t[0].disconnect+"",I,J,B;function S(L,q){return L[1].reconnecting?Co:Po}let E=S(t),M=E(t);return{c(){e=c("div"),M.c(),n=h(),i=c("div"),o=c("span"),r=g(a),_=h(),d=c("span"),v=g(u),f=h(),m=c("div"),j=c("span"),A=g(w),p=h(),C=c("span"),P=g(D),k=h(),N=c("button"),I=g(y),s(d,"class","info-value svelte-1br9j49"),s(i,"class","info-line svelte-1br9j49"),s(C,"class","info-value svelte-1br9j49"),s(m,"class","info-line svelte-1br9j49"),s(N,"class","disconnect-btn svelte-1br9j49"),s(e,"class","connected-info svelte-1br9j49")},m(L,q){K(L,e,q),M.m(e,null),l(e,n),l(e,i),l(i,o),l(o,r),l(i,_),l(i,d),l(d,v),l(e,f),l(e,m),l(m,j),l(j,A),l(m,p),l(m,C),l(C,P),l(e,k),l(e,N),l(N,I),J||(B=W(N,"click",t[12]),J=!0)},p(L,q){E===(E=S(L))&&M?M.p(L,q):(M.d(1),M=E(L),M&&(M.c(),M.m(e,n))),q&1&&a!==(a=L[0].server+"")&&b(r,a),q&2&&u!==(u=L[1].server+"")&&b(v,u),q&1&&w!==(w=L[0].virtual_ip+"")&&b(A,w),q&3&&D!==(D=(L[1].virtualIP||L[0].na)+"")&&b(P,D),q&1&&y!==(y=L[0].disconnect+"")&&b(I,y)},d(L){L&&F(e),M.d(),J=!1,B()}}}function Ao(t){let e,n,i,o=t[0].brand+"",a,r,_,d=t[0].tagline+"",u,v,f,m,j=t[0].server_addr+"",w,A,p,C,D,P,k,N,y,I=t[0].nickname+"",J,B,S,E,M,L,q,V,Q=(t[5]?t[0].connecting:t[0].connect)+"",ce,O,Y,U,z,te=t[0].paste_invite+"",oe,Z,H,pe,ue=t[0].paste_invite+"",Ie,Ne,fe,ye,ge,je,De=t[0].join+"",me,le,We,_e=t[7].serverAddr&&gi(t),he=t[7].nickname&&wi(t),be=(t[5]||t[1].phase==="dialing"||t[1].phase==="auth")&&ki(t);return{c(){e=c("div"),n=c("div"),i=c("h1"),a=g(o),r=h(),_=c("p"),u=g(d),v=h(),f=c("div"),m=c("label"),w=g(j),A=h(),p=c("input"),P=h(),_e&&_e.c(),k=h(),N=c("div"),y=c("label"),J=g(I),B=h(),S=c("input"),L=h(),he&&he.c(),q=h(),V=c("button"),ce=g(Q),O=h(),be&&be.c(),Y=h(),U=c("details"),z=c("summary"),oe=g(te),Z=h(),H=c("div"),pe=c("label"),Ie=g(ue),Ne=h(),fe=c("input"),ge=h(),je=c("button"),me=g(De),s(i,"class","brand svelte-1br9j49"),s(_,"class","tagline svelte-1br9j49"),s(n,"class","brand-block svelte-1br9j49"),s(m,"for","server-input"),s(m,"class","svelte-1br9j49"),s(p,"id","server-input"),s(p,"type","text"),s(p,"placeholder","host:8080"),s(p,"aria-invalid",C=!!t[7].serverAddr),s(p,"aria-describedby",D=t[7].serverAddr?"server-err":void 0),s(p,"class","svelte-1br9j49"),ke(p,"invalid",t[7].serverAddr),s(f,"class","field svelte-1br9j49"),s(y,"for","nick-input"),s(y,"class","svelte-1br9j49"),s(S,"id","nick-input"),s(S,"type","text"),s(S,"placeholder","Player"),s(S,"aria-invalid",E=!!t[7].nickname),s(S,"aria-describedby",M=t[7].nickname?"nick-err":void 0),s(S,"class","svelte-1br9j49"),ke(S,"invalid",t[7].nickname),s(N,"class","field svelte-1br9j49"),s(V,"class","connect-btn svelte-1br9j49"),V.disabled=t[5],s(z,"class","svelte-1br9j49"),s(pe,"for","invite-input"),s(pe,"class","sr-only svelte-1br9j49"),s(fe,"id","invite-input"),s(fe,"type","text"),s(fe,"placeholder",ye=t[0].invite_placeholder),s(fe,"class","svelte-1br9j49"),s(je,"class","secondary-btn svelte-1br9j49"),je.disabled=t[5],s(H,"class","invite-block svelte-1br9j49"),s(U,"class","invite-disclosure svelte-1br9j49"),s(e,"class","connect-form svelte-1br9j49")},m(X,se){K(X,e,se),l(e,n),l(n,i),l(i,a),l(n,r),l(n,_),l(_,u),l(e,v),l(e,f),l(f,m),l(m,w),l(f,A),l(f,p),ie(p,t[2]),l(f,P),_e&&_e.m(f,null),l(e,k),l(e,N),l(N,y),l(y,J),l(N,B),l(N,S),ie(S,t[3]),l(N,L),he&&he.m(N,null),l(e,q),l(e,V),l(V,ce),l(e,O),be&&be.m(e,null),l(e,Y),l(e,U),l(U,z),l(z,oe),l(U,Z),l(U,H),l(H,pe),l(pe,Ie),l(H,Ne),l(H,fe),ie(fe,t[4]),l(H,ge),l(H,je),l(je,me),U.open=t[6],le||(We=[W(p,"input",t[13]),W(S,"input",t[14]),W(S,"keydown",t[11]),W(V,"click",t[9]),W(fe,"input",t[15]),W(je,"click",t[10]),W(U,"toggle",t[16])],le=!0)},p(X,se){se&1&&o!==(o=X[0].brand+"")&&b(a,o),se&1&&d!==(d=X[0].tagline+"")&&b(u,d),se&1&&j!==(j=X[0].server_addr+"")&&b(w,j),se&128&&C!==(C=!!X[7].serverAddr)&&s(p,"aria-invalid",C),se&128&&D!==(D=X[7].serverAddr?"server-err":void 0)&&s(p,"aria-describedby",D),se&4&&p.value!==X[2]&&ie(p,X[2]),se&128&&ke(p,"invalid",X[7].serverAddr),X[7].serverAddr?_e?_e.p(X,se):(_e=gi(X),_e.c(),_e.m(f,null)):_e&&(_e.d(1),_e=null),se&1&&I!==(I=X[0].nickname+"")&&b(J,I),se&128&&E!==(E=!!X[7].nickname)&&s(S,"aria-invalid",E),se&128&&M!==(M=X[7].nickname?"nick-err":void 0)&&s(S,"aria-describedby",M),se&8&&S.value!==X[3]&&ie(S,X[3]),se&128&&ke(S,"invalid",X[7].nickname),X[7].nickname?he?he.p(X,se):(he=wi(X),he.c(),he.m(N,null)):he&&(he.d(1),he=null),se&33&&Q!==(Q=(X[5]?X[0].connecting:X[0].connect)+"")&&b(ce,Q),se&32&&(V.disabled=X[5]),X[5]||X[1].phase==="dialing"||X[1].phase==="auth"?be?be.p(X,se):(be=ki(X),be.c(),be.m(e,Y)):be&&(be.d(1),be=null),se&1&&te!==(te=X[0].paste_invite+"")&&b(oe,te),se&1&&ue!==(ue=X[0].paste_invite+"")&&b(Ie,ue),se&1&&ye!==(ye=X[0].invite_placeholder)&&s(fe,"placeholder",ye),se&16&&fe.value!==X[4]&&ie(fe,X[4]),se&1&&De!==(De=X[0].join+"")&&b(me,De),se&32&&(je.disabled=X[5]),se&64&&(U.open=X[6])},d(X){X&&F(e),_e&&_e.d(),he&&he.d(),be&&be.d(),le=!1,Le(We)}}}function Po(t){let e,n,i,o,a=t[0].connected+"",r;return{c(){e=c("div"),n=c("span"),i=h(),o=c("span"),r=g(a),s(n,"class","sq sq-green svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,d){K(_,e,d),l(e,n),l(e,i),l(e,o),l(o,r)},p(_,d){d&1&&a!==(a=_[0].connected+"")&&b(r,a)},d(_){_&&F(e)}}}function Co(t){let e,n,i,o,a=t[0].reconnecting+"",r;return{c(){e=c("div"),n=c("span"),i=h(),o=c("span"),r=g(a),s(n,"class","sq sq-warn svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,d){K(_,e,d),l(e,n),l(e,i),l(e,o),l(o,r)},p(_,d){d&1&&a!==(a=_[0].reconnecting+"")&&b(r,a)},d(_){_&&F(e)}}}function gi(t){let e,n=t[7].serverAddr+"",i;return{c(){e=c("span"),i=g(n),s(e,"id","server-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].serverAddr+"")&&b(i,n)},d(o){o&&F(e)}}}function wi(t){let e,n=t[7].nickname+"",i;return{c(){e=c("span"),i=g(n),s(e,"id","nick-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].nickname+"")&&b(i,n)},d(o){o&&F(e)}}}function ki(t){let e,n=(t[8]||t[0].connecting)+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","phase svelte-1br9j49"),s(e,"role","status")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&257&&n!==(n=(o[8]||o[0].connecting)+"")&&b(i,n)},d(o){o&&F(e)}}}function No(t){let e;function n(a,r){return a[1].connected?Eo:Ao}let i=n(t),o=i(t);return{c(){e=c("div"),o.c(),s(e,"class","connect-view svelte-1br9j49")},m(a,r){K(a,e,r),o.m(e,null)},p(a,[r]){i===(i=n(a))&&o?o.p(a,r):(o.d(1),o=i(a),o&&(o.c(),o.m(e,null)))},i:de,o:de,d(a){a&&F(e),o.d()}}}function Do(t,e,n){let i,o,a,r;ve(t,kt,y=>n(0,o=y)),ve(t,ze,y=>n(1,a=y)),ve(t,Be,y=>n(17,r=y));let _="",d="",u="",v=!1,f=!1,m={};fn(async()=>{const y=await window.go.main.App.LoadConfig();y.serverAddr&&n(2,_=y.serverAddr),y.nickname&&n(3,d=y.nickname),y&&Be.set({...r,...y}),y.autoConnect&&y.serverAddr&&y.nickname&&w()});function j(){const y={};return _.trim()||(y.serverAddr=o.field_required),d.trim()||(y.nickname=o.field_required),n(7,m=y),Object.keys(y).length===0}async function w(){if(!v&&j()){n(5,v=!0),un();try{const y=await window.go.main.App.Connect(_,d);ze.set(y),Ce.set("network"),ee(ne(o.notif_connected,{addr:_})),n(7,m={})}catch(y){ee(ne(o.error_connect,{err:y}),"error")}finally{n(5,v=!1)}}}async function A(){if(u.trim()){un();try{const y=await window.go.main.App.ParseInvite(u.trim());if(!y.server||!y.room){ee(o.error_invalid_invite,"error");return}if(n(2,_=y.server),!a.connected){if(!d.trim()){n(7,m={...m,nickname:o.field_required}),ee(o.notif_need_config,"error");return}n(5,v=!0);const I=await window.go.main.App.Connect(_,d);ze.set(I),n(5,v=!1)}await window.go.main.App.JoinRoom(y.room,y.password||""),ee(ne(o.notif_joined,{name:y.room})),Ce.set("network")}catch(y){ee(ne(o.error_join,{err:y}),"error"),n(5,v=!1)}}}function p(y){y.key==="Enter"&&(y.preventDefault(),w())}async function C(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),ze.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ce.set("connect"),ee(o.notif_disconnected)}catch(y){ee(ne(o.error_disconnect,{err:y}),"error")}}function D(){_=this.value,n(2,_)}function P(){d=this.value,n(3,d)}function k(){u=this.value,n(4,u)}function N(){f=this.open,n(6,f)}return t.$$.update=()=>{t.$$.dirty&3&&n(8,i=a.phase==="dialing"?o.phase_dialing:a.phase==="auth"?o.phase_auth:a.phase==="ready"?o.phase_ready:a.phase==="error"?o.phase_error:"")},[o,a,_,d,u,v,f,m,i,w,A,p,C,D,P,k,N]}class Lo extends wt{constructor(e){super(),gt(this,e,Do,No,dt,{})}}function bi(t,e,n){const i=t.slice();return i[23]=e[n],i[25]=n,i}function yi(t){let e,n,i,o,a=t[0].no_messages+"",r,_,d,u=t[0].no_messages_desc+"",v;return{c(){e=c("div"),n=c("div"),n.textContent="[ . . . ]",i=h(),o=c("div"),r=g(a),_=h(),d=c("div"),v=g(u),s(n,"class","empty-chat-icon"),s(o,"class","empty-chat-label svelte-11c1d7e"),s(d,"class","empty-chat-desc svelte-11c1d7e"),s(e,"class","empty-chat svelte-11c1d7e")},m(f,m){K(f,e,m),l(e,n),l(e,i),l(e,o),l(o,r),l(e,_),l(e,d),l(d,v)},p(f,m){m&1&&a!==(a=f[0].no_messages+"")&&b(r,a),m&1&&u!==(u=f[0].no_messages_desc+"")&&b(v,u)},d(f){f&&F(e)}}}function ji(t){let e,n=t[12](t[23].timestamp)+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","date-sep svelte-11c1d7e")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[12](o[23].timestamp)+"")&&b(i,n)},d(o){o&&F(e)}}}function Io(t){let e,n,i,o=(t[23].isSelf?t[6].nickname||t[0].you_self:t[23].nickname)+"",a,r,_,d,u,v=t[23].message+"",f,m,j=t[23].status==="pending"&&Si(),w=t[23].status==="failed"&&Ei(t);return{c(){e=c("div"),n=c("div"),i=c("span"),a=g(o),r=h(),j&&j.c(),_=h(),w&&w.c(),d=h(),u=c("div"),f=g(v),m=h(),s(i,"class","msg-nick"),s(n,"class","msg-meta svelte-11c1d7e"),s(u,"class","msg-body svelte-11c1d7e"),s(e,"class","msg svelte-11c1d7e"),ke(e,"self",t[23].isSelf)},m(A,p){K(A,e,p),l(e,n),l(n,i),l(i,a),l(n,r),j&&j.m(n,null),l(n,_),w&&w.m(n,null),l(e,d),l(e,u),l(u,f),l(e,m)},p(A,p){p&193&&o!==(o=(A[23].isSelf?A[6].nickname||A[0].you_self:A[23].nickname)+"")&&b(a,o),A[23].status==="pending"?j||(j=Si(),j.c(),j.m(n,_)):j&&(j.d(1),j=null),A[23].status==="failed"?w?w.p(A,p):(w=Ei(A),w.c(),w.m(n,null)):w&&(w.d(1),w=null),p&128&&v!==(v=A[23].message+"")&&b(f,v),p&128&&ke(e,"self",A[23].isSelf)},d(A){A&&F(e),j&&j.d(),w&&w.d()}}}function Ro(t){let e,n=t[23].message+"",i;return{c(){e=c("div"),i=g(n),s(e,"class","system-line svelte-11c1d7e")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[23].message+"")&&b(i,n)},d(o){o&&F(e)}}}function Si(t){let e;return{c(){e=c("span"),e.textContent="…",s(e,"class","msg-status")},m(n,i){K(n,e,i)},d(n){n&&F(e)}}}function Ei(t){let e,n=t[0].retry+"",i,o,a;function r(){return t[18](t[23])}return{c(){e=c("button"),i=g(n),s(e,"class","retry-btn svelte-11c1d7e")},m(_,d){K(_,e,d),l(e,i),o||(a=W(e,"click",r),o=!0)},p(_,d){t=_,d&1&&n!==(n=t[0].retry+"")&&b(i,n)},d(_){_&&F(e),o=!1,a()}}}function Ai(t,e){let n,i=Pi(e[23],e[25],e[7]),o,a,r=i&&ji(e);function _(v,f){return v[23].system?Ro:Io}let d=_(e),u=d(e);return{key:t,first:null,c(){n=Ul(),r&&r.c(),o=h(),u.c(),a=Ul(),this.first=n},m(v,f){K(v,n,f),r&&r.m(v,f),K(v,o,f),u.m(v,f),K(v,a,f)},p(v,f){e=v,f&128&&(i=Pi(e[23],e[25],e[7])),i?r?r.p(e,f):(r=ji(e),r.c(),r.m(o.parentNode,o)):r&&(r.d(1),r=null),d===(d=_(e))&&u?u.p(e,f):(u.d(1),u=d(e),u&&(u.c(),u.m(a.parentNode,a)))},d(v){v&&(F(n),F(o),F(a)),r&&r.d(v),u.d(v)}}}function To(t){let e,n,i,o,a,r,_,d,u,v,f,m=[],j=new Map,w,A,p,C,D,P,k,N=t[0].send+"",y,I,J,B,S=t[7].length===0&&yi(t),E=ft(t[7]);const M=L=>L[23].id;for(let L=0;Ln(15,a=S)),ve(t,kt,S=>n(0,r=S)),ve(t,cn,S=>n(16,_=S)),ve(t,Be,S=>n(6,d=S)),ve(t,Ce,S=>n(17,u=S)),ve(t,so,S=>n(7,v=S));let f="",m,j,w=!0;Gi(()=>{m&&w&&n(2,m.scrollTop=m.scrollHeight,m)});function A(){if(!m)return;w=m.scrollHeight-m.scrollTop-m.clientHeight<60}async function p(){const S=f.trim();if(!S)return;if(!a.connected){ee(r.error_not_connected,"error");return}if(!a.room){ee(r.send_disabled_no_room,"error");return}let E=S;const M=[...S];M.length>1e3&&(E=M.slice(0,1e3).join(""),ee(r.msg_truncated,"info")),n(1,f=""),j&&n(3,j.style.height="auto",j);const L="local_"+Date.now()+"_"+Math.random().toString(36).slice(2,7);Ql(L,d.nickname||r.you_self,E,!0,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,E):await window.go.main.App.BroadcastChat(E),ln(L,"sent")}catch(q){ln(L,"failed"),ee(ne(r.error_send,{err:q}),"error")}}async function C(S){ln(S.id,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,S.message):await window.go.main.App.BroadcastChat(S.message),ln(S.id,"sent")}catch(E){ln(S.id,"failed"),ee(ne(r.error_send,{err:E}),"error")}}function D(S){S.key==="Enter"&&!S.shiftKey&&(S.preventDefault(),p())}function P(S){const E=new Date(S),M=new Date,L=new Date(M.getFullYear(),M.getMonth(),M.getDate()),q=new Date(L-864e5),V=new Date(E.getFullYear(),E.getMonth(),E.getDate());return V.getTime()===L.getTime()?r.today:V.getTime()===q.getTime()?r.yesterday:E.toLocaleDateString([],{weekday:"long",month:"short",day:"numeric"})}function k(){j&&(n(3,j.style.height="auto",j),n(3,j.style.height=Math.min(j.scrollHeight,120)+"px",j))}function N(){cn.set(null),Ce.set("network")}const y=S=>C(S);function I(S){Vt[S?"unshift":"push"](()=>{m=S,n(2,m)})}function J(S){Vt[S?"unshift":"push"](()=>{j=S,n(3,j)})}function B(){f=this.value,n(1,f)}return t.$$.update=()=>{t.$$.dirty&131072&&u==="chat"&&Kl(_n()),t.$$.dirty&98305&&n(5,i=_?ne(r.chat_with,{name:_.nickname}):ne(r.room_chat_title,{room:a.room||r.network})),t.$$.dirty&32768&&n(4,o=a.connected&&!!a.room)},[r,f,m,j,o,i,d,v,A,p,C,D,P,k,N,a,_,u,y,I,J,B]}class Mo extends wt{constructor(e){super(),gt(this,e,Oo,To,dt,{})}}function Ci(t){let e,n=t[7].notif_reconnect_required+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","reconnect-banner svelte-1pfl9w0"),s(e,"role","status")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].notif_reconnect_required+"")&&b(i,n)},d(o){o&&F(e)}}}function Ni(t){let e,n=t[7].apply_update+"",i,o,a;return{c(){e=c("button"),i=g(n),s(e,"class","btn btn-update svelte-1pfl9w0"),s(e,"type","button"),e.disabled=t[3]},m(r,_){K(r,e,_),l(e,i),o||(a=W(e,"click",t[10]),o=!0)},p(r,_){_&128&&n!==(n=r[7].apply_update+"")&&b(i,n),_&8&&(e.disabled=r[3])},d(r){r&&F(e),o=!1,a()}}}function qo(t){let e,n=t[7].update_failed+"",i,o,a;return{c(){e=c("p"),i=g(n),o=g(": "),a=g(t[6]),s(e,"class","hint reconnect-hint svelte-1pfl9w0")},m(r,_){K(r,e,_),l(e,i),l(e,o),l(e,a)},p(r,_){_&128&&n!==(n=r[7].update_failed+"")&&b(i,n),_&64&&b(a,r[6])},d(r){r&&F(e)}}}function Uo(t){let e,n=t[7].update_downloading+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_downloading+"")&&b(i,n)},d(o){o&&F(e)}}}function zo(t){let e,n=ne(t[7].update_available,{v:t[5]})+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&160&&n!==(n=ne(o[7].update_available,{v:o[5]})+"")&&b(i,n)},d(o){o&&F(e)}}}function Wo(t){let e,n=t[7].update_latest+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_latest+"")&&b(i,n)},d(o){o&&F(e)}}}function Fo(t){let e,n=t[7].update_checking+"",i;return{c(){e=c("p"),i=g(n),s(e,"class","hint svelte-1pfl9w0")},m(o,a){K(o,e,a),l(e,i)},p(o,a){a&128&&n!==(n=o[7].update_checking+"")&&b(i,n)},d(o){o&&F(e)}}}function Ko(t){let e,n,i=t[7].settings_title+"",o,a,r,_,d,u,v,f=t[7].section_connection+"",m,j,w,A,p,C=t[7].server_addr+"",D,P,k,N,y,I,J=t[7].nickname+"",B,S,E,M,L,q,V=t[7].server_token+"",Q,ce,O,Y,U,z,te=t[7].reconnect_apply+"",oe,Z,H,pe,ue=t[7].auto_connect+"",Ie,Ne,fe,ye,ge,je=t[7].auto_connect_desc+"",De,me,le,We,_e=t[7].auto_join+"",he,be,X,se,st,Fe=t[7].auto_join_desc+"",rt,it,re,Ae,R,x=t[7].section_network+"",Se,Re,we,Ee,Ke=t[7].advanced_warn+"",bt,Pe,$,ae,Je=t[7].connection_mode+"",il,xl,xe,yt,dn=t[7].connection_direct+"",ol,jt,pn=t[7].connection_relay+"",al,es,vn,mn=t[7].connection_mode_desc+"",rl,ts,St,Yt,hn=t[7].mtu+"",cl,ns,Ge,ls,gn,wn=t[7].mtu_desc+"",ul,ss,Et,Ht,kn=t[7].dns_server+"",_l,is,et,os,bn,yn=t[7].dns_desc+"",fl,as,At,Xt,jn=t[7].socks5+"",dl,rs,He,Sn,cs,En,An=t[7].socks5_desc+"",pl,us,Pt,Qt,Pn=t[7].stun_server+"",vl,_s,tt,fs,Cn,Nn=t[7].stun_desc+"",ml,ds,Xe,Ct,ps,Dn=t[7].section_system+"",hl,vs,ms,Nt,Ln,In=t[7].start_windows+"",gl,hs,pt,gs,ot,Rn,Tn=t[7].updates+"",wl,ws,ct,On=t[7].check_updates+"",kl,ks,bs,ys,Ve,Dt,js,Mn=t[7].section_appearance+"",bl,Ss,Es,ut,Zt,qn=t[7].ui_scale+"",yl,As,Qe,Un,Ps,$t,zn=(t[0].uiScale??100)+"",jl,Cs,Ns,Wn,Fn=t[7].ui_scale_desc+"",Sl,Ds,Lt,Kn,Jn=t[7].theme+"",El,Ls,at,It,qe,Is,Gn=t[7].theme_dark+"",Al,Rs,Rt,Ue,Ts,Vn=t[7].theme_light+"",Pl,Bn,Os,Tt,xt,Yn=t[7].language+"",Cl,Ms,nt,Ot,Hn=t[7].language_en+"",Nl,Mt,Xn=t[7].language_ru+"",Dl,qt,Qn=t[7].language_zh+"",Ll,qs,Us,_t,en,Zn=t[7].save+"",Il,zs,tn,$n=t[7].reset+"",Rl,Ws,nn,Fs,Tl,Ol,Ml,Ks,Te=t[2]&&Ci(t),Oe=t[4]==="available"&&Ni(t);function Js(T,G){if(T[4]==="checking")return Fo;if(T[4]==="latest")return Wo;if(T[4]==="available")return zo;if(T[4]==="downloading")return Uo;if(T[4]==="error"&&T[6])return qo}let Ut=Js(t),Me=Ut&&Ut(t);return Ol=Fi(t[28][0]),{c(){e=c("div"),n=c("h2"),o=g(i),a=h(),r=c("div"),Te&&Te.c(),_=h(),d=c("div"),u=c("div"),v=g("─── "),m=g(f),j=g(" ───"),w=h(),A=c("div"),p=c("label"),D=g(C),P=h(),k=c("input"),N=h(),y=c("div"),I=c("label"),B=g(J),S=h(),E=c("input"),M=h(),L=c("div"),q=c("label"),Q=g(V),ce=h(),O=c("input"),U=h(),z=c("p"),oe=g(te),Z=h(),H=c("label"),pe=c("span"),Ie=g(ue),Ne=h(),fe=c("input"),ye=h(),ge=c("span"),De=g(je),me=h(),le=c("label"),We=c("span"),he=g(_e),be=h(),X=c("input"),se=h(),st=c("span"),rt=g(Fe),it=h(),re=c("div"),Ae=c("div"),R=g("─── "),Se=g(x),Re=g(" ───"),we=h(),Ee=c("p"),bt=g(Ke),Pe=h(),$=c("div"),ae=c("label"),il=g(Je),xl=h(),xe=c("select"),yt=c("option"),ol=g(dn),jt=c("option"),al=g(pn),es=h(),vn=c("p"),rl=g(mn),ts=h(),St=c("div"),Yt=c("label"),cl=g(hn),ns=h(),Ge=c("input"),ls=h(),gn=c("p"),ul=g(wn),ss=h(),Et=c("div"),Ht=c("label"),_l=g(kn),is=h(),et=c("input"),os=h(),bn=c("p"),fl=g(yn),as=h(),At=c("div"),Xt=c("label"),dl=g(jn),rs=h(),He=c("input"),cs=h(),En=c("p"),pl=g(An),us=h(),Pt=c("div"),Qt=c("label"),vl=g(Pn),_s=h(),tt=c("input"),fs=h(),Cn=c("p"),ml=g(Nn),ds=h(),Xe=c("div"),Ct=c("div"),ps=g("─── "),hl=g(Dn),vs=g(" ───"),ms=h(),Nt=c("label"),Ln=c("span"),gl=g(In),hs=h(),pt=c("input"),gs=h(),ot=c("div"),Rn=c("span"),wl=g(Tn),ws=h(),ct=c("button"),kl=g(On),ks=h(),Oe&&Oe.c(),bs=h(),Me&&Me.c(),ys=h(),Ve=c("div"),Dt=c("div"),js=g("─── "),bl=g(Mn),Ss=g(" ───"),Es=h(),ut=c("div"),Zt=c("label"),yl=g(qn),As=h(),Qe=c("input"),Ps=h(),$t=c("span"),jl=g(zn),Cs=g("%"),Ns=h(),Wn=c("p"),Sl=g(Fn),Ds=h(),Lt=c("div"),Kn=c("span"),El=g(Jn),Ls=h(),at=c("div"),It=c("label"),qe=c("input"),Is=h(),Al=g(Gn),Rs=h(),Rt=c("label"),Ue=c("input"),Ts=h(),Pl=g(Vn),Os=h(),Tt=c("div"),xt=c("label"),Cl=g(Yn),Ms=h(),nt=c("select"),Ot=c("option"),Nl=g(Hn),Mt=c("option"),Dl=g(Xn),qt=c("option"),Ll=g(Qn),Us=h(),_t=c("div"),en=c("button"),Il=g(Zn),zs=h(),tn=c("button"),Rl=g($n),Ws=h(),nn=c("div"),Fs=g("v"),Tl=g(t[1]),s(n,"class","settings-title svelte-1pfl9w0"),s(u,"class","section-title svelte-1pfl9w0"),s(p,"class","setting-label svelte-1pfl9w0"),s(p,"for","cfg-server"),s(k,"id","cfg-server"),s(k,"type","text"),s(k,"placeholder","vps.example.com:8080"),s(k,"class","svelte-1pfl9w0"),s(A,"class","setting-row svelte-1pfl9w0"),s(I,"class","setting-label svelte-1pfl9w0"),s(I,"for","cfg-nick"),s(E,"id","cfg-nick"),s(E,"type","text"),s(E,"placeholder","Your nickname"),s(E,"class","svelte-1pfl9w0"),s(y,"class","setting-row svelte-1pfl9w0"),s(q,"class","setting-label svelte-1pfl9w0"),s(q,"for","cfg-token"),s(O,"id","cfg-token"),s(O,"type","password"),s(O,"placeholder",Y=t[7].server_token_desc),s(O,"class","svelte-1pfl9w0"),s(L,"class","setting-row svelte-1pfl9w0"),s(z,"class","hint reconnect-hint svelte-1pfl9w0"),s(pe,"class","setting-label svelte-1pfl9w0"),s(fe,"type","checkbox"),s(fe,"class","svelte-1pfl9w0"),s(ge,"class","toggle-label svelte-1pfl9w0"),s(H,"class","setting-row toggle-row svelte-1pfl9w0"),s(We,"class","setting-label svelte-1pfl9w0"),s(X,"type","checkbox"),s(X,"class","svelte-1pfl9w0"),s(st,"class","toggle-label svelte-1pfl9w0"),s(le,"class","setting-row toggle-row svelte-1pfl9w0"),s(d,"class","section svelte-1pfl9w0"),s(Ae,"class","section-title svelte-1pfl9w0"),s(Ee,"class","hint svelte-1pfl9w0"),s(ae,"class","setting-label svelte-1pfl9w0"),s(ae,"for","cfg-conn"),yt.__value="direct",ie(yt,yt.__value),jt.__value="relay",ie(jt,jt.__value),s(xe,"id","cfg-conn"),s(xe,"class","svelte-1pfl9w0"),t[0].connectionMode===void 0&&tl(()=>t[21].call(xe)),s($,"class","setting-row svelte-1pfl9w0"),s(vn,"class","hint svelte-1pfl9w0"),s(Yt,"class","setting-label svelte-1pfl9w0"),s(Yt,"for","cfg-mtu"),s(Ge,"id","cfg-mtu"),s(Ge,"type","number"),s(Ge,"min","576"),s(Ge,"max","9000"),s(Ge,"placeholder","1500"),s(Ge,"class","svelte-1pfl9w0"),s(St,"class","setting-row svelte-1pfl9w0"),s(gn,"class","hint svelte-1pfl9w0"),s(Ht,"class","setting-label svelte-1pfl9w0"),s(Ht,"for","cfg-dns"),s(et,"id","cfg-dns"),s(et,"type","text"),s(et,"placeholder","system default"),s(et,"class","svelte-1pfl9w0"),s(Et,"class","setting-row svelte-1pfl9w0"),s(bn,"class","hint svelte-1pfl9w0"),s(Xt,"class","setting-label svelte-1pfl9w0"),s(Xt,"for","cfg-socks"),s(He,"id","cfg-socks"),s(He,"type","text"),s(He,"placeholder",Sn=t[7].socks5_placeholder),s(He,"class","svelte-1pfl9w0"),s(At,"class","setting-row svelte-1pfl9w0"),s(En,"class","hint reconnect-hint svelte-1pfl9w0"),s(Qt,"class","setting-label svelte-1pfl9w0"),s(Qt,"for","cfg-stun"),s(tt,"id","cfg-stun"),s(tt,"type","text"),s(tt,"placeholder","stun.l.google.com:19302"),s(tt,"class","svelte-1pfl9w0"),s(Pt,"class","setting-row svelte-1pfl9w0"),s(Cn,"class","hint reconnect-hint svelte-1pfl9w0"),s(re,"class","section svelte-1pfl9w0"),s(Ct,"class","section-title svelte-1pfl9w0"),s(Ln,"class","setting-label svelte-1pfl9w0"),s(pt,"type","checkbox"),s(pt,"class","svelte-1pfl9w0"),s(Nt,"class","setting-row toggle-row svelte-1pfl9w0"),s(Rn,"class","setting-label svelte-1pfl9w0"),s(ct,"class","btn btn-check svelte-1pfl9w0"),s(ct,"type","button"),ct.disabled=t[3],s(ot,"class","setting-row update-row svelte-1pfl9w0"),s(Xe,"class","section svelte-1pfl9w0"),s(Dt,"class","section-title svelte-1pfl9w0"),s(Zt,"class","setting-label svelte-1pfl9w0"),s(Zt,"for","cfg-scale"),s(Qe,"id","cfg-scale"),s(Qe,"type","range"),s(Qe,"min","75"),s(Qe,"max","150"),s(Qe,"step","5"),Qe.value=Un=t[0].uiScale??100,s(Qe,"class","svelte-1pfl9w0"),s($t,"class","scale-value svelte-1pfl9w0"),s(ut,"class","setting-row scale-row svelte-1pfl9w0"),s(Wn,"class","hint svelte-1pfl9w0"),s(Kn,"class","setting-label svelte-1pfl9w0"),s(qe,"type","radio"),qe.__value="dark",ie(qe,qe.__value),s(It,"class","radio-option svelte-1pfl9w0"),s(Ue,"type","radio"),Ue.__value="light",ie(Ue,Ue.__value),s(Rt,"class","radio-option svelte-1pfl9w0"),s(at,"class","radio-group svelte-1pfl9w0"),s(at,"role","radiogroup"),s(at,"aria-label",Bn=t[7].theme),s(Lt,"class","setting-row radio-row svelte-1pfl9w0"),s(xt,"class","setting-label svelte-1pfl9w0"),s(xt,"for","cfg-lang"),Ot.__value="en",ie(Ot,Ot.__value),Mt.__value="ru",ie(Mt,Mt.__value),qt.__value="zh",ie(qt,qt.__value),s(nt,"id","cfg-lang"),s(nt,"class","svelte-1pfl9w0"),s(Tt,"class","setting-row svelte-1pfl9w0"),s(Ve,"class","section svelte-1pfl9w0"),s(en,"class","btn btn-save svelte-1pfl9w0"),s(tn,"class","btn btn-reset svelte-1pfl9w0"),s(nn,"class","ver svelte-1pfl9w0"),s(_t,"class","section actions-section svelte-1pfl9w0"),s(r,"class","settings-content svelte-1pfl9w0"),s(e,"class","settings-view svelte-1pfl9w0"),Ol.p(qe,Ue)},m(T,G){K(T,e,G),l(e,n),l(n,o),l(e,a),l(e,r),Te&&Te.m(r,null),l(r,_),l(r,d),l(d,u),l(u,v),l(u,m),l(u,j),l(d,w),l(d,A),l(A,p),l(p,D),l(A,P),l(A,k),ie(k,t[0].serverAddr),l(d,N),l(d,y),l(y,I),l(I,B),l(y,S),l(y,E),ie(E,t[0].nickname),l(d,M),l(d,L),l(L,q),l(q,Q),l(L,ce),l(L,O),ie(O,t[0].serverToken),l(d,U),l(d,z),l(z,oe),l(d,Z),l(d,H),l(H,pe),l(pe,Ie),l(H,Ne),l(H,fe),fe.checked=t[0].autoConnect,l(H,ye),l(H,ge),l(ge,De),l(d,me),l(d,le),l(le,We),l(We,he),l(le,be),l(le,X),X.checked=t[0].autoJoinLastRoom,l(le,se),l(le,st),l(st,rt),l(r,it),l(r,re),l(re,Ae),l(Ae,R),l(Ae,Se),l(Ae,Re),l(re,we),l(re,Ee),l(Ee,bt),l(re,Pe),l(re,$),l($,ae),l(ae,il),l($,xl),l($,xe),l(xe,yt),l(yt,ol),l(xe,jt),l(jt,al),xn(xe,t[0].connectionMode,!0),l(re,es),l(re,vn),l(vn,rl),l(re,ts),l(re,St),l(St,Yt),l(Yt,cl),l(St,ns),l(St,Ge),ie(Ge,t[0].mtu),l(re,ls),l(re,gn),l(gn,ul),l(re,ss),l(re,Et),l(Et,Ht),l(Ht,_l),l(Et,is),l(Et,et),ie(et,t[0].dnsServer),l(re,os),l(re,bn),l(bn,fl),l(re,as),l(re,At),l(At,Xt),l(Xt,dl),l(At,rs),l(At,He),ie(He,t[0].socks5Proxy),l(re,cs),l(re,En),l(En,pl),l(re,us),l(re,Pt),l(Pt,Qt),l(Qt,vl),l(Pt,_s),l(Pt,tt),ie(tt,t[0].stunServer),l(re,fs),l(re,Cn),l(Cn,ml),l(r,ds),l(r,Xe),l(Xe,Ct),l(Ct,ps),l(Ct,hl),l(Ct,vs),l(Xe,ms),l(Xe,Nt),l(Nt,Ln),l(Ln,gl),l(Nt,hs),l(Nt,pt),pt.checked=t[0].startWithWindows,l(Xe,gs),l(Xe,ot),l(ot,Rn),l(Rn,wl),l(ot,ws),l(ot,ct),l(ct,kl),l(ot,ks),Oe&&Oe.m(ot,null),l(Xe,bs),Me&&Me.m(Xe,null),l(r,ys),l(r,Ve),l(Ve,Dt),l(Dt,js),l(Dt,bl),l(Dt,Ss),l(Ve,Es),l(Ve,ut),l(ut,Zt),l(Zt,yl),l(ut,As),l(ut,Qe),l(ut,Ps),l(ut,$t),l($t,jl),l($t,Cs),l(Ve,Ns),l(Ve,Wn),l(Wn,Sl),l(Ve,Ds),l(Ve,Lt),l(Lt,Kn),l(Kn,El),l(Lt,Ls),l(Lt,at),l(at,It),l(It,qe),qe.checked=qe.__value===t[0].theme,l(It,Is),l(It,Al),l(at,Rs),l(at,Rt),l(Rt,Ue),Ue.checked=Ue.__value===t[0].theme,l(Rt,Ts),l(Rt,Pl),l(Ve,Os),l(Ve,Tt),l(Tt,xt),l(xt,Cl),l(Tt,Ms),l(Tt,nt),l(nt,Ot),l(Ot,Nl),l(nt,Mt),l(Mt,Dl),l(nt,qt),l(qt,Ll),xn(nt,t[0].lang||t[8]),l(r,Us),l(r,_t),l(_t,en),l(en,Il),l(_t,zs),l(_t,tn),l(tn,Rl),l(_t,Ws),l(_t,nn),l(nn,Fs),l(nn,Tl),Ml||(Ks=[W(k,"input",t[16]),W(E,"input",t[17]),W(O,"input",t[18]),W(fe,"change",t[19]),W(X,"change",t[20]),W(xe,"change",t[21]),W(Ge,"input",t[22]),W(et,"input",t[23]),W(He,"input",t[24]),W(tt,"input",t[25]),W(pt,"change",t[26]),W(ct,"click",t[9]),W(Qe,"input",t[13]),W(qe,"change",t[27]),W(qe,"change",t[15]),W(Ue,"change",t[29]),W(Ue,"change",t[15]),W(nt,"change",t[14]),W(en,"click",t[11]),W(tn,"click",t[12])],Ml=!0)},p(T,[G]){G&128&&i!==(i=T[7].settings_title+"")&&b(o,i),T[2]?Te?Te.p(T,G):(Te=Ci(T),Te.c(),Te.m(r,_)):Te&&(Te.d(1),Te=null),G&128&&f!==(f=T[7].section_connection+"")&&b(m,f),G&128&&C!==(C=T[7].server_addr+"")&&b(D,C),G&1&&k.value!==T[0].serverAddr&&ie(k,T[0].serverAddr),G&128&&J!==(J=T[7].nickname+"")&&b(B,J),G&1&&E.value!==T[0].nickname&&ie(E,T[0].nickname),G&128&&V!==(V=T[7].server_token+"")&&b(Q,V),G&128&&Y!==(Y=T[7].server_token_desc)&&s(O,"placeholder",Y),G&1&&O.value!==T[0].serverToken&&ie(O,T[0].serverToken),G&128&&te!==(te=T[7].reconnect_apply+"")&&b(oe,te),G&128&&ue!==(ue=T[7].auto_connect+"")&&b(Ie,ue),G&1&&(fe.checked=T[0].autoConnect),G&128&&je!==(je=T[7].auto_connect_desc+"")&&b(De,je),G&128&&_e!==(_e=T[7].auto_join+"")&&b(he,_e),G&1&&(X.checked=T[0].autoJoinLastRoom),G&128&&Fe!==(Fe=T[7].auto_join_desc+"")&&b(rt,Fe),G&128&&x!==(x=T[7].section_network+"")&&b(Se,x),G&128&&Ke!==(Ke=T[7].advanced_warn+"")&&b(bt,Ke),G&128&&Je!==(Je=T[7].connection_mode+"")&&b(il,Je),G&128&&dn!==(dn=T[7].connection_direct+"")&&b(ol,dn),G&128&&pn!==(pn=T[7].connection_relay+"")&&b(al,pn),G&1&&xn(xe,T[0].connectionMode),G&128&&mn!==(mn=T[7].connection_mode_desc+"")&&b(rl,mn),G&128&&hn!==(hn=T[7].mtu+"")&&b(cl,hn),G&1&&Oi(Ge.value)!==T[0].mtu&&ie(Ge,T[0].mtu),G&128&&wn!==(wn=T[7].mtu_desc+"")&&b(ul,wn),G&128&&kn!==(kn=T[7].dns_server+"")&&b(_l,kn),G&1&&et.value!==T[0].dnsServer&&ie(et,T[0].dnsServer),G&128&&yn!==(yn=T[7].dns_desc+"")&&b(fl,yn),G&128&&jn!==(jn=T[7].socks5+"")&&b(dl,jn),G&128&&Sn!==(Sn=T[7].socks5_placeholder)&&s(He,"placeholder",Sn),G&1&&He.value!==T[0].socks5Proxy&&ie(He,T[0].socks5Proxy),G&128&&An!==(An=T[7].socks5_desc+"")&&b(pl,An),G&128&&Pn!==(Pn=T[7].stun_server+"")&&b(vl,Pn),G&1&&tt.value!==T[0].stunServer&&ie(tt,T[0].stunServer),G&128&&Nn!==(Nn=T[7].stun_desc+"")&&b(ml,Nn),G&128&&Dn!==(Dn=T[7].section_system+"")&&b(hl,Dn),G&128&&In!==(In=T[7].start_windows+"")&&b(gl,In),G&1&&(pt.checked=T[0].startWithWindows),G&128&&Tn!==(Tn=T[7].updates+"")&&b(wl,Tn),G&128&&On!==(On=T[7].check_updates+"")&&b(kl,On),G&8&&(ct.disabled=T[3]),T[4]==="available"?Oe?Oe.p(T,G):(Oe=Ni(T),Oe.c(),Oe.m(ot,null)):Oe&&(Oe.d(1),Oe=null),Ut===(Ut=Js(T))&&Me?Me.p(T,G):(Me&&Me.d(1),Me=Ut&&Ut(T),Me&&(Me.c(),Me.m(Xe,null))),G&128&&Mn!==(Mn=T[7].section_appearance+"")&&b(bl,Mn),G&128&&qn!==(qn=T[7].ui_scale+"")&&b(yl,qn),G&1&&Un!==(Un=T[0].uiScale??100)&&(Qe.value=Un),G&1&&zn!==(zn=(T[0].uiScale??100)+"")&&b(jl,zn),G&128&&Fn!==(Fn=T[7].ui_scale_desc+"")&&b(Sl,Fn),G&128&&Jn!==(Jn=T[7].theme+"")&&b(El,Jn),G&1&&(qe.checked=qe.__value===T[0].theme),G&128&&Gn!==(Gn=T[7].theme_dark+"")&&b(Al,Gn),G&1&&(Ue.checked=Ue.__value===T[0].theme),G&128&&Vn!==(Vn=T[7].theme_light+"")&&b(Pl,Vn),G&128&&Bn!==(Bn=T[7].theme)&&s(at,"aria-label",Bn),G&128&&Yn!==(Yn=T[7].language+"")&&b(Cl,Yn),G&128&&Hn!==(Hn=T[7].language_en+"")&&b(Nl,Hn),G&128&&Xn!==(Xn=T[7].language_ru+"")&&b(Dl,Xn),G&128&&Qn!==(Qn=T[7].language_zh+"")&&b(Ll,Qn),G&257&&qs!==(qs=T[0].lang||T[8])&&xn(nt,T[0].lang||T[8]),G&128&&Zn!==(Zn=T[7].save+"")&&b(Il,Zn),G&128&&$n!==($n=T[7].reset+"")&&b(Rl,$n),G&2&&b(Tl,T[1])},i:de,o:de,d(T){T&&F(e),Te&&Te.d(),Oe&&Oe.d(),Me&&Me.d(),Ol.r(),Ml=!1,Le(Ks)}}}function Jo(t,e,n){let i,o,a;ve(t,Be,O=>n(30,i=O)),ve(t,kt,O=>n(7,o=O)),ve(t,$l,O=>n(8,a=O));let r={...i},_="1.0.0",d=!1,u=!1,v="",f="",m="";async function j(){n(3,u=!0),n(4,v="checking"),n(6,m=""),n(5,f="");try{const O=await window.go.main.App.CheckForUpdate();O?.available?(n(4,v="available"),n(5,f=O.latest||"")):n(4,v="latest")}catch(O){n(4,v="error"),n(6,m=String(O)),ee(o.error_update_check+O,"error")}finally{n(3,u=!1)}}async function w(){if(confirm(o.confirm_update)){n(3,u=!0),n(4,v="downloading"),n(6,m="");try{await window.go.main.App.ApplyUpdate(),ee(o.notif_updating,"info")}catch(O){n(4,v="error"),n(6,m=String(O)),n(3,u=!1),ee(o.error_update+O,"error")}}}async function A(){Ze(Be,i={...r},i);try{n(2,d=!!await window.go.main.App.SaveSettings(r)),r.lang&&sn(r.lang),ee(o.notif_settings_saved,"info"),d&&ee(o.notif_reconnect_required,"info")}catch(O){ee(o.error_save+O,"error")}}async function p(){if(confirm(o.confirm_reset))try{n(0,r=await window.go.main.App.ResetSettings()),Ze(Be,i={...r},i),n(2,d=!1),r.lang&&sn(r.lang),ee(o.notif_settings_saved,"info")}catch(O){ee(o.error_save+O,"error")}}function C(O){const Y=Math.min(150,Math.max(75,Number(O.target.value)||100));n(0,r.uiScale=Y,r),Ze(Be,i={...i,uiScale:Y},i)}function D(O){n(0,r.lang=O.target.value,r),sn(O.target.value)}function P(){Ze(Be,i={...i,theme:r.theme},i)}fn(async()=>{try{const O=await window.go.main.App.GetSettings();O&&(n(0,r={...r,...O}),r.connectionMode||n(0,r.connectionMode="direct",r),Ze(Be,i=r,i),r.lang&&sn(r.lang)),window.go.main.App.GetVersion&&n(1,_=await window.go.main.App.GetVersion())}catch{}});const k=[[]];function N(){r.serverAddr=this.value,n(0,r)}function y(){r.nickname=this.value,n(0,r)}function I(){r.serverToken=this.value,n(0,r)}function J(){r.autoConnect=this.checked,n(0,r)}function B(){r.autoJoinLastRoom=this.checked,n(0,r)}function S(){r.connectionMode=Ji(this),n(0,r)}function E(){r.mtu=Oi(this.value),n(0,r)}function M(){r.dnsServer=this.value,n(0,r)}function L(){r.socks5Proxy=this.value,n(0,r)}function q(){r.stunServer=this.value,n(0,r)}function V(){r.startWithWindows=this.checked,n(0,r)}function Q(){r.theme=this.__value,n(0,r)}function ce(){r.theme=this.__value,n(0,r)}return[r,_,d,u,v,f,m,o,a,j,w,A,p,C,D,P,N,y,I,J,B,S,E,M,L,q,V,Q,k,ce]}class Go extends wt{constructor(e){super(),gt(this,e,Jo,Ko,dt,{})}}function Di(t,e,n){const i=t.slice();return i[13]=e[n],i}function Vo(t){let e,n,i,o,a,r,_,d,u,v,f,m,j,w,A,p;o=new vo({});const C=[Qo,Xo,Ho,Yo],D=[];function P(k,N){return k[3]==="network"?0:k[3]==="chat"?1:k[3]==="settings"?2:3}return v=P(t),f=D[v]=C[v](t),j=new So({}),{c(){e=c("div"),n=c("div"),i=c("div"),Bt(o.$$.fragment),a=h(),r=c("div"),_=h(),d=c("main"),u=c("div"),f.c(),m=h(),Bt(j.$$.fragment),s(r,"class","drag-handle svelte-1hi7jen"),ke(r,"active",t[1]),s(i,"class","sidebar-wrapper svelte-1hi7jen"),Vs(i,"width",t[0]+"px"),s(u,"class","view-fade svelte-1hi7jen"),s(u,"key",t[3]),s(d,"class","main-area svelte-1hi7jen"),s(n,"class","layout svelte-1hi7jen"),s(e,"class","shell svelte-1hi7jen")},m(k,N){K(k,e,N),l(e,n),l(n,i),mt(o,i,null),l(i,a),l(i,r),l(n,_),l(n,d),l(d,u),D[v].m(u,null),l(e,m),mt(j,e,null),w=!0,A||(p=W(r,"mousedown",t[6]),A=!0)},p(k,N){(!w||N&2)&&ke(r,"active",k[1]),(!w||N&1)&&Vs(i,"width",k[0]+"px");let y=v;v=P(k),v===y?D[v].p(k,N):(Ui(),lt(D[y],1,1,()=>{D[y]=null}),zi(),f=D[v],f?f.p(k,N):(f=D[v]=C[v](k),f.c()),Ye(f,1),f.m(u,null)),(!w||N&8)&&s(u,"key",k[3])},i(k){w||(Ye(o.$$.fragment,k),Ye(f),Ye(j.$$.fragment,k),w=!0)},o(k){lt(o.$$.fragment,k),lt(f),lt(j.$$.fragment,k),w=!1},d(k){k&&F(e),ht(o),D[v].d(),ht(j),A=!1,p()}}}function Bo(t){let e,n,i,o;return i=new Lo({}),{c(){e=c("div"),n=c("div"),Bt(i.$$.fragment),s(n,"class","fullscreen-connect svelte-1hi7jen"),s(e,"class","shell connect-shell svelte-1hi7jen")},m(a,r){K(a,e,r),l(e,n),mt(i,n,null),o=!0},p:de,i(a){o||(Ye(i.$$.fragment,a),o=!0)},o(a){lt(i.$$.fragment,a),o=!1},d(a){a&&F(e),ht(i)}}}function Yo(t){let e,n,i;return{c(){e=c("div"),n=g("Unknown view: "),i=g(t[3]),s(e,"class","unknown-view svelte-1hi7jen")},m(o,a){K(o,e,a),l(e,n),l(e,i)},p(o,a){a&8&&b(i,o[3])},i:de,o:de,d(o){o&&F(e)}}}function Ho(t){let e,n;return e=new Go({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Xo(t){let e,n;return e=new Mo({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Qo(t){let e,n;return e=new bo({}),{c(){Bt(e.$$.fragment)},m(i,o){mt(e,i,o),n=!0},p:de,i(i){n||(Ye(e.$$.fragment,i),n=!0)},o(i){lt(e.$$.fragment,i),n=!1},d(i){ht(e,i)}}}function Li(t){let e,n,i=t[4].msg+"",o,a,r,_=t[2].dismiss_error+"",d,u,v,f;return{c(){e=c("div"),n=c("span"),o=g(i),a=h(),r=c("button"),d=g(_),s(n,"class","error-strip-msg svelte-1hi7jen"),s(r,"type","button"),s(r,"class","error-strip-dismiss svelte-1hi7jen"),s(r,"aria-label",u=t[2].dismiss_error),s(e,"class","error-strip svelte-1hi7jen"),s(e,"role","alert")},m(m,j){K(m,e,j),l(e,n),l(n,o),l(e,a),l(e,r),l(r,d),v||(f=W(r,"click",un),v=!0)},p(m,j){j&16&&i!==(i=m[4].msg+"")&&b(o,i),j&4&&_!==(_=m[2].dismiss_error+"")&&b(d,_),j&4&&u!==(u=m[2].dismiss_error)&&s(r,"aria-label",u)},d(m){m&&F(e),v=!1,f()}}}function Ii(t,e){let n,i,o=e[13].type==="error"?"!":">",a,r,_=e[13].msg+"",d,u,v;return{key:t,first:null,c(){n=c("div"),i=c("span"),a=g(o),r=h(),d=g(_),u=h(),s(i,"class","notif-icon svelte-1hi7jen"),s(n,"class",v="notification "+e[13].type+" svelte-1hi7jen"),s(n,"role","status"),this.first=n},m(f,m){K(f,n,m),l(n,i),l(i,a),l(n,r),l(n,d),l(n,u)},p(f,m){e=f,m&32&&o!==(o=e[13].type==="error"?"!":">")&&b(a,o),m&32&&_!==(_=e[13].msg+"")&&b(d,_),m&32&&v!==(v="notification "+e[13].type+" svelte-1hi7jen")&&s(n,"class",v)},d(f){f&&F(n)}}}function Zo(t){let e,n,i,o,a,r,_,d,u=[],v=new Map,f,m;const j=[Bo,Vo],w=[];function A(P,k){return P[3]==="connect"?0:1}a=A(t),r=w[a]=j[a](t);let p=t[4]&&Li(t),C=ft(t[5]);const D=P=>P[13].id;for(let P=0;P{w[N]=null}),zi(),r=w[a],r?r.p(P,k):(r=w[a]=j[a](P),r.c()),Ye(r,1),r.m(_.parentNode,_)),P[4]?p?p.p(P,k):(p=Li(P),p.c(),p.m(d.parentNode,d)):p&&(p.d(1),p=null),k&32&&(C=ft(P[5]),u=sl(u,k,D,1,P,C,v,f.parentNode,ll,Ii,f,Di))},i(P){m||(Ye(r),m=!0)},o(P){lt(r),m=!1},d(P){P&&(F(e),F(n),F(i),F(o),F(_),F(d),F(f)),w[a].d(P),p&&p.d(P);for(let k=0;kn(2,i=p)),ve(t,Be,p=>n(7,o=p)),ve(t,Ce,p=>n(3,a=p)),ve(t,nl,p=>n(4,r=p)),ve(t,Wl,p=>n(5,_=p));let d=220,u=!1,v,f,m=!0;function j(p){n(1,u=!0),v=p.clientX,f=d,document.addEventListener("mousemove",w),document.addEventListener("mouseup",A),p.preventDefault()}function w(p){if(!u)return;const C=f+(p.clientX-v);n(0,d=Math.max(140,Math.min(400,C)))}function A(){n(1,u=!1),document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",A)}return fn(async()=>{window.addEventListener("keydown",Ri);try{const p=await window.go.main.App.LoadConfig();p&&(Be.set({...o,...p}),p.lang&&sn(p.lang))}catch{}window.runtime?.EventsOn&&(window.runtime.EventsOn("status_changed",p=>{m&&(ze.set(p),!p.connected&&!p.reconnecting&&Ce.set("connect"))}),window.runtime.EventsOn("peers_changed",p=>{m&&Yl.set(p||[])}),window.runtime.EventsOn("error",p=>{m&&ee(p,"error")}),window.runtime.EventsOn("chat_message",p=>{m&&Ql(p.fromID,p.nickname,p.message,!1,"sent",!1,!!p.isDM)}),window.runtime.EventsOn("system_chat",p=>{m&&lo(p.message||"")}),window.runtime.EventsOn("room_deleted",p=>{m&&(ee(i.notif_room_deleted,"error"),Ce.set("network"))}),window.runtime.EventsOn("auto_join_skipped",p=>{if(!m)return;const C=p?.room||"";ee(ne(i.notif_auto_join_skipped,{name:C}),"info")}))}),Mi(()=>{m=!1,window.removeEventListener("keydown",Ri),document.removeEventListener("mousemove",w),document.removeEventListener("mouseup",A),window.runtime?.EventsOff&&(window.runtime.EventsOff("status_changed"),window.runtime.EventsOff("peers_changed"),window.runtime.EventsOff("error"),window.runtime.EventsOff("chat_message"),window.runtime.EventsOff("system_chat"),window.runtime.EventsOff("room_deleted"),window.runtime.EventsOff("auto_join_skipped"))}),t.$$.update=()=>{if(t.$$.dirty&128){const p=$o(o.uiScale)/100;document.documentElement.style.zoom=String(p)}t.$$.dirty&128&&(o.theme==="light"?document.documentElement.classList.add("light-theme"):document.documentElement.classList.remove("light-theme"))},[d,u,i,a,r,_,j,o]}class ea extends wt{constructor(e){super(),gt(this,e,xo,Zo,dt,{})}}new ea({target:document.getElementById("app")}); diff --git a/client/frontend/dist/assets/index-C-aPttjH.css b/client/frontend/dist/assets/index-C-aPttjH.css new file mode 100644 index 0000000..2463c61 --- /dev/null +++ b/client/frontend/dist/assets/index-C-aPttjH.css @@ -0,0 +1 @@ +.sidebar.svelte-4t8g6m.svelte-4t8g6m{width:100%;height:100%;background:var(--bg-surface);display:flex;flex-direction:column;flex-shrink:0}.sidebar-header.svelte-4t8g6m.svelte-4t8g6m{padding:12px;border-bottom:1px solid var(--border)}.sidebar-header.svelte-4t8g6m h2.svelte-4t8g6m{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim);font-weight:600}.sidebar-meta.svelte-4t8g6m.svelte-4t8g6m{font-size:var(--font-size-xs);color:var(--text-muted);margin-top:4px}.sidebar-actions.svelte-4t8g6m.svelte-4t8g6m{padding:8px;display:flex;flex-direction:column;gap:6px;border-bottom:1px solid var(--border)}.sidebar-actions.svelte-4t8g6m .btn.svelte-4t8g6m{min-height:32px;padding:6px 12px}.network-list.svelte-4t8g6m.svelte-4t8g6m{flex:1;overflow-y:auto;overflow-x:hidden;padding:4px 0}.network-item.svelte-4t8g6m.svelte-4t8g6m{display:flex;align-items:center;padding:10px 12px;min-height:40px;cursor:pointer;gap:8px;border-bottom:1px solid var(--border-deep);transition:background .12s ease,opacity .12s ease;position:relative}.network-item.svelte-4t8g6m.svelte-4t8g6m:hover,.network-item.svelte-4t8g6m.svelte-4t8g6m:focus-visible{background:var(--bg-hover)}.network-item.active.svelte-4t8g6m.svelte-4t8g6m{background:var(--bg-active)}.network-item.disabled.svelte-4t8g6m.svelte-4t8g6m{opacity:.55}.network-indicator.svelte-4t8g6m.svelte-4t8g6m{width:8px;height:8px;border-radius:50%;background:var(--text-dim);flex-shrink:0}.network-indicator.active-dot.svelte-4t8g6m.svelte-4t8g6m{background:var(--text-bright)}.network-info.svelte-4t8g6m.svelte-4t8g6m{flex:1;min-width:0}.network-name.svelte-4t8g6m.svelte-4t8g6m{font-size:var(--font-size);color:var(--text-bright);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.network-meta.svelte-4t8g6m.svelte-4t8g6m{font-size:var(--font-size-xs);color:var(--text-secondary);line-height:1.4}.row-actions.svelte-4t8g6m.svelte-4t8g6m{position:relative;flex-shrink:0}.menu-btn.svelte-4t8g6m.svelte-4t8g6m{background:none;border:1px solid transparent;border-radius:var(--radius-sm, 4px);color:var(--text-muted);cursor:pointer;width:32px;height:32px;display:flex;align-items:center;justify-content:center}.menu-btn.svelte-4t8g6m.svelte-4t8g6m:hover,.menu-btn[aria-expanded=true].svelte-4t8g6m.svelte-4t8g6m{color:var(--text-bright);border-color:var(--border);background:var(--bg-raised)}.overflow-menu.svelte-4t8g6m.svelte-4t8g6m{position:absolute;right:0;top:100%;z-index:20;min-width:160px;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md, 6px);display:flex;flex-direction:column;box-shadow:0 4px 12px #00000059}.menu-item.svelte-4t8g6m.svelte-4t8g6m{background:none;border:none;text-align:left;padding:10px 12px;min-height:36px;color:var(--text-primary);font-family:inherit;font-size:var(--font-size-sm);cursor:pointer}.menu-item.svelte-4t8g6m.svelte-4t8g6m:hover{background:var(--bg-hover);color:var(--text-bright)}.menu-item.danger.svelte-4t8g6m.svelte-4t8g6m{color:var(--fault, var(--error))}.menu-item.danger.svelte-4t8g6m.svelte-4t8g6m:hover{background:#e23d3d1a}.empty-desc.svelte-4t8g6m.svelte-4t8g6m{margin-top:6px;font-size:var(--font-size-xs);color:var(--text-dim)}.empty-state.svelte-4t8g6m.svelte-4t8g6m{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)}.modal-overlay.svelte-4t8g6m.svelte-4t8g6m{position:fixed;inset:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:100;animation:svelte-4t8g6m-fadeIn .12s ease-out}@keyframes svelte-4t8g6m-fadeIn{0%{opacity:0}to{opacity:1}}.modal.svelte-4t8g6m.svelte-4t8g6m{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md, 6px);padding:20px;width:320px;max-height:80vh;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.modal.svelte-4t8g6m h3.svelte-4t8g6m{font-size:var(--font-size);color:var(--text-bright);font-weight:600;text-transform:uppercase;letter-spacing:.08em;font-size:10px}.modal.svelte-4t8g6m input.svelte-4t8g6m{padding:10px;min-height:36px;border:1px solid var(--border);border-radius:var(--radius-sm, 4px);background:var(--bg-primary);color:var(--text-primary);font-size:var(--font-size);font-family:var(--font-mono)}.modal.svelte-4t8g6m input.invalid.svelte-4t8g6m{border-color:var(--error)}.field-error.svelte-4t8g6m.svelte-4t8g6m,.modal-error.svelte-4t8g6m.svelte-4t8g6m{font-size:var(--font-size-xs);color:var(--error)}.modal-error.svelte-4t8g6m.svelte-4t8g6m{padding:8px;border:1px solid var(--error);background:#c45c5c14}.modal-actions.svelte-4t8g6m.svelte-4t8g6m{display:flex;gap:6px;justify-content:flex-end}.modal-actions.svelte-4t8g6m .btn.svelte-4t8g6m{min-height:32px;padding:6px 12px}.sr-only.svelte-4t8g6m.svelte-4t8g6m{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.peer-view.svelte-s8897d.svelte-s8897d{display:flex;flex-direction:column;height:100%}.peer-header.svelte-s8897d.svelte-s8897d{padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;background:var(--bg-surface);flex-wrap:wrap}.peer-header.svelte-s8897d h2.svelte-s8897d{font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em}.room-chat-btn.svelte-s8897d.svelte-s8897d{margin-left:auto;background:transparent;border:1px solid var(--border);border-radius:var(--radius-md, 6px);color:var(--text-secondary);font-family:inherit;font-size:var(--font-size-xs);padding:6px 10px;min-height:32px;cursor:pointer;position:relative}.room-chat-btn.svelte-s8897d.svelte-s8897d:hover{color:var(--text-bright);border-color:var(--border-hover)}.badge.svelte-s8897d.svelte-s8897d{display:inline-block;min-width:14px;padding:0 4px;margin-left:4px;background:var(--fault, var(--error));color:#fff;font-size:10px;line-height:14px;text-align:center}.peer-table.svelte-s8897d.svelte-s8897d{flex:1;overflow:auto;min-height:0;min-width:0}.table-row.svelte-s8897d.svelte-s8897d{display:grid;grid-template-columns:minmax(56px,72px) minmax(72px,1fr) minmax(88px,110px) minmax(48px,70px) minmax(72px,96px) minmax(64px,80px);gap:8px;align-items:center;padding:10px 16px;min-height:40px;border-bottom:1px solid var(--border-deep);font-size:var(--font-size-sm);min-width:520px;transition:background var(--dur-fast, .12s) ease}.table-row.svelte-s8897d.svelte-s8897d:not(.table-header-row):hover{background:var(--bg-hover)}.table-header-row.svelte-s8897d.svelte-s8897d{color:var(--text-muted);text-transform:uppercase;font-size:var(--font-size-xs);letter-spacing:.08em}.self-row.svelte-s8897d.svelte-s8897d{background:var(--bg-surface)}.nickname.svelte-s8897d.svelte-s8897d{color:var(--text-bright);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.self-tag.svelte-s8897d.svelte-s8897d{margin-left:6px;font-size:var(--font-size-xs);color:var(--text-muted)}.col-ip.svelte-s8897d.svelte-s8897d,.col-ping.svelte-s8897d.svelte-s8897d,.col-path.svelte-s8897d.svelte-s8897d{font-family:var(--font-mono);color:var(--text-secondary)}.col-path.svelte-s8897d.svelte-s8897d{display:flex;align-items:center;gap:6px}.col-ping.probing.svelte-s8897d.svelte-s8897d{color:var(--text-bright)}.clickable.svelte-s8897d.svelte-s8897d{cursor:pointer}.clickable.svelte-s8897d.svelte-s8897d:hover{color:var(--text-bright)}.status-cell.svelte-s8897d.svelte-s8897d{display:flex;align-items:center;gap:6px}.status-text.svelte-s8897d.svelte-s8897d{font-size:var(--font-size-xs);color:var(--text-secondary)}.sq.svelte-s8897d.svelte-s8897d{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0}.sq-online.svelte-s8897d.svelte-s8897d{background:var(--text-bright)}.sq-offline.svelte-s8897d.svelte-s8897d{background:var(--text-dim)}.col-action.svelte-s8897d.svelte-s8897d{display:flex;gap:2px;justify-content:flex-end}.row-btn.svelte-s8897d.svelte-s8897d{background:transparent;border:none;border-radius:var(--radius-sm, 4px);color:var(--text-muted);cursor:pointer;min-width:32px;min-height:32px;padding:0;display:flex;align-items:center;justify-content:center}.row-btn.svelte-s8897d.svelte-s8897d:hover:not(:disabled){color:var(--text-bright)}.row-btn.svelte-s8897d.svelte-s8897d:disabled{opacity:.35;cursor:not-allowed}.empty-peers.svelte-s8897d.svelte-s8897d{padding:48px 24px;text-align:center;color:var(--text-muted)}.empty-label.svelte-s8897d.svelte-s8897d{color:var(--text-secondary);margin:8px 0 4px}.empty-desc.svelte-s8897d.svelte-s8897d{font-size:var(--font-size-xs)}.statusbar.svelte-3s78ew{min-height:var(--statusbar-height);background:var(--bg-deep);border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:4px 12px;font-size:var(--font-size-xs);color:var(--text-secondary);flex-shrink:0;font-family:var(--font-mono);z-index:1;position:relative;min-width:0}.status-left.svelte-3s78ew,.status-right.svelte-3s78ew{display:flex;align-items:center;gap:8px 14px;min-width:0}.status-right.svelte-3s78ew{flex:1 1 auto;justify-content:flex-end}.status-item.svelte-3s78ew{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:36ch}.status-server.svelte-3s78ew{max-width:28ch}.status-ver.svelte-3s78ew{flex-shrink:0;max-width:none}.hint-fault.svelte-3s78ew{color:var(--fault, var(--error))}.connect-view.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:32px 24px}.connect-form.svelte-1br9j49.svelte-1br9j49,.connected-info.svelte-1br9j49.svelte-1br9j49{width:min(360px,100%);display:flex;flex-direction:column;gap:16px;animation:svelte-1br9j49-connectIn .45s cubic-bezier(.16,1,.3,1) both}@keyframes svelte-1br9j49-connectIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.brand-block.svelte-1br9j49.svelte-1br9j49{text-align:center;margin-bottom:12px}.brand.svelte-1br9j49.svelte-1br9j49{font-family:var(--font-display);font-size:clamp(36px,7vw,48px);font-weight:400;letter-spacing:.02em;text-transform:uppercase;color:var(--text-bright);line-height:1.05}.tagline.svelte-1br9j49.svelte-1br9j49{margin-top:10px;font-size:var(--font-size-sm);color:var(--text-secondary);text-transform:none;letter-spacing:.02em;line-height:1.45}.field.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:7px}label.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-secondary);text-transform:uppercase;letter-spacing:.08em}input.svelte-1br9j49.svelte-1br9j49{background:#111111d9;border:1px solid var(--border-light);color:var(--text-bright);padding:13px 14px;min-height:44px;font-family:var(--font-mono);font-size:var(--font-size);transition:border-color .15s ease,background .15s ease}input.svelte-1br9j49.svelte-1br9j49::placeholder{color:var(--text-dim)}input.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--border-hover)}input.svelte-1br9j49.svelte-1br9j49:focus{outline:none;border-color:var(--text-bright);background:#141414f2}input.invalid.svelte-1br9j49.svelte-1br9j49{border-color:var(--error)}.field-error.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--error)}.connect-btn.svelte-1br9j49.svelte-1br9j49,.disconnect-btn.svelte-1br9j49.svelte-1br9j49,.secondary-btn.svelte-1br9j49.svelte-1br9j49{border:none;padding:15px 18px;min-height:48px;font-family:var(--font-mono);font-size:var(--font-size);cursor:pointer;text-transform:uppercase;letter-spacing:.12em;font-weight:600;transition:background .15s ease,border-color .15s ease,transform .12s ease}.connect-btn.svelte-1br9j49.svelte-1br9j49{margin-top:4px;background:var(--accent);color:var(--accent-ink)}.connect-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){background:var(--accent-hover);transform:translateY(-1px)}.connect-btn.svelte-1br9j49.svelte-1br9j49:active:not(:disabled){transform:translateY(0)}.connect-btn.svelte-1br9j49.svelte-1br9j49:disabled{opacity:.45;cursor:not-allowed;transform:none}.secondary-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--text-primary);border:1px solid var(--border-light);font-weight:500;letter-spacing:.08em}.secondary-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--accent);color:var(--text-bright)}.disconnect-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--error);border:1px solid var(--error);font-weight:500}.phase.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-muted);text-align:center;letter-spacing:.04em}.invite-disclosure.svelte-1br9j49.svelte-1br9j49{margin-top:8px;border-top:1px solid var(--border);padding-top:14px}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49{cursor:pointer;color:var(--text-muted);font-size:var(--font-size-sm);list-style:none;min-height:36px;display:flex;align-items:center;justify-content:center;transition:color .15s ease}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:hover{color:var(--text-secondary)}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49::-webkit-details-marker{display:none}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:before{content:"+";margin-right:8px;color:var(--text-dim)}.invite-disclosure[open].svelte-1br9j49 summary.svelte-1br9j49:before{content:"−"}.invite-block.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:10px;margin-top:12px}.connected-line.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;gap:8px;color:var(--text-bright)}.info-line.svelte-1br9j49.svelte-1br9j49{display:flex;justify-content:space-between;font-size:var(--font-size-sm);color:var(--text-secondary)}.info-value.svelte-1br9j49.svelte-1br9j49{color:var(--text-primary);font-family:var(--font-mono)}.sq.svelte-1br9j49.svelte-1br9j49{width:8px;height:8px;display:inline-block}.sq-green.svelte-1br9j49.svelte-1br9j49{background:var(--success)}.sq-warn.svelte-1br9j49.svelte-1br9j49{background:var(--warning)}.sr-only.svelte-1br9j49.svelte-1br9j49{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.light-theme input.svelte-1br9j49.svelte-1br9j49{background:#ffffffa6}.light-theme input.svelte-1br9j49.svelte-1br9j49:focus{background:#ffffffe6}.chat-view.svelte-dxth9d.svelte-dxth9d{display:flex;flex-direction:column;height:100%}.chat-header.svelte-dxth9d.svelte-dxth9d{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--border);background:var(--bg-surface)}.back-btn.svelte-dxth9d.svelte-dxth9d{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-secondary);cursor:pointer}.chat-title.svelte-dxth9d.svelte-dxth9d{color:var(--text-bright);font-size:var(--font-size)}.chat-messages.svelte-dxth9d.svelte-dxth9d{flex:1;overflow-y:auto;padding:16px;min-height:0}.empty-chat.svelte-dxth9d.svelte-dxth9d{text-align:center;padding:40px 16px;color:var(--text-muted)}.empty-chat-label.svelte-dxth9d.svelte-dxth9d{color:var(--text-secondary);margin:8px 0 4px}.empty-chat-desc.svelte-dxth9d.svelte-dxth9d{font-size:var(--font-size-xs)}.date-sep.svelte-dxth9d.svelte-dxth9d{text-align:center;font-size:var(--font-size-xs);color:var(--text-dim);margin:12px 0}.system-line.svelte-dxth9d.svelte-dxth9d{text-align:center;font-size:var(--font-size-xs);color:var(--text-muted);margin:8px 0}.msg.svelte-dxth9d.svelte-dxth9d{margin-bottom:10px;max-width:80%}.msg.self.svelte-dxth9d.svelte-dxth9d{margin-left:auto;text-align:right}.msg-meta.svelte-dxth9d.svelte-dxth9d{font-size:var(--font-size-xs);color:var(--text-muted);margin-bottom:2px}.msg-body.svelte-dxth9d.svelte-dxth9d{display:inline-block;padding:8px 10px;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);white-space:pre-wrap;word-break:break-word;text-align:left}.msg.self.svelte-dxth9d .msg-body.svelte-dxth9d{background:var(--bg-active)}.retry-btn.svelte-dxth9d.svelte-dxth9d{margin-left:6px;background:transparent;border:none;color:var(--error);cursor:pointer;font-size:var(--font-size-xs)}.chat-input-area.svelte-dxth9d.svelte-dxth9d{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border);background:var(--bg-surface)}textarea.svelte-dxth9d.svelte-dxth9d{flex:1;resize:none;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);padding:8px 10px;font-family:inherit;font-size:var(--font-size);min-height:36px}textarea.svelte-dxth9d.svelte-dxth9d:disabled{opacity:.5}.send-btn.svelte-dxth9d.svelte-dxth9d{background:var(--accent);color:var(--accent-ink);border:none;border-radius:var(--radius-md, 6px);padding:0 16px;cursor:pointer;font-family:inherit;text-transform:uppercase}.send-btn.svelte-dxth9d.svelte-dxth9d:disabled{opacity:.4;cursor:not-allowed}.settings-view.svelte-51kqlv.svelte-51kqlv{display:flex;flex-direction:column;height:100%;padding:24px 32px}.settings-content.svelte-51kqlv.svelte-51kqlv{flex:1;overflow-y:auto;min-height:0;height:0}.settings-title.svelte-51kqlv.svelte-51kqlv{font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-bottom:20px}.reconnect-banner.svelte-51kqlv.svelte-51kqlv{background:var(--bg-raised);border:1px solid var(--border-hover);color:var(--text-bright);padding:10px 12px;margin-bottom:16px;font-size:var(--font-size-sm)}.section.svelte-51kqlv.svelte-51kqlv{margin-bottom:24px}.section-title.svelte-51kqlv.svelte-51kqlv{font-size:10px;font-weight:600;color:var(--text-dim);letter-spacing:.08em;text-transform:uppercase;margin-bottom:10px}.hint.svelte-51kqlv.svelte-51kqlv{font-size:var(--font-size-xs);color:var(--text-muted);margin:6px 0 12px;line-height:1.4}.reconnect-hint.svelte-51kqlv.svelte-51kqlv{color:var(--text-secondary)}.setting-row.svelte-51kqlv.svelte-51kqlv{display:flex;align-items:center;gap:12px;margin-bottom:10px;min-height:32px}.setting-label.svelte-51kqlv.svelte-51kqlv{min-width:140px;color:var(--text-secondary);font-size:var(--font-size-sm)}.toggle-label.svelte-51kqlv.svelte-51kqlv{color:var(--text-muted);font-size:var(--font-size-xs)}input[type=text].svelte-51kqlv.svelte-51kqlv,input[type=password].svelte-51kqlv.svelte-51kqlv,input[type=number].svelte-51kqlv.svelte-51kqlv,select.svelte-51kqlv.svelte-51kqlv{flex:1;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm, 4px);color:var(--text-primary);padding:8px 10px;min-height:32px;font-family:var(--font-mono);font-size:var(--font-size-sm)}input[type=checkbox].svelte-51kqlv.svelte-51kqlv{width:18px;height:18px}.radio-group.svelte-51kqlv.svelte-51kqlv{display:flex;gap:12px}.radio-option.svelte-51kqlv.svelte-51kqlv{display:flex;align-items:center;gap:6px;color:var(--text-secondary);font-size:var(--font-size-sm);min-height:32px}.scale-row.svelte-51kqlv input[type=range].svelte-51kqlv{flex:1;min-width:120px;accent-color:var(--accent)}.scale-value.svelte-51kqlv.svelte-51kqlv{min-width:44px;text-align:right;color:var(--text-secondary);font-size:var(--font-size-sm);font-family:var(--font-mono)}.actions-section.svelte-51kqlv.svelte-51kqlv{display:flex;gap:8px;align-items:center}.actions-section.svelte-51kqlv .btn.svelte-51kqlv{min-height:32px;padding:6px 12px}.update-row.svelte-51kqlv.svelte-51kqlv{flex-wrap:wrap}.update-row.svelte-51kqlv .btn.svelte-51kqlv{min-height:32px;padding:6px 12px}.btn-check.svelte-51kqlv.svelte-51kqlv,.btn-update.svelte-51kqlv.svelte-51kqlv{background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.btn-check.svelte-51kqlv.svelte-51kqlv:hover:not(:disabled),.btn-update.svelte-51kqlv.svelte-51kqlv:hover:not(:disabled){border-color:var(--border-hover);color:var(--text-bright)}.btn-check.svelte-51kqlv.svelte-51kqlv:disabled,.btn-update.svelte-51kqlv.svelte-51kqlv:disabled{opacity:.5;cursor:default}.ver.svelte-51kqlv.svelte-51kqlv{margin-left:auto;color:var(--text-dim);font-size:var(--font-size-xs)}.band.svelte-wx9xg3{display:flex;align-items:center;gap:16px;padding:8px 12px;min-height:48px;background:var(--bg-surface);border-bottom:1px solid var(--border);flex-shrink:0}.wordmark.svelte-wx9xg3{font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--text-bright);flex-shrink:0}.facts.svelte-wx9xg3{display:flex;flex-wrap:wrap;align-items:center;gap:16px 20px;flex:1;min-width:0}.fact.svelte-wx9xg3{display:flex;flex-direction:column;gap:2px;min-width:0}.cap.svelte-wx9xg3{font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dim)}.val.svelte-wx9xg3{color:var(--text-bright);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:28ch}.mono.svelte-wx9xg3{font-family:var(--font-mono);font-weight:500}.vip.svelte-wx9xg3{background:none;border:none;padding:0;text-align:left;cursor:pointer;color:var(--text-bright)}.vip.svelte-wx9xg3:hover{text-decoration:underline}.path-row.svelte-wx9xg3{display:flex;align-items:center;gap:6px}.actions.svelte-wx9xg3{display:flex;gap:8px;flex-shrink:0;margin-left:auto}.btn.active.svelte-wx9xg3{border-color:var(--border-hover);background:var(--bg-hover);color:var(--text-bright)}.shell.svelte-1v9dp4p{display:flex;flex-direction:column;height:100%;width:100%;position:relative;z-index:1;min-height:0}.connect-shell.svelte-1v9dp4p{z-index:1}.connected-shell.svelte-1v9dp4p{background:var(--bg-primary)}.layout.svelte-1v9dp4p{display:flex;flex:1;min-height:0;position:relative}.fullscreen-connect.svelte-1v9dp4p{display:flex;flex:1;width:100%;align-items:center;justify-content:center;min-height:0}.sidebar-wrapper.svelte-1v9dp4p{position:relative;flex-shrink:0;background:var(--bg-surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}.drag-handle.svelte-1v9dp4p{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10;background:transparent;transition:background .1s}.drag-handle.svelte-1v9dp4p:hover,.drag-handle.active.svelte-1v9dp4p,.drag-handle.svelte-1v9dp4p:focus-visible{background:var(--border-hover)}.main-area.svelte-1v9dp4p{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg-primary);min-width:0;min-height:0}.view-pane.svelte-1v9dp4p{flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;animation:svelte-1v9dp4p-viewIn .18s var(--ease-out, ease-out) both}@keyframes svelte-1v9dp4p-viewIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.unknown-view.svelte-1v9dp4p{padding:40px;color:var(--text-muted)}.error-strip.svelte-1v9dp4p{position:fixed;left:12px;right:12px;bottom:calc(var(--statusbar-height) + 12px);z-index:1100;display:flex;align-items:center;gap:12px;padding:10px 14px;background:var(--bg-raised);border:1px solid var(--error);color:var(--error);font-size:var(--font-size-sm)}.error-strip-msg.svelte-1v9dp4p{flex:1;min-width:0;word-break:break-word}.error-strip-dismiss.svelte-1v9dp4p{flex-shrink:0;min-height:32px;padding:4px 10px;border:1px solid var(--error);background:transparent;color:var(--error);cursor:pointer;font-family:var(--font-mono);font-size:var(--font-size-xs);text-transform:uppercase}.error-strip-dismiss.svelte-1v9dp4p:hover{background:#c45c5c1f}@keyframes svelte-1v9dp4p-slideIn{0%{transform:translate(12px);opacity:0}to{transform:translate(0);opacity:1}}.notification.svelte-1v9dp4p{position:fixed;top:12px;right:12px;padding:6px 12px;font-size:var(--font-size-sm);z-index:1000;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);animation:svelte-1v9dp4p-slideIn .16s var(--ease-out, ease-out) both}.notification.error.svelte-1v9dp4p{border-color:var(--error);color:var(--error)}.notification.info.svelte-1v9dp4p{border-color:var(--border)}.notif-icon.svelte-1v9dp4p{margin-right:6px;font-weight:700}.space-bg,.space-bg:before,.space-bg:after,.space-dust,.space-dust:before{position:fixed;pointer-events:none;z-index:0}.space-bg{inset:0;background:radial-gradient(ellipse 85% 65% at 50% 36%,rgba(255,255,255,.045) 0%,transparent 55%),radial-gradient(ellipse 120% 80% at 50% 100%,rgba(255,255,255,.03) 0%,transparent 50%),radial-gradient(ellipse 100% 100% at 50% 50%,#0a0a0a,#050505 70%,#000)}.space-bg:before{content:"";position:absolute;inset:0;opacity:.8;background:radial-gradient(1.2px 1.2px at 5% 10%,rgba(255,255,255,.55) 0%,transparent 100%),radial-gradient(1px 1px at 12% 32%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 18% 68%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 25% 45%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 32% 18%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 38% 78%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 45% 15%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 52% 58%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 58% 28%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 65% 10%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 72% 72%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 78% 40%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 85% 65%,rgba(255,255,255,.48) 0%,transparent 100%),radial-gradient(1px 1px at 90% 22%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 94% 88%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 8% 88%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 30% 92%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(1px 1px at 48% 42%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 62% 88%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1px 1px at 88% 52%,rgba(255,255,255,.26) 0%,transparent 100%)}.space-bg:after{content:"";position:absolute;inset:0;background-image:radial-gradient(1.5px 1.5px at 8% 18%,rgba(255,255,255,.7) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 48% 38%,rgba(255,255,255,.6) 0%,transparent 100%),radial-gradient(1.5px 1.5px at 88% 28%,rgba(255,255,255,.65) 0%,transparent 100%),radial-gradient(1px 1px at 22% 55%,rgba(255,255,255,.45) 0%,transparent 100%),radial-gradient(1px 1px at 70% 60%,rgba(255,255,255,.4) 0%,transparent 100%);animation:twinkle 9s ease-in-out infinite alternate;opacity:.5}@keyframes twinkle{0%{opacity:.2}45%{opacity:.5}to{opacity:.25}}.space-dust{inset:0;background:radial-gradient(ellipse 80% 70% at 50% 45%,transparent 42%,rgba(0,0,0,.62) 100%);opacity:1}.space-dust:before{content:"";position:absolute;inset:0;opacity:.32;background:radial-gradient(.5px .5px at 20% 30%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(.5px .5px at 40% 60%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 60% 25%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 75% 70%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(.5px .5px at 88% 40%,rgba(255,255,255,.3) 0%,transparent 100%)}.light-theme .space-bg,.light-theme .space-bg:before,.light-theme .space-bg:after,.light-theme .space-dust,.light-theme .space-dust:before{display:none!important}html[data-app=connected]{--bg-deep: #0a0a0a;--bg-primary: #0a0a0a;--bg-surface: #111111;--bg-raised: #181818;--bg-hover: #1c1c1c;--bg-active: #222222;--border-deep: #1a1a1a;--border: #2a2a2a;--border-light: #3a3a3a;--border-hover: #4a4a4a;--text-bright: #f0f0f0;--text-primary: #f0f0f0;--text-secondary: #8a8a8a;--text-muted: #8a8a8a;--text-dim: #5c5c5c;--accent: #ffffff;--accent-hover: #f0f0f0;--accent-ink: #0a0a0a;--live: #2fbf62;--fault: #e23d3d;--success: #8a8a8a;--warning: #8a8a8a;--error: #e23d3d;--focus-ring: #f0f0f0;--font-sans: ui-sans-serif, "Segoe UI", system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", Consolas, monospace;--font-size: 13px;--font-size-sm: 12px;--font-size-xs: 10px;--line-height: 1.45;--radius-sm: 4px;--radius-md: 6px;--statusbar-height: 26px;--ease-out: cubic-bezier(.16, 1, .3, 1);--dur-fast: .12s;--dur-mid: .18s}html[data-app=connected].light-theme{--bg-deep: #f5f5f5;--bg-primary: #f5f5f5;--bg-surface: #ececec;--bg-raised: #e4e4e4;--bg-hover: #dedede;--bg-active: #d6d6d6;--border-deep: #e0e0e0;--border: #d0d0d0;--border-light: #c4c4c4;--border-hover: #999999;--text-bright: #111111;--text-primary: #111111;--text-secondary: #5c5c5c;--text-muted: #6a6a6a;--text-dim: #8a8a8a;--accent: #111111;--accent-hover: #000000;--accent-ink: #f5f5f5;--live: #1a8f45;--fault: #c41e1e;--success: #6a6a6a;--warning: #6a6a6a;--error: #c41e1e;--focus-ring: #111111}html[data-app=connected],html[data-app=connected] body,html[data-app=connected] #app{color:var(--text-primary);font-family:var(--font-sans);font-size:var(--font-size);line-height:var(--line-height);background:var(--bg-deep)}html[data-app=connected] input,html[data-app=connected] textarea,html[data-app=connected] button,html[data-app=connected] select{font-family:inherit}html[data-app=connected] .btn{padding:6px 12px;min-height:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-md);background:transparent;color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-sans);transition:background var(--dur-fast) ease,border-color var(--dur-fast) ease,opacity var(--dur-fast) ease,transform var(--dur-fast) ease}html[data-app=connected] .btn:hover:not(:disabled){background:var(--bg-hover);border-color:var(--border-hover)}html[data-app=connected] .btn:active:not(:disabled){transform:translateY(1px)}html[data-app=connected] .btn.primary,html[data-app=connected] .btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}html[data-app=connected] .btn.primary:hover,html[data-app=connected] .btn-save:hover{background:var(--accent-hover)}html[data-app=connected] .btn:disabled{opacity:.4;cursor:not-allowed}html[data-app=connected] .btn.danger{color:var(--fault);border-color:var(--fault)}html[data-app=connected] .path-dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0;background:var(--text-dim)}html[data-app=connected] .path-dot.direct{background:var(--live)}html[data-app=connected] .path-dot.relay,html[data-app=connected] .path-dot.reconnecting{background:var(--fault)}html[data-app=connected] .path-dot.reconnecting{animation:pathPulse 1.2s var(--ease-out) infinite}html[data-app=connected] .path-dot.disconnected{background:var(--text-dim)}html[data-app=connected] .unread-badge{background:var(--fault);color:#fff}@keyframes pathPulse{0%,to{opacity:1}50%{opacity:.35}}html[data-app=connected] .connected-shell{animation:shellIn var(--dur-mid) var(--ease-out) both}@keyframes shellIn{0%{opacity:0}to{opacity:1}}@media (prefers-reduced-motion: reduce){html[data-app=connected]{--dur-fast: .01ms;--dur-mid: .01ms}html[data-app=connected] *,html[data-app=connected] *:before,html[data-app=connected] *:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}@font-face{font-family:Bungee;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/bungee-latin-Dfnurram.woff2) format("woff2")}:root{--bg-deep: #000000;--bg-primary: #050505;--bg-surface: #0a0a0a;--bg-raised: #111111;--bg-hover: #181818;--bg-active: #1f1f1f;--border-deep: #111111;--border: #1c1c1c;--border-light: #2a2a2a;--border-hover: #3d3d3d;--text-bright: #f5f5f5;--text-primary: #c8c8c8;--text-secondary: #8a8a8a;--text-muted: #5c5c5c;--text-dim: #3a3a3a;--accent: #f0f0f0;--accent-hover: #ffffff;--accent-ink: #000000;--success: #9a9a9a;--warning: #c8c8c8;--error: #c45c5c;--focus-ring: #f0f0f0;--sidebar-width: 220px;--statusbar-height: 28px;--font-display: "Bungee", ui-sans-serif, system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;--font-size: 12px;--font-size-sm: 11px;--font-size-xs: 10px;--line-height: 1.6}.light-theme{--bg-deep: #f5f5f5;--bg-primary: #f0f0f0;--bg-surface: #e8e8e8;--bg-raised: #e0e0e0;--bg-hover: #d8d8d8;--bg-active: #cfcfcf;--border-deep: #d0d0d0;--border: #cccccc;--border-light: #bbbbbb;--border-hover: #999999;--text-bright: #111111;--text-primary: #222222;--text-secondary: #555555;--text-muted: #888888;--text-dim: #aaaaaa;--accent: #000000;--accent-hover: #222222;--accent-ink: #f5f5f5;--success: #555555;--warning: #333333;--error: #b33a3a;--focus-ring: #000000}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html,body,#app{height:100%;width:100%;overflow:hidden;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size);line-height:var(--line-height);-webkit-font-smoothing:antialiased;user-select:auto}html,body{background:var(--bg-deep)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border)}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}::-webkit-scrollbar-corner{background:transparent}::selection{background:#ffffff1a;color:var(--text-bright)}input,textarea,button,select{font-family:var(--font-mono);font-size:var(--font-size)}input:focus-visible,textarea:focus-visible,select:focus-visible,button:focus-visible,[tabindex]:focus-visible,.network-item:focus-visible,.clickable:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}button{cursor:pointer;border:none;background:none;color:inherit}a{color:var(--text-bright);text-decoration:none}a:hover{text-decoration:underline}.btn{padding:8px 12px;min-height:36px;border:1px solid var(--border);background:var(--bg-raised);color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-mono);transition:background .1s ease,opacity .1s ease}.btn:hover:not(:disabled){background:var(--bg-hover)}.btn.primary,.btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}.btn.primary:hover,.btn-save:hover{background:var(--accent-hover)}.btn:disabled{opacity:.4;cursor:not-allowed}.btn.danger{color:var(--error);border-color:var(--error)}.empty-state{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)} diff --git a/client/frontend/dist/assets/index-C4YP2y5T.js b/client/frontend/dist/assets/index-C4YP2y5T.js new file mode 100644 index 0000000..3759f65 --- /dev/null +++ b/client/frontend/dist/assets/index-C4YP2y5T.js @@ -0,0 +1 @@ +(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const a of r.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&i(a)}).observe(document,{childList:!0,subtree:!0});function n(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(o){if(o.ep)return;o.ep=!0;const r=n(o);fetch(o.href,r)}})();function ce(){}function Ci(t){return t()}function Ws(){return Object.create(null)}function Pe(t){t.forEach(Ci)}function Vl(t){return typeof t=="function"}function $e(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}function Li(t){return Object.keys(t).length===0}function zl(t,...e){if(t==null){for(const i of e)i(void 0);return ce}const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function xt(t){let e;return zl(t,n=>e=n)(),e}function ae(t,e,n){t.$$.on_destroy.push(zl(e,n))}function nt(t,e,n){return t.set(n),e}function l(t,e){t.appendChild(e)}function B(t,e,n){t.insertBefore(e,n||null)}function z(t){t.parentNode&&t.parentNode.removeChild(t)}function c(t){return document.createElement(t)}function Ke(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function h(t){return document.createTextNode(t)}function m(){return h(" ")}function Tl(){return h("")}function V(t,e,n,i){return t.addEventListener(e,n,i),()=>t.removeEventListener(e,n,i)}function Ut(t){return function(e){return e.stopPropagation(),t.call(this,e)}}function s(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function Ii(t){let e;return{p(...n){e=n,e.forEach(i=>t.push(i))},r(){e.forEach(n=>t.splice(t.indexOf(n),1))}}}function Pi(t){return t===""?null:+t}function Ri(t){return Array.from(t.childNodes)}function w(t,e){e=""+e,t.data!==e&&(t.data=e)}function ne(t,e){t.value=e??""}function Fs(t,e,n,i){n==null?t.style.removeProperty(e):t.style.setProperty(e,n,"")}function Qn(t,e,n){for(let i=0;ii.call(this,e))}const Ot=[],Wt=[];let Mt=[];const Ks=[],Mi=Promise.resolve();let Ol=!1;function Ui(){Ol||(Ol=!0,Mi.then(Di))}function $n(t){Mt.push(t)}const Rl=new Set;let Rt=0;function Di(){if(Rt!==0)return;const t=tn;do{try{for(;Rtt.indexOf(i)===-1?e.push(i):n.push(i)),n.forEach(i=>i()),Mt=e}const Zn=new Set;let vt;function Bl(){vt={r:0,c:[],p:vt}}function Gl(){vt.r||Pe(vt.c),vt=vt.p}function Le(t,e){t&&t.i&&(Zn.delete(t),t.i(e))}function Ue(t,e,n,i){if(t&&t.o){if(Zn.has(t))return;Zn.add(t),vt.c.push(()=>{Zn.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function ut(t){return t?.length!==void 0?t:Array.from(t)}function el(t,e){t.d(1),e.delete(t.key)}function tl(t,e,n,i,o,r,a,_,u,d,f,p){let v=t.length,b=r.length,g=v;const L={};for(;g--;)L[t[g].key]=g;const j=[],y=new Map,k=new Map,q=[];for(g=b;g--;){const W=p(o,r,g),J=n(W);let S=a.get(J);S?q.push(()=>S.p(W,e)):(S=d(J,W),S.c()),y.set(J,j[g]=S),J in L&&k.set(J,Math.abs(g-L[J]))}const M=new Set,K=new Set;function E(W){Le(W,1),W.m(_,f),a.set(W.key,W),f=W.first,b--}for(;v&&b;){const W=j[b-1],J=t[v-1],S=W.key,A=J.key;W===J?(f=W.first,v--,b--):y.has(A)?!a.has(S)||M.has(S)?E(W):K.has(A)?v--:k.get(S)>k.get(A)?(K.add(S),E(W)):(M.add(A),v--):(u(J,a),v--)}for(;v--;){const W=t[v];y.has(W.key)||u(W,a)}for(;b;)E(j[b-1]);return Pe(q),j}function mt(t){t&&t.c()}function at(t,e,n){const{fragment:i,after_update:o}=t.$$;i&&i.m(e,n),$n(()=>{const r=t.$$.on_mount.map(Ci).filter(Vl);t.$$.on_destroy?t.$$.on_destroy.push(...r):Pe(r),t.$$.on_mount=[]}),o.forEach($n)}function ct(t,e){const n=t.$$;n.fragment!==null&&(Fi(n.after_update),Pe(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function Ki(t,e){t.$$.dirty[0]===-1&&(Ot.push(t),Ui(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const g=b.length?b[0]:v;return d.ctx&&o(d.ctx[p],d.ctx[p]=g)&&(!d.skip_bound&&d.bound[p]&&d.bound[p](g),f&&Ki(t,p)),v}):[],d.update(),f=!0,Pe(d.before_update),d.fragment=i?i(d.ctx):!1,e.target){if(e.hydrate){const p=Ri(e.target);d.fragment&&d.fragment.l(p),p.forEach(z)}else d.fragment&&d.fragment.c();e.intro&&Le(t.$$.fragment),at(t,e.target,e.anchor),Di()}en(u)}class dt{$$=void 0;$$set=void 0;$destroy(){ct(this,1),this.$destroy=ce}$on(e,n){if(!Vl(n))return ce;const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!Li(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Vi="4",Tt=[];function zi(t,e){return{subscribe:Ge(t,e).subscribe}}function Ge(t,e=ce){let n;const i=new Set;function o(_){if($e(t,_)&&(t=_,n)){const u=!Tt.length;for(const d of i)d[1](),Tt.push(d,t);if(u){for(let d=0;d{i.delete(d),i.size===0&&n&&(n(),n=null)}}return{set:o,update:r,subscribe:a}}function Ji(t,e,n){const i=!Array.isArray(t),o=i?[t]:t;if(!o.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const r=e.length<2;return zi(n,(a,_)=>{let u=!1;const d=[];let f=0,p=ce;const v=()=>{if(f)return;p();const g=e(i?d[0]:d,a,_);r?a(g):p=Vl(g)?g:ce},b=o.map((g,L)=>zl(g,j=>{d[L]=j,f&=~(1<{f|=1<[...i,{id:n,msg:t,type:e}]),setTimeout(()=>{Ul.update(i=>i.filter(o=>o.id!==n))},4e3),e==="error"&&Yi(t)}function Yi(t){if(!t){xn.set(null);return}xn.set({id:++Hi,msg:String(t)})}function ln(){xn.set(null)}function Wl(t,e){return t&&t.id?"peer:"+t.id:"room:"+(e||"network")}function sn(){return Wl(xt(nn),xt(De).room)}function Xl(t,e,n,i=!1,o="sent",r=!1,a=!1){const _=++Gi;let u;r?u=Wl(null,xt(De).room):i?u=sn():a?u="peer:"+t:u=Wl(null,xt(De).room),Hl.update(p=>{const v=p[u]?[...p[u]]:[];return v.push({id:i&&t.startsWith("local_")?t:_,fromID:t,nickname:e,message:n,timestamp:Date.now(),isSelf:i,status:o,system:r}),{...p,[u]:v.length>Vs?v.slice(-Vs):v}});const d=xt(Ee),f=sn();!i&&!(d==="chat"&&u===f)&&Yl.update(p=>({...p,[u]:(p[u]||0)+1}))}function Xi(t){Xl("system","",t,!1,"sent",!0)}function Fl(t){Yl.update(e=>{const n={...e};return delete n[t],n})}function Zt(t,e){const n=sn();Hl.update(i=>{const o=i[n];return o?{...i,[n]:o.map(r=>r.id===t?{...r,status:e}:r)}:i})}const Qi={subscribe(t){return Hl.subscribe(e=>{t(e[sn()]||[])})}},Kl={brand:"Entangled",tagline:"Private LAN for friends — anywhere.",networks:"Networks",network_count:"{n} network(s)",create_network:"Create Network",join_network:"Join Network",connecting:"Connecting...",peer_count:"{n} peer(s)",offline_click:"Offline — click to connect",saved:"Saved",no_networks:"No saved networks",no_networks_desc:"Create or join a network to get started",settings:"Settings",network_name:"Network name",password_opt:"Password (optional)",cancel:"Cancel",create:"Create",join:"Join",leave:"Leave network",remove:"Remove saved",delete_room:"Delete network",more_actions:"More actions",copy_invite:"Copy invite",paste_invite:"Have an invite?",invite_copied:"Invite copied",invite_placeholder:"server|room|password",server_addr:"Server Address",nickname:"Nickname",server_token:"Server token",server_token_desc:"optional shared secret (ENTANGLED_TOKEN)",connect:"Connect",disconnect:"Disconnect",connected:"Connected",server:"Server",virtual_ip:"Virtual IP",na:"N/A",reconnecting:"Reconnecting...",disconnected:"Disconnected",phase_dialing:"Dialing server…",phase_auth:"Authenticating…",phase_ready:"Ready",phase_error:"Error",room_chat:"Room Chat",chat:"Chat",col_nickname:"Nickname",col_ip:"Virtual IP",col_ping:"Ping",ping_peer:"Ping",ping_sent:"Pinging {name}…",error_ping:"Ping failed: {err}",col_path:"Path",col_status:"Status",status_online:"Online",status_offline:"Offline",path_p2p:"Direct",path_relay:"Relay",path_ws:"Fallback",path_unknown:"—",path_p2p_tip:"Peer-to-peer direct connection",path_relay_tip:"Traffic routed through the server relay",path_ws_tip:"WebSocket fallback path",you:"You",me:"me",no_peers:"No peers connected",no_peers_desc:"Create or join a network, then wait for friends",network:"Network",chat_with:"Chat with {name}",room_chat_title:"Room Chat — {room}",back:"Back",no_messages:"No messages yet",no_messages_desc:"Send a message to start the conversation",type_message:"Type a message...",send:"Send",send_disabled_no_room:"Join a network to chat",msg_truncated:"Message truncated to 1000 characters",retry:"Retry",today:"Today",yesterday:"Yesterday",you_self:"You",status_connected:"Connected",status_disconnected:"Disconnected",status_reconnecting:"Reconnecting…",status_relay_degraded:"Some peers on relay",status_server:"Server: {s}",status_ip:"IP: {ip}",status_network:"Network: {room}",status_peers:"Peers: {n}",version:"Entangled v{v}",settings_title:"Settings",section_connection:"CONNECTION",section_network:"ADVANCED NETWORK",section_system:"SYSTEM",section_appearance:"APPEARANCE",advanced_warn:"Only change these if you know what they do.",reconnect_apply:"Reconnect to apply",auto_connect:"Auto Connect",auto_connect_desc:"connect to last server on startup",auto_join:"Auto Join Last Room",auto_join_desc:"join last open room after connect (password rooms need a manual join after restart)",connection_mode:"Connection",connection_direct:"Direct (P2P)",connection_relay:"Relay (server)",connection_mode_desc:"Direct prefers peer-to-peer and uses relay only when needed. Relay forces all traffic through the server.",mtu:"MTU",mtu_desc:"Packet size. Wrong values can break games or cause lag.",dns_server:"DNS Server",dns_desc:"Optional DNS for the virtual network. Leave blank for system default.",socks5:"SOCKS5 Proxy",socks5_placeholder:"e.g. 127.0.0.1:10808",socks5_desc:"Proxies signaling (WebSocket) only — not peer/relay UDP. Reconnect to apply.",stun_server:"STUN Server",stun_desc:"Helps find your public address for direct links. Reconnect to apply.",start_windows:"Start with Windows",updates:"Updates",check_updates:"Check for updates",apply_update:"Update",update_checking:"Checking for updates…",update_latest:"You are up to date.",update_available:"Update available: v{v}",update_downloading:"Downloading update… the app will restart.",update_failed:"Update failed",confirm_update:"Download and install the update? The app will restart.",error_update_check:"Update check failed: ",error_update:"Update failed: ",notif_updating:"Installing update…",ui_scale:"UI Scale",ui_scale_desc:"Scales the whole interface. Use with window resize or F11 fullscreen.",theme:"Theme",theme_dark:"Dark",theme_light:"Light",language:"Language",save:"SAVE",reset:"RESET TO DEFAULTS",language_en:"English",language_ru:"Russian",language_zh:"Chinese",copied:"Copied",header_room:"Room",header_vip:"VIP",header_path:"Path",header_peers:"Peers",dismiss_error:"Dismiss",field_required:"Required",notif_created:"Network created: {name}",notif_joined:"Joined network: {name}",notif_left:"Left network",notif_removed:"Removed: {name}",notif_deleted:"Network deleted: {name}",notif_connected:"Connected to {addr}",notif_disconnected:"Disconnected",notif_settings_saved:"Settings saved",notif_reconnect_required:"Reconnect to apply proxy / STUN / token changes",notif_auto_join_skipped:'Auto-join skipped for "{name}" — enter the password to join',notif_need_config:"Set server & nickname in Connect page first",notif_room_deleted:"Network was deleted by owner",invite_no_password:"Invite copied without password (not stored). Add it before sharing.",error_create:"Failed to create network: {err}",error_join:"Failed to join: {err}",error_leave:"Failed to leave: {err}",error_remove:"Failed to remove: {err}",error_connect:"Connection failed: {err}",error_disconnect:"Error: {err}",error_send:"Failed to send: {err}",error_not_connected:"Not connected — cannot send message",error_invalid_invite:"Invalid invite: server and room are required",error_save:"Failed to save settings: {err}",confirm_disconnect:"Disconnect from server?",confirm_leave:"Leave the current network? It stays in your saved list.",confirm_leave_remove:"Leave and remove this network from your saved list?",confirm_remove:'Remove "{name}" from saved networks? (does not delete the network for others)',confirm_delete:'Permanently delete network "{name}" for everyone?',confirm_reset:"Reset all settings to defaults?"},Zi={brand:"Entangled",tagline:"Частная LAN для друзей — где угодно.",networks:"Сети",network_count:"{n} сет(ь/и/ей)",create_network:"Создать сеть",join_network:"Подключиться",connecting:"Подключение...",peer_count:"{n} участник(ов)",offline_click:"Не в сети — нажмите для подключения",saved:"Сохранено",no_networks:"Нет сохранённых сетей",no_networks_desc:"Создайте или войдите в сеть, чтобы начать",settings:"Настройки",network_name:"Название сети",password_opt:"Пароль (опционально)",cancel:"Отмена",create:"Создать",join:"Войти",leave:"Покинуть сеть",remove:"Убрать из списка",delete_room:"Удалить сеть",more_actions:"Ещё действия",copy_invite:"Копировать инвайт",paste_invite:"Есть инвайт?",invite_copied:"Инвайт скопирован",invite_placeholder:"сервер|комната|пароль",server_addr:"Адрес сервера",nickname:"Псевдоним",server_token:"Токен сервера",server_token_desc:"опциональный секрет (ENTANGLED_TOKEN)",connect:"Подключиться",disconnect:"Отключиться",connected:"Подключено",server:"Сервер",virtual_ip:"Виртуальный IP",na:"Н/Д",reconnecting:"Переподключение...",disconnected:"Отключено",phase_dialing:"Подключение к серверу…",phase_auth:"Аутентификация…",phase_ready:"Готово",phase_error:"Ошибка",room_chat:"Чат комнаты",chat:"Чат",col_nickname:"Псевдоним",col_ip:"Виртуальный IP",col_ping:"Пинг",ping_peer:"Пинг",ping_sent:"Пинг {name}…",error_ping:"Пинг не удался: {err}",col_path:"Путь",col_status:"Статус",status_online:"В сети",status_offline:"Не в сети",path_p2p:"Прямой",path_relay:"Релей",path_ws:"Запасной",path_unknown:"—",path_p2p_tip:"Прямое соединение peer-to-peer",path_relay_tip:"Трафик через серверный релей",path_ws_tip:"Запасной путь через WebSocket",you:"Вы",me:"я",no_peers:"Нет подключённых участников",no_peers_desc:"Создайте или войдите в сеть и дождитесь друзей",network:"Сеть",chat_with:"Чат с {name}",room_chat_title:"Чат комнаты — {room}",back:"Назад",no_messages:"Сообщений пока нет",no_messages_desc:"Отправьте сообщение, чтобы начать разговор",type_message:"Введите сообщение...",send:"Отправить",send_disabled_no_room:"Войдите в сеть, чтобы писать",msg_truncated:"Сообщение обрезано до 1000 символов",retry:"Повторить",today:"Сегодня",yesterday:"Вчера",you_self:"Вы",status_connected:"Подключено",status_disconnected:"Отключено",status_reconnecting:"Переподключение…",status_relay_degraded:"Часть пиров через релей",status_server:"Сервер: {s}",status_ip:"IP: {ip}",status_network:"Сеть: {room}",status_peers:"Участники: {n}",version:"Entangled v{v}",settings_title:"Настройки",section_connection:"ПОДКЛЮЧЕНИЕ",section_network:"ДОП. СЕТЬ",section_system:"СИСТЕМА",section_appearance:"ВНЕШНИЙ ВИД",advanced_warn:"Меняйте только если понимаете, что делаете.",reconnect_apply:"Переподключитесь, чтобы применить",auto_connect:"Автоподключение",auto_connect_desc:"подключаться к последнему серверу при запуске",auto_join:"Автовход в комнату",auto_join_desc:"входить в последнюю открытую комнату (с паролем — вручную после перезапуска)",connection_mode:"Соединение",connection_direct:"Прямое (P2P)",connection_relay:"Релей (сервер)",connection_mode_desc:"Прямое предпочитает P2P и использует релей только при необходимости. Релей гонит весь трафик через сервер.",mtu:"MTU",mtu_desc:"Размер пакета. Неверное значение ломает игры или даёт лаги.",dns_server:"DNS-сервер",dns_desc:"Опциональный DNS виртуальной сети. Пусто — системный по умолчанию.",socks5:"SOCKS5-прокси",socks5_placeholder:"напр. 127.0.0.1:10808",socks5_desc:"Только сигнальный WebSocket, не UDP пиров/релея. Переподключитесь, чтобы применить.",stun_server:"STUN-сервер",stun_desc:"Помогает найти публичный адрес. Переподключитесь, чтобы применить.",start_windows:"Запуск с Windows",updates:"Обновления",check_updates:"Проверить обновления",apply_update:"Обновить",update_checking:"Проверка обновлений…",update_latest:"У вас актуальная версия.",update_available:"Доступно обновление: v{v}",update_downloading:"Загрузка обновления… приложение перезапустится.",update_failed:"Ошибка обновления",confirm_update:"Скачать и установить обновление? Приложение перезапустится.",error_update_check:"Не удалось проверить обновления: ",error_update:"Не удалось обновить: ",notif_updating:"Установка обновления…",ui_scale:"Масштаб UI",ui_scale_desc:"Масштабирует весь интерфейс. Вместе с изменением размера окна или F11.",theme:"Тема",theme_dark:"Тёмная",theme_light:"Светлая",language:"Язык",save:"СОХРАНИТЬ",reset:"СБРОСИТЬ",language_en:"Английский",language_ru:"Русский",language_zh:"Китайский",copied:"Скопировано",header_room:"Комната",header_vip:"VIP",header_path:"Путь",header_peers:"Участники",dismiss_error:"Закрыть",field_required:"Обязательно",notif_created:"Сеть создана: {name}",notif_joined:"Подключились к сети: {name}",notif_left:"Покинули сеть",notif_removed:"Удалено: {name}",notif_deleted:"Сеть удалена: {name}",notif_connected:"Подключились к {addr}",notif_disconnected:"Отключились",notif_settings_saved:"Настройки сохранены",notif_reconnect_required:"Переподключитесь, чтобы применить прокси / STUN / токен",notif_auto_join_skipped:"Автовход пропущен для «{name}» — введите пароль вручную",notif_need_config:"Укажите сервер и псевдоним на странице подключения",notif_room_deleted:"Сеть удалена владельцем",invite_no_password:"Инвайт скопирован без пароля (он не хранится). Добавьте перед отправкой.",error_create:"Не удалось создать сеть: {err}",error_join:"Не удалось подключиться: {err}",error_leave:"Не удалось покинуть: {err}",error_remove:"Не удалось удалить: {err}",error_connect:"Ошибка подключения: {err}",error_disconnect:"Ошибка: {err}",error_send:"Не удалось отправить: {err}",error_not_connected:"Нет подключения — невозможно отправить сообщение",error_invalid_invite:"Неверный инвайт: нужны сервер и комната",error_save:"Не удалось сохранить настройки: {err}",confirm_disconnect:"Отключиться от сервера?",confirm_leave:"Покинуть текущую сеть? Она останется в сохранённых.",confirm_leave_remove:"Покинуть и убрать сеть из сохранённых?",confirm_remove:'Убрать "{name}" из сохранённых? (сеть для других не удалится)',confirm_delete:'Навсегда удалить сеть "{name}" для всех?',confirm_reset:"Сбросить все настройки?"},$i={brand:"Entangled",tagline:"朋友的私人局域网 — 随时随地。",networks:"网络",network_count:"{n} 个网络",create_network:"创建网络",join_network:"加入网络",connecting:"连接中...",peer_count:"{n} 个节点",offline_click:"离线 — 点击连接",saved:"已保存",no_networks:"暂无保存的网络",no_networks_desc:"创建或加入网络以开始",settings:"设置",network_name:"网络名称",password_opt:"密码(可选)",cancel:"取消",create:"创建",join:"加入",leave:"离开网络",remove:"移除已保存",delete_room:"删除网络",more_actions:"更多操作",copy_invite:"复制邀请",paste_invite:"有邀请码?",invite_copied:"邀请已复制",invite_placeholder:"服务器|房间|密码",server_addr:"服务器地址",nickname:"昵称",server_token:"服务器令牌",server_token_desc:"可选共享密钥(ENTANGLED_TOKEN)",connect:"连接",disconnect:"断开",connected:"已连接",server:"服务器",virtual_ip:"虚拟 IP",na:"无",reconnecting:"重新连接...",disconnected:"已断开",phase_dialing:"正在连接服务器…",phase_auth:"正在验证…",phase_ready:"就绪",phase_error:"错误",room_chat:"房间聊天",chat:"聊天",col_nickname:"昵称",col_ip:"虚拟 IP",col_ping:"延迟",ping_peer:"测速",ping_sent:"正在测速 {name}…",error_ping:"测速失败: {err}",col_path:"路径",col_status:"状态",status_online:"在线",status_offline:"离线",path_p2p:"直连",path_relay:"中继",path_ws:"备用",path_unknown:"—",path_p2p_tip:"点对点直连",path_relay_tip:"经服务器中继转发",path_ws_tip:"WebSocket 备用路径",you:"你",me:"我",no_peers:"暂无连接的节点",no_peers_desc:"创建或加入网络,然后等待好友",network:"网络",chat_with:"与 {name} 聊天",room_chat_title:"房间聊天 — {room}",back:"返回",no_messages:"暂无消息",no_messages_desc:"发送一条消息开始对话",type_message:"输入消息...",send:"发送",send_disabled_no_room:"加入网络后才能聊天",msg_truncated:"消息已截断至 1000 个字符",retry:"重试",today:"今天",yesterday:"昨天",you_self:"你",status_connected:"已连接",status_disconnected:"已断开",status_reconnecting:"重新连接…",status_relay_degraded:"部分节点经中继",status_server:"服务器: {s}",status_ip:"IP: {ip}",status_network:"网络: {room}",status_peers:"节点: {n}",version:"Entangled v{v}",settings_title:"设置",section_connection:"连接",section_network:"高级网络",section_system:"系统",section_appearance:"外观",advanced_warn:"仅在了解作用时更改这些选项。",reconnect_apply:"重新连接以生效",auto_connect:"自动连接",auto_connect_desc:"启动时自动连接到上次的服务器",auto_join:"自动加入房间",auto_join_desc:"连接后自动加入上次的开放房间(有密码的房间重启后需手动加入)",connection_mode:"连接方式",connection_direct:"直连 (P2P)",connection_relay:"中继 (服务器)",connection_mode_desc:"直连优先点对点,必要时才用中继。中继模式强制全部流量经服务器。",mtu:"MTU",mtu_desc:"数据包大小。错误值可能导致游戏异常或卡顿。",dns_server:"DNS 服务器",dns_desc:"虚拟网络可选 DNS。留空则使用系统默认。",socks5:"SOCKS5 代理",socks5_placeholder:"例如 127.0.0.1:10808",socks5_desc:"仅代理信令 WebSocket,不含节点/中继 UDP。重新连接以生效。",stun_server:"STUN 服务器",stun_desc:"用于发现公网地址以便直连。重新连接以生效。",start_windows:"开机自启",updates:"更新",check_updates:"检查更新",apply_update:"更新",update_checking:"正在检查更新…",update_latest:"已是最新版本。",update_available:"有可用更新:v{v}",update_downloading:"正在下载更新…应用将重启。",update_failed:"更新失败",confirm_update:"下载并安装更新?应用将重启。",error_update_check:"检查更新失败:",error_update:"更新失败:",notif_updating:"正在安装更新…",ui_scale:"界面缩放",ui_scale_desc:"缩放整个界面。可配合窗口调整大小或 F11 全屏使用。",theme:"主题",theme_dark:"深色",theme_light:"浅色",language:"语言",save:"保存",reset:"重置为默认",language_en:"英语",language_ru:"俄语",language_zh:"中文",copied:"已复制",header_room:"房间",header_vip:"VIP",header_path:"路径",header_peers:"节点",dismiss_error:"关闭",field_required:"必填",notif_created:"网络已创建: {name}",notif_joined:"已加入网络: {name}",notif_left:"已离开网络",notif_removed:"已删除: {name}",notif_deleted:"网络已删除: {name}",notif_connected:"已连接到 {addr}",notif_disconnected:"已断开连接",notif_settings_saved:"设置已保存",notif_reconnect_required:"请重新连接以使代理 / STUN / 令牌生效",notif_auto_join_skipped:"已跳过自动加入「{name}」— 请输入密码后手动加入",notif_need_config:"请先在连接页面设置服务器和昵称",notif_room_deleted:"网络已被所有者删除",invite_no_password:"邀请已复制但无密码(密码不存储)。分享前请自行添加。",error_create:"创建网络失败: {err}",error_join:"加入失败: {err}",error_leave:"离开失败: {err}",error_remove:"删除失败: {err}",error_connect:"连接失败: {err}",error_disconnect:"错误: {err}",error_send:"发送失败: {err}",error_not_connected:"未连接 — 无法发送消息",error_invalid_invite:"无效邀请:需要服务器和房间名",error_save:"保存设置失败: {err}",confirm_disconnect:"确定断开服务器连接?",confirm_leave:"离开当前网络?仍保留在已保存列表中。",confirm_leave_remove:"离开并从已保存列表中移除?",confirm_remove:'从已保存网络中移除 "{name}"?(不会删除他人的网络)',confirm_delete:'永久删除网络 "{name}"(对所有人)?',confirm_reset:"确定重置所有设置?"},Ql={en:Kl,ru:Zi,zh:$i};function xi(){const t=localStorage.getItem("entangled_locale");if(t&&Ql[t])return t;const e=navigator.language?.slice(0,2);return e==="ru"?"ru":e==="zh"?"zh":"en"}const Zl=Ge(xi()),ft=Ji(Zl,t=>{const e=Ql[t]||Kl;return new Proxy(e,{get(n,i){if(typeof i=="string")return n[i]??Kl[i]??i}})});function $t(t){Ql[t]&&(localStorage.setItem("entangled_locale",t),Zl.set(t))}function se(t,e){return t?String(t).replace(/\{(\w+)\}/g,(n,i)=>e&&e[i]!=null?e[i]:`{${i}}`):""}typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(Vi);function eo(t,e){return t?.reconnecting?"reconnecting":t?.connected?(e||[]).some(o=>o.connected&&(o.path==="relay"||o.path==="ws"))?"relay":"direct":"disconnected"}function zs(t,e,n){const i=t.slice();return i[60]=e[n],i}function Js(t){let e,n,i=t[15].no_networks+"",o,r,a,_=t[15].no_networks_desc+"",u,d;return{c(){e=c("div"),n=c("div"),o=h(i),r=m(),a=c("div"),u=h(_),d=m(),s(a,"class","empty-desc svelte-4t8g6m"),s(e,"class","empty-state svelte-4t8g6m")},m(f,p){B(f,e,p),l(e,n),l(n,o),l(e,r),l(e,a),l(a,u),l(e,d)},p(f,p){p[0]&32768&&i!==(i=f[15].no_networks+"")&&w(o,i),p[0]&32768&&_!==(_=f[15].no_networks_desc+"")&&w(u,_)},d(f){f&&z(e)}}}function to(t){let e=t[15].saved+"",n;return{c(){n=h(e)},m(i,o){B(i,n,o)},p(i,o){o[0]&32768&&e!==(e=i[15].saved+"")&&w(n,e)},d(i){i&&z(n)}}}function no(t){let e=t[15].offline_click+"",n;return{c(){n=h(e)},m(i,o){B(i,n,o)},p(i,o){o[0]&32768&&e!==(e=i[15].offline_click+"")&&w(n,e)},d(i){i&&z(n)}}}function lo(t){let e=se(t[15].peer_count,{n:t[16].peerCount})+"",n;return{c(){n=h(e)},m(i,o){B(i,n,o)},p(i,o){o[0]&98304&&e!==(e=se(i[15].peer_count,{n:i[16].peerCount})+"")&&w(n,e)},d(i){i&&z(n)}}}function so(t){let e=t[15].connecting+"",n;return{c(){n=h(e)},m(i,o){B(i,n,o)},p(i,o){o[0]&32768&&e!==(e=i[15].connecting+"")&&w(n,e)},d(i){i&&z(n)}}}function Bs(t){let e,n,i=t[15].copy_invite+"",o,r,a,_,u=t[15].remove+"",d,f,p,v;function b(...y){return t[38](t[60],...y)}let g=t[16].room===t[60].name&&Gs(t);function L(...y){return t[40](t[60],...y)}let j=t[16].room===t[60].name&&t[16].isOwner&&Hs(t);return{c(){e=c("div"),n=c("button"),o=h(i),r=m(),g&&g.c(),a=m(),_=c("button"),d=h(u),f=m(),j&&j.c(),s(n,"type","button"),s(n,"role","menuitem"),s(n,"class","menu-item svelte-4t8g6m"),s(_,"type","button"),s(_,"role","menuitem"),s(_,"class","menu-item danger svelte-4t8g6m"),s(e,"class","overflow-menu svelte-4t8g6m"),s(e,"role","menu"),s(e,"tabindex","-1")},m(y,k){B(y,e,k),l(e,n),l(n,o),l(e,r),g&&g.m(e,null),l(e,a),l(e,_),l(_,d),l(e,f),j&&j.m(e,null),p||(v=[V(n,"click",b),V(_,"click",L),V(e,"click",Ut(t[35])),V(e,"keydown",Ut(t[36]))],p=!0)},p(y,k){t=y,k[0]&32768&&i!==(i=t[15].copy_invite+"")&&w(o,i),t[16].room===t[60].name?g?g.p(t,k):(g=Gs(t),g.c(),g.m(e,a)):g&&(g.d(1),g=null),k[0]&32768&&u!==(u=t[15].remove+"")&&w(d,u),t[16].room===t[60].name&&t[16].isOwner?j?j.p(t,k):(j=Hs(t),j.c(),j.m(e,null)):j&&(j.d(1),j=null)},d(y){y&&z(e),g&&g.d(),j&&j.d(),p=!1,Pe(v)}}}function Gs(t){let e,n=t[15].leave+"",i,o,r;return{c(){e=c("button"),i=h(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item svelte-4t8g6m")},m(a,_){B(a,e,_),l(e,i),o||(r=V(e,"click",t[39]),o=!0)},p(a,_){_[0]&32768&&n!==(n=a[15].leave+"")&&w(i,n)},d(a){a&&z(e),o=!1,r()}}}function Hs(t){let e,n=t[15].delete_room+"",i,o,r;function a(..._){return t[41](t[60],..._)}return{c(){e=c("button"),i=h(n),s(e,"type","button"),s(e,"role","menuitem"),s(e,"class","menu-item danger svelte-4t8g6m")},m(_,u){B(_,e,u),l(e,i),o||(r=V(e,"click",a),o=!0)},p(_,u){t=_,u[0]&32768&&n!==(n=t[15].delete_room+"")&&w(i,n)},d(_){_&&z(e),o=!1,r()}}}function Ys(t,e){let n,i,o,r,a,_=e[60].name+"",u,d,f,p,v,b,g,L,j,y,k,q,M,K,E,W,J,S,A;function G(P,N){return P[11]===P[60].name?so:P[16].room===P[60].name?lo:P[16].connected?to:no}let F=G(e),U=F(e);function Q(...P){return e[37](e[60],...P)}let C=e[12]===e[60].name&&Bs(e);function T(){return e[42](e[60])}function Z(...P){return e[43](e[60],...P)}return{key:t,first:null,c(){n=c("div"),i=c("div"),o=m(),r=c("div"),a=c("div"),u=h(_),d=m(),f=c("div"),U.c(),p=m(),v=c("div"),b=c("button"),g=Ke("svg"),L=Ke("circle"),j=Ke("circle"),y=Ke("circle"),K=m(),C&&C.c(),E=m(),s(i,"class","network-indicator svelte-4t8g6m"),s(i,"aria-hidden","true"),qe(i,"active-dot",e[16].room===e[60].name),s(a,"class","network-name svelte-4t8g6m"),s(f,"class","network-meta svelte-4t8g6m"),s(r,"class","network-info svelte-4t8g6m"),s(L,"cx","8"),s(L,"cy","3.5"),s(L,"r","1.25"),s(L,"fill","currentColor"),s(j,"cx","8"),s(j,"cy","8"),s(j,"r","1.25"),s(j,"fill","currentColor"),s(y,"cx","8"),s(y,"cy","12.5"),s(y,"r","1.25"),s(y,"fill","currentColor"),s(g,"width","16"),s(g,"height","16"),s(g,"viewBox","0 0 16 16"),s(g,"aria-hidden","true"),s(b,"type","button"),s(b,"class","menu-btn svelte-4t8g6m"),s(b,"aria-haspopup","menu"),s(b,"aria-expanded",k=e[12]===e[60].name),s(b,"aria-label",q=e[15].more_actions),s(b,"title",M=e[15].more_actions),s(v,"class","row-actions svelte-4t8g6m"),s(n,"class","network-item svelte-4t8g6m"),s(n,"role","button"),s(n,"tabindex","0"),s(n,"aria-current",W=e[16].room===e[60].name?"true":void 0),s(n,"aria-label",J=e[60].name),qe(n,"active",e[16].room===e[60].name),qe(n,"disabled",!e[16].connected&&!e[11]),this.first=n},m(P,N){B(P,n,N),l(n,i),l(n,o),l(n,r),l(r,a),l(a,u),l(r,d),l(r,f),U.m(f,null),l(n,p),l(n,v),l(v,b),l(b,g),l(g,L),l(g,j),l(g,y),l(v,K),C&&C.m(v,null),l(n,E),S||(A=[V(b,"click",Q),V(n,"click",T),V(n,"keydown",Z)],S=!0)},p(P,N){e=P,N[0]&65537&&qe(i,"active-dot",e[16].room===e[60].name),N[0]&1&&_!==(_=e[60].name+"")&&w(u,_),F===(F=G(e))&&U?U.p(e,N):(U.d(1),U=F(e),U&&(U.c(),U.m(f,null))),N[0]&4097&&k!==(k=e[12]===e[60].name)&&s(b,"aria-expanded",k),N[0]&32768&&q!==(q=e[15].more_actions)&&s(b,"aria-label",q),N[0]&32768&&M!==(M=e[15].more_actions)&&s(b,"title",M),e[12]===e[60].name?C?C.p(e,N):(C=Bs(e),C.c(),C.m(v,null)):C&&(C.d(1),C=null),N[0]&65537&&W!==(W=e[16].room===e[60].name?"true":void 0)&&s(n,"aria-current",W),N[0]&1&&J!==(J=e[60].name)&&s(n,"aria-label",J),N[0]&65537&&qe(n,"active",e[16].room===e[60].name),N[0]&67584&&qe(n,"disabled",!e[16].connected&&!e[11])},d(P){P&&z(n),U.d(),C&&C.d(),S=!1,Pe(A)}}}function Xs(t){let e,n,i,o=t[15].create_network+"",r,a,_,u=t[15].network_name+"",d,f,p,v,b,g,L,j,y=t[15].password_opt+"",k,q,M,K,E,W,J,S,A=t[15].cancel+"",G,F,U,Q=t[15].create+"",C,T,Z,P=t[9]&&Qs(t),N=t[7]&&Zs(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),r=h(o),a=m(),_=c("label"),d=h(u),f=m(),p=c("input"),g=m(),P&&P.c(),L=m(),j=c("label"),k=h(y),q=m(),M=c("input"),E=m(),N&&N.c(),W=m(),J=c("div"),S=c("button"),G=h(A),F=m(),U=c("button"),C=h(Q),s(i,"id","create-title"),s(i,"class","svelte-4t8g6m"),s(_,"class","sr-only svelte-4t8g6m"),s(_,"for","create-name"),s(p,"id","create-name"),s(p,"type","text"),s(p,"placeholder",v=t[15].network_name),s(p,"aria-invalid",b=!!t[9]),s(p,"class","svelte-4t8g6m"),qe(p,"invalid",t[9]),s(j,"class","sr-only svelte-4t8g6m"),s(j,"for","create-pass"),s(M,"id","create-pass"),s(M,"type","password"),s(M,"placeholder",K=t[15].password_opt),s(M,"class","svelte-4t8g6m"),s(S,"class","btn svelte-4t8g6m"),s(U,"class","btn primary svelte-4t8g6m"),s(J,"class","modal-actions svelte-4t8g6m"),s(n,"class","modal svelte-4t8g6m"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","create-title"),s(e,"class","modal-overlay svelte-4t8g6m"),s(e,"role","presentation")},m(I,H){B(I,e,H),l(e,n),l(n,i),l(i,r),l(n,a),l(n,_),l(_,d),l(n,f),l(n,p),ne(p,t[3]),l(n,g),P&&P.m(n,null),l(n,L),l(n,j),l(j,k),l(n,q),l(n,M),ne(M,t[4]),l(n,E),N&&N.m(n,null),l(n,W),l(n,J),l(J,S),l(S,G),l(J,F),l(J,U),l(U,C),t[46](n),T||(Z=[V(p,"input",t[44]),V(M,"input",t[45]),V(S,"click",t[18]),V(U,"click",t[21]),V(n,"click",Ut(t[33])),V(n,"keydown",Ut(t[34])),V(e,"click",t[18]),V(e,"keydown",t[47])],T=!0)},p(I,H){H[0]&32768&&o!==(o=I[15].create_network+"")&&w(r,o),H[0]&32768&&u!==(u=I[15].network_name+"")&&w(d,u),H[0]&32768&&v!==(v=I[15].network_name)&&s(p,"placeholder",v),H[0]&512&&b!==(b=!!I[9])&&s(p,"aria-invalid",b),H[0]&8&&p.value!==I[3]&&ne(p,I[3]),H[0]&512&&qe(p,"invalid",I[9]),I[9]?P?P.p(I,H):(P=Qs(I),P.c(),P.m(n,L)):P&&(P.d(1),P=null),H[0]&32768&&y!==(y=I[15].password_opt+"")&&w(k,y),H[0]&32768&&K!==(K=I[15].password_opt)&&s(M,"placeholder",K),H[0]&16&&M.value!==I[4]&&ne(M,I[4]),I[7]?N?N.p(I,H):(N=Zs(I),N.c(),N.m(n,W)):N&&(N.d(1),N=null),H[0]&32768&&A!==(A=I[15].cancel+"")&&w(G,A),H[0]&32768&&Q!==(Q=I[15].create+"")&&w(C,Q)},d(I){I&&z(e),P&&P.d(),N&&N.d(),t[46](null),T=!1,Pe(Z)}}}function Qs(t){let e,n;return{c(){e=c("span"),n=h(t[9]),s(e,"class","field-error svelte-4t8g6m"),s(e,"role","alert")},m(i,o){B(i,e,o),l(e,n)},p(i,o){o[0]&512&&w(n,i[9])},d(i){i&&z(e)}}}function Zs(t){let e,n;return{c(){e=c("div"),n=h(t[7]),s(e,"class","modal-error svelte-4t8g6m"),s(e,"role","alert")},m(i,o){B(i,e,o),l(e,n)},p(i,o){o[0]&128&&w(n,i[7])},d(i){i&&z(e)}}}function $s(t){let e,n,i,o=t[15].join_network+"",r,a,_,u=t[15].network_name+"",d,f,p,v,b,g,L,j,y=t[15].password_opt+"",k,q,M,K,E,W,J,S,A=t[15].cancel+"",G,F,U,Q=t[15].join+"",C,T,Z,P=t[10]&&xs(t),N=t[8]&&ei(t);return{c(){e=c("div"),n=c("div"),i=c("h3"),r=h(o),a=m(),_=c("label"),d=h(u),f=m(),p=c("input"),g=m(),P&&P.c(),L=m(),j=c("label"),k=h(y),q=m(),M=c("input"),E=m(),N&&N.c(),W=m(),J=c("div"),S=c("button"),G=h(A),F=m(),U=c("button"),C=h(Q),s(i,"id","join-title"),s(i,"class","svelte-4t8g6m"),s(_,"class","sr-only svelte-4t8g6m"),s(_,"for","join-name"),s(p,"id","join-name"),s(p,"type","text"),s(p,"placeholder",v=t[15].network_name),s(p,"aria-invalid",b=!!t[10]),s(p,"class","svelte-4t8g6m"),qe(p,"invalid",t[10]),s(j,"class","sr-only svelte-4t8g6m"),s(j,"for","join-pass"),s(M,"id","join-pass"),s(M,"type","password"),s(M,"placeholder",K=t[15].password_opt),s(M,"class","svelte-4t8g6m"),s(S,"class","btn svelte-4t8g6m"),s(U,"class","btn primary svelte-4t8g6m"),s(J,"class","modal-actions svelte-4t8g6m"),s(n,"class","modal svelte-4t8g6m"),s(n,"role","dialog"),s(n,"aria-modal","true"),s(n,"aria-labelledby","join-title"),s(e,"class","modal-overlay svelte-4t8g6m"),s(e,"role","presentation")},m(I,H){B(I,e,H),l(e,n),l(n,i),l(i,r),l(n,a),l(n,_),l(_,d),l(n,f),l(n,p),ne(p,t[5]),l(n,g),P&&P.m(n,null),l(n,L),l(n,j),l(j,k),l(n,q),l(n,M),ne(M,t[6]),l(n,E),N&&N.m(n,null),l(n,W),l(n,J),l(J,S),l(S,G),l(J,F),l(J,U),l(U,C),t[51](n),T||(Z=[V(p,"input",t[48]),V(M,"input",t[49]),V(S,"click",t[20]),V(U,"click",t[50]),V(n,"click",Ut(t[31])),V(n,"keydown",Ut(t[32])),V(e,"click",t[20]),V(e,"keydown",t[52])],T=!0)},p(I,H){H[0]&32768&&o!==(o=I[15].join_network+"")&&w(r,o),H[0]&32768&&u!==(u=I[15].network_name+"")&&w(d,u),H[0]&32768&&v!==(v=I[15].network_name)&&s(p,"placeholder",v),H[0]&1024&&b!==(b=!!I[10])&&s(p,"aria-invalid",b),H[0]&32&&p.value!==I[5]&&ne(p,I[5]),H[0]&1024&&qe(p,"invalid",I[10]),I[10]?P?P.p(I,H):(P=xs(I),P.c(),P.m(n,L)):P&&(P.d(1),P=null),H[0]&32768&&y!==(y=I[15].password_opt+"")&&w(k,y),H[0]&32768&&K!==(K=I[15].password_opt)&&s(M,"placeholder",K),H[0]&64&&M.value!==I[6]&&ne(M,I[6]),I[8]?N?N.p(I,H):(N=ei(I),N.c(),N.m(n,W)):N&&(N.d(1),N=null),H[0]&32768&&A!==(A=I[15].cancel+"")&&w(G,A),H[0]&32768&&Q!==(Q=I[15].join+"")&&w(C,Q)},d(I){I&&z(e),P&&P.d(),N&&N.d(),t[51](null),T=!1,Pe(Z)}}}function xs(t){let e,n;return{c(){e=c("span"),n=h(t[10]),s(e,"class","field-error svelte-4t8g6m"),s(e,"role","alert")},m(i,o){B(i,e,o),l(e,n)},p(i,o){o[0]&1024&&w(n,i[10])},d(i){i&&z(e)}}}function ei(t){let e,n;return{c(){e=c("div"),n=h(t[8]),s(e,"class","modal-error svelte-4t8g6m"),s(e,"role","alert")},m(i,o){B(i,e,o),l(e,n)},p(i,o){o[0]&256&&w(n,i[8])},d(i){i&&z(e)}}}function io(t){let e,n,i,o=t[15].networks+"",r,a,_,u=se(t[15].network_count,{n:t[0].length})+"",d,f,p,v,b=t[15].create_network+"",g,L,j,y,k=t[15].join_network+"",q,M,K,E,W=[],J=new Map,S,A,G,F,U,Q=ut(t[0]);const C=N=>N[60].name;for(let N=0;Nn(15,i=D)),ae(t,Ee,D=>n(55,o=D)),ae(t,De,D=>n(16,r=D));let a=[],_=!1,u=!1,d="",f="",p="",v="",b="",g="",L="",j="",y="",k="",q="",M=null,K,E;on(async()=>{n(0,a=await window.go.main.App.GetSavedRooms());const D=await window.go.main.App.LoadConfig();D.serverAddr&&(y=D.serverAddr),D.nickname&&(k=D.nickname),window.addEventListener("keydown",W),window.addEventListener("click",J)}),Ni(()=>{window.removeEventListener("keydown",W),window.removeEventListener("click",J)});function W(D){if(D.key==="Escape"){if(M){n(12,M=null);return}if(_){G();return}if(u){U();return}}}function J(){n(12,M=null)}async function S(){n(0,a=await window.go.main.App.GetSavedRooms())}function A(){n(7,b=""),n(9,L=""),n(1,_=!0),ln()}function G(){n(1,_=!1),n(7,b=""),n(9,L="")}function F(){n(8,g=""),n(10,j=""),n(2,u=!0),ln()}function U(){n(2,u=!1),n(8,g=""),n(10,j="")}async function Q(){if(n(9,L=""),n(7,b=""),!d.trim()){n(9,L=i.field_required);return}try{await window.go.main.App.CreateRoom(d,f),ee(se(i.notif_created,{name:d})),nt(Ee,o="network",o),G(),n(3,d=""),n(4,f=""),await S()}catch(D){n(7,b=se(i.error_create,{err:D})),ee(b,"error")}}async function C(D,x){n(10,j=""),n(8,g="");const Ne=D||p,pe=x!==void 0?x:v;if(!Ne.trim()){n(10,j=i.field_required);return}try{await window.go.main.App.JoinRoom(Ne,pe),ee(se(i.notif_joined,{name:Ne})),nt(Ee,o="network",o),U(),n(5,p=""),n(6,v=""),await S()}catch($){n(8,g=se(i.error_join,{err:$})),ee(g,"error"),u||(n(5,p=Ne),n(6,v=""),n(2,u=!0))}}async function T(){if(confirm(i.confirm_leave))try{await window.go.main.App.LeaveRoom(),ee(i.notif_left),await S()}catch(D){ee(se(i.error_leave,{err:D}),"error")}}async function Z(D){const x=r.room===D;if(x){if(!confirm(i.confirm_leave_remove))return}else if(!confirm(se(i.confirm_remove,{name:D})))return;try{x&&await window.go.main.App.LeaveRoom(),await window.go.main.App.RemoveSavedRoom(D),ee(se(i.notif_removed,{name:D})),await S()}catch(Ne){ee(se(i.error_remove,{err:Ne}),"error")}}async function P(D){if(confirm(se(i.confirm_delete,{name:D})))try{await window.go.main.App.DeleteRoom(D),await window.go.main.App.RemoveSavedRoom(D),ee(se(i.notif_deleted,{name:D})),await S()}catch(x){ee(String(x),"error")}}async function N(D){try{const x=await window.go.main.App.FormatInvite(D.name,D.password||"");await window.go.main.App.CopyText(x);const Ne=String(x).split("|"),pe=Ne.length>=3&&Ne[2]!=="";D.locked&&!pe?ee(i.invite_no_password,"info"):ee(i.invite_copied)}catch(x){ee(String(x),"error")}}async function I(){try{const D=await window.go.main.App.LoadConfig();D.serverAddr&&(y=D.serverAddr),D.nickname&&(k=D.nickname)}catch{}}async function H(D,x,Ne){if(!q){n(11,q=D),n(12,M=null);try{await I();const pe=Ne||y;if(!r.connected){if(!pe||!k){ee(i.notif_need_config,"error"),nt(Ee,o="connect",o);return}const $=await window.go.main.App.Connect(pe,k);De.set($),await S()}await window.go.main.App.JoinRoom(D,x||""),nt(Ee,o="network",o),await S()}catch(pe){const $=se(i.error_join,{err:pe});ee($,"error"),n(5,p=D),n(6,v=""),n(8,g=$),n(2,u=!0)}finally{n(11,q="")}}}function ve(D,x){(D.key==="Enter"||D.key===" ")&&(D.preventDefault(),H(x.name,x.password,x.server))}function le(D,x){D.stopPropagation(),n(12,M=M===x?null:x)}function me(D,x){D.stopPropagation(),n(12,M=null),x()}function de(D){It.call(this,t,D)}function Ae(D){It.call(this,t,D)}function je(D){It.call(this,t,D)}function ye(D){It.call(this,t,D)}function ue(D){It.call(this,t,D)}function ke(D){It.call(this,t,D)}const Se=(D,x)=>le(x,D.name),fe=(D,x)=>me(x,()=>N(D)),we=D=>me(D,T),ie=(D,x)=>me(x,()=>Z(D.name)),Ce=(D,x)=>me(x,()=>P(D.name)),he=D=>H(D.name,D.password,D.server),be=(D,x)=>ve(x,D);function _e(){d=this.value,n(3,d)}function oe(){f=this.value,n(4,f)}function te(D){Wt[D?"unshift":"push"](()=>{K=D,n(13,K)})}const R=D=>D.key==="Escape"&&G();function X(){p=this.value,n(5,p)}function lt(){v=this.value,n(6,v)}const xe=()=>C();function re(D){Wt[D?"unshift":"push"](()=>{E=D,n(14,E)})}return[a,_,u,d,f,p,v,b,g,L,j,q,M,K,E,i,r,A,G,F,U,Q,C,T,Z,P,N,H,ve,le,me,de,Ae,je,ye,ue,ke,Se,fe,we,ie,Ce,he,be,_e,oe,te,R,X,lt,xe,re,D=>D.key==="Escape"&&U()]}class ro extends dt{constructor(e){super(),_t(this,e,oo,io,$e,{},null,[-1,-1,-1])}}function ti(t,e,n){const i=t.slice();return i[22]=e[n],i}function ni(t){let e,n=t[4].chat+"",i,o,r,a,_,u=t[2]>0&&li(t);return{c(){e=c("button"),i=h(n),o=m(),u&&u.c(),s(e,"class","room-chat-btn svelte-s8897d"),s(e,"title",r=t[4].room_chat)},m(d,f){B(d,e,f),l(e,i),l(e,o),u&&u.m(e,null),a||(_=V(e,"click",t[7]),a=!0)},p(d,f){f&16&&n!==(n=d[4].chat+"")&&w(i,n),d[2]>0?u?u.p(d,f):(u=li(d),u.c(),u.m(e,null)):u&&(u.d(1),u=null),f&16&&r!==(r=d[4].room_chat)&&s(e,"title",r)},d(d){d&&z(e),u&&u.d(),a=!1,_()}}}function li(t){let e,n;return{c(){e=c("span"),n=h(t[2]),s(e,"class","badge unread-badge svelte-s8897d")},m(i,o){B(i,e,o),l(e,n)},p(i,o){o&4&&w(n,i[2])},d(i){i&&z(e)}}}function si(t){let e,n,i=t[4].no_peers+"",o,r,a,_=t[4].no_peers_desc+"",u,d;return{c(){e=c("div"),n=c("div"),o=h(i),r=m(),a=c("div"),u=h(_),d=m(),s(n,"class","empty-label svelte-s8897d"),s(a,"class","empty-desc svelte-s8897d"),s(e,"class","empty-peers svelte-s8897d")},m(f,p){B(f,e,p),l(e,n),l(n,o),l(e,r),l(e,a),l(a,u),l(e,d)},p(f,p){p&16&&i!==(i=f[4].no_peers+"")&&w(o,i),p&16&&_!==(_=f[4].no_peers_desc+"")&&w(u,_)},d(f){f&&z(e)}}}function ii(t){let e,n=t[10](t[22].id)+"",i;return{c(){e=c("span"),i=h(n),s(e,"class","badge unread-badge svelte-s8897d")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&8&&n!==(n=o[10](o[22].id)+"")&&w(i,n)},d(o){o&&z(e)}}}function ao(t){let e;return{c(){e=h("...")},m(n,i){B(n,e,i)},p:ce,d(n){n&&z(e)}}}function co(t){let e=t[22].ping+"",n,i;return{c(){n=h(e),i=h("ms")},m(o,r){B(o,n,r),B(o,i,r)},p(o,r){r&8&&e!==(e=o[22].ping+"")&&w(n,e)},d(o){o&&(z(n),z(i))}}}function uo(t){let e;return{c(){e=h("-")},m(n,i){B(n,e,i)},p:ce,d(n){n&&z(e)}}}function _o(t){let e=t[4].path_unknown+"",n;return{c(){n=h(e)},m(i,o){B(i,n,o)},p(i,o){o&16&&e!==(e=i[4].path_unknown+"")&&w(n,e)},d(i){i&&z(n)}}}function fo(t){let e,n,i,o=t[11](t[22].path)+"",r;return{c(){e=c("span"),i=m(),r=h(o),s(e,"class",n="path-dot "+ri(t[22].path)+" svelte-s8897d"),s(e,"aria-hidden","true")},m(a,_){B(a,e,_),B(a,i,_),B(a,r,_)},p(a,_){_&8&&n!==(n="path-dot "+ri(a[22].path)+" svelte-s8897d")&&s(e,"class",n),_&8&&o!==(o=a[11](a[22].path)+"")&&w(r,o)},d(a){a&&(z(e),z(i),z(r))}}}function oi(t,e){let n,i,o,r,a,_,u=(e[22].connected?e[4].status_online:e[4].status_offline)+"",d,f,p,v,b=(e[22].nickname||e[22].id)+"",g,L,j=e[10](e[22].id)>0,y,k,q=(e[22].virtualIP||e[4].na)+"",M,K,E,W,J,S,A,G,F,U,Q,C,T,Z,P,N,I,H,ve,le,me,de,Ae,je,ye,ue=j&&ii(e);function ke(){return e[18](e[22])}function Se(...te){return e[19](e[22],...te)}function fe(te,R){return te[22].connected?te[22].ping>=0&&!te[1][te[22].id]?co:ao:uo}let we=fe(e),ie=we(e);function Ce(te,R){return te[22].path?fo:_o}let he=Ce(e),be=he(e);function _e(){return e[20](e[22])}function oe(){return e[21](e[22])}return{key:t,first:null,c(){n=c("div"),i=c("span"),o=c("span"),a=m(),_=c("span"),d=h(u),f=m(),p=c("span"),v=c("span"),g=h(b),L=m(),ue&&ue.c(),y=m(),k=c("span"),M=h(q),K=m(),E=c("span"),ie.c(),W=m(),J=c("span"),be.c(),A=m(),G=c("span"),F=c("button"),U=Ke("svg"),Q=Ke("circle"),C=Ke("circle"),T=Ke("circle"),I=m(),H=c("button"),ve=Ke("svg"),le=Ke("path"),Ae=m(),s(o,"class",r="sq "+(e[22].connected?"sq-online":"sq-offline")+" svelte-s8897d"),s(o,"aria-hidden","true"),s(_,"class","status-text svelte-s8897d"),s(i,"class","status-cell svelte-s8897d"),s(i,"role","cell"),s(v,"class","nickname svelte-s8897d"),s(p,"class","col-name"),s(p,"role","cell"),s(k,"class","col-ip clickable svelte-s8897d"),s(k,"role","button"),s(k,"tabindex","0"),s(E,"class","col-ping svelte-s8897d"),s(E,"role","cell"),qe(E,"probing",e[22].connected&&(e[22].ping<0||e[1][e[22].id])),s(J,"class","col-path svelte-s8897d"),s(J,"role","cell"),s(J,"title",S=e[12](e[22].path)),s(Q,"cx","8"),s(Q,"cy","8"),s(Q,"r","1.6"),s(Q,"fill","currentColor"),s(C,"cx","8"),s(C,"cy","8"),s(C,"r","4.2"),s(C,"fill","none"),s(C,"stroke","currentColor"),s(C,"stroke-width","1.2"),s(T,"cx","8"),s(T,"cy","8"),s(T,"r","6.4"),s(T,"fill","none"),s(T,"stroke","currentColor"),s(T,"stroke-width","1.1"),s(T,"opacity","0.55"),s(U,"width","14"),s(U,"height","14"),s(U,"viewBox","0 0 16 16"),s(U,"aria-hidden","true"),s(F,"class","row-btn svelte-s8897d"),F.disabled=Z=!e[22].connected||!!e[1][e[22].id],s(F,"title",P=e[4].ping_peer),s(F,"aria-label",N=e[4].ping_peer),s(le,"d","M3 4.5h10v6.5H7.2L4 13.5V11H3z"),s(le,"fill","none"),s(le,"stroke","currentColor"),s(le,"stroke-width","1.2"),s(le,"stroke-linejoin","round"),s(ve,"width","14"),s(ve,"height","14"),s(ve,"viewBox","0 0 16 16"),s(ve,"aria-hidden","true"),s(H,"class","row-btn svelte-s8897d"),s(H,"title",me=e[4].chat+" "+(e[22].nickname||e[22].id)),s(H,"aria-label",de=e[4].chat+" "+(e[22].nickname||e[22].id)),s(G,"class","col-action svelte-s8897d"),s(G,"role","cell"),s(n,"class","table-row svelte-s8897d"),s(n,"role","row"),this.first=n},m(te,R){B(te,n,R),l(n,i),l(i,o),l(i,a),l(i,_),l(_,d),l(n,f),l(n,p),l(p,v),l(v,g),l(p,L),ue&&ue.m(p,null),l(n,y),l(n,k),l(k,M),l(n,K),l(n,E),ie.m(E,null),l(n,W),l(n,J),be.m(J,null),l(n,A),l(n,G),l(G,F),l(F,U),l(U,Q),l(U,C),l(U,T),l(G,I),l(G,H),l(H,ve),l(ve,le),l(n,Ae),je||(ye=[V(k,"click",ke),V(k,"keydown",Se),V(F,"click",_e),V(H,"click",oe)],je=!0)},p(te,R){e=te,R&8&&r!==(r="sq "+(e[22].connected?"sq-online":"sq-offline")+" svelte-s8897d")&&s(o,"class",r),R&24&&u!==(u=(e[22].connected?e[4].status_online:e[4].status_offline)+"")&&w(d,u),R&8&&b!==(b=(e[22].nickname||e[22].id)+"")&&w(g,b),R&8&&(j=e[10](e[22].id)>0),j?ue?ue.p(e,R):(ue=ii(e),ue.c(),ue.m(p,null)):ue&&(ue.d(1),ue=null),R&24&&q!==(q=(e[22].virtualIP||e[4].na)+"")&&w(M,q),we===(we=fe(e))&&ie?ie.p(e,R):(ie.d(1),ie=we(e),ie&&(ie.c(),ie.m(E,null))),R&10&&qe(E,"probing",e[22].connected&&(e[22].ping<0||e[1][e[22].id])),he===(he=Ce(e))&&be?be.p(e,R):(be.d(1),be=he(e),be&&(be.c(),be.m(J,null))),R&8&&S!==(S=e[12](e[22].path))&&s(J,"title",S),R&10&&Z!==(Z=!e[22].connected||!!e[1][e[22].id])&&(F.disabled=Z),R&16&&P!==(P=e[4].ping_peer)&&s(F,"title",P),R&16&&N!==(N=e[4].ping_peer)&&s(F,"aria-label",N),R&24&&me!==(me=e[4].chat+" "+(e[22].nickname||e[22].id))&&s(H,"title",me),R&24&&de!==(de=e[4].chat+" "+(e[22].nickname||e[22].id))&&s(H,"aria-label",de)},d(te){te&&z(n),ue&&ue.d(),ie.d(),be.d(),je=!1,Pe(ye)}}}function po(t){let e,n,i,o=t[4].header_peers+"",r,a,_,u,d,f,p,v,b,g=t[4].col_nickname+"",L,j,y,k=t[4].col_ip+"",q,M,K,E=t[4].col_ping+"",W,J,S,A=t[4].col_path+"",G,F,U,Q,C,T,Z,P,N,I=t[4].status_online+"",H,ve,le,me,de=(t[5].nickname||t[4].you)+"",Ae,je,ye,ue=t[4].me+"",ke,Se,fe,we=(t[0].virtualIP||t[4].na)+"",ie,Ce,he,be,_e,oe,te,R,X=[],lt=new Map,xe,re,st,D=t[0].room&&ni(t),x=ut(t[3]);const Ne=$=>$[22].id;for(let $=0;$n(4,r=S)),ae(t,Yl,S=>n(14,a=S)),ae(t,De,S=>n(0,_=S)),ae(t,Ml,S=>n(15,u=S)),ae(t,Ve,S=>n(5,d=S));let f={};function p(S){nn.set({id:S.id,nickname:S.nickname||S.id}),Fl("peer:"+S.id),Ee.set("chat")}function v(){nn.set(null),Fl("room:"+(_.room||"network")),Ee.set("chat")}async function b(S){if(S)try{await window.go.main.App.CopyText(S),ee(r.copied)}catch{}}async function g(S){if(!(!S?.id||!S.connected||f[S.id])){n(1,f={...f,[S.id]:!0});try{await window.go.main.App.PingPeer(S.id),ee(se(r.ping_sent,{name:S.nickname||S.id}))}catch(A){ee(se(r.error_ping,{err:A}),"error")}finally{setTimeout(()=>{const A={...f};delete A[S.id],n(1,f=A)},800)}}}function L(S){return a["peer:"+S]||0}function j(S){return S==="p2p"?r.path_p2p:S==="relay"?r.path_relay:S==="ws"?r.path_ws:r.path_unknown}function y(S){return S==="p2p"?r.path_p2p_tip:S==="relay"?r.path_relay_tip:S==="ws"?r.path_ws_tip:""}function k(S,A){(S.key==="Enter"||S.key===" ")&&(S.preventDefault(),b(A))}const q=()=>b(_.virtualIP),M=S=>k(S,_.virtualIP),K=S=>b(S.virtualIP),E=(S,A)=>k(A,S.virtualIP),W=S=>g(S),J=S=>p(S);return t.$$.update=()=>{t.$$.dirty&32768&&n(3,i=[...u].sort((S,A)=>(S.nickname||"").localeCompare(A.nickname||""))),t.$$.dirty&16385&&n(2,o=a["room:"+(_.room||"network")]||0)},[_,f,o,i,r,d,p,v,b,g,L,j,y,k,a,u,q,M,K,E,W,J]}class mo extends dt{constructor(e){super(),_t(this,e,vo,po,$e,{})}}function ai(t){let e,n=t[2].status_reconnecting+"",i;return{c(){e=c("span"),i=h(n),s(e,"class","hint-fault svelte-3s78ew")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&4&&n!==(n=o[2].status_reconnecting+"")&&w(i,n)},d(o){o&&z(e)}}}function ci(t){let e,n=se(t[2].status_server,{s:t[3].server})+"",i,o;return{c(){e=c("span"),i=h(n),s(e,"class","status-item status-server svelte-3s78ew"),s(e,"title",o=t[3].server)},m(r,a){B(r,e,a),l(e,i)},p(r,a){a&12&&n!==(n=se(r[2].status_server,{s:r[3].server})+"")&&w(i,n),a&8&&o!==(o=r[3].server)&&s(e,"title",o)},d(r){r&&z(e)}}}function ho(t){let e,n,i,o,r,a,_=se(t[2].version,{v:t[1]})+"",u,d=t[0]==="reconnecting"&&ai(t),f=t[3].server&&ci(t);return{c(){e=c("footer"),n=c("div"),d&&d.c(),i=m(),o=c("div"),f&&f.c(),r=m(),a=c("span"),u=h(_),s(n,"class","status-left svelte-3s78ew"),s(a,"class","status-item status-ver svelte-3s78ew"),s(o,"class","status-right svelte-3s78ew"),s(e,"class","statusbar svelte-3s78ew"),s(e,"role","status"),s(e,"aria-live","polite")},m(p,v){B(p,e,v),l(e,n),d&&d.m(n,null),l(e,i),l(e,o),f&&f.m(o,null),l(o,r),l(o,a),l(a,u)},p(p,[v]){p[0]==="reconnecting"?d?d.p(p,v):(d=ai(p),d.c(),d.m(n,null)):d&&(d.d(1),d=null),p[3].server?f?f.p(p,v):(f=ci(p),f.c(),f.m(o,r)):f&&(f.d(1),f=null),v&6&&_!==(_=se(p[2].version,{v:p[1]})+"")&&w(u,_)},i:ce,o:ce,d(p){p&&z(e),d&&d.d(),f&&f.d()}}}function go(t,e,n){let i,o;ae(t,ft,_=>n(2,i=_)),ae(t,De,_=>n(3,o=_));let{pathAggregate:r="disconnected"}=e,a="1.0.0";return on(async()=>{try{window.go?.main?.App?.GetVersion&&n(1,a=await window.go.main.App.GetVersion())}catch{}}),t.$$set=_=>{"pathAggregate"in _&&n(0,r=_.pathAggregate)},[r,a,i,o]}class ko extends dt{constructor(e){super(),_t(this,e,go,ho,$e,{pathAggregate:0})}}function wo(t){let e,n,i,o,r=t[0].server+"",a,_,u,d=t[1].server+"",f,p,v,b,g=t[0].virtual_ip+"",L,j,y,k=(t[1].virtualIP||t[0].na)+"",q,M,K,E=t[0].disconnect+"",W,J,S;function A(U,Q){return U[1].reconnecting?So:yo}let G=A(t),F=G(t);return{c(){e=c("div"),F.c(),n=m(),i=c("div"),o=c("span"),a=h(r),_=m(),u=c("span"),f=h(d),p=m(),v=c("div"),b=c("span"),L=h(g),j=m(),y=c("span"),q=h(k),M=m(),K=c("button"),W=h(E),s(u,"class","info-value svelte-1br9j49"),s(i,"class","info-line svelte-1br9j49"),s(y,"class","info-value svelte-1br9j49"),s(v,"class","info-line svelte-1br9j49"),s(K,"class","disconnect-btn svelte-1br9j49"),s(e,"class","connected-info svelte-1br9j49")},m(U,Q){B(U,e,Q),F.m(e,null),l(e,n),l(e,i),l(i,o),l(o,a),l(i,_),l(i,u),l(u,f),l(e,p),l(e,v),l(v,b),l(b,L),l(v,j),l(v,y),l(y,q),l(e,M),l(e,K),l(K,W),J||(S=V(K,"click",t[12]),J=!0)},p(U,Q){G===(G=A(U))&&F?F.p(U,Q):(F.d(1),F=G(U),F&&(F.c(),F.m(e,n))),Q&1&&r!==(r=U[0].server+"")&&w(a,r),Q&2&&d!==(d=U[1].server+"")&&w(f,d),Q&1&&g!==(g=U[0].virtual_ip+"")&&w(L,g),Q&3&&k!==(k=(U[1].virtualIP||U[0].na)+"")&&w(q,k),Q&1&&E!==(E=U[0].disconnect+"")&&w(W,E)},d(U){U&&z(e),F.d(),J=!1,S()}}}function bo(t){let e,n,i,o=t[0].brand+"",r,a,_,u=t[0].tagline+"",d,f,p,v,b=t[0].server_addr+"",g,L,j,y,k,q,M,K,E,W=t[0].nickname+"",J,S,A,G,F,U,Q,C,T=(t[5]?t[0].connecting:t[0].connect)+"",Z,P,N,I,H,ve=t[0].paste_invite+"",le,me,de,Ae,je=t[0].paste_invite+"",ye,ue,ke,Se,fe,we,ie=t[0].join+"",Ce,he,be,_e=t[7].serverAddr&&ui(t),oe=t[7].nickname&&_i(t),te=(t[5]||t[1].phase==="dialing"||t[1].phase==="auth")&&di(t);return{c(){e=c("div"),n=c("div"),i=c("h1"),r=h(o),a=m(),_=c("p"),d=h(u),f=m(),p=c("div"),v=c("label"),g=h(b),L=m(),j=c("input"),q=m(),_e&&_e.c(),M=m(),K=c("div"),E=c("label"),J=h(W),S=m(),A=c("input"),U=m(),oe&&oe.c(),Q=m(),C=c("button"),Z=h(T),P=m(),te&&te.c(),N=m(),I=c("details"),H=c("summary"),le=h(ve),me=m(),de=c("div"),Ae=c("label"),ye=h(je),ue=m(),ke=c("input"),fe=m(),we=c("button"),Ce=h(ie),s(i,"class","brand svelte-1br9j49"),s(_,"class","tagline svelte-1br9j49"),s(n,"class","brand-block svelte-1br9j49"),s(v,"for","server-input"),s(v,"class","svelte-1br9j49"),s(j,"id","server-input"),s(j,"type","text"),s(j,"placeholder","host:8080"),s(j,"aria-invalid",y=!!t[7].serverAddr),s(j,"aria-describedby",k=t[7].serverAddr?"server-err":void 0),s(j,"class","svelte-1br9j49"),qe(j,"invalid",t[7].serverAddr),s(p,"class","field svelte-1br9j49"),s(E,"for","nick-input"),s(E,"class","svelte-1br9j49"),s(A,"id","nick-input"),s(A,"type","text"),s(A,"placeholder","Player"),s(A,"aria-invalid",G=!!t[7].nickname),s(A,"aria-describedby",F=t[7].nickname?"nick-err":void 0),s(A,"class","svelte-1br9j49"),qe(A,"invalid",t[7].nickname),s(K,"class","field svelte-1br9j49"),s(C,"class","connect-btn svelte-1br9j49"),C.disabled=t[5],s(H,"class","svelte-1br9j49"),s(Ae,"for","invite-input"),s(Ae,"class","sr-only svelte-1br9j49"),s(ke,"id","invite-input"),s(ke,"type","text"),s(ke,"placeholder",Se=t[0].invite_placeholder),s(ke,"class","svelte-1br9j49"),s(we,"class","secondary-btn svelte-1br9j49"),we.disabled=t[5],s(de,"class","invite-block svelte-1br9j49"),s(I,"class","invite-disclosure svelte-1br9j49"),s(e,"class","connect-form svelte-1br9j49")},m(R,X){B(R,e,X),l(e,n),l(n,i),l(i,r),l(n,a),l(n,_),l(_,d),l(e,f),l(e,p),l(p,v),l(v,g),l(p,L),l(p,j),ne(j,t[2]),l(p,q),_e&&_e.m(p,null),l(e,M),l(e,K),l(K,E),l(E,J),l(K,S),l(K,A),ne(A,t[3]),l(K,U),oe&&oe.m(K,null),l(e,Q),l(e,C),l(C,Z),l(e,P),te&&te.m(e,null),l(e,N),l(e,I),l(I,H),l(H,le),l(I,me),l(I,de),l(de,Ae),l(Ae,ye),l(de,ue),l(de,ke),ne(ke,t[4]),l(de,fe),l(de,we),l(we,Ce),I.open=t[6],he||(be=[V(j,"input",t[13]),V(A,"input",t[14]),V(A,"keydown",t[11]),V(C,"click",t[9]),V(ke,"input",t[15]),V(we,"click",t[10]),V(I,"toggle",t[16])],he=!0)},p(R,X){X&1&&o!==(o=R[0].brand+"")&&w(r,o),X&1&&u!==(u=R[0].tagline+"")&&w(d,u),X&1&&b!==(b=R[0].server_addr+"")&&w(g,b),X&128&&y!==(y=!!R[7].serverAddr)&&s(j,"aria-invalid",y),X&128&&k!==(k=R[7].serverAddr?"server-err":void 0)&&s(j,"aria-describedby",k),X&4&&j.value!==R[2]&&ne(j,R[2]),X&128&&qe(j,"invalid",R[7].serverAddr),R[7].serverAddr?_e?_e.p(R,X):(_e=ui(R),_e.c(),_e.m(p,null)):_e&&(_e.d(1),_e=null),X&1&&W!==(W=R[0].nickname+"")&&w(J,W),X&128&&G!==(G=!!R[7].nickname)&&s(A,"aria-invalid",G),X&128&&F!==(F=R[7].nickname?"nick-err":void 0)&&s(A,"aria-describedby",F),X&8&&A.value!==R[3]&&ne(A,R[3]),X&128&&qe(A,"invalid",R[7].nickname),R[7].nickname?oe?oe.p(R,X):(oe=_i(R),oe.c(),oe.m(K,null)):oe&&(oe.d(1),oe=null),X&33&&T!==(T=(R[5]?R[0].connecting:R[0].connect)+"")&&w(Z,T),X&32&&(C.disabled=R[5]),R[5]||R[1].phase==="dialing"||R[1].phase==="auth"?te?te.p(R,X):(te=di(R),te.c(),te.m(e,N)):te&&(te.d(1),te=null),X&1&&ve!==(ve=R[0].paste_invite+"")&&w(le,ve),X&1&&je!==(je=R[0].paste_invite+"")&&w(ye,je),X&1&&Se!==(Se=R[0].invite_placeholder)&&s(ke,"placeholder",Se),X&16&&ke.value!==R[4]&&ne(ke,R[4]),X&1&&ie!==(ie=R[0].join+"")&&w(Ce,ie),X&32&&(we.disabled=R[5]),X&64&&(I.open=R[6])},d(R){R&&z(e),_e&&_e.d(),oe&&oe.d(),te&&te.d(),he=!1,Pe(be)}}}function yo(t){let e,n,i,o,r=t[0].connected+"",a;return{c(){e=c("div"),n=c("span"),i=m(),o=c("span"),a=h(r),s(n,"class","sq sq-green svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,u){B(_,e,u),l(e,n),l(e,i),l(e,o),l(o,a)},p(_,u){u&1&&r!==(r=_[0].connected+"")&&w(a,r)},d(_){_&&z(e)}}}function So(t){let e,n,i,o,r=t[0].reconnecting+"",a;return{c(){e=c("div"),n=c("span"),i=m(),o=c("span"),a=h(r),s(n,"class","sq sq-warn svelte-1br9j49"),s(n,"aria-hidden","true"),s(e,"class","connected-line svelte-1br9j49"),s(e,"role","status")},m(_,u){B(_,e,u),l(e,n),l(e,i),l(e,o),l(o,a)},p(_,u){u&1&&r!==(r=_[0].reconnecting+"")&&w(a,r)},d(_){_&&z(e)}}}function ui(t){let e,n=t[7].serverAddr+"",i;return{c(){e=c("span"),i=h(n),s(e,"id","server-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].serverAddr+"")&&w(i,n)},d(o){o&&z(e)}}}function _i(t){let e,n=t[7].nickname+"",i;return{c(){e=c("span"),i=h(n),s(e,"id","nick-err"),s(e,"class","field-error svelte-1br9j49"),s(e,"role","alert")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].nickname+"")&&w(i,n)},d(o){o&&z(e)}}}function di(t){let e,n=(t[8]||t[0].connecting)+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","phase svelte-1br9j49"),s(e,"role","status")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&257&&n!==(n=(o[8]||o[0].connecting)+"")&&w(i,n)},d(o){o&&z(e)}}}function qo(t){let e;function n(r,a){return r[1].connected?wo:bo}let i=n(t),o=i(t);return{c(){e=c("div"),o.c(),s(e,"class","connect-view svelte-1br9j49")},m(r,a){B(r,e,a),o.m(e,null)},p(r,[a]){i===(i=n(r))&&o?o.p(r,a):(o.d(1),o=i(r),o&&(o.c(),o.m(e,null)))},i:ce,o:ce,d(r){r&&z(e),o.d()}}}function Ao(t,e,n){let i,o,r,a;ae(t,ft,E=>n(0,o=E)),ae(t,De,E=>n(1,r=E)),ae(t,Ve,E=>n(17,a=E));let _="",u="",d="",f=!1,p=!1,v={};on(async()=>{const E=await window.go.main.App.LoadConfig();E.serverAddr&&n(2,_=E.serverAddr),E.nickname&&n(3,u=E.nickname),E&&Ve.set({...a,...E}),E.autoConnect&&E.serverAddr&&E.nickname&&g()});function b(){const E={};return _.trim()||(E.serverAddr=o.field_required),u.trim()||(E.nickname=o.field_required),n(7,v=E),Object.keys(E).length===0}async function g(){if(!f&&b()){n(5,f=!0),ln();try{const E=await window.go.main.App.Connect(_,u);De.set(E),Ee.set("network"),ee(se(o.notif_connected,{addr:_})),n(7,v={})}catch(E){ee(se(o.error_connect,{err:E}),"error")}finally{n(5,f=!1)}}}async function L(){if(d.trim()){ln();try{const E=await window.go.main.App.ParseInvite(d.trim());if(!E.server||!E.room){ee(o.error_invalid_invite,"error");return}if(n(2,_=E.server),!r.connected){if(!u.trim()){n(7,v={...v,nickname:o.field_required}),ee(o.notif_need_config,"error");return}n(5,f=!0);const W=await window.go.main.App.Connect(_,u);De.set(W),n(5,f=!1)}await window.go.main.App.JoinRoom(E.room,E.password||""),ee(se(o.notif_joined,{name:E.room})),Ee.set("network")}catch(E){ee(se(o.error_join,{err:E}),"error"),n(5,f=!1)}}}function j(E){E.key==="Enter"&&(E.preventDefault(),g())}async function y(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),De.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ee.set("connect"),ee(o.notif_disconnected)}catch(E){ee(se(o.error_disconnect,{err:E}),"error")}}function k(){_=this.value,n(2,_)}function q(){u=this.value,n(3,u)}function M(){d=this.value,n(4,d)}function K(){p=this.open,n(6,p)}return t.$$.update=()=>{t.$$.dirty&3&&n(8,i=r.phase==="dialing"?o.phase_dialing:r.phase==="auth"?o.phase_auth:r.phase==="ready"?o.phase_ready:r.phase==="error"?o.phase_error:"")},[o,r,_,u,d,f,p,v,i,g,L,j,y,k,q,M,K]}class jo extends dt{constructor(e){super(),_t(this,e,Ao,qo,$e,{})}}function fi(t,e,n){const i=t.slice();return i[23]=e[n],i[25]=n,i}function pi(t){let e,n,i=t[0].no_messages+"",o,r,a,_=t[0].no_messages_desc+"",u;return{c(){e=c("div"),n=c("div"),o=h(i),r=m(),a=c("div"),u=h(_),s(n,"class","empty-chat-label svelte-dxth9d"),s(a,"class","empty-chat-desc svelte-dxth9d"),s(e,"class","empty-chat svelte-dxth9d")},m(d,f){B(d,e,f),l(e,n),l(n,o),l(e,r),l(e,a),l(a,u)},p(d,f){f&1&&i!==(i=d[0].no_messages+"")&&w(o,i),f&1&&_!==(_=d[0].no_messages_desc+"")&&w(u,_)},d(d){d&&z(e)}}}function vi(t){let e,n=t[12](t[23].timestamp)+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","date-sep svelte-dxth9d")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[12](o[23].timestamp)+"")&&w(i,n)},d(o){o&&z(e)}}}function Eo(t){let e,n,i,o=(t[23].isSelf?t[6].nickname||t[0].you_self:t[23].nickname)+"",r,a,_,u,d,f=t[23].message+"",p,v,b=t[23].status==="pending"&&mi(),g=t[23].status==="failed"&&hi(t);return{c(){e=c("div"),n=c("div"),i=c("span"),r=h(o),a=m(),b&&b.c(),_=m(),g&&g.c(),u=m(),d=c("div"),p=h(f),v=m(),s(i,"class","msg-nick"),s(n,"class","msg-meta svelte-dxth9d"),s(d,"class","msg-body svelte-dxth9d"),s(e,"class","msg svelte-dxth9d"),qe(e,"self",t[23].isSelf)},m(L,j){B(L,e,j),l(e,n),l(n,i),l(i,r),l(n,a),b&&b.m(n,null),l(n,_),g&&g.m(n,null),l(e,u),l(e,d),l(d,p),l(e,v)},p(L,j){j&193&&o!==(o=(L[23].isSelf?L[6].nickname||L[0].you_self:L[23].nickname)+"")&&w(r,o),L[23].status==="pending"?b||(b=mi(),b.c(),b.m(n,_)):b&&(b.d(1),b=null),L[23].status==="failed"?g?g.p(L,j):(g=hi(L),g.c(),g.m(n,null)):g&&(g.d(1),g=null),j&128&&f!==(f=L[23].message+"")&&w(p,f),j&128&&qe(e,"self",L[23].isSelf)},d(L){L&&z(e),b&&b.d(),g&&g.d()}}}function Co(t){let e,n=t[23].message+"",i;return{c(){e=c("div"),i=h(n),s(e,"class","system-line svelte-dxth9d")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[23].message+"")&&w(i,n)},d(o){o&&z(e)}}}function mi(t){let e;return{c(){e=c("span"),e.textContent="…",s(e,"class","msg-status")},m(n,i){B(n,e,i)},d(n){n&&z(e)}}}function hi(t){let e,n=t[0].retry+"",i,o,r;function a(){return t[18](t[23])}return{c(){e=c("button"),i=h(n),s(e,"class","retry-btn svelte-dxth9d")},m(_,u){B(_,e,u),l(e,i),o||(r=V(e,"click",a),o=!0)},p(_,u){t=_,u&1&&n!==(n=t[0].retry+"")&&w(i,n)},d(_){_&&z(e),o=!1,r()}}}function gi(t,e){let n,i=ki(e[23],e[25],e[7]),o,r,a=i&&vi(e);function _(f,p){return f[23].system?Co:Eo}let u=_(e),d=u(e);return{key:t,first:null,c(){n=Tl(),a&&a.c(),o=m(),d.c(),r=Tl(),this.first=n},m(f,p){B(f,n,p),a&&a.m(f,p),B(f,o,p),d.m(f,p),B(f,r,p)},p(f,p){e=f,p&128&&(i=ki(e[23],e[25],e[7])),i?a?a.p(e,p):(a=vi(e),a.c(),a.m(o.parentNode,o)):a&&(a.d(1),a=null),u===(u=_(e))&&d?d.p(e,p):(d.d(1),d=u(e),d&&(d.c(),d.m(r.parentNode,r)))},d(f){f&&(z(n),z(o),z(r)),a&&a.d(f),d.d(f)}}}function Po(t){let e,n,i,o,r,a,_,u,d,f,p,v,b,g=[],L=new Map,j,y,k,q,M,K,E,W=t[0].send+"",J,S,A,G,F=t[7].length===0&&pi(t),U=ut(t[7]);const Q=C=>C[23].id;for(let C=0;Cn(15,r=A)),ae(t,ft,A=>n(0,a=A)),ae(t,nn,A=>n(16,_=A)),ae(t,Ve,A=>n(6,u=A)),ae(t,Ee,A=>n(17,d=A)),ae(t,Qi,A=>n(7,f=A));let p="",v,b,g=!0;Oi(()=>{v&&g&&n(2,v.scrollTop=v.scrollHeight,v)});function L(){if(!v)return;g=v.scrollHeight-v.scrollTop-v.clientHeight<60}async function j(){const A=p.trim();if(!A)return;if(!r.connected){ee(a.error_not_connected,"error");return}if(!r.room){ee(a.send_disabled_no_room,"error");return}let G=A;const F=[...A];F.length>1e3&&(G=F.slice(0,1e3).join(""),ee(a.msg_truncated,"info")),n(1,p=""),b&&n(3,b.style.height="auto",b);const U="local_"+Date.now()+"_"+Math.random().toString(36).slice(2,7);Xl(U,u.nickname||a.you_self,G,!0,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,G):await window.go.main.App.BroadcastChat(G),Zt(U,"sent")}catch(Q){Zt(U,"failed"),ee(se(a.error_send,{err:Q}),"error")}}async function y(A){Zt(A.id,"pending");try{_&&_.id?await window.go.main.App.SendChat(_.id,A.message):await window.go.main.App.BroadcastChat(A.message),Zt(A.id,"sent")}catch(G){Zt(A.id,"failed"),ee(se(a.error_send,{err:G}),"error")}}function k(A){A.key==="Enter"&&!A.shiftKey&&(A.preventDefault(),j())}function q(A){const G=new Date(A),F=new Date,U=new Date(F.getFullYear(),F.getMonth(),F.getDate()),Q=new Date(U-864e5),C=new Date(G.getFullYear(),G.getMonth(),G.getDate());return C.getTime()===U.getTime()?a.today:C.getTime()===Q.getTime()?a.yesterday:G.toLocaleDateString([],{weekday:"long",month:"short",day:"numeric"})}function M(){b&&(n(3,b.style.height="auto",b),n(3,b.style.height=Math.min(b.scrollHeight,120)+"px",b))}function K(){nn.set(null),Ee.set("network")}const E=A=>y(A);function W(A){Wt[A?"unshift":"push"](()=>{v=A,n(2,v)})}function J(A){Wt[A?"unshift":"push"](()=>{b=A,n(3,b)})}function S(){p=this.value,n(1,p)}return t.$$.update=()=>{t.$$.dirty&131072&&d==="chat"&&Fl(sn()),t.$$.dirty&98305&&n(5,i=_?se(a.chat_with,{name:_.nickname}):se(a.room_chat_title,{room:r.room||a.network})),t.$$.dirty&32768&&n(4,o=r.connected&&!!r.room)},[a,p,v,b,o,i,u,f,L,j,y,k,q,M,K,r,_,d,E,W,J,S]}class Do extends dt{constructor(e){super(),_t(this,e,No,Po,$e,{})}}function wi(t){let e,n=t[7].notif_reconnect_required+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","reconnect-banner svelte-51kqlv"),s(e,"role","status")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].notif_reconnect_required+"")&&w(i,n)},d(o){o&&z(e)}}}function bi(t){let e,n=t[7].apply_update+"",i,o,r;return{c(){e=c("button"),i=h(n),s(e,"class","btn btn-update svelte-51kqlv"),s(e,"type","button"),e.disabled=t[3]},m(a,_){B(a,e,_),l(e,i),o||(r=V(e,"click",t[10]),o=!0)},p(a,_){_&128&&n!==(n=a[7].apply_update+"")&&w(i,n),_&8&&(e.disabled=a[3])},d(a){a&&z(e),o=!1,r()}}}function Lo(t){let e,n=t[7].update_failed+"",i,o,r;return{c(){e=c("p"),i=h(n),o=h(": "),r=h(t[6]),s(e,"class","hint reconnect-hint svelte-51kqlv")},m(a,_){B(a,e,_),l(e,i),l(e,o),l(e,r)},p(a,_){_&128&&n!==(n=a[7].update_failed+"")&&w(i,n),_&64&&w(r,a[6])},d(a){a&&z(e)}}}function Io(t){let e,n=t[7].update_downloading+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].update_downloading+"")&&w(i,n)},d(o){o&&z(e)}}}function Ro(t){let e,n=se(t[7].update_available,{v:t[5]})+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&160&&n!==(n=se(o[7].update_available,{v:o[5]})+"")&&w(i,n)},d(o){o&&z(e)}}}function To(t){let e,n=t[7].update_latest+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].update_latest+"")&&w(i,n)},d(o){o&&z(e)}}}function Oo(t){let e,n=t[7].update_checking+"",i;return{c(){e=c("p"),i=h(n),s(e,"class","hint svelte-51kqlv")},m(o,r){B(o,e,r),l(e,i)},p(o,r){r&128&&n!==(n=o[7].update_checking+"")&&w(i,n)},d(o){o&&z(e)}}}function Mo(t){let e,n,i=t[7].settings_title+"",o,r,a,_,u,d,f=t[7].section_connection+"",p,v,b,g,L=t[7].server_addr+"",j,y,k,q,M,K,E=t[7].nickname+"",W,J,S,A,G,F,U=t[7].server_token+"",Q,C,T,Z,P,N,I=t[7].reconnect_apply+"",H,ve,le,me,de=t[7].auto_connect+"",Ae,je,ye,ue,ke,Se=t[7].auto_connect_desc+"",fe,we,ie,Ce,he=t[7].auto_join+"",be,_e,oe,te,R,X=t[7].auto_join_desc+"",lt,xe,re,st,D=t[7].section_network+"",x,Ne,pe,$=t[7].advanced_warn+"",ge,He,ht,Ft,rn=t[7].connection_mode+"",nl,$l,Ye,gt,an=t[7].connection_direct+"",ll,kt,cn=t[7].connection_relay+"",sl,xl,un,_n=t[7].connection_mode_desc+"",il,es,wt,Kt,dn=t[7].mtu+"",ol,ts,We,ns,fn,pn=t[7].mtu_desc+"",rl,ls,bt,Vt,vn=t[7].dns_server+"",al,ss,Xe,is,mn,hn=t[7].dns_desc+"",cl,os,yt,zt,gn=t[7].socks5+"",ul,rs,ze,kn,as,wn,bn=t[7].socks5_desc+"",_l,cs,St,Jt,yn=t[7].stun_server+"",dl,us,Qe,_s,Sn,qn=t[7].stun_desc+"",fl,ds,Je,An,jn=t[7].section_system+"",pl,fs,qt,En,Cn=t[7].start_windows+"",vl,ps,pt,vs,et,Pn,Nn=t[7].updates+"",ml,ms,it,Dn=t[7].check_updates+"",hl,hs,gs,ks,Fe,Ln,In=t[7].section_appearance+"",gl,ws,ot,Bt,Rn=t[7].ui_scale+"",kl,bs,Be,Tn,ys,Gt,On=(t[0].uiScale??100)+"",wl,Ss,qs,Mn,Un=t[7].ui_scale_desc+"",bl,As,At,Wn,Fn=t[7].theme+"",yl,js,tt,jt,Oe,Es,Kn=t[7].theme_dark+"",Sl,Cs,Et,Me,Ps,Vn=t[7].theme_light+"",ql,zn,Ns,Ct,Ht,Jn=t[7].language+"",Al,Ds,Ze,Pt,Bn=t[7].language_en+"",jl,Nt,Gn=t[7].language_ru+"",El,Dt,Hn=t[7].language_zh+"",Cl,Ls,Is,rt,Yt,Yn=t[7].save+"",Pl,Rs,Xt,Xn=t[7].reset+"",Nl,Ts,Qt,Os,Dl,Ll,Il,Ms,Ie=t[2]&&wi(t),Re=t[4]==="available"&&bi(t);function Us(O,Y){if(O[4]==="checking")return Oo;if(O[4]==="latest")return To;if(O[4]==="available")return Ro;if(O[4]==="downloading")return Io;if(O[4]==="error"&&O[6])return Lo}let Lt=Us(t),Te=Lt&&Lt(t);return Ll=Ii(t[28][0]),{c(){e=c("div"),n=c("h2"),o=h(i),r=m(),a=c("div"),Ie&&Ie.c(),_=m(),u=c("div"),d=c("div"),p=h(f),v=m(),b=c("div"),g=c("label"),j=h(L),y=m(),k=c("input"),q=m(),M=c("div"),K=c("label"),W=h(E),J=m(),S=c("input"),A=m(),G=c("div"),F=c("label"),Q=h(U),C=m(),T=c("input"),P=m(),N=c("p"),H=h(I),ve=m(),le=c("label"),me=c("span"),Ae=h(de),je=m(),ye=c("input"),ue=m(),ke=c("span"),fe=h(Se),we=m(),ie=c("label"),Ce=c("span"),be=h(he),_e=m(),oe=c("input"),te=m(),R=c("span"),lt=h(X),xe=m(),re=c("div"),st=c("div"),x=h(D),Ne=m(),pe=c("p"),ge=h($),He=m(),ht=c("div"),Ft=c("label"),nl=h(rn),$l=m(),Ye=c("select"),gt=c("option"),ll=h(an),kt=c("option"),sl=h(cn),xl=m(),un=c("p"),il=h(_n),es=m(),wt=c("div"),Kt=c("label"),ol=h(dn),ts=m(),We=c("input"),ns=m(),fn=c("p"),rl=h(pn),ls=m(),bt=c("div"),Vt=c("label"),al=h(vn),ss=m(),Xe=c("input"),is=m(),mn=c("p"),cl=h(hn),os=m(),yt=c("div"),zt=c("label"),ul=h(gn),rs=m(),ze=c("input"),as=m(),wn=c("p"),_l=h(bn),cs=m(),St=c("div"),Jt=c("label"),dl=h(yn),us=m(),Qe=c("input"),_s=m(),Sn=c("p"),fl=h(qn),ds=m(),Je=c("div"),An=c("div"),pl=h(jn),fs=m(),qt=c("label"),En=c("span"),vl=h(Cn),ps=m(),pt=c("input"),vs=m(),et=c("div"),Pn=c("span"),ml=h(Nn),ms=m(),it=c("button"),hl=h(Dn),hs=m(),Re&&Re.c(),gs=m(),Te&&Te.c(),ks=m(),Fe=c("div"),Ln=c("div"),gl=h(In),ws=m(),ot=c("div"),Bt=c("label"),kl=h(Rn),bs=m(),Be=c("input"),ys=m(),Gt=c("span"),wl=h(On),Ss=h("%"),qs=m(),Mn=c("p"),bl=h(Un),As=m(),At=c("div"),Wn=c("span"),yl=h(Fn),js=m(),tt=c("div"),jt=c("label"),Oe=c("input"),Es=m(),Sl=h(Kn),Cs=m(),Et=c("label"),Me=c("input"),Ps=m(),ql=h(Vn),Ns=m(),Ct=c("div"),Ht=c("label"),Al=h(Jn),Ds=m(),Ze=c("select"),Pt=c("option"),jl=h(Bn),Nt=c("option"),El=h(Gn),Dt=c("option"),Cl=h(Hn),Is=m(),rt=c("div"),Yt=c("button"),Pl=h(Yn),Rs=m(),Xt=c("button"),Nl=h(Xn),Ts=m(),Qt=c("div"),Os=h("v"),Dl=h(t[1]),s(n,"class","settings-title svelte-51kqlv"),s(d,"class","section-title svelte-51kqlv"),s(g,"class","setting-label svelte-51kqlv"),s(g,"for","cfg-server"),s(k,"id","cfg-server"),s(k,"type","text"),s(k,"placeholder","vps.example.com:8080"),s(k,"class","svelte-51kqlv"),s(b,"class","setting-row svelte-51kqlv"),s(K,"class","setting-label svelte-51kqlv"),s(K,"for","cfg-nick"),s(S,"id","cfg-nick"),s(S,"type","text"),s(S,"placeholder","Your nickname"),s(S,"class","svelte-51kqlv"),s(M,"class","setting-row svelte-51kqlv"),s(F,"class","setting-label svelte-51kqlv"),s(F,"for","cfg-token"),s(T,"id","cfg-token"),s(T,"type","password"),s(T,"placeholder",Z=t[7].server_token_desc),s(T,"class","svelte-51kqlv"),s(G,"class","setting-row svelte-51kqlv"),s(N,"class","hint reconnect-hint svelte-51kqlv"),s(me,"class","setting-label svelte-51kqlv"),s(ye,"type","checkbox"),s(ye,"class","svelte-51kqlv"),s(ke,"class","toggle-label svelte-51kqlv"),s(le,"class","setting-row toggle-row svelte-51kqlv"),s(Ce,"class","setting-label svelte-51kqlv"),s(oe,"type","checkbox"),s(oe,"class","svelte-51kqlv"),s(R,"class","toggle-label svelte-51kqlv"),s(ie,"class","setting-row toggle-row svelte-51kqlv"),s(u,"class","section svelte-51kqlv"),s(st,"class","section-title svelte-51kqlv"),s(pe,"class","hint svelte-51kqlv"),s(Ft,"class","setting-label svelte-51kqlv"),s(Ft,"for","cfg-conn"),gt.__value="direct",ne(gt,gt.__value),kt.__value="relay",ne(kt,kt.__value),s(Ye,"id","cfg-conn"),s(Ye,"class","svelte-51kqlv"),t[0].connectionMode===void 0&&$n(()=>t[21].call(Ye)),s(ht,"class","setting-row svelte-51kqlv"),s(un,"class","hint svelte-51kqlv"),s(Kt,"class","setting-label svelte-51kqlv"),s(Kt,"for","cfg-mtu"),s(We,"id","cfg-mtu"),s(We,"type","number"),s(We,"min","576"),s(We,"max","9000"),s(We,"placeholder","1500"),s(We,"class","svelte-51kqlv"),s(wt,"class","setting-row svelte-51kqlv"),s(fn,"class","hint svelte-51kqlv"),s(Vt,"class","setting-label svelte-51kqlv"),s(Vt,"for","cfg-dns"),s(Xe,"id","cfg-dns"),s(Xe,"type","text"),s(Xe,"placeholder","system default"),s(Xe,"class","svelte-51kqlv"),s(bt,"class","setting-row svelte-51kqlv"),s(mn,"class","hint svelte-51kqlv"),s(zt,"class","setting-label svelte-51kqlv"),s(zt,"for","cfg-socks"),s(ze,"id","cfg-socks"),s(ze,"type","text"),s(ze,"placeholder",kn=t[7].socks5_placeholder),s(ze,"class","svelte-51kqlv"),s(yt,"class","setting-row svelte-51kqlv"),s(wn,"class","hint reconnect-hint svelte-51kqlv"),s(Jt,"class","setting-label svelte-51kqlv"),s(Jt,"for","cfg-stun"),s(Qe,"id","cfg-stun"),s(Qe,"type","text"),s(Qe,"placeholder","stun.l.google.com:19302"),s(Qe,"class","svelte-51kqlv"),s(St,"class","setting-row svelte-51kqlv"),s(Sn,"class","hint reconnect-hint svelte-51kqlv"),s(re,"class","section svelte-51kqlv"),s(An,"class","section-title svelte-51kqlv"),s(En,"class","setting-label svelte-51kqlv"),s(pt,"type","checkbox"),s(pt,"class","svelte-51kqlv"),s(qt,"class","setting-row toggle-row svelte-51kqlv"),s(Pn,"class","setting-label svelte-51kqlv"),s(it,"class","btn btn-check svelte-51kqlv"),s(it,"type","button"),it.disabled=t[3],s(et,"class","setting-row update-row svelte-51kqlv"),s(Je,"class","section svelte-51kqlv"),s(Ln,"class","section-title svelte-51kqlv"),s(Bt,"class","setting-label svelte-51kqlv"),s(Bt,"for","cfg-scale"),s(Be,"id","cfg-scale"),s(Be,"type","range"),s(Be,"min","75"),s(Be,"max","150"),s(Be,"step","5"),Be.value=Tn=t[0].uiScale??100,s(Be,"class","svelte-51kqlv"),s(Gt,"class","scale-value svelte-51kqlv"),s(ot,"class","setting-row scale-row svelte-51kqlv"),s(Mn,"class","hint svelte-51kqlv"),s(Wn,"class","setting-label svelte-51kqlv"),s(Oe,"type","radio"),Oe.__value="dark",ne(Oe,Oe.__value),s(jt,"class","radio-option svelte-51kqlv"),s(Me,"type","radio"),Me.__value="light",ne(Me,Me.__value),s(Et,"class","radio-option svelte-51kqlv"),s(tt,"class","radio-group svelte-51kqlv"),s(tt,"role","radiogroup"),s(tt,"aria-label",zn=t[7].theme),s(At,"class","setting-row radio-row svelte-51kqlv"),s(Ht,"class","setting-label svelte-51kqlv"),s(Ht,"for","cfg-lang"),Pt.__value="en",ne(Pt,Pt.__value),Nt.__value="ru",ne(Nt,Nt.__value),Dt.__value="zh",ne(Dt,Dt.__value),s(Ze,"id","cfg-lang"),s(Ze,"class","svelte-51kqlv"),s(Ct,"class","setting-row svelte-51kqlv"),s(Fe,"class","section svelte-51kqlv"),s(Yt,"class","btn btn-save svelte-51kqlv"),s(Xt,"class","btn btn-reset svelte-51kqlv"),s(Qt,"class","ver svelte-51kqlv"),s(rt,"class","section actions-section svelte-51kqlv"),s(a,"class","settings-content svelte-51kqlv"),s(e,"class","settings-view svelte-51kqlv"),Ll.p(Oe,Me)},m(O,Y){B(O,e,Y),l(e,n),l(n,o),l(e,r),l(e,a),Ie&&Ie.m(a,null),l(a,_),l(a,u),l(u,d),l(d,p),l(u,v),l(u,b),l(b,g),l(g,j),l(b,y),l(b,k),ne(k,t[0].serverAddr),l(u,q),l(u,M),l(M,K),l(K,W),l(M,J),l(M,S),ne(S,t[0].nickname),l(u,A),l(u,G),l(G,F),l(F,Q),l(G,C),l(G,T),ne(T,t[0].serverToken),l(u,P),l(u,N),l(N,H),l(u,ve),l(u,le),l(le,me),l(me,Ae),l(le,je),l(le,ye),ye.checked=t[0].autoConnect,l(le,ue),l(le,ke),l(ke,fe),l(u,we),l(u,ie),l(ie,Ce),l(Ce,be),l(ie,_e),l(ie,oe),oe.checked=t[0].autoJoinLastRoom,l(ie,te),l(ie,R),l(R,lt),l(a,xe),l(a,re),l(re,st),l(st,x),l(re,Ne),l(re,pe),l(pe,ge),l(re,He),l(re,ht),l(ht,Ft),l(Ft,nl),l(ht,$l),l(ht,Ye),l(Ye,gt),l(gt,ll),l(Ye,kt),l(kt,sl),Qn(Ye,t[0].connectionMode,!0),l(re,xl),l(re,un),l(un,il),l(re,es),l(re,wt),l(wt,Kt),l(Kt,ol),l(wt,ts),l(wt,We),ne(We,t[0].mtu),l(re,ns),l(re,fn),l(fn,rl),l(re,ls),l(re,bt),l(bt,Vt),l(Vt,al),l(bt,ss),l(bt,Xe),ne(Xe,t[0].dnsServer),l(re,is),l(re,mn),l(mn,cl),l(re,os),l(re,yt),l(yt,zt),l(zt,ul),l(yt,rs),l(yt,ze),ne(ze,t[0].socks5Proxy),l(re,as),l(re,wn),l(wn,_l),l(re,cs),l(re,St),l(St,Jt),l(Jt,dl),l(St,us),l(St,Qe),ne(Qe,t[0].stunServer),l(re,_s),l(re,Sn),l(Sn,fl),l(a,ds),l(a,Je),l(Je,An),l(An,pl),l(Je,fs),l(Je,qt),l(qt,En),l(En,vl),l(qt,ps),l(qt,pt),pt.checked=t[0].startWithWindows,l(Je,vs),l(Je,et),l(et,Pn),l(Pn,ml),l(et,ms),l(et,it),l(it,hl),l(et,hs),Re&&Re.m(et,null),l(Je,gs),Te&&Te.m(Je,null),l(a,ks),l(a,Fe),l(Fe,Ln),l(Ln,gl),l(Fe,ws),l(Fe,ot),l(ot,Bt),l(Bt,kl),l(ot,bs),l(ot,Be),l(ot,ys),l(ot,Gt),l(Gt,wl),l(Gt,Ss),l(Fe,qs),l(Fe,Mn),l(Mn,bl),l(Fe,As),l(Fe,At),l(At,Wn),l(Wn,yl),l(At,js),l(At,tt),l(tt,jt),l(jt,Oe),Oe.checked=Oe.__value===t[0].theme,l(jt,Es),l(jt,Sl),l(tt,Cs),l(tt,Et),l(Et,Me),Me.checked=Me.__value===t[0].theme,l(Et,Ps),l(Et,ql),l(Fe,Ns),l(Fe,Ct),l(Ct,Ht),l(Ht,Al),l(Ct,Ds),l(Ct,Ze),l(Ze,Pt),l(Pt,jl),l(Ze,Nt),l(Nt,El),l(Ze,Dt),l(Dt,Cl),Qn(Ze,t[0].lang||t[8]),l(a,Is),l(a,rt),l(rt,Yt),l(Yt,Pl),l(rt,Rs),l(rt,Xt),l(Xt,Nl),l(rt,Ts),l(rt,Qt),l(Qt,Os),l(Qt,Dl),Il||(Ms=[V(k,"input",t[16]),V(S,"input",t[17]),V(T,"input",t[18]),V(ye,"change",t[19]),V(oe,"change",t[20]),V(Ye,"change",t[21]),V(We,"input",t[22]),V(Xe,"input",t[23]),V(ze,"input",t[24]),V(Qe,"input",t[25]),V(pt,"change",t[26]),V(it,"click",t[9]),V(Be,"input",t[13]),V(Oe,"change",t[27]),V(Oe,"change",t[15]),V(Me,"change",t[29]),V(Me,"change",t[15]),V(Ze,"change",t[14]),V(Yt,"click",t[11]),V(Xt,"click",t[12])],Il=!0)},p(O,[Y]){Y&128&&i!==(i=O[7].settings_title+"")&&w(o,i),O[2]?Ie?Ie.p(O,Y):(Ie=wi(O),Ie.c(),Ie.m(a,_)):Ie&&(Ie.d(1),Ie=null),Y&128&&f!==(f=O[7].section_connection+"")&&w(p,f),Y&128&&L!==(L=O[7].server_addr+"")&&w(j,L),Y&1&&k.value!==O[0].serverAddr&&ne(k,O[0].serverAddr),Y&128&&E!==(E=O[7].nickname+"")&&w(W,E),Y&1&&S.value!==O[0].nickname&&ne(S,O[0].nickname),Y&128&&U!==(U=O[7].server_token+"")&&w(Q,U),Y&128&&Z!==(Z=O[7].server_token_desc)&&s(T,"placeholder",Z),Y&1&&T.value!==O[0].serverToken&&ne(T,O[0].serverToken),Y&128&&I!==(I=O[7].reconnect_apply+"")&&w(H,I),Y&128&&de!==(de=O[7].auto_connect+"")&&w(Ae,de),Y&1&&(ye.checked=O[0].autoConnect),Y&128&&Se!==(Se=O[7].auto_connect_desc+"")&&w(fe,Se),Y&128&&he!==(he=O[7].auto_join+"")&&w(be,he),Y&1&&(oe.checked=O[0].autoJoinLastRoom),Y&128&&X!==(X=O[7].auto_join_desc+"")&&w(lt,X),Y&128&&D!==(D=O[7].section_network+"")&&w(x,D),Y&128&&$!==($=O[7].advanced_warn+"")&&w(ge,$),Y&128&&rn!==(rn=O[7].connection_mode+"")&&w(nl,rn),Y&128&&an!==(an=O[7].connection_direct+"")&&w(ll,an),Y&128&&cn!==(cn=O[7].connection_relay+"")&&w(sl,cn),Y&1&&Qn(Ye,O[0].connectionMode),Y&128&&_n!==(_n=O[7].connection_mode_desc+"")&&w(il,_n),Y&128&&dn!==(dn=O[7].mtu+"")&&w(ol,dn),Y&1&&Pi(We.value)!==O[0].mtu&&ne(We,O[0].mtu),Y&128&&pn!==(pn=O[7].mtu_desc+"")&&w(rl,pn),Y&128&&vn!==(vn=O[7].dns_server+"")&&w(al,vn),Y&1&&Xe.value!==O[0].dnsServer&&ne(Xe,O[0].dnsServer),Y&128&&hn!==(hn=O[7].dns_desc+"")&&w(cl,hn),Y&128&&gn!==(gn=O[7].socks5+"")&&w(ul,gn),Y&128&&kn!==(kn=O[7].socks5_placeholder)&&s(ze,"placeholder",kn),Y&1&&ze.value!==O[0].socks5Proxy&&ne(ze,O[0].socks5Proxy),Y&128&&bn!==(bn=O[7].socks5_desc+"")&&w(_l,bn),Y&128&&yn!==(yn=O[7].stun_server+"")&&w(dl,yn),Y&1&&Qe.value!==O[0].stunServer&&ne(Qe,O[0].stunServer),Y&128&&qn!==(qn=O[7].stun_desc+"")&&w(fl,qn),Y&128&&jn!==(jn=O[7].section_system+"")&&w(pl,jn),Y&128&&Cn!==(Cn=O[7].start_windows+"")&&w(vl,Cn),Y&1&&(pt.checked=O[0].startWithWindows),Y&128&&Nn!==(Nn=O[7].updates+"")&&w(ml,Nn),Y&128&&Dn!==(Dn=O[7].check_updates+"")&&w(hl,Dn),Y&8&&(it.disabled=O[3]),O[4]==="available"?Re?Re.p(O,Y):(Re=bi(O),Re.c(),Re.m(et,null)):Re&&(Re.d(1),Re=null),Lt===(Lt=Us(O))&&Te?Te.p(O,Y):(Te&&Te.d(1),Te=Lt&&Lt(O),Te&&(Te.c(),Te.m(Je,null))),Y&128&&In!==(In=O[7].section_appearance+"")&&w(gl,In),Y&128&&Rn!==(Rn=O[7].ui_scale+"")&&w(kl,Rn),Y&1&&Tn!==(Tn=O[0].uiScale??100)&&(Be.value=Tn),Y&1&&On!==(On=(O[0].uiScale??100)+"")&&w(wl,On),Y&128&&Un!==(Un=O[7].ui_scale_desc+"")&&w(bl,Un),Y&128&&Fn!==(Fn=O[7].theme+"")&&w(yl,Fn),Y&1&&(Oe.checked=Oe.__value===O[0].theme),Y&128&&Kn!==(Kn=O[7].theme_dark+"")&&w(Sl,Kn),Y&1&&(Me.checked=Me.__value===O[0].theme),Y&128&&Vn!==(Vn=O[7].theme_light+"")&&w(ql,Vn),Y&128&&zn!==(zn=O[7].theme)&&s(tt,"aria-label",zn),Y&128&&Jn!==(Jn=O[7].language+"")&&w(Al,Jn),Y&128&&Bn!==(Bn=O[7].language_en+"")&&w(jl,Bn),Y&128&&Gn!==(Gn=O[7].language_ru+"")&&w(El,Gn),Y&128&&Hn!==(Hn=O[7].language_zh+"")&&w(Cl,Hn),Y&257&&Ls!==(Ls=O[0].lang||O[8])&&Qn(Ze,O[0].lang||O[8]),Y&128&&Yn!==(Yn=O[7].save+"")&&w(Pl,Yn),Y&128&&Xn!==(Xn=O[7].reset+"")&&w(Nl,Xn),Y&2&&w(Dl,O[1])},i:ce,o:ce,d(O){O&&z(e),Ie&&Ie.d(),Re&&Re.d(),Te&&Te.d(),Ll.r(),Il=!1,Pe(Ms)}}}function Uo(t,e,n){let i,o,r;ae(t,Ve,P=>n(30,i=P)),ae(t,ft,P=>n(7,o=P)),ae(t,Zl,P=>n(8,r=P));let a={...i},_="1.0.0",u=!1,d=!1,f="",p="",v="";async function b(){n(3,d=!0),n(4,f="checking"),n(6,v=""),n(5,p="");try{const P=await window.go.main.App.CheckForUpdate();P?.available?(n(4,f="available"),n(5,p=P.latest||"")):n(4,f="latest")}catch(P){n(4,f="error"),n(6,v=String(P)),ee(o.error_update_check+P,"error")}finally{n(3,d=!1)}}async function g(){if(confirm(o.confirm_update)){n(3,d=!0),n(4,f="downloading"),n(6,v="");try{await window.go.main.App.ApplyUpdate(),ee(o.notif_updating,"info")}catch(P){n(4,f="error"),n(6,v=String(P)),n(3,d=!1),ee(o.error_update+P,"error")}}}async function L(){nt(Ve,i={...a},i);try{n(2,u=!!await window.go.main.App.SaveSettings(a)),a.lang&&$t(a.lang),ee(o.notif_settings_saved,"info"),u&&ee(o.notif_reconnect_required,"info")}catch(P){ee(o.error_save+P,"error")}}async function j(){if(confirm(o.confirm_reset))try{n(0,a=await window.go.main.App.ResetSettings()),nt(Ve,i={...a},i),n(2,u=!1),a.lang&&$t(a.lang),ee(o.notif_settings_saved,"info")}catch(P){ee(o.error_save+P,"error")}}function y(P){const N=Math.min(150,Math.max(75,Number(P.target.value)||100));n(0,a.uiScale=N,a),nt(Ve,i={...i,uiScale:N},i)}function k(P){n(0,a.lang=P.target.value,a),$t(P.target.value)}function q(){nt(Ve,i={...i,theme:a.theme},i)}on(async()=>{try{const P=await window.go.main.App.GetSettings();P&&(n(0,a={...a,...P}),a.connectionMode||n(0,a.connectionMode="direct",a),nt(Ve,i=a,i),a.lang&&$t(a.lang)),window.go.main.App.GetVersion&&n(1,_=await window.go.main.App.GetVersion())}catch{}});const M=[[]];function K(){a.serverAddr=this.value,n(0,a)}function E(){a.nickname=this.value,n(0,a)}function W(){a.serverToken=this.value,n(0,a)}function J(){a.autoConnect=this.checked,n(0,a)}function S(){a.autoJoinLastRoom=this.checked,n(0,a)}function A(){a.connectionMode=Ti(this),n(0,a)}function G(){a.mtu=Pi(this.value),n(0,a)}function F(){a.dnsServer=this.value,n(0,a)}function U(){a.socks5Proxy=this.value,n(0,a)}function Q(){a.stunServer=this.value,n(0,a)}function C(){a.startWithWindows=this.checked,n(0,a)}function T(){a.theme=this.__value,n(0,a)}function Z(){a.theme=this.__value,n(0,a)}return[a,_,u,d,f,p,v,o,r,b,g,L,j,y,k,q,K,E,W,J,S,A,G,F,U,Q,C,T,M,Z]}class Wo extends dt{constructor(e){super(),_t(this,e,Uo,Mo,$e,{})}}function Fo(t){let e,n,i=t[1].brand+"",o,r,a,_,u,d=t[1].header_room+"",f,p,v,b=(t[3].room||t[1].na)+"",g,L,j,y,k=t[1].header_vip+"",q,M,K,E=(t[3].virtualIP||t[1].na)+"",W,J,S,A,G,F=t[1].header_path+"",U,Q,C,T,Z,P,N,I,H,ve,le,me=t[1].header_peers+"",de,Ae,je,ye=se(t[1].peer_count,{n:t[3].peerCount??0})+"",ue,ke,Se,fe,we=t[1].settings+"",ie,Ce,he,be=t[1].disconnect+"",_e,oe,te;return{c(){e=c("header"),n=c("span"),o=h(i),r=m(),a=c("div"),_=c("div"),u=c("span"),f=h(d),p=m(),v=c("span"),g=h(b),L=m(),j=c("div"),y=c("span"),q=h(k),M=m(),K=c("button"),W=h(E),S=m(),A=c("div"),G=c("span"),U=h(F),Q=m(),C=c("span"),T=c("span"),P=m(),N=c("span"),I=h(t[2]),H=m(),ve=c("div"),le=c("span"),de=h(me),Ae=m(),je=c("span"),ue=h(ye),ke=m(),Se=c("div"),fe=c("button"),ie=h(we),Ce=m(),he=c("button"),_e=h(be),s(n,"class","wordmark svelte-wx9xg3"),s(u,"class","cap svelte-wx9xg3"),s(v,"class","val svelte-wx9xg3"),s(_,"class","fact svelte-wx9xg3"),s(y,"class","cap svelte-wx9xg3"),s(K,"type","button"),s(K,"class","val mono vip svelte-wx9xg3"),s(K,"title",J=t[1].virtual_ip),s(j,"class","fact svelte-wx9xg3"),s(G,"class","cap svelte-wx9xg3"),s(T,"class",Z="path-dot "+t[0]+" svelte-wx9xg3"),s(T,"aria-hidden","true"),s(N,"class","val mono svelte-wx9xg3"),s(C,"class","path-row svelte-wx9xg3"),s(A,"class","fact path-fact svelte-wx9xg3"),s(le,"class","cap svelte-wx9xg3"),s(je,"class","val svelte-wx9xg3"),s(ve,"class","fact svelte-wx9xg3"),s(a,"class","facts svelte-wx9xg3"),s(fe,"type","button"),s(fe,"class","btn svelte-wx9xg3"),qe(fe,"active",t[4]==="settings"),s(he,"type","button"),s(he,"class","btn danger"),s(Se,"class","actions svelte-wx9xg3"),s(e,"class","band svelte-wx9xg3")},m(R,X){B(R,e,X),l(e,n),l(n,o),l(e,r),l(e,a),l(a,_),l(_,u),l(u,f),l(_,p),l(_,v),l(v,g),l(a,L),l(a,j),l(j,y),l(y,q),l(j,M),l(j,K),l(K,W),l(a,S),l(a,A),l(A,G),l(G,U),l(A,Q),l(A,C),l(C,T),l(C,P),l(C,N),l(N,I),l(a,H),l(a,ve),l(ve,le),l(le,de),l(ve,Ae),l(ve,je),l(je,ue),l(e,ke),l(e,Se),l(Se,fe),l(fe,ie),l(Se,Ce),l(Se,he),l(he,_e),oe||(te=[V(K,"click",t[6]),V(fe,"click",t[5]),V(he,"click",t[7])],oe=!0)},p(R,[X]){X&2&&i!==(i=R[1].brand+"")&&w(o,i),X&2&&d!==(d=R[1].header_room+"")&&w(f,d),X&10&&b!==(b=(R[3].room||R[1].na)+"")&&w(g,b),X&2&&k!==(k=R[1].header_vip+"")&&w(q,k),X&10&&E!==(E=(R[3].virtualIP||R[1].na)+"")&&w(W,E),X&2&&J!==(J=R[1].virtual_ip)&&s(K,"title",J),X&2&&F!==(F=R[1].header_path+"")&&w(U,F),X&1&&Z!==(Z="path-dot "+R[0]+" svelte-wx9xg3")&&s(T,"class",Z),X&4&&w(I,R[2]),X&2&&me!==(me=R[1].header_peers+"")&&w(de,me),X&10&&ye!==(ye=se(R[1].peer_count,{n:R[3].peerCount??0})+"")&&w(ue,ye),X&2&&we!==(we=R[1].settings+"")&&w(ie,we),X&16&&qe(fe,"active",R[4]==="settings"),X&2&&be!==(be=R[1].disconnect+"")&&w(_e,be)},i:ce,o:ce,d(R){R&&z(e),oe=!1,Pe(te)}}}function Ko(t,e,n){let i,o,r,a;ae(t,ft,v=>n(1,o=v)),ae(t,De,v=>n(3,r=v)),ae(t,Ee,v=>n(4,a=v));let{pathAggregate:_="disconnected"}=e,u="network";function d(){a==="settings"?Ee.set(u||"network"):(u=a,Ee.set("settings"))}async function f(){const v=r.virtualIP;if(v)try{await window.go.main.App.CopyText(v),ee(o.copied)}catch{}}async function p(){if(confirm(o.confirm_disconnect))try{await window.go.main.App.Disconnect(),De.set({connected:!1,reconnecting:!1,server:"",room:"",virtualIP:"",peerCount:0,isOwner:!1,phase:"idle"}),Ee.set("connect"),ee(o.notif_disconnected)}catch(v){ee(se(o.error_disconnect,{err:v}),"error")}}return t.$$set=v=>{"pathAggregate"in v&&n(0,_=v.pathAggregate)},t.$$.update=()=>{t.$$.dirty&3&&n(2,i=_==="direct"?o.path_p2p:_==="relay"?o.path_relay:_==="reconnecting"?o.status_reconnecting:o.status_disconnected)},[_,o,i,r,a,d,f,p]}class Vo extends dt{constructor(e){super(),_t(this,e,Ko,Fo,$e,{pathAggregate:0})}}function yi(t,e,n){const i=t.slice();return i[16]=e[n],i}function Si(t){let e,n,i;return{c(){e=c("div"),n=m(),i=c("div"),s(e,"class","space-bg"),s(e,"aria-hidden","true"),s(i,"class","space-dust"),s(i,"aria-hidden","true")},m(o,r){B(o,e,r),B(o,n,r),B(o,i,r)},d(o){o&&(z(e),z(n),z(i))}}}function zo(t){let e,n,i,o,r,a,_,u,d,f,p=t[0],v,b,g,L,j;n=new Vo({props:{pathAggregate:t[3]}}),a=new ro({});let y=qi(t);return b=new ko({props:{pathAggregate:t[3]}}),{c(){e=c("div"),mt(n.$$.fragment),i=m(),o=c("div"),r=c("div"),mt(a.$$.fragment),_=m(),u=c("div"),d=m(),f=c("main"),y.c(),v=m(),mt(b.$$.fragment),s(u,"class","drag-handle svelte-1v9dp4p"),qe(u,"active",t[2]),s(r,"class","sidebar-wrapper svelte-1v9dp4p"),Fs(r,"width",t[1]+"px"),s(f,"class","main-area svelte-1v9dp4p"),s(o,"class","layout svelte-1v9dp4p"),s(e,"class","shell connected-shell svelte-1v9dp4p")},m(k,q){B(k,e,q),at(n,e,null),l(e,i),l(e,o),l(o,r),at(a,r,null),l(r,_),l(r,u),l(o,d),l(o,f),y.m(f,null),l(e,v),at(b,e,null),g=!0,L||(j=V(u,"mousedown",t[7]),L=!0)},p(k,q){const M={};q&8&&(M.pathAggregate=k[3]),n.$set(M),(!g||q&4)&&qe(u,"active",k[2]),(!g||q&2)&&Fs(r,"width",k[1]+"px"),q&1&&$e(p,p=k[0])?(Bl(),Ue(y,1,1,ce),Gl(),y=qi(k),y.c(),Le(y,1),y.m(f,null)):y.p(k,q);const K={};q&8&&(K.pathAggregate=k[3]),b.$set(K)},i(k){g||(Le(n.$$.fragment,k),Le(a.$$.fragment,k),Le(y),Le(b.$$.fragment,k),g=!0)},o(k){Ue(n.$$.fragment,k),Ue(a.$$.fragment,k),Ue(y),Ue(b.$$.fragment,k),g=!1},d(k){k&&z(e),ct(n),ct(a),y.d(k),ct(b),L=!1,j()}}}function Jo(t){let e,n,i,o;return i=new jo({}),{c(){e=c("div"),n=c("div"),mt(i.$$.fragment),s(n,"class","fullscreen-connect svelte-1v9dp4p"),s(e,"class","shell connect-shell svelte-1v9dp4p")},m(r,a){B(r,e,a),l(e,n),at(i,n,null),o=!0},p:ce,i(r){o||(Le(i.$$.fragment,r),o=!0)},o(r){Ue(i.$$.fragment,r),o=!1},d(r){r&&z(e),ct(i)}}}function Bo(t){let e,n,i;return{c(){e=c("div"),n=h("Unknown view: "),i=h(t[0]),s(e,"class","unknown-view svelte-1v9dp4p")},m(o,r){B(o,e,r),l(e,n),l(e,i)},p(o,r){r&1&&w(i,o[0])},i:ce,o:ce,d(o){o&&z(e)}}}function Go(t){let e,n;return e=new Wo({}),{c(){mt(e.$$.fragment)},m(i,o){at(e,i,o),n=!0},p:ce,i(i){n||(Le(e.$$.fragment,i),n=!0)},o(i){Ue(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function Ho(t){let e,n;return e=new Do({}),{c(){mt(e.$$.fragment)},m(i,o){at(e,i,o),n=!0},p:ce,i(i){n||(Le(e.$$.fragment,i),n=!0)},o(i){Ue(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function Yo(t){let e,n;return e=new mo({}),{c(){mt(e.$$.fragment)},m(i,o){at(e,i,o),n=!0},p:ce,i(i){n||(Le(e.$$.fragment,i),n=!0)},o(i){Ue(e.$$.fragment,i),n=!1},d(i){ct(e,i)}}}function qi(t){let e,n,i,o;const r=[Yo,Ho,Go,Bo],a=[];function _(u,d){return u[0]==="network"?0:u[0]==="chat"?1:u[0]==="settings"?2:3}return n=_(t),i=a[n]=r[n](t),{c(){e=c("div"),i.c(),s(e,"class","view-pane svelte-1v9dp4p")},m(u,d){B(u,e,d),a[n].m(e,null),o=!0},p(u,d){let f=n;n=_(u),n===f?a[n].p(u,d):(Bl(),Ue(a[f],1,1,()=>{a[f]=null}),Gl(),i=a[n],i?i.p(u,d):(i=a[n]=r[n](u),i.c()),Le(i,1),i.m(e,null))},i(u){o||(Le(i),o=!0)},o(u){Ue(i),o=!1},d(u){u&&z(e),a[n].d()}}}function Ai(t){let e,n,i=t[5].msg+"",o,r,a,_=t[4].dismiss_error+"",u,d,f,p;return{c(){e=c("div"),n=c("span"),o=h(i),r=m(),a=c("button"),u=h(_),s(n,"class","error-strip-msg svelte-1v9dp4p"),s(a,"type","button"),s(a,"class","error-strip-dismiss svelte-1v9dp4p"),s(a,"aria-label",d=t[4].dismiss_error),s(e,"class","error-strip svelte-1v9dp4p"),s(e,"role","alert")},m(v,b){B(v,e,b),l(e,n),l(n,o),l(e,r),l(e,a),l(a,u),f||(p=V(a,"click",ln),f=!0)},p(v,b){b&32&&i!==(i=v[5].msg+"")&&w(o,i),b&16&&_!==(_=v[4].dismiss_error+"")&&w(u,_),b&16&&d!==(d=v[4].dismiss_error)&&s(a,"aria-label",d)},d(v){v&&z(e),f=!1,p()}}}function ji(t,e){let n,i,o=e[16].type==="error"?"!":">",r,a,_=e[16].msg+"",u,d,f;return{key:t,first:null,c(){n=c("div"),i=c("span"),r=h(o),a=m(),u=h(_),d=m(),s(i,"class","notif-icon svelte-1v9dp4p"),s(n,"class",f="notification "+e[16].type+" svelte-1v9dp4p"),s(n,"role","status"),this.first=n},m(p,v){B(p,n,v),l(n,i),l(i,r),l(n,a),l(n,u),l(n,d)},p(p,v){e=p,v&64&&o!==(o=e[16].type==="error"?"!":">")&&w(r,o),v&64&&_!==(_=e[16].msg+"")&&w(u,_),v&64&&f!==(f="notification "+e[16].type+" svelte-1v9dp4p")&&s(n,"class",f)},d(p){p&&z(n)}}}function Xo(t){let e,n,i,o,r,a=[],_=new Map,u,d,f=t[0]==="connect"&&Si();const p=[Jo,zo],v=[];function b(y,k){return y[0]==="connect"?0:1}n=b(t),i=v[n]=p[n](t);let g=t[5]&&Ai(t),L=ut(t[6]);const j=y=>y[16].id;for(let y=0;y{v[q]=null}),Gl(),i=v[n],i?i.p(y,k):(i=v[n]=p[n](y),i.c()),Le(i,1),i.m(o.parentNode,o)),y[5]?g?g.p(y,k):(g=Ai(y),g.c(),g.m(r.parentNode,r)):g&&(g.d(1),g=null),k&64&&(L=ut(y[6]),a=tl(a,k,j,1,y,L,_,u.parentNode,el,ji,u,yi))},i(y){d||(Le(i),d=!0)},o(y){Ue(i),d=!1},d(y){y&&(z(e),z(o),z(r),z(u)),f&&f.d(y),v[n].d(y),g&&g.d(y);for(let k=0;kn(4,o=q)),ae(t,Ve,q=>n(8,r=q)),ae(t,Ml,q=>n(9,a=q)),ae(t,De,q=>n(10,_=q)),ae(t,Ee,q=>n(0,u=q)),ae(t,xn,q=>n(5,d=q)),ae(t,Ul,q=>n(6,f=q));let p=220,v=!1,b,g,L=!0;function j(q){n(2,v=!0),b=q.clientX,g=p,document.addEventListener("mousemove",y),document.addEventListener("mouseup",k),q.preventDefault()}function y(q){if(!v)return;const M=g+(q.clientX-b);n(1,p=Math.max(140,Math.min(400,M)))}function k(){n(2,v=!1),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",k)}return on(async()=>{window.addEventListener("keydown",Ei);try{const q=await window.go.main.App.LoadConfig();q&&(Ve.set({...r,...q}),q.lang&&$t(q.lang))}catch{}window.runtime?.EventsOn&&(window.runtime.EventsOn("status_changed",q=>{L&&(De.set(q),!q.connected&&!q.reconnecting&&Ee.set("connect"))}),window.runtime.EventsOn("peers_changed",q=>{L&&Ml.set(q||[])}),window.runtime.EventsOn("error",q=>{L&&ee(q,"error")}),window.runtime.EventsOn("chat_message",q=>{L&&Xl(q.fromID,q.nickname,q.message,!1,"sent",!1,!!q.isDM)}),window.runtime.EventsOn("system_chat",q=>{L&&Xi(q.message||"")}),window.runtime.EventsOn("room_deleted",q=>{L&&(ee(o.notif_room_deleted,"error"),Ee.set("network"))}),window.runtime.EventsOn("auto_join_skipped",q=>{if(!L)return;const M=q?.room||"";ee(se(o.notif_auto_join_skipped,{name:M}),"info")}))}),Ni(()=>{L=!1,window.removeEventListener("keydown",Ei),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",k),window.runtime?.EventsOff&&(window.runtime.EventsOff("status_changed"),window.runtime.EventsOff("peers_changed"),window.runtime.EventsOff("error"),window.runtime.EventsOff("chat_message"),window.runtime.EventsOff("system_chat"),window.runtime.EventsOff("room_deleted"),window.runtime.EventsOff("auto_join_skipped"))}),t.$$.update=()=>{if(t.$$.dirty&256){const q=Qo(r.uiScale)/100;document.documentElement.style.zoom=String(q)}t.$$.dirty&256&&(r.theme==="light"?document.documentElement.classList.add("light-theme"):document.documentElement.classList.remove("light-theme")),t.$$.dirty&1&&document.documentElement.setAttribute("data-app",u==="connect"?"connect":"connected"),t.$$.dirty&1536&&n(3,i=eo(_,a))},[u,p,v,i,o,d,f,j,r,a,_]}class $o extends dt{constructor(e){super(),_t(this,e,Zo,Xo,$e,{})}}new $o({target:document.getElementById("app")}); diff --git a/client/frontend/dist/assets/index-coA7a2P7.css b/client/frontend/dist/assets/index-coA7a2P7.css deleted file mode 100644 index 43570b8..0000000 --- a/client/frontend/dist/assets/index-coA7a2P7.css +++ /dev/null @@ -1 +0,0 @@ -.sidebar.svelte-1oaanap.svelte-1oaanap{width:100%;height:100%;background:var(--bg-surface);display:flex;flex-direction:column;flex-shrink:0}.sidebar-header.svelte-1oaanap.svelte-1oaanap{padding:12px;border-bottom:1px solid var(--border)}.sidebar-header.svelte-1oaanap h2.svelte-1oaanap{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--text-secondary);font-weight:600}.sidebar-meta.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--text-muted);margin-top:4px}.sidebar-actions.svelte-1oaanap.svelte-1oaanap{padding:8px;display:flex;flex-direction:column;gap:6px;border-bottom:1px solid var(--border)}.sidebar-actions.svelte-1oaanap .btn.svelte-1oaanap{min-height:36px;padding:8px 10px}.network-list.svelte-1oaanap.svelte-1oaanap{flex:1;overflow-y:auto;overflow-x:hidden;padding:4px 0}.network-item.svelte-1oaanap.svelte-1oaanap{display:flex;align-items:center;padding:10px 12px;min-height:44px;cursor:pointer;gap:8px;border-bottom:1px solid var(--border-deep);transition:background .12s ease,opacity .12s ease;position:relative}.network-item.svelte-1oaanap.svelte-1oaanap:hover,.network-item.svelte-1oaanap.svelte-1oaanap:focus-visible{background:var(--bg-hover)}.network-item.active.svelte-1oaanap.svelte-1oaanap{background:var(--bg-active)}.network-item.disabled.svelte-1oaanap.svelte-1oaanap{opacity:.55}.network-indicator.svelte-1oaanap.svelte-1oaanap{width:4px;height:12px;background:var(--text-muted);flex-shrink:0}.network-indicator.active-dot.svelte-1oaanap.svelte-1oaanap{background:var(--accent)}.network-info.svelte-1oaanap.svelte-1oaanap{flex:1;min-width:0}.network-name.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size);color:var(--text-bright);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.network-meta.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--text-secondary);line-height:1.4}.row-actions.svelte-1oaanap.svelte-1oaanap{position:relative;flex-shrink:0}.menu-btn.svelte-1oaanap.svelte-1oaanap{background:none;border:1px solid transparent;color:var(--text-muted);cursor:pointer;font-family:var(--font-mono);font-size:16px;line-height:1;width:32px;height:32px;display:flex;align-items:center;justify-content:center}.menu-btn.svelte-1oaanap.svelte-1oaanap:hover,.menu-btn[aria-expanded=true].svelte-1oaanap.svelte-1oaanap{color:var(--text-bright);border-color:var(--border);background:var(--bg-raised)}.overflow-menu.svelte-1oaanap.svelte-1oaanap{position:absolute;right:0;top:100%;z-index:20;min-width:160px;background:var(--bg-raised);border:1px solid var(--border);display:flex;flex-direction:column;box-shadow:0 4px 12px #00000059}.menu-item.svelte-1oaanap.svelte-1oaanap{background:none;border:none;text-align:left;padding:10px 12px;min-height:36px;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.menu-item.svelte-1oaanap.svelte-1oaanap:hover{background:var(--bg-hover);color:var(--text-bright)}.menu-item.danger.svelte-1oaanap.svelte-1oaanap{color:var(--error)}.menu-item.danger.svelte-1oaanap.svelte-1oaanap:hover{background:#c45c5c1f}.empty-desc.svelte-1oaanap.svelte-1oaanap{margin-top:6px;font-size:var(--font-size-xs);color:var(--text-dim)}.empty-state.svelte-1oaanap.svelte-1oaanap{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)}.sidebar-footer.svelte-1oaanap.svelte-1oaanap{padding:8px;border-top:1px solid var(--border)}.settings-btn.svelte-1oaanap.svelte-1oaanap{width:100%;min-height:36px}.modal-overlay.svelte-1oaanap.svelte-1oaanap{position:fixed;inset:0;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:100;animation:svelte-1oaanap-fadeIn .12s ease-out}@keyframes svelte-1oaanap-fadeIn{0%{opacity:0}to{opacity:1}}.modal.svelte-1oaanap.svelte-1oaanap{background:var(--bg-surface);border:1px solid var(--border);padding:20px;width:320px;max-height:80vh;overflow-y:auto;display:flex;flex-direction:column;gap:10px}.modal.svelte-1oaanap h3.svelte-1oaanap{font-size:var(--font-size);color:var(--text-bright);font-weight:500;text-transform:uppercase;letter-spacing:.5px}.modal.svelte-1oaanap input.svelte-1oaanap{padding:10px;min-height:40px;border:1px solid var(--border);background:var(--bg-primary);color:var(--text-primary);font-size:var(--font-size);font-family:var(--font-mono)}.modal.svelte-1oaanap input.invalid.svelte-1oaanap{border-color:var(--error)}.field-error.svelte-1oaanap.svelte-1oaanap,.modal-error.svelte-1oaanap.svelte-1oaanap{font-size:var(--font-size-xs);color:var(--error)}.modal-error.svelte-1oaanap.svelte-1oaanap{padding:8px;border:1px solid var(--error);background:#c45c5c14}.modal-actions.svelte-1oaanap.svelte-1oaanap{display:flex;gap:6px;justify-content:flex-end}.modal-actions.svelte-1oaanap .btn.svelte-1oaanap{min-height:36px;padding:8px 12px}.sr-only.svelte-1oaanap.svelte-1oaanap{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.peer-view.svelte-mpjrp9.svelte-mpjrp9{display:flex;flex-direction:column;height:100%}.peer-header.svelte-mpjrp9.svelte-mpjrp9{padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;background:var(--bg-surface);flex-wrap:wrap}.peer-header.svelte-mpjrp9 h2.svelte-mpjrp9{font-size:var(--font-size);font-weight:500;color:var(--text-bright);text-transform:uppercase;letter-spacing:.5px}.ip-badge.svelte-mpjrp9.svelte-mpjrp9{padding:4px 8px;min-height:28px;background:var(--bg-raised);font-size:var(--font-size-xs);font-family:var(--font-mono);color:var(--text-secondary);border:1px solid var(--border);cursor:pointer}.ip-badge.svelte-mpjrp9.svelte-mpjrp9:hover{border-color:var(--border-hover);color:var(--text-bright)}.room-chat-btn.svelte-mpjrp9.svelte-mpjrp9{margin-left:auto;background:transparent;border:1px solid var(--border);color:var(--text-secondary);font-family:var(--font-mono);font-size:var(--font-size-xs);padding:6px 10px;min-height:32px;cursor:pointer;position:relative}.room-chat-btn.svelte-mpjrp9.svelte-mpjrp9:hover{color:var(--text-bright);border-color:var(--border-hover)}.relay-hint.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs);color:var(--text-muted)}.badge.svelte-mpjrp9.svelte-mpjrp9{display:inline-block;min-width:14px;padding:0 4px;margin-left:4px;background:var(--accent);color:var(--accent-ink);font-size:10px;line-height:14px;text-align:center}.peer-table.svelte-mpjrp9.svelte-mpjrp9{flex:1;overflow:auto;min-height:0;min-width:0}.table-row.svelte-mpjrp9.svelte-mpjrp9{display:grid;grid-template-columns:minmax(56px,72px) minmax(72px,1fr) minmax(88px,110px) minmax(48px,70px) minmax(52px,72px) minmax(64px,80px);gap:8px;align-items:center;padding:10px 16px;min-height:40px;border-bottom:1px solid var(--border-deep);font-size:var(--font-size-sm);min-width:520px}.table-header-row.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-muted);text-transform:uppercase;font-size:var(--font-size-xs);letter-spacing:.4px}.self-row.svelte-mpjrp9.svelte-mpjrp9{background:var(--bg-surface)}.nickname.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-bright);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.self-tag.svelte-mpjrp9.svelte-mpjrp9{margin-left:6px;font-size:var(--font-size-xs);color:var(--text-muted)}.col-ip.svelte-mpjrp9.svelte-mpjrp9,.col-ping.svelte-mpjrp9.svelte-mpjrp9,.col-path.svelte-mpjrp9.svelte-mpjrp9{font-family:var(--font-mono);color:var(--text-secondary)}.col-ping.probing.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-bright)}.clickable.svelte-mpjrp9.svelte-mpjrp9{cursor:pointer}.clickable.svelte-mpjrp9.svelte-mpjrp9:hover{color:var(--text-bright)}.status-cell.svelte-mpjrp9.svelte-mpjrp9{display:flex;align-items:center;gap:6px}.status-text.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs);color:var(--text-secondary)}.sq.svelte-mpjrp9.svelte-mpjrp9{width:8px;height:8px;display:inline-block;flex-shrink:0}.sq-online.svelte-mpjrp9.svelte-mpjrp9{background:var(--success)}.sq-offline.svelte-mpjrp9.svelte-mpjrp9{background:var(--text-dim)}.col-action.svelte-mpjrp9.svelte-mpjrp9{display:flex;gap:2px;justify-content:flex-end}.row-btn.svelte-mpjrp9.svelte-mpjrp9{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-family:var(--font-mono);min-width:32px;min-height:32px;padding:0}.row-btn.svelte-mpjrp9.svelte-mpjrp9:hover:not(:disabled){color:var(--text-bright)}.row-btn.svelte-mpjrp9.svelte-mpjrp9:disabled{opacity:.35;cursor:not-allowed}.empty-peers.svelte-mpjrp9.svelte-mpjrp9{padding:48px 24px;text-align:center;color:var(--text-muted)}.empty-label.svelte-mpjrp9.svelte-mpjrp9{color:var(--text-secondary);margin:8px 0 4px}.empty-desc.svelte-mpjrp9.svelte-mpjrp9{font-size:var(--font-size-xs)}.statusbar.svelte-1pzfkl{min-height:var(--statusbar-height);background:var(--bg-deep);border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:4px 12px;font-size:var(--font-size-xs);color:var(--text-secondary);flex-shrink:0;font-family:var(--font-mono);z-index:1;position:relative;min-width:0}.status-left.svelte-1pzfkl,.status-right.svelte-1pzfkl{display:flex;align-items:center;gap:8px 14px;min-width:0;flex-wrap:wrap}.status-left.svelte-1pzfkl{flex:0 1 auto}.status-right.svelte-1pzfkl{flex:1 1 auto;justify-content:flex-end;opacity:.85}.status-item.svelte-1pzfkl{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:36ch}.status-server.svelte-1pzfkl{max-width:28ch}.status-room.svelte-1pzfkl{max-width:22ch}.status-ver.svelte-1pzfkl{flex-shrink:0;max-width:none}.degraded.svelte-1pzfkl{color:var(--warning)}.sq.svelte-1pzfkl{display:inline-block;width:7px;height:7px;background:var(--error);vertical-align:middle;flex-shrink:0}.sq.sq-connected.svelte-1pzfkl{background:var(--success)}.sq.sq-warn.svelte-1pzfkl{background:var(--warning)}.connect-view.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;justify-content:center;width:100%;height:100%;padding:32px 24px}.connect-form.svelte-1br9j49.svelte-1br9j49,.connected-info.svelte-1br9j49.svelte-1br9j49{width:min(360px,100%);display:flex;flex-direction:column;gap:16px;animation:svelte-1br9j49-connectIn .45s cubic-bezier(.16,1,.3,1) both}@keyframes svelte-1br9j49-connectIn{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.brand-block.svelte-1br9j49.svelte-1br9j49{text-align:center;margin-bottom:12px}.brand.svelte-1br9j49.svelte-1br9j49{font-family:var(--font-display);font-size:clamp(36px,7vw,48px);font-weight:400;letter-spacing:.02em;text-transform:uppercase;color:var(--text-bright);line-height:1.05}.tagline.svelte-1br9j49.svelte-1br9j49{margin-top:10px;font-size:var(--font-size-sm);color:var(--text-secondary);text-transform:none;letter-spacing:.02em;line-height:1.45}.field.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:7px}label.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-secondary);text-transform:uppercase;letter-spacing:.08em}input.svelte-1br9j49.svelte-1br9j49{background:#111111d9;border:1px solid var(--border-light);color:var(--text-bright);padding:13px 14px;min-height:44px;font-family:var(--font-mono);font-size:var(--font-size);transition:border-color .15s ease,background .15s ease}input.svelte-1br9j49.svelte-1br9j49::placeholder{color:var(--text-dim)}input.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--border-hover)}input.svelte-1br9j49.svelte-1br9j49:focus{outline:none;border-color:var(--text-bright);background:#141414f2}input.invalid.svelte-1br9j49.svelte-1br9j49{border-color:var(--error)}.field-error.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--error)}.connect-btn.svelte-1br9j49.svelte-1br9j49,.disconnect-btn.svelte-1br9j49.svelte-1br9j49,.secondary-btn.svelte-1br9j49.svelte-1br9j49{border:none;padding:15px 18px;min-height:48px;font-family:var(--font-mono);font-size:var(--font-size);cursor:pointer;text-transform:uppercase;letter-spacing:.12em;font-weight:600;transition:background .15s ease,border-color .15s ease,transform .12s ease}.connect-btn.svelte-1br9j49.svelte-1br9j49{margin-top:4px;background:var(--accent);color:var(--accent-ink)}.connect-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){background:var(--accent-hover);transform:translateY(-1px)}.connect-btn.svelte-1br9j49.svelte-1br9j49:active:not(:disabled){transform:translateY(0)}.connect-btn.svelte-1br9j49.svelte-1br9j49:disabled{opacity:.45;cursor:not-allowed;transform:none}.secondary-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--text-primary);border:1px solid var(--border-light);font-weight:500;letter-spacing:.08em}.secondary-btn.svelte-1br9j49.svelte-1br9j49:hover:not(:disabled){border-color:var(--accent);color:var(--text-bright)}.disconnect-btn.svelte-1br9j49.svelte-1br9j49{background:transparent;color:var(--error);border:1px solid var(--error);font-weight:500}.phase.svelte-1br9j49.svelte-1br9j49{font-size:var(--font-size-xs);color:var(--text-muted);text-align:center;letter-spacing:.04em}.invite-disclosure.svelte-1br9j49.svelte-1br9j49{margin-top:8px;border-top:1px solid var(--border);padding-top:14px}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49{cursor:pointer;color:var(--text-muted);font-size:var(--font-size-sm);list-style:none;min-height:36px;display:flex;align-items:center;justify-content:center;transition:color .15s ease}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:hover{color:var(--text-secondary)}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49::-webkit-details-marker{display:none}.invite-disclosure.svelte-1br9j49 summary.svelte-1br9j49:before{content:"+";margin-right:8px;color:var(--text-dim)}.invite-disclosure[open].svelte-1br9j49 summary.svelte-1br9j49:before{content:"−"}.invite-block.svelte-1br9j49.svelte-1br9j49{display:flex;flex-direction:column;gap:10px;margin-top:12px}.connected-line.svelte-1br9j49.svelte-1br9j49{display:flex;align-items:center;gap:8px;color:var(--text-bright)}.info-line.svelte-1br9j49.svelte-1br9j49{display:flex;justify-content:space-between;font-size:var(--font-size-sm);color:var(--text-secondary)}.info-value.svelte-1br9j49.svelte-1br9j49{color:var(--text-primary);font-family:var(--font-mono)}.sq.svelte-1br9j49.svelte-1br9j49{width:8px;height:8px;display:inline-block}.sq-green.svelte-1br9j49.svelte-1br9j49{background:var(--success)}.sq-warn.svelte-1br9j49.svelte-1br9j49{background:var(--warning)}.sr-only.svelte-1br9j49.svelte-1br9j49{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.light-theme input.svelte-1br9j49.svelte-1br9j49{background:#ffffffa6}.light-theme input.svelte-1br9j49.svelte-1br9j49:focus{background:#ffffffe6}.chat-view.svelte-11c1d7e.svelte-11c1d7e{display:flex;flex-direction:column;height:100%}.chat-header.svelte-11c1d7e.svelte-11c1d7e{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--border);background:var(--bg-surface)}.back-btn.svelte-11c1d7e.svelte-11c1d7e{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:transparent;border:1px solid var(--border);color:var(--text-secondary);cursor:pointer;font-family:var(--font-mono)}.chat-title.svelte-11c1d7e.svelte-11c1d7e{color:var(--text-bright);font-size:var(--font-size)}.chat-messages.svelte-11c1d7e.svelte-11c1d7e{flex:1;overflow-y:auto;padding:16px;min-height:0}.empty-chat.svelte-11c1d7e.svelte-11c1d7e{text-align:center;padding:40px 16px;color:var(--text-muted)}.empty-chat-label.svelte-11c1d7e.svelte-11c1d7e{color:var(--text-secondary);margin:8px 0 4px}.empty-chat-desc.svelte-11c1d7e.svelte-11c1d7e{font-size:var(--font-size-xs)}.date-sep.svelte-11c1d7e.svelte-11c1d7e{text-align:center;font-size:var(--font-size-xs);color:var(--text-dim);margin:12px 0}.system-line.svelte-11c1d7e.svelte-11c1d7e{text-align:center;font-size:var(--font-size-xs);color:var(--text-muted);margin:8px 0}.msg.svelte-11c1d7e.svelte-11c1d7e{margin-bottom:10px;max-width:80%}.msg.self.svelte-11c1d7e.svelte-11c1d7e{margin-left:auto;text-align:right}.msg-meta.svelte-11c1d7e.svelte-11c1d7e{font-size:var(--font-size-xs);color:var(--text-muted);margin-bottom:2px}.msg-body.svelte-11c1d7e.svelte-11c1d7e{display:inline-block;padding:8px 10px;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);white-space:pre-wrap;word-break:break-word;text-align:left}.msg.self.svelte-11c1d7e .msg-body.svelte-11c1d7e{background:var(--bg-active)}.retry-btn.svelte-11c1d7e.svelte-11c1d7e{margin-left:6px;background:transparent;border:none;color:var(--error);cursor:pointer;font-size:var(--font-size-xs)}.chat-input-area.svelte-11c1d7e.svelte-11c1d7e{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border);background:var(--bg-surface)}textarea.svelte-11c1d7e.svelte-11c1d7e{flex:1;resize:none;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);padding:8px 10px;font-family:var(--font-mono);font-size:var(--font-size);min-height:36px}textarea.svelte-11c1d7e.svelte-11c1d7e:disabled{opacity:.5}.send-btn.svelte-11c1d7e.svelte-11c1d7e{background:var(--accent);color:var(--accent-ink);border:none;padding:0 16px;cursor:pointer;font-family:var(--font-mono);text-transform:uppercase}.send-btn.svelte-11c1d7e.svelte-11c1d7e:disabled{opacity:.4;cursor:not-allowed}.settings-view.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;flex-direction:column;height:100%;padding:24px 32px}.settings-content.svelte-1pfl9w0.svelte-1pfl9w0{flex:1;overflow-y:auto;min-height:0;height:0}.settings-title.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size);color:var(--text-bright);text-transform:uppercase;letter-spacing:1px;font-weight:500;margin-bottom:20px}.reconnect-banner.svelte-1pfl9w0.svelte-1pfl9w0{background:var(--bg-raised);border:1px solid var(--border-hover);color:var(--text-bright);padding:10px 12px;margin-bottom:16px;font-size:var(--font-size-sm)}.section.svelte-1pfl9w0.svelte-1pfl9w0{margin-bottom:24px}.section-title.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size-xs);color:var(--text-muted);letter-spacing:1px}.hint.svelte-1pfl9w0.svelte-1pfl9w0{font-size:var(--font-size-xs);color:var(--text-muted);margin:6px 0 12px;line-height:1.4}.reconnect-hint.svelte-1pfl9w0.svelte-1pfl9w0{color:var(--text-secondary)}.setting-row.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;align-items:center;gap:12px;margin-bottom:10px;min-height:32px}.setting-label.svelte-1pfl9w0.svelte-1pfl9w0{min-width:140px;color:var(--text-secondary);font-size:var(--font-size-sm)}.toggle-label.svelte-1pfl9w0.svelte-1pfl9w0{color:var(--text-muted);font-size:var(--font-size-xs)}input[type=text].svelte-1pfl9w0.svelte-1pfl9w0,input[type=password].svelte-1pfl9w0.svelte-1pfl9w0,input[type=number].svelte-1pfl9w0.svelte-1pfl9w0,select.svelte-1pfl9w0.svelte-1pfl9w0{flex:1;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);padding:8px 10px;min-height:36px;font-family:var(--font-mono);font-size:var(--font-size-sm)}input[type=checkbox].svelte-1pfl9w0.svelte-1pfl9w0{width:18px;height:18px}.radio-group.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;gap:12px}.radio-option.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;align-items:center;gap:6px;color:var(--text-secondary);font-size:var(--font-size-sm);min-height:32px}.scale-row.svelte-1pfl9w0 input[type=range].svelte-1pfl9w0{flex:1;min-width:120px;accent-color:var(--accent)}.scale-value.svelte-1pfl9w0.svelte-1pfl9w0{min-width:44px;text-align:right;color:var(--text-secondary);font-size:var(--font-size-sm);font-family:var(--font-mono)}.actions-section.svelte-1pfl9w0.svelte-1pfl9w0{display:flex;gap:8px;align-items:center}.actions-section.svelte-1pfl9w0 .btn.svelte-1pfl9w0{min-height:36px;padding:8px 14px}.update-row.svelte-1pfl9w0.svelte-1pfl9w0{flex-wrap:wrap}.update-row.svelte-1pfl9w0 .btn.svelte-1pfl9w0{min-height:36px;padding:8px 14px}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0,.btn-update.svelte-1pfl9w0.svelte-1pfl9w0{background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size-sm);cursor:pointer}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0:hover:not(:disabled),.btn-update.svelte-1pfl9w0.svelte-1pfl9w0:hover:not(:disabled){border-color:var(--border-hover);color:var(--text-bright)}.btn-check.svelte-1pfl9w0.svelte-1pfl9w0:disabled,.btn-update.svelte-1pfl9w0.svelte-1pfl9w0:disabled{opacity:.5;cursor:default}.ver.svelte-1pfl9w0.svelte-1pfl9w0{margin-left:auto;color:var(--text-dim);font-size:var(--font-size-xs)}.shell.svelte-1hi7jen{display:flex;flex-direction:column;height:100%;width:100%;position:relative;z-index:1;min-height:0}.connect-shell.svelte-1hi7jen{z-index:1}.layout.svelte-1hi7jen{display:flex;flex:1;min-height:0;position:relative}.fullscreen-connect.svelte-1hi7jen{display:flex;flex:1;width:100%;align-items:center;justify-content:center;min-height:0}.sidebar-wrapper.svelte-1hi7jen{position:relative;flex-shrink:0;background:var(--bg-surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden;min-height:0}.drag-handle.svelte-1hi7jen{position:absolute;top:0;right:-3px;width:6px;height:100%;cursor:col-resize;z-index:10;background:transparent;transition:background .1s}.drag-handle.svelte-1hi7jen:hover,.drag-handle.active.svelte-1hi7jen,.drag-handle.svelte-1hi7jen:focus-visible{background:var(--border-hover)}.main-area.svelte-1hi7jen{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--bg-primary);min-width:0;min-height:0}.view-fade.svelte-1hi7jen{flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;animation:svelte-1hi7jen-viewIn .2s ease-out}@keyframes svelte-1hi7jen-viewIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.unknown-view.svelte-1hi7jen{padding:40px;color:var(--text-muted)}.error-strip.svelte-1hi7jen{position:fixed;left:12px;right:12px;bottom:calc(var(--statusbar-height) + 12px);z-index:1100;display:flex;align-items:center;gap:12px;padding:10px 14px;background:var(--bg-raised);border:1px solid var(--error);color:var(--error);font-size:var(--font-size-sm)}.error-strip-msg.svelte-1hi7jen{flex:1;min-width:0;word-break:break-word}.error-strip-dismiss.svelte-1hi7jen{flex-shrink:0;min-height:32px;padding:4px 10px;border:1px solid var(--error);background:transparent;color:var(--error);cursor:pointer;font-family:var(--font-mono);font-size:var(--font-size-xs);text-transform:uppercase}.error-strip-dismiss.svelte-1hi7jen:hover{background:#c45c5c1f}.notification.svelte-1hi7jen{position:fixed;top:12px;right:12px;padding:6px 12px;font-size:var(--font-size-sm);z-index:1000;background:var(--bg-raised);border:1px solid var(--border);color:var(--text-primary);animation:svelte-1hi7jen-slideIn .15s ease-out}.notification.error.svelte-1hi7jen{border-color:var(--error);color:var(--error)}.notification.info.svelte-1hi7jen{border-color:var(--border)}.notif-icon.svelte-1hi7jen{margin-right:6px;font-weight:700}@keyframes svelte-1hi7jen-slideIn{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.space-bg,.space-bg:before,.space-bg:after,.space-dust,.space-dust:before{position:fixed;pointer-events:none;z-index:0}.space-bg{inset:0;background:radial-gradient(ellipse 85% 65% at 50% 36%,rgba(255,255,255,.045) 0%,transparent 55%),radial-gradient(ellipse 120% 80% at 50% 100%,rgba(255,255,255,.03) 0%,transparent 50%),radial-gradient(ellipse 100% 100% at 50% 50%,#0a0a0a,#050505 70%,#000)}.space-bg:before{content:"";position:absolute;inset:0;opacity:.8;background:radial-gradient(1.2px 1.2px at 5% 10%,rgba(255,255,255,.55) 0%,transparent 100%),radial-gradient(1px 1px at 12% 32%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 18% 68%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 25% 45%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 32% 18%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 38% 78%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 45% 15%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 52% 58%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 58% 28%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 65% 10%,rgba(255,255,255,.5) 0%,transparent 100%),radial-gradient(1px 1px at 72% 72%,rgba(255,255,255,.35) 0%,transparent 100%),radial-gradient(1px 1px at 78% 40%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 85% 65%,rgba(255,255,255,.48) 0%,transparent 100%),radial-gradient(1px 1px at 90% 22%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(1px 1px at 94% 88%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 8% 88%,rgba(255,255,255,.26) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 30% 92%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(1px 1px at 48% 42%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(1px 1px at 62% 88%,rgba(255,255,255,.32) 0%,transparent 100%),radial-gradient(1px 1px at 88% 52%,rgba(255,255,255,.26) 0%,transparent 100%)}.space-bg:after{content:"";position:absolute;inset:0;background-image:radial-gradient(1.5px 1.5px at 8% 18%,rgba(255,255,255,.7) 0%,transparent 100%),radial-gradient(1.2px 1.2px at 48% 38%,rgba(255,255,255,.6) 0%,transparent 100%),radial-gradient(1.5px 1.5px at 88% 28%,rgba(255,255,255,.65) 0%,transparent 100%),radial-gradient(1px 1px at 22% 55%,rgba(255,255,255,.45) 0%,transparent 100%),radial-gradient(1px 1px at 70% 60%,rgba(255,255,255,.4) 0%,transparent 100%);animation:twinkle 9s ease-in-out infinite alternate;opacity:.5}@keyframes twinkle{0%{opacity:.2}45%{opacity:.5}to{opacity:.25}}.space-dust{inset:0;background:radial-gradient(ellipse 80% 70% at 50% 45%,transparent 42%,rgba(0,0,0,.62) 100%);opacity:1}.space-dust:before{content:"";position:absolute;inset:0;opacity:.32;background:radial-gradient(.5px .5px at 20% 30%,rgba(255,255,255,.4) 0%,transparent 100%),radial-gradient(.5px .5px at 40% 60%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 60% 25%,rgba(255,255,255,.28) 0%,transparent 100%),radial-gradient(.5px .5px at 75% 70%,rgba(255,255,255,.3) 0%,transparent 100%),radial-gradient(.5px .5px at 88% 40%,rgba(255,255,255,.3) 0%,transparent 100%)}.light-theme .space-bg,.light-theme .space-bg:before,.light-theme .space-bg:after,.light-theme .space-dust,.light-theme .space-dust:before{display:none!important}@font-face{font-family:Bungee;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/bungee-latin-Dfnurram.woff2) format("woff2")}:root{--bg-deep: #000000;--bg-primary: #050505;--bg-surface: #0a0a0a;--bg-raised: #111111;--bg-hover: #181818;--bg-active: #1f1f1f;--border-deep: #111111;--border: #1c1c1c;--border-light: #2a2a2a;--border-hover: #3d3d3d;--text-bright: #f5f5f5;--text-primary: #c8c8c8;--text-secondary: #8a8a8a;--text-muted: #5c5c5c;--text-dim: #3a3a3a;--accent: #f0f0f0;--accent-hover: #ffffff;--accent-ink: #000000;--success: #9a9a9a;--warning: #c8c8c8;--error: #c45c5c;--focus-ring: #f0f0f0;--sidebar-width: 220px;--statusbar-height: 28px;--font-display: "Bungee", ui-sans-serif, system-ui, sans-serif;--font-mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, "Liberation Mono", monospace;--font-size: 12px;--font-size-sm: 11px;--font-size-xs: 10px;--line-height: 1.6}.light-theme{--bg-deep: #f5f5f5;--bg-primary: #f0f0f0;--bg-surface: #e8e8e8;--bg-raised: #e0e0e0;--bg-hover: #d8d8d8;--bg-active: #cfcfcf;--border-deep: #d0d0d0;--border: #cccccc;--border-light: #bbbbbb;--border-hover: #999999;--text-bright: #111111;--text-primary: #222222;--text-secondary: #555555;--text-muted: #888888;--text-dim: #aaaaaa;--accent: #000000;--accent-hover: #222222;--accent-ink: #f5f5f5;--success: #555555;--warning: #333333;--error: #b33a3a;--focus-ring: #000000}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html,body,#app{height:100%;width:100%;overflow:hidden;color:var(--text-primary);font-family:var(--font-mono);font-size:var(--font-size);line-height:var(--line-height);-webkit-font-smoothing:antialiased;user-select:auto}html,body{background:var(--bg-deep)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border)}::-webkit-scrollbar-thumb:hover{background:var(--border-hover)}::-webkit-scrollbar-corner{background:transparent}::selection{background:#ffffff1a;color:var(--text-bright)}input,textarea,button,select{font-family:var(--font-mono);font-size:var(--font-size)}input:focus-visible,textarea:focus-visible,select:focus-visible,button:focus-visible,[tabindex]:focus-visible,.network-item:focus-visible,.clickable:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}button{cursor:pointer;border:none;background:none;color:inherit}a{color:var(--text-bright);text-decoration:none}a:hover{text-decoration:underline}.btn{padding:8px 12px;min-height:36px;border:1px solid var(--border);background:var(--bg-raised);color:var(--text-primary);cursor:pointer;font-size:var(--font-size-sm);text-align:center;font-family:var(--font-mono);transition:background .1s ease,opacity .1s ease}.btn:hover:not(:disabled){background:var(--bg-hover)}.btn.primary,.btn-save{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:500}.btn.primary:hover,.btn-save:hover{background:var(--accent-hover)}.btn:disabled{opacity:.4;cursor:not-allowed}.btn.danger{color:var(--error);border-color:var(--error)}.empty-state{padding:16px;text-align:center;color:var(--text-muted);font-size:var(--font-size-sm)} diff --git a/client/frontend/dist/index.html b/client/frontend/dist/index.html index da5e5ee..739c979 100644 --- a/client/frontend/dist/index.html +++ b/client/frontend/dist/index.html @@ -7,8 +7,8 @@ Entangled VPN - - + +
diff --git a/client/frontend/src/App.svelte b/client/frontend/src/App.svelte index 5c46983..ad084ba 100644 --- a/client/frontend/src/App.svelte +++ b/client/frontend/src/App.svelte @@ -2,12 +2,14 @@ import { onMount, onDestroy } from 'svelte' import { status, peers, view, settings, notifications, durableError, clearDurableError, addNotification, addChatMessage, addSystemChat } from './lib/stores/app.js' import { currentLang, setLang, t, fmt } from './lib/locales/index.js' + import { derivePathAggregate } from './lib/path.js' import Sidebar from './lib/components/Sidebar.svelte' import PeerList from './lib/components/PeerList.svelte' import StatusBar from './lib/components/StatusBar.svelte' import ConnectView from './lib/components/ConnectView.svelte' import ChatView from './lib/components/ChatView.svelte' import SettingsView from './lib/components/SettingsView.svelte' + import ConnectedHeader from './lib/components/ConnectedHeader.svelte' function clampScale(n) { const v = Number(n) || 100 @@ -27,6 +29,13 @@ } } + $: document.documentElement.setAttribute( + 'data-app', + $view === 'connect' ? 'connect' : 'connected', + ) + + $: pathAggregate = derivePathAggregate($status, $peers) + let sidebarWidth = 220 let isDragging = false let startX, startWidth @@ -127,8 +136,10 @@ }) - - +{#if $view === 'connect'} + + +{/if} {#if $view === 'connect'}
@@ -137,7 +148,16 @@
{:else} -
+
+ +
-
- {#if $view === 'network'} - - {:else if $view === 'chat'} - - {:else if $view === 'settings'} - - {:else} -
Unknown view: {$view}
- {/if} -
+ {#key $view} +
+ {#if $view === 'network'} + + {:else if $view === 'chat'} + + {:else if $view === 'settings'} + + {:else} +
Unknown view: {$view}
+ {/if} +
+ {/key}
- +
{/if} @@ -197,6 +219,9 @@ .connect-shell { z-index: 1; } + .connected-shell { + background: var(--bg-primary); + } .layout { display: flex; flex: 1; @@ -243,17 +268,23 @@ min-width: 0; min-height: 0; } - .view-fade { + .view-pane { flex: 1; display: flex; flex-direction: column; min-height: 0; min-width: 0; - animation: viewIn 0.2s ease-out; + animation: viewIn 180ms var(--ease-out, ease-out) both; } @keyframes viewIn { - 0% { opacity: 0; transform: translateY(8px); } - 100% { opacity: 1; transform: translateY(0); } + from { + opacity: 0; + transform: translateY(4px); + } + to { + opacity: 1; + transform: translateY(0); + } } .unknown-view { padding: 40px; @@ -294,6 +325,10 @@ .error-strip-dismiss:hover { background: rgba(196, 92, 92, 0.12); } + @keyframes slideIn { + from { transform: translateX(12px); opacity: 0; } + to { transform: translateX(0); opacity: 1; } + } .notification { position: fixed; top: 12px; @@ -304,7 +339,7 @@ background: var(--bg-raised); border: 1px solid var(--border); color: var(--text-primary); - animation: slideIn 0.15s ease-out; + animation: slideIn 160ms var(--ease-out, ease-out) both; } .notification.error { border-color: var(--error); @@ -317,8 +352,4 @@ margin-right: 6px; font-weight: 700; } - @keyframes slideIn { - from { transform: translateX(100%); opacity: 0; } - to { transform: translateX(0); opacity: 1; } - } diff --git a/client/frontend/src/app.css b/client/frontend/src/app.css index 8e245a1..c599898 100644 --- a/client/frontend/src/app.css +++ b/client/frontend/src/app.css @@ -1,4 +1,5 @@ @import './space.css'; +@import './connected.css'; @font-face { font-family: 'Bungee'; diff --git a/client/frontend/src/connected.css b/client/frontend/src/connected.css new file mode 100644 index 0000000..30efdd6 --- /dev/null +++ b/client/frontend/src/connected.css @@ -0,0 +1,194 @@ +/* Connected Operate shell. Intro keeps :root / Bungee / space.css. */ + +html[data-app="connected"] { + --bg-deep: #0a0a0a; + --bg-primary: #0a0a0a; + --bg-surface: #111111; + --bg-raised: #181818; + --bg-hover: #1c1c1c; + --bg-active: #222222; + --border-deep: #1a1a1a; + --border: #2a2a2a; + --border-light: #3a3a3a; + --border-hover: #4a4a4a; + --text-bright: #f0f0f0; + --text-primary: #f0f0f0; + --text-secondary: #8a8a8a; + --text-muted: #8a8a8a; + --text-dim: #5c5c5c; + --accent: #ffffff; + --accent-hover: #f0f0f0; + --accent-ink: #0a0a0a; + --live: #2fbf62; + --fault: #e23d3d; + --success: #8a8a8a; + --warning: #8a8a8a; + --error: #e23d3d; + --focus-ring: #f0f0f0; + --font-sans: ui-sans-serif, 'Segoe UI', system-ui, sans-serif; + --font-mono: ui-monospace, 'Cascadia Code', Consolas, monospace; + --font-size: 13px; + --font-size-sm: 12px; + --font-size-xs: 10px; + --line-height: 1.45; + --radius-sm: 4px; + --radius-md: 6px; + --statusbar-height: 26px; + --ease-out: cubic-bezier(0.16, 1, 0.3, 1); + --dur-fast: 120ms; + --dur-mid: 180ms; +} + +html[data-app="connected"].light-theme { + --bg-deep: #f5f5f5; + --bg-primary: #f5f5f5; + --bg-surface: #ececec; + --bg-raised: #e4e4e4; + --bg-hover: #dedede; + --bg-active: #d6d6d6; + --border-deep: #e0e0e0; + --border: #d0d0d0; + --border-light: #c4c4c4; + --border-hover: #999999; + --text-bright: #111111; + --text-primary: #111111; + --text-secondary: #5c5c5c; + --text-muted: #6a6a6a; + --text-dim: #8a8a8a; + --accent: #111111; + --accent-hover: #000000; + --accent-ink: #f5f5f5; + --live: #1a8f45; + --fault: #c41e1e; + --success: #6a6a6a; + --warning: #6a6a6a; + --error: #c41e1e; + --focus-ring: #111111; +} + +html[data-app="connected"], +html[data-app="connected"] body, +html[data-app="connected"] #app { + color: var(--text-primary); + font-family: var(--font-sans); + font-size: var(--font-size); + line-height: var(--line-height); + background: var(--bg-deep); +} + +html[data-app="connected"] input, +html[data-app="connected"] textarea, +html[data-app="connected"] button, +html[data-app="connected"] select { + font-family: inherit; +} + +html[data-app="connected"] .btn { + padding: 6px 12px; + min-height: 32px; + height: 32px; + border: 1px solid var(--border); + border-radius: var(--radius-md); + background: transparent; + color: var(--text-primary); + cursor: pointer; + font-size: var(--font-size-sm); + text-align: center; + font-family: var(--font-sans); + transition: + background var(--dur-fast) ease, + border-color var(--dur-fast) ease, + opacity var(--dur-fast) ease, + transform var(--dur-fast) ease; +} + +html[data-app="connected"] .btn:hover:not(:disabled) { + background: var(--bg-hover); + border-color: var(--border-hover); +} + +html[data-app="connected"] .btn:active:not(:disabled) { + transform: translateY(1px); +} + +html[data-app="connected"] .btn.primary, +html[data-app="connected"] .btn-save { + background: var(--accent); + border-color: var(--accent); + color: var(--accent-ink); + font-weight: 500; +} + +html[data-app="connected"] .btn.primary:hover, +html[data-app="connected"] .btn-save:hover { + background: var(--accent-hover); +} + +html[data-app="connected"] .btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +html[data-app="connected"] .btn.danger { + color: var(--fault); + border-color: var(--fault); +} + +html[data-app="connected"] .path-dot { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; + flex-shrink: 0; + background: var(--text-dim); +} + +html[data-app="connected"] .path-dot.direct { + background: var(--live); +} + +html[data-app="connected"] .path-dot.relay, +html[data-app="connected"] .path-dot.reconnecting { + background: var(--fault); +} + +html[data-app="connected"] .path-dot.reconnecting { + animation: pathPulse 1.2s var(--ease-out) infinite; +} + +html[data-app="connected"] .path-dot.disconnected { + background: var(--text-dim); +} + +html[data-app="connected"] .unread-badge { + background: var(--fault); + color: #fff; +} + +@keyframes pathPulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.35; } +} + +html[data-app="connected"] .connected-shell { + animation: shellIn var(--dur-mid) var(--ease-out) both; +} + +@keyframes shellIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@media (prefers-reduced-motion: reduce) { + html[data-app="connected"] { + --dur-fast: 0.01ms; + --dur-mid: 0.01ms; + } + html[data-app="connected"] *, + html[data-app="connected"] *::before, + html[data-app="connected"] *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} diff --git a/client/frontend/src/lib/components/ChatView.svelte b/client/frontend/src/lib/components/ChatView.svelte index e2a6055..b0d48e8 100644 --- a/client/frontend/src/lib/components/ChatView.svelte +++ b/client/frontend/src/lib/components/ChatView.svelte @@ -128,14 +128,17 @@
- + {title}
{#if $chatMessages.length === 0}
-
[ . . . ]
{$t.no_messages}
{$t.no_messages_desc}
@@ -197,9 +200,9 @@ justify-content: center; background: transparent; border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-secondary); cursor: pointer; - font-family: var(--font-mono); } .chat-title { color: var(--text-bright); @@ -245,6 +248,7 @@ padding: 8px 10px; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); white-space: pre-wrap; word-break: break-word; @@ -273,9 +277,10 @@ resize: none; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); padding: 8px 10px; - font-family: var(--font-mono); + font-family: inherit; font-size: var(--font-size); min-height: 36px; } @@ -284,9 +289,10 @@ background: var(--accent); color: var(--accent-ink); border: none; + border-radius: var(--radius-md, 6px); padding: 0 16px; cursor: pointer; - font-family: var(--font-mono); + font-family: inherit; text-transform: uppercase; } .send-btn:disabled { opacity: 0.4; cursor: not-allowed; } diff --git a/client/frontend/src/lib/components/ConnectedHeader.svelte b/client/frontend/src/lib/components/ConnectedHeader.svelte new file mode 100644 index 0000000..682ed13 --- /dev/null +++ b/client/frontend/src/lib/components/ConnectedHeader.svelte @@ -0,0 +1,171 @@ + + +
+ {$t.brand} + +
+
+ {$t.header_room} + {$status.room || $t.na} +
+
+ {$t.header_vip} + +
+
+ {$t.header_path} + + + {pathLabel} + +
+
+ {$t.header_peers} + {fmt($t.peer_count, { n: $status.peerCount ?? 0 })} +
+
+ +
+ + +
+
+ + diff --git a/client/frontend/src/lib/components/PeerList.svelte b/client/frontend/src/lib/components/PeerList.svelte index 8107a91..a6e3112 100644 --- a/client/frontend/src/lib/components/PeerList.svelte +++ b/client/frontend/src/lib/components/PeerList.svelte @@ -6,7 +6,6 @@ $: sortedPeers = [...$peers].sort((a, b) => (a.nickname || '').localeCompare(b.nickname || '')) $: roomUnread = $unread['room:' + ($status.room || 'network')] || 0 - $: anyRelay = $peers.some(p => p.path === 'relay' || p.path === 'ws') function openPeerChat(peer) { chatTarget.set({ id: peer.id, nickname: peer.nickname || peer.id }) @@ -56,6 +55,12 @@ return $t.path_unknown } + function pathTone(path) { + if (path === 'p2p') return 'direct' + if (path === 'relay' || path === 'ws') return 'relay' + return '' + } + function pathTip(path) { if (path === 'p2p') return $t.path_p2p_tip if (path === 'relay') return $t.path_relay_tip @@ -73,19 +78,13 @@
-

{$status.room || $t.network}

- +

{$t.header_peers}

{#if $status.room} {/if} - {#if anyRelay} - {$t.status_relay_degraded} - {/if}
@@ -127,7 +126,7 @@ {peer.nickname || peer.id} - {#if peerUnread(peer.id) > 0}{peerUnread(peer.id)}{/if} + {#if peerUnread(peer.id) > 0}{peerUnread(peer.id)}{/if} {peer.path ? pathLabel(peer.path) : $t.path_unknown} + > + {#if peer.path} + + {pathLabel(peer.path)} + {:else} + {$t.path_unknown} + {/if} + + > + + + > + +
{:else}
-
[ . . . ]
{$t.no_peers}
{$t.no_peers_desc}
@@ -192,29 +207,19 @@ flex-wrap: wrap; } .peer-header h2 { - font-size: var(--font-size); - font-weight: 500; - color: var(--text-bright); + font-size: 10px; + font-weight: 600; + color: var(--text-dim); text-transform: uppercase; - letter-spacing: 0.5px; - } - .ip-badge { - padding: 4px 8px; - min-height: 28px; - background: var(--bg-raised); - font-size: var(--font-size-xs); - font-family: var(--font-mono); - color: var(--text-secondary); - border: 1px solid var(--border); - cursor: pointer; + letter-spacing: 0.08em; } - .ip-badge:hover { border-color: var(--border-hover); color: var(--text-bright); } .room-chat-btn { margin-left: auto; background: transparent; border: 1px solid var(--border); + border-radius: var(--radius-md, 6px); color: var(--text-secondary); - font-family: var(--font-mono); + font-family: inherit; font-size: var(--font-size-xs); padding: 6px 10px; min-height: 32px; @@ -222,17 +227,13 @@ position: relative; } .room-chat-btn:hover { color: var(--text-bright); border-color: var(--border-hover); } - .relay-hint { - font-size: var(--font-size-xs); - color: var(--text-muted); - } .badge { display: inline-block; min-width: 14px; padding: 0 4px; margin-left: 4px; - background: var(--accent); - color: var(--accent-ink); + background: var(--fault, var(--error)); + color: #fff; font-size: 10px; line-height: 14px; text-align: center; @@ -245,7 +246,7 @@ } .table-row { display: grid; - grid-template-columns: minmax(56px, 72px) minmax(72px, 1fr) minmax(88px, 110px) minmax(48px, 70px) minmax(52px, 72px) minmax(64px, 80px); + grid-template-columns: minmax(56px, 72px) minmax(72px, 1fr) minmax(88px, 110px) minmax(48px, 70px) minmax(72px, 96px) minmax(64px, 80px); gap: 8px; align-items: center; padding: 10px 16px; @@ -253,12 +254,16 @@ border-bottom: 1px solid var(--border-deep); font-size: var(--font-size-sm); min-width: 520px; + transition: background var(--dur-fast, 120ms) ease; + } + .table-row:not(.table-header-row):hover { + background: var(--bg-hover); } .table-header-row { color: var(--text-muted); text-transform: uppercase; font-size: var(--font-size-xs); - letter-spacing: 0.4px; + letter-spacing: 0.08em; } .self-row { background: var(--bg-surface); } .nickname { color: var(--text-bright); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @@ -271,6 +276,11 @@ font-family: var(--font-mono); color: var(--text-secondary); } + .col-path { + display: flex; + align-items: center; + gap: 6px; + } .col-ping.probing { color: var(--text-bright); } .clickable { cursor: pointer; } .clickable:hover { color: var(--text-bright); } @@ -286,10 +296,11 @@ .sq { width: 8px; height: 8px; + border-radius: 50%; display: inline-block; flex-shrink: 0; } - .sq-online { background: var(--success); } + .sq-online { background: var(--text-bright); } .sq-offline { background: var(--text-dim); } .col-action { display: flex; @@ -299,12 +310,15 @@ .row-btn { background: transparent; border: none; + border-radius: var(--radius-sm, 4px); color: var(--text-muted); cursor: pointer; - font-family: var(--font-mono); min-width: 32px; min-height: 32px; padding: 0; + display: flex; + align-items: center; + justify-content: center; } .row-btn:hover:not(:disabled) { color: var(--text-bright); } .row-btn:disabled { diff --git a/client/frontend/src/lib/components/SettingsView.svelte b/client/frontend/src/lib/components/SettingsView.svelte index 16909ea..a0113e7 100644 --- a/client/frontend/src/lib/components/SettingsView.svelte +++ b/client/frontend/src/lib/components/SettingsView.svelte @@ -114,7 +114,7 @@

{$t.notif_reconnect_required}

{/if}
-
─── {$t.section_connection} ───
+
{$t.section_connection}
@@ -146,7 +146,7 @@
-
─── {$t.section_network} ───
+
{$t.section_network}

{$t.advanced_warn}

@@ -184,7 +184,7 @@
-
─── {$t.section_system} ───
+
{$t.section_system}
-
─── {$t.section_appearance} ───
+
{$t.section_appearance}
@@ -279,11 +279,11 @@ height: 0; } .settings-title { - font-size: var(--font-size); - color: var(--text-bright); + font-size: 10px; + font-weight: 600; + color: var(--text-dim); text-transform: uppercase; - letter-spacing: 1px; - font-weight: 500; + letter-spacing: 0.08em; margin-bottom: 20px; } .reconnect-banner { @@ -296,9 +296,12 @@ } .section { margin-bottom: 24px; } .section-title { - font-size: var(--font-size-xs); - color: var(--text-muted); - letter-spacing: 1px; + font-size: 10px; + font-weight: 600; + color: var(--text-dim); + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 10px; } .hint { font-size: var(--font-size-xs); @@ -327,9 +330,10 @@ flex: 1; background: var(--bg-raised); border: 1px solid var(--border); + border-radius: var(--radius-sm, 4px); color: var(--text-primary); padding: 8px 10px; - min-height: 36px; + min-height: 32px; font-family: var(--font-mono); font-size: var(--font-size-sm); } @@ -359,9 +363,9 @@ font-family: var(--font-mono); } .actions-section { display: flex; gap: 8px; align-items: center; } - .actions-section .btn { min-height: 36px; padding: 8px 14px; } + .actions-section .btn { min-height: 32px; padding: 6px 12px; } .update-row { flex-wrap: wrap; } - .update-row .btn { min-height: 36px; padding: 8px 14px; } + .update-row .btn { min-height: 32px; padding: 6px 12px; } .btn-check, .btn-update { background: var(--bg-raised); border: 1px solid var(--border); diff --git a/client/frontend/src/lib/components/Sidebar.svelte b/client/frontend/src/lib/components/Sidebar.svelte index 8eec7ea..2bf3b80 100644 --- a/client/frontend/src/lib/components/Sidebar.svelte +++ b/client/frontend/src/lib/components/Sidebar.svelte @@ -17,7 +17,6 @@ let serverAddr = '' let nickname = '' let joining = '' - let prevView = 'network' let menuOpen = null let createDialog let joinDialog @@ -296,7 +295,11 @@ aria-label={$t.more_actions} title={$t.more_actions} on:click={(e) => toggleMenu(e, room.name)} - >⋯ + > {#if menuOpen === room.name} - - {#if showCreate}