From cd16d4383f914be6bd75ecf1de5b588e76670d5b Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Mon, 17 Aug 2026 16:54:02 +0200 Subject: [PATCH] Orgs: let any user create an organization and become its admin Organization writes were superadmin-only, so standing up a tenant needed an out-of-band superadmin. Creating one is now self-service, and an admin manages the org they belong to. - POST /api/orgs is open to any authenticated user. A creator who isn't a superadmin must have no organization yet (a single-valued membership relation means a second one would abandon the first), and is promoted to the new org's admin and first member in the same request. If that promotion fails the org is rolled back, so it is never left stranded with nobody able to administer it. Superadmins still create tenants without joining them. - PATCH/DELETE are manager-gated and scope an admin to their own org. An admin deletes theirs only as its sole member: they are detached and demoted to a plain user before the record goes, so the org is empty when it is removed. Other members still block deletion with a 409. - /api/me now carries organization + organizationName, which the clients need to tell "no org yet" from "org you administer". The panel, Web App (new OrgManager.vue in Settings) and Phone App (new _OrganizationSection) all mirror the server's gates rather than re-deciding them. The Phone App cached its role at login and gates the Users tab on it, so AuthService.adoptRole refreshes that from the profile instead of making a freshly promoted admin sign in again. Covered by orgs_test.go, which drives the real handler + middleware chain against a stand-in PocketBase: promotion, the already-a-member refusal, superadmin staying unattached, the rollback, own-org scoping, the detach-and-demote, and the blocking-member 409. Co-Authored-By: Claude Opus 5 --- API Server/README.md | 18 +- .../api/dist/assets/index-D-rTgBao.js | 17 - .../api/dist/assets/index-OHZkxAdj.js | 17 + API Server/internal/api/dist/index.html | 2 +- API Server/internal/api/me.go | 20 +- API Server/internal/api/orgs.go | 91 ++++- API Server/internal/api/orgs_test.go | 333 ++++++++++++++++++ API Server/internal/api/server.go | 15 +- API Server/internal/models/models.go | 5 + API Server/panel/src/App.vue | 15 +- API Server/panel/src/components/OrgsCard.vue | 47 ++- API Server/panel/src/i18n/da.json | 6 +- API Server/panel/src/i18n/en.json | 6 +- API Server/panel/src/i18n/pl.json | 6 +- Phone App/README.md | 7 +- Phone App/assets/i18n/da.json | 18 + Phone App/assets/i18n/en.json | 18 + Phone App/assets/i18n/pl.json | 18 + Phone App/lib/api.dart | 23 ++ Phone App/lib/auth.dart | 13 + Phone App/lib/models.dart | 21 ++ Phone App/lib/screens/settings_screen.dart | 252 +++++++++++++ README.md | 5 +- Web App/README.md | 8 +- Web App/web/src/api.js | 11 + Web App/web/src/components/OrgManager.vue | 203 +++++++++++ Web App/web/src/i18n/da.json | 19 +- Web App/web/src/i18n/en.json | 19 +- Web App/web/src/i18n/pl.json | 19 +- Web App/web/src/views/Settings.vue | 4 + 30 files changed, 1193 insertions(+), 63 deletions(-) delete mode 100644 API Server/internal/api/dist/assets/index-D-rTgBao.js create mode 100644 API Server/internal/api/dist/assets/index-OHZkxAdj.js create mode 100644 API Server/internal/api/orgs_test.go create mode 100644 Web App/web/src/components/OrgManager.vue diff --git a/API Server/README.md b/API Server/README.md index 2fe37fa..3a428a1 100644 --- a/API Server/README.md +++ b/API Server/README.md @@ -76,6 +76,22 @@ their own account. An organization cannot be deleted while it still has members. membership. A superadmin spans all organizations; an admin is scoped by the server to their own. Users may have no organization at all. +Creating one is self-service: any user who does not already belong to an +organization may `POST /api/orgs`, and becomes that organization's **admin** and +first member in the same request (if the promotion fails the new organization is +rolled back, so it is never left with nobody able to administer it). A user who +already belongs to one is refused — membership is a single relation, so creating +a second would mean silently abandoning the first. + +A superadmin is the exception: they create organizations without joining them, +since they already span every tenant. + +From there an admin manages **their own** organization — rename it, or delete it +once they are its only member. Deleting it detaches and demotes them back to a +plain `user` before the record is removed, so the organization is empty when it +goes. A superadmin may rename or delete any organization, but still only once it +has no members at all. + ### Per-user car ownership + sharing Cars are not a global list. `cars.owner` marks ownership and `car_shares` grants @@ -139,7 +155,7 @@ POST /api/me/verify/request GET /api/me/export POST /api/me/import POST /api/me/delete POST /api/me/delete/cancel -# users + organizations (admin or superadmin; org writes are superadmin-only) +# users + organizations (admin or superadmin; POST /api/orgs is open to any user) GET /api/users POST /api/users PATCH /api/users/{id} DELETE /api/users/{id} GET /api/orgs POST /api/orgs diff --git a/API Server/internal/api/dist/assets/index-D-rTgBao.js b/API Server/internal/api/dist/assets/index-D-rTgBao.js deleted file mode 100644 index 3ebb755..0000000 --- a/API Server/internal/api/dist/assets/index-D-rTgBao.js +++ /dev/null @@ -1,17 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/** -* @vue/shared v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function ln(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const Y={},xt=[],He=()=>{},gi=()=>!1,ks=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ss=e=>e.startsWith("onUpdate:"),he=Object.assign,an=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,G=(e,t)=>$o.call(e,t),L=Array.isArray,kt=e=>es(e)==="[object Map]",Rt=e=>es(e)==="[object Set]",Rn=e=>es(e)==="[object Date]",H=e=>typeof e=="function",ne=e=>typeof e=="string",Ve=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",mi=e=>(Z(e)||H(e))&&H(e.then)&&H(e.catch),bi=Object.prototype.toString,es=e=>bi.call(e),Ao=e=>es(e).slice(8,-1),vi=e=>es(e)==="[object Object]",cn=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ft=ln(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ts=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Oo=/-\w/g,Ce=Ts(e=>e.replace(Oo,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,ct=Ts(e=>e.replace(Ro,"-$1").toLowerCase()),_i=Ts(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ms=Ts(e=>e?`on${_i(e)}`:""),Be=(e,t)=>!Object.is(e,t),fs=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Es=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let In;const Cs=()=>In||(In=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function un(e){if(L(e)){const t={};for(let s=0;s{if(s){const n=s.split(Uo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function $e(e){let t="";if(ne(e))t=e;else if(L(e))for(let s=0;srt(s,t))}const xi=e=>!!(e&&e.__v_isRef===!0),b=e=>ne(e)?e:e==null?"":L(e)||Z(e)&&(e.toString===bi||!H(e.toString))?xi(e)?b(e.value):JSON.stringify(e,ki,2):String(e),ki=(e,t)=>xi(t)?ki(e,t.value):kt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ns(n,o)+" =>"]=i,s),{})}:Rt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ns(s))}:Ve(t)?Ns(t):Z(t)&&!L(t)&&!vi(t)?String(t):t,Ns=(e,t="")=>{var s;return Ve(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 ae;class Lo{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&&ae&&(ae.active?(this.parent=ae,this.index=(ae.scopes||(ae.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;t0&&--this._on===0){if(ae===this)ae=this.prevScope;else{let t=ae;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;s0)return;if(Ht){let t=Ht;for(Ht=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Bt;){let t=Bt;for(Bt=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 Ci(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Pi(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),hn(n),Bo(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function qs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&($i(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function $i(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===qt)||(e.globalVersion=qt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!qs(e))))return;e.flags|=2;const t=e.dep,s=Q,n=Pe;Q=e,Pe=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||Be(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,Pe=n,Pi(e),e.flags&=-3}}function hn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.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)hn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Bo(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Pe=!0;const Ai=[];function Ke(){Ai.push(Pe),Pe=!1}function We(){const e=Ai.pop();Pe=e===void 0?!0:e}function Un(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let qt=0;class Ho{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 gn{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(!Q||!Pe||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new Ho(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,Oi(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=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,qt++,this.notify(t)}notify(t){fn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{pn()}}}function Oi(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Oi(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Zs=new WeakMap,vt=Symbol(""),Js=Symbol(""),Zt=Symbol("");function ue(e,t,s){if(Pe&&Q){let n=Zs.get(e);n||Zs.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new gn),i.map=n,i.key=s),i.track()}}function Je(e,t,s,n,i,o){const r=Zs.get(e);if(!r){qt++;return}const l=a=>{a&&a.trigger()};if(fn(),t==="clear")r.forEach(l);else{const a=L(e),p=a&&cn(s);if(a&&s==="length"){const u=Number(n);r.forEach((m,y)=>{(y==="length"||y===Zt||!Ve(y)&&y>=u)&&l(m)})}else switch((s!==void 0||r.has(void 0))&&l(r.get(s)),p&&l(r.get(Zt)),t){case"add":a?p&&l(r.get("length")):(l(r.get(vt)),kt(e)&&l(r.get(Js)));break;case"delete":a||(l(r.get(vt)),kt(e)&&l(r.get(Js)));break;case"set":kt(e)&&l(r.get(vt));break}}pn()}function yt(e){const t=W(e);return t===e?t:(ue(t,"iterate",Zt),Se(e)?t:t.map(Ae))}function Ps(e){return ue(e=W(e),"iterate",Zt),e}function Le(e,t){return et(e)?Ct(_t(e)?Ae(t):t):Ae(t)}const Vo={__proto__:null,[Symbol.iterator](){return zs(this,Symbol.iterator,e=>Le(this,e))},concat(...e){return yt(this).concat(...e.map(t=>L(t)?yt(t):t))},entries(){return zs(this,"entries",e=>(e[1]=Le(this,e[1]),e))},every(e,t){return Ge(this,"every",e,t,void 0,arguments)},filter(e,t){return Ge(this,"filter",e,t,s=>s.map(n=>Le(this,n)),arguments)},find(e,t){return Ge(this,"find",e,t,s=>Le(this,s),arguments)},findIndex(e,t){return Ge(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ge(this,"findLast",e,t,s=>Le(this,s),arguments)},findLastIndex(e,t){return Ge(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ge(this,"forEach",e,t,void 0,arguments)},includes(...e){return Ls(this,"includes",e)},indexOf(...e){return Ls(this,"indexOf",e)},join(e){return yt(this).join(e)},lastIndexOf(...e){return Ls(this,"lastIndexOf",e)},map(e,t){return Ge(this,"map",e,t,void 0,arguments)},pop(){return Nt(this,"pop")},push(...e){return Nt(this,"push",e)},reduce(e,...t){return jn(this,"reduce",e,t)},reduceRight(e,...t){return jn(this,"reduceRight",e,t)},shift(){return Nt(this,"shift")},some(e,t){return Ge(this,"some",e,t,void 0,arguments)},splice(...e){return Nt(this,"splice",e)},toReversed(){return yt(this).toReversed()},toSorted(e){return yt(this).toSorted(e)},toSpliced(...e){return yt(this).toSpliced(...e)},unshift(...e){return Nt(this,"unshift",e)},values(){return zs(this,"values",e=>Le(this,e))}};function zs(e,t,s){const n=Ps(e),i=n[t]();return n!==e&&!Se(e)&&(i._next=i.next,i.next=()=>{const o=i._next();return o.done||(o.value=s(o.value)),o}),i}const Ko=Array.prototype;function Ge(e,t,s,n,i,o){const r=Ps(e),l=r!==e&&!Se(e),a=r[t];if(a!==Ko[t]){const m=a.apply(e,o);return l?Ae(m):m}let p=s;r!==e&&(l?p=function(m,y){return s.call(this,Le(e,m),y,e)}:s.length>2&&(p=function(m,y){return s.call(this,m,y,e)}));const u=a.call(r,p,n);return l&&i?i(u):u}function jn(e,t,s,n){const i=Ps(e),o=i!==e&&!Se(e);let r=s,l=!1;i!==e&&(o?(l=n.length===0,r=function(p,u,m){return l&&(l=!1,p=Le(e,p)),s.call(this,p,Le(e,u),m,e)}):s.length>3&&(r=function(p,u,m){return s.call(this,p,u,m,e)}));const a=i[t](r,...n);return l?Le(e,a):a}function Ls(e,t,s){const n=W(e);ue(n,"iterate",Zt);const i=n[t](...s);return(i===-1||i===!1)&&vn(s[0])?(s[0]=W(s[0]),n[t](...s)):i}function Nt(e,t,s=[]){Ke(),fn();const n=W(e)[t].apply(e,s);return pn(),We(),n}const Wo=ln("__proto__,__v_isRef,__isVue"),Ri=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ve));function Go(e){Ve(e)||(e=String(e));const t=W(this);return ue(t,"has",e),t.hasOwnProperty(e)}class Ii{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const i=this._isReadonly,o=this._isShallow;if(s==="__v_isReactive")return!i;if(s==="__v_isReadonly")return i;if(s==="__v_isShallow")return o;if(s==="__v_raw")return n===(i?o?nr:Ni:o?Mi:ji).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=L(t);if(!i){let a;if(r&&(a=Vo[s]))return a;if(s==="hasOwnProperty")return Go}const l=Reflect.get(t,s,fe(t)?t:n);if((Ve(s)?Ri.has(s):Wo(s))||(i||ue(t,"get",s),o))return l;if(fe(l)){const a=r&&cn(s)?l:l.value;return i&&Z(a)?Xs(a):a}return Z(l)?i?Xs(l):Jt(l):l}}class Ui extends Ii{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=L(t)&&cn(s);if(!this._isShallow){const p=et(o);if(!Se(n)&&!et(n)&&(o=W(o),n=W(n)),!r&&fe(o)&&!fe(n))return p||(o.value=n),!0}const l=r?Number(s)e,as=e=>Reflect.getPrototypeOf(e);function Xo(e,t,s){return function(...n){const i=this.__v_raw,o=W(i),r=kt(o),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,p=i[e](...n),u=s?Ys:t?Ct:Ae;return!t&&ue(o,"iterate",a?Js:vt),he(Object.create(p),{next(){const{value:m,done:y}=p.next();return y?{value:m,done:y}:{value:l?[u(m[0]),u(m[1])]:u(m),done:y}}})}}function cs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Qo(e,t){const s={get(i){const o=this.__v_raw,r=W(o),l=W(i);e||(Be(i,l)&&ue(r,"get",i),ue(r,"get",l));const{has:a}=as(r),p=t?Ys:e?Ct:Ae;if(a.call(r,i))return p(o.get(i));if(a.call(r,l))return p(o.get(l));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&ue(W(i),"iterate",vt),i.size},has(i){const o=this.__v_raw,r=W(o),l=W(i);return e||(Be(i,l)&&ue(r,"has",i),ue(r,"has",l)),i===l?o.has(i):o.has(i)||o.has(l)},forEach(i,o){const r=this,l=r.__v_raw,a=W(l),p=t?Ys:e?Ct:Ae;return!e&&ue(a,"iterate",vt),l.forEach((u,m)=>i.call(o,p(u),p(m),r))}};return he(s,e?{add:cs("add"),set:cs("set"),delete:cs("delete"),clear:cs("clear")}:{add(i){const o=W(this),r=as(o),l=W(i),a=!t&&!Se(i)&&!et(i)?l:i;return r.has.call(o,a)||Be(i,a)&&r.has.call(o,i)||Be(l,a)&&r.has.call(o,l)||(o.add(a),Je(o,"add",a,a)),this},set(i,o){!t&&!Se(o)&&!et(o)&&(o=W(o));const r=W(this),{has:l,get:a}=as(r);let p=l.call(r,i);p||(i=W(i),p=l.call(r,i));const u=a.call(r,i);return r.set(i,o),p?Be(o,u)&&Je(r,"set",i,o):Je(r,"add",i,o),this},delete(i){const o=W(this),{has:r,get:l}=as(o);let a=r.call(o,i);a||(i=W(i),a=r.call(o,i)),l&&l.call(o,i);const p=o.delete(i);return a&&Je(o,"delete",i,void 0),p},clear(){const i=W(this),o=i.size!==0,r=i.clear();return o&&Je(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Xo(i,e,t)}),s}function mn(e,t){const s=Qo(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(G(s,i)&&i in n?s:n,i,o)}const er={get:mn(!1,!1)},tr={get:mn(!1,!0)},sr={get:mn(!0,!1)};const ji=new WeakMap,Mi=new WeakMap,Ni=new WeakMap,nr=new WeakMap;function ir(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Jt(e){return et(e)?e:bn(e,!1,Zo,er,ji)}function or(e){return bn(e,!1,Yo,tr,Mi)}function Xs(e){return bn(e,!0,Jo,sr,Ni)}function bn(e,t,s,n,i){if(!Z(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=i.get(e);if(o)return o;const r=ir(Ao(e));if(r===0)return e;const l=new Proxy(e,r===2?n:s);return i.set(e,l),l}function _t(e){return et(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function et(e){return!!(e&&e.__v_isReadonly)}function Se(e){return!!(e&&e.__v_isShallow)}function vn(e){return e?!!e.__v_raw:!1}function W(e){const t=e&&e.__v_raw;return t?W(t):e}function rr(e){return!G(e,"__v_skip")&&Object.isExtensible(e)&&yi(e,"__v_skip",!0),e}const Ae=e=>Z(e)?Jt(e):e,Ct=e=>Z(e)?Xs(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function V(e){return lr(e,!1)}function lr(e,t){return fe(e)?e:new ar(e,t)}class ar{constructor(t,s){this.dep=new gn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:W(t),this._value=s?t:Ae(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Se(t)||et(t);t=n?t:W(t),Be(t,s)&&(this._rawValue=t,this._value=n?t:Ae(t),this.dep.trigger())}}function g(e){return fe(e)?e.value:e}const cr={get:(e,t,s)=>t==="__v_raw"?e:g(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return fe(i)&&!fe(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Di(e){return _t(e)?e:new Proxy(e,cr)}class ur{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new gn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=qt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&Q!==this)return Ei(this,!0),!0}get value(){const t=this.dep.track();return $i(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function dr(e,t,s=!1){let n,i;return H(e)?n=e:(n=e.get,i=e.set),new ur(n,i,s)}const us={},gs=new WeakMap;let mt;function fr(e,t=!1,s=mt){if(s){let n=gs.get(s);n||gs.set(s,n=[]),n.push(e)}}function pr(e,t,s=Y){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:l,call:a}=s,p=M=>i?M:Se(M)||i===!1||i===0?Ye(M,1):Ye(M);let u,m,y,A,D=!1,C=!1;if(fe(e)?(m=()=>e.value,D=Se(e)):_t(e)?(m=()=>p(e),D=!0):L(e)?(C=!0,D=e.some(M=>_t(M)||Se(M)),m=()=>e.map(M=>{if(fe(M))return M.value;if(_t(M))return p(M);if(H(M))return a?a(M,2):M()})):H(e)?t?m=a?()=>a(e,2):e:m=()=>{if(y){Ke();try{y()}finally{We()}}const M=mt;mt=u;try{return a?a(e,3,[A]):e(A)}finally{mt=M}}:m=He,t&&i){const M=m,oe=i===!0?1/0:i;m=()=>Ye(M(),oe)}const P=Fo(),T=()=>{u.stop(),P&&P.active&&an(P.effects,u)};if(o&&t){const M=t;t=(...oe)=>{const Re=M(...oe);return T(),Re}}let $=C?new Array(e.length).fill(us):us;const j=M=>{if(!(!(u.flags&1)||!u.dirty&&!M))if(t){const oe=u.run();if(M||i||D||(C?oe.some((Re,Ie)=>Be(Re,$[Ie])):Be(oe,$))){y&&y();const Re=mt;mt=u;try{const Ie=[oe,$===us?void 0:C&&$[0]===us?[]:$,A];$=oe,a?a(t,3,Ie):t(...Ie)}finally{mt=Re}}}else u.run()};return l&&l(j),u=new Si(m),u.scheduler=r?()=>r(j,!1):j,A=M=>fr(M,!1,u),y=u.onStop=()=>{const M=gs.get(u);if(M){if(a)a(M,4);else for(const oe of M)oe();gs.delete(u)}},t?n?j(!0):$=u.run():r?r(j.bind(null,!0),!0):u.run(),T.pause=u.pause.bind(u),T.resume=u.resume.bind(u),T.stop=T,T}function Ye(e,t=1/0,s){if(t<=0||!Z(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,fe(e))Ye(e.value,t,s);else if(L(e))for(let n=0;n{Ye(n,t,s)});else if(vi(e)){for(const n in e)Ye(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&Ye(e[n],t,s)}return e}/** -* @vue/runtime-core v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function ts(e,t,s,n){try{return n?e(...n):e()}catch(i){$s(i,t,s)}}function Oe(e,t,s,n){if(H(e)){const i=ts(e,t,s,n);return i&&mi(i)&&i.catch(o=>{$s(o,t,s)}),i}if(L(e)){const i=[];for(let o=0;o>>1,i=be[n],o=Yt(i);o=Yt(s)?be.push(e):be.splice(gr(t),0,e),e.flags|=1,Fi()}}function Fi(){ms||(ms=zi.then(Hi))}function mr(e){L(e)?St.push(...e):ot&&e.id===-1?ot.splice(wt+1,0,e):e.flags&1||(St.push(e),e.flags|=1),Fi()}function Mn(e,t,s=ze+1){for(;sYt(s)-Yt(n));if(St.length=0,ot){ot.push(...t);return}for(ot=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Hi(e){try{for(ze=0;ze{n._d&&Gn(-1);const o=bs(t);let r;try{r=e(...i)}finally{bs(o),n._d&&Gn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function re(e,t){if(xe===null)return e;const s=Is(xe),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&H(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),yr=()=>ps(_r);function Fs(e,t,s){return Ki(e,t,s)}function Ki(e,t,s=Y){const{immediate:n,deep:i,flush:o,once:r}=s,l=he({},s),a=t&&n||!t&&o!=="post";let p;if(Qt){if(o==="sync"){const A=yr();p=A.__watcherHandles||(A.__watcherHandles=[])}else if(!a){const A=()=>{};return A.stop=He,A.resume=He,A.pause=He,A}}const u=ve;l.call=(A,D,C)=>Oe(A,u,D,C);let m=!1;o==="post"?l.scheduler=A=>{_e(A,u&&u.suspense)}:o!=="sync"&&(m=!0,l.scheduler=(A,D)=>{D?A():_n(A)}),l.augmentJob=A=>{t&&(A.flags|=4),m&&(A.flags|=2,u&&(A.id=u.uid,A.i=u))};const y=pr(e,t,l);return Qt&&(p?p.push(y):a&&y()),y}function wr(e,t,s){const n=this.proxy,i=ne(e)?e.includes(".")?Wi(n,e):()=>n[e]:e.bind(n,n);let o;H(t)?o=t:(o=t.handler,s=t);const r=ss(this),l=Ki(i,o.bind(n),s);return r(),l}function Wi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Bs=Symbol("_leaveCb");function yn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,yn(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 Gi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Nn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const vs=new WeakMap;function Vt(e,t,s,n,i=!1){if(L(e)){e.forEach((C,P)=>Vt(C,t&&(L(t)?t[P]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Vt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?Is(n.component):n.el,r=i?null:o,{i:l,r:a}=e,p=t&&t.r,u=l.refs===Y?l.refs={}:l.refs,m=l.setupState,y=W(m),A=m===Y?gi:C=>Nn(u,C)?!1:G(y,C),D=(C,P)=>!(P&&Nn(u,P));if(p!=null&&p!==a){if(Dn(t),ne(p))u[p]=null,A(p)&&(m[p]=null);else if(fe(p)){const C=t;D(p,C.k)&&(p.value=null),C.k&&(u[C.k]=null)}}if(H(a)){Ke();try{ts(a,l,12,[r,u])}finally{We()}}else{const C=ne(a),P=fe(a);if(C||P){const T=()=>{if(e.f){const $=C?A(a)?m[a]:u[a]:D()||!e.k?a.value:u[e.k];if(i)L($)&&an($,o);else if(L($))$.includes(o)||$.push(o);else if(C)u[a]=[o],A(a)&&(m[a]=u[a]);else{const j=[o];D(a,e.k)&&(a.value=j),e.k&&(u[e.k]=j)}}else C?(u[a]=r,A(a)&&(m[a]=r)):P&&(D(a,e.k)&&(a.value=r),e.k&&(u[e.k]=r))};if(r){const $=()=>{T(),vs.delete(e)};$.id=-1,vs.set(e,$),_e($,s)}else Dn(e),T()}}}function Dn(e){const t=vs.get(e);t&&(t.flags|=8,vs.delete(e))}Cs().requestIdleCallback;Cs().cancelIdleCallback;const Kt=e=>!!e.type.__asyncLoader,qi=e=>e.type.__isKeepAlive;function Sr(e,t){Zi(e,"a",t)}function Tr(e,t){Zi(e,"da",t)}function Zi(e,t,s=ve){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(As(t,n,s),s){let i=s.parent;for(;i&&i.parent;)qi(i.parent.vnode)&&Er(n,t,s,i),i=i.parent}}function Er(e,t,s,n){const i=As(t,e,n,!0);wn(()=>{an(n[t],i)},s)}function As(e,t,s=ve,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{Ke();const l=ss(s),a=Oe(t,s,e,r);return l(),We(),a});return n?i.unshift(o):i.push(o),o}}const tt=e=>(t,s=ve)=>{(!Qt||e==="sp")&&As(e,(...n)=>t(...n),s)},Cr=tt("bm"),ut=tt("m"),Pr=tt("bu"),$r=tt("u"),Ar=tt("bum"),wn=tt("um"),Or=tt("sp"),Rr=tt("rtg"),Ir=tt("rtc");function Ur(e,t=ve){As("ec",e,t)}const jr=Symbol.for("v-ndc");function ke(e,t,s,n){let i;const o=s,r=L(e);if(r||ne(e)){const l=r&&_t(e);let a=!1,p=!1;l&&(a=!Se(e),p=et(e),e=Ps(e)),i=new Array(e.length);for(let u=0,m=e.length;ut(l,a,void 0,o));else{const l=Object.keys(e);i=new Array(l.length);for(let a=0,p=l.length;ae?bo(e)?Is(e):Qs(e.parent):null,Wt=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Qs(e.parent),$root:e=>Qs(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Yi(e),$forceUpdate:e=>e.f||(e.f=()=>{_n(e.update)}),$nextTick:e=>e.n||(e.n=Li.bind(e.proxy)),$watch:e=>wr.bind(e)}),Hs=(e,t)=>e!==Y&&!e.__isScriptSetup&&G(e,t),Mr={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const y=r[t];if(y!==void 0)switch(y){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return o[t]}else{if(Hs(n,t))return r[t]=1,n[t];if(i!==Y&&G(i,t))return r[t]=2,i[t];if(G(o,t))return r[t]=3,o[t];if(s!==Y&&G(s,t))return r[t]=4,s[t];en&&(r[t]=0)}}const p=Wt[t];let u,m;if(p)return t==="$attrs"&&ue(e.attrs,"get",""),p(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(s!==Y&&G(s,t))return r[t]=4,s[t];if(m=a.config.globalProperties,G(m,t))return m[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Hs(i,t)?(i[t]=s,!0):n!==Y&&G(n,t)?(n[t]=s,!0):G(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:i,props:o,type:r}},l){let a;return!!(s[l]||e!==Y&&l[0]!=="$"&&G(e,l)||Hs(t,l)||G(o,l)||G(n,l)||G(Wt,l)||G(i.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:G(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function zn(e){return L(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let en=!0;function Nr(e){const t=Yi(e),s=e.proxy,n=e.ctx;en=!1,t.beforeCreate&&Ln(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:l,provide:a,inject:p,created:u,beforeMount:m,mounted:y,beforeUpdate:A,updated:D,activated:C,deactivated:P,beforeDestroy:T,beforeUnmount:$,destroyed:j,unmounted:M,render:oe,renderTracked:Re,renderTriggered:Ie,errorCaptured:st,serverPrefetch:ns,expose:dt,inheritAttrs:It,components:is,directives:os,filters:Us}=t;if(p&&Dr(p,n,null),r)for(const te in r){const X=r[te];H(X)&&(n[te]=X.bind(s))}if(i){const te=i.call(s,s);Z(te)&&(e.data=Jt(te))}if(en=!0,o)for(const te in o){const X=o[te],ft=H(X)?X.bind(s,s):H(X.get)?X.get.bind(s,s):He,rs=!H(X)&&H(X.set)?X.set.bind(s):He,pt=Qe({get:ft,set:rs});Object.defineProperty(n,te,{enumerable:!0,configurable:!0,get:()=>pt.value,set:Ue=>pt.value=Ue})}if(l)for(const te in l)Ji(l[te],n,s,te);if(a){const te=H(a)?a.call(s):a;Reflect.ownKeys(te).forEach(X=>{vr(X,te[X])})}u&&Ln(u,e,"c");function ge(te,X){L(X)?X.forEach(ft=>te(ft.bind(s))):X&&te(X.bind(s))}if(ge(Cr,m),ge(ut,y),ge(Pr,A),ge($r,D),ge(Sr,C),ge(Tr,P),ge(Ur,st),ge(Ir,Re),ge(Rr,Ie),ge(Ar,$),ge(wn,M),ge(Or,ns),L(dt))if(dt.length){const te=e.exposed||(e.exposed={});dt.forEach(X=>{Object.defineProperty(te,X,{get:()=>s[X],set:ft=>s[X]=ft,enumerable:!0})})}else e.exposed||(e.exposed={});oe&&e.render===He&&(e.render=oe),It!=null&&(e.inheritAttrs=It),is&&(e.components=is),os&&(e.directives=os),ns&&Gi(e)}function Dr(e,t,s=He){L(e)&&(e=tn(e));for(const n in e){const i=e[n];let o;Z(i)?"default"in i?o=ps(i.from||n,i.default,!0):o=ps(i.from||n):o=ps(i),fe(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[n]=o}}function Ln(e,t,s){Oe(L(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Ji(e,t,s,n){let i=n.includes(".")?Wi(s,n):()=>s[n];if(ne(e)){const o=t[e];H(o)&&Fs(i,o)}else if(H(e))Fs(i,e.bind(s));else if(Z(e))if(L(e))e.forEach(o=>Ji(o,t,s,n));else{const o=H(e.handler)?e.handler.bind(s):t[e.handler];H(o)&&Fs(i,o,e)}}function Yi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,l=o.get(t);let a;return l?a=l:!i.length&&!s&&!n?a=t:(a={},i.length&&i.forEach(p=>_s(a,p,r,!0)),_s(a,t,r)),Z(t)&&o.set(t,a),a}function _s(e,t,s,n=!1){const{mixins:i,extends:o}=t;o&&_s(e,o,s,!0),i&&i.forEach(r=>_s(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const l=zr[r]||s&&s[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const zr={data:Fn,props:Bn,emits:Bn,methods:zt,computed:zt,beforeCreate:me,created:me,beforeMount:me,mounted:me,beforeUpdate:me,updated:me,beforeDestroy:me,beforeUnmount:me,destroyed:me,unmounted:me,activated:me,deactivated:me,errorCaptured:me,serverPrefetch:me,components:zt,directives:zt,watch:Fr,provide:Fn,inject:Lr};function Fn(e,t){return t?e?function(){return he(H(e)?e.call(this,this):e,H(t)?t.call(this,this):t)}:t:e}function Lr(e,t){return zt(tn(e),tn(t))}function tn(e){if(L(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Ce(t)}Modifiers`]||e[`${ct(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||Y;let i=s;const o=t.startsWith("update:"),r=o&&Vr(n,t.slice(7));r&&(r.trim&&(i=s.map(u=>ne(u)?u.trim():u)),r.number&&(i=s.map(Es)));let l,a=n[l=Ms(t)]||n[l=Ms(Ce(t))];!a&&o&&(a=n[l=Ms(ct(t))]),a&&Oe(a,e,6,i);const p=n[l+"Once"];if(p){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Oe(p,e,6,i)}}const Wr=new WeakMap;function Qi(e,t,s=!1){const n=s?Wr:t.emitsCache,i=n.get(e);if(i!==void 0)return i;const o=e.emits;let r={},l=!1;if(!H(e)){const a=p=>{const u=Qi(p,t,!0);u&&(l=!0,he(r,u))};!s&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Z(e)&&n.set(e,null),null):(L(o)?o.forEach(a=>r[a]=null):he(r,o),Z(e)&&n.set(e,r),r)}function Os(e,t){return!e||!ks(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),G(e,t[0].toLowerCase()+t.slice(1))||G(e,ct(t))||G(e,t))}function Hn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:l,emit:a,render:p,renderCache:u,props:m,data:y,setupState:A,ctx:D,inheritAttrs:C}=e,P=bs(e);let T,$;try{if(s.shapeFlag&4){const M=i||n,oe=M;T=Fe(p.call(oe,M,u,m,A,y,D)),$=l}else{const M=t;T=Fe(M.length>1?M(m,{attrs:l,slots:r,emit:a}):M(m,null)),$=t.props?l:Gr(l)}}catch(M){Gt.length=0,$s(M,e,1),T=ce(lt)}let j=T;if($&&C!==!1){const M=Object.keys($),{shapeFlag:oe}=j;M.length&&oe&7&&(o&&M.some(Ss)&&($=qr($,o)),j=Pt(j,$,!1,!0))}return s.dirs&&(j=Pt(j,null,!1,!0),j.dirs=j.dirs?j.dirs.concat(s.dirs):s.dirs),s.transition&&yn(j,s.transition),T=j,bs(P),T}const Gr=e=>{let t;for(const s in e)(s==="class"||s==="style"||ks(s))&&((t||(t={}))[s]=e[s]);return t},qr=(e,t)=>{const s={};for(const n in e)(!Ss(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Zr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:l,patchFlag:a}=t,p=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&a>=0){if(a&1024)return!0;if(a&16)return n?Vn(n,r,p):!!r;if(a&8){const u=t.dynamicProps;for(let m=0;mObject.create(to),no=e=>Object.getPrototypeOf(e)===to;function Yr(e,t,s,n=!1){const i={},o=so();e.propsDefaults=Object.create(null),io(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);s?e.props=n?i:or(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Xr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,l=W(i),[a]=e.propsOptions;let p=!1;if((n||r>0)&&!(r&16)){if(r&8){const u=e.vnode.dynamicProps;for(let m=0;m{a=!0;const[y,A]=oo(m,t,!0);he(r,y),A&&l.push(...A)};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!a)return Z(e)&&n.set(e,xt),xt;if(L(o))for(let u=0;ue==="_"||e==="_ctx"||e==="$stable",kn=e=>L(e)?e.map(Fe):[Fe(e)],el=(e,t,s)=>{if(t._n)return t;const n=br((...i)=>kn(t(...i)),s);return n._c=!1,n},ro=(e,t,s)=>{const n=e._ctx;for(const i in e){if(xn(i))continue;const o=e[i];if(H(o))t[i]=el(i,o,n);else if(o!=null){const r=kn(o);t[i]=()=>r}}},lo=(e,t)=>{const s=kn(t);e.slots.default=()=>s},ao=(e,t,s)=>{for(const n in t)(s||!xn(n))&&(e[n]=t[n])},tl=(e,t,s)=>{const n=e.slots=so();if(e.vnode.shapeFlag&32){const i=t._;i?(ao(n,t,s),s&&yi(n,"_",i,!0)):ro(t,n)}else t&&lo(e,t)},sl=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=Y;if(n.shapeFlag&32){const l=t._;l?s&&l===1?o=!1:ao(i,t,s):(o=!t.$stable,ro(t,i)),r=t}else t&&(lo(e,t),r={default:1});if(o)for(const l in i)!xn(l)&&r[l]==null&&delete i[l]},_e=ll;function nl(e){return il(e)}function il(e,t){const s=Cs();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:l,createComment:a,setText:p,setElementText:u,parentNode:m,nextSibling:y,setScopeId:A=He,insertStaticContent:D}=e,C=(c,f,v,S=null,x=null,_=null,I=void 0,R=null,O=!!f.dynamicChildren)=>{if(c===f)return;c&&!Dt(c,f)&&(S=ls(c),Ue(c,x,_,!0),c=null),f.patchFlag===-2&&(O=!1,f.dynamicChildren=null);const{type:w,ref:z,shapeFlag:U}=f;switch(w){case Rs:P(c,f,v,S);break;case lt:T(c,f,v,S);break;case Ks:c==null&&$(f,v,S,I);break;case ee:is(c,f,v,S,x,_,I,R,O);break;default:U&1?oe(c,f,v,S,x,_,I,R,O):U&6?os(c,f,v,S,x,_,I,R,O):(U&64||U&128)&&w.process(c,f,v,S,x,_,I,R,O,jt)}z!=null&&x?Vt(z,c&&c.ref,_,f||c,!f):z==null&&c&&c.ref!=null&&Vt(c.ref,null,_,c,!0)},P=(c,f,v,S)=>{if(c==null)n(f.el=l(f.children),v,S);else{const x=f.el=c.el;f.children!==c.children&&p(x,f.children)}},T=(c,f,v,S)=>{c==null?n(f.el=a(f.children||""),v,S):f.el=c.el},$=(c,f,v,S)=>{[c.el,c.anchor]=D(c.children,f,v,S,c.el,c.anchor)},j=({el:c,anchor:f},v,S)=>{let x;for(;c&&c!==f;)x=y(c),n(c,v,S),c=x;n(f,v,S)},M=({el:c,anchor:f})=>{let v;for(;c&&c!==f;)v=y(c),i(c),c=v;i(f)},oe=(c,f,v,S,x,_,I,R,O)=>{if(f.type==="svg"?I="svg":f.type==="math"&&(I="mathml"),c==null)Re(f,v,S,x,_,I,R,O);else{const w=c.el&&c.el._isVueCE?c.el:null;try{w&&w._beginPatch(),ns(c,f,x,_,I,R,O)}finally{w&&w._endPatch()}}},Re=(c,f,v,S,x,_,I,R)=>{let O,w;const{props:z,shapeFlag:U,transition:N,dirs:F}=c;if(O=c.el=r(c.type,_,z&&z.is,z),U&8?u(O,c.children):U&16&&st(c.children,O,null,S,x,Vs(c,_),I,R),F&&ht(c,null,S,"created"),Ie(O,c,c.scopeId,I,S),z){for(const J in z)J!=="value"&&!Ft(J)&&o(O,J,null,z[J],_,S);"value"in z&&o(O,"value",null,z.value,_),(w=z.onVnodeBeforeMount)&&De(w,S,c)}F&&ht(c,null,S,"beforeMount");const K=ol(x,N);K&&N.beforeEnter(O),n(O,f,v),((w=z&&z.onVnodeMounted)||K||F)&&_e(()=>{try{w&&De(w,S,c),K&&N.enter(O),F&&ht(c,null,S,"mounted")}finally{}},x)},Ie=(c,f,v,S,x)=>{if(v&&A(c,v),S)for(let _=0;_{for(let w=O;w{const R=f.el=c.el;let{patchFlag:O,dynamicChildren:w,dirs:z}=f;O|=c.patchFlag&16;const U=c.props||Y,N=f.props||Y;let F;if(v&>(v,!1),(F=N.onVnodeBeforeUpdate)&&De(F,v,f,c),z&&ht(f,c,v,"beforeUpdate"),v&>(v,!0),w&&(!c.dynamicChildren||c.dynamicChildren.length!==w.length)&&(O=0,I=!1,w=null),(U.innerHTML&&N.innerHTML==null||U.textContent&&N.textContent==null)&&u(R,""),w?dt(c.dynamicChildren,w,R,v,S,Vs(f,x),_):I||X(c,f,R,null,v,S,Vs(f,x),_,!1),O>0){if(O&16)It(R,U,N,v,x);else if(O&2&&U.class!==N.class&&o(R,"class",null,N.class,x),O&4&&o(R,"style",U.style,N.style,x),O&8){const K=f.dynamicProps;for(let J=0;J{F&&De(F,v,f,c),z&&ht(f,c,v,"updated")},S)},dt=(c,f,v,S,x,_,I)=>{for(let R=0;R{if(f!==v){if(f!==Y)for(const _ in f)!Ft(_)&&!(_ in v)&&o(c,_,f[_],null,x,S);for(const _ in v){if(Ft(_))continue;const I=v[_],R=f[_];I!==R&&_!=="value"&&o(c,_,R,I,x,S)}"value"in v&&o(c,"value",f.value,v.value,x)}},is=(c,f,v,S,x,_,I,R,O)=>{const w=f.el=c?c.el:l(""),z=f.anchor=c?c.anchor:l("");let{patchFlag:U,dynamicChildren:N,slotScopeIds:F}=f;F&&(R=R?R.concat(F):F),c==null?(n(w,v,S),n(z,v,S),st(f.children||[],v,z,x,_,I,R,O)):U>0&&U&64&&N&&c.dynamicChildren&&c.dynamicChildren.length===N.length?(dt(c.dynamicChildren,N,v,x,_,I,R),(f.key!=null||x&&f===x.subTree)&&co(c,f,!0)):X(c,f,v,z,x,_,I,R,O)},os=(c,f,v,S,x,_,I,R,O)=>{f.slotScopeIds=R,c==null?f.shapeFlag&512?x.ctx.activate(f,v,S,I,O):Us(f,v,S,x,_,I,O):En(c,f,O)},Us=(c,f,v,S,x,_,I)=>{const R=c.component=hl(c,S,x);if(qi(c)&&(R.ctx.renderer=jt),ml(R,!1,I),R.asyncDep){if(x&&x.registerDep(R,ge,I),!c.el){const O=R.subTree=ce(lt);T(null,O,f,v),c.placeholder=O.el}}else ge(R,c,f,v,x,_,I)},En=(c,f,v)=>{const S=f.component=c.component;if(Zr(c,f,v))if(S.asyncDep&&!S.asyncResolved){te(S,f,v);return}else S.next=f,S.update();else f.el=c.el,S.vnode=f},ge=(c,f,v,S,x,_,I)=>{const R=()=>{if(c.isMounted){let{next:U,bu:N,u:F,parent:K,vnode:J}=c;{const Me=uo(c);if(Me){U&&(U.el=J.el,te(c,U,I)),Me.asyncDep.then(()=>{_e(()=>{c.isUnmounted||w()},x)});return}}let q=U,ie;gt(c,!1),U?(U.el=J.el,te(c,U,I)):U=J,N&&fs(N),(ie=U.props&&U.props.onVnodeBeforeUpdate)&&De(ie,K,U,J),gt(c,!0);const le=Hn(c),je=c.subTree;c.subTree=le,C(je,le,m(je.el),ls(je),c,x,_),U.el=le.el,q===null&&Jr(c,le.el),F&&_e(F,x),(ie=U.props&&U.props.onVnodeUpdated)&&_e(()=>De(ie,K,U,J),x)}else{let U;const{el:N,props:F}=f,{bm:K,m:J,parent:q,root:ie,type:le}=c,je=Kt(f);gt(c,!1),K&&fs(K),!je&&(U=F&&F.onVnodeBeforeMount)&&De(U,q,f),gt(c,!0);{ie.ce&&ie.ce._hasShadowRoot()&&ie.ce._injectChildStyle(le,c.parent?c.parent.type:void 0);const Me=c.subTree=Hn(c);C(null,Me,v,S,c,x,_),f.el=Me.el}if(J&&_e(J,x),!je&&(U=F&&F.onVnodeMounted)){const Me=f;_e(()=>De(U,q,Me),x)}(f.shapeFlag&256||q&&Kt(q.vnode)&&q.vnode.shapeFlag&256)&&c.a&&_e(c.a,x),c.isMounted=!0,f=v=S=null}};c.scope.on();const O=c.effect=new Si(R);c.scope.off();const w=c.update=O.run.bind(O),z=c.job=O.runIfDirty.bind(O);z.i=c,z.id=c.uid,O.scheduler=()=>_n(z),gt(c,!0),w()},te=(c,f,v)=>{f.component=c;const S=c.vnode.props;c.vnode=f,c.next=null,Xr(c,f.props,S,v),sl(c,f.children,v),Ke(),Mn(c),We()},X=(c,f,v,S,x,_,I,R,O=!1)=>{const w=c&&c.children,z=c?c.shapeFlag:0,U=f.children,{patchFlag:N,shapeFlag:F}=f;if(N>0){if(N&128){rs(w,U,v,S,x,_,I,R,O);return}else if(N&256){ft(w,U,v,S,x,_,I,R,O);return}}F&8?(z&16&&Ut(w,x,_),U!==w&&u(v,U)):z&16?F&16?rs(w,U,v,S,x,_,I,R,O):Ut(w,x,_,!0):(z&8&&u(v,""),F&16&&st(U,v,S,x,_,I,R,O))},ft=(c,f,v,S,x,_,I,R,O)=>{c=c||xt,f=f||xt;const w=c.length,z=f.length,U=Math.min(w,z);let N;for(N=0;Nz?Ut(c,x,_,!0,!1,U):st(f,v,S,x,_,I,R,O,U)},rs=(c,f,v,S,x,_,I,R,O)=>{let w=0;const z=f.length;let U=c.length-1,N=z-1;for(;w<=U&&w<=N;){const F=c[w],K=f[w]=O?Ze(f[w]):Fe(f[w]);if(Dt(F,K))C(F,K,v,null,x,_,I,R,O);else break;w++}for(;w<=U&&w<=N;){const F=c[U],K=f[N]=O?Ze(f[N]):Fe(f[N]);if(Dt(F,K))C(F,K,v,null,x,_,I,R,O);else break;U--,N--}if(w>U){if(w<=N){const F=N+1,K=FN)for(;w<=U;)Ue(c[w],x,_,!0),w++;else{const F=w,K=w,J=new Map;for(w=K;w<=N;w++){const ye=f[w]=O?Ze(f[w]):Fe(f[w]);ye.key!=null&&J.set(ye.key,w)}let q,ie=0;const le=N-K+1;let je=!1,Me=0;const Mt=new Array(le);for(w=0;w=le){Ue(ye,x,_,!0);continue}let Ne;if(ye.key!=null)Ne=J.get(ye.key);else for(q=K;q<=N;q++)if(Mt[q-K]===0&&Dt(ye,f[q])){Ne=q;break}Ne===void 0?Ue(ye,x,_,!0):(Mt[Ne-K]=w+1,Ne>=Me?Me=Ne:je=!0,C(ye,f[Ne],v,null,x,_,I,R,O),ie++)}const $n=je?rl(Mt):xt;for(q=$n.length-1,w=le-1;w>=0;w--){const ye=K+w,Ne=f[ye],An=f[ye+1],On=ye+1{const{el:_,type:I,transition:R,children:O,shapeFlag:w}=c;if(w&6){pt(c.component.subTree,f,v,S);return}if(w&128){c.suspense.move(f,v,S);return}if(w&64){I.move(c,f,v,jt);return}if(I===ee){n(_,f,v);for(let U=0;UR.enter(_),x));else{const{leave:U,delayLeave:N,afterLeave:F}=R,K=()=>{c.ctx.isUnmounted?i(_):n(_,f,v)},J=()=>{const q=_._isLeaving||!!_[Bs];_._isLeaving&&_[Bs](!0),R.persisted&&!q?K():U(_,()=>{K(),F&&F()})};N?N(_,K,J):J()}else n(_,f,v)},Ue=(c,f,v,S=!1,x=!1)=>{const{type:_,props:I,ref:R,children:O,dynamicChildren:w,shapeFlag:z,patchFlag:U,dirs:N,cacheIndex:F,memo:K}=c;if(U===-2&&(x=!1),R!=null&&(Ke(),Vt(R,null,v,c,!0),We()),F!=null&&(f.renderCache[F]=void 0),z&256){f.ctx.deactivate(c);return}const J=z&1&&N,q=!Kt(c);let ie;if(q&&(ie=I&&I.onVnodeBeforeUnmount)&&De(ie,f,c),z&6)Po(c.component,v,S);else{if(z&128){c.suspense.unmount(v,S);return}J&&ht(c,null,f,"beforeUnmount"),z&64?c.type.remove(c,f,v,jt,S):w&&!w.hasOnce&&(_!==ee||U>0&&U&64)?Ut(w,f,v,!1,!0):(_===ee&&U&384||!x&&z&16)&&Ut(O,f,v),S&&Cn(c)}const le=K!=null&&F==null;(q&&(ie=I&&I.onVnodeUnmounted)||J||le)&&_e(()=>{ie&&De(ie,f,c),J&&ht(c,null,f,"unmounted"),le&&(c.el=null)},v)},Cn=c=>{const{type:f,el:v,anchor:S,transition:x}=c;if(f===ee){Co(v,S);return}if(f===Ks){M(c);return}const _=()=>{i(v),x&&!x.persisted&&x.afterLeave&&x.afterLeave()};if(c.shapeFlag&1&&x&&!x.persisted){const{leave:I,delayLeave:R}=x,O=()=>I(v,_);R?R(c.el,_,O):O()}else _()},Co=(c,f)=>{let v;for(;c!==f;)v=y(c),i(c),c=v;i(f)},Po=(c,f,v)=>{const{bum:S,scope:x,job:_,subTree:I,um:R,m:O,a:w}=c;Wn(O),Wn(w),S&&fs(S),x.stop(),_&&(_.flags|=8,Ue(I,c,f,v)),R&&_e(R,f),_e(()=>{c.isUnmounted=!0},f)},Ut=(c,f,v,S=!1,x=!1,_=0)=>{for(let I=_;I{if(c.shapeFlag&6)return ls(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const f=y(c.anchor||c.el),v=f&&f[xr];return v?y(v):f};let js=!1;const Pn=(c,f,v)=>{let S;c==null?f._vnode&&(Ue(f._vnode,null,null,!0),S=f._vnode.component):C(f._vnode||null,c,f,null,null,null,v),f._vnode=c,js||(js=!0,Mn(S),Bi(),js=!1)},jt={p:C,um:Ue,m:pt,r:Cn,mt:Us,mc:st,pc:X,pbc:dt,n:ls,o:e};return{render:Pn,hydrate:void 0,createApp:Hr(Pn)}}function Vs({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function gt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ol(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function co(e,t,s=!1){const n=e.children,i=t.children;if(L(n)&&L(i))for(let o=0;o>1,e[s[l]]0&&(t[n]=s[o-1]),s[o]=n)}}for(o=s.length,r=s[o-1];o-- >0;)s[o]=r,r=t[r];return s}function uo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:uo(t)}function Wn(e){if(e)for(let t=0;te.__isSuspense;function ll(e,t){t&&t.pendingBranch?L(e)?t.effects.push(...e):t.effects.push(e):mr(e)}const ee=Symbol.for("v-fgt"),Rs=Symbol.for("v-txt"),lt=Symbol.for("v-cmt"),Ks=Symbol.for("v-stc"),Gt=[];let we=null;function k(e=!1){Gt.push(we=e?null:[])}function al(){Gt.pop(),we=Gt[Gt.length-1]||null}let Xt=1;function Gn(e,t=!1){Xt+=e,e<0&&we&&t&&(we.hasOnce=!0)}function ho(e){return e.dynamicChildren=Xt>0?we||xt:null,al(),Xt>0&&we&&we.push(e),e}function E(e,t,s,n,i,o){return ho(d(e,t,s,n,i,o,!0))}function it(e,t,s,n,i){return ho(ce(e,t,s,n,i,!0))}function go(e){return e?e.__v_isVNode===!0:!1}function Dt(e,t){return e.type===t.type&&e.key===t.key}const mo=({key:e})=>e??null,hs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?ne(e)||fe(e)||H(e)?{i:xe,r:e,k:t,f:!!s}:e:null);function d(e,t=null,s=null,n=0,i=null,o=e===ee?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&mo(t),ref:t&&hs(t),scopeId:Vi,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:xe};return l?(ys(a,s),o&128&&e.normalize(a)):s&&(a.shapeFlag|=ne(s)?8:16),Xt>0&&!r&&we&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&we.push(a),a}const ce=cl;function cl(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===jr)&&(e=lt),go(e)){const l=Pt(e,t,!0);return s&&ys(l,s),Xt>0&&!o&&we&&(l.shapeFlag&6?we[we.indexOf(e)]=l:we.push(l)),l.patchFlag=-2,l}if(yl(e)&&(e=e.__vccOpts),t){t=ul(t);let{class:l,style:a}=t;l&&!ne(l)&&(t.class=$e(l)),Z(a)&&(vn(a)&&!L(a)&&(a=he({},a)),t.style=un(a))}const r=ne(e)?1:po(e)?128:kr(e)?64:Z(e)?4:H(e)?2:0;return d(e,t,s,n,i,r,o,!0)}function ul(e){return e?vn(e)||no(e)?he({},e):e:null}function Pt(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:l,transition:a}=e,p=t?dl(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:p,key:p&&mo(p),ref:t&&t.ref?s&&o?L(o)?o.concat(hs(t)):[o,hs(t)]:hs(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ee?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Pt(e.ssContent),ssFallback:e.ssFallback&&Pt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&n&&yn(u,a.clone(u)),u}function Te(e=" ",t=0){return ce(Rs,null,e,t)}function B(e="",t=!1){return t?(k(),it(lt,null,e)):ce(lt,null,e)}function Fe(e){return e==null||typeof e=="boolean"?ce(lt):L(e)?ce(ee,null,e.slice()):go(e)?Ze(e):ce(Rs,null,String(e))}function Ze(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Pt(e)}function ys(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(L(t))s=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ys(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!no(t)?t._ctx=xe:i===3&&xe&&(xe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(H(t)){if(n&65){ys(e,{default:t});return}t={default:t,_ctx:xe},s=32}else t=String(t),n&64?(s=16,t=[Te(t)]):s=8;e.children=t,e.shapeFlag|=s}function dl(...e){const t={};for(let s=0;sve||xe;let ws,nn;{const e=Cs(),t=(s,n)=>{let i;return(i=e[s])||(i=e[s]=[]),i.push(n),o=>{i.length>1?i.forEach(r=>r(o)):i[0](o)}};ws=t("__VUE_INSTANCE_SETTERS__",s=>ve=s),nn=t("__VUE_SSR_SETTERS__",s=>Qt=s)}const ss=e=>{const t=ve;return ws(e),e.scope.on(),()=>{e.scope.off(),ws(t)}},qn=()=>{ve&&ve.scope.off(),ws(null)};function bo(e){return e.vnode.shapeFlag&4}let Qt=!1;function ml(e,t=!1,s=!1){t&&nn(t);const{props:n,children:i}=e.vnode,o=bo(e);Yr(e,n,o,t),tl(e,i,s||t);const r=o?bl(e,t):void 0;return t&&nn(!1),r}function bl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Mr);const{setup:n}=s;if(n){Ke();const i=e.setupContext=n.length>1?_l(e):null,o=ss(e),r=ts(n,e,0,[e.props,i]),l=mi(r);if(We(),o(),(l||e.sp)&&!Kt(e)&&Gi(e),l){if(r.then(qn,qn),t)return r.then(a=>{Zn(e,a)}).catch(a=>{$s(a,e,0)});e.asyncDep=r}else Zn(e,r)}else vo(e)}function Zn(e,t,s){H(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=Di(t)),vo(e)}function vo(e,t,s){const n=e.type;e.render||(e.render=n.render||He);{const i=ss(e);Ke();try{Nr(e)}finally{We(),i()}}}const vl={get(e,t){return ue(e,"get",""),e[t]}};function _l(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,vl),slots:e.slots,emit:e.emit,expose:t}}function Is(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Di(rr(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in Wt)return Wt[s](e)},has(t,s){return s in t||s in Wt}})):e.proxy}function yl(e){return H(e)&&"__vccOpts"in e}const Qe=(e,t)=>dr(e,t,Qt),wl="3.5.39";/** -* @vue/runtime-dom v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let on;const Jn=typeof window<"u"&&window.trustedTypes;if(Jn)try{on=Jn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=on?e=>on.createHTML(e):e=>e,xl="http://www.w3.org/2000/svg",kl="http://www.w3.org/1998/Math/MathML",qe=typeof document<"u"?document:null,Yn=qe&&qe.createElement("template"),Sl={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 i=t==="svg"?qe.createElementNS(xl,e):t==="mathml"?qe.createElementNS(kl,e):s?qe.createElement(e,{is:s}):qe.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>qe.createTextNode(e),createComment:e=>qe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>qe.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Yn.innerHTML=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const l=Yn.content;if(n==="svg"||n==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Tl=Symbol("_vtc");function El(e,t,s){const n=e[Tl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const Xn=Symbol("_vod"),Cl=Symbol("_vsh"),Pl=Symbol(""),$l=/(?:^|;)\s*display\s*:/;function Al(e,t,s){const n=e.style,i=ne(s);let o=!1;if(s&&!i){if(t)if(ne(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Lt(n,l,"")}else for(const r in t)s[r]==null&&Lt(n,r,"");for(const r in s){r==="display"&&(o=!0);const l=s[r];l!=null?Rl(e,r,!ne(t)&&t?t[r]:void 0,l)||Lt(n,r,l):Lt(n,r,"")}}else if(i){if(t!==s){const r=n[Pl];r&&(s+=";"+r),n.cssText=s,o=$l.test(s)}}else t&&e.removeAttribute("style");Xn in e&&(e[Xn]=o?n.display:"",e[Cl]&&(n.display="none"))}const Qn=/\s*!important$/;function Lt(e,t,s){if(L(s))s.forEach(n=>Lt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Ol(e,t);Qn.test(s)?e.setProperty(ct(n),s.replace(Qn,""),"important"):e[n]=s}}const ei=["Webkit","Moz","ms"],Ws={};function Ol(e,t){const s=Ws[t];if(s)return s;let n=Ce(t);if(n!=="filter"&&n in e)return Ws[t]=n;n=_i(n);for(let i=0;iGs||(Dl.then(()=>Gs=0),Gs=Date.now());function Ll(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(L(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),l=[n];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Fl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?El(e,n,r):t==="style"?Al(e,s,n):ks(t)?Ss(t)||Ul(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Bl(e,t,n,r))?(ni(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&si(e,t,n,r,o,t!=="value")):e._isVueCE&&(Hl(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ne(n)))?ni(e,Ce(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),si(e,t,n,r))};function Bl(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&oi(t)&&H(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return oi(t)&&ne(s)?!1:t in e}function Hl(e,t){const s=e._def.props;if(!s)return!1;const n=Ce(t);return Array.isArray(s)?s.some(i=>Ce(i)===n):Object.keys(s).some(i=>Ce(i)===n)}const at=e=>{const t=e.props["onUpdate:modelValue"]||!1;return L(t)?s=>fs(t,s):t};function Vl(e){e.target.composing=!0}function ri(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ee=Symbol("_assign");function li(e,t,s){return t&&(e=e.trim()),s&&(e=Es(e)),e}const pe={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ee]=at(i);const o=n||i.props&&i.props.type==="number";Xe(e,t?"change":"input",r=>{r.target.composing||e[Ee](li(e.value,s,o))}),(s||o)&&Xe(e,"change",()=>{e.value=li(e.value,s,o)}),t||(Xe(e,"compositionstart",Vl),Xe(e,"compositionend",ri),Xe(e,"change",ri))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ee]=at(r),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?Es(e.value):e.value,a=t??"";if(l===a)return;const p=e.getRootNode();(p instanceof Document||p instanceof ShadowRoot)&&p.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===a)||(e.value=a)}},Kl={deep:!0,created(e,t,s){e[Ee]=at(s),Xe(e,"change",()=>{const n=e._modelValue,i=$t(e),o=e.checked,r=e[Ee];if(L(n)){const l=dn(n,i),a=l!==-1;if(o&&!a)r(n.concat(i));else if(!o&&a){const p=[...n];p.splice(l,1),r(p)}}else if(Rt(n)){const l=new Set(n);o?l.add(i):l.delete(i),r(l)}else r(yo(e,o))})},mounted:ai,beforeUpdate(e,t,s){e[Ee]=at(s),ai(e,t,s)}};function ai(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(L(t))i=dn(t,n.props.value)>-1;else if(Rt(t))i=t.has(n.props.value);else{if(t===s)return;i=rt(t,yo(e,!0))}e.checked!==i&&(e.checked=i)}const Wl={created(e,{value:t},s){e.checked=rt(t,s.props.value),e[Ee]=at(s),Xe(e,"change",()=>{e[Ee]($t(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ee]=at(n),t!==s&&(e.checked=rt(t,n.props.value))}},xs={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=Rt(t);Xe(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Es($t(r)):$t(r));e[Ee](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Li(()=>{e._assigning=!1})}),e[Ee]=at(n)},mounted(e,{value:t}){ci(e,t)},beforeUpdate(e,t,s){e[Ee]=at(s)},updated(e,{value:t}){e._assigning||ci(e,t)}};function ci(e,t){const s=e.multiple,n=L(t);if(!(s&&!n&&!Rt(t))){for(let i=0,o=e.options.length;iString(p)===String(l)):r.selected=dn(t,l)>-1}else r.selected=t.has(l);else if(rt($t(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function $t(e){return"_value"in e?e._value:e.value}function yo(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const Gl={created(e,t,s){ds(e,t,s,null,"created")},mounted(e,t,s){ds(e,t,s,null,"mounted")},beforeUpdate(e,t,s,n){ds(e,t,s,n,"beforeUpdate")},updated(e,t,s,n){ds(e,t,s,n,"updated")}};function ql(e,t){switch(e){case"SELECT":return xs;case"TEXTAREA":return pe;default:switch(t){case"checkbox":return Kl;case"radio":return Wl;default:return pe}}}function ds(e,t,s,n,i){const r=ql(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Zl=["ctrl","shift","alt","meta"],Jl={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Zl.some(s=>e[`${s}Key`]&&!t.includes(s))},Yl=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((i,...o)=>{for(let r=0;r{const s=e._withKeys||(e._withKeys={}),n=t.join(".");return s[n]||(s[n]=(i=>{if(!("key"in i))return;const o=ct(i.key);if(t.some(r=>r===o||Xl[r]===o))return e(i)}))},ea=he({patchProp:Fl},Sl);let ui;function ta(){return ui||(ui=nl(ea))}const sa=((...e)=>{const t=ta().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=ia(n);if(!i)return;const o=t._component;!H(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,na(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function na(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ia(e){return ne(e)?document.querySelector(e):e}const wo="dh-panel-theme";function oa(){var e;try{const t=localStorage.getItem(wo);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Et=V(oa());function xo(e){Et.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(wo,e)}catch{}}function di(){xo(Et.value==="dark"?"light":"dark")}xo(Et.value);const ra={apiServer:"API server",switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme",theme:"Theme",signOut:"Sign out",loading:"Loading…",standardUserNote:"Signed in as a standard user — management sections need an admin role",footer:"DriverVault — car maintenance & service tracker."},la={overview:"Overview",users:"Users",orgs:"Organizations",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},aa={title:"Sign in",subtitle:"Superadmin console for the DriverVault API Server.",email:"Email",password:"Password",submit:"Sign in",submitting:"Signing in…",invalid:"Invalid email or password.",failed:"Could not sign in.",authNote:"Authenticates against PocketBase through this server"},ca={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ua={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},da={title:"Users",allOrgs:"All organizations",yourOrg:"Your organization",newUser:"New user",password:"Password",passwordUnchanged:"Password (blank = unchanged)",passwordPlaceholder:"min 8 characters",orgNone:"— none —",you:"you",empty:"No users.",confirmDelete:"Delete {email}? This cannot be undone."},fa={title:"Organizations",subtitle:"Tenants users belong to",newOrg:"New organization",namePlaceholder:"Acme Fleet",empty:"No organizations yet.",colId:"ID",confirmDelete:'Delete the organization "{name}"?'},pa={title:"PocketBase",subtitle:"Database connection used by every endpoint",connected:"connected",noSuperuser:"no superuser",unreachable:"unreachable",baseUrl:"Base URL",superuserEmail:"Superuser email",superuserPassword:"Superuser password",passwordUnchanged:"unchanged",passwordNotSet:"not set",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Connection OK — superuser authenticated.",testReachableNoAuth:"PocketBase is reachable, but the service account did not authenticate.",testUnreachable:"PocketBase is not reachable at that address.",savedNotice:"Saved. The server is now using this PocketBase."},ha={title:"Web App",subtitle:"Address probed by the status check, and who may call this API from a browser",reachable:"reachable",unreachable:"unreachable",baseUrl:"Base URL",allowedOrigins:"Allowed origins",originsHint:"Comma separated, or {star} for any. Native mobile apps are not subject to CORS.",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Web App is reachable.",testFailed:"Web App did not answer its health check at that address.",savedNotice:"Saved. New origins apply to the next request."},ga={title:"Plugins",subtitle:"Third-party service integrations",registerExternal:"Register external",cancelRegister:"Cancel",name:"Name",baseUrl:"Base URL",provider:"Provider",register:"Register",empty:"No plugins yet. Register an external one above, or compile a built-in connector.",builtin:"builtin",enabled:"enabled",disabled:"disabled",health:"Health",configure:"Configure",close:"Close",noConfig:"This plugin takes no configuration.",notSet:"Not set — let organizations and users choose",capabilities:"Capabilities",saved:"Saved.",checking:"Checking…",save:"Save",saveEnable:"Save & enable",disable:"Disable",remove:"Remove",builtinNote:"Built-in plugins can be disabled but not removed",confirmRemove:'Remove the external plugin "{name}"? Its saved config is deleted.'},ma={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupParts:"Parts",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},ba={app:ra,sections:la,login:aa,status:ca,common:ua,users:da,orgs:fa,pocketbase:pa,webapp:ha,plugins:ga,api:ma},va={apiServer:"Serwer API",switchToLight:"Przełącz na motyw jasny",switchToDark:"Przełącz na motyw ciemny",theme:"Motyw",signOut:"Wyloguj się",loading:"Ładowanie…",standardUserNote:"Zalogowano jako zwykły użytkownik — sekcje zarządzania wymagają roli administratora",footer:"DriverVault — rejestr serwisu i konserwacji samochodu."},_a={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},ya={title:"Zaloguj się",subtitle:"Konsola superadministratora serwera API DriverVault.",email:"E-mail",password:"Hasło",submit:"Zaloguj się",submitting:"Logowanie…",invalid:"Nieprawidłowy e-mail lub hasło.",failed:"Nie udało się zalogować.",authNote:"Uwierzytelnia w PocketBase za pośrednictwem tego serwera"},wa={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},xa={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},ka={title:"Użytkownicy",allOrgs:"Wszystkie organizacje",yourOrg:"Twoja organizacja",newUser:"Nowy użytkownik",password:"Hasło",passwordUnchanged:"Hasło (puste = bez zmian)",passwordPlaceholder:"min. 8 znaków",orgNone:"— brak —",you:"Ty",empty:"Brak użytkowników.",confirmDelete:"Usunąć {email}? Tej operacji nie można cofnąć."},Sa={title:"Organizacje",subtitle:"Podmioty, do których należą użytkownicy",newOrg:"Nowa organizacja",namePlaceholder:"Acme Fleet",empty:"Brak organizacji.",colId:"ID",confirmDelete:"Usunąć organizację „{name}”?"},Ta={title:"PocketBase",subtitle:"Połączenie z bazą danych używane przez każdy punkt końcowy",connected:"połączono",noSuperuser:"brak superużytkownika",unreachable:"niedostępny",baseUrl:"Adres bazowy",superuserEmail:"E-mail superużytkownika",superuserPassword:"Hasło superużytkownika",passwordUnchanged:"bez zmian",passwordNotSet:"nie ustawiono",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Połączenie OK — superużytkownik uwierzytelniony.",testReachableNoAuth:"PocketBase jest dostępny, ale konto usługowe nie zostało uwierzytelnione.",testUnreachable:"PocketBase jest niedostępny pod tym adresem.",savedNotice:"Zapisano. Serwer korzysta teraz z tego PocketBase."},Ea={title:"Aplikacja webowa",subtitle:"Adres sprawdzany podczas kontroli statusu oraz kto może wywoływać to API z przeglądarki",reachable:"dostępna",unreachable:"niedostępna",baseUrl:"Adres bazowy",allowedOrigins:"Dozwolone źródła",originsHint:"Oddzielone przecinkami lub {star} dla dowolnego. Natywne aplikacje mobilne nie podlegają CORS.",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Aplikacja webowa jest dostępna.",testFailed:"Aplikacja webowa nie odpowiedziała na kontrolę stanu pod tym adresem.",savedNotice:"Zapisano. Nowe źródła obowiązują od następnego żądania."},Ca={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",registerExternal:"Zarejestruj zewnętrzną",cancelRegister:"Anuluj",name:"Nazwa",baseUrl:"Adres bazowy",provider:"Dostawca",register:"Zarejestruj",empty:"Brak wtyczek. Zarejestruj zewnętrzną powyżej lub skompiluj wbudowany łącznik.",builtin:"wbudowana",enabled:"włączona",disabled:"wyłączona",health:"Stan",configure:"Konfiguruj",close:"Zamknij",noConfig:"Ta wtyczka nie wymaga konfiguracji.",notSet:"Nie ustawiono — pozwól organizacjom i użytkownikom wybrać",capabilities:"Możliwości",saved:"Zapisano.",checking:"Sprawdzanie…",save:"Zapisz",saveEnable:"Zapisz i włącz",disable:"Wyłącz",remove:"Usuń",builtinNote:"Wtyczki wbudowane można wyłączyć, ale nie usunąć",confirmRemove:"Usunąć zewnętrzną wtyczkę „{name}”? Jej zapisana konfiguracja zostanie usunięta."},Pa={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupParts:"Części",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},$a={app:va,sections:_a,login:ya,status:wa,common:xa,users:ka,orgs:Sa,pocketbase:Ta,webapp:Ea,plugins:Ca,api:Pa},Aa={apiServer:"API-server",switchToLight:"Skift til lyst tema",switchToDark:"Skift til mørkt tema",theme:"Tema",signOut:"Log ud",loading:"Indlæser…",standardUserNote:"Logget ind som almindelig bruger — administrationssektioner kræver en administratorrolle",footer:"DriverVault — bilservice- og vedligeholdelsesregister."},Oa={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},Ra={title:"Log ind",subtitle:"Superadmin-konsol til DriverVault API-serveren.",email:"E-mail",password:"Adgangskode",submit:"Log ind",submitting:"Logger ind…",invalid:"Ugyldig e-mail eller adgangskode.",failed:"Kunne ikke logge ind.",authNote:"Godkender mod PocketBase gennem denne server"},Ia={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},Ua={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},ja={title:"Brugere",allOrgs:"Alle organisationer",yourOrg:"Din organisation",newUser:"Ny bruger",password:"Adgangskode",passwordUnchanged:"Adgangskode (tom = uændret)",passwordPlaceholder:"mindst 8 tegn",orgNone:"— ingen —",you:"dig",empty:"Ingen brugere.",confirmDelete:"Slet {email}? Dette kan ikke fortrydes."},Ma={title:"Organisationer",subtitle:"Enheder, som brugere tilhører",newOrg:"Ny organisation",namePlaceholder:"Acme Fleet",empty:"Ingen organisationer endnu.",colId:"ID",confirmDelete:'Slet organisationen "{name}"?'},Na={title:"PocketBase",subtitle:"Databaseforbindelse brugt af hvert endpoint",connected:"forbundet",noSuperuser:"ingen superbruger",unreachable:"utilgængelig",baseUrl:"Basis-URL",superuserEmail:"Superbrugerens e-mail",superuserPassword:"Superbrugerens adgangskode",passwordUnchanged:"uændret",passwordNotSet:"ikke angivet",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Forbindelse OK — superbruger godkendt.",testReachableNoAuth:"PocketBase er tilgængelig, men servicekontoen blev ikke godkendt.",testUnreachable:"PocketBase er ikke tilgængelig på den adresse.",savedNotice:"Gemt. Serveren bruger nu denne PocketBase."},Da={title:"Webapp",subtitle:"Adressen, der tjekkes ved statuskontrol, og hvem der må kalde dette API fra en browser",reachable:"tilgængelig",unreachable:"utilgængelig",baseUrl:"Basis-URL",allowedOrigins:"Tilladte oprindelser",originsHint:"Kommasepareret, eller {star} for enhver. Native mobilapps er ikke underlagt CORS.",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Webappen er tilgængelig.",testFailed:"Webappen svarede ikke på sit helbredstjek på den adresse.",savedNotice:"Gemt. Nye oprindelser gælder fra næste anmodning."},za={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",registerExternal:"Registrér ekstern",cancelRegister:"Annuller",name:"Navn",baseUrl:"Basis-URL",provider:"Udbyder",register:"Registrér",empty:"Ingen plugins endnu. Registrér et eksternt ovenfor, eller kompilér et indbygget stik.",builtin:"indbygget",enabled:"aktiveret",disabled:"deaktiveret",health:"Helbred",configure:"Konfigurer",close:"Luk",noConfig:"Dette plugin kræver ingen konfiguration.",notSet:"Ikke angivet — lad organisationer og brugere vælge",capabilities:"Funktioner",saved:"Gemt.",checking:"Tjekker…",save:"Gem",saveEnable:"Gem og aktivér",disable:"Deaktiver",remove:"Fjern",builtinNote:"Indbyggede plugins kan deaktiveres, men ikke fjernes",confirmRemove:'Fjern det eksterne plugin "{name}"? Dets gemte konfiguration slettes.'},La={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupParts:"Reservedele",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Fa={app:Aa,sections:Oa,login:Ra,status:Ia,common:Ua,users:ja,orgs:Ma,pocketbase:Na,webapp:Da,plugins:za,api:La},ko="dh-panel-lang",So="en",At={en:ba,pl:$a,da:Fa},Ba=Object.keys(At);function Ha(){try{const t=localStorage.getItem(ko);if(t&&At[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return At[e]?e:So}const Sn=V(Ha());function Va(e){if(At[e]){Sn.value=e;try{localStorage.setItem(ko,e)}catch{}}}function fi(e,t){return t.split(".").reduce((s,n)=>s==null?void 0:s[n],e)}function Ka(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Wa(e,t,s){let n="other";try{n=new Intl.PluralRules(s).select(t)}catch{n=t===1?"one":"other"}return e[n]??e.other??e.one}function h(e,t){const s=Sn.value;let n=fi(At[s],e);if(n==null&&(n=fi(At[So],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Wa(n,t.n,s)}return typeof n!="string"?e:Ka(n,t)}function pi(e,t,s){const i=h(e,{...s,[t]:"\0"}),o=i.indexOf("\0");return o===-1?{before:i,after:""}:{before:i.slice(0,o),after:i.slice(o+1)}}const rn="dh-panel-token";function Ga(){try{return localStorage.getItem(rn)||""}catch{return""}}const Ot=V(Ga()),de=V(null),bt=Qe(()=>{var e;return((e=de.value)==null?void 0:e.role)==="superadmin"}),hi=Qe(()=>{var e,t;return((e=de.value)==null?void 0:e.role)==="admin"||((t=de.value)==null?void 0:t.role)==="superadmin"});function To(e){Ot.value=e;try{e?localStorage.setItem(rn,e):localStorage.removeItem(rn)}catch{}}class qa extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Za(e,t){if(!e||typeof e!="object")return`HTTP ${t}`;if(e.error)return e.error;const s=Object.entries(e.data||{}).map(([n,i])=>`${n}: ${(i==null?void 0:i.message)||i}`).filter(Boolean);return s.length?s.join("; "):e.message||`HTTP ${t}`}async function se(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Ot.value&&(i.Authorization=Ot.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let l=null;try{l=r?JSON.parse(r):null}catch{l=null}if(!o.ok)throw o.status===401&&n&&Tn(),new qa(Za(l,o.status),o.status,l);return l}async function Ja(e,t){const s=await se("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return To(s.token),await Eo(),de.value}async function Eo(){return de.value=await se("/api/identity"),de.value}function Tn(){To(""),de.value=null}async function Ya(){if(!Ot.value)return null;try{return await Eo()}catch{return Tn(),null}}const Xa={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},Qa={class:"dh-card p-6"},ec={class:"text-lg font-bold tracking-[-0.02em] text-strong"},tc={class:"mt-1 mb-5 text-sm text-body"},sc={class:"dh-label",for:"login-email"},nc={class:"dh-label",for:"login-password"},ic={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},oc=["disabled"],rc={class:"eyebrow text-center"},lc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=V(""),i=V(""),o=V(""),r=V(!1),l=Qe(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function a(){if(l.value){o.value="",r.value=!0;try{const p=await Ja(n.value.trim(),i.value);s("authenticated",p)}catch(p){o.value=p.status===400||p.status===404?h("login.invalid"):p.message||h("login.failed"),i.value=""}finally{r.value=!1}}}return(p,u)=>(k(),E("div",Xa,[d("div",Qa,[d("h1",ec,b(g(h)("login.title")),1),d("p",tc,b(g(h)("login.subtitle")),1),d("form",{class:"flex flex-col gap-4",onSubmit:Yl(a,["prevent"])},[d("div",null,[d("label",sc,b(g(h)("login.email")),1),re(d("input",{id:"login-email","onUpdate:modelValue":u[0]||(u[0]=m=>n.value=m),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[pe,n.value]])]),d("div",null,[d("label",nc,b(g(h)("login.password")),1),re(d("input",{id:"login-password","onUpdate:modelValue":u[1]||(u[1]=m=>i.value=m),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[pe,i.value]])]),o.value?(k(),E("p",ic,b(o.value),1)):B("",!0),d("button",{class:"dh-btn w-full",type:"submit",disabled:!l.value},b(r.value?g(h)("login.submitting"):g(h)("login.submit")),9,oc)],32)]),d("p",rc,b(g(h)("login.authNote")),1)]))}},ac={class:"dh-card overflow-hidden"},cc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uc={class:"text-base font-bold tracking-[-0.02em] text-strong"},dc={key:0,class:"dh-pill bg-danger-soft text-danger"},fc={key:0,class:"px-5 py-4 text-sm text-danger"},pc={key:1,class:"w-full text-left text-sm"},hc={class:"px-5 py-3 font-medium text-strong"},gc={class:"data px-5 py-3 text-xs text-muted"},mc={class:"data px-5 py-3 text-right text-xs text-muted"},bc={class:"px-5 py-3 text-right"},vc={key:2,class:"px-5 py-4 text-sm text-muted"},_c={__name:"StatusCard",setup(e){const t=V(null),s=V("");let n=null;async function i(){try{t.value=await se("/api/status",{auth:!1}),s.value=""}catch(l){t.value=null,s.value=l.message||h("status.unreachable")}}const o=Qe(()=>{var l,a,p;return[{key:"apiServer",label:h("status.apiServer"),h:(l=t.value)==null?void 0:l.apiServer},{key:"pocketBase",label:h("status.pocketBase"),h:(a=t.value)==null?void 0:a.pocketBase},{key:"webApp",label:h("status.webApp"),h:(p=t.value)==null?void 0:p.webApp}]});ut(()=>{i(),n=setInterval(i,1e4)}),wn(()=>clearInterval(n));const r=l=>l==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(l,a)=>(k(),E("div",ac,[d("div",cc,[d("div",uc,b(g(h)("status.title")),1),s.value?(k(),E("span",dc,[a[0]||(a[0]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b(g(h)("status.unreachable")),1)])):B("",!0)]),s.value?(k(),E("div",fc,b(s.value),1)):t.value?(k(),E("table",pc,[d("tbody",null,[(k(!0),E(ee,null,ke(o.value,p=>(k(),E("tr",{key:p.key,class:"border-t border-subtle first:border-t-0"},[d("td",hc,b(p.label),1),d("td",gc,b(p.h.url||g(h)("status.thisProcess")),1),d("td",mc,b(p.h.latencyMs!=null?p.h.latencyMs+"ms":g(h)("common.empty")),1),d("td",bc,[d("span",{class:$e(["dh-pill",r(p.h.status)])},[a[1]||(a[1]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b(p.h.status),1)],2)])]))),128))])])):(k(),E("div",vc,b(g(h)("status.checking")),1))]))}},yc={class:"dh-card overflow-hidden"},wc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},xc={class:"text-base font-bold tracking-[-0.02em] text-strong"},kc={class:"mt-0.5 text-xs text-muted"},Sc={class:"flex flex-col gap-4 px-5 py-4"},Tc={class:"dh-label",for:"pb-url"},Ec={class:"grid gap-4 sm:grid-cols-2"},Cc={class:"dh-label",for:"pb-email"},Pc={class:"dh-label",for:"pb-password"},$c=["placeholder"],Ac={key:0,class:"data text-xs text-muted"},Oc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Rc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Ic={class:"flex items-center gap-2"},Uc=["disabled"],jc=["disabled"],Mc={class:"eyebrow"},Nc={__name:"PocketBaseCard",setup(e){const t=V(null),s=V({url:"",adminEmail:"",adminPassword:""}),n=V(null),i=V(""),o=V(""),r=V(!1);async function l(){try{t.value=await se("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(u){i.value=u.message}}ut(l);async function a(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?h("pocketbase.testOk"):n.value.reachable?h("pocketbase.testReachableNoAuth"):h("pocketbase.testUnreachable")}catch(u){i.value=u.message}finally{r.value=!1}}async function p(){i.value="",o.value="",r.value=!0;try{const u=await se("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=u.config,n.value=u.config.probe,s.value.adminPassword="",o.value=u.warning||h("pocketbase.savedNotice")}catch(u){i.value=u.message}finally{r.value=!1}}return(u,m)=>{var y,A;return k(),E("div",yc,[d("div",wc,[d("div",null,[d("div",xc,b(g(h)("pocketbase.title")),1),d("p",kc,b(g(h)("pocketbase.subtitle")),1)]),n.value?(k(),E("span",{key:0,class:$e(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[m[3]||(m[3]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(" "+b(n.value.superuser?g(h)("pocketbase.connected"):n.value.reachable?g(h)("pocketbase.noSuperuser"):g(h)("pocketbase.unreachable")),1)],2)):B("",!0)]),d("div",Sc,[d("div",null,[d("label",Tc,b(g(h)("pocketbase.baseUrl")),1),re(d("input",{id:"pb-url","onUpdate:modelValue":m[0]||(m[0]=D=>s.value.url=D),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[pe,s.value.url]])]),d("div",Ec,[d("div",null,[d("label",Cc,b(g(h)("pocketbase.superuserEmail")),1),re(d("input",{id:"pb-email","onUpdate:modelValue":m[1]||(m[1]=D=>s.value.adminEmail=D),class:"dh-input",autocomplete:"off"},null,512),[[pe,s.value.adminEmail]])]),d("div",null,[d("label",Pc,b(g(h)("pocketbase.superuserPassword")),1),re(d("input",{id:"pb-password","onUpdate:modelValue":m[2]||(m[2]=D=>s.value.adminPassword=D),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(y=t.value)!=null&&y.adminConfigured?g(h)("pocketbase.passwordUnchanged"):g(h)("pocketbase.passwordNotSet")},null,8,$c),[[pe,s.value.adminPassword]])])]),(A=n.value)!=null&&A.detail?(k(),E("p",Ac,b(n.value.detail),1)):B("",!0),o.value?(k(),E("p",Oc,b(o.value),1)):B("",!0),i.value?(k(),E("p",Rc,b(i.value),1)):B("",!0),d("div",Ic,[d("button",{class:"dh-btn",disabled:r.value,onClick:p},b(g(h)("pocketbase.saveApply")),9,Uc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:a},b(g(h)("pocketbase.testConnection")),9,jc),m[4]||(m[4]=d("span",{class:"flex-1"},null,-1)),d("span",Mc,b(g(h)("pocketbase.persistedEnv")),1)])])])}}},Dc={class:"dh-card overflow-hidden"},zc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Lc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Fc={class:"mt-0.5 text-xs text-muted"},Bc={class:"flex flex-col gap-4 px-5 py-4"},Hc={class:"dh-label",for:"web-url"},Vc={class:"dh-label",for:"web-origins"},Kc={class:"mt-1 text-xs text-muted"},Wc={key:0,class:"data text-xs text-muted"},Gc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},qc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Zc={class:"flex items-center gap-2"},Jc=["disabled"],Yc=["disabled"],Xc={class:"eyebrow"},Qc={__name:"WebAppCard",setup(e){const t=V(null),s=V({url:"",origins:""}),n=V(null),i=V(""),o=V(""),r=V(!1),l=y=>y.split(",").map(A=>A.trim()).filter(Boolean);function a(y){t.value=y,s.value={url:y.url,origins:(y.allowOrigins||[]).join(", ")},n.value=y.probe}async function p(){try{a(await se("/api/admin/webapp-config"))}catch(y){i.value=y.message}}ut(p);async function u(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?h("webapp.testOk"):h("webapp.testFailed")}catch(y){i.value=y.message}finally{r.value=!1}}async function m(){i.value="",o.value="",r.value=!0;try{const y=await se("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:l(s.value.origins)}});a(y.config),o.value=y.warning||h("webapp.savedNotice")}catch(y){i.value=y.message}finally{r.value=!1}}return(y,A)=>{var D;return k(),E("div",Dc,[d("div",zc,[d("div",null,[d("div",Lc,b(g(h)("webapp.title")),1),d("p",Fc,b(g(h)("webapp.subtitle")),1)]),n.value?(k(),E("span",{key:0,class:$e(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[A[2]||(A[2]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(" "+b(n.value.status==="ok"?g(h)("webapp.reachable"):g(h)("webapp.unreachable")),1)],2)):B("",!0)]),d("div",Bc,[d("div",null,[d("label",Hc,b(g(h)("webapp.baseUrl")),1),re(d("input",{id:"web-url","onUpdate:modelValue":A[0]||(A[0]=C=>s.value.url=C),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[pe,s.value.url]])]),d("div",null,[d("label",Vc,b(g(h)("webapp.allowedOrigins")),1),re(d("input",{id:"web-origins","onUpdate:modelValue":A[1]||(A[1]=C=>s.value.origins=C),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[pe,s.value.origins]]),d("p",Kc,[Te(b(g(pi)("webapp.originsHint","star").before),1),A[3]||(A[3]=d("span",{class:"data"},"*",-1)),Te(b(g(pi)("webapp.originsHint","star").after),1)])]),(D=n.value)!=null&&D.error?(k(),E("p",Wc,b(n.value.error),1)):B("",!0),o.value?(k(),E("p",Gc,b(o.value),1)):B("",!0),i.value?(k(),E("p",qc,b(i.value),1)):B("",!0),d("div",Zc,[d("button",{class:"dh-btn",disabled:r.value,onClick:m},b(g(h)("webapp.saveApply")),9,Jc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:u},b(g(h)("webapp.testConnection")),9,Yc),A[4]||(A[4]=d("span",{class:"flex-1"},null,-1)),d("span",Xc,b(g(h)("webapp.persistedEnv")),1)])])])}}},eu={class:"dh-card overflow-hidden"},tu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},su={class:"text-base font-bold tracking-[-0.02em] text-strong"},nu={class:"mt-0.5 text-xs text-muted"},iu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},ou={class:"grid gap-3 sm:grid-cols-3"},ru={class:"dh-label"},lu={class:"dh-label"},au={class:"dh-label"},cu=["disabled"],uu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},du={key:2,class:"px-5 py-6 text-center text-sm text-muted"},fu={class:"flex items-center gap-3 px-5 py-3"},pu=["onClick"],hu={class:"font-semibold text-strong"},gu={class:"dh-pill bg-sunken text-muted"},mu={key:0,class:"text-xs text-muted"},bu=["disabled","onClick"],vu=["disabled","onClick"],_u={key:0,class:"bg-sunken px-5 py-4"},yu={key:0,class:"data mb-3 text-xs text-muted"},wu={key:1,class:"grid gap-3 sm:grid-cols-2"},xu={class:"dh-label"},ku={key:0,class:"text-danger"},Su=["onUpdate:modelValue"],Tu={key:0,value:""},Eu=["value"],Cu=["onUpdate:modelValue","type","placeholder"],Pu={key:2,class:"mt-1 text-xs text-muted"},$u={key:2,class:"text-xs text-muted"},Au={key:3,class:"mt-4"},Ou={class:"eyebrow mb-1.5"},Ru={class:"data flex flex-col gap-1 text-xs text-muted"},Iu={class:"text-strong"},Uu={key:0},ju={key:1},Mu={key:4,class:"data mt-3 text-xs text-body"},Nu={class:"mt-4 flex items-center gap-2"},Du=["disabled","onClick"],zu=["disabled","onClick"],Lu=["disabled","onClick"],Fu={key:5,class:"eyebrow mt-2"},Bu={__name:"PluginsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=Jt({}),r=Jt({}),l=V(!1),a=V({name:"",baseURL:"",provider:""});async function p(){try{const P=await se("/api/admin/plugins");t.value=P.plugins||[],s.value=""}catch(P){s.value=P.message}}ut(p);function u(P){var $;if(i.value===P.name){i.value=null;return}const T={};for(const j of P.configFields||[])T[j.key]=(($=P.config)==null?void 0:$[j.key])??"";o[P.name]=T,i.value=P.name}async function m(P,T){n.value=!0,r[P.name]="";try{const $=await se(`/api/admin/plugins/${encodeURIComponent(P.name)}`,{method:"PUT",body:{enabled:T,config:o[P.name]??{}}});r[P.name]=$.warning||h("plugins.saved"),await p()}catch($){r[P.name]=$.message}finally{n.value=!1}}async function y(P){n.value=!0,r[P.name]=h("plugins.checking");try{const T=await se(`/api/admin/plugins/${encodeURIComponent(P.name)}/health`,{method:"POST"});r[P.name]=`${T.health.status}${T.health.detail?" — "+T.health.detail:""}`,await p()}catch(T){r[P.name]=T.message}finally{n.value=!1}}async function A(P){if(confirm(h("plugins.confirmRemove",{name:P.name}))){n.value=!0;try{await se(`/api/admin/plugins/${encodeURIComponent(P.name)}`,{method:"DELETE"}),i.value===P.name&&(i.value=null),await p()}catch(T){r[P.name]=T.message}finally{n.value=!1}}}async function D(){n.value=!0,s.value="";try{await se("/api/admin/plugins",{method:"POST",body:a.value}),a.value={name:"",baseURL:"",provider:""},l.value=!1,await p()}catch(P){s.value=P.message}finally{n.value=!1}}const C=P=>P==="ok"?"bg-success-soft text-success":P==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(P,T)=>(k(),E("div",eu,[d("div",tu,[d("div",null,[d("div",su,b(g(h)("plugins.title")),1),d("p",nu,b(g(h)("plugins.subtitle")),1)]),d("button",{class:"dh-btn-ghost",onClick:T[0]||(T[0]=$=>l.value=!l.value)},b(l.value?g(h)("plugins.cancelRegister"):g(h)("plugins.registerExternal")),1)]),l.value?(k(),E("div",iu,[d("div",ou,[d("div",null,[d("label",ru,b(g(h)("plugins.name")),1),re(d("input",{"onUpdate:modelValue":T[1]||(T[1]=$=>a.value.name=$),class:"dh-input",placeholder:"acme-parts"},null,512),[[pe,a.value.name]])]),d("div",null,[d("label",lu,b(g(h)("plugins.baseUrl")),1),re(d("input",{"onUpdate:modelValue":T[2]||(T[2]=$=>a.value.baseURL=$),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[pe,a.value.baseURL]])]),d("div",null,[d("label",au,b(g(h)("plugins.provider")),1),re(d("input",{"onUpdate:modelValue":T[3]||(T[3]=$=>a.value.provider=$),class:"dh-input",placeholder:"ACME Corp"},null,512),[[pe,a.value.provider]])])]),d("button",{class:"dh-btn mt-3",disabled:n.value||!a.value.name||!a.value.baseURL,onClick:D},b(g(h)("plugins.register")),9,cu)])):B("",!0),s.value?(k(),E("p",uu,b(s.value),1)):B("",!0),t.value.length?B("",!0):(k(),E("p",du,b(g(h)("plugins.empty")),1)),(k(!0),E(ee,null,ke(t.value,$=>(k(),E("div",{key:$.name,class:"border-t border-subtle first:border-t-0"},[d("div",fu,[d("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:j=>u($)},[d("span",hu,b($.name),1),d("span",gu,b($.kind||g(h)("plugins.builtin")),1),$.provider?(k(),E("span",mu,b($.provider),1)):B("",!0),$.health?(k(),E("span",{key:1,class:$e(["dh-pill",C($.health.status)])},[T[4]||(T[4]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Te(b($.health.status),1)],2)):B("",!0)],8,pu),d("span",{class:$e(["dh-pill",$.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},b($.enabled?g(h)("plugins.enabled"):g(h)("plugins.disabled")),3),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:j=>y($)},b(g(h)("plugins.health")),9,bu),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:j=>u($)},b(i.value===$.name?g(h)("plugins.close"):g(h)("plugins.configure")),9,vu)]),i.value===$.name?(k(),E("div",_u,[$.baseURL?(k(),E("div",yu,b($.baseURL),1)):B("",!0),($.configFields||[]).length?(k(),E("div",wu,[(k(!0),E(ee,null,ke($.configFields,j=>(k(),E("div",{key:j.key},[d("label",xu,[Te(b(j.label||j.key),1),j.required?(k(),E("span",ku," *")):B("",!0)]),j.type==="select"?re((k(),E("select",{key:0,"onUpdate:modelValue":M=>o[$.name][j.key]=M,class:"dh-select"},[j.required?B("",!0):(k(),E("option",Tu,b(g(h)("plugins.notSet")),1)),(k(!0),E(ee,null,ke(j.options||[],M=>(k(),E("option",{key:M.value,value:M.value},b(M.label||M.value),9,Eu))),128))],8,Su)),[[xs,o[$.name][j.key]]]):re((k(),E("input",{key:1,"onUpdate:modelValue":M=>o[$.name][j.key]=M,class:"dh-input",type:j.type==="password"?"password":j.type==="number"?"number":"text",placeholder:j.default||"",autocomplete:"off"},null,8,Cu)),[[Gl,o[$.name][j.key]]]),j.help?(k(),E("p",Pu,b(j.help),1)):B("",!0)]))),128))])):(k(),E("p",$u,b(g(h)("plugins.noConfig")),1)),($.capabilities||[]).length?(k(),E("div",Au,[d("div",Ou,b(g(h)("plugins.capabilities")),1),d("ul",Ru,[(k(!0),E(ee,null,ke($.capabilities,j=>(k(),E("li",{key:j.id},[d("span",Iu,b(j.id),1),j.method||j.endpoint?(k(),E("span",Uu," — "+b(j.method)+" "+b(j.endpoint),1)):B("",!0),j.description?(k(),E("span",ju," · "+b(j.description),1)):B("",!0)]))),128))])])):B("",!0),r[$.name]?(k(),E("p",Mu,b(r[$.name]),1)):B("",!0),d("div",Nu,[d("button",{class:"dh-btn",disabled:n.value,onClick:j=>m($,!0)},b($.enabled?g(h)("plugins.save"):g(h)("plugins.saveEnable")),9,Du),$.enabled?(k(),E("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:j=>m($,!1)},b(g(h)("plugins.disable")),9,zu)):B("",!0),T[5]||(T[5]=d("span",{class:"flex-1"},null,-1)),$.kind==="external"?(k(),E("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:j=>A($)},b(g(h)("plugins.remove")),9,Lu)):B("",!0)]),$.kind!=="external"?(k(),E("p",Fu,b(g(h)("plugins.builtinNote")),1)):B("",!0)])):B("",!0)]))),128))]))}},Hu={class:"dh-card overflow-hidden"},Vu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Ku={class:"text-base font-bold tracking-[-0.02em] text-strong"},Wu={class:"mt-0.5 text-xs text-muted"},Gu={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},qu={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Zu={class:"grid gap-3 sm:grid-cols-2"},Ju={class:"dh-label"},Yu={class:"dh-label"},Xu={class:"dh-label"},Qu=["placeholder"],ed={class:"dh-label"},td=["value"],sd={key:0},nd={class:"dh-label"},id={value:""},od=["value"],rd={class:"mt-3 flex items-center gap-2"},ld=["disabled"],ad=["disabled"],cd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ud={key:3,class:"w-full text-left text-sm"},dd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},fd={class:"data px-5 py-2.5 text-xs text-strong"},pd={key:0,class:"eyebrow ml-1"},hd={class:"px-5 py-2.5 text-body"},gd={class:"px-5 py-2.5 text-body"},md={class:"px-5 py-2.5"},bd={class:"px-5 py-2.5 text-right whitespace-nowrap"},vd=["onClick"],_d=["disabled","onClick"],yd={__name:"UsersCard",setup(e){const t=V([]),s=V([]),n=V(""),i=V(!1),o=V(null),r=V({}),l=Qe(()=>bt.value?["user","admin","superadmin"]:["user","admin"]);async function a(){try{const[C,P]=await Promise.all([se("/api/users"),se("/api/orgs")]);t.value=C.users||[],s.value=P.organizations||[],n.value=""}catch(C){n.value=C.message}}ut(a);function p(){var C;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:bt.value?"":((C=de.value)==null?void 0:C.organization)||""}}function u(C){o.value=C.id,r.value={email:C.email,name:C.name||"",password:"",role:C.role,organization:C.organization||""}}function m(){o.value=null,n.value=""}async function y(){i.value=!0,n.value="";try{if(o.value==="new")await se("/api/users",{method:"POST",body:r.value});else{const C={...r.value};C.password||delete C.password,await se(`/api/users/${o.value}`,{method:"PATCH",body:C})}o.value=null,await a()}catch(C){n.value=C.message}finally{i.value=!1}}async function A(C){if(confirm(h("users.confirmDelete",{email:C.email}))){i.value=!0,n.value="";try{await se(`/api/users/${C.id}`,{method:"DELETE"}),await a()}catch(P){n.value=P.message}finally{i.value=!1}}}const D=C=>C==="superadmin"?"bg-info-soft text-info":C==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(C,P)=>(k(),E("div",Hu,[d("div",Vu,[d("div",null,[d("div",Ku,b(g(h)("users.title")),1),d("p",Wu,b(g(bt)?g(h)("users.allOrgs"):g(h)("users.yourOrg")),1)]),d("button",{class:"dh-btn",onClick:p},b(g(h)("users.newUser")),1)]),n.value?(k(),E("p",Gu,b(n.value),1)):B("",!0),o.value?(k(),E("div",qu,[d("div",Zu,[d("div",null,[d("label",Ju,b(g(h)("common.email")),1),re(d("input",{"onUpdate:modelValue":P[0]||(P[0]=T=>r.value.email=T),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[pe,r.value.email]])]),d("div",null,[d("label",Yu,b(g(h)("common.name")),1),re(d("input",{"onUpdate:modelValue":P[1]||(P[1]=T=>r.value.name=T),class:"dh-input",autocomplete:"off"},null,512),[[pe,r.value.name]])]),d("div",null,[d("label",Xu,b(o.value==="new"?g(h)("users.password"):g(h)("users.passwordUnchanged")),1),re(d("input",{"onUpdate:modelValue":P[2]||(P[2]=T=>r.value.password=T),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:g(h)("users.passwordPlaceholder")},null,8,Qu),[[pe,r.value.password]])]),d("div",null,[d("label",ed,b(g(h)("common.role")),1),re(d("select",{"onUpdate:modelValue":P[3]||(P[3]=T=>r.value.role=T),class:"dh-select"},[(k(!0),E(ee,null,ke(l.value,T=>(k(),E("option",{key:T,value:T},b(T),9,td))),128))],512),[[xs,r.value.role]])]),g(bt)?(k(),E("div",sd,[d("label",nd,b(g(h)("common.organization")),1),re(d("select",{"onUpdate:modelValue":P[4]||(P[4]=T=>r.value.organization=T),class:"dh-select"},[d("option",id,b(g(h)("users.orgNone")),1),(k(!0),E(ee,null,ke(s.value,T=>(k(),E("option",{key:T.id,value:T.id},b(T.name),9,od))),128))],512),[[xs,r.value.organization]])])):B("",!0)]),d("div",rd,[d("button",{class:"dh-btn",disabled:i.value,onClick:y},b(o.value==="new"?g(h)("common.create"):g(h)("common.save")),9,ld),d("button",{class:"dh-btn-ghost",disabled:i.value,onClick:m},b(g(h)("common.cancel")),9,ad)])])):B("",!0),t.value.length?(k(),E("table",ud,[d("thead",null,[d("tr",dd,[d("th",null,b(g(h)("common.email")),1),d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("common.organization")),1),d("th",null,b(g(h)("common.role")),1),P[5]||(P[5]=d("th",null,null,-1))])]),d("tbody",null,[(k(!0),E(ee,null,ke(t.value,T=>{var $,j;return k(),E("tr",{key:T.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",fd,[Te(b(T.email)+" ",1),T.id===(($=g(de))==null?void 0:$.id)?(k(),E("span",pd,b(g(h)("users.you")),1)):B("",!0)]),d("td",hd,b(T.name||g(h)("common.empty")),1),d("td",gd,b(T.organizationName||g(h)("common.empty")),1),d("td",md,[d("span",{class:$e(["dh-pill",D(T.role)])},b(T.role),3)]),d("td",bd,[d("button",{class:"dh-btn-ghost",onClick:M=>u(T)},b(g(h)("common.edit")),9,vd),T.id!==((j=g(de))==null?void 0:j.id)?(k(),E("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:M=>A(T)},b(g(h)("common.delete")),9,_d)):B("",!0)])])}),128))])])):(k(),E("p",cd,b(g(h)("users.empty")),1))]))}},wd={class:"dh-card overflow-hidden"},xd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},kd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Sd={class:"mt-0.5 text-xs text-muted"},Td={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Ed={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Cd={class:"dh-label"},Pd=["placeholder"],$d={class:"mt-3 flex items-center gap-2"},Ad=["disabled"],Od=["disabled"],Rd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Id={key:3,class:"w-full text-left text-sm"},Ud={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},jd={class:"px-5 py-2.5 font-medium text-strong"},Md={class:"data px-5 py-2.5 text-xs text-muted"},Nd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Dd=["onClick"],zd=["disabled","onClick"],Ld={__name:"OrgsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=V("");async function r(){try{const y=await se("/api/orgs");t.value=y.organizations||[],s.value=""}catch(y){s.value=y.message}}ut(r);function l(){i.value="new",o.value=""}function a(y){i.value=y.id,o.value=y.name}function p(){i.value=null,s.value=""}async function u(){n.value=!0,s.value="";try{i.value==="new"?await se("/api/orgs",{method:"POST",body:{name:o.value}}):await se(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await r()}catch(y){s.value=y.message}finally{n.value=!1}}async function m(y){if(confirm(h("orgs.confirmDelete",{name:y.name}))){n.value=!0,s.value="";try{await se(`/api/orgs/${y.id}`,{method:"DELETE"}),await r()}catch(A){s.value=A.message}finally{n.value=!1}}}return(y,A)=>(k(),E("div",wd,[d("div",xd,[d("div",null,[d("div",kd,b(g(h)("orgs.title")),1),d("p",Sd,b(g(h)("orgs.subtitle")),1)]),g(bt)?(k(),E("button",{key:0,class:"dh-btn",onClick:l},b(g(h)("orgs.newOrg")),1)):B("",!0)]),s.value?(k(),E("p",Td,b(s.value),1)):B("",!0),i.value?(k(),E("div",Ed,[d("label",Cd,b(g(h)("common.name")),1),re(d("input",{"onUpdate:modelValue":A[0]||(A[0]=D=>o.value=D),class:"dh-input",placeholder:g(h)("orgs.namePlaceholder"),onKeyup:Ql(u,["enter"])},null,40,Pd),[[pe,o.value]]),d("div",$d,[d("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:u},b(i.value==="new"?g(h)("common.create"):g(h)("common.save")),9,Ad),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:p},b(g(h)("common.cancel")),9,Od)])])):B("",!0),t.value.length?(k(),E("table",Id,[d("thead",null,[d("tr",Ud,[d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("orgs.colId")),1),A[1]||(A[1]=d("th",null,null,-1))])]),d("tbody",null,[(k(!0),E(ee,null,ke(t.value,D=>(k(),E("tr",{key:D.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",jd,b(D.name),1),d("td",Md,b(D.id),1),d("td",Nd,[g(bt)?(k(),E(ee,{key:0},[d("button",{class:"dh-btn-ghost",onClick:C=>a(D)},b(g(h)("common.rename")),9,Dd),d("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:C=>m(D)},b(g(h)("common.delete")),9,zd)],64)):B("",!0)])]))),128))])])):(k(),E("p",Rd,b(g(h)("orgs.empty")),1))]))}},Fd={class:"dh-card overflow-hidden"},Bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Hd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Vd={class:"eyebrow"},Kd={class:"w-full text-left text-sm"},Wd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Gd={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},qd={class:"text-strong"},Zd={class:"border-t border-subtle px-5 py-2.5 text-body"},nt={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array},setup(e){const t={GET:"text-success",POST:"text-brandtext",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(k(),E("div",Fd,[d("div",Bd,[d("div",Hd,b(e.title),1),d("span",Vd,b(e.auth),1)]),d("table",Kd,[d("thead",null,[d("tr",Wd,[d("th",null,b(g(h)("api.colEndpoint")),1),d("th",null,b(g(h)("api.colDescription")),1)])]),d("tbody",null,[(k(!0),E(ee,null,ke(e.endpoints,i=>(k(),E("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[d("td",Gd,[d("span",{class:$e(["font-semibold",t[i.method]])},b(i.method),3),d("span",qd,b(i.path),1)]),d("td",Zd,b(i.desc),1)]))),128))])])]))}},Jd={class:"mx-auto flex max-w-4xl flex-col gap-6 px-6 pt-12 pb-16"},Yd={class:"flex items-center gap-3"},Xd={class:"inline-flex items-center gap-2.5 select-none"},Qd={class:"h-8 w-8 shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},ef={transform:"translate(7 0) skewX(-13)"},tf=["fill"],sf=["fill"],nf=["fill"],of={class:"eyebrow mt-1.5"},rf={key:0,class:"data hidden text-xs text-muted sm:inline"},lf={key:0},af={key:1,class:"dh-pill bg-info-soft text-info"},cf=["value","aria-label"],uf=["value"],df=["title"],ff={key:0,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},pf={key:1,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},hf={key:0,class:"eyebrow py-16 text-center"},gf={class:"flex flex-wrap gap-1.5"},mf=["onClick"],bf={key:7,class:"eyebrow text-center"},vf={class:"eyebrow text-center"},_f={__name:"App",setup(e){const t=V(!0),s=V("overview");ut(async()=>{await Ya(),t.value=!1});const n=Qe(()=>{const C=[{id:"overview",label:h("sections.overview")}];return hi.value&&C.push({id:"users",label:h("sections.users")},{id:"orgs",label:h("sections.orgs")}),bt.value&&C.push({id:"pocketbase",label:h("sections.pocketbase")},{id:"webapp",label:h("sections.webapp")},{id:"plugins",label:h("sections.plugins")}),C.push({id:"api",label:h("sections.api")}),C}),i=Qe(()=>Ba.map(C=>{let P=C;try{P=new Intl.DisplayNames([C],{type:"language"}).of(C)||C}catch{}return{code:C,label:P.charAt(0).toUpperCase()+P.slice(1)}}));function o(){Tn(),s.value="overview"}const r=Qe(()=>Et.value==="dark"?["#60a5fa","#93c5fd","#ffffff"]:["var(--brand-700)","var(--brand-500)","var(--brand-400)"]),l=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/api/status",desc:"Health of PocketBase + Web App"},{method:"POST",path:"/api/auth/login",desc:"Exchange email + password for a PocketBase token"},{method:"GET",path:"/api/auth/validate",desc:"Check whether a token is still valid"}],a=[{method:"GET",path:"/api/auth/me",desc:"Identity of the bearer token"},{method:"GET",path:"/api/identity",desc:"Identity incl. role + organization"}],p=[{method:"GET",path:"/api/cars",desc:"List owned + shared cars"},{method:"POST",path:"/api/cars",desc:"Create a car"},{method:"GET",path:"/api/cars/{id}",desc:"Fetch one car"},{method:"PATCH",path:"/api/cars/{id}",desc:"Update a car"},{method:"DELETE",path:"/api/cars/{id}",desc:"Delete a car (owner only)"},{method:"GET",path:"/api/cars/{id}/service-records",desc:"A car's service history"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/shares",desc:"Who a car is shared with (owner)"},{method:"POST",path:"/api/cars/{id}/shares",desc:"Share a car by email (owner)"},{method:"DELETE",path:"/api/cars/{id}/shares/{userId}",desc:"Revoke a share (owner)"}],u=[{method:"GET",path:"/api/service-records",desc:"List service records"},{method:"POST",path:"/api/service-records",desc:"Log a service record"},{method:"GET",path:"/api/service-records/{id}",desc:"Fetch one record"},{method:"PATCH",path:"/api/service-records/{id}",desc:"Update a record"},{method:"DELETE",path:"/api/service-records/{id}",desc:"Delete a record"}],m=[{method:"GET",path:"/api/parts",desc:"List parts"},{method:"POST",path:"/api/parts",desc:"Add a part"},{method:"GET",path:"/api/parts/{id}",desc:"Fetch one part"},{method:"PATCH",path:"/api/parts/{id}",desc:"Update a part"},{method:"DELETE",path:"/api/parts/{id}",desc:"Delete a part"}],y=[{method:"GET",path:"/api/me",desc:"Current user profile"},{method:"PATCH",path:"/api/me",desc:"Update profile"},{method:"POST",path:"/api/me/password",desc:"Change password"},{method:"POST",path:"/api/me/avatar",desc:"Upload avatar"},{method:"GET",path:"/api/me/avatar",desc:"Fetch avatar"},{method:"DELETE",path:"/api/me/avatar",desc:"Remove avatar"},{method:"POST",path:"/api/me/verify/request",desc:"Request email verification"},{method:"GET",path:"/api/me/export",desc:"Export your data"},{method:"POST",path:"/api/me/import",desc:"Import data"},{method:"POST",path:"/api/me/delete",desc:"Request account deletion"},{method:"POST",path:"/api/me/delete/cancel",desc:"Cancel deletion request"},{method:"DELETE",path:"/api/me",desc:"Finalize account deletion"}],A=[{method:"GET",path:"/api/users",desc:"List users (scoped by role)"},{method:"POST",path:"/api/users",desc:"Create a user"},{method:"PATCH",path:"/api/users/{id}",desc:"Update email / name / role / org / password"},{method:"DELETE",path:"/api/users/{id}",desc:"Delete a user"},{method:"GET",path:"/api/orgs",desc:"List organizations"},{method:"POST",path:"/api/orgs",desc:"Create an organization (superadmin)"},{method:"PATCH",path:"/api/orgs/{id}",desc:"Rename an organization (superadmin)"},{method:"DELETE",path:"/api/orgs/{id}",desc:"Delete an organization (superadmin)"}],D=[{method:"GET",path:"/api/admin/pb-config",desc:"PocketBase connection + live probe"},{method:"POST",path:"/api/admin/pb-config/test",desc:"Probe a candidate connection"},{method:"PUT",path:"/api/admin/pb-config",desc:"Apply + persist a connection"},{method:"GET",path:"/api/admin/webapp-config",desc:"Web App URL + CORS origins, with a live probe"},{method:"POST",path:"/api/admin/webapp-config/test",desc:"Probe a candidate Web App address"},{method:"PUT",path:"/api/admin/webapp-config",desc:"Apply + persist Web App settings"},{method:"GET",path:"/api/admin/plugins",desc:"List plugins (secrets masked)"},{method:"POST",path:"/api/admin/plugins",desc:"Register an external plugin"},{method:"GET",path:"/api/admin/plugins/{name}",desc:"Fetch one plugin"},{method:"PUT",path:"/api/admin/plugins/{name}",desc:"Enable/disable + configure"},{method:"DELETE",path:"/api/admin/plugins/{name}",desc:"Remove an external plugin"},{method:"POST",path:"/api/admin/plugins/{name}/health",desc:"Run a health check now"}];return(C,P)=>(k(),E("div",Jd,[d("div",Yd,[d("span",Xd,[(k(),E("svg",Qd,[d("g",ef,[d("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:r.value[0]},null,8,tf),d("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:r.value[1]},null,8,sf),d("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:r.value[2]},null,8,nf)])])),P[2]||(P[2]=d("span",{class:"text-2xl leading-none font-extrabold tracking-[-0.03em] italic"},[d("span",{class:"text-strong"},"Driver"),d("span",{class:"text-brandtext"},"Vault")],-1))]),d("span",of,b(g(h)("app.apiServer")),1),P[5]||(P[5]=d("div",{class:"flex-1"},null,-1)),g(de)?(k(),E("span",rf,[Te(b(g(de).email),1),g(de).organizationName?(k(),E("span",lf," · "+b(g(de).organizationName),1)):B("",!0)])):B("",!0),g(de)?(k(),E("span",af,b(g(de).role),1)):B("",!0),d("select",{class:"dh-select !w-auto !py-1 !text-xs",value:g(Sn),"aria-label":g(h)("sections.overview"),onChange:P[0]||(P[0]=T=>g(Va)(T.target.value))},[(k(!0),E(ee,null,ke(i.value,T=>(k(),E("option",{key:T.code,value:T.code},b(T.label),9,uf))),128))],40,cf),d("button",{class:"dh-btn-ghost",title:g(Et)==="dark"?g(h)("app.switchToLight"):g(h)("app.switchToDark"),onClick:P[1]||(P[1]=(...T)=>g(di)&&g(di)(...T))},[g(Et)==="dark"?(k(),E("svg",ff,[...P[3]||(P[3]=[d("circle",{cx:"12",cy:"12",r:"4"},null,-1),d("path",{"stroke-linecap":"round",d:"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"},null,-1)])])):(k(),E("svg",pf,[...P[4]||(P[4]=[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"},null,-1)])])),Te(" "+b(g(h)("app.theme")),1)],8,df),g(Ot)?(k(),E("button",{key:2,class:"dh-btn-ghost",onClick:o},b(g(h)("app.signOut")),1)):B("",!0)]),t.value?(k(),E("p",hf,b(g(h)("app.loading")),1)):g(Ot)?(k(),E(ee,{key:2},[d("nav",gf,[(k(!0),E(ee,null,ke(n.value,T=>(k(),E("button",{key:T.id,class:$e(["dh-btn-ghost",s.value===T.id?"border-accent text-brandtext":""]),onClick:$=>s.value=T.id},b(T.label),11,mf))),128))]),s.value==="overview"?(k(),it(_c,{key:0})):s.value==="users"?(k(),it(yd,{key:1})):s.value==="orgs"?(k(),it(Ld,{key:2})):s.value==="pocketbase"?(k(),it(Nc,{key:3})):s.value==="webapp"?(k(),it(Qc,{key:4})):s.value==="plugins"?(k(),it(Bu,{key:5})):s.value==="api"?(k(),E(ee,{key:6},[ce(nt,{title:g(h)("api.groupPublic"),auth:g(h)("api.authNone"),endpoints:l},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupIdentity"),auth:g(h)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupCars"),auth:g(h)("api.authBearer"),endpoints:p},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupService"),auth:g(h)("api.authBearer"),endpoints:u},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupParts"),auth:g(h)("api.authBearer"),endpoints:m},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupAccount"),auth:g(h)("api.authBearer"),endpoints:y},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupManagement"),auth:g(h)("api.authManager"),endpoints:A},null,8,["title","auth"]),ce(nt,{title:g(h)("api.groupSuperadmin"),auth:g(h)("api.authSuperadmin"),endpoints:D},null,8,["title","auth"])],64)):B("",!0),!g(hi)&&s.value==="overview"?(k(),E("p",bf,b(g(h)("app.standardUserNote")),1)):B("",!0)],64)):(k(),it(lc,{key:1})),d("p",vf,b(g(h)("app.footer")),1)]))}};sa(_f).mount("#app"); diff --git a/API Server/internal/api/dist/assets/index-OHZkxAdj.js b/API Server/internal/api/dist/assets/index-OHZkxAdj.js new file mode 100644 index 0000000..fee5676 --- /dev/null +++ b/API Server/internal/api/dist/assets/index-OHZkxAdj.js @@ -0,0 +1,17 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/** +* @vue/shared v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function cn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const J={},xt=[],Ke=()=>{},mi=()=>!1,Ts=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),he=Object.assign,un=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,G=(e,t)=>$o.call(e,t),M=Array.isArray,kt=e=>es(e)==="[object Map]",Rt=e=>es(e)==="[object Set]",jn=e=>es(e)==="[object Date]",H=e=>typeof e=="function",ne=e=>typeof e=="string",We=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",bi=e=>(Z(e)||H(e))&&H(e.then)&&H(e.catch),vi=Object.prototype.toString,es=e=>vi.call(e),Ao=e=>es(e).slice(8,-1),_i=e=>es(e)==="[object Object]",dn=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ft=cn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Cs=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Oo=/-\w/g,Pe=Cs(e=>e.replace(Oo,t=>t.slice(1).toUpperCase())),Ro=/\B([A-Z])/g,ut=Cs(e=>e.replace(Ro,"-$1").toLowerCase()),yi=Cs(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ds=Cs(e=>e?`on${yi(e)}`:""),Ve=(e,t)=>!Object.is(e,t),fs=(e,...t)=>{for(let s=0;s{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Ps=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let zn;const $s=()=>zn||(zn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function fn(e){if(M(e)){const t={};for(let s=0;s{if(s){const n=s.split(jo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Oe(e){let t="";if(ne(e))t=e;else if(M(e))for(let s=0;slt(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),b=e=>ne(e)?e:e==null?"":M(e)||Z(e)&&(e.toString===vi||!H(e.toString))?ki(e)?b(e.value):JSON.stringify(e,Si,2):String(e),Si=(e,t)=>ki(t)?Si(e,t.value):kt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ms(n,o)+" =>"]=i,s),{})}:Rt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ms(s))}:We(t)?Ms(t):Z(t)&&!M(t)&&!_i(t)?String(t):t,Ms=(e,t="")=>{var s;return We(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 ce;class Lo{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&&ce&&(ce.active?(this.parent=ce,this.index=(ce.scopes||(ce.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;t0&&--this._on===0){if(ce===this)ce=this.prevScope;else{let t=ce;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;s0)return;if(Ht){let t=Ht;for(Ht=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Bt;){let t=Bt;for(Bt=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 Pi(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function $i(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),mn(n),Bo(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Ys(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Ai(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ai(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===qt)||(e.globalVersion=qt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Ys(e))))return;e.flags|=2;const t=e.dep,s=Q,n=$e;Q=e,$e=!0;try{Pi(e);const i=e.fn(e._value);(t.version===0||Ve(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,$e=n,$i(e),e.flags&=-3}}function mn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.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)mn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Bo(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let $e=!0;const Oi=[];function Ge(){Oi.push($e),$e=!1}function qe(){const e=Oi.pop();$e=e===void 0?!0:e}function Un(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let qt=0;class Ho{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 bn{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(!Q||!$e||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new Ho(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,Ri(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=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,qt++,this.notify(t)}notify(t){hn();try{for(let s=this.subs;s;s=s.prevSub)s.sub.notify()&&s.sub.dep.notify()}finally{gn()}}}function Ri(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let n=t.deps;n;n=n.nextDep)Ri(n)}const s=e.dep.subs;s!==e&&(e.prevSub=s,s&&(s.nextSub=e)),e.dep.subs=e}}const Js=new WeakMap,vt=Symbol(""),Xs=Symbol(""),Zt=Symbol("");function de(e,t,s){if($e&&Q){let n=Js.get(e);n||Js.set(e,n=new Map);let i=n.get(s);i||(n.set(s,i=new bn),i.map=n,i.key=s),i.track()}}function Xe(e,t,s,n,i,o){const r=Js.get(e);if(!r){qt++;return}const l=a=>{a&&a.trigger()};if(hn(),t==="clear")r.forEach(l);else{const a=M(e),p=a&&dn(s);if(a&&s==="length"){const u=Number(n);r.forEach((m,P)=>{(P==="length"||P===Zt||!We(P)&&P>=u)&&l(m)})}else switch((s!==void 0||r.has(void 0))&&l(r.get(s)),p&&l(r.get(Zt)),t){case"add":a?p&&l(r.get("length")):(l(r.get(vt)),kt(e)&&l(r.get(Xs)));break;case"delete":a||(l(r.get(vt)),kt(e)&&l(r.get(Xs)));break;case"set":kt(e)&&l(r.get(vt));break}}gn()}function yt(e){const t=W(e);return t===e?t:(de(t,"iterate",Zt),Te(e)?t:t.map(Re))}function As(e){return de(e=W(e),"iterate",Zt),e}function Be(e,t){return tt(e)?Ct(_t(e)?Re(t):t):Re(t)}const Vo={__proto__:null,[Symbol.iterator](){return Fs(this,Symbol.iterator,e=>Be(this,e))},concat(...e){return yt(this).concat(...e.map(t=>M(t)?yt(t):t))},entries(){return Fs(this,"entries",e=>(e[1]=Be(this,e[1]),e))},every(e,t){return Ze(this,"every",e,t,void 0,arguments)},filter(e,t){return Ze(this,"filter",e,t,s=>s.map(n=>Be(this,n)),arguments)},find(e,t){return Ze(this,"find",e,t,s=>Be(this,s),arguments)},findIndex(e,t){return Ze(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Ze(this,"findLast",e,t,s=>Be(this,s),arguments)},findLastIndex(e,t){return Ze(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Ze(this,"forEach",e,t,void 0,arguments)},includes(...e){return Bs(this,"includes",e)},indexOf(...e){return Bs(this,"indexOf",e)},join(e){return yt(this).join(e)},lastIndexOf(...e){return Bs(this,"lastIndexOf",e)},map(e,t){return Ze(this,"map",e,t,void 0,arguments)},pop(){return Nt(this,"pop")},push(...e){return Nt(this,"push",e)},reduce(e,...t){return Nn(this,"reduce",e,t)},reduceRight(e,...t){return Nn(this,"reduceRight",e,t)},shift(){return Nt(this,"shift")},some(e,t){return Ze(this,"some",e,t,void 0,arguments)},splice(...e){return Nt(this,"splice",e)},toReversed(){return yt(this).toReversed()},toSorted(e){return yt(this).toSorted(e)},toSpliced(...e){return yt(this).toSpliced(...e)},unshift(...e){return Nt(this,"unshift",e)},values(){return Fs(this,"values",e=>Be(this,e))}};function Fs(e,t,s){const n=As(e),i=n[t]();return n!==e&&!Te(e)&&(i._next=i.next,i.next=()=>{const o=i._next();return o.done||(o.value=s(o.value)),o}),i}const Ko=Array.prototype;function Ze(e,t,s,n,i,o){const r=As(e),l=r!==e&&!Te(e),a=r[t];if(a!==Ko[t]){const m=a.apply(e,o);return l?Re(m):m}let p=s;r!==e&&(l?p=function(m,P){return s.call(this,Be(e,m),P,e)}:s.length>2&&(p=function(m,P){return s.call(this,m,P,e)}));const u=a.call(r,p,n);return l&&i?i(u):u}function Nn(e,t,s,n){const i=As(e),o=i!==e&&!Te(e);let r=s,l=!1;i!==e&&(o?(l=n.length===0,r=function(p,u,m){return l&&(l=!1,p=Be(e,p)),s.call(this,p,Be(e,u),m,e)}):s.length>3&&(r=function(p,u,m){return s.call(this,p,u,m,e)}));const a=i[t](r,...n);return l?Be(e,a):a}function Bs(e,t,s){const n=W(e);de(n,"iterate",Zt);const i=n[t](...s);return(i===-1||i===!1)&&yn(s[0])?(s[0]=W(s[0]),n[t](...s)):i}function Nt(e,t,s=[]){Ge(),hn();const n=W(e)[t].apply(e,s);return gn(),qe(),n}const Wo=cn("__proto__,__v_isRef,__isVue"),Ii=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(We));function Go(e){We(e)||(e=String(e));const t=W(this);return de(t,"has",e),t.hasOwnProperty(e)}class ji{constructor(t=!1,s=!1){this._isReadonly=t,this._isShallow=s}get(t,s,n){if(s==="__v_skip")return t.__v_skip;const i=this._isReadonly,o=this._isShallow;if(s==="__v_isReactive")return!i;if(s==="__v_isReadonly")return i;if(s==="__v_isShallow")return o;if(s==="__v_raw")return n===(i?o?nr:Di:o?Ni:Ui).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const r=M(t);if(!i){let a;if(r&&(a=Vo[s]))return a;if(s==="hasOwnProperty")return Go}const l=Reflect.get(t,s,fe(t)?t:n);if((We(s)?Ii.has(s):Wo(s))||(i||de(t,"get",s),o))return l;if(fe(l)){const a=r&&dn(s)?l:l.value;return i&&Z(a)?en(a):a}return Z(l)?i?en(l):Yt(l):l}}class zi extends ji{constructor(t=!1){super(!1,t)}set(t,s,n,i){let o=t[s];const r=M(t)&&dn(s);if(!this._isShallow){const p=tt(o);if(!Te(n)&&!tt(n)&&(o=W(o),n=W(n)),!r&&fe(o)&&!fe(n))return p||(o.value=n),!0}const l=r?Number(s)e,as=e=>Reflect.getPrototypeOf(e);function Xo(e,t,s){return function(...n){const i=this.__v_raw,o=W(i),r=kt(o),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,p=i[e](...n),u=s?Qs:t?Ct:Re;return!t&&de(o,"iterate",a?Xs:vt),he(Object.create(p),{next(){const{value:m,done:P}=p.next();return P?{value:m,done:P}:{value:l?[u(m[0]),u(m[1])]:u(m),done:P}}})}}function cs(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Qo(e,t){const s={get(i){const o=this.__v_raw,r=W(o),l=W(i);e||(Ve(i,l)&&de(r,"get",i),de(r,"get",l));const{has:a}=as(r),p=t?Qs:e?Ct:Re;if(a.call(r,i))return p(o.get(i));if(a.call(r,l))return p(o.get(l));o!==r&&o.get(i)},get size(){const i=this.__v_raw;return!e&&de(W(i),"iterate",vt),i.size},has(i){const o=this.__v_raw,r=W(o),l=W(i);return e||(Ve(i,l)&&de(r,"has",i),de(r,"has",l)),i===l?o.has(i):o.has(i)||o.has(l)},forEach(i,o){const r=this,l=r.__v_raw,a=W(l),p=t?Qs:e?Ct:Re;return!e&&de(a,"iterate",vt),l.forEach((u,m)=>i.call(o,p(u),p(m),r))}};return he(s,e?{add:cs("add"),set:cs("set"),delete:cs("delete"),clear:cs("clear")}:{add(i){const o=W(this),r=as(o),l=W(i),a=!t&&!Te(i)&&!tt(i)?l:i;return r.has.call(o,a)||Ve(i,a)&&r.has.call(o,i)||Ve(l,a)&&r.has.call(o,l)||(o.add(a),Xe(o,"add",a,a)),this},set(i,o){!t&&!Te(o)&&!tt(o)&&(o=W(o));const r=W(this),{has:l,get:a}=as(r);let p=l.call(r,i);p||(i=W(i),p=l.call(r,i));const u=a.call(r,i);return r.set(i,o),p?Ve(o,u)&&Xe(r,"set",i,o):Xe(r,"add",i,o),this},delete(i){const o=W(this),{has:r,get:l}=as(o);let a=r.call(o,i);a||(i=W(i),a=r.call(o,i)),l&&l.call(o,i);const p=o.delete(i);return a&&Xe(o,"delete",i,void 0),p},clear(){const i=W(this),o=i.size!==0,r=i.clear();return o&&Xe(i,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(i=>{s[i]=Xo(i,e,t)}),s}function vn(e,t){const s=Qo(e,t);return(n,i,o)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(G(s,i)&&i in n?s:n,i,o)}const er={get:vn(!1,!1)},tr={get:vn(!1,!0)},sr={get:vn(!0,!1)};const Ui=new WeakMap,Ni=new WeakMap,Di=new WeakMap,nr=new WeakMap;function ir(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Yt(e){return tt(e)?e:_n(e,!1,Zo,er,Ui)}function or(e){return _n(e,!1,Jo,tr,Ni)}function en(e){return _n(e,!0,Yo,sr,Di)}function _n(e,t,s,n,i){if(!Z(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const o=i.get(e);if(o)return o;const r=ir(Ao(e));if(r===0)return e;const l=new Proxy(e,r===2?n:s);return i.set(e,l),l}function _t(e){return tt(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function tt(e){return!!(e&&e.__v_isReadonly)}function Te(e){return!!(e&&e.__v_isShallow)}function yn(e){return e?!!e.__v_raw:!1}function W(e){const t=e&&e.__v_raw;return t?W(t):e}function rr(e){return!G(e,"__v_skip")&&Object.isExtensible(e)&&wi(e,"__v_skip",!0),e}const Re=e=>Z(e)?Yt(e):e,Ct=e=>Z(e)?en(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function V(e){return lr(e,!1)}function lr(e,t){return fe(e)?e:new ar(e,t)}class ar{constructor(t,s){this.dep=new bn,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=s?t:W(t),this._value=s?t:Re(t),this.__v_isShallow=s}get value(){return this.dep.track(),this._value}set value(t){const s=this._rawValue,n=this.__v_isShallow||Te(t)||tt(t);t=n?t:W(t),Ve(t,s)&&(this._rawValue=t,this._value=n?t:Re(t),this.dep.trigger())}}function g(e){return fe(e)?e.value:e}const cr={get:(e,t,s)=>t==="__v_raw"?e:g(Reflect.get(e,t,s)),set:(e,t,s,n)=>{const i=e[t];return fe(i)&&!fe(s)?(i.value=s,!0):Reflect.set(e,t,s,n)}};function Mi(e){return _t(e)?e:new Proxy(e,cr)}class ur{constructor(t,s,n){this.fn=t,this.setter=s,this._value=void 0,this.dep=new bn(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=qt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!s,this.isSSR=n}notify(){if(this.flags|=16,!(this.flags&8)&&Q!==this)return Ci(this,!0),!0}get value(){const t=this.dep.track();return Ai(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function dr(e,t,s=!1){let n,i;return H(e)?n=e:(n=e.get,i=e.set),new ur(n,i,s)}const us={},ms=new WeakMap;let bt;function fr(e,t=!1,s=bt){if(s){let n=ms.get(s);n||ms.set(s,n=[]),n.push(e)}}function pr(e,t,s=J){const{immediate:n,deep:i,once:o,scheduler:r,augmentJob:l,call:a}=s,p=U=>i?U:Te(U)||i===!1||i===0?Qe(U,1):Qe(U);let u,m,P,O,F=!1,_=!1;if(fe(e)?(m=()=>e.value,F=Te(e)):_t(e)?(m=()=>p(e),F=!0):M(e)?(_=!0,F=e.some(U=>_t(U)||Te(U)),m=()=>e.map(U=>{if(fe(U))return U.value;if(_t(U))return p(U);if(H(U))return a?a(U,2):U()})):H(e)?t?m=a?()=>a(e,2):e:m=()=>{if(P){Ge();try{P()}finally{qe()}}const U=bt;bt=u;try{return a?a(e,3,[O]):e(O)}finally{bt=U}}:m=Ke,t&&i){const U=m,oe=i===!0?1/0:i;m=()=>Qe(U(),oe)}const E=Fo(),y=()=>{u.stop(),E&&E.active&&un(E.effects,u)};if(o&&t){const U=t;t=(...oe)=>{const je=U(...oe);return y(),je}}let $=_?new Array(e.length).fill(us):us;const z=U=>{if(!(!(u.flags&1)||!u.dirty&&!U))if(t){const oe=u.run();if(U||i||F||(_?oe.some((je,ze)=>Ve(je,$[ze])):Ve(oe,$))){P&&P();const je=bt;bt=u;try{const ze=[oe,$===us?void 0:_&&$[0]===us?[]:$,O];$=oe,a?a(t,3,ze):t(...ze)}finally{bt=je}}}else u.run()};return l&&l(z),u=new Ti(m),u.scheduler=r?()=>r(z,!1):z,O=U=>fr(U,!1,u),P=u.onStop=()=>{const U=ms.get(u);if(U){if(a)a(U,4);else for(const oe of U)oe();ms.delete(u)}},t?n?z(!0):$=u.run():r?r(z.bind(null,!0),!0):u.run(),y.pause=u.pause.bind(u),y.resume=u.resume.bind(u),y.stop=y,y}function Qe(e,t=1/0,s){if(t<=0||!Z(e)||e.__v_skip||(s=s||new Map,(s.get(e)||0)>=t))return e;if(s.set(e,t),t--,fe(e))Qe(e.value,t,s);else if(M(e))for(let n=0;n{Qe(n,t,s)});else if(_i(e)){for(const n in e)Qe(e[n],t,s);for(const n of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,n)&&Qe(e[n],t,s)}return e}/** +* @vue/runtime-core v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ts(e,t,s,n){try{return n?e(...n):e()}catch(i){Os(i,t,s)}}function Ie(e,t,s,n){if(H(e)){const i=ts(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Os(o,t,s)}),i}if(M(e)){const i=[];for(let o=0;o>>1,i=be[n],o=Jt(i);o=Jt(s)?be.push(e):be.splice(gr(t),0,e),e.flags|=1,Bi()}}function Bi(){bs||(bs=Li.then(Vi))}function mr(e){M(e)?St.push(...e):rt&&e.id===-1?rt.splice(wt+1,0,e):e.flags&1||(St.push(e),e.flags|=1),Bi()}function Dn(e,t,s=Fe+1){for(;sJt(s)-Jt(n));if(St.length=0,rt){rt.push(...t);return}for(rt=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(Fe=0;Fe{n._d&&Zn(-1);const o=vs(t);let r;try{r=e(...i)}finally{vs(o),n._d&&Zn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function le(e,t){if(ke===null)return e;const s=zs(ke),n=e.dirs||(e.dirs=[]);for(let i=0;i1)return s&&H(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),yr=()=>ps(_r);function Hs(e,t,s){return Wi(e,t,s)}function Wi(e,t,s=J){const{immediate:n,deep:i,flush:o,once:r}=s,l=he({},s),a=t&&n||!t&&o!=="post";let p;if(Qt){if(o==="sync"){const O=yr();p=O.__watcherHandles||(O.__watcherHandles=[])}else if(!a){const O=()=>{};return O.stop=Ke,O.resume=Ke,O.pause=Ke,O}}const u=ve;l.call=(O,F,_)=>Ie(O,u,F,_);let m=!1;o==="post"?l.scheduler=O=>{_e(O,u&&u.suspense)}:o!=="sync"&&(m=!0,l.scheduler=(O,F)=>{F?O():wn(O)}),l.augmentJob=O=>{t&&(O.flags|=4),m&&(O.flags|=2,u&&(O.id=u.uid,O.i=u))};const P=pr(e,t,l);return Qt&&(p?p.push(P):a&&P()),P}function wr(e,t,s){const n=this.proxy,i=ne(e)?e.includes(".")?Gi(n,e):()=>n[e]:e.bind(n,n);let o;H(t)?o=t:(o=t.handler,s=t);const r=ss(this),l=Wi(i,o.bind(n),s);return r(),l}function Gi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;ie.__isTeleport,Vs=Symbol("_leaveCb");function xn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,xn(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 qi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Mn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const _s=new WeakMap;function Vt(e,t,s,n,i=!1){if(M(e)){e.forEach((_,E)=>Vt(_,t&&(M(t)?t[E]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Vt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?zs(n.component):n.el,r=i?null:o,{i:l,r:a}=e,p=t&&t.r,u=l.refs===J?l.refs={}:l.refs,m=l.setupState,P=W(m),O=m===J?mi:_=>Mn(u,_)?!1:G(P,_),F=(_,E)=>!(E&&Mn(u,E));if(p!=null&&p!==a){if(Ln(t),ne(p))u[p]=null,O(p)&&(m[p]=null);else if(fe(p)){const _=t;F(p,_.k)&&(p.value=null),_.k&&(u[_.k]=null)}}if(H(a)){Ge();try{ts(a,l,12,[r,u])}finally{qe()}}else{const _=ne(a),E=fe(a);if(_||E){const y=()=>{if(e.f){const $=_?O(a)?m[a]:u[a]:F()||!e.k?a.value:u[e.k];if(i)M($)&&un($,o);else if(M($))$.includes(o)||$.push(o);else if(_)u[a]=[o],O(a)&&(m[a]=u[a]);else{const z=[o];F(a,e.k)&&(a.value=z),e.k&&(u[e.k]=z)}}else _?(u[a]=r,O(a)&&(m[a]=r)):E&&(F(a,e.k)&&(a.value=r),e.k&&(u[e.k]=r))};if(r){const $=()=>{y(),_s.delete(e)};$.id=-1,_s.set(e,$),_e($,s)}else Ln(e),y()}}}function Ln(e){const t=_s.get(e);t&&(t.flags|=8,_s.delete(e))}$s().requestIdleCallback;$s().cancelIdleCallback;const Kt=e=>!!e.type.__asyncLoader,Zi=e=>e.type.__isKeepAlive;function Sr(e,t){Yi(e,"a",t)}function Tr(e,t){Yi(e,"da",t)}function Yi(e,t,s=ve){const n=e.__wdc||(e.__wdc=()=>{let i=s;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(Rs(t,n,s),s){let i=s.parent;for(;i&&i.parent;)Zi(i.parent.vnode)&&Er(n,t,s,i),i=i.parent}}function Er(e,t,s,n){const i=Rs(t,e,n,!0);kn(()=>{un(n[t],i)},s)}function Rs(e,t,s=ve,n=!1){if(s){const i=s[e]||(s[e]=[]),o=t.__weh||(t.__weh=(...r)=>{Ge();const l=ss(s),a=Ie(t,s,e,r);return l(),qe(),a});return n?i.unshift(o):i.push(o),o}}const st=e=>(t,s=ve)=>{(!Qt||e==="sp")&&Rs(e,(...n)=>t(...n),s)},Cr=st("bm"),dt=st("m"),Pr=st("bu"),$r=st("u"),Ar=st("bum"),kn=st("um"),Or=st("sp"),Rr=st("rtg"),Ir=st("rtc");function jr(e,t=ve){Rs("ec",e,t)}const zr=Symbol.for("v-ndc");function Se(e,t,s,n){let i;const o=s,r=M(e);if(r||ne(e)){const l=r&&_t(e);let a=!1,p=!1;l&&(a=!Te(e),p=tt(e),e=As(e)),i=new Array(e.length);for(let u=0,m=e.length;ut(l,a,void 0,o));else{const l=Object.keys(e);i=new Array(l.length);for(let a=0,p=l.length;ae?vo(e)?zs(e):tn(e.parent):null,Wt=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>tn(e.parent),$root:e=>tn(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Xi(e),$forceUpdate:e=>e.f||(e.f=()=>{wn(e.update)}),$nextTick:e=>e.n||(e.n=Fi.bind(e.proxy)),$watch:e=>wr.bind(e)}),Ks=(e,t)=>e!==J&&!e.__isScriptSetup&&G(e,t),Ur={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:s,setupState:n,data:i,props:o,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const P=r[t];if(P!==void 0)switch(P){case 1:return n[t];case 2:return i[t];case 4:return s[t];case 3:return o[t]}else{if(Ks(n,t))return r[t]=1,n[t];if(i!==J&&G(i,t))return r[t]=2,i[t];if(G(o,t))return r[t]=3,o[t];if(s!==J&&G(s,t))return r[t]=4,s[t];sn&&(r[t]=0)}}const p=Wt[t];let u,m;if(p)return t==="$attrs"&&de(e.attrs,"get",""),p(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(s!==J&&G(s,t))return r[t]=4,s[t];if(m=a.config.globalProperties,G(m,t))return m[t]},set({_:e},t,s){const{data:n,setupState:i,ctx:o}=e;return Ks(i,t)?(i[t]=s,!0):n!==J&&G(n,t)?(n[t]=s,!0):G(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=s,!0)},has({_:{data:e,setupState:t,accessCache:s,ctx:n,appContext:i,props:o,type:r}},l){let a;return!!(s[l]||e!==J&&l[0]!=="$"&&G(e,l)||Ks(t,l)||G(o,l)||G(n,l)||G(Wt,l)||G(i.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,s){return s.get!=null?e._.accessCache[t]=0:G(s,"value")&&this.set(e,t,s.value,null),Reflect.defineProperty(e,t,s)}};function Fn(e){return M(e)?e.reduce((t,s)=>(t[s]=null,t),{}):e}let sn=!0;function Nr(e){const t=Xi(e),s=e.proxy,n=e.ctx;sn=!1,t.beforeCreate&&Bn(t.beforeCreate,e,"bc");const{data:i,computed:o,methods:r,watch:l,provide:a,inject:p,created:u,beforeMount:m,mounted:P,beforeUpdate:O,updated:F,activated:_,deactivated:E,beforeDestroy:y,beforeUnmount:$,destroyed:z,unmounted:U,render:oe,renderTracked:je,renderTriggered:ze,errorCaptured:nt,serverPrefetch:ns,expose:ft,inheritAttrs:It,components:is,directives:os,filters:Us}=t;if(p&&Dr(p,n,null),r)for(const te in r){const X=r[te];H(X)&&(n[te]=X.bind(s))}if(i){const te=i.call(s,s);Z(te)&&(e.data=Yt(te))}if(sn=!0,o)for(const te in o){const X=o[te],pt=H(X)?X.bind(s,s):H(X.get)?X.get.bind(s,s):Ke,rs=!H(X)&&H(X.set)?X.set.bind(s):Ke,ht=Ae({get:pt,set:rs});Object.defineProperty(n,te,{enumerable:!0,configurable:!0,get:()=>ht.value,set:Ue=>ht.value=Ue})}if(l)for(const te in l)Ji(l[te],n,s,te);if(a){const te=H(a)?a.call(s):a;Reflect.ownKeys(te).forEach(X=>{vr(X,te[X])})}u&&Bn(u,e,"c");function ge(te,X){M(X)?X.forEach(pt=>te(pt.bind(s))):X&&te(X.bind(s))}if(ge(Cr,m),ge(dt,P),ge(Pr,O),ge($r,F),ge(Sr,_),ge(Tr,E),ge(jr,nt),ge(Ir,je),ge(Rr,ze),ge(Ar,$),ge(kn,U),ge(Or,ns),M(ft))if(ft.length){const te=e.exposed||(e.exposed={});ft.forEach(X=>{Object.defineProperty(te,X,{get:()=>s[X],set:pt=>s[X]=pt,enumerable:!0})})}else e.exposed||(e.exposed={});oe&&e.render===Ke&&(e.render=oe),It!=null&&(e.inheritAttrs=It),is&&(e.components=is),os&&(e.directives=os),ns&&qi(e)}function Dr(e,t,s=Ke){M(e)&&(e=nn(e));for(const n in e){const i=e[n];let o;Z(i)?"default"in i?o=ps(i.from||n,i.default,!0):o=ps(i.from||n):o=ps(i),fe(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[n]=o}}function Bn(e,t,s){Ie(M(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,s)}function Ji(e,t,s,n){let i=n.includes(".")?Gi(s,n):()=>s[n];if(ne(e)){const o=t[e];H(o)&&Hs(i,o)}else if(H(e))Hs(i,e.bind(s));else if(Z(e))if(M(e))e.forEach(o=>Ji(o,t,s,n));else{const o=H(e.handler)?e.handler.bind(s):t[e.handler];H(o)&&Hs(i,o,e)}}function Xi(e){const t=e.type,{mixins:s,extends:n}=t,{mixins:i,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,l=o.get(t);let a;return l?a=l:!i.length&&!s&&!n?a=t:(a={},i.length&&i.forEach(p=>ys(a,p,r,!0)),ys(a,t,r)),Z(t)&&o.set(t,a),a}function ys(e,t,s,n=!1){const{mixins:i,extends:o}=t;o&&ys(e,o,s,!0),i&&i.forEach(r=>ys(e,r,s,!0));for(const r in t)if(!(n&&r==="expose")){const l=Mr[r]||s&&s[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const Mr={data:Hn,props:Vn,emits:Vn,methods:Mt,computed:Mt,beforeCreate:me,created:me,beforeMount:me,mounted:me,beforeUpdate:me,updated:me,beforeDestroy:me,beforeUnmount:me,destroyed:me,unmounted:me,activated:me,deactivated:me,errorCaptured:me,serverPrefetch:me,components:Mt,directives:Mt,watch:Fr,provide:Hn,inject:Lr};function Hn(e,t){return t?e?function(){return he(H(e)?e.call(this,this):e,H(t)?t.call(this,this):t)}:t:e}function Lr(e,t){return Mt(nn(e),nn(t))}function nn(e){if(M(e)){const t={};for(let s=0;st==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Pe(t)}Modifiers`]||e[`${ut(t)}Modifiers`];function Kr(e,t,...s){if(e.isUnmounted)return;const n=e.vnode.props||J;let i=s;const o=t.startsWith("update:"),r=o&&Vr(n,t.slice(7));r&&(r.trim&&(i=s.map(u=>ne(u)?u.trim():u)),r.number&&(i=s.map(Ps)));let l,a=n[l=Ds(t)]||n[l=Ds(Pe(t))];!a&&o&&(a=n[l=Ds(ut(t))]),a&&Ie(a,e,6,i);const p=n[l+"Once"];if(p){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Ie(p,e,6,i)}}const Wr=new WeakMap;function eo(e,t,s=!1){const n=s?Wr:t.emitsCache,i=n.get(e);if(i!==void 0)return i;const o=e.emits;let r={},l=!1;if(!H(e)){const a=p=>{const u=eo(p,t,!0);u&&(l=!0,he(r,u))};!s&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Z(e)&&n.set(e,null),null):(M(o)?o.forEach(a=>r[a]=null):he(r,o),Z(e)&&n.set(e,r),r)}function Is(e,t){return!e||!Ts(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),G(e,t[0].toLowerCase()+t.slice(1))||G(e,ut(t))||G(e,t))}function Kn(e){const{type:t,vnode:s,proxy:n,withProxy:i,propsOptions:[o],slots:r,attrs:l,emit:a,render:p,renderCache:u,props:m,data:P,setupState:O,ctx:F,inheritAttrs:_}=e,E=vs(e);let y,$;try{if(s.shapeFlag&4){const U=i||n,oe=U;y=He(p.call(oe,U,u,m,O,P,F)),$=l}else{const U=t;y=He(U.length>1?U(m,{attrs:l,slots:r,emit:a}):U(m,null)),$=t.props?l:Gr(l)}}catch(U){Gt.length=0,Os(U,e,1),y=ue(at)}let z=y;if($&&_!==!1){const U=Object.keys($),{shapeFlag:oe}=z;U.length&&oe&7&&(o&&U.some(Es)&&($=qr($,o)),z=Pt(z,$,!1,!0))}return s.dirs&&(z=Pt(z,null,!1,!0),z.dirs=z.dirs?z.dirs.concat(s.dirs):s.dirs),s.transition&&xn(z,s.transition),y=z,vs(E),y}const Gr=e=>{let t;for(const s in e)(s==="class"||s==="style"||Ts(s))&&((t||(t={}))[s]=e[s]);return t},qr=(e,t)=>{const s={};for(const n in e)(!Es(n)||!(n.slice(9)in t))&&(s[n]=e[n]);return s};function Zr(e,t,s){const{props:n,children:i,component:o}=e,{props:r,children:l,patchFlag:a}=t,p=o.emitsOptions;if(t.dirs||t.transition)return!0;if(s&&a>=0){if(a&1024)return!0;if(a&16)return n?Wn(n,r,p):!!r;if(a&8){const u=t.dynamicProps;for(let m=0;mObject.create(so),io=e=>Object.getPrototypeOf(e)===so;function Jr(e,t,s,n=!1){const i={},o=no();e.propsDefaults=Object.create(null),oo(e,t,i,o);for(const r in e.propsOptions[0])r in i||(i[r]=void 0);s?e.props=n?i:or(i):e.type.props?e.props=i:e.props=o,e.attrs=o}function Xr(e,t,s,n){const{props:i,attrs:o,vnode:{patchFlag:r}}=e,l=W(i),[a]=e.propsOptions;let p=!1;if((n||r>0)&&!(r&16)){if(r&8){const u=e.vnode.dynamicProps;for(let m=0;m{a=!0;const[P,O]=ro(m,t,!0);he(r,P),O&&l.push(...O)};!s&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!a)return Z(e)&&n.set(e,xt),xt;if(M(o))for(let u=0;ue==="_"||e==="_ctx"||e==="$stable",Tn=e=>M(e)?e.map(He):[He(e)],el=(e,t,s)=>{if(t._n)return t;const n=br((...i)=>Tn(t(...i)),s);return n._c=!1,n},lo=(e,t,s)=>{const n=e._ctx;for(const i in e){if(Sn(i))continue;const o=e[i];if(H(o))t[i]=el(i,o,n);else if(o!=null){const r=Tn(o);t[i]=()=>r}}},ao=(e,t)=>{const s=Tn(t);e.slots.default=()=>s},co=(e,t,s)=>{for(const n in t)(s||!Sn(n))&&(e[n]=t[n])},tl=(e,t,s)=>{const n=e.slots=no();if(e.vnode.shapeFlag&32){const i=t._;i?(co(n,t,s),s&&wi(n,"_",i,!0)):lo(t,n)}else t&&ao(e,t)},sl=(e,t,s)=>{const{vnode:n,slots:i}=e;let o=!0,r=J;if(n.shapeFlag&32){const l=t._;l?s&&l===1?o=!1:co(i,t,s):(o=!t.$stable,lo(t,i)),r=t}else t&&(ao(e,t),r={default:1});if(o)for(const l in i)!Sn(l)&&r[l]==null&&delete i[l]},_e=ll;function nl(e){return il(e)}function il(e,t){const s=$s();s.__VUE__=!0;const{insert:n,remove:i,patchProp:o,createElement:r,createText:l,createComment:a,setText:p,setElementText:u,parentNode:m,nextSibling:P,setScopeId:O=Ke,insertStaticContent:F}=e,_=(c,f,v,T=null,k=null,w=null,I=void 0,R=null,A=!!f.dynamicChildren)=>{if(c===f)return;c&&!Dt(c,f)&&(T=ls(c),Ue(c,k,w,!0),c=null),f.patchFlag===-2&&(A=!1,f.dynamicChildren=null);const{type:x,ref:D,shapeFlag:j}=f;switch(x){case js:E(c,f,v,T);break;case at:y(c,f,v,T);break;case Gs:c==null&&$(f,v,T,I);break;case ee:is(c,f,v,T,k,w,I,R,A);break;default:j&1?oe(c,f,v,T,k,w,I,R,A):j&6?os(c,f,v,T,k,w,I,R,A):(j&64||j&128)&&x.process(c,f,v,T,k,w,I,R,A,zt)}D!=null&&k?Vt(D,c&&c.ref,w,f||c,!f):D==null&&c&&c.ref!=null&&Vt(c.ref,null,w,c,!0)},E=(c,f,v,T)=>{if(c==null)n(f.el=l(f.children),v,T);else{const k=f.el=c.el;f.children!==c.children&&p(k,f.children)}},y=(c,f,v,T)=>{c==null?n(f.el=a(f.children||""),v,T):f.el=c.el},$=(c,f,v,T)=>{[c.el,c.anchor]=F(c.children,f,v,T,c.el,c.anchor)},z=({el:c,anchor:f},v,T)=>{let k;for(;c&&c!==f;)k=P(c),n(c,v,T),c=k;n(f,v,T)},U=({el:c,anchor:f})=>{let v;for(;c&&c!==f;)v=P(c),i(c),c=v;i(f)},oe=(c,f,v,T,k,w,I,R,A)=>{if(f.type==="svg"?I="svg":f.type==="math"&&(I="mathml"),c==null)je(f,v,T,k,w,I,R,A);else{const x=c.el&&c.el._isVueCE?c.el:null;try{x&&x._beginPatch(),ns(c,f,k,w,I,R,A)}finally{x&&x._endPatch()}}},je=(c,f,v,T,k,w,I,R)=>{let A,x;const{props:D,shapeFlag:j,transition:N,dirs:L}=c;if(A=c.el=r(c.type,w,D&&D.is,D),j&8?u(A,c.children):j&16&&nt(c.children,A,null,T,k,Ws(c,w),I,R),L&>(c,null,T,"created"),ze(A,c,c.scopeId,I,T),D){for(const Y in D)Y!=="value"&&!Ft(Y)&&o(A,Y,null,D[Y],w,T);"value"in D&&o(A,"value",null,D.value,w),(x=D.onVnodeBeforeMount)&&Le(x,T,c)}L&>(c,null,T,"beforeMount");const K=ol(k,N);K&&N.beforeEnter(A),n(A,f,v),((x=D&&D.onVnodeMounted)||K||L)&&_e(()=>{try{x&&Le(x,T,c),K&&N.enter(A),L&>(c,null,T,"mounted")}finally{}},k)},ze=(c,f,v,T,k)=>{if(v&&O(c,v),T)for(let w=0;w{for(let x=A;x{const R=f.el=c.el;let{patchFlag:A,dynamicChildren:x,dirs:D}=f;A|=c.patchFlag&16;const j=c.props||J,N=f.props||J;let L;if(v&&mt(v,!1),(L=N.onVnodeBeforeUpdate)&&Le(L,v,f,c),D&>(f,c,v,"beforeUpdate"),v&&mt(v,!0),x&&(!c.dynamicChildren||c.dynamicChildren.length!==x.length)&&(A=0,I=!1,x=null),(j.innerHTML&&N.innerHTML==null||j.textContent&&N.textContent==null)&&u(R,""),x?ft(c.dynamicChildren,x,R,v,T,Ws(f,k),w):I||X(c,f,R,null,v,T,Ws(f,k),w,!1),A>0){if(A&16)It(R,j,N,v,k);else if(A&2&&j.class!==N.class&&o(R,"class",null,N.class,k),A&4&&o(R,"style",j.style,N.style,k),A&8){const K=f.dynamicProps;for(let Y=0;Y{L&&Le(L,v,f,c),D&>(f,c,v,"updated")},T)},ft=(c,f,v,T,k,w,I)=>{for(let R=0;R{if(f!==v){if(f!==J)for(const w in f)!Ft(w)&&!(w in v)&&o(c,w,f[w],null,k,T);for(const w in v){if(Ft(w))continue;const I=v[w],R=f[w];I!==R&&w!=="value"&&o(c,w,R,I,k,T)}"value"in v&&o(c,"value",f.value,v.value,k)}},is=(c,f,v,T,k,w,I,R,A)=>{const x=f.el=c?c.el:l(""),D=f.anchor=c?c.anchor:l("");let{patchFlag:j,dynamicChildren:N,slotScopeIds:L}=f;L&&(R=R?R.concat(L):L),c==null?(n(x,v,T),n(D,v,T),nt(f.children||[],v,D,k,w,I,R,A)):j>0&&j&64&&N&&c.dynamicChildren&&c.dynamicChildren.length===N.length?(ft(c.dynamicChildren,N,v,k,w,I,R),(f.key!=null||k&&f===k.subTree)&&uo(c,f,!0)):X(c,f,v,D,k,w,I,R,A)},os=(c,f,v,T,k,w,I,R,A)=>{f.slotScopeIds=R,c==null?f.shapeFlag&512?k.ctx.activate(f,v,T,I,A):Us(f,v,T,k,w,I,A):Pn(c,f,A)},Us=(c,f,v,T,k,w,I)=>{const R=c.component=hl(c,T,k);if(Zi(c)&&(R.ctx.renderer=zt),ml(R,!1,I),R.asyncDep){if(k&&k.registerDep(R,ge,I),!c.el){const A=R.subTree=ue(at);y(null,A,f,v),c.placeholder=A.el}}else ge(R,c,f,v,k,w,I)},Pn=(c,f,v)=>{const T=f.component=c.component;if(Zr(c,f,v))if(T.asyncDep&&!T.asyncResolved){te(T,f,v);return}else T.next=f,T.update();else f.el=c.el,T.vnode=f},ge=(c,f,v,T,k,w,I)=>{const R=()=>{if(c.isMounted){let{next:j,bu:N,u:L,parent:K,vnode:Y}=c;{const De=fo(c);if(De){j&&(j.el=Y.el,te(c,j,I)),De.asyncDep.then(()=>{_e(()=>{c.isUnmounted||x()},k)});return}}let q=j,ie;mt(c,!1),j?(j.el=Y.el,te(c,j,I)):j=Y,N&&fs(N),(ie=j.props&&j.props.onVnodeBeforeUpdate)&&Le(ie,K,j,Y),mt(c,!0);const ae=Kn(c),Ne=c.subTree;c.subTree=ae,_(Ne,ae,m(Ne.el),ls(Ne),c,k,w),j.el=ae.el,q===null&&Yr(c,ae.el),L&&_e(L,k),(ie=j.props&&j.props.onVnodeUpdated)&&_e(()=>Le(ie,K,j,Y),k)}else{let j;const{el:N,props:L}=f,{bm:K,m:Y,parent:q,root:ie,type:ae}=c,Ne=Kt(f);mt(c,!1),K&&fs(K),!Ne&&(j=L&&L.onVnodeBeforeMount)&&Le(j,q,f),mt(c,!0);{ie.ce&&ie.ce._hasShadowRoot()&&ie.ce._injectChildStyle(ae,c.parent?c.parent.type:void 0);const De=c.subTree=Kn(c);_(null,De,v,T,c,k,w),f.el=De.el}if(Y&&_e(Y,k),!Ne&&(j=L&&L.onVnodeMounted)){const De=f;_e(()=>Le(j,q,De),k)}(f.shapeFlag&256||q&&Kt(q.vnode)&&q.vnode.shapeFlag&256)&&c.a&&_e(c.a,k),c.isMounted=!0,f=v=T=null}};c.scope.on();const A=c.effect=new Ti(R);c.scope.off();const x=c.update=A.run.bind(A),D=c.job=A.runIfDirty.bind(A);D.i=c,D.id=c.uid,A.scheduler=()=>wn(D),mt(c,!0),x()},te=(c,f,v)=>{f.component=c;const T=c.vnode.props;c.vnode=f,c.next=null,Xr(c,f.props,T,v),sl(c,f.children,v),Ge(),Dn(c),qe()},X=(c,f,v,T,k,w,I,R,A=!1)=>{const x=c&&c.children,D=c?c.shapeFlag:0,j=f.children,{patchFlag:N,shapeFlag:L}=f;if(N>0){if(N&128){rs(x,j,v,T,k,w,I,R,A);return}else if(N&256){pt(x,j,v,T,k,w,I,R,A);return}}L&8?(D&16&&jt(x,k,w),j!==x&&u(v,j)):D&16?L&16?rs(x,j,v,T,k,w,I,R,A):jt(x,k,w,!0):(D&8&&u(v,""),L&16&&nt(j,v,T,k,w,I,R,A))},pt=(c,f,v,T,k,w,I,R,A)=>{c=c||xt,f=f||xt;const x=c.length,D=f.length,j=Math.min(x,D);let N;for(N=0;ND?jt(c,k,w,!0,!1,j):nt(f,v,T,k,w,I,R,A,j)},rs=(c,f,v,T,k,w,I,R,A)=>{let x=0;const D=f.length;let j=c.length-1,N=D-1;for(;x<=j&&x<=N;){const L=c[x],K=f[x]=A?Je(f[x]):He(f[x]);if(Dt(L,K))_(L,K,v,null,k,w,I,R,A);else break;x++}for(;x<=j&&x<=N;){const L=c[j],K=f[N]=A?Je(f[N]):He(f[N]);if(Dt(L,K))_(L,K,v,null,k,w,I,R,A);else break;j--,N--}if(x>j){if(x<=N){const L=N+1,K=LN)for(;x<=j;)Ue(c[x],k,w,!0),x++;else{const L=x,K=x,Y=new Map;for(x=K;x<=N;x++){const ye=f[x]=A?Je(f[x]):He(f[x]);ye.key!=null&&Y.set(ye.key,x)}let q,ie=0;const ae=N-K+1;let Ne=!1,De=0;const Ut=new Array(ae);for(x=0;x=ae){Ue(ye,k,w,!0);continue}let Me;if(ye.key!=null)Me=Y.get(ye.key);else for(q=K;q<=N;q++)if(Ut[q-K]===0&&Dt(ye,f[q])){Me=q;break}Me===void 0?Ue(ye,k,w,!0):(Ut[Me-K]=x+1,Me>=De?De=Me:Ne=!0,_(ye,f[Me],v,null,k,w,I,R,A),ie++)}const On=Ne?rl(Ut):xt;for(q=On.length-1,x=ae-1;x>=0;x--){const ye=K+x,Me=f[ye],Rn=f[ye+1],In=ye+1{const{el:w,type:I,transition:R,children:A,shapeFlag:x}=c;if(x&6){ht(c.component.subTree,f,v,T);return}if(x&128){c.suspense.move(f,v,T);return}if(x&64){I.move(c,f,v,zt);return}if(I===ee){n(w,f,v);for(let j=0;jR.enter(w),k));else{const{leave:j,delayLeave:N,afterLeave:L}=R,K=()=>{c.ctx.isUnmounted?i(w):n(w,f,v)},Y=()=>{const q=w._isLeaving||!!w[Vs];w._isLeaving&&w[Vs](!0),R.persisted&&!q?K():j(w,()=>{K(),L&&L()})};N?N(w,K,Y):Y()}else n(w,f,v)},Ue=(c,f,v,T=!1,k=!1)=>{const{type:w,props:I,ref:R,children:A,dynamicChildren:x,shapeFlag:D,patchFlag:j,dirs:N,cacheIndex:L,memo:K}=c;if(j===-2&&(k=!1),R!=null&&(Ge(),Vt(R,null,v,c,!0),qe()),L!=null&&(f.renderCache[L]=void 0),D&256){f.ctx.deactivate(c);return}const Y=D&1&&N,q=!Kt(c);let ie;if(q&&(ie=I&&I.onVnodeBeforeUnmount)&&Le(ie,f,c),D&6)Po(c.component,v,T);else{if(D&128){c.suspense.unmount(v,T);return}Y&>(c,null,f,"beforeUnmount"),D&64?c.type.remove(c,f,v,zt,T):x&&!x.hasOnce&&(w!==ee||j>0&&j&64)?jt(x,f,v,!1,!0):(w===ee&&j&384||!k&&D&16)&&jt(A,f,v),T&&$n(c)}const ae=K!=null&&L==null;(q&&(ie=I&&I.onVnodeUnmounted)||Y||ae)&&_e(()=>{ie&&Le(ie,f,c),Y&>(c,null,f,"unmounted"),ae&&(c.el=null)},v)},$n=c=>{const{type:f,el:v,anchor:T,transition:k}=c;if(f===ee){Co(v,T);return}if(f===Gs){U(c);return}const w=()=>{i(v),k&&!k.persisted&&k.afterLeave&&k.afterLeave()};if(c.shapeFlag&1&&k&&!k.persisted){const{leave:I,delayLeave:R}=k,A=()=>I(v,w);R?R(c.el,w,A):A()}else w()},Co=(c,f)=>{let v;for(;c!==f;)v=P(c),i(c),c=v;i(f)},Po=(c,f,v)=>{const{bum:T,scope:k,job:w,subTree:I,um:R,m:A,a:x}=c;qn(A),qn(x),T&&fs(T),k.stop(),w&&(w.flags|=8,Ue(I,c,f,v)),R&&_e(R,f),_e(()=>{c.isUnmounted=!0},f)},jt=(c,f,v,T=!1,k=!1,w=0)=>{for(let I=w;I{if(c.shapeFlag&6)return ls(c.component.subTree);if(c.shapeFlag&128)return c.suspense.next();const f=P(c.anchor||c.el),v=f&&f[xr];return v?P(v):f};let Ns=!1;const An=(c,f,v)=>{let T;c==null?f._vnode&&(Ue(f._vnode,null,null,!0),T=f._vnode.component):_(f._vnode||null,c,f,null,null,null,v),f._vnode=c,Ns||(Ns=!0,Dn(T),Hi(),Ns=!1)},zt={p:_,um:Ue,m:ht,r:$n,mt:Us,mc:nt,pc:X,pbc:ft,n:ls,o:e};return{render:An,hydrate:void 0,createApp:Hr(An)}}function Ws({type:e,props:t},s){return s==="svg"&&e==="foreignObject"||s==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:s}function mt({effect:e,job:t},s){s?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function ol(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function uo(e,t,s=!1){const n=e.children,i=t.children;if(M(n)&&M(i))for(let o=0;o>1,e[s[l]]0&&(t[n]=s[o-1]),s[o]=n)}}for(o=s.length,r=s[o-1];o-- >0;)s[o]=r,r=t[r];return s}function fo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:fo(t)}function qn(e){if(e)for(let t=0;te.__isSuspense;function ll(e,t){t&&t.pendingBranch?M(e)?t.effects.push(...e):t.effects.push(e):mr(e)}const ee=Symbol.for("v-fgt"),js=Symbol.for("v-txt"),at=Symbol.for("v-cmt"),Gs=Symbol.for("v-stc"),Gt=[];let we=null;function S(e=!1){Gt.push(we=e?null:[])}function al(){Gt.pop(),we=Gt[Gt.length-1]||null}let Xt=1;function Zn(e,t=!1){Xt+=e,e<0&&we&&t&&(we.hasOnce=!0)}function go(e){return e.dynamicChildren=Xt>0?we||xt:null,al(),Xt>0&&we&&we.push(e),e}function C(e,t,s,n,i,o){return go(d(e,t,s,n,i,o,!0))}function ot(e,t,s,n,i){return go(ue(e,t,s,n,i,!0))}function mo(e){return e?e.__v_isVNode===!0:!1}function Dt(e,t){return e.type===t.type&&e.key===t.key}const bo=({key:e})=>e??null,hs=({ref:e,ref_key:t,ref_for:s})=>(typeof e=="number"&&(e=""+e),e!=null?ne(e)||fe(e)||H(e)?{i:ke,r:e,k:t,f:!!s}:e:null);function d(e,t=null,s=null,n=0,i=null,o=e===ee?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&bo(t),ref:t&&hs(t),scopeId:Ki,slotScopeIds:null,children:s,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:ke};return l?(ws(a,s),o&128&&e.normalize(a)):s&&(a.shapeFlag|=ne(s)?8:16),Xt>0&&!r&&we&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&we.push(a),a}const ue=cl;function cl(e,t=null,s=null,n=0,i=null,o=!1){if((!e||e===zr)&&(e=at),mo(e)){const l=Pt(e,t,!0);return s&&ws(l,s),Xt>0&&!o&&we&&(l.shapeFlag&6?we[we.indexOf(e)]=l:we.push(l)),l.patchFlag=-2,l}if(yl(e)&&(e=e.__vccOpts),t){t=ul(t);let{class:l,style:a}=t;l&&!ne(l)&&(t.class=Oe(l)),Z(a)&&(yn(a)&&!M(a)&&(a=he({},a)),t.style=fn(a))}const r=ne(e)?1:ho(e)?128:kr(e)?64:Z(e)?4:H(e)?2:0;return d(e,t,s,n,i,r,o,!0)}function ul(e){return e?yn(e)||io(e)?he({},e):e:null}function Pt(e,t,s=!1,n=!1){const{props:i,ref:o,patchFlag:r,children:l,transition:a}=e,p=t?dl(i||{},t):i,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:p,key:p&&bo(p),ref:t&&t.ref?s&&o?M(o)?o.concat(hs(t)):[o,hs(t)]:hs(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ee?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Pt(e.ssContent),ssFallback:e.ssFallback&&Pt(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&n&&xn(u,a.clone(u)),u}function Ee(e=" ",t=0){return ue(js,null,e,t)}function B(e="",t=!1){return t?(S(),ot(at,null,e)):ue(at,null,e)}function He(e){return e==null||typeof e=="boolean"?ue(at):M(e)?ue(ee,null,e.slice()):mo(e)?Je(e):ue(js,null,String(e))}function Je(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Pt(e)}function ws(e,t){let s=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(M(t))s=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ws(e,i()),i._c&&(i._d=!0));return}else{s=32;const i=t._;!i&&!io(t)?t._ctx=ke:i===3&&ke&&(ke.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(H(t)){if(n&65){ws(e,{default:t});return}t={default:t,_ctx:ke},s=32}else t=String(t),n&64?(s=16,t=[Ee(t)]):s=8;e.children=t,e.shapeFlag|=s}function dl(...e){const t={};for(let s=0;sve||ke;let xs,rn;{const e=$s(),t=(s,n)=>{let i;return(i=e[s])||(i=e[s]=[]),i.push(n),o=>{i.length>1?i.forEach(r=>r(o)):i[0](o)}};xs=t("__VUE_INSTANCE_SETTERS__",s=>ve=s),rn=t("__VUE_SSR_SETTERS__",s=>Qt=s)}const ss=e=>{const t=ve;return xs(e),e.scope.on(),()=>{e.scope.off(),xs(t)}},Yn=()=>{ve&&ve.scope.off(),xs(null)};function vo(e){return e.vnode.shapeFlag&4}let Qt=!1;function ml(e,t=!1,s=!1){t&&rn(t);const{props:n,children:i}=e.vnode,o=vo(e);Jr(e,n,o,t),tl(e,i,s||t);const r=o?bl(e,t):void 0;return t&&rn(!1),r}function bl(e,t){const s=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ur);const{setup:n}=s;if(n){Ge();const i=e.setupContext=n.length>1?_l(e):null,o=ss(e),r=ts(n,e,0,[e.props,i]),l=bi(r);if(qe(),o(),(l||e.sp)&&!Kt(e)&&qi(e),l){if(r.then(Yn,Yn),t)return r.then(a=>{Jn(e,a)}).catch(a=>{Os(a,e,0)});e.asyncDep=r}else Jn(e,r)}else _o(e)}function Jn(e,t,s){H(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=Mi(t)),_o(e)}function _o(e,t,s){const n=e.type;e.render||(e.render=n.render||Ke);{const i=ss(e);Ge();try{Nr(e)}finally{qe(),i()}}}const vl={get(e,t){return de(e,"get",""),e[t]}};function _l(e){const t=s=>{e.exposed=s||{}};return{attrs:new Proxy(e.attrs,vl),slots:e.slots,emit:e.emit,expose:t}}function zs(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Mi(rr(e.exposed)),{get(t,s){if(s in t)return t[s];if(s in Wt)return Wt[s](e)},has(t,s){return s in t||s in Wt}})):e.proxy}function yl(e){return H(e)&&"__vccOpts"in e}const Ae=(e,t)=>dr(e,t,Qt),wl="3.5.39";/** +* @vue/runtime-dom v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ln;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{ln=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const yo=ln?e=>ln.createHTML(e):e=>e,xl="http://www.w3.org/2000/svg",kl="http://www.w3.org/1998/Math/MathML",Ye=typeof document<"u"?document:null,Qn=Ye&&Ye.createElement("template"),Sl={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 i=t==="svg"?Ye.createElementNS(xl,e):t==="mathml"?Ye.createElementNS(kl,e):s?Ye.createElement(e,{is:s}):Ye.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ye.createTextNode(e),createComment:e=>Ye.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ye.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Qn.innerHTML=yo(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const l=Qn.content;if(n==="svg"||n==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Tl=Symbol("_vtc");function El(e,t,s){const n=e[Tl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Cl=Symbol("_vsh"),Pl=Symbol(""),$l=/(?:^|;)\s*display\s*:/;function Al(e,t,s){const n=e.style,i=ne(s);let o=!1;if(s&&!i){if(t)if(ne(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Lt(n,l,"")}else for(const r in t)s[r]==null&&Lt(n,r,"");for(const r in s){r==="display"&&(o=!0);const l=s[r];l!=null?Rl(e,r,!ne(t)&&t?t[r]:void 0,l)||Lt(n,r,l):Lt(n,r,"")}}else if(i){if(t!==s){const r=n[Pl];r&&(s+=";"+r),n.cssText=s,o=$l.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Cl]&&(n.display="none"))}const ti=/\s*!important$/;function Lt(e,t,s){if(M(s))s.forEach(n=>Lt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Ol(e,t);ti.test(s)?e.setProperty(ut(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Ol(e,t){const s=qs[t];if(s)return s;let n=Pe(t);if(n!=="filter"&&n in e)return qs[t]=n;n=yi(n);for(let i=0;iZs||(Dl.then(()=>Zs=0),Zs=Date.now());function Ll(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(M(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),l=[n];for(let a=0;ae.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Fl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?El(e,n,r):t==="style"?Al(e,s,n):Ts(t)?Es(t)||jl(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Bl(e,t,n,r))?(oi(e,t,n),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&ii(e,t,n,r,o,t!=="value")):e._isVueCE&&(Hl(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ne(n)))?oi(e,Pe(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Bl(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&li(t)&&H(s));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return li(t)&&ne(s)?!1:t in e}function Hl(e,t){const s=e._def.props;if(!s)return!1;const n=Pe(t);return Array.isArray(s)?s.some(i=>Pe(i)===n):Object.keys(s).some(i=>Pe(i)===n)}const ct=e=>{const t=e.props["onUpdate:modelValue"]||!1;return M(t)?s=>fs(t,s):t};function Vl(e){e.target.composing=!0}function ai(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ce=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=Ps(e)),e}const pe={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ce]=ct(i);const o=n||i.props&&i.props.type==="number";et(e,t?"change":"input",r=>{r.target.composing||e[Ce](ci(e.value,s,o))}),(s||o)&&et(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(et(e,"compositionstart",Vl),et(e,"compositionend",ai),et(e,"change",ai))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ce]=ct(r),e.composing)return;const l=(o||e.type==="number")&&!/^0\d/.test(e.value)?Ps(e.value):e.value,a=t??"";if(l===a)return;const p=e.getRootNode();(p instanceof Document||p instanceof ShadowRoot)&&p.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===a)||(e.value=a)}},Kl={deep:!0,created(e,t,s){e[Ce]=ct(s),et(e,"change",()=>{const n=e._modelValue,i=$t(e),o=e.checked,r=e[Ce];if(M(n)){const l=pn(n,i),a=l!==-1;if(o&&!a)r(n.concat(i));else if(!o&&a){const p=[...n];p.splice(l,1),r(p)}}else if(Rt(n)){const l=new Set(n);o?l.add(i):l.delete(i),r(l)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Ce]=ct(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(M(t))i=pn(t,n.props.value)>-1;else if(Rt(t))i=t.has(n.props.value);else{if(t===s)return;i=lt(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wl={created(e,{value:t},s){e.checked=lt(t,s.props.value),e[Ce]=ct(s),et(e,"change",()=>{e[Ce]($t(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ce]=ct(n),t!==s&&(e.checked=lt(t,n.props.value))}},ks={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=Rt(t);et(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Ps($t(r)):$t(r));e[Ce](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Ce]=ct(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Ce]=ct(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=M(t);if(!(s&&!n&&!Rt(t))){for(let i=0,o=e.options.length;iString(p)===String(l)):r.selected=pn(t,l)>-1}else r.selected=t.has(l);else if(lt($t(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function $t(e){return"_value"in e?e._value:e.value}function wo(e,t){const s=t?"_trueValue":"_falseValue";return s in e?e[s]:t}const Gl={created(e,t,s){ds(e,t,s,null,"created")},mounted(e,t,s){ds(e,t,s,null,"mounted")},beforeUpdate(e,t,s,n){ds(e,t,s,n,"beforeUpdate")},updated(e,t,s,n){ds(e,t,s,n,"updated")}};function ql(e,t){switch(e){case"SELECT":return ks;case"TEXTAREA":return pe;default:switch(t){case"checkbox":return Kl;case"radio":return Wl;default:return pe}}}function ds(e,t,s,n,i){const r=ql(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Zl=["ctrl","shift","alt","meta"],Yl={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>Zl.some(s=>e[`${s}Key`]&&!t.includes(s))},Jl=(e,t)=>{if(!e)return e;const s=e._withMods||(e._withMods={}),n=t.join(".");return s[n]||(s[n]=((i,...o)=>{for(let r=0;r{const s=e._withKeys||(e._withKeys={}),n=t.join(".");return s[n]||(s[n]=(i=>{if(!("key"in i))return;const o=ut(i.key);if(t.some(r=>r===o||Xl[r]===o))return e(i)}))},ea=he({patchProp:Fl},Sl);let fi;function ta(){return fi||(fi=nl(ea))}const sa=((...e)=>{const t=ta().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=ia(n);if(!i)return;const o=t._component;!H(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,na(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function na(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function ia(e){return ne(e)?document.querySelector(e):e}const xo="dh-panel-theme";function oa(){var e;try{const t=localStorage.getItem(xo);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Et=V(oa());function ko(e){Et.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(xo,e)}catch{}}function pi(){ko(Et.value==="dark"?"light":"dark")}ko(Et.value);const ra={apiServer:"API server",switchToLight:"Switch to light theme",switchToDark:"Switch to dark theme",theme:"Theme",signOut:"Sign out",loading:"Loading…",standardUserNote:"Signed in as a standard user — management sections need an admin role",footer:"DriverVault — car maintenance & service tracker."},la={overview:"Overview",users:"Users",orgs:"Organizations",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},aa={title:"Sign in",subtitle:"Superadmin console for the DriverVault API Server.",email:"Email",password:"Password",submit:"Sign in",submitting:"Signing in…",invalid:"Invalid email or password.",failed:"Could not sign in.",authNote:"Authenticates against PocketBase through this server"},ca={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ua={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},da={title:"Users",allOrgs:"All organizations",yourOrg:"Your organization",newUser:"New user",password:"Password",passwordUnchanged:"Password (blank = unchanged)",passwordPlaceholder:"min 8 characters",orgNone:"— none —",you:"you",empty:"No users.",confirmDelete:"Delete {email}? This cannot be undone."},fa={title:"Organizations",subtitle:"Tenants users belong to",subtitleOwn:"Your organization",subtitleNone:"Create one to manage your own team",newOrg:"New organization",namePlaceholder:"Acme Fleet",empty:"No organizations yet.",createHint:"You have no organization yet. Create one to become its admin.",colId:"ID",confirmDelete:'Delete the organization "{name}"?',confirmDeleteOwn:'Delete your organization "{name}"? You will be removed from it and become a regular user.'},pa={title:"PocketBase",subtitle:"Database connection used by every endpoint",connected:"connected",noSuperuser:"no superuser",unreachable:"unreachable",baseUrl:"Base URL",superuserEmail:"Superuser email",superuserPassword:"Superuser password",passwordUnchanged:"unchanged",passwordNotSet:"not set",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Connection OK — superuser authenticated.",testReachableNoAuth:"PocketBase is reachable, but the service account did not authenticate.",testUnreachable:"PocketBase is not reachable at that address.",savedNotice:"Saved. The server is now using this PocketBase."},ha={title:"Web App",subtitle:"Address probed by the status check, and who may call this API from a browser",reachable:"reachable",unreachable:"unreachable",baseUrl:"Base URL",allowedOrigins:"Allowed origins",originsHint:"Comma separated, or {star} for any. Native mobile apps are not subject to CORS.",saveApply:"Save & apply",testConnection:"Test connection",persistedEnv:"persisted to .env",testOk:"Web App is reachable.",testFailed:"Web App did not answer its health check at that address.",savedNotice:"Saved. New origins apply to the next request."},ga={title:"Plugins",subtitle:"Third-party service integrations",registerExternal:"Register external",cancelRegister:"Cancel",name:"Name",baseUrl:"Base URL",provider:"Provider",register:"Register",empty:"No plugins yet. Register an external one above, or compile a built-in connector.",builtin:"builtin",enabled:"enabled",disabled:"disabled",health:"Health",configure:"Configure",close:"Close",noConfig:"This plugin takes no configuration.",notSet:"Not set — let organizations and users choose",capabilities:"Capabilities",saved:"Saved.",checking:"Checking…",save:"Save",saveEnable:"Save & enable",disable:"Disable",remove:"Remove",builtinNote:"Built-in plugins can be disabled but not removed",confirmRemove:'Remove the external plugin "{name}"? Its saved config is deleted.'},ma={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupParts:"Parts",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},ba={app:ra,sections:la,login:aa,status:ca,common:ua,users:da,orgs:fa,pocketbase:pa,webapp:ha,plugins:ga,api:ma},va={apiServer:"Serwer API",switchToLight:"Przełącz na motyw jasny",switchToDark:"Przełącz na motyw ciemny",theme:"Motyw",signOut:"Wyloguj się",loading:"Ładowanie…",standardUserNote:"Zalogowano jako zwykły użytkownik — sekcje zarządzania wymagają roli administratora",footer:"DriverVault — rejestr serwisu i konserwacji samochodu."},_a={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},ya={title:"Zaloguj się",subtitle:"Konsola superadministratora serwera API DriverVault.",email:"E-mail",password:"Hasło",submit:"Zaloguj się",submitting:"Logowanie…",invalid:"Nieprawidłowy e-mail lub hasło.",failed:"Nie udało się zalogować.",authNote:"Uwierzytelnia w PocketBase za pośrednictwem tego serwera"},wa={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},xa={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},ka={title:"Użytkownicy",allOrgs:"Wszystkie organizacje",yourOrg:"Twoja organizacja",newUser:"Nowy użytkownik",password:"Hasło",passwordUnchanged:"Hasło (puste = bez zmian)",passwordPlaceholder:"min. 8 znaków",orgNone:"— brak —",you:"Ty",empty:"Brak użytkowników.",confirmDelete:"Usunąć {email}? Tej operacji nie można cofnąć."},Sa={title:"Organizacje",subtitle:"Podmioty, do których należą użytkownicy",subtitleOwn:"Twoja organizacja",subtitleNone:"Utwórz ją, aby zarządzać własnym zespołem",newOrg:"Nowa organizacja",namePlaceholder:"Acme Fleet",empty:"Brak organizacji.",createHint:"Nie masz jeszcze organizacji. Utwórz ją, aby zostać jej administratorem.",colId:"ID",confirmDelete:"Usunąć organizację „{name}”?",confirmDeleteOwn:"Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem."},Ta={title:"PocketBase",subtitle:"Połączenie z bazą danych używane przez każdy punkt końcowy",connected:"połączono",noSuperuser:"brak superużytkownika",unreachable:"niedostępny",baseUrl:"Adres bazowy",superuserEmail:"E-mail superużytkownika",superuserPassword:"Hasło superużytkownika",passwordUnchanged:"bez zmian",passwordNotSet:"nie ustawiono",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Połączenie OK — superużytkownik uwierzytelniony.",testReachableNoAuth:"PocketBase jest dostępny, ale konto usługowe nie zostało uwierzytelnione.",testUnreachable:"PocketBase jest niedostępny pod tym adresem.",savedNotice:"Zapisano. Serwer korzysta teraz z tego PocketBase."},Ea={title:"Aplikacja webowa",subtitle:"Adres sprawdzany podczas kontroli statusu oraz kto może wywoływać to API z przeglądarki",reachable:"dostępna",unreachable:"niedostępna",baseUrl:"Adres bazowy",allowedOrigins:"Dozwolone źródła",originsHint:"Oddzielone przecinkami lub {star} dla dowolnego. Natywne aplikacje mobilne nie podlegają CORS.",saveApply:"Zapisz i zastosuj",testConnection:"Testuj połączenie",persistedEnv:"zapisano w .env",testOk:"Aplikacja webowa jest dostępna.",testFailed:"Aplikacja webowa nie odpowiedziała na kontrolę stanu pod tym adresem.",savedNotice:"Zapisano. Nowe źródła obowiązują od następnego żądania."},Ca={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",registerExternal:"Zarejestruj zewnętrzną",cancelRegister:"Anuluj",name:"Nazwa",baseUrl:"Adres bazowy",provider:"Dostawca",register:"Zarejestruj",empty:"Brak wtyczek. Zarejestruj zewnętrzną powyżej lub skompiluj wbudowany łącznik.",builtin:"wbudowana",enabled:"włączona",disabled:"wyłączona",health:"Stan",configure:"Konfiguruj",close:"Zamknij",noConfig:"Ta wtyczka nie wymaga konfiguracji.",notSet:"Nie ustawiono — pozwól organizacjom i użytkownikom wybrać",capabilities:"Możliwości",saved:"Zapisano.",checking:"Sprawdzanie…",save:"Zapisz",saveEnable:"Zapisz i włącz",disable:"Wyłącz",remove:"Usuń",builtinNote:"Wtyczki wbudowane można wyłączyć, ale nie usunąć",confirmRemove:"Usunąć zewnętrzną wtyczkę „{name}”? Jej zapisana konfiguracja zostanie usunięta."},Pa={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupParts:"Części",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},$a={app:va,sections:_a,login:ya,status:wa,common:xa,users:ka,orgs:Sa,pocketbase:Ta,webapp:Ea,plugins:Ca,api:Pa},Aa={apiServer:"API-server",switchToLight:"Skift til lyst tema",switchToDark:"Skift til mørkt tema",theme:"Tema",signOut:"Log ud",loading:"Indlæser…",standardUserNote:"Logget ind som almindelig bruger — administrationssektioner kræver en administratorrolle",footer:"DriverVault — bilservice- og vedligeholdelsesregister."},Oa={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},Ra={title:"Log ind",subtitle:"Superadmin-konsol til DriverVault API-serveren.",email:"E-mail",password:"Adgangskode",submit:"Log ind",submitting:"Logger ind…",invalid:"Ugyldig e-mail eller adgangskode.",failed:"Kunne ikke logge ind.",authNote:"Godkender mod PocketBase gennem denne server"},Ia={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},ja={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},za={title:"Brugere",allOrgs:"Alle organisationer",yourOrg:"Din organisation",newUser:"Ny bruger",password:"Adgangskode",passwordUnchanged:"Adgangskode (tom = uændret)",passwordPlaceholder:"mindst 8 tegn",orgNone:"— ingen —",you:"dig",empty:"Ingen brugere.",confirmDelete:"Slet {email}? Dette kan ikke fortrydes."},Ua={title:"Organisationer",subtitle:"Enheder, som brugere tilhører",subtitleOwn:"Din organisation",subtitleNone:"Opret en for at administrere dit eget team",newOrg:"Ny organisation",namePlaceholder:"Acme Fleet",empty:"Ingen organisationer endnu.",createHint:"Du har endnu ingen organisation. Opret en for at blive dens administrator.",colId:"ID",confirmDelete:'Slet organisationen "{name}"?',confirmDeleteOwn:"Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger."},Na={title:"PocketBase",subtitle:"Databaseforbindelse brugt af hvert endpoint",connected:"forbundet",noSuperuser:"ingen superbruger",unreachable:"utilgængelig",baseUrl:"Basis-URL",superuserEmail:"Superbrugerens e-mail",superuserPassword:"Superbrugerens adgangskode",passwordUnchanged:"uændret",passwordNotSet:"ikke angivet",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Forbindelse OK — superbruger godkendt.",testReachableNoAuth:"PocketBase er tilgængelig, men servicekontoen blev ikke godkendt.",testUnreachable:"PocketBase er ikke tilgængelig på den adresse.",savedNotice:"Gemt. Serveren bruger nu denne PocketBase."},Da={title:"Webapp",subtitle:"Adressen, der tjekkes ved statuskontrol, og hvem der må kalde dette API fra en browser",reachable:"tilgængelig",unreachable:"utilgængelig",baseUrl:"Basis-URL",allowedOrigins:"Tilladte oprindelser",originsHint:"Kommasepareret, eller {star} for enhver. Native mobilapps er ikke underlagt CORS.",saveApply:"Gem og anvend",testConnection:"Test forbindelse",persistedEnv:"gemt i .env",testOk:"Webappen er tilgængelig.",testFailed:"Webappen svarede ikke på sit helbredstjek på den adresse.",savedNotice:"Gemt. Nye oprindelser gælder fra næste anmodning."},Ma={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",registerExternal:"Registrér ekstern",cancelRegister:"Annuller",name:"Navn",baseUrl:"Basis-URL",provider:"Udbyder",register:"Registrér",empty:"Ingen plugins endnu. Registrér et eksternt ovenfor, eller kompilér et indbygget stik.",builtin:"indbygget",enabled:"aktiveret",disabled:"deaktiveret",health:"Helbred",configure:"Konfigurer",close:"Luk",noConfig:"Dette plugin kræver ingen konfiguration.",notSet:"Ikke angivet — lad organisationer og brugere vælge",capabilities:"Funktioner",saved:"Gemt.",checking:"Tjekker…",save:"Gem",saveEnable:"Gem og aktivér",disable:"Deaktiver",remove:"Fjern",builtinNote:"Indbyggede plugins kan deaktiveres, men ikke fjernes",confirmRemove:'Fjern det eksterne plugin "{name}"? Dets gemte konfiguration slettes.'},La={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupParts:"Reservedele",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Fa={app:Aa,sections:Oa,login:Ra,status:Ia,common:ja,users:za,orgs:Ua,pocketbase:Na,webapp:Da,plugins:Ma,api:La},So="dh-panel-lang",To="en",At={en:ba,pl:$a,da:Fa},Ba=Object.keys(At);function Ha(){try{const t=localStorage.getItem(So);if(t&&At[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return At[e]?e:To}const En=V(Ha());function Va(e){if(At[e]){En.value=e;try{localStorage.setItem(So,e)}catch{}}}function hi(e,t){return t.split(".").reduce((s,n)=>s==null?void 0:s[n],e)}function Ka(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Wa(e,t,s){let n="other";try{n=new Intl.PluralRules(s).select(t)}catch{n=t===1?"one":"other"}return e[n]??e.other??e.one}function h(e,t){const s=En.value;let n=hi(At[s],e);if(n==null&&(n=hi(At[To],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Wa(n,t.n,s)}return typeof n!="string"?e:Ka(n,t)}function gi(e,t,s){const i=h(e,{...s,[t]:"\0"}),o=i.indexOf("\0");return o===-1?{before:i,after:""}:{before:i.slice(0,o),after:i.slice(o+1)}}const an="dh-panel-token";function Ga(){try{return localStorage.getItem(an)||""}catch{return""}}const Ot=V(Ga()),re=V(null),xe=Ae(()=>{var e;return((e=re.value)==null?void 0:e.role)==="superadmin"}),gs=Ae(()=>{var e,t;return((e=re.value)==null?void 0:e.role)==="admin"||((t=re.value)==null?void 0:t.role)==="superadmin"});function Eo(e){Ot.value=e;try{e?localStorage.setItem(an,e):localStorage.removeItem(an)}catch{}}class qa extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Za(e,t){if(!e||typeof e!="object")return`HTTP ${t}`;if(e.error)return e.error;const s=Object.entries(e.data||{}).map(([n,i])=>`${n}: ${(i==null?void 0:i.message)||i}`).filter(Boolean);return s.length?s.join("; "):e.message||`HTTP ${t}`}async function se(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Ot.value&&(i.Authorization=Ot.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let l=null;try{l=r?JSON.parse(r):null}catch{l=null}if(!o.ok)throw o.status===401&&n&&Cn(),new qa(Za(l,o.status),o.status,l);return l}async function Ya(e,t){const s=await se("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Eo(s.token),await Ss(),re.value}async function Ss(){return re.value=await se("/api/identity"),re.value}function Cn(){Eo(""),re.value=null}async function Ja(){if(!Ot.value)return null;try{return await Ss()}catch{return Cn(),null}}const Xa={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},Qa={class:"dh-card p-6"},ec={class:"text-lg font-bold tracking-[-0.02em] text-strong"},tc={class:"mt-1 mb-5 text-sm text-body"},sc={class:"dh-label",for:"login-email"},nc={class:"dh-label",for:"login-password"},ic={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},oc=["disabled"],rc={class:"eyebrow text-center"},lc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=V(""),i=V(""),o=V(""),r=V(!1),l=Ae(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function a(){if(l.value){o.value="",r.value=!0;try{const p=await Ya(n.value.trim(),i.value);s("authenticated",p)}catch(p){o.value=p.status===400||p.status===404?h("login.invalid"):p.message||h("login.failed"),i.value=""}finally{r.value=!1}}}return(p,u)=>(S(),C("div",Xa,[d("div",Qa,[d("h1",ec,b(g(h)("login.title")),1),d("p",tc,b(g(h)("login.subtitle")),1),d("form",{class:"flex flex-col gap-4",onSubmit:Jl(a,["prevent"])},[d("div",null,[d("label",sc,b(g(h)("login.email")),1),le(d("input",{id:"login-email","onUpdate:modelValue":u[0]||(u[0]=m=>n.value=m),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[pe,n.value]])]),d("div",null,[d("label",nc,b(g(h)("login.password")),1),le(d("input",{id:"login-password","onUpdate:modelValue":u[1]||(u[1]=m=>i.value=m),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[pe,i.value]])]),o.value?(S(),C("p",ic,b(o.value),1)):B("",!0),d("button",{class:"dh-btn w-full",type:"submit",disabled:!l.value},b(r.value?g(h)("login.submitting"):g(h)("login.submit")),9,oc)],32)]),d("p",rc,b(g(h)("login.authNote")),1)]))}},ac={class:"dh-card overflow-hidden"},cc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uc={class:"text-base font-bold tracking-[-0.02em] text-strong"},dc={key:0,class:"dh-pill bg-danger-soft text-danger"},fc={key:0,class:"px-5 py-4 text-sm text-danger"},pc={key:1,class:"w-full text-left text-sm"},hc={class:"px-5 py-3 font-medium text-strong"},gc={class:"data px-5 py-3 text-xs text-muted"},mc={class:"data px-5 py-3 text-right text-xs text-muted"},bc={class:"px-5 py-3 text-right"},vc={key:2,class:"px-5 py-4 text-sm text-muted"},_c={__name:"StatusCard",setup(e){const t=V(null),s=V("");let n=null;async function i(){try{t.value=await se("/api/status",{auth:!1}),s.value=""}catch(l){t.value=null,s.value=l.message||h("status.unreachable")}}const o=Ae(()=>{var l,a,p;return[{key:"apiServer",label:h("status.apiServer"),h:(l=t.value)==null?void 0:l.apiServer},{key:"pocketBase",label:h("status.pocketBase"),h:(a=t.value)==null?void 0:a.pocketBase},{key:"webApp",label:h("status.webApp"),h:(p=t.value)==null?void 0:p.webApp}]});dt(()=>{i(),n=setInterval(i,1e4)}),kn(()=>clearInterval(n));const r=l=>l==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(l,a)=>(S(),C("div",ac,[d("div",cc,[d("div",uc,b(g(h)("status.title")),1),s.value?(S(),C("span",dc,[a[0]||(a[0]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b(g(h)("status.unreachable")),1)])):B("",!0)]),s.value?(S(),C("div",fc,b(s.value),1)):t.value?(S(),C("table",pc,[d("tbody",null,[(S(!0),C(ee,null,Se(o.value,p=>(S(),C("tr",{key:p.key,class:"border-t border-subtle first:border-t-0"},[d("td",hc,b(p.label),1),d("td",gc,b(p.h.url||g(h)("status.thisProcess")),1),d("td",mc,b(p.h.latencyMs!=null?p.h.latencyMs+"ms":g(h)("common.empty")),1),d("td",bc,[d("span",{class:Oe(["dh-pill",r(p.h.status)])},[a[1]||(a[1]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b(p.h.status),1)],2)])]))),128))])])):(S(),C("div",vc,b(g(h)("status.checking")),1))]))}},yc={class:"dh-card overflow-hidden"},wc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},xc={class:"text-base font-bold tracking-[-0.02em] text-strong"},kc={class:"mt-0.5 text-xs text-muted"},Sc={class:"flex flex-col gap-4 px-5 py-4"},Tc={class:"dh-label",for:"pb-url"},Ec={class:"grid gap-4 sm:grid-cols-2"},Cc={class:"dh-label",for:"pb-email"},Pc={class:"dh-label",for:"pb-password"},$c=["placeholder"],Ac={key:0,class:"data text-xs text-muted"},Oc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Rc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Ic={class:"flex items-center gap-2"},jc=["disabled"],zc=["disabled"],Uc={class:"eyebrow"},Nc={__name:"PocketBaseCard",setup(e){const t=V(null),s=V({url:"",adminEmail:"",adminPassword:""}),n=V(null),i=V(""),o=V(""),r=V(!1);async function l(){try{t.value=await se("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(u){i.value=u.message}}dt(l);async function a(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?h("pocketbase.testOk"):n.value.reachable?h("pocketbase.testReachableNoAuth"):h("pocketbase.testUnreachable")}catch(u){i.value=u.message}finally{r.value=!1}}async function p(){i.value="",o.value="",r.value=!0;try{const u=await se("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=u.config,n.value=u.config.probe,s.value.adminPassword="",o.value=u.warning||h("pocketbase.savedNotice")}catch(u){i.value=u.message}finally{r.value=!1}}return(u,m)=>{var P,O;return S(),C("div",yc,[d("div",wc,[d("div",null,[d("div",xc,b(g(h)("pocketbase.title")),1),d("p",kc,b(g(h)("pocketbase.subtitle")),1)]),n.value?(S(),C("span",{key:0,class:Oe(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[m[3]||(m[3]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(" "+b(n.value.superuser?g(h)("pocketbase.connected"):n.value.reachable?g(h)("pocketbase.noSuperuser"):g(h)("pocketbase.unreachable")),1)],2)):B("",!0)]),d("div",Sc,[d("div",null,[d("label",Tc,b(g(h)("pocketbase.baseUrl")),1),le(d("input",{id:"pb-url","onUpdate:modelValue":m[0]||(m[0]=F=>s.value.url=F),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[pe,s.value.url]])]),d("div",Ec,[d("div",null,[d("label",Cc,b(g(h)("pocketbase.superuserEmail")),1),le(d("input",{id:"pb-email","onUpdate:modelValue":m[1]||(m[1]=F=>s.value.adminEmail=F),class:"dh-input",autocomplete:"off"},null,512),[[pe,s.value.adminEmail]])]),d("div",null,[d("label",Pc,b(g(h)("pocketbase.superuserPassword")),1),le(d("input",{id:"pb-password","onUpdate:modelValue":m[2]||(m[2]=F=>s.value.adminPassword=F),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(P=t.value)!=null&&P.adminConfigured?g(h)("pocketbase.passwordUnchanged"):g(h)("pocketbase.passwordNotSet")},null,8,$c),[[pe,s.value.adminPassword]])])]),(O=n.value)!=null&&O.detail?(S(),C("p",Ac,b(n.value.detail),1)):B("",!0),o.value?(S(),C("p",Oc,b(o.value),1)):B("",!0),i.value?(S(),C("p",Rc,b(i.value),1)):B("",!0),d("div",Ic,[d("button",{class:"dh-btn",disabled:r.value,onClick:p},b(g(h)("pocketbase.saveApply")),9,jc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:a},b(g(h)("pocketbase.testConnection")),9,zc),m[4]||(m[4]=d("span",{class:"flex-1"},null,-1)),d("span",Uc,b(g(h)("pocketbase.persistedEnv")),1)])])])}}},Dc={class:"dh-card overflow-hidden"},Mc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Lc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Fc={class:"mt-0.5 text-xs text-muted"},Bc={class:"flex flex-col gap-4 px-5 py-4"},Hc={class:"dh-label",for:"web-url"},Vc={class:"dh-label",for:"web-origins"},Kc={class:"mt-1 text-xs text-muted"},Wc={key:0,class:"data text-xs text-muted"},Gc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},qc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Zc={class:"flex items-center gap-2"},Yc=["disabled"],Jc=["disabled"],Xc={class:"eyebrow"},Qc={__name:"WebAppCard",setup(e){const t=V(null),s=V({url:"",origins:""}),n=V(null),i=V(""),o=V(""),r=V(!1),l=P=>P.split(",").map(O=>O.trim()).filter(Boolean);function a(P){t.value=P,s.value={url:P.url,origins:(P.allowOrigins||[]).join(", ")},n.value=P.probe}async function p(){try{a(await se("/api/admin/webapp-config"))}catch(P){i.value=P.message}}dt(p);async function u(){i.value="",o.value="",r.value=!0;try{n.value=await se("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?h("webapp.testOk"):h("webapp.testFailed")}catch(P){i.value=P.message}finally{r.value=!1}}async function m(){i.value="",o.value="",r.value=!0;try{const P=await se("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:l(s.value.origins)}});a(P.config),o.value=P.warning||h("webapp.savedNotice")}catch(P){i.value=P.message}finally{r.value=!1}}return(P,O)=>{var F;return S(),C("div",Dc,[d("div",Mc,[d("div",null,[d("div",Lc,b(g(h)("webapp.title")),1),d("p",Fc,b(g(h)("webapp.subtitle")),1)]),n.value?(S(),C("span",{key:0,class:Oe(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[O[2]||(O[2]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(" "+b(n.value.status==="ok"?g(h)("webapp.reachable"):g(h)("webapp.unreachable")),1)],2)):B("",!0)]),d("div",Bc,[d("div",null,[d("label",Hc,b(g(h)("webapp.baseUrl")),1),le(d("input",{id:"web-url","onUpdate:modelValue":O[0]||(O[0]=_=>s.value.url=_),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[pe,s.value.url]])]),d("div",null,[d("label",Vc,b(g(h)("webapp.allowedOrigins")),1),le(d("input",{id:"web-origins","onUpdate:modelValue":O[1]||(O[1]=_=>s.value.origins=_),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[pe,s.value.origins]]),d("p",Kc,[Ee(b(g(gi)("webapp.originsHint","star").before),1),O[3]||(O[3]=d("span",{class:"data"},"*",-1)),Ee(b(g(gi)("webapp.originsHint","star").after),1)])]),(F=n.value)!=null&&F.error?(S(),C("p",Wc,b(n.value.error),1)):B("",!0),o.value?(S(),C("p",Gc,b(o.value),1)):B("",!0),i.value?(S(),C("p",qc,b(i.value),1)):B("",!0),d("div",Zc,[d("button",{class:"dh-btn",disabled:r.value,onClick:m},b(g(h)("webapp.saveApply")),9,Yc),d("button",{class:"dh-btn-ghost",disabled:r.value,onClick:u},b(g(h)("webapp.testConnection")),9,Jc),O[4]||(O[4]=d("span",{class:"flex-1"},null,-1)),d("span",Xc,b(g(h)("webapp.persistedEnv")),1)])])])}}},eu={class:"dh-card overflow-hidden"},tu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},su={class:"text-base font-bold tracking-[-0.02em] text-strong"},nu={class:"mt-0.5 text-xs text-muted"},iu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},ou={class:"grid gap-3 sm:grid-cols-3"},ru={class:"dh-label"},lu={class:"dh-label"},au={class:"dh-label"},cu=["disabled"],uu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},du={key:2,class:"px-5 py-6 text-center text-sm text-muted"},fu={class:"flex items-center gap-3 px-5 py-3"},pu=["onClick"],hu={class:"font-semibold text-strong"},gu={class:"dh-pill bg-sunken text-muted"},mu={key:0,class:"text-xs text-muted"},bu=["disabled","onClick"],vu=["disabled","onClick"],_u={key:0,class:"bg-sunken px-5 py-4"},yu={key:0,class:"data mb-3 text-xs text-muted"},wu={key:1,class:"grid gap-3 sm:grid-cols-2"},xu={class:"dh-label"},ku={key:0,class:"text-danger"},Su=["onUpdate:modelValue"],Tu={key:0,value:""},Eu=["value"],Cu=["onUpdate:modelValue","type","placeholder"],Pu={key:2,class:"mt-1 text-xs text-muted"},$u={key:2,class:"text-xs text-muted"},Au={key:3,class:"mt-4"},Ou={class:"eyebrow mb-1.5"},Ru={class:"data flex flex-col gap-1 text-xs text-muted"},Iu={class:"text-strong"},ju={key:0},zu={key:1},Uu={key:4,class:"data mt-3 text-xs text-body"},Nu={class:"mt-4 flex items-center gap-2"},Du=["disabled","onClick"],Mu=["disabled","onClick"],Lu=["disabled","onClick"],Fu={key:5,class:"eyebrow mt-2"},Bu={__name:"PluginsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=Yt({}),r=Yt({}),l=V(!1),a=V({name:"",baseURL:"",provider:""});async function p(){try{const E=await se("/api/admin/plugins");t.value=E.plugins||[],s.value=""}catch(E){s.value=E.message}}dt(p);function u(E){var $;if(i.value===E.name){i.value=null;return}const y={};for(const z of E.configFields||[])y[z.key]=(($=E.config)==null?void 0:$[z.key])??"";o[E.name]=y,i.value=E.name}async function m(E,y){n.value=!0,r[E.name]="";try{const $=await se(`/api/admin/plugins/${encodeURIComponent(E.name)}`,{method:"PUT",body:{enabled:y,config:o[E.name]??{}}});r[E.name]=$.warning||h("plugins.saved"),await p()}catch($){r[E.name]=$.message}finally{n.value=!1}}async function P(E){n.value=!0,r[E.name]=h("plugins.checking");try{const y=await se(`/api/admin/plugins/${encodeURIComponent(E.name)}/health`,{method:"POST"});r[E.name]=`${y.health.status}${y.health.detail?" — "+y.health.detail:""}`,await p()}catch(y){r[E.name]=y.message}finally{n.value=!1}}async function O(E){if(confirm(h("plugins.confirmRemove",{name:E.name}))){n.value=!0;try{await se(`/api/admin/plugins/${encodeURIComponent(E.name)}`,{method:"DELETE"}),i.value===E.name&&(i.value=null),await p()}catch(y){r[E.name]=y.message}finally{n.value=!1}}}async function F(){n.value=!0,s.value="";try{await se("/api/admin/plugins",{method:"POST",body:a.value}),a.value={name:"",baseURL:"",provider:""},l.value=!1,await p()}catch(E){s.value=E.message}finally{n.value=!1}}const _=E=>E==="ok"?"bg-success-soft text-success":E==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(E,y)=>(S(),C("div",eu,[d("div",tu,[d("div",null,[d("div",su,b(g(h)("plugins.title")),1),d("p",nu,b(g(h)("plugins.subtitle")),1)]),d("button",{class:"dh-btn-ghost",onClick:y[0]||(y[0]=$=>l.value=!l.value)},b(l.value?g(h)("plugins.cancelRegister"):g(h)("plugins.registerExternal")),1)]),l.value?(S(),C("div",iu,[d("div",ou,[d("div",null,[d("label",ru,b(g(h)("plugins.name")),1),le(d("input",{"onUpdate:modelValue":y[1]||(y[1]=$=>a.value.name=$),class:"dh-input",placeholder:"acme-parts"},null,512),[[pe,a.value.name]])]),d("div",null,[d("label",lu,b(g(h)("plugins.baseUrl")),1),le(d("input",{"onUpdate:modelValue":y[2]||(y[2]=$=>a.value.baseURL=$),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[pe,a.value.baseURL]])]),d("div",null,[d("label",au,b(g(h)("plugins.provider")),1),le(d("input",{"onUpdate:modelValue":y[3]||(y[3]=$=>a.value.provider=$),class:"dh-input",placeholder:"ACME Corp"},null,512),[[pe,a.value.provider]])])]),d("button",{class:"dh-btn mt-3",disabled:n.value||!a.value.name||!a.value.baseURL,onClick:F},b(g(h)("plugins.register")),9,cu)])):B("",!0),s.value?(S(),C("p",uu,b(s.value),1)):B("",!0),t.value.length?B("",!0):(S(),C("p",du,b(g(h)("plugins.empty")),1)),(S(!0),C(ee,null,Se(t.value,$=>(S(),C("div",{key:$.name,class:"border-t border-subtle first:border-t-0"},[d("div",fu,[d("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:z=>u($)},[d("span",hu,b($.name),1),d("span",gu,b($.kind||g(h)("plugins.builtin")),1),$.provider?(S(),C("span",mu,b($.provider),1)):B("",!0),$.health?(S(),C("span",{key:1,class:Oe(["dh-pill",_($.health.status)])},[y[4]||(y[4]=d("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),Ee(b($.health.status),1)],2)):B("",!0)],8,pu),d("span",{class:Oe(["dh-pill",$.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},b($.enabled?g(h)("plugins.enabled"):g(h)("plugins.disabled")),3),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:z=>P($)},b(g(h)("plugins.health")),9,bu),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:z=>u($)},b(i.value===$.name?g(h)("plugins.close"):g(h)("plugins.configure")),9,vu)]),i.value===$.name?(S(),C("div",_u,[$.baseURL?(S(),C("div",yu,b($.baseURL),1)):B("",!0),($.configFields||[]).length?(S(),C("div",wu,[(S(!0),C(ee,null,Se($.configFields,z=>(S(),C("div",{key:z.key},[d("label",xu,[Ee(b(z.label||z.key),1),z.required?(S(),C("span",ku," *")):B("",!0)]),z.type==="select"?le((S(),C("select",{key:0,"onUpdate:modelValue":U=>o[$.name][z.key]=U,class:"dh-select"},[z.required?B("",!0):(S(),C("option",Tu,b(g(h)("plugins.notSet")),1)),(S(!0),C(ee,null,Se(z.options||[],U=>(S(),C("option",{key:U.value,value:U.value},b(U.label||U.value),9,Eu))),128))],8,Su)),[[ks,o[$.name][z.key]]]):le((S(),C("input",{key:1,"onUpdate:modelValue":U=>o[$.name][z.key]=U,class:"dh-input",type:z.type==="password"?"password":z.type==="number"?"number":"text",placeholder:z.default||"",autocomplete:"off"},null,8,Cu)),[[Gl,o[$.name][z.key]]]),z.help?(S(),C("p",Pu,b(z.help),1)):B("",!0)]))),128))])):(S(),C("p",$u,b(g(h)("plugins.noConfig")),1)),($.capabilities||[]).length?(S(),C("div",Au,[d("div",Ou,b(g(h)("plugins.capabilities")),1),d("ul",Ru,[(S(!0),C(ee,null,Se($.capabilities,z=>(S(),C("li",{key:z.id},[d("span",Iu,b(z.id),1),z.method||z.endpoint?(S(),C("span",ju," — "+b(z.method)+" "+b(z.endpoint),1)):B("",!0),z.description?(S(),C("span",zu," · "+b(z.description),1)):B("",!0)]))),128))])])):B("",!0),r[$.name]?(S(),C("p",Uu,b(r[$.name]),1)):B("",!0),d("div",Nu,[d("button",{class:"dh-btn",disabled:n.value,onClick:z=>m($,!0)},b($.enabled?g(h)("plugins.save"):g(h)("plugins.saveEnable")),9,Du),$.enabled?(S(),C("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:z=>m($,!1)},b(g(h)("plugins.disable")),9,Mu)):B("",!0),y[5]||(y[5]=d("span",{class:"flex-1"},null,-1)),$.kind==="external"?(S(),C("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:z=>O($)},b(g(h)("plugins.remove")),9,Lu)):B("",!0)]),$.kind!=="external"?(S(),C("p",Fu,b(g(h)("plugins.builtinNote")),1)):B("",!0)])):B("",!0)]))),128))]))}},Hu={class:"dh-card overflow-hidden"},Vu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Ku={class:"text-base font-bold tracking-[-0.02em] text-strong"},Wu={class:"mt-0.5 text-xs text-muted"},Gu={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},qu={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Zu={class:"grid gap-3 sm:grid-cols-2"},Yu={class:"dh-label"},Ju={class:"dh-label"},Xu={class:"dh-label"},Qu=["placeholder"],ed={class:"dh-label"},td=["value"],sd={key:0},nd={class:"dh-label"},id={value:""},od=["value"],rd={class:"mt-3 flex items-center gap-2"},ld=["disabled"],ad=["disabled"],cd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ud={key:3,class:"w-full text-left text-sm"},dd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},fd={class:"data px-5 py-2.5 text-xs text-strong"},pd={key:0,class:"eyebrow ml-1"},hd={class:"px-5 py-2.5 text-body"},gd={class:"px-5 py-2.5 text-body"},md={class:"px-5 py-2.5"},bd={class:"px-5 py-2.5 text-right whitespace-nowrap"},vd=["onClick"],_d=["disabled","onClick"],yd={__name:"UsersCard",setup(e){const t=V([]),s=V([]),n=V(""),i=V(!1),o=V(null),r=V({}),l=Ae(()=>xe.value?["user","admin","superadmin"]:["user","admin"]);async function a(){try{const[_,E]=await Promise.all([se("/api/users"),se("/api/orgs")]);t.value=_.users||[],s.value=E.organizations||[],n.value=""}catch(_){n.value=_.message}}dt(a);function p(){var _;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:xe.value?"":((_=re.value)==null?void 0:_.organization)||""}}function u(_){o.value=_.id,r.value={email:_.email,name:_.name||"",password:"",role:_.role,organization:_.organization||""}}function m(){o.value=null,n.value=""}async function P(){i.value=!0,n.value="";try{if(o.value==="new")await se("/api/users",{method:"POST",body:r.value});else{const _={...r.value};_.password||delete _.password,await se(`/api/users/${o.value}`,{method:"PATCH",body:_})}o.value=null,await a()}catch(_){n.value=_.message}finally{i.value=!1}}async function O(_){if(confirm(h("users.confirmDelete",{email:_.email}))){i.value=!0,n.value="";try{await se(`/api/users/${_.id}`,{method:"DELETE"}),await a()}catch(E){n.value=E.message}finally{i.value=!1}}}const F=_=>_==="superadmin"?"bg-info-soft text-info":_==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(_,E)=>(S(),C("div",Hu,[d("div",Vu,[d("div",null,[d("div",Ku,b(g(h)("users.title")),1),d("p",Wu,b(g(xe)?g(h)("users.allOrgs"):g(h)("users.yourOrg")),1)]),d("button",{class:"dh-btn",onClick:p},b(g(h)("users.newUser")),1)]),n.value?(S(),C("p",Gu,b(n.value),1)):B("",!0),o.value?(S(),C("div",qu,[d("div",Zu,[d("div",null,[d("label",Yu,b(g(h)("common.email")),1),le(d("input",{"onUpdate:modelValue":E[0]||(E[0]=y=>r.value.email=y),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[pe,r.value.email]])]),d("div",null,[d("label",Ju,b(g(h)("common.name")),1),le(d("input",{"onUpdate:modelValue":E[1]||(E[1]=y=>r.value.name=y),class:"dh-input",autocomplete:"off"},null,512),[[pe,r.value.name]])]),d("div",null,[d("label",Xu,b(o.value==="new"?g(h)("users.password"):g(h)("users.passwordUnchanged")),1),le(d("input",{"onUpdate:modelValue":E[2]||(E[2]=y=>r.value.password=y),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:g(h)("users.passwordPlaceholder")},null,8,Qu),[[pe,r.value.password]])]),d("div",null,[d("label",ed,b(g(h)("common.role")),1),le(d("select",{"onUpdate:modelValue":E[3]||(E[3]=y=>r.value.role=y),class:"dh-select"},[(S(!0),C(ee,null,Se(l.value,y=>(S(),C("option",{key:y,value:y},b(y),9,td))),128))],512),[[ks,r.value.role]])]),g(xe)?(S(),C("div",sd,[d("label",nd,b(g(h)("common.organization")),1),le(d("select",{"onUpdate:modelValue":E[4]||(E[4]=y=>r.value.organization=y),class:"dh-select"},[d("option",id,b(g(h)("users.orgNone")),1),(S(!0),C(ee,null,Se(s.value,y=>(S(),C("option",{key:y.id,value:y.id},b(y.name),9,od))),128))],512),[[ks,r.value.organization]])])):B("",!0)]),d("div",rd,[d("button",{class:"dh-btn",disabled:i.value,onClick:P},b(o.value==="new"?g(h)("common.create"):g(h)("common.save")),9,ld),d("button",{class:"dh-btn-ghost",disabled:i.value,onClick:m},b(g(h)("common.cancel")),9,ad)])])):B("",!0),t.value.length?(S(),C("table",ud,[d("thead",null,[d("tr",dd,[d("th",null,b(g(h)("common.email")),1),d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("common.organization")),1),d("th",null,b(g(h)("common.role")),1),E[5]||(E[5]=d("th",null,null,-1))])]),d("tbody",null,[(S(!0),C(ee,null,Se(t.value,y=>{var $,z;return S(),C("tr",{key:y.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",fd,[Ee(b(y.email)+" ",1),y.id===(($=g(re))==null?void 0:$.id)?(S(),C("span",pd,b(g(h)("users.you")),1)):B("",!0)]),d("td",hd,b(y.name||g(h)("common.empty")),1),d("td",gd,b(y.organizationName||g(h)("common.empty")),1),d("td",md,[d("span",{class:Oe(["dh-pill",F(y.role)])},b(y.role),3)]),d("td",bd,[d("button",{class:"dh-btn-ghost",onClick:U=>u(y)},b(g(h)("common.edit")),9,vd),y.id!==((z=g(re))==null?void 0:z.id)?(S(),C("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:U=>O(y)},b(g(h)("common.delete")),9,_d)):B("",!0)])])}),128))])])):(S(),C("p",cd,b(g(h)("users.empty")),1))]))}},wd={class:"dh-card overflow-hidden"},xd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},kd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Sd={class:"mt-0.5 text-xs text-muted"},Td={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Ed={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},Cd={class:"dh-label"},Pd=["placeholder"],$d={class:"mt-3 flex items-center gap-2"},Ad=["disabled"],Od=["disabled"],Rd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Id={key:3,class:"w-full text-left text-sm"},jd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},zd={class:"px-5 py-2.5 font-medium text-strong"},Ud={class:"data px-5 py-2.5 text-xs text-muted"},Nd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Dd=["onClick"],Md=["disabled","onClick"],Ld={__name:"OrgsCard",setup(e){const t=V([]),s=V(""),n=V(!1),i=V(null),o=V(""),r=Ae(()=>{var _;return((_=re.value)==null?void 0:_.organization)||""}),l=Ae(()=>xe.value||!r.value);function a(_){return xe.value||_.id===r.value}async function p(){if(!gs.value){t.value=[];return}try{const _=await se("/api/orgs");t.value=_.organizations||[],s.value=""}catch(_){s.value=_.message}}dt(p);function u(){i.value="new",o.value=""}function m(_){i.value=_.id,o.value=_.name}function P(){i.value=null,s.value=""}async function O(){n.value=!0,s.value="";try{i.value==="new"?(await se("/api/orgs",{method:"POST",body:{name:o.value}}),xe.value||await Ss()):await se(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await p()}catch(_){s.value=_.message}finally{n.value=!1}}async function F(_){const E=!xe.value&&_.id===r.value;if(confirm(h(E?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:_.name}))){n.value=!0,s.value="";try{await se(`/api/orgs/${_.id}`,{method:"DELETE"}),E&&await Ss(),await p()}catch($){s.value=$.message}finally{n.value=!1}}}return(_,E)=>(S(),C("div",wd,[d("div",xd,[d("div",null,[d("div",kd,b(g(xe)?g(h)("orgs.title"):g(h)("common.organization")),1),d("p",Sd,b(g(xe)?g(h)("orgs.subtitle"):r.value?g(h)("orgs.subtitleOwn"):g(h)("orgs.subtitleNone")),1)]),l.value?(S(),C("button",{key:0,class:"dh-btn",onClick:u},b(g(h)("orgs.newOrg")),1)):B("",!0)]),s.value?(S(),C("p",Td,b(s.value),1)):B("",!0),i.value?(S(),C("div",Ed,[d("label",Cd,b(g(h)("common.name")),1),le(d("input",{"onUpdate:modelValue":E[0]||(E[0]=y=>o.value=y),class:"dh-input",placeholder:g(h)("orgs.namePlaceholder"),onKeyup:Ql(O,["enter"])},null,40,Pd),[[pe,o.value]]),d("div",$d,[d("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:O},b(i.value==="new"?g(h)("common.create"):g(h)("common.save")),9,Ad),d("button",{class:"dh-btn-ghost",disabled:n.value,onClick:P},b(g(h)("common.cancel")),9,Od)])])):B("",!0),t.value.length?(S(),C("table",Id,[d("thead",null,[d("tr",jd,[d("th",null,b(g(h)("common.name")),1),d("th",null,b(g(h)("orgs.colId")),1),E[1]||(E[1]=d("th",null,null,-1))])]),d("tbody",null,[(S(!0),C(ee,null,Se(t.value,y=>(S(),C("tr",{key:y.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[d("td",zd,b(y.name),1),d("td",Ud,b(y.id),1),d("td",Nd,[a(y)?(S(),C(ee,{key:0},[d("button",{class:"dh-btn-ghost",onClick:$=>m(y)},b(g(h)("common.rename")),9,Dd),d("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:$=>F(y)},b(g(h)("common.delete")),9,Md)],64)):B("",!0)])]))),128))])])):(S(),C("p",Rd,b(l.value&&!g(xe)?g(h)("orgs.createHint"):g(h)("orgs.empty")),1))]))}},Fd={class:"dh-card overflow-hidden"},Bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Hd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Vd={class:"eyebrow"},Kd={class:"w-full text-left text-sm"},Wd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Gd={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},qd={class:"text-strong"},Zd={class:"border-t border-subtle px-5 py-2.5 text-body"},it={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array},setup(e){const t={GET:"text-success",POST:"text-brandtext",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(S(),C("div",Fd,[d("div",Bd,[d("div",Hd,b(e.title),1),d("span",Vd,b(e.auth),1)]),d("table",Kd,[d("thead",null,[d("tr",Wd,[d("th",null,b(g(h)("api.colEndpoint")),1),d("th",null,b(g(h)("api.colDescription")),1)])]),d("tbody",null,[(S(!0),C(ee,null,Se(e.endpoints,i=>(S(),C("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[d("td",Gd,[d("span",{class:Oe(["font-semibold",t[i.method]])},b(i.method),3),d("span",qd,b(i.path),1)]),d("td",Zd,b(i.desc),1)]))),128))])])]))}},Yd={class:"mx-auto flex max-w-4xl flex-col gap-6 px-6 pt-12 pb-16"},Jd={class:"flex items-center gap-3"},Xd={class:"inline-flex items-center gap-2.5 select-none"},Qd={class:"h-8 w-8 shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},ef={transform:"translate(7 0) skewX(-13)"},tf=["fill"],sf=["fill"],nf=["fill"],of={class:"eyebrow mt-1.5"},rf={key:0,class:"data hidden text-xs text-muted sm:inline"},lf={key:0},af={key:1,class:"dh-pill bg-info-soft text-info"},cf=["value","aria-label"],uf=["value"],df=["title"],ff={key:0,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},pf={key:1,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.75",class:"h-4 w-4"},hf={key:0,class:"eyebrow py-16 text-center"},gf={class:"flex flex-wrap gap-1.5"},mf=["onClick"],bf={key:7,class:"eyebrow text-center"},vf={class:"eyebrow text-center"},_f={__name:"App",setup(e){const t=V(!0),s=V("overview");dt(async()=>{await Ja(),t.value=!1});const n=Ae(()=>{const _=[{id:"overview",label:h("sections.overview")}];return gs.value&&_.push({id:"users",label:h("sections.users")}),(gs.value||re.value)&&_.push({id:"orgs",label:h("sections.orgs")}),xe.value&&_.push({id:"pocketbase",label:h("sections.pocketbase")},{id:"webapp",label:h("sections.webapp")},{id:"plugins",label:h("sections.plugins")}),_.push({id:"api",label:h("sections.api")}),_}),i=Ae(()=>Ba.map(_=>{let E=_;try{E=new Intl.DisplayNames([_],{type:"language"}).of(_)||_}catch{}return{code:_,label:E.charAt(0).toUpperCase()+E.slice(1)}}));function o(){Cn(),s.value="overview"}const r=Ae(()=>Et.value==="dark"?["#60a5fa","#93c5fd","#ffffff"]:["var(--brand-700)","var(--brand-500)","var(--brand-400)"]),l=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/api/status",desc:"Health of PocketBase + Web App"},{method:"POST",path:"/api/auth/login",desc:"Exchange email + password for a PocketBase token"},{method:"GET",path:"/api/auth/validate",desc:"Check whether a token is still valid"}],a=[{method:"GET",path:"/api/auth/me",desc:"Identity of the bearer token"},{method:"GET",path:"/api/identity",desc:"Identity incl. role + organization"}],p=[{method:"GET",path:"/api/cars",desc:"List owned + shared cars"},{method:"POST",path:"/api/cars",desc:"Create a car"},{method:"GET",path:"/api/cars/{id}",desc:"Fetch one car"},{method:"PATCH",path:"/api/cars/{id}",desc:"Update a car"},{method:"DELETE",path:"/api/cars/{id}",desc:"Delete a car (owner only)"},{method:"GET",path:"/api/cars/{id}/service-records",desc:"A car's service history"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/shares",desc:"Who a car is shared with (owner)"},{method:"POST",path:"/api/cars/{id}/shares",desc:"Share a car by email (owner)"},{method:"DELETE",path:"/api/cars/{id}/shares/{userId}",desc:"Revoke a share (owner)"}],u=[{method:"GET",path:"/api/service-records",desc:"List service records"},{method:"POST",path:"/api/service-records",desc:"Log a service record"},{method:"GET",path:"/api/service-records/{id}",desc:"Fetch one record"},{method:"PATCH",path:"/api/service-records/{id}",desc:"Update a record"},{method:"DELETE",path:"/api/service-records/{id}",desc:"Delete a record"}],m=[{method:"GET",path:"/api/parts",desc:"List parts"},{method:"POST",path:"/api/parts",desc:"Add a part"},{method:"GET",path:"/api/parts/{id}",desc:"Fetch one part"},{method:"PATCH",path:"/api/parts/{id}",desc:"Update a part"},{method:"DELETE",path:"/api/parts/{id}",desc:"Delete a part"}],P=[{method:"GET",path:"/api/me",desc:"Current user profile"},{method:"PATCH",path:"/api/me",desc:"Update profile"},{method:"POST",path:"/api/me/password",desc:"Change password"},{method:"POST",path:"/api/me/avatar",desc:"Upload avatar"},{method:"GET",path:"/api/me/avatar",desc:"Fetch avatar"},{method:"DELETE",path:"/api/me/avatar",desc:"Remove avatar"},{method:"POST",path:"/api/me/verify/request",desc:"Request email verification"},{method:"GET",path:"/api/me/export",desc:"Export your data"},{method:"POST",path:"/api/me/import",desc:"Import data"},{method:"POST",path:"/api/me/delete",desc:"Request account deletion"},{method:"POST",path:"/api/me/delete/cancel",desc:"Cancel deletion request"},{method:"DELETE",path:"/api/me",desc:"Finalize account deletion"}],O=[{method:"GET",path:"/api/users",desc:"List users (scoped by role)"},{method:"POST",path:"/api/users",desc:"Create a user"},{method:"PATCH",path:"/api/users/{id}",desc:"Update email / name / role / org / password"},{method:"DELETE",path:"/api/users/{id}",desc:"Delete a user"},{method:"GET",path:"/api/orgs",desc:"List organizations"},{method:"POST",path:"/api/orgs",desc:"Create an organization (any user without one; creator becomes admin)"},{method:"PATCH",path:"/api/orgs/{id}",desc:"Rename an organization (own org; any as superadmin)"},{method:"DELETE",path:"/api/orgs/{id}",desc:"Delete an organization (own org; any as superadmin)"}],F=[{method:"GET",path:"/api/admin/pb-config",desc:"PocketBase connection + live probe"},{method:"POST",path:"/api/admin/pb-config/test",desc:"Probe a candidate connection"},{method:"PUT",path:"/api/admin/pb-config",desc:"Apply + persist a connection"},{method:"GET",path:"/api/admin/webapp-config",desc:"Web App URL + CORS origins, with a live probe"},{method:"POST",path:"/api/admin/webapp-config/test",desc:"Probe a candidate Web App address"},{method:"PUT",path:"/api/admin/webapp-config",desc:"Apply + persist Web App settings"},{method:"GET",path:"/api/admin/plugins",desc:"List plugins (secrets masked)"},{method:"POST",path:"/api/admin/plugins",desc:"Register an external plugin"},{method:"GET",path:"/api/admin/plugins/{name}",desc:"Fetch one plugin"},{method:"PUT",path:"/api/admin/plugins/{name}",desc:"Enable/disable + configure"},{method:"DELETE",path:"/api/admin/plugins/{name}",desc:"Remove an external plugin"},{method:"POST",path:"/api/admin/plugins/{name}/health",desc:"Run a health check now"}];return(_,E)=>(S(),C("div",Yd,[d("div",Jd,[d("span",Xd,[(S(),C("svg",Qd,[d("g",ef,[d("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:r.value[0]},null,8,tf),d("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:r.value[1]},null,8,sf),d("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:r.value[2]},null,8,nf)])])),E[2]||(E[2]=d("span",{class:"text-2xl leading-none font-extrabold tracking-[-0.03em] italic"},[d("span",{class:"text-strong"},"Driver"),d("span",{class:"text-brandtext"},"Vault")],-1))]),d("span",of,b(g(h)("app.apiServer")),1),E[5]||(E[5]=d("div",{class:"flex-1"},null,-1)),g(re)?(S(),C("span",rf,[Ee(b(g(re).email),1),g(re).organizationName?(S(),C("span",lf," · "+b(g(re).organizationName),1)):B("",!0)])):B("",!0),g(re)?(S(),C("span",af,b(g(re).role),1)):B("",!0),d("select",{class:"dh-select !w-auto !py-1 !text-xs",value:g(En),"aria-label":g(h)("sections.overview"),onChange:E[0]||(E[0]=y=>g(Va)(y.target.value))},[(S(!0),C(ee,null,Se(i.value,y=>(S(),C("option",{key:y.code,value:y.code},b(y.label),9,uf))),128))],40,cf),d("button",{class:"dh-btn-ghost",title:g(Et)==="dark"?g(h)("app.switchToLight"):g(h)("app.switchToDark"),onClick:E[1]||(E[1]=(...y)=>g(pi)&&g(pi)(...y))},[g(Et)==="dark"?(S(),C("svg",ff,[...E[3]||(E[3]=[d("circle",{cx:"12",cy:"12",r:"4"},null,-1),d("path",{"stroke-linecap":"round",d:"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"},null,-1)])])):(S(),C("svg",pf,[...E[4]||(E[4]=[d("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"},null,-1)])])),Ee(" "+b(g(h)("app.theme")),1)],8,df),g(Ot)?(S(),C("button",{key:2,class:"dh-btn-ghost",onClick:o},b(g(h)("app.signOut")),1)):B("",!0)]),t.value?(S(),C("p",hf,b(g(h)("app.loading")),1)):g(Ot)?(S(),C(ee,{key:2},[d("nav",gf,[(S(!0),C(ee,null,Se(n.value,y=>(S(),C("button",{key:y.id,class:Oe(["dh-btn-ghost",s.value===y.id?"border-accent text-brandtext":""]),onClick:$=>s.value=y.id},b(y.label),11,mf))),128))]),s.value==="overview"?(S(),ot(_c,{key:0})):s.value==="users"?(S(),ot(yd,{key:1})):s.value==="orgs"?(S(),ot(Ld,{key:2})):s.value==="pocketbase"?(S(),ot(Nc,{key:3})):s.value==="webapp"?(S(),ot(Qc,{key:4})):s.value==="plugins"?(S(),ot(Bu,{key:5})):s.value==="api"?(S(),C(ee,{key:6},[ue(it,{title:g(h)("api.groupPublic"),auth:g(h)("api.authNone"),endpoints:l},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupIdentity"),auth:g(h)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupCars"),auth:g(h)("api.authBearer"),endpoints:p},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupService"),auth:g(h)("api.authBearer"),endpoints:u},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupParts"),auth:g(h)("api.authBearer"),endpoints:m},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupAccount"),auth:g(h)("api.authBearer"),endpoints:P},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupManagement"),auth:g(h)("api.authManager"),endpoints:O},null,8,["title","auth"]),ue(it,{title:g(h)("api.groupSuperadmin"),auth:g(h)("api.authSuperadmin"),endpoints:F},null,8,["title","auth"])],64)):B("",!0),!g(gs)&&s.value==="overview"?(S(),C("p",bf,b(g(h)("app.standardUserNote")),1)):B("",!0)],64)):(S(),ot(lc,{key:1})),d("p",vf,b(g(h)("app.footer")),1)]))}};sa(_f).mount("#app"); diff --git a/API Server/internal/api/dist/index.html b/API Server/internal/api/dist/index.html index 1cb0f90..3e43359 100644 --- a/API Server/internal/api/dist/index.html +++ b/API Server/internal/api/dist/index.html @@ -6,7 +6,7 @@ DriverVault · API Server - + diff --git a/API Server/internal/api/me.go b/API Server/internal/api/me.go index afbb9d9..30cdbf3 100644 --- a/API Server/internal/api/me.go +++ b/API Server/internal/api/me.go @@ -33,6 +33,7 @@ type userRecord struct { FontSize string `json:"font_size"` DeletionRequestedAt string `json:"deletion_requested_at"` Role string `json:"role"` + Organization string `json:"organization"` Created string `json:"created"` } @@ -51,6 +52,8 @@ func (rec userRecord) toModel() models.User { FontSize: orDefault(rec.FontSize, "medium"), Role: orDefault(rec.Role, "user"), Created: rec.Created, + + Organization: rec.Organization, } if t := parsePBDate(rec.DeletionRequestedAt); !t.IsZero() { u.DeletionRequestedAt = &t @@ -65,6 +68,17 @@ func orDefault(v, fallback string) string { return v } +// profileOf builds the profile payload for a user record, resolving their +// organization's name so the clients can label the membership without a second +// round trip. The lookup is best effort — an unresolvable name leaves the id. +func (s *Server) profileOf(r *http.Request, rec *userRecord) models.User { + u := rec.toModel() + if u.Organization != "" { + u.OrganizationName = s.orgName(r.Context(), u.Organization) + } + return u +} + func (s *Server) fetchUser(r *http.Request, id string) (*userRecord, error) { var rec userRecord if err := s.pb.GetOne(r.Context(), s.usersCollection(), id, &rec); err != nil { @@ -84,7 +98,7 @@ func (s *Server) handleGetMe(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, rec)) } type updateMeRequest struct { @@ -181,7 +195,7 @@ func (s *Server) handleUpdateMe(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, &rec)) } type changePasswordRequest struct { @@ -256,7 +270,7 @@ func (s *Server) handleUploadAvatar(w http.ResponseWriter, r *http.Request) { writePBError(w, err) return } - writeJSON(w, http.StatusOK, rec.toModel()) + writeJSON(w, http.StatusOK, s.profileOf(r, rec)) } func (s *Server) handleDeleteAvatar(w http.ResponseWriter, r *http.Request) { diff --git a/API Server/internal/api/orgs.go b/API Server/internal/api/orgs.go index caa3d9d..ac863eb 100644 --- a/API Server/internal/api/orgs.go +++ b/API Server/internal/api/orgs.go @@ -81,8 +81,24 @@ func (s *Server) handleListOrgs(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"organizations": list.Items}) } -// POST /api/orgs — create an organization (superadmin only). Body: {name}. +// POST /api/orgs — create an organization. Body: {name}. A superadmin may create +// any number of organizations and is not attached to them (they manage every +// tenant centrally). Any other user may create one only if they don't already +// belong to an organization, and they become its admin and first member — the +// self-service path for standing up a new tenant. +// +// This handler carries no requireRole gate (any authenticated caller may reach +// it), so it checks the service account itself. func (s *Server) handleCreateOrg(w http.ResponseWriter, r *http.Request) { + if !s.pb.Configured() { + writeError(w, http.StatusServiceUnavailable, "organizations are not configured on the server") + return + } + who := caller(r) + if !who.isSuperadmin() && who.OrgID != "" { + writeError(w, http.StatusForbidden, "you already belong to an organization") + return + } name, ok := decodeOrgName(w, r) if !ok { return @@ -100,16 +116,42 @@ func (s *Server) handleCreateOrg(w http.ResponseWriter, r *http.Request) { } var org orgView _ = json.Unmarshal(data, &org) + + // A non-superadmin creator becomes the admin of, and first member of, the org + // they just made. If that promotion fails, roll the org back so we never leave + // a stranded organization that nobody can administer. + if !who.isSuperadmin() { + data, status, err = s.pb.Raw(r.Context(), http.MethodPatch, + "/api/collections/"+s.usersCollection()+"/records/"+url.PathEscape(who.ID), + map[string]any{"organization": org.ID, "role": roleAdmin}) + if err != nil || status != http.StatusOK { + _, _, _ = s.pb.Raw(r.Context(), http.MethodDelete, + "/api/collections/"+colOrgs+"/records/"+url.PathEscape(org.ID), nil) + if err != nil { + writeUpstreamDown(w, err) + return + } + relay(w, status, data) + return + } + } writeJSON(w, http.StatusCreated, map[string]any{"organization": org}) } -// PATCH /api/orgs/{id} — rename an organization (superadmin only). Body: {name}. +// PATCH /api/orgs/{id} — rename an organization (manager only). A superadmin may +// rename any organization; an admin may rename only their own. Body: {name}. func (s *Server) handleUpdateOrg(w http.ResponseWriter, r *http.Request) { + who := caller(r) id := r.PathValue("id") if id == "" { writeError(w, http.StatusBadRequest, "missing organization id") return } + // An admin is scoped to their own organization; a superadmin spans all. + if !who.isSuperadmin() && (who.OrgID == "" || id != who.OrgID) { + writeError(w, http.StatusForbidden, "you can only rename your own organization") + return + } name, ok := decodeOrgName(w, r) if !ok { return @@ -129,18 +171,35 @@ func (s *Server) handleUpdateOrg(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"organization": org}) } -// DELETE /api/orgs/{id} — delete an organization (superadmin only). Refused -// while the org still has members, to avoid silently orphaning users. +// DELETE /api/orgs/{id} — delete an organization (manager only). A superadmin may +// delete any organization, but only once it has no members. An admin may delete +// only their own organization, and only when they are its sole member: the admin +// is detached and demoted back to a plain user, then the org is removed. Either +// path refuses to silently orphan other members. func (s *Server) handleDeleteOrg(w http.ResponseWriter, r *http.Request) { + who := caller(r) id := r.PathValue("id") if id == "" { writeError(w, http.StatusBadRequest, "missing organization id") return } - // Guard: block deletion if any user still belongs to this org. + // Count the members that block deletion. A superadmin is blocked by anyone at + // all; an admin deleting their own org is blocked only by *other* members, + // since they detach themselves below. + filter := "organization = \"" + id + "\"" + blocked := "organization still has members; reassign or remove them first" + if !who.isSuperadmin() { + // An admin is scoped to their own organization. + if who.OrgID == "" || id != who.OrgID { + writeError(w, http.StatusForbidden, "you can only delete your own organization") + return + } + filter += " && id != \"" + who.ID + "\"" + blocked = "organization still has other members; reassign or remove them first" + } countPath := "/api/collections/" + s.usersCollection() + "/records?perPage=1&fields=id&filter=" + - url.QueryEscape("organization = \""+id+"\"") + url.QueryEscape(filter) data, status, err := s.pb.Raw(r.Context(), http.MethodGet, countPath, nil) if err != nil { writeUpstreamDown(w, err) @@ -152,7 +211,25 @@ func (s *Server) handleDeleteOrg(w http.ResponseWriter, r *http.Request) { } _ = json.Unmarshal(data, &page) if page.TotalItems > 0 { - writeError(w, http.StatusConflict, "organization still has members; reassign or remove them first") + writeError(w, http.StatusConflict, blocked) + return + } + } + + // Detach and demote the admin so the org is empty before it is removed. Done + // before the delete because users.organization does not cascade: a failed + // delete leaves an empty org a superadmin can clean up, which beats leaving a + // member pointing at an organization that no longer exists. + if !who.isSuperadmin() { + data, status, err = s.pb.Raw(r.Context(), http.MethodPatch, + "/api/collections/"+s.usersCollection()+"/records/"+url.PathEscape(who.ID), + map[string]any{"organization": "", "role": roleUser}) + if err != nil { + writeUpstreamDown(w, err) + return + } + if status != http.StatusOK { + relay(w, status, data) return } } diff --git a/API Server/internal/api/orgs_test.go b/API Server/internal/api/orgs_test.go new file mode 100644 index 0000000..4aeb427 --- /dev/null +++ b/API Server/internal/api/orgs_test.go @@ -0,0 +1,333 @@ +package api + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "sync" + "testing" + + "drivervault/apiserver/internal/config" + "drivervault/apiserver/internal/pb" +) + +// These tests cover the self-service organization flows through the real +// Handler + middleware chain: an org-less user creating an org and being +// promoted to its admin (including the rollback when that promotion fails), and +// an admin renaming or deleting only their own organization. A stand-in +// PocketBase (orgFakePB) serves exactly the endpoints those paths hit. + +const ( + orgTestUserID = "u1" + orgTestBearer = "user-bearer-token" + orgTestNewID = "neworg1" +) + +// orgFakePB answers the identity, organization and user-record calls the org +// handlers make, and records the writes so tests can assert on them. +type orgFakePB struct { + mu sync.Mutex + + // Identity returned by auth-refresh. + callerRole string + callerOrg string + + // Behaviour switches. + userPatchStatus int // status for a caller promotion/demotion (200 when 0) + memberCount int // totalItems for the blocking-member query + + // Recorded effects. + createdOrgs []string + orgPatches []map[string]any + orgDeletes []string + userPatches []map[string]any +} + +func (f *orgFakePB) handler(t *testing.T) http.Handler { + t.Helper() + mux := http.NewServeMux() + + // Service-account auth (pb.Client.Authenticate). + mux.HandleFunc("POST /api/collections/_superusers/auth-with-password", func(w http.ResponseWriter, r *http.Request) { + writeJSON(w, 200, map[string]any{"token": "svc-token"}) + }) + + // Identify the bearer (withAuth → identify → AuthRefresh). + mux.HandleFunc("POST /api/collections/users/auth-refresh", func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("Authorization") == "" { + writeJSON(w, 401, map[string]any{}) + return + } + f.mu.Lock() + defer f.mu.Unlock() + writeJSON(w, 200, map[string]any{"record": map[string]any{ + "id": orgTestUserID, "email": "owner@test.local", "name": "Owner", + "role": f.callerRole, "organization": f.callerOrg, + }}) + }) + + // Organization create / rename / delete. + mux.HandleFunc("POST /api/collections/organizations/records", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.createdOrgs = append(f.createdOrgs, orgTestNewID) + f.mu.Unlock() + writeJSON(w, 200, map[string]any{"id": orgTestNewID, "name": body["name"], "created": "2026-08-17 10:00:00Z"}) + }) + mux.HandleFunc("PATCH /api/collections/organizations/records/{id}", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.orgPatches = append(f.orgPatches, body) + f.mu.Unlock() + writeJSON(w, 200, map[string]any{"id": r.PathValue("id"), "name": body["name"]}) + }) + mux.HandleFunc("DELETE /api/collections/organizations/records/{id}", func(w http.ResponseWriter, r *http.Request) { + f.mu.Lock() + f.orgDeletes = append(f.orgDeletes, r.PathValue("id")) + f.mu.Unlock() + writeJSON(w, 204, nil) + }) + + // Blocking-member count for a delete. + mux.HandleFunc("GET /api/collections/users/records", func(w http.ResponseWriter, r *http.Request) { + f.mu.Lock() + defer f.mu.Unlock() + writeJSON(w, 200, map[string]any{"totalItems": f.memberCount, "items": []any{}}) + }) + + // Caller promotion / demotion. + mux.HandleFunc("PATCH /api/collections/users/records/{id}", func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + _ = json.NewDecoder(r.Body).Decode(&body) + f.mu.Lock() + f.userPatches = append(f.userPatches, body) + status := f.userPatchStatus + f.mu.Unlock() + if status != 0 && status != 200 { + writeJSON(w, status, map[string]any{"message": "cannot update user"}) + return + } + writeJSON(w, 200, map[string]any{"id": r.PathValue("id")}) + }) + + return mux +} + +// newOrgTestServer wires the fake PocketBase to a real Handler and returns the +// app's base URL. +func newOrgTestServer(t *testing.T, f *orgFakePB) string { + t.Helper() + pbSrv := httptest.NewServer(f.handler(t)) + t.Cleanup(pbSrv.Close) + + s := New(config.Config{UsersCollection: "users"}, pb.New(pbSrv.URL, "admin@test.local", "pw")) + appSrv := httptest.NewServer(s.Handler()) + t.Cleanup(appSrv.Close) + return appSrv.URL +} + +// orgReq issues an authenticated request and returns the status and decoded body. +func orgReq(t *testing.T, base, method, path string, body any) (int, map[string]any) { + t.Helper() + var buf bytes.Buffer + if body != nil { + if err := json.NewEncoder(&buf).Encode(body); err != nil { + t.Fatal(err) + } + } + req, err := http.NewRequest(method, base+path, &buf) + if err != nil { + t.Fatal(err) + } + req.Header.Set("Authorization", "Bearer "+orgTestBearer) + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + out := map[string]any{} + _ = json.NewDecoder(resp.Body).Decode(&out) + return resp.StatusCode, out +} + +func TestCreateOrgPromotesCreatorToAdmin(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Acme Inc."}) + if status != http.StatusCreated { + t.Fatalf("status = %d, want 201 (body %v)", status, body) + } + org, _ := body["organization"].(map[string]any) + if org["id"] != orgTestNewID || org["name"] != "Acme Inc." { + t.Fatalf("organization = %v, want id %q name %q", org, orgTestNewID, "Acme Inc.") + } + + if len(f.userPatches) != 1 { + t.Fatalf("user patches = %d, want 1 (%v)", len(f.userPatches), f.userPatches) + } + patch := f.userPatches[0] + if patch["organization"] != orgTestNewID { + t.Errorf("patched organization = %v, want %q", patch["organization"], orgTestNewID) + } + if patch["role"] != roleAdmin { + t.Errorf("patched role = %v, want %q", patch["role"], roleAdmin) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org was rolled back unexpectedly: %v", f.orgDeletes) + } +} + +func TestCreateOrgRejectedWhenCallerAlreadyHasOne(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "existing1"} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Second Org"}) + if status != http.StatusForbidden { + t.Fatalf("status = %d, want 403 (body %v)", status, body) + } + if len(f.createdOrgs) != 0 { + t.Errorf("created orgs = %v, want none", f.createdOrgs) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none", f.userPatches) + } +} + +// A superadmin manages every tenant centrally, so creating one must not move +// them into it or change their role. +func TestCreateOrgLeavesSuperadminUnattached(t *testing.T) { + f := &orgFakePB{callerRole: roleSuperadmin, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Tenant A"}) + if status != http.StatusCreated { + t.Fatalf("status = %d, want 201 (body %v)", status, body) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none for a superadmin", f.userPatches) + } +} + +// If the creator cannot be promoted, the new org must not survive — otherwise it +// is stranded with nobody able to administer it. +func TestCreateOrgRollsBackWhenPromotionFails(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "", userPatchStatus: http.StatusBadRequest} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": "Doomed"}) + if status == http.StatusCreated { + t.Fatalf("status = %d, want a failure", status) + } + if len(f.orgDeletes) != 1 || f.orgDeletes[0] != orgTestNewID { + t.Errorf("org deletes = %v, want rollback of %q", f.orgDeletes, orgTestNewID) + } +} + +func TestCreateOrgRejectsBadName(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: ""} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodPost, "/api/orgs", map[string]any{"name": " "}) + if status != http.StatusBadRequest { + t.Fatalf("status = %d, want 400", status) + } + if len(f.createdOrgs) != 0 { + t.Errorf("created orgs = %v, want none", f.createdOrgs) + } +} + +func TestUpdateOrgAdminScopedToOwnOrg(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + // Someone else's organization is off limits. + status, _ := orgReq(t, base, http.MethodPatch, "/api/orgs/o2", map[string]any{"name": "Hijack"}) + if status != http.StatusForbidden { + t.Fatalf("foreign org status = %d, want 403", status) + } + if len(f.orgPatches) != 0 { + t.Fatalf("org patches = %v, want none", f.orgPatches) + } + + // Their own is fine. + status, body := orgReq(t, base, http.MethodPatch, "/api/orgs/o1", map[string]any{"name": "Renamed"}) + if status != http.StatusOK { + t.Fatalf("own org status = %d, want 200 (body %v)", status, body) + } + if len(f.orgPatches) != 1 || f.orgPatches[0]["name"] != "Renamed" { + t.Errorf("org patches = %v, want one rename to %q", f.orgPatches, "Renamed") + } +} + +// An admin deleting their own org is detached and demoted first, so the org is +// empty by the time it is removed. +func TestDeleteOrgAdminSoleMemberIsDetachedAndDemoted(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1", memberCount: 0} + base := newOrgTestServer(t, f) + + status, body := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil) + if status != http.StatusOK { + t.Fatalf("status = %d, want 200 (body %v)", status, body) + } + if len(f.userPatches) != 1 { + t.Fatalf("user patches = %d, want 1 (%v)", len(f.userPatches), f.userPatches) + } + patch := f.userPatches[0] + if patch["organization"] != "" { + t.Errorf("patched organization = %v, want cleared", patch["organization"]) + } + if patch["role"] != roleUser { + t.Errorf("patched role = %v, want %q", patch["role"], roleUser) + } + if len(f.orgDeletes) != 1 || f.orgDeletes[0] != "o1" { + t.Errorf("org deletes = %v, want [o1]", f.orgDeletes) + } +} + +func TestDeleteOrgBlockedByOtherMembers(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1", memberCount: 2} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil) + if status != http.StatusConflict { + t.Fatalf("status = %d, want 409", status) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org deletes = %v, want none", f.orgDeletes) + } + if len(f.userPatches) != 0 { + t.Errorf("user patches = %v, want none — the admin must stay put", f.userPatches) + } +} + +func TestDeleteOrgAdminCannotDeleteForeignOrg(t *testing.T) { + f := &orgFakePB{callerRole: roleAdmin, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o2", nil) + if status != http.StatusForbidden { + t.Fatalf("status = %d, want 403", status) + } + if len(f.orgDeletes) != 0 { + t.Errorf("org deletes = %v, want none", f.orgDeletes) + } +} + +// A plain user is not a manager, so rename/delete stay closed to them even for +// the org they belong to. +func TestPlainUserCannotManageOrgs(t *testing.T) { + f := &orgFakePB{callerRole: roleUser, callerOrg: "o1"} + base := newOrgTestServer(t, f) + + if status, _ := orgReq(t, base, http.MethodPatch, "/api/orgs/o1", map[string]any{"name": "Nope"}); status != http.StatusForbidden { + t.Errorf("rename status = %d, want 403", status) + } + if status, _ := orgReq(t, base, http.MethodDelete, "/api/orgs/o1", nil); status != http.StatusForbidden { + t.Errorf("delete status = %d, want 403", status) + } +} diff --git a/API Server/internal/api/server.go b/API Server/internal/api/server.go index 6742d93..144fc49 100644 --- a/API Server/internal/api/server.go +++ b/API Server/internal/api/server.go @@ -28,7 +28,7 @@ // GET /api/me/export POST /api/me/import // POST /api/me/delete POST /api/me/delete/cancel // -// # users + organizations (manager; writes to orgs are superadmin-only) +// # users + organizations (manager; POST /api/orgs is open to any user) // GET /api/users POST /api/users // PATCH /api/users/{id} DELETE /api/users/{id} // GET /api/orgs POST /api/orgs @@ -285,12 +285,15 @@ func (s *Server) Handler() http.Handler { mux.HandleFunc("PATCH /api/users/{id}", s.requireManager(s.handleUpdateUser)) mux.HandleFunc("DELETE /api/users/{id}", s.requireManager(s.handleDeleteUser)) - // Organizations — listing is manager-scoped; create/edit/delete are - // superadmin-only (a superadmin spans all organizations). + // Organizations — the tenants users belong to. Listing is manager-scoped (an + // admin sees only their own org). Any org-less user may create an org and + // becomes its admin; an admin may rename or delete their own org; a superadmin + // spans every organization. Create carries no role gate, so it checks the + // service account itself. mux.HandleFunc("GET /api/orgs", s.requireManager(s.handleListOrgs)) - mux.HandleFunc("POST /api/orgs", s.requireSuperadmin(s.handleCreateOrg)) - mux.HandleFunc("PATCH /api/orgs/{id}", s.requireSuperadmin(s.handleUpdateOrg)) - mux.HandleFunc("DELETE /api/orgs/{id}", s.requireSuperadmin(s.handleDeleteOrg)) + mux.HandleFunc("POST /api/orgs", s.handleCreateOrg) + mux.HandleFunc("PATCH /api/orgs/{id}", s.requireManager(s.handleUpdateOrg)) + mux.HandleFunc("DELETE /api/orgs/{id}", s.requireManager(s.handleDeleteOrg)) // PocketBase connection settings — superadmin only. These do NOT require the // service account to already be configured (they exist to configure it). diff --git a/API Server/internal/models/models.go b/API Server/internal/models/models.go index 47f8407..bc1231b 100644 --- a/API Server/internal/models/models.go +++ b/API Server/internal/models/models.go @@ -335,6 +335,11 @@ type User struct { FontSize string `json:"fontSize"` // small | medium | large Role string `json:"role"` // user | admin + // Organization membership. Empty when the user belongs to no organization — + // the clients use that to offer creating one (which makes them its admin). + Organization string `json:"organization"` + OrganizationName string `json:"organizationName,omitempty"` + // Non-empty while an account-deletion request is pending its cooldown. DeletionRequestedAt *time.Time `json:"deletionRequestedAt,omitempty"` diff --git a/API Server/panel/src/App.vue b/API Server/panel/src/App.vue index 055ca68..9b17f0a 100644 --- a/API Server/panel/src/App.vue +++ b/API Server/panel/src/App.vue @@ -26,7 +26,14 @@ onMounted(async () => { const sections = computed(() => { const out = [{ id: "overview", label: t("sections.overview") }]; if (isManager.value) { - out.push({ id: "users", label: t("sections.users") }, { id: "orgs", label: t("sections.orgs") }); + out.push({ id: "users", label: t("sections.users") }); + } + // Organizations is open to everyone: a manager sees the org(s) they manage, + // and an org-less user gets the form that stands one up (making them its + // admin). Only a caller with neither an org nor a manager role sees nothing + // to do there, and they still get the create form. + if (isManager.value || me.value) { + out.push({ id: "orgs", label: t("sections.orgs") }); } if (isSuperadmin.value) { out.push( @@ -129,9 +136,9 @@ const managementApi = [ { method: "PATCH", path: "/api/users/{id}", desc: "Update email / name / role / org / password" }, { method: "DELETE", path: "/api/users/{id}", desc: "Delete a user" }, { method: "GET", path: "/api/orgs", desc: "List organizations" }, - { method: "POST", path: "/api/orgs", desc: "Create an organization (superadmin)" }, - { method: "PATCH", path: "/api/orgs/{id}", desc: "Rename an organization (superadmin)" }, - { method: "DELETE", path: "/api/orgs/{id}", desc: "Delete an organization (superadmin)" }, + { method: "POST", path: "/api/orgs", desc: "Create an organization (any user without one; creator becomes admin)" }, + { method: "PATCH", path: "/api/orgs/{id}", desc: "Rename an organization (own org; any as superadmin)" }, + { method: "DELETE", path: "/api/orgs/{id}", desc: "Delete an organization (own org; any as superadmin)" }, ]; const superadminApi = [ diff --git a/API Server/panel/src/components/OrgsCard.vue b/API Server/panel/src/components/OrgsCard.vue index 7ae4227..7795d9e 100644 --- a/API Server/panel/src/components/OrgsCard.vue +++ b/API Server/panel/src/components/OrgsCard.vue @@ -1,17 +1,31 @@ + + diff --git a/Web App/web/src/i18n/da.json b/Web App/web/src/i18n/da.json index 5628a95..6524c8d 100644 --- a/Web App/web/src/i18n/da.json +++ b/Web App/web/src/i18n/da.json @@ -108,7 +108,7 @@ "title": "Brugere", "subtitleAll": "Konti på tværs af alle organisationer.", "subtitleOrg": "Konti i din organisation.", - "subtitleOrgsNote": "Organisationer tildeles i API-panelet.", + "subtitleOrgsNote": "Organisationer administreres under Indstillinger.", "addUser": "Tilføj bruger", "colEmail": "E-mail", "colName": "Navn", @@ -199,6 +199,23 @@ "saveBio": "Gem beskrivelse" }, + "org": { + "title": "Organisation", + "titleAll": "Organisationer", + "subtitleOwn": "Den organisation du administrerer", + "subtitleNone": "Opret en for at administrere dit eget team", + "subtitleAll": "Enheder, som brugere tilhører", + "nameLabel": "Organisationsnavn", + "namePlaceholder": "Acme Fleet", + "newOrg": "Ny organisation", + "create": "Opret organisation", + "createHint": "Du bliver dens administrator og kan derefter tilføje og administrere brugere.", + "rename": "Omdøb", + "empty": "Ingen organisationer endnu.", + "confirmDelete": "Slet organisationen „{name}“? Dette kan ikke fortrydes.", + "confirmDeleteOwn": "Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger. Dette kan ikke fortrydes." + }, + "privacy": { "title": "Privatliv og sikkerhed", "signOut": "Log ud", diff --git a/Web App/web/src/i18n/en.json b/Web App/web/src/i18n/en.json index 544329e..75d7fbf 100644 --- a/Web App/web/src/i18n/en.json +++ b/Web App/web/src/i18n/en.json @@ -126,7 +126,7 @@ "title": "Users", "subtitleAll": "Accounts across every organization.", "subtitleOrg": "Accounts in your organization.", - "subtitleOrgsNote": "Organizations are assigned in the API panel.", + "subtitleOrgsNote": "Organizations are managed in Settings.", "addUser": "Add user", "colEmail": "Email", "colName": "Name", @@ -274,6 +274,23 @@ "controlDisconnected": "Not connected" }, + "org": { + "title": "Organization", + "titleAll": "Organizations", + "subtitleOwn": "The organization you administer", + "subtitleNone": "Create one to manage your own team", + "subtitleAll": "Tenants users belong to", + "nameLabel": "Organization name", + "namePlaceholder": "Acme Fleet", + "newOrg": "New organization", + "create": "Create organization", + "createHint": "You'll become its admin and can then add and manage users.", + "rename": "Rename", + "empty": "No organizations yet.", + "confirmDelete": "Delete the organization “{name}”? This cannot be undone.", + "confirmDeleteOwn": "Delete your organization “{name}”? You'll be removed from it and become a regular user. This cannot be undone." + }, + "privacy": { "title": "Privacy & security", "signOut": "Sign out", diff --git a/Web App/web/src/i18n/pl.json b/Web App/web/src/i18n/pl.json index cc4c1be..d5eb4e1 100644 --- a/Web App/web/src/i18n/pl.json +++ b/Web App/web/src/i18n/pl.json @@ -112,7 +112,7 @@ "title": "Użytkownicy", "subtitleAll": "Konta ze wszystkich organizacji.", "subtitleOrg": "Konta w Twojej organizacji.", - "subtitleOrgsNote": "Organizacje przypisuje się w panelu API.", + "subtitleOrgsNote": "Organizacjami zarządza się w Ustawieniach.", "addUser": "Dodaj użytkownika", "colEmail": "E-mail", "colName": "Imię i nazwisko", @@ -203,6 +203,23 @@ "saveBio": "Zapisz opis" }, + "org": { + "title": "Organizacja", + "titleAll": "Organizacje", + "subtitleOwn": "Organizacja, którą administrujesz", + "subtitleNone": "Utwórz ją, aby zarządzać własnym zespołem", + "subtitleAll": "Podmioty, do których należą użytkownicy", + "nameLabel": "Nazwa organizacji", + "namePlaceholder": "Acme Fleet", + "newOrg": "Nowa organizacja", + "create": "Utwórz organizację", + "createHint": "Zostaniesz jej administratorem i będziesz móc dodawać użytkowników oraz nimi zarządzać.", + "rename": "Zmień nazwę", + "empty": "Brak organizacji.", + "confirmDelete": "Usunąć organizację „{name}”? Tego nie można cofnąć.", + "confirmDeleteOwn": "Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem. Tego nie można cofnąć." + }, + "privacy": { "title": "Prywatność i bezpieczeństwo", "signOut": "Wyloguj się", diff --git a/Web App/web/src/views/Settings.vue b/Web App/web/src/views/Settings.vue index d123486..ab99d35 100644 --- a/Web App/web/src/views/Settings.vue +++ b/Web App/web/src/views/Settings.vue @@ -6,6 +6,7 @@ import { state, logout, refreshProfile } from "../auth"; import { prefs, applyProfilePrefs } from "../prefs"; import { formatDate, formatMoney } from "../lib/format.js"; import { t, tSplit, TRANSLATED_LANGUAGES } from "../i18n"; +import OrgManager from "../components/OrgManager.vue"; const router = useRouter(); @@ -1258,6 +1259,9 @@ onBeforeUnmount(() => {
+ + +