Add location-aware automatic default bounding box

The OpenSky "Default bounding box" now follows where flying happens.
A new "Automatic" picker mode (the default) resolves the live-map area
from a location cascade — drone telemetry → phone GPS → browser
geolocation → the user's Region country → Europe — instead of a fixed
box. Manual presets and Custom coordinates still work.

- Web App: new shared countries.js dataset (all countries + bbox,
  offline point→country); the bbox picker gains all European countries
  and an Automatic option (client pref prefs.autoBbox); the Region
  setting expands from 6 locale entries to all countries; the live map
  resolves the cascade each poll and sends it as ?bbox=.
- API Server: the states endpoint accepts and validates a ?bbox=
  override (validBBox); the Web App BFF forwards the query; the hub
  relays new phoneLatitude/phoneLongitude telemetry to the Web App.
- Fly App: reports the phone's own GPS (geolocator) alongside
  telemetry, used as the "your location" fallback.
- API panel: the OpenSky bbox picker lists all European countries.

Builds verified across web, panel, both Go modules and the Fly App
APK. Region list, Automatic default and the cascade ?bbox= override
verified in the browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 4.8 committed 2026-07-14 00:07:12 +02:00
1 parent 150758b0bf
commit 94f6876024
20 files changed
+637 -71

No files matched your search

-17
View File
@@ -1,17 +0,0 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&n(l)}).observe(document,{childList:!0,subtree:!0});function s(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(o){if(o.ep)return;o.ep=!0;const i=s(o);fetch(o.href,i)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function An(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Nt=[],tt=()=>{},$o=()=>!1,Ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),zs=e=>e.startsWith("onUpdate:"),Se=Object.assign,On=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Qi=Object.prototype.hasOwnProperty,Q=(e,t)=>Qi.call(e,t),N=Array.isArray,Ft=e=>ms(e)==="[object Map]",Wt=e=>ms(e)==="[object Set]",eo=e=>ms(e)==="[object Date]",B=e=>typeof e=="function",ce=e=>typeof e=="string",st=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",jo=e=>(te(e)||B(e))&&B(e.then)&&B(e.catch),Do=Object.prototype.toString,ms=e=>Do.call(e),el=e=>ms(e).slice(8,-1),Lo=e=>ms(e)==="[object Object]",Rn=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ss=An(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ws=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},tl=/-\w/g,Be=Ws(e=>e.replace(tl,t=>t.slice(1).toUpperCase())),sl=/\B([A-Z])/g,xt=Ws(e=>e.replace(sl,"-$1").toLowerCase()),No=Ws(e=>e.charAt(0).toUpperCase()+e.slice(1)),on=Ws(e=>e?`on${No(e)}`:""),et=(e,t)=>!Object.is(e,t),Is=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},Fo=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Gs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let to;const qs=()=>to||(to=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function In(e){if(N(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],o=ce(n)?ll(n):In(n);if(o)for(const i in o)t[i]=o[i]}return t}else if(ce(e)||te(e))return e}const nl=/;(?![^(]*\))/g,ol=/:([^]+)/,il=/\/\*[^]*?\*\//g;function ll(e){const t={};return e.replace(il,"").split(nl).forEach(s=>{if(s){const n=s.split(ol);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ue(e){let t="";if(ce(e))t=e;else if(N(e))for(let s=0;s<e.length;s++){const n=Ue(e[s]);n&&(t+=n+" ")}else if(te(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const rl="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",al=An(rl);function Vo(e){return!!e||e===""}function cl(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=vt(e[n],t[n]);return s}function vt(e,t){if(e===t)return!0;let s=eo(e),n=eo(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=st(e),n=st(t),s||n)return e===t;if(s=N(e),n=N(t),s||n)return s&&n?cl(e,t):!1;if(s=te(e),n=te(t),s||n){if(!s||!n)return!1;const o=Object.keys(e).length,i=Object.keys(t).length;if(o!==i)return!1;for(const l in e){const r=e.hasOwnProperty(l),c=t.hasOwnProperty(l);if(r&&!c||!r&&c||!vt(e[l],t[l]))return!1}}return String(e)===String(t)}function Mn(e,t){return e.findIndex(s=>vt(s,t))}const Ho=e=>!!(e&&e.__v_isRef===!0),O=e=>ce(e)?e:e==null?"":N(e)||te(e)&&(e.toString===Do||!B(e.toString))?Ho(e)?O(e.value):JSON.stringify(e,Bo,2):String(e),Bo=(e,t)=>Ho(t)?Bo(e,t.value):Ft(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,o],i)=>(s[ln(n,i)+" =>"]=o,s),{})}:Wt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>ln(s))}:st(t)?ln(t):te(t)&&!N(t)&&!Lo(t)?String(t):t,ln=(e,t="")=>{var s;return st(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let ve;class ul{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ve&&(ve.active?(this.parent=ve,this.index=(ve.scopes||(ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ve;try{return ve=this,t()}finally{ve=s}}}on(){++this._on===1&&(this.prevScope=ve,ve=this)}off(){if(this._on>0&&--this._on===0){if(ve===this)ve=this.prevScope;else{let t=ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const o=this.parent.scopes.pop();o&&o!==this&&(this.parent.scopes[this.index]=o,o.index=this.index)}this.parent=void 0}}}function fl(){return ve}let re;const rn=new WeakSet;class Ko{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ve&&(ve.active?ve.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,rn.has(this)&&(rn.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Wo(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,so(this),Go(this);const t=re,s=Ke;re=this,Ke=!0;try{return this.fn()}finally{qo(this),re=t,Ke=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)jn(t);this.deps=this.depsTail=void 0,so(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?rn.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){vn(this)&&this.run()}get dirty(){return vn(this)}}let zo=0,ns,os;function Wo(e,t=!1){if(e.flags|=8,t){e.next=os,os=e;return}e.next=ns,ns=e}function Un(){zo++}function $n(){if(--zo>0)return;if(os){let t=os;for(os=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;ns;){let t=ns;for(ns=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Go(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function qo(e){let t,s=e.depsTail,n=s;for(;n;){const o=n.prevDep;n.version===-1?(n===s&&(s=o),jn(n),dl(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=o}e.deps=t,e.depsTail=s}function vn(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Jo(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Jo(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===cs)||(e.globalVersion=cs,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!vn(e))))return;e.flags|=2;const t=e.dep,s=re,n=Ke;re=e,Ke=!0;try{Go(e);const o=e.fn(e._value);(t.version===0||et(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{re=s,Ke=n,qo(e),e.flags&=-3}}function jn(e,t=!1){const{dep:s,prevSub:n,nextSub:o}=e;if(n&&(n.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let i=s.computed.deps;i;i=i.nextDep)jn(i,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function dl(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ke=!0;const Yo=[];function nt(){Yo.push(Ke),Ke=!1}function ot(){const e=Yo.pop();Ke=e===void 0?!0:e}function so(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=re;re=void 0;try{t()}finally{re=s}}}let cs=0;class pl{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Dn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!re||!Ke||re===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==re)s=this.activeLink=new pl(re,this),re.deps?(s.prevDep=re.depsTail,re.depsTail.nextDep=s,re.depsTail=s):re.deps=re.depsTail=s,Xo(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=re.depsTail,s.nextDep=void 0,re.depsTail.nextDep=s,re.depsTail=s,re.deps===s&&(re.deps=n)}return s}trigger(t){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function gs(e,t,s,n){try{return n?e(...n):e()}catch(o){Ys(o,t,s)}}function We(e,t,s,n){if(B(e)){const o=gs(e,t,s,n);return o&&jo(o)&&o.catch(i=>{Ys(i,t,s)}),o}if(N(e)){const o=[];for(let i=0;i<e.length;i++)o.push(We(e[i],t,s,n));return o}}function Ys(e,t,s,n=!0){const o=t?t.vnode:null,{errorHandler:i,throwUnhandledErrorInProduction:l}=t&&t.appContext.config||ne;if(t){let r=t.parent;const c=t.proxy,g=`https://vuejs.org/error-reference/#runtime-${s}`;for(;r;){const h=r.ec;if(h){for(let y=0;y<h.length;y++)if(h[y](e,c,g)===!1)return}r=r.parent}if(i){nt(),gs(i,null,10,[e,c,g]),ot();return}}Ll(e,s,o,n,l)}function Ll(e,t,s,n=!0,o=!1){if(o)throw e;console.error(e)}const Pe=[];let Xe=-1;const Vt=[];let gt=null,Dt=0;const ii=Promise.resolve();let Ds=null;function li(e){const t=Ds||ii;return e?t.then(this?e.bind(this):e):t}function Nl(e){let t=Xe+1,s=Pe.length;for(;t<s;){const n=t+s>>>1,o=Pe[n],i=fs(o);i<e||i===e&&o.flags&2?t=n+1:s=n}return t}function Hn(e){if(!(e.flags&1)){const t=fs(e),s=Pe[Pe.length-1];!s||!(e.flags&2)&&t>=fs(s)?Pe.push(e):Pe.splice(Nl(t),0,e),e.flags|=1,ri()}}function ri(){Ds||(Ds=ii.then(ci))}function Fl(e){N(e)?Vt.push(...e):gt&&e.id===-1?gt.splice(Dt+1,0,e):e.flags&1||(Vt.push(e),e.flags|=1),ri()}function oo(e,t,s=Xe+1){for(;s<Pe.length;s++){const n=Pe[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;Pe.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function ai(e){if(Vt.length){const t=[...new Set(Vt)].sort((s,n)=>fs(s)-fs(n));if(Vt.length=0,gt){gt.push(...t);return}for(gt=t,Dt=0;Dt<gt.length;Dt++){const s=gt[Dt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}gt=null,Dt=0}}const fs=e=>e.id==null?e.flags&2?-1:1/0:e.id;function ci(e){try{for(Xe=0;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),gs(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&(t.flags&=-2)}Xe=-1,Pe.length=0,ai(),Ds=null,(Pe.length||Vt.length)&&ci()}}let Fe=null,ui=null;function Ls(e){const t=Fe;return Fe=e,ui=e&&e.type.__scopeId||null,t}function Vl(e,t=Fe,s){if(!t||e._n)return e;const n=(...o)=>{n._d&&go(-1);const i=Ls(t);let l;try{l=e(...o)}finally{Ls(i),n._d&&go(1)}return l};return n._n=!0,n._c=!0,n._d=!0,n}function le(e,t){if(Fe===null)return e;const s=en(Fe),n=e.dirs||(e.dirs=[]);for(let o=0;o<t.length;o++){let[i,l,r,c=ne]=t[o];i&&(B(i)&&(i={mounted:i,updated:i}),i.deep&&ft(l),n.push({dir:i,instance:s,value:l,oldValue:void 0,arg:r,modifiers:c}))}return e}function St(e,t,s,n){const o=e.dirs,i=t&&t.dirs;for(let l=0;l<o.length;l++){const r=o[l];i&&(r.oldValue=i[l].value);let c=r.dir[n];c&&(nt(),We(c,s,8,[e.el,r,e,t]),ot())}}function Hl(e,t){if(Ae){let s=Ae.provides;const n=Ae.parent&&Ae.parent.provides;n===s&&(s=Ae.provides=Object.create(n)),s[e]=t}}function Ms(e,t,s=!1){const n=Vr();if(n||Ht){let o=Ht?Ht._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(o&&e in o)return o[e];if(arguments.length>1)return s&&B(t)?t.call(n&&n.proxy):t}}const Bl=Symbol.for("v-scx"),Kl=()=>Ms(Bl);function un(e,t,s){return fi(e,t,s)}function fi(e,t,s=ne){const{immediate:n,deep:o,flush:i,once:l}=s,r=Se({},s),c=t&&n||!t&&i!=="post";let g;if(ps){if(i==="sync"){const M=Kl();g=M.__watcherHandles||(M.__watcherHandles=[])}else if(!c){const M=()=>{};return M.stop=tt,M.resume=tt,M.pause=tt,M}}const h=Ae;r.call=(M,q,U)=>We(M,h,q,U);let y=!1;i==="post"?r.scheduler=M=>{Re(M,h&&h.suspense)}:i!=="sync"&&(y=!0,r.scheduler=(M,q)=>{q?M():Hn(M)}),r.augmentJob=M=>{t&&(M.flags|=4),y&&(M.flags|=2,h&&(M.id=h.uid,M.i=h))};const R=Dl(e,t,r);return ps&&(g?g.push(R):c&&R()),R}function zl(e,t,s){const n=this.proxy,o=ce(e)?e.includes(".")?di(n,e):()=>n[e]:e.bind(n,n);let i;B(t)?i=t:(i=t.handler,s=t);const l=vs(this),r=fi(o,i.bind(n),s);return l(),r}function di(e,t){const s=t.split(".");return()=>{let n=e;for(let o=0;o<s.length&&n;o++)n=n[s[o]];return n}}const Wl=Symbol("_vte"),Gl=e=>e.__isTeleport,fn=Symbol("_leaveCb");function Bn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Bn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function io(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const Ns=new WeakMap;function is(e,t,s,n,o=!1){if(N(e)){e.forEach((U,W)=>is(U,t&&(N(t)?t[W]:t),s,n,o));return}if(ls(n)&&!o){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&is(e,t,s,n.component.subTree);return}const i=n.shapeFlag&4?en(n.component):n.el,l=o?null:i,{i:r,r:c}=e,g=t&&t.r,h=r.refs===ne?r.refs={}:r.refs,y=r.setupState,R=Z(y),M=y===ne?$o:U=>io(h,U)?!1:Q(R,U),q=(U,W)=>!(W&&io(h,W));if(g!=null&&g!==c){if(lo(t),ce(g))h[g]=null,M(g)&&(y[g]=null);else if(Ce(g)){const U=t;q(g,U.k)&&(g.value=null),U.k&&(h[U.k]=null)}}if(B(c)){nt();try{gs(c,r,12,[l,h])}finally{ot()}}else{const U=ce(c),W=Ce(c);if(U||W){const Y=()=>{if(e.f Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Pn;const yo=typeof window<"u"&&window.trustedTypes;if(yo)try{Pn=yo.createPolicy("vue",{createHTML:e=>e})}catch{}const Ni=Pn?e=>Pn.createHTML(e):e=>e,qr="http://www.w3.org/2000/svg",Jr="http://www.w3.org/1998/Math/MathML",at=typeof document<"u"?document:null,xo=at&&at.createElement("template"),Yr={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const o=t==="svg"?at.createElementNS(qr,e):t==="mathml"?at.createElementNS(Jr,e):s?at.createElement(e,{is:s}):at.createElement(e);return e==="select"&&n&&n.multiple!=null&&o.setAttribute("multiple",n.multiple),o},createText:e=>at.createTextNode(e),createComment:e=>at.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>at.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,o,i){const l=s?s.previousSibling:t.lastChild;if(o&&(o===i||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),s),!(o===i||!(o=o.nextSibling)););else{xo.innerHTML=Ni(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const r=xo.content;if(n==="svg"||n==="mathml"){const c=r.firstChild;for(;c.firstChild;)r.appendChild(c.firstChild);r.removeChild(c)}t.insertBefore(r,s)}return[l?l.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Xr=Symbol("_vtc");function Zr(e,t,s){const n=e[Xr];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Bs=Symbol("_vod"),Fi=Symbol("_vsh"),Xt={name:"show",beforeMount(e,{value:t},{transition:s}){e[Bs]=e.style.display==="none"?"":e.style.display,s&&t?s.beforeEnter(e):Zt(e,t)},mounted(e,{value:t},{transition:s}){s&&t&&s.enter(e)},updated(e,{value:t,oldValue:s},{transition:n}){!t!=!s&&(n?t?(n.beforeEnter(e),Zt(e,!0),n.enter(e)):n.leave(e,()=>{Zt(e,!1)}):Zt(e,t))},beforeUnmount(e,{value:t}){Zt(e,t)}};function Zt(e,t){e.style.display=t?e[Bs]:"none",e[Fi]=!t}const Qr=Symbol(""),ea=/(?:^|;)\s*display\s*:/;function ta(e,t,s){const n=e.style,o=ce(s);let i=!1;if(s&&!o){if(t)if(ce(t))for(const l of t.split(";")){const r=l.slice(0,l.indexOf(":")).trim();s[r]==null&&ts(n,r,"")}else for(const l in t)s[l]==null&&ts(n,l,"");for(const l in s){l==="display"&&(i=!0);const r=s[l];r!=null?na(e,l,!ce(t)&&t?t[l]:void 0,r)||ts(n,l,r):ts(n,l,"")}}else if(o){if(t!==s){const l=n[Qr];l&&(s+=";"+l),n.cssText=s,i=ea.test(s)}}else t&&e.removeAttribute("style");Bs in e&&(e[Bs]=i?n.display:"",e[Fi]&&(n.display="none"))}const _o=/\s*!important$/;function ts(e,t,s){if(N(s))s.forEach(n=>ts(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=sa(e,t);_o.test(s)?e.setProperty(xt(n),s.replace(_o,""),"important"):e[n]=s}}const wo=["Webkit","Moz","ms"],hn={};function sa(e,t){const s=hn[t];if(s)return s;let n=Be(t);if(n!=="filter"&&n in e)return hn[t]=n;n=No(n);for(let o=0;o<wo.length;o++){const i=wo[o]+n;if(i in e)return hn[t]=i}return t}function na(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ce(n)&&s===n}const Co="http://www.w3.org/1999/xlink";function So(e,t,s,n,o,i=al(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(Co,t.slice(6,t.length)):e.setAttributeNS(Co,t,s):s==null||i&&!Vo(s)?e.removeAttribute(t):e.setAttribute(t,i?"":st(s)?String(s):s)}function ko(e,t,s,n,o){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?Ni(s):s);return}const i=e.tagName;if(t==="value"&&i!=="PROGRESS"&&!i.includes("-")){const r=i==="OPTION"?e.getAttribute("value")||"":e.value,c=s==null?e.type==="checkbox"?"on":"":String(s);(r!==c||!("_value"in e))&&(e.value=c),s==null&&e.removeAttribute(t),e._value=s;return}let l=!1;if(s===""||s==null){const r=typeof e[t];r==="boolean"?s=Vo(s):s==null&&r==="string"?(s="",l=!0):r==="number"&&(s=0,l=!0)}try{e[t]=s}catch{}l&&e.removeAttribute(o||t)}function dt(e,t,s,n){e.addEventListener(t,s,n)}function oa(e,t,s,n){e.removeEventListener(t,s,n)}const Eo=Symbol("_vei");function ia(e,t,s,n,o=null){const i=e[Eo]||(e[Eo]={}),l=i[t];if(n&&l)l.value=n;else{const[r,c]=aa(t);if(n){const g=i[t]=fa(n,o);dt(e,r,g,c)}else l&&(oa(e,r,l,c),i[t]=void 0)}}const la=/(Once|Passive|Capture)$/,ra=/^on:?(?:Once|Passive|Capture)$/;function aa(e){let t,s;for(;(s=e.match(la))&&!ra.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):xt(e.slice(2)),t]}let mn=0;const ca=Promise.resolve(),ua=()=>mn||(ca.then(()=>mn=0),mn=Date.now());function fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const o=s.value;if(N(o)){const i=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{i.call(n),n._stopped=!0};const l=o.slice(),r=[n];for(let c=0;c<l.length&&!n._stopped;c++){const g=l[c];g&&We(g,t,5,r)}}else We(o,t,5,[n])};return s.value=e,s.attached=ua(),s}const To=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,da=(e,t,s,n,o Line truncated
+17
View File
@@ -0,0 +1,17 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))n(l);new MutationObserver(l=>{for(const o of l)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&n(i)}).observe(document,{childList:!0,subtree:!0});function s(l){const o={};return l.integrity&&(o.integrity=l.integrity),l.referrerPolicy&&(o.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?o.credentials="include":l.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(l){if(l.ep)return;l.ep=!0;const o=s(l);fetch(l.href,o)}})();/**
* @vue/shared v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function An(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const ne={},Nt=[],tt=()=>{},Ul=()=>!1,Ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),zs=e=>e.startsWith("onUpdate:"),Se=Object.assign,On=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Qo=Object.prototype.hasOwnProperty,Q=(e,t)=>Qo.call(e,t),N=Array.isArray,Ft=e=>gs(e)==="[object Map]",Wt=e=>gs(e)==="[object Set]",el=e=>gs(e)==="[object Date]",B=e=>typeof e=="function",ce=e=>typeof e=="string",st=e=>typeof e=="symbol",te=e=>e!==null&&typeof e=="object",$l=e=>(te(e)||B(e))&&B(e.then)&&B(e.catch),jl=Object.prototype.toString,gs=e=>jl.call(e),ei=e=>gs(e).slice(8,-1),Ll=e=>gs(e)==="[object Object]",Mn=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,ss=An(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ws=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},ti=/-\w/g,Be=Ws(e=>e.replace(ti,t=>t.slice(1).toUpperCase())),si=/\B([A-Z])/g,xt=Ws(e=>e.replace(si,"-$1").toLowerCase()),Dl=Ws(e=>e.charAt(0).toUpperCase()+e.slice(1)),ln=Ws(e=>e?`on${Dl(e)}`:""),et=(e,t)=>!Object.is(e,t),Rs=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},Nl=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Gs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let tl;const Js=()=>tl||(tl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Rn(e){if(N(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],l=ce(n)?ii(n):Rn(n);if(l)for(const o in l)t[o]=l[o]}return t}else if(ce(e)||te(e))return e}const ni=/;(?![^(]*\))/g,li=/:([^]+)/,oi=/\/\*[^]*?\*\//g;function ii(e){const t={};return e.replace(oi,"").split(ni).forEach(s=>{if(s){const n=s.split(li);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ue(e){let t="";if(ce(e))t=e;else if(N(e))for(let s=0;s<e.length;s++){const n=Ue(e[s]);n&&(t+=n+" ")}else if(te(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const ri="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",ai=An(ri);function Fl(e){return!!e||e===""}function ci(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=vt(e[n],t[n]);return s}function vt(e,t){if(e===t)return!0;let s=el(e),n=el(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=st(e),n=st(t),s||n)return e===t;if(s=N(e),n=N(t),s||n)return s&&n?ci(e,t):!1;if(s=te(e),n=te(t),s||n){if(!s||!n)return!1;const l=Object.keys(e).length,o=Object.keys(t).length;if(l!==o)return!1;for(const i in e){const r=e.hasOwnProperty(i),c=t.hasOwnProperty(i);if(r&&!c||!r&&c||!vt(e[i],t[i]))return!1}}return String(e)===String(t)}function In(e,t){return e.findIndex(s=>vt(s,t))}const Vl=e=>!!(e&&e.__v_isRef===!0),O=e=>ce(e)?e:e==null?"":N(e)||te(e)&&(e.toString===jl||!B(e.toString))?Vl(e)?O(e.value):JSON.stringify(e,Hl,2):String(e),Hl=(e,t)=>Vl(t)?Hl(e,t.value):Ft(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,l],o)=>(s[on(n,o)+" =>"]=l,s),{})}:Wt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>on(s))}:st(t)?on(t):te(t)&&!N(t)&&!Ll(t)?String(t):t,on=(e,t="")=>{var s;return st(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
* @vue/reactivity v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let ve;class ui{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ve&&(ve.active?(this.parent=ve,this.index=(ve.scopes||(ve.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ve;try{return ve=this,t()}finally{ve=s}}}on(){++this._on===1&&(this.prevScope=ve,ve=this)}off(){if(this._on>0&&--this._on===0){if(ve===this)ve=this.prevScope;else{let t=ve;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const l=this.parent.scopes.pop();l&&l!==this&&(this.parent.scopes[this.index]=l,l.index=this.index)}this.parent=void 0}}}function fi(){return ve}let re;const rn=new WeakSet;class Bl{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ve&&(ve.active?ve.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,rn.has(this)&&(rn.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||zl(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,sl(this),Wl(this);const t=re,s=Ke;re=this,Ke=!0;try{return this.fn()}finally{Gl(this),re=t,Ke=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)jn(t);this.deps=this.depsTail=void 0,sl(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?rn.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){vn(this)&&this.run()}get dirty(){return vn(this)}}let Kl=0,ns,ls;function zl(e,t=!1){if(e.flags|=8,t){e.next=ls,ls=e;return}e.next=ns,ns=e}function Un(){Kl++}function $n(){if(--Kl>0)return;if(ls){let t=ls;for(ls=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;ns;){let t=ns;for(ns=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Wl(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Gl(e){let t,s=e.depsTail,n=s;for(;n;){const l=n.prevDep;n.version===-1?(n===s&&(s=l),jn(n),di(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=l}e.deps=t,e.depsTail=s}function vn(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Jl(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Jl(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===cs)||(e.globalVersion=cs,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!vn(e))))return;e.flags|=2;const t=e.dep,s=re,n=Ke;re=e,Ke=!0;try{Wl(e);const l=e.fn(e._value);(t.version===0||et(l,e._value))&&(e.flags|=128,e._value=l,t.version++)}catch(l){throw t.version++,l}finally{re=s,Ke=n,Gl(e),e.flags&=-3}}function jn(e,t=!1){const{dep:s,prevSub:n,nextSub:l}=e;if(n&&(n.nextSub=l,e.prevSub=void 0),l&&(l.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)jn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function di(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ke=!0;const ql=[];function nt(){ql.push(Ke),Ke=!1}function lt(){const e=ql.pop();Ke=e===void 0?!0:e}function sl(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=re;re=void 0;try{t()}finally{re=s}}}let cs=0;class pi{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Ln{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!re||!Ke||re===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==re)s=this.activeLink=new pi(re,this),re.deps?(s.prevDep=re.depsTail,re.depsTail.nextDep=s,re.depsTail=s):re.deps=re.depsTail=s,Yl(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=re.depsTail,s.nextDep=void 0,re.depsTail.nextDep=s,re.depsTail=s,re.deps===s&&(re.deps=n)}return s}trigger(t){this.versiLine truncated
* @vue/runtime-core v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/function ms(e,t,s,n){try{return n?e(...n):e()}catch(l){Ys(l,t,s)}}function We(e,t,s,n){if(B(e)){const l=ms(e,t,s,n);return l&&$l(l)&&l.catch(o=>{Ys(o,t,s)}),l}if(N(e)){const l=[];for(let o=0;o<e.length;o++)l.push(We(e[o],t,s,n));return l}}function Ys(e,t,s,n=!0){const l=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:i}=t&&t.appContext.config||ne;if(t){let r=t.parent;const c=t.proxy,m=`https://vuejs.org/error-reference/#runtime-${s}`;for(;r;){const h=r.ec;if(h){for(let y=0;y<h.length;y++)if(h[y](e,c,m)===!1)return}r=r.parent}if(o){nt(),ms(o,null,10,[e,c,m]),lt();return}}Di(e,s,l,n,i)}function Di(e,t,s,n=!0,l=!1){if(l)throw e;console.error(e)}const Pe=[];let Xe=-1;const Vt=[];let mt=null,Lt=0;const lo=Promise.resolve();let Ls=null;function oo(e){const t=Ls||lo;return e?t.then(this?e.bind(this):e):t}function Ni(e){let t=Xe+1,s=Pe.length;for(;t<s;){const n=t+s>>>1,l=Pe[n],o=fs(l);o<e||o===e&&l.flags&2?t=n+1:s=n}return t}function Hn(e){if(!(e.flags&1)){const t=fs(e),s=Pe[Pe.length-1];!s||!(e.flags&2)&&t>=fs(s)?Pe.push(e):Pe.splice(Ni(t),0,e),e.flags|=1,io()}}function io(){Ls||(Ls=lo.then(ao))}function Fi(e){N(e)?Vt.push(...e):mt&&e.id===-1?mt.splice(Lt+1,0,e):e.flags&1||(Vt.push(e),e.flags|=1),io()}function ll(e,t,s=Xe+1){for(;s<Pe.length;s++){const n=Pe[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;Pe.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function ro(e){if(Vt.length){const t=[...new Set(Vt)].sort((s,n)=>fs(s)-fs(n));if(Vt.length=0,mt){mt.push(...t);return}for(mt=t,Lt=0;Lt<mt.length;Lt++){const s=mt[Lt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}mt=null,Lt=0}}const fs=e=>e.id==null?e.flags&2?-1:1/0:e.id;function ao(e){try{for(Xe=0;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),ms(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Xe<Pe.length;Xe++){const t=Pe[Xe];t&&(t.flags&=-2)}Xe=-1,Pe.length=0,ro(),Ls=null,(Pe.length||Vt.length)&&ao()}}let Fe=null,co=null;function Ds(e){const t=Fe;return Fe=e,co=e&&e.type.__scopeId||null,t}function Vi(e,t=Fe,s){if(!t||e._n)return e;const n=(...l)=>{n._d&&gl(-1);const o=Ds(t);let i;try{i=e(...l)}finally{Ds(o),n._d&&gl(1)}return i};return n._n=!0,n._c=!0,n._d=!0,n}function ie(e,t){if(Fe===null)return e;const s=en(Fe),n=e.dirs||(e.dirs=[]);for(let l=0;l<t.length;l++){let[o,i,r,c=ne]=t[l];o&&(B(o)&&(o={mounted:o,updated:o}),o.deep&&ft(i),n.push({dir:o,instance:s,value:i,oldValue:void 0,arg:r,modifiers:c}))}return e}function St(e,t,s,n){const l=e.dirs,o=t&&t.dirs;for(let i=0;i<l.length;i++){const r=l[i];o&&(r.oldValue=o[i].value);let c=r.dir[n];c&&(nt(),We(c,s,8,[e.el,r,e,t]),lt())}}function Hi(e,t){if(Ae){let s=Ae.provides;const n=Ae.parent&&Ae.parent.provides;n===s&&(s=Ae.provides=Object.create(n)),s[e]=t}}function Is(e,t,s=!1){const n=Vr();if(n||Ht){let l=Ht?Ht._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(l&&e in l)return l[e];if(arguments.length>1)return s&&B(t)?t.call(n&&n.proxy):t}}const Bi=Symbol.for("v-scx"),Ki=()=>Is(Bi);function un(e,t,s){return uo(e,t,s)}function uo(e,t,s=ne){const{immediate:n,deep:l,flush:o,once:i}=s,r=Se({},s),c=t&&n||!t&&o!=="post";let m;if(ps){if(o==="sync"){const I=Ki();m=I.__watcherHandles||(I.__watcherHandles=[])}else if(!c){const I=()=>{};return I.stop=tt,I.resume=tt,I.pause=tt,I}}const h=Ae;r.call=(I,J,U)=>We(I,h,J,U);let y=!1;o==="post"?r.scheduler=I=>{Me(I,h&&h.suspense)}:o!=="sync"&&(y=!0,r.scheduler=(I,J)=>{J?I():Hn(I)}),r.augmentJob=I=>{t&&(I.flags|=4),y&&(I.flags|=2,h&&(I.id=h.uid,I.i=h))};const M=Li(e,t,r);return ps&&(m?m.push(M):c&&M()),M}function zi(e,t,s){const n=this.proxy,l=ce(e)?e.includes(".")?fo(n,e):()=>n[e]:e.bind(n,n);let o;B(t)?o=t:(o=t.handler,s=t);const i=vs(this),r=uo(l,o.bind(n),s);return i(),r}function fo(e,t){const s=t.split(".");return()=>{let n=e;for(let l=0;l<s.length&&n;l++)n=n[s[l]];return n}}const Wi=Symbol("_vte"),Gi=e=>e.__isTeleport,fn=Symbol("_leaveCb");function Bn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Bn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function po(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function ol(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const Ns=new WeakMap;function os(e,t,s,n,l=!1){if(N(e)){e.forEach((U,W)=>os(U,t&&(N(t)?t[W]:t),s,n,l));return}if(is(n)&&!l){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&os(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?en(n.component):n.el,i=l?null:o,{i:r,r:c}=e,m=t&&t.r,h=r.refs===ne?r.refs={}:r.refs,y=r.setupState,M=Z(y),I=y===ne?Ul:U=>ol(h,U)?!1:Q(M,U),J=(U,W)=>!(W&&ol(h,W));if(m!=null&&m!==c){if(il(t),ce(m))h[m]=null,I(m)&&(y[m]=null);else if(Ce(m)){const U=t;J(m,U.k)&&(m.value=null),U.k&&(h[U.k]=null)}}if(B(c)){nt();try{ms(c,r,12,[i,h])}finally{lt()}}else{const U=ce(c),W=Ce(c);if(U||W){const Y=()=>{if(e.f Line truncated
* @vue/runtime-dom v3.5.39
* (c) 2018-present Yuxi (Evan) You and Vue contributors
* @license MIT
**/let Pn;const bl=typeof window<"u"&&window.trustedTypes;if(bl)try{Pn=bl.createPolicy("vue",{createHTML:e=>e})}catch{}const No=Pn?e=>Pn.createHTML(e):e=>e,Jr="http://www.w3.org/2000/svg",qr="http://www.w3.org/1998/Math/MathML",at=typeof document<"u"?document:null,yl=at&&at.createElement("template"),Yr={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const l=t==="svg"?at.createElementNS(Jr,e):t==="mathml"?at.createElementNS(qr,e):s?at.createElement(e,{is:s}):at.createElement(e);return e==="select"&&n&&n.multiple!=null&&l.setAttribute("multiple",n.multiple),l},createText:e=>at.createTextNode(e),createComment:e=>at.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>at.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,l,o){const i=s?s.previousSibling:t.lastChild;if(l&&(l===o||l.nextSibling))for(;t.insertBefore(l.cloneNode(!0),s),!(l===o||!(l=l.nextSibling)););else{yl.innerHTML=No(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const r=yl.content;if(n==="svg"||n==="mathml"){const c=r.firstChild;for(;c.firstChild;)r.appendChild(c.firstChild);r.removeChild(c)}t.insertBefore(r,s)}return[i?i.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Xr=Symbol("_vtc");function Zr(e,t,s){const n=e[Xr];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Bs=Symbol("_vod"),Fo=Symbol("_vsh"),Xt={name:"show",beforeMount(e,{value:t},{transition:s}){e[Bs]=e.style.display==="none"?"":e.style.display,s&&t?s.beforeEnter(e):Zt(e,t)},mounted(e,{value:t},{transition:s}){s&&t&&s.enter(e)},updated(e,{value:t,oldValue:s},{transition:n}){!t!=!s&&(n?t?(n.beforeEnter(e),Zt(e,!0),n.enter(e)):n.leave(e,()=>{Zt(e,!1)}):Zt(e,t))},beforeUnmount(e,{value:t}){Zt(e,t)}};function Zt(e,t){e.style.display=t?e[Bs]:"none",e[Fo]=!t}const Qr=Symbol(""),ea=/(?:^|;)\s*display\s*:/;function ta(e,t,s){const n=e.style,l=ce(s);let o=!1;if(s&&!l){if(t)if(ce(t))for(const i of t.split(";")){const r=i.slice(0,i.indexOf(":")).trim();s[r]==null&&ts(n,r,"")}else for(const i in t)s[i]==null&&ts(n,i,"");for(const i in s){i==="display"&&(o=!0);const r=s[i];r!=null?na(e,i,!ce(t)&&t?t[i]:void 0,r)||ts(n,i,r):ts(n,i,"")}}else if(l){if(t!==s){const i=n[Qr];i&&(s+=";"+i),n.cssText=s,o=ea.test(s)}}else t&&e.removeAttribute("style");Bs in e&&(e[Bs]=o?n.display:"",e[Fo]&&(n.display="none"))}const xl=/\s*!important$/;function ts(e,t,s){if(N(s))s.forEach(n=>ts(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=sa(e,t);xl.test(s)?e.setProperty(xt(n),s.replace(xl,""),"important"):e[n]=s}}const _l=["Webkit","Moz","ms"],hn={};function sa(e,t){const s=hn[t];if(s)return s;let n=Be(t);if(n!=="filter"&&n in e)return hn[t]=n;n=Dl(n);for(let l=0;l<_l.length;l++){const o=_l[l]+n;if(o in e)return hn[t]=o}return t}function na(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ce(n)&&s===n}const wl="http://www.w3.org/1999/xlink";function Cl(e,t,s,n,l,o=ai(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(wl,t.slice(6,t.length)):e.setAttributeNS(wl,t,s):s==null||o&&!Fl(s)?e.removeAttribute(t):e.setAttribute(t,o?"":st(s)?String(s):s)}function Sl(e,t,s,n,l){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?No(s):s);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const r=o==="OPTION"?e.getAttribute("value")||"":e.value,c=s==null?e.type==="checkbox"?"on":"":String(s);(r!==c||!("_value"in e))&&(e.value=c),s==null&&e.removeAttribute(t),e._value=s;return}let i=!1;if(s===""||s==null){const r=typeof e[t];r==="boolean"?s=Fl(s):s==null&&r==="string"?(s="",i=!0):r==="number"&&(s=0,i=!0)}try{e[t]=s}catch{}i&&e.removeAttribute(l||t)}function dt(e,t,s,n){e.addEventListener(t,s,n)}function la(e,t,s,n){e.removeEventListener(t,s,n)}const kl=Symbol("_vei");function oa(e,t,s,n,l=null){const o=e[kl]||(e[kl]={}),i=o[t];if(n&&i)i.value=n;else{const[r,c]=aa(t);if(n){const m=o[t]=fa(n,l);dt(e,r,m,c)}else i&&(la(e,r,i,c),o[t]=void 0)}}const ia=/(Once|Passive|Capture)$/,ra=/^on:?(?:Once|Passive|Capture)$/;function aa(e){let t,s;for(;(s=e.match(ia))&&!ra.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):xt(e.slice(2)),t]}let gn=0;const ca=Promise.resolve(),ua=()=>gn||(ca.then(()=>gn=0),gn=Date.now());function fa(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const l=s.value;if(N(l)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const i=l.slice(),r=[n];for(let c=0;c<i.length&&!n._stopped;c++){const m=i[c];m&&We(m,t,5,r)}}else We(l,t,5,[n])};return s.value=e,s.attached=ua(),s}const El=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,da=(e,t,s,n,l Line truncated
+1 -1
View File
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0F1E3D" />
<title>PilotVault · API Server</title>
<script type="module" crossorigin src="/assets/index--4fMszzi.js"></script>
<script type="module" crossorigin src="/assets/index-CwiTp2Sb.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CVh8EDzq.css">
</head>
<body>
+34 -1
View File
@@ -7,9 +7,34 @@ import (
"io"
"net/http"
"net/url"
"strconv"
"strings"
)
// validBBox reports whether s is a well-formed "lamin,lomin,lamax,lomax" bounding
// box: four numbers, latitudes in [-90,90], longitudes in [-180,180], and min < max
// on each axis. Used to vet the Live map's client-supplied ?bbox= override before
// it reaches OpenSky.
func validBBox(s string) bool {
parts := strings.Split(s, ",")
if len(parts) != 4 {
return false
}
n := make([]float64, 4)
for i, p := range parts {
v, err := strconv.ParseFloat(strings.TrimSpace(p), 64)
if err != nil {
return false
}
n[i] = v
}
laMin, loMin, laMax, loMax := n[0], n[1], n[2], n[3]
if laMin < -90 || laMax > 90 || loMin < -180 || loMax > 180 {
return false
}
return laMin < laMax && loMin < loMax
}
// Integrations exposes the OpenSky plugin's settings to end users under a
// three-layer cascade (superadmin/global → organization → user). Each of the
// four settings resolves independently, top wins, and a blank field falls
@@ -586,11 +611,19 @@ func (s *Server) handleOpenSkyStates(w http.ResponseWriter, r *http.Request) {
return
}
// The Live map may request a specific area (auto cascade: drone → device →
// region). Honour a well-formed ?bbox= override; otherwise use the resolved
// config bbox. Malformed input is ignored rather than erroring.
bbox := res.eff.Bbox
if q := strings.TrimSpace(r.URL.Query().Get("bbox")); q != "" && validBBox(q) {
bbox = q
}
cfg := map[string]string{
"clientId": res.eff.ClientID,
"clientSecret": res.eff.ClientSecret,
"plan": res.eff.Plan,
"bbox": res.eff.Bbox,
"bbox": bbox,
"allowAnonymous": boolStr(res.allowAnon),
}
raw, err := s.plugins.InvokeWith(r.Context(), openSkyPlugin, cfg, "states.bbox", nil)
+10
View File
@@ -11,6 +11,10 @@ type Telemetry struct {
Altitude *float64 `json:"altitude,omitempty"`
Latitude *float64 `json:"latitude,omitempty"`
Longitude *float64 `json:"longitude,omitempty"`
// Phone's own GPS (reported by the Fly App), distinct from the drone's fix
// above — used as a location fallback for the Web App's auto bounding box.
PhoneLatitude *float64 `json:"phoneLatitude,omitempty"`
PhoneLongitude *float64 `json:"phoneLongitude,omitempty"`
VelocityX *float64 `json:"velocityX,omitempty"`
VelocityY *float64 `json:"velocityY,omitempty"`
VelocityZ *float64 `json:"velocityZ,omitempty"`
@@ -100,6 +104,12 @@ func applyTelemetry(t *Telemetry, raw map[string]any) {
if v, ok := toFloat(raw["longitude"]); ok {
t.Longitude = &v
}
if v, ok := toFloat(raw["phoneLatitude"]); ok {
t.PhoneLatitude = &v
}
if v, ok := toFloat(raw["phoneLongitude"]); ok {
t.PhoneLongitude = &v
}
if v, ok := toFloat(raw["velocityX"]); ok {
t.VelocityX = &v
}
+52 -6
View File
@@ -190,15 +190,61 @@ const BBOX_GROUPS = [
{ value: "-56,-82,13,-34", label: "South America" },
{ value: "-48,110,-10,180", label: "Oceania" },
] },
{ label: "Countries", options: [
{ value: "49,14.1,54.9,24.2", label: "Poland" },
{ value: "50.5,3.2,53.7,7.3", label: "Netherlands" },
{ value: "47.2,5.8,55.1,15.1", label: "Germany" },
// European countries (mirrors Web App/web/src/countries.js — keep in sync).
{ label: "European countries", options: [
{ value: "39.6,19.3,42.7,21.1", label: "Albania" },
{ value: "42.4,1.4,42.7,1.8", label: "Andorra" },
{ value: "46.4,9.5,49.0,17.2", label: "Austria" },
{ value: "51.2,23.2,56.2,32.8", label: "Belarus" },
{ value: "49.5,2.5,51.5,6.4", label: "Belgium" },
{ value: "42.6,15.7,45.3,19.6", label: "Bosnia and Herzegovina" },
{ value: "41.2,22.4,44.2,28.6", label: "Bulgaria" },
{ value: "42.4,13.5,46.6,19.4", label: "Croatia" },
{ value: "34.6,32.3,35.7,34.6", label: "Cyprus" },
{ value: "48.6,12.1,51.1,18.9", label: "Czechia" },
{ value: "54.6,8.1,57.8,12.7", label: "Denmark" },
{ value: "57.5,21.8,59.7,28.2", label: "Estonia" },
{ value: "59.8,20.6,70.1,31.6", label: "Finland" },
{ value: "41.3,-5.2,51.1,9.6", label: "France" },
{ value: "49.9,-8.7,59,1.8", label: "United Kingdom" },
{ value: "35.9,-9.6,43.8,3.4", label: "Spain" },
{ value: "47.2,5.8,55.1,15.1", label: "Germany" },
{ value: "34.8,19.4,41.8,28.3", label: "Greece" },
{ value: "45.7,16.1,48.6,22.9", label: "Hungary" },
{ value: "63.3,-24.6,66.6,-13.5", label: "Iceland" },
{ value: "51.4,-10.6,55.4,-6.0", label: "Ireland" },
{ value: "36.6,6.6,47.1,18.6", label: "Italy" },
{ value: "41.8,20.0,43.3,21.8", label: "Kosovo" },
{ value: "55.7,20.9,58.1,28.2", label: "Latvia" },
{ value: "47.0,9.4,47.3,9.6", label: "Liechtenstein" },
{ value: "53.9,20.9,56.5,26.9", label: "Lithuania" },
{ value: "49.4,5.7,50.2,6.5", label: "Luxembourg" },
{ value: "35.8,14.1,36.1,14.6", label: "Malta" },
{ value: "45.4,26.6,48.5,30.2", label: "Moldova" },
{ value: "43.72,7.40,43.75,7.44", label: "Monaco" },
{ value: "41.8,18.4,43.6,20.4", label: "Montenegro" },
{ value: "50.7,3.3,53.7,7.2", label: "Netherlands" },
{ value: "40.8,20.4,42.4,23.0", label: "North Macedonia" },
{ value: "57.9,4.6,71.2,31.1", label: "Norway" },
{ value: "49.0,14.1,54.9,24.2", label: "Poland" },
{ value: "36.9,-9.5,42.2,-6.2", label: "Portugal" },
{ value: "43.6,20.2,48.3,29.7", label: "Romania" },
{ value: "41.2,19.6,81.9,180", label: "Russia" },
{ value: "43.89,12.40,43.99,12.52", label: "San Marino" },
{ value: "42.2,18.8,46.2,23.0", label: "Serbia" },
{ value: "47.7,16.8,49.6,22.6", label: "Slovakia" },
{ value: "45.4,13.4,46.9,16.6", label: "Slovenia" },
{ value: "35.9,-9.4,43.8,3.4", label: "Spain" },
{ value: "55.3,11.1,69.1,24.2", label: "Sweden" },
{ value: "45.8,5.9,47.8,10.5", label: "Switzerland" },
{ value: "35.8,25.7,42.3,44.8", label: "Turkey" },
{ value: "44.4,22.1,52.4,40.2", label: "Ukraine" },
{ value: "49.9,-8.7,60.9,1.8", label: "United Kingdom" },
{ value: "41.900,12.445,41.908,12.458", label: "Vatican City" },
] },
{ label: "Other countries", options: [
{ value: "24,-125,49.5,-66.5", label: "United States" },
{ value: "41.7,-141,83.1,-52.6", label: "Canada" },
{ value: "-43.6,113.3,-10.7,153.6", label: "Australia" },
{ value: "24,122.9,45.5,145.8", label: "Japan" },
] },
];
const BBOX_FLAT = BBOX_GROUPS.flatMap((g) => g.options);