diff --git a/API Server/internal/api/dist/assets/index-CvNOI6h4.js b/API Server/internal/api/dist/assets/index-BBZfstAT.js similarity index 87% rename from API Server/internal/api/dist/assets/index-CvNOI6h4.js rename to API Server/internal/api/dist/assets/index-BBZfstAT.js index a94e9a9..f7e7246 100644 --- a/API Server/internal/api/dist/assets/index-CvNOI6h4.js +++ b/API Server/internal/api/dist/assets/index-BBZfstAT.js @@ -14,4 +14,4 @@ * @vue/runtime-dom v3.5.39 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT -**/let an;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{an=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=an?e=>an.createHTML(e):e=>e,ka="http://www.w3.org/2000/svg",Ta="http://www.w3.org/1998/Math/MathML",tt=typeof document<"u"?document:null,Qn=tt&&tt.createElement("template"),Sa={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"?tt.createElementNS(ka,e):t==="mathml"?tt.createElementNS(Ta,e):s?tt.createElement(e,{is:s}):tt.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>tt.createTextNode(e),createComment:e=>tt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>tt.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=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const a=Qn.content;if(n==="svg"||n==="mathml"){const l=a.firstChild;for(;l.firstChild;)a.appendChild(l.firstChild);a.removeChild(l)}t.insertBefore(a,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Ea=Symbol("_vtc");function Pa(e,t,s){const n=e[Ea];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Ca=Symbol("_vsh"),Aa=Symbol(""),$a=/(?:^|;)\s*display\s*:/;function Oa(e,t,s){const n=e.style,i=ue(s);let o=!1;if(s&&!i){if(t)if(ue(t))for(const r of t.split(";")){const a=r.slice(0,r.indexOf(":")).trim();s[a]==null&&Ft(n,a,"")}else for(const r in t)s[r]==null&&Ft(n,r,"");for(const r in s){r==="display"&&(o=!0);const a=s[r];a!=null?Ra(e,r,!ue(t)&&t?t[r]:void 0,a)||Ft(n,r,a):Ft(n,r,"")}}else if(i){if(t!==s){const r=n[Aa];r&&(s+=";"+r),n.cssText=s,o=$a.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Ca]&&(n.display="none"))}const ti=/\s*!important$/;function Ft(e,t,s){if(L(s))s.forEach(n=>Ft(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Da(e,t);ti.test(s)?e.setProperty(ft(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Da(e,t){const s=qs[t];if(s)return s;let n=je(t);if(n!=="filter"&&n in e)return qs[t]=n;n=_i(n);for(let i=0;iZs||(Ma.then(()=>Zs=0),Zs=Date.now());function Fa(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(),a=[n];for(let l=0;le.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ba=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?Pa(e,n,r):t==="style"?Oa(e,s,n):Ss(t)?Es(t)||Ia(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ha(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&&(Va(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ue(n)))?oi(e,je(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Ha(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&ai(t)&&W(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 ai(t)&&ue(s)?!1:t in e}function Va(e,t){const s=e._def.props;if(!s)return!1;const n=je(t);return Array.isArray(s)?s.some(i=>je(i)===n):Object.keys(s).some(i=>je(i)===n)}const pt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return L(t)?s=>ps(t,s):t};function Ga(e){e.target.composing=!0}function li(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ie=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=Cs(e)),e}const be={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ie]=pt(i);const o=n||i.props&&i.props.type==="number";ot(e,t?"change":"input",r=>{r.target.composing||e[Ie](ci(e.value,s,o))}),(s||o)&&ot(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(ot(e,"compositionstart",Ga),ot(e,"compositionend",li),ot(e,"change",li))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ie]=pt(r),e.composing)return;const a=(o||e.type==="number")&&!/^0\d/.test(e.value)?Cs(e.value):e.value,l=t??"";if(a===l)return;const g=e.getRootNode();(g instanceof Document||g instanceof ShadowRoot)&&g.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===l)||(e.value=l)}},Ka={deep:!0,created(e,t,s){e[Ie]=pt(s),ot(e,"change",()=>{const n=e._modelValue,i=Ot(e),o=e.checked,r=e[Ie];if(L(n)){const a=fn(n,i),l=a!==-1;if(o&&!l)r(n.concat(i));else if(!o&&l){const g=[...n];g.splice(a,1),r(g)}}else if(zt(n)){const a=new Set(n);o?a.add(i):a.delete(i),r(a)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Ie]=pt(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(L(t))i=fn(t,n.props.value)>-1;else if(zt(t))i=t.has(n.props.value);else{if(t===s)return;i=ut(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wa={created(e,{value:t},s){e.checked=ut(t,s.props.value),e[Ie]=pt(s),ot(e,"change",()=>{e[Ie](Ot(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ie]=pt(n),t!==s&&(e.checked=ut(t,n.props.value))}},ks={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=zt(t);ot(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Cs(Ot(r)):Ot(r));e[Ie](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Ie]=pt(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Ie]=pt(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=L(t);if(!(s&&!n&&!zt(t))){for(let i=0,o=e.options.length;iString(g)===String(a)):r.selected=fn(t,a)>-1}else r.selected=t.has(a);else if(ut(Ot(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Ot(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 qa={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 Za(e,t){switch(e){case"SELECT":return ks;case"TEXTAREA":return be;default:switch(t){case"checkbox":return Ka;case"radio":return Wa;default:return be}}}function ds(e,t,s,n,i){const r=Za(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Ja=["ctrl","shift","alt","meta"],Ya={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)=>Ja.some(s=>e[`${s}Key`]&&!t.includes(s))},Xa=(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=ft(i.key);if(t.some(r=>r===o||Qa[r]===o))return e(i)}))},el=_e({patchProp:Ba},Sa);let pi;function tl(){return pi||(pi=ia(el))}const sl=((...e)=>{const t=tl().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=il(n);if(!i)return;const o=t._component;!W(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,nl(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function nl(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function il(e){return ue(e)?document.querySelector(e):e}const ko="dh-panel-theme";function ol(){var e;try{const t=localStorage.getItem(ko);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Ct=H(ol());function To(e){Ct.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(ko,e)}catch{}}function fi(){To(Ct.value==="dark"?"light":"dark")}To(Ct.value);const rl={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."},al={overview:"Overview",users:"Users",orgs:"Organizations",server:"API Server",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},ll={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"},cl={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ul={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},dl={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."},pl={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.'},fl={title:"API Server",subtitle:"How this server identifies itself to the clients that connect to it",name:"Server name",nameHint:"Shown by clients that can be pointed at more than one DriverVault, such as the Web App's server switcher. Reported by /api/health.",saveApply:"Save & apply",persistedEnv:"persisted to .env",savedNotice:"Saved. The new name applies to the next request."},hl={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."},gl={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."},ml={title:"Plugins",subtitle:"Third-party service integrations",categories:{vehicles:"Car manufacturers",chargers:"EV chargers",notifications:"Notifications","apis-external":"Other APIs","drives-external":"Remote drives","drives-local":"Local drives"},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.'},bl={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Charger credentials",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupTechnical:"Technical checks",groupParts:"Parts",groupFuel:"Fuel",groupCharging:"Charging",groupMaintenance:"Maintenance",groupDocuments:"Documents",groupReminders:"Reminders",groupAttachments:"Attachments",groupProviders:"Vehicle providers",groupIntegrations:"Integrations",groupOcpp:"OCPP",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},vl={app:rl,sections:al,login:ll,status:cl,common:ul,users:dl,orgs:pl,server:fl,pocketbase:hl,webapp:gl,plugins:ml,api:bl},yl={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."},_l={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",server:"Serwer API",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},wl={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"},xl={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},kl={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},Tl={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ąć."},Sl={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."},El={title:"Serwer API",subtitle:"Jak ten serwer przedstawia się klientom, które się z nim łączą",name:"Nazwa serwera",nameHint:"Widoczna w klientach, które można skierować na więcej niż jeden DriverVault, na przykład w przełączniku serwerów aplikacji webowej. Zwracana przez /api/health.",saveApply:"Zapisz i zastosuj",persistedEnv:"zapisano w .env",savedNotice:"Zapisano. Nowa nazwa obowiązuje od następnego żądania."},Pl={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."},Cl={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."},Al={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",categories:{vehicles:"Producenci samochodów",chargers:"Ładowarki EV",notifications:"Powiadomienia","apis-external":"Pozostałe API","drives-external":"Dyski zdalne","drives-local":"Dyski lokalne"},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."},$l={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",authCharger:"Dane logowania ładowarki",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupTechnical:"Przeglądy techniczne",groupParts:"Części",groupFuel:"Paliwo",groupCharging:"Ładowanie",groupMaintenance:"Naprawy",groupDocuments:"Dokumenty",groupReminders:"Przypomnienia",groupAttachments:"Załączniki",groupProviders:"Dostawcy pojazdów",groupIntegrations:"Integracje",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},Ol={app:yl,sections:_l,login:wl,status:xl,common:kl,users:Tl,orgs:Sl,server:El,pocketbase:Pl,webapp:Cl,plugins:Al,api:$l},Dl={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."},Rl={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",server:"API-server",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},zl={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"},Il={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},jl={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},Ul={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."},Nl={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."},Ml={title:"API-server",subtitle:"Hvordan denne server identificerer sig over for de klienter, der forbinder til den",name:"Servernavn",nameHint:"Vises af klienter, der kan pege på mere end én DriverVault, for eksempel webappens serverskifter. Returneres af /api/health.",saveApply:"Gem og anvend",persistedEnv:"gemt i .env",savedNotice:"Gemt. Det nye navn gælder fra næste anmodning."},Ll={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."},Fl={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."},Bl={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",categories:{vehicles:"Bilproducenter",chargers:"EV-ladere",notifications:"Notifikationer","apis-external":"Øvrige API'er","drives-external":"Eksterne drev","drives-local":"Lokale drev"},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.'},Hl={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Laderens loginoplysninger",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupTechnical:"Syn",groupParts:"Reservedele",groupFuel:"Brændstof",groupCharging:"Opladning",groupMaintenance:"Værksted",groupDocuments:"Dokumenter",groupReminders:"Påmindelser",groupAttachments:"Vedhæftede filer",groupProviders:"Køretøjsudbydere",groupIntegrations:"Integrationer",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Vl={app:Dl,sections:Rl,login:zl,status:Il,common:jl,users:Ul,orgs:Nl,server:Ml,pocketbase:Ll,webapp:Fl,plugins:Bl,api:Hl},So="dh-panel-lang",Eo="en",Dt={en:vl,pl:Ol,da:Vl},Gl=Object.keys(Dt);function Kl(){try{const t=localStorage.getItem(So);if(t&&Dt[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return Dt[e]?e:Eo}const En=H(Kl());function Wl(e){if(Dt[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 ql(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Zl(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 f(e,t){const s=En.value;let n=hi(Dt[s],e);if(n==null&&(n=hi(Dt[Eo],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Zl(n,t.n,s)}return typeof n!="string"?e:ql(n,t)}function gi(e,t,s){const i=f(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 ln="dh-panel-token";function Jl(){try{return localStorage.getItem(ln)||""}catch{return""}}const Rt=H(Jl()),he=H(null),De=Oe(()=>{var e;return((e=he.value)==null?void 0:e.role)==="superadmin"}),gs=Oe(()=>{var e,t;return((e=he.value)==null?void 0:e.role)==="admin"||((t=he.value)==null?void 0:t.role)==="superadmin"});function Po(e){Rt.value=e;try{e?localStorage.setItem(ln,e):localStorage.removeItem(ln)}catch{}}class Yl extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Xl(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 ae(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Rt.value&&(i.Authorization=Rt.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let a=null;try{a=r?JSON.parse(r):null}catch{a=null}if(!o.ok)throw o.status===401&&n&&Pn(),new Yl(Xl(a,o.status),o.status,a);return a}async function Ql(e,t){const s=await ae("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Po(s.token),await Ts(),he.value}async function Ts(){return he.value=await ae("/api/identity"),he.value}function Pn(){Po(""),he.value=null}async function ec(){if(!Rt.value)return null;try{return await Ts()}catch{return Pn(),null}}const tc={class:"inline-flex items-center gap-2.5 select-none"},sc={class:"h-full w-auto shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},nc={transform:"translate(7 0) skewX(-13)"},ic=["fill"],oc=["fill"],rc=["fill"],ac={key:0,class:"text-[1.35em] font-extrabold italic leading-none tracking-[-0.03em]"},lc={__name:"Logo",props:{iconOnly:{type:Boolean,default:!1},onDark:{type:Boolean,default:!1}},setup(e){return(t,s)=>(y(),T("span",tc,[(y(),T("svg",sc,[u("g",nc,[u("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:e.onDark?"#60A5FA":"var(--brand-700)"},null,8,ic),u("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:e.onDark?"#93C5FD":"var(--brand-500)"},null,8,oc),u("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:e.onDark?"#ffffff":"var(--brand-400)"},null,8,rc)])])),e.iconOnly?F("",!0):(y(),T("span",ac,[u("span",{class:Ee(e.onDark?"text-white":"text-strong")},"Driver",2),u("span",{class:Ee(e.onDark?"text-brand-400":"text-brandtext")},"Vault",2)])),s[0]||(s[0]=u("span",{class:"sr-only"},"DriverVault",-1))]))}},cc={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},uc={class:"dh-card p-6"},dc={class:"text-lg font-bold tracking-[-0.02em] text-strong"},pc={class:"mt-1 mb-5 text-sm text-body"},fc={class:"dh-label",for:"login-email"},hc={class:"dh-label",for:"login-password"},gc={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},mc=["disabled"],bc={class:"eyebrow text-center"},vc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=H(""),i=H(""),o=H(""),r=H(!1),a=Oe(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function l(){if(a.value){o.value="",r.value=!0;try{const g=await Ql(n.value.trim(),i.value);s("authenticated",g)}catch(g){o.value=g.status===400||g.status===404?f("login.invalid"):g.message||f("login.failed"),i.value=""}finally{r.value=!1}}}return(g,d)=>(y(),T("div",cc,[u("div",uc,[u("h1",dc,m(h(f)("login.title")),1),u("p",pc,m(h(f)("login.subtitle")),1),u("form",{class:"flex flex-col gap-4",onSubmit:Xa(l,["prevent"])},[u("div",null,[u("label",fc,m(h(f)("login.email")),1),pe(u("input",{id:"login-email","onUpdate:modelValue":d[0]||(d[0]=b=>n.value=b),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[be,n.value]])]),u("div",null,[u("label",hc,m(h(f)("login.password")),1),pe(u("input",{id:"login-password","onUpdate:modelValue":d[1]||(d[1]=b=>i.value=b),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[be,i.value]])]),o.value?(y(),T("p",gc,m(o.value),1)):F("",!0),u("button",{class:"dh-btn w-full",type:"submit",disabled:!a.value},m(r.value?h(f)("login.submitting"):h(f)("login.submit")),9,mc)],32)]),u("p",bc,m(h(f)("login.authNote")),1)]))}},yc={class:"dh-card overflow-hidden"},_c={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},wc={class:"text-base font-bold tracking-[-0.02em] text-strong"},xc={key:0,class:"dh-pill bg-danger-soft text-danger"},kc={key:0,class:"px-5 py-4 text-sm text-danger"},Tc={key:1,class:"w-full text-left text-sm"},Sc={class:"px-5 py-3 font-medium text-strong"},Ec={class:"data px-5 py-3 text-xs text-muted"},Pc={class:"data px-5 py-3 text-right text-xs text-muted"},Cc={class:"px-5 py-3 text-right"},Ac={key:2,class:"px-5 py-4 text-sm text-muted"},$c={__name:"StatusCard",setup(e){const t=H(null),s=H("");let n=null;async function i(){try{t.value=await ae("/api/status",{auth:!1}),s.value=""}catch(a){t.value=null,s.value=a.message||f("status.unreachable")}}const o=Oe(()=>{var a,l,g;return[{key:"apiServer",label:f("status.apiServer"),h:(a=t.value)==null?void 0:a.apiServer},{key:"pocketBase",label:f("status.pocketBase"),h:(l=t.value)==null?void 0:l.pocketBase},{key:"webApp",label:f("status.webApp"),h:(g=t.value)==null?void 0:g.webApp}]});lt(()=>{i(),n=setInterval(i,1e4)}),kn(()=>clearInterval(n));const r=a=>a==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(a,l)=>(y(),T("div",yc,[u("div",_c,[u("div",wc,m(h(f)("status.title")),1),s.value?(y(),T("span",xc,[l[0]||(l[0]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(h(f)("status.unreachable")),1)])):F("",!0)]),s.value?(y(),T("div",kc,m(s.value),1)):t.value?(y(),T("table",Tc,[u("tbody",null,[(y(!0),T(re,null,Ce(o.value,g=>(y(),T("tr",{key:g.key,class:"border-t border-subtle first:border-t-0"},[u("td",Sc,m(g.label),1),u("td",Ec,m(g.h.url||h(f)("status.thisProcess")),1),u("td",Pc,m(g.h.latencyMs!=null?g.h.latencyMs+"ms":h(f)("common.empty")),1),u("td",Cc,[u("span",{class:Ee(["dh-pill",r(g.h.status)])},[l[1]||(l[1]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(g.h.status),1)],2)])]))),128))])])):(y(),T("div",Ac,m(h(f)("status.checking")),1))]))}},Oc={class:"dh-card overflow-hidden"},Dc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Rc={class:"text-base font-bold tracking-[-0.02em] text-strong"},zc={class:"mt-0.5 text-xs text-muted"},Ic={class:"flex flex-col gap-4 px-5 py-4"},jc={class:"dh-label",for:"pb-url"},Uc={class:"grid gap-4 sm:grid-cols-2"},Nc={class:"dh-label",for:"pb-email"},Mc={class:"dh-label",for:"pb-password"},Lc=["placeholder"],Fc={key:0,class:"data text-xs text-muted"},Bc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Hc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Vc={class:"flex items-center gap-2"},Gc=["disabled"],Kc=["disabled"],Wc={class:"eyebrow"},qc={__name:"PocketBaseCard",setup(e){const t=H(null),s=H({url:"",adminEmail:"",adminPassword:""}),n=H(null),i=H(""),o=H(""),r=H(!1);async function a(){try{t.value=await ae("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(d){i.value=d.message}}lt(a);async function l(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?f("pocketbase.testOk"):n.value.reachable?f("pocketbase.testReachableNoAuth"):f("pocketbase.testUnreachable")}catch(d){i.value=d.message}finally{r.value=!1}}async function g(){i.value="",o.value="",r.value=!0;try{const d=await ae("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=d.config,n.value=d.config.probe,s.value.adminPassword="",o.value=d.warning||f("pocketbase.savedNotice")}catch(d){i.value=d.message}finally{r.value=!1}}return(d,b)=>{var E,A;return y(),T("div",Oc,[u("div",Dc,[u("div",null,[u("div",Rc,m(h(f)("pocketbase.title")),1),u("p",zc,m(h(f)("pocketbase.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[b[3]||(b[3]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.superuser?h(f)("pocketbase.connected"):n.value.reachable?h(f)("pocketbase.noSuperuser"):h(f)("pocketbase.unreachable")),1)],2)):F("",!0)]),u("div",Ic,[u("div",null,[u("label",jc,m(h(f)("pocketbase.baseUrl")),1),pe(u("input",{id:"pb-url","onUpdate:modelValue":b[0]||(b[0]=V=>s.value.url=V),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[be,s.value.url]])]),u("div",Uc,[u("div",null,[u("label",Nc,m(h(f)("pocketbase.superuserEmail")),1),pe(u("input",{id:"pb-email","onUpdate:modelValue":b[1]||(b[1]=V=>s.value.adminEmail=V),class:"dh-input",autocomplete:"off"},null,512),[[be,s.value.adminEmail]])]),u("div",null,[u("label",Mc,m(h(f)("pocketbase.superuserPassword")),1),pe(u("input",{id:"pb-password","onUpdate:modelValue":b[2]||(b[2]=V=>s.value.adminPassword=V),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(E=t.value)!=null&&E.adminConfigured?h(f)("pocketbase.passwordUnchanged"):h(f)("pocketbase.passwordNotSet")},null,8,Lc),[[be,s.value.adminPassword]])])]),(A=n.value)!=null&&A.detail?(y(),T("p",Fc,m(n.value.detail),1)):F("",!0),o.value?(y(),T("p",Bc,m(o.value),1)):F("",!0),i.value?(y(),T("p",Hc,m(i.value),1)):F("",!0),u("div",Vc,[u("button",{class:"dh-btn",disabled:r.value,onClick:g},m(h(f)("pocketbase.saveApply")),9,Gc),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:l},m(h(f)("pocketbase.testConnection")),9,Kc),b[4]||(b[4]=u("span",{class:"flex-1"},null,-1)),u("span",Wc,m(h(f)("pocketbase.persistedEnv")),1)])])])}}},Zc={class:"dh-card overflow-hidden"},Jc={class:"border-b border-subtle px-5 py-4"},Yc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Xc={class:"mt-0.5 text-xs text-muted"},Qc={class:"flex flex-col gap-4 px-5 py-4"},eu={class:"dh-label",for:"server-name"},tu={class:"mt-1 text-xs text-muted"},su={key:0,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},nu={key:1,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},iu={class:"flex items-center gap-2"},ou=["disabled"],ru={class:"eyebrow"},au={__name:"ServerCard",setup(e){const t=H({name:""}),s=H(""),n=H(""),i=H(!1);async function o(){try{const a=await ae("/api/admin/server-config");t.value={name:a.name}}catch(a){s.value=a.message}}lt(o);async function r(){s.value="",n.value="",i.value=!0;try{const a=await ae("/api/admin/server-config",{method:"PUT",body:{name:t.value.name}});t.value={name:a.config.name},n.value=a.warning||f("server.savedNotice")}catch(a){s.value=a.message}finally{i.value=!1}}return(a,l)=>(y(),T("div",Zc,[u("div",Jc,[u("div",Yc,m(h(f)("server.title")),1),u("p",Xc,m(h(f)("server.subtitle")),1)]),u("div",Qc,[u("div",null,[u("label",eu,m(h(f)("server.name")),1),pe(u("input",{id:"server-name","onUpdate:modelValue":l[0]||(l[0]=g=>t.value.name=g),class:"dh-input",maxlength:"64",placeholder:"DriverVault API Server",onKeyup:xo(r,["enter"])},null,544),[[be,t.value.name]]),u("p",tu,m(h(f)("server.nameHint")),1)]),n.value?(y(),T("p",su,m(n.value),1)):F("",!0),s.value?(y(),T("p",nu,m(s.value),1)):F("",!0),u("div",iu,[u("button",{class:"dh-btn",disabled:i.value,onClick:r},m(h(f)("server.saveApply")),9,ou),l[1]||(l[1]=u("span",{class:"flex-1"},null,-1)),u("span",ru,m(h(f)("server.persistedEnv")),1)])])]))}},lu={class:"dh-card overflow-hidden"},cu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uu={class:"text-base font-bold tracking-[-0.02em] text-strong"},du={class:"mt-0.5 text-xs text-muted"},pu={class:"flex flex-col gap-4 px-5 py-4"},fu={class:"dh-label",for:"web-url"},hu={class:"dh-label",for:"web-origins"},gu={class:"mt-1 text-xs text-muted"},mu={key:0,class:"data text-xs text-muted"},bu={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},vu={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},yu={class:"flex items-center gap-2"},_u=["disabled"],wu=["disabled"],xu={class:"eyebrow"},ku={__name:"WebAppCard",setup(e){const t=H(null),s=H({url:"",origins:""}),n=H(null),i=H(""),o=H(""),r=H(!1),a=E=>E.split(",").map(A=>A.trim()).filter(Boolean);function l(E){t.value=E,s.value={url:E.url,origins:(E.allowOrigins||[]).join(", ")},n.value=E.probe}async function g(){try{l(await ae("/api/admin/webapp-config"))}catch(E){i.value=E.message}}lt(g);async function d(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?f("webapp.testOk"):f("webapp.testFailed")}catch(E){i.value=E.message}finally{r.value=!1}}async function b(){i.value="",o.value="",r.value=!0;try{const E=await ae("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:a(s.value.origins)}});l(E.config),o.value=E.warning||f("webapp.savedNotice")}catch(E){i.value=E.message}finally{r.value=!1}}return(E,A)=>{var V;return y(),T("div",lu,[u("div",cu,[u("div",null,[u("div",uu,m(h(f)("webapp.title")),1),u("p",du,m(h(f)("webapp.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[A[2]||(A[2]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.status==="ok"?h(f)("webapp.reachable"):h(f)("webapp.unreachable")),1)],2)):F("",!0)]),u("div",pu,[u("div",null,[u("label",fu,m(h(f)("webapp.baseUrl")),1),pe(u("input",{id:"web-url","onUpdate:modelValue":A[0]||(A[0]=x=>s.value.url=x),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[be,s.value.url]])]),u("div",null,[u("label",hu,m(h(f)("webapp.allowedOrigins")),1),pe(u("input",{id:"web-origins","onUpdate:modelValue":A[1]||(A[1]=x=>s.value.origins=x),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[be,s.value.origins]]),u("p",gu,[$e(m(h(gi)("webapp.originsHint","star").before),1),A[3]||(A[3]=u("span",{class:"data"},"*",-1)),$e(m(h(gi)("webapp.originsHint","star").after),1)])]),(V=n.value)!=null&&V.error?(y(),T("p",mu,m(n.value.error),1)):F("",!0),o.value?(y(),T("p",bu,m(o.value),1)):F("",!0),i.value?(y(),T("p",vu,m(i.value),1)):F("",!0),u("div",yu,[u("button",{class:"dh-btn",disabled:r.value,onClick:b},m(h(f)("webapp.saveApply")),9,_u),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:d},m(h(f)("webapp.testConnection")),9,wu),A[4]||(A[4]=u("span",{class:"flex-1"},null,-1)),u("span",xu,m(h(f)("webapp.persistedEnv")),1)])])])}}},Tu={class:"dh-card overflow-hidden"},Su={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Eu={class:"text-base font-bold tracking-[-0.02em] text-strong"},Pu={class:"mt-0.5 text-xs text-muted"},Cu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},Au={class:"grid gap-3 sm:grid-cols-3"},$u={class:"dh-label"},Ou={class:"dh-label"},Du={class:"dh-label"},Ru=["disabled"],zu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Iu={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ju={key:3,class:"flex flex-wrap gap-1.5 border-b border-subtle px-5 py-3"},Uu=["onClick"],Nu={class:"dh-pill bg-sunken text-muted"},Mu={class:"flex items-center gap-3 px-5 py-3"},Lu=["onClick"],Fu={class:"font-semibold text-strong"},Bu={class:"dh-pill bg-sunken text-muted"},Hu={key:0,class:"text-xs text-muted"},Vu=["disabled","onClick"],Gu=["disabled","onClick"],Ku={key:0,class:"bg-sunken px-5 py-4"},Wu={key:0,class:"data mb-3 text-xs text-muted"},qu={key:1,class:"grid gap-3 sm:grid-cols-2"},Zu={class:"dh-label"},Ju={key:0,class:"text-danger"},Yu=["onUpdate:modelValue"],Xu={key:0,value:""},Qu=["value"],ed=["onUpdate:modelValue","type","placeholder"],td={key:2,class:"mt-1 text-xs text-muted"},sd={key:2,class:"text-xs text-muted"},nd={key:3,class:"mt-4"},id={class:"eyebrow mb-1.5"},od={class:"data flex flex-col gap-1 text-xs text-muted"},rd={class:"text-strong"},ad={key:0},ld={key:1},cd={key:4,class:"data mt-3 text-xs text-body"},ud={class:"mt-4 flex items-center gap-2"},dd=["disabled","onClick"],pd=["disabled","onClick"],fd=["disabled","onClick"],hd={key:5,class:"eyebrow mt-2"},gd={__name:"PluginsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=Yt({}),r=Yt({}),a=H(!1),l=H({name:"",baseURL:"",provider:""}),g=H(""),d=["vehicles","chargers","notifications","apis-external","drives-external","drives-local"],b=z=>d.includes(z.category)?z.category:"apis-external",E=Oe(()=>{var K;const z={};for(const P of t.value)(z[K=b(P)]||(z[K]=[])).push(P);return d.filter(P=>z[P]).map(P=>({id:P,label:f(`plugins.categories.${P}`),plugins:z[P]}))}),A=Oe(()=>E.value.find(z=>z.id===g.value)||E.value[0]),V=Oe(()=>{var z;return((z=A.value)==null?void 0:z.plugins)||[]});async function x(){try{const z=await ae("/api/admin/plugins");t.value=z.plugins||[],s.value=""}catch(z){s.value=z.message}}lt(x);function N(z){var P;if(i.value===z.name){i.value=null;return}const K={};for(const I of z.configFields||[])K[I.key]=((P=z.config)==null?void 0:P[I.key])??"";o[z.name]=K,i.value=z.name}async function R(z,K){n.value=!0,r[z.name]="";try{const P=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"PUT",body:{enabled:K,config:o[z.name]??{}}});r[z.name]=P.warning||f("plugins.saved"),await x()}catch(P){r[z.name]=P.message}finally{n.value=!1}}async function G(z){n.value=!0,r[z.name]=f("plugins.checking");try{const K=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}/health`,{method:"POST"});r[z.name]=`${K.health.status}${K.health.detail?" — "+K.health.detail:""}`,await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}async function Z(z){if(confirm(f("plugins.confirmRemove",{name:z.name}))){n.value=!0;try{await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"DELETE"}),i.value===z.name&&(i.value=null),await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}}async function U(){n.value=!0,s.value="";try{await ae("/api/admin/plugins",{method:"POST",body:l.value}),l.value={name:"",baseURL:"",provider:""},a.value=!1,await x()}catch(z){s.value=z.message}finally{n.value=!1}}const le=z=>z==="ok"?"bg-success-soft text-success":z==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(z,K)=>(y(),T("div",Tu,[u("div",Su,[u("div",null,[u("div",Eu,m(h(f)("plugins.title")),1),u("p",Pu,m(h(f)("plugins.subtitle")),1)]),u("button",{class:"dh-btn-ghost",onClick:K[0]||(K[0]=P=>a.value=!a.value)},m(a.value?h(f)("plugins.cancelRegister"):h(f)("plugins.registerExternal")),1)]),a.value?(y(),T("div",Cu,[u("div",Au,[u("div",null,[u("label",$u,m(h(f)("plugins.name")),1),pe(u("input",{"onUpdate:modelValue":K[1]||(K[1]=P=>l.value.name=P),class:"dh-input",placeholder:"acme-parts"},null,512),[[be,l.value.name]])]),u("div",null,[u("label",Ou,m(h(f)("plugins.baseUrl")),1),pe(u("input",{"onUpdate:modelValue":K[2]||(K[2]=P=>l.value.baseURL=P),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[be,l.value.baseURL]])]),u("div",null,[u("label",Du,m(h(f)("plugins.provider")),1),pe(u("input",{"onUpdate:modelValue":K[3]||(K[3]=P=>l.value.provider=P),class:"dh-input",placeholder:"ACME Corp"},null,512),[[be,l.value.provider]])])]),u("button",{class:"dh-btn mt-3",disabled:n.value||!l.value.name||!l.value.baseURL,onClick:U},m(h(f)("plugins.register")),9,Ru)])):F("",!0),s.value?(y(),T("p",zu,m(s.value),1)):F("",!0),t.value.length?F("",!0):(y(),T("p",Iu,m(h(f)("plugins.empty")),1)),E.value.length>1?(y(),T("nav",ju,[(y(!0),T(re,null,Ce(E.value,P=>{var I;return y(),T("button",{key:P.id,class:Ee(["dh-btn-ghost",((I=A.value)==null?void 0:I.id)===P.id?"border-accent text-brandtext":""]),onClick:J=>g.value=P.id},[$e(m(P.label)+" ",1),u("span",Nu,m(P.plugins.length),1)],10,Uu)}),128))])):F("",!0),(y(!0),T(re,null,Ce(V.value,P=>(y(),T("div",{key:P.name,class:"border-t border-subtle first:border-t-0"},[u("div",Mu,[u("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:I=>N(P)},[u("span",Fu,m(P.name),1),u("span",Bu,m(P.kind||h(f)("plugins.builtin")),1),P.provider?(y(),T("span",Hu,m(P.provider),1)):F("",!0),P.health?(y(),T("span",{key:1,class:Ee(["dh-pill",le(P.health.status)])},[K[4]||(K[4]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(P.health.status),1)],2)):F("",!0)],8,Lu),u("span",{class:Ee(["dh-pill",P.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},m(P.enabled?h(f)("plugins.enabled"):h(f)("plugins.disabled")),3),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>G(P)},m(h(f)("plugins.health")),9,Vu),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>N(P)},m(i.value===P.name?h(f)("plugins.close"):h(f)("plugins.configure")),9,Gu)]),i.value===P.name?(y(),T("div",Ku,[P.baseURL?(y(),T("div",Wu,m(P.baseURL),1)):F("",!0),(P.configFields||[]).length?(y(),T("div",qu,[(y(!0),T(re,null,Ce(P.configFields,I=>(y(),T("div",{key:I.key},[u("label",Zu,[$e(m(I.label||I.key),1),I.required?(y(),T("span",Ju," *")):F("",!0)]),I.type==="select"?pe((y(),T("select",{key:0,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-select"},[I.required?F("",!0):(y(),T("option",Xu,m(h(f)("plugins.notSet")),1)),(y(!0),T(re,null,Ce(I.options||[],J=>(y(),T("option",{key:J.value,value:J.value},m(J.label||J.value),9,Qu))),128))],8,Yu)),[[ks,o[P.name][I.key]]]):pe((y(),T("input",{key:1,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-input",type:I.type==="password"?"password":I.type==="number"?"number":"text",placeholder:I.default||"",autocomplete:"off"},null,8,ed)),[[qa,o[P.name][I.key]]]),I.help?(y(),T("p",td,m(I.help),1)):F("",!0)]))),128))])):(y(),T("p",sd,m(h(f)("plugins.noConfig")),1)),(P.capabilities||[]).length?(y(),T("div",nd,[u("div",id,m(h(f)("plugins.capabilities")),1),u("ul",od,[(y(!0),T(re,null,Ce(P.capabilities,I=>(y(),T("li",{key:I.id},[u("span",rd,m(I.id),1),I.method||I.endpoint?(y(),T("span",ad," — "+m(I.method)+" "+m(I.endpoint),1)):F("",!0),I.description?(y(),T("span",ld," · "+m(I.description),1)):F("",!0)]))),128))])])):F("",!0),r[P.name]?(y(),T("p",cd,m(r[P.name]),1)):F("",!0),u("div",ud,[u("button",{class:"dh-btn",disabled:n.value,onClick:I=>R(P,!0)},m(P.enabled?h(f)("plugins.save"):h(f)("plugins.saveEnable")),9,dd),P.enabled?(y(),T("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:I=>R(P,!1)},m(h(f)("plugins.disable")),9,pd)):F("",!0),K[5]||(K[5]=u("span",{class:"flex-1"},null,-1)),P.kind==="external"?(y(),T("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:I=>Z(P)},m(h(f)("plugins.remove")),9,fd)):F("",!0)]),P.kind!=="external"?(y(),T("p",hd,m(h(f)("plugins.builtinNote")),1)):F("",!0)])):F("",!0)]))),128))]))}},md={class:"dh-card overflow-hidden"},bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},vd={class:"text-base font-bold tracking-[-0.02em] text-strong"},yd={class:"mt-0.5 text-xs text-muted"},_d={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},wd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},xd={class:"grid gap-3 sm:grid-cols-2"},kd={class:"dh-label"},Td={class:"dh-label"},Sd={class:"dh-label"},Ed=["placeholder"],Pd={class:"dh-label"},Cd=["value"],Ad={key:0},$d={class:"dh-label"},Od={value:""},Dd=["value"],Rd={class:"mt-3 flex items-center gap-2"},zd=["disabled"],Id=["disabled"],jd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Ud={key:3,class:"w-full text-left text-sm"},Nd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Md={class:"data px-5 py-2.5 text-xs text-strong"},Ld={key:0,class:"eyebrow ml-1"},Fd={class:"px-5 py-2.5 text-body"},Bd={class:"px-5 py-2.5 text-body"},Hd={class:"px-5 py-2.5"},Vd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Gd=["onClick"],Kd=["disabled","onClick"],Wd={__name:"UsersCard",setup(e){const t=H([]),s=H([]),n=H(""),i=H(!1),o=H(null),r=H({}),a=Oe(()=>De.value?["user","admin","superadmin"]:["user","admin"]);async function l(){try{const[x,N]=await Promise.all([ae("/api/users"),ae("/api/orgs")]);t.value=x.users||[],s.value=N.organizations||[],n.value=""}catch(x){n.value=x.message}}lt(l);function g(){var x;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:De.value?"":((x=he.value)==null?void 0:x.organization)||""}}function d(x){o.value=x.id,r.value={email:x.email,name:x.name||"",password:"",role:x.role,organization:x.organization||""}}function b(){o.value=null,n.value=""}async function E(){i.value=!0,n.value="";try{if(o.value==="new")await ae("/api/users",{method:"POST",body:r.value});else{const x={...r.value};x.password||delete x.password,await ae(`/api/users/${o.value}`,{method:"PATCH",body:x})}o.value=null,await l()}catch(x){n.value=x.message}finally{i.value=!1}}async function A(x){if(confirm(f("users.confirmDelete",{email:x.email}))){i.value=!0,n.value="";try{await ae(`/api/users/${x.id}`,{method:"DELETE"}),await l()}catch(N){n.value=N.message}finally{i.value=!1}}}const V=x=>x==="superadmin"?"bg-info-soft text-info":x==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(x,N)=>(y(),T("div",md,[u("div",bd,[u("div",null,[u("div",vd,m(h(f)("users.title")),1),u("p",yd,m(h(De)?h(f)("users.allOrgs"):h(f)("users.yourOrg")),1)]),u("button",{class:"dh-btn",onClick:g},m(h(f)("users.newUser")),1)]),n.value?(y(),T("p",_d,m(n.value),1)):F("",!0),o.value?(y(),T("div",wd,[u("div",xd,[u("div",null,[u("label",kd,m(h(f)("common.email")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>r.value.email=R),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[be,r.value.email]])]),u("div",null,[u("label",Td,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[1]||(N[1]=R=>r.value.name=R),class:"dh-input",autocomplete:"off"},null,512),[[be,r.value.name]])]),u("div",null,[u("label",Sd,m(o.value==="new"?h(f)("users.password"):h(f)("users.passwordUnchanged")),1),pe(u("input",{"onUpdate:modelValue":N[2]||(N[2]=R=>r.value.password=R),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:h(f)("users.passwordPlaceholder")},null,8,Ed),[[be,r.value.password]])]),u("div",null,[u("label",Pd,m(h(f)("common.role")),1),pe(u("select",{"onUpdate:modelValue":N[3]||(N[3]=R=>r.value.role=R),class:"dh-select"},[(y(!0),T(re,null,Ce(a.value,R=>(y(),T("option",{key:R,value:R},m(R),9,Cd))),128))],512),[[ks,r.value.role]])]),h(De)?(y(),T("div",Ad,[u("label",$d,m(h(f)("common.organization")),1),pe(u("select",{"onUpdate:modelValue":N[4]||(N[4]=R=>r.value.organization=R),class:"dh-select"},[u("option",Od,m(h(f)("users.orgNone")),1),(y(!0),T(re,null,Ce(s.value,R=>(y(),T("option",{key:R.id,value:R.id},m(R.name),9,Dd))),128))],512),[[ks,r.value.organization]])])):F("",!0)]),u("div",Rd,[u("button",{class:"dh-btn",disabled:i.value,onClick:E},m(o.value==="new"?h(f)("common.create"):h(f)("common.save")),9,zd),u("button",{class:"dh-btn-ghost",disabled:i.value,onClick:b},m(h(f)("common.cancel")),9,Id)])])):F("",!0),t.value.length?(y(),T("table",Ud,[u("thead",null,[u("tr",Nd,[u("th",null,m(h(f)("common.email")),1),u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("common.organization")),1),u("th",null,m(h(f)("common.role")),1),N[5]||(N[5]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>{var G,Z;return y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",Md,[$e(m(R.email)+" ",1),R.id===((G=h(he))==null?void 0:G.id)?(y(),T("span",Ld,m(h(f)("users.you")),1)):F("",!0)]),u("td",Fd,m(R.name||h(f)("common.empty")),1),u("td",Bd,m(R.organizationName||h(f)("common.empty")),1),u("td",Hd,[u("span",{class:Ee(["dh-pill",V(R.role)])},m(R.role),3)]),u("td",Vd,[u("button",{class:"dh-btn-ghost",onClick:U=>d(R)},m(h(f)("common.edit")),9,Gd),R.id!==((Z=h(he))==null?void 0:Z.id)?(y(),T("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:U=>A(R)},m(h(f)("common.delete")),9,Kd)):F("",!0)])])}),128))])])):(y(),T("p",jd,m(h(f)("users.empty")),1))]))}},qd={class:"dh-card overflow-hidden"},Zd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Jd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Yd={class:"mt-0.5 text-xs text-muted"},Xd={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Qd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},ep={class:"dh-label"},tp=["placeholder"],sp={class:"mt-3 flex items-center gap-2"},np=["disabled"],ip=["disabled"],op={key:2,class:"px-5 py-6 text-center text-sm text-muted"},rp={key:3,class:"w-full text-left text-sm"},ap={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},lp={class:"px-5 py-2.5 font-medium text-strong"},cp={class:"data px-5 py-2.5 text-xs text-muted"},up={class:"px-5 py-2.5 text-right whitespace-nowrap"},dp=["onClick"],pp=["disabled","onClick"],fp={__name:"OrgsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=H(""),r=Oe(()=>{var x;return((x=he.value)==null?void 0:x.organization)||""}),a=Oe(()=>De.value||!r.value);function l(x){return De.value||x.id===r.value}async function g(){if(!gs.value){t.value=[];return}try{const x=await ae("/api/orgs");t.value=x.organizations||[],s.value=""}catch(x){s.value=x.message}}lt(g);function d(){i.value="new",o.value=""}function b(x){i.value=x.id,o.value=x.name}function E(){i.value=null,s.value=""}async function A(){n.value=!0,s.value="";try{i.value==="new"?(await ae("/api/orgs",{method:"POST",body:{name:o.value}}),De.value||await Ts()):await ae(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await g()}catch(x){s.value=x.message}finally{n.value=!1}}async function V(x){const N=!De.value&&x.id===r.value;if(confirm(f(N?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:x.name}))){n.value=!0,s.value="";try{await ae(`/api/orgs/${x.id}`,{method:"DELETE"}),N&&await Ts(),await g()}catch(G){s.value=G.message}finally{n.value=!1}}}return(x,N)=>(y(),T("div",qd,[u("div",Zd,[u("div",null,[u("div",Jd,m(h(De)?h(f)("orgs.title"):h(f)("common.organization")),1),u("p",Yd,m(h(De)?h(f)("orgs.subtitle"):r.value?h(f)("orgs.subtitleOwn"):h(f)("orgs.subtitleNone")),1)]),a.value?(y(),T("button",{key:0,class:"dh-btn",onClick:d},m(h(f)("orgs.newOrg")),1)):F("",!0)]),s.value?(y(),T("p",Xd,m(s.value),1)):F("",!0),i.value?(y(),T("div",Qd,[u("label",ep,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>o.value=R),class:"dh-input",placeholder:h(f)("orgs.namePlaceholder"),onKeyup:xo(A,["enter"])},null,40,tp),[[be,o.value]]),u("div",sp,[u("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:A},m(i.value==="new"?h(f)("common.create"):h(f)("common.save")),9,np),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:E},m(h(f)("common.cancel")),9,ip)])])):F("",!0),t.value.length?(y(),T("table",rp,[u("thead",null,[u("tr",ap,[u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("orgs.colId")),1),N[1]||(N[1]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>(y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",lp,m(R.name),1),u("td",cp,m(R.id),1),u("td",up,[l(R)?(y(),T(re,{key:0},[u("button",{class:"dh-btn-ghost",onClick:G=>b(R)},m(h(f)("common.rename")),9,dp),u("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:G=>V(R)},m(h(f)("common.delete")),9,pp)],64)):F("",!0)])]))),128))])])):(y(),T("p",op,m(a.value&&!h(De)?h(f)("orgs.createHint"):h(f)("orgs.empty")),1))]))}},hp={class:"dh-card overflow-hidden"},gp={class:"border-b border-subtle px-5 py-4"},mp={class:"flex items-center justify-between"},bp={class:"text-base font-bold tracking-[-0.02em] text-strong"},vp={class:"eyebrow"},yp={key:0,class:"mt-1.5 text-xs text-muted"},_p={class:"overflow-x-auto"},wp={class:"w-full text-left text-sm"},xp={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},kp={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},Tp={class:"text-strong"},Sp={class:"border-t border-subtle px-5 py-2.5 text-body"},fe={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array,note:String},setup(e){const t={GET:"text-success",POST:"text-brandtext",PUT:"text-info",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(y(),T("div",hp,[u("div",gp,[u("div",mp,[u("div",bp,m(e.title),1),u("span",vp,m(e.auth),1)]),e.note?(y(),T("p",yp,m(e.note),1)):F("",!0)]),u("div",_p,[u("table",wp,[u("thead",null,[u("tr",xp,[u("th",null,m(h(f)("api.colEndpoint")),1),u("th",null,m(h(f)("api.colDescription")),1)])]),u("tbody",null,[(y(!0),T(re,null,Ce(e.endpoints,i=>(y(),T("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[u("td",kp,[u("span",{class:Ee(["font-semibold",t[i.method]])},m(i.method),3),u("span",Tp,m(i.path),1)]),u("td",Sp,m(i.desc),1)]))),128))])])])]))}},Ep={class:"mx-auto flex max-w-4xl flex-col gap-6 px-6 pt-12 pb-16"},Pp={class:"flex items-center gap-3"},Cp={class:"eyebrow mt-1.5"},Ap={key:0,class:"data hidden text-xs text-muted sm:inline"},$p={key:0},Op={key:1,class:"dh-pill bg-info-soft text-info"},Dp=["value","aria-label"],Rp=["value"],zp=["title"],Ip={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"},jp={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"},Up={key:0,class:"eyebrow py-16 text-center"},Np={class:"flex flex-wrap gap-1.5"},Mp=["onClick"],Lp={key:8,class:"eyebrow text-center"},Fp={class:"eyebrow text-center"},Bp="{records} is any of service-records, technical-checks, maintenance, fuel-entries, charging-sessions, car-documents, parts.",Hp={__name:"App",setup(e){const t=H(!0),s=H("overview");lt(async()=>{await ec(),t.value=!1});const n=Oe(()=>{const P=[{id:"overview",label:f("sections.overview")}];return gs.value&&P.push({id:"users",label:f("sections.users")}),(gs.value||he.value)&&P.push({id:"orgs",label:f("sections.orgs")}),De.value&&P.push({id:"server",label:f("sections.server")},{id:"pocketbase",label:f("sections.pocketbase")},{id:"webapp",label:f("sections.webapp")},{id:"plugins",label:f("sections.plugins")}),P.push({id:"api",label:f("sections.api")}),P}),i=Oe(()=>Gl.map(P=>{let I=P;try{I=new Intl.DisplayNames([P],{type:"language"}).of(P)||P}catch{}return{code:P,label:I.charAt(0).toUpperCase()+I.slice(1)}}));function o(){Pn(),s.value="overview"}const r=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/healthz",desc:"The same probe under the conventional container path"},{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"}],l=[{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:"PUT",path:"/api/cars/{id}/view",desc:"Save the car's layout — hidden tabs/fields/columns and their order"},{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}/technical-checks",desc:"A car's roadworthiness inspections"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/fuel-entries",desc:"A car's refuelings"},{method:"GET",path:"/api/cars/{id}/fuel-stats",desc:"Consumption + cost totals from the fuel log"},{method:"GET",path:"/api/cars/{id}/charging-sessions",desc:"A car's charging sessions"},{method:"GET",path:"/api/cars/{id}/charging-stats",desc:"Energy + cost totals from the charging log"},{method:"GET",path:"/api/cars/{id}/maintenance",desc:"A car's maintenance log"},{method:"GET",path:"/api/cars/{id}/documents",desc:"A car's documents"},{method:"GET",path:"/api/cars/{id}/reminders",desc:"A car's reminders"},{method:"GET",path:"/api/cars/{id}/provider",desc:"Live snapshot from the car's connected service"},{method:"POST",path:"/api/cars/{id}/provider",desc:"Link the car to a provider vehicle (an empty provider unlinks)"},{method:"POST",path:"/api/cars/{id}/provider/sync",desc:"Re-apply the provider's data to the car"},{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)"}],g=[{method:"GET",path:"/api/service-records",desc:"List one car's service records (?car={id})"},{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"}],d=[{method:"GET",path:"/api/technical-checks",desc:"List one car's inspections (?car={id})"},{method:"POST",path:"/api/technical-checks",desc:"Log an inspection"},{method:"GET",path:"/api/technical-checks/{id}",desc:"Fetch one inspection"},{method:"PATCH",path:"/api/technical-checks/{id}",desc:"Update an inspection"},{method:"DELETE",path:"/api/technical-checks/{id}",desc:"Delete an inspection"}],b=[{method:"GET",path:"/api/parts",desc:"List one car's parts (?car={id})"},{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"}],E=[{method:"GET",path:"/api/fuel-entries",desc:"List one car's refuelings (?car={id})"},{method:"POST",path:"/api/fuel-entries",desc:"Log a refueling"},{method:"GET",path:"/api/fuel-entries/{id}",desc:"Fetch one refueling"},{method:"PATCH",path:"/api/fuel-entries/{id}",desc:"Update a refueling"},{method:"DELETE",path:"/api/fuel-entries/{id}",desc:"Delete a refueling"}],A=[{method:"GET",path:"/api/charging-sessions",desc:"List one car's charging sessions (?car={id})"},{method:"POST",path:"/api/charging-sessions",desc:"Log a charging session"},{method:"GET",path:"/api/charging-sessions/{id}",desc:"Fetch one session"},{method:"PATCH",path:"/api/charging-sessions/{id}",desc:"Update a session"},{method:"DELETE",path:"/api/charging-sessions/{id}",desc:"Delete a session"}],V=[{method:"GET",path:"/api/maintenance",desc:"List one car's maintenance jobs (?car={id})"},{method:"POST",path:"/api/maintenance",desc:"Log a maintenance job"},{method:"GET",path:"/api/maintenance/{id}",desc:"Fetch one job"},{method:"PATCH",path:"/api/maintenance/{id}",desc:"Update a job"},{method:"DELETE",path:"/api/maintenance/{id}",desc:"Delete a job"}],x=[{method:"GET",path:"/api/car-documents",desc:"List one car's documents (?car={id})"},{method:"POST",path:"/api/car-documents",desc:"Add a document"},{method:"GET",path:"/api/car-documents/{id}",desc:"Fetch one document"},{method:"PATCH",path:"/api/car-documents/{id}",desc:"Update a document"},{method:"DELETE",path:"/api/car-documents/{id}",desc:"Delete a document"}],N=[{method:"GET",path:"/api/reminders",desc:"List one car's reminders (?car={id})"},{method:"POST",path:"/api/reminders",desc:"Create a reminder"},{method:"GET",path:"/api/reminders/{id}",desc:"Fetch one reminder"},{method:"PATCH",path:"/api/reminders/{id}",desc:"Update a reminder"},{method:"DELETE",path:"/api/reminders/{id}",desc:"Delete a reminder"},{method:"POST",path:"/api/reminders/{id}/complete",desc:"Mark done — a recurring reminder rolls forward from now"}],R=[{method:"POST",path:"/api/{records}/{id}/file",desc:"Attach a file, replacing any previous one (PDF or image, max 10 MB)"},{method:"GET",path:"/api/{records}/{id}/file",desc:"Download the attachment (car access re-checked on every request)"},{method:"DELETE",path:"/api/{records}/{id}/file",desc:"Detach and delete the file"}],G=[{method:"GET",path:"/api/vehicle-providers",desc:"Registered providers and whether the caller can use each one"},{method:"GET",path:"/api/vehicle-providers/{provider}/vehicles",desc:"Vehicles on the caller's provider account, as importable cars"},{method:"POST",path:"/api/vehicle-providers/{provider}/import",desc:"Create a car from a provider vehicle (409 if already imported)"}],Z=[{method:"GET",path:"/api/integrations/toyota",desc:"Resolved Toyota Connected settings (secrets masked)"},{method:"PUT",path:"/api/integrations/toyota",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/toyota/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/toyota/vehicles",desc:"Raw MyToyota vehicle payload"},{method:"GET",path:"/api/integrations/anker-solix",desc:"Resolved Anker Solix settings (secrets masked)"},{method:"PUT",path:"/api/integrations/anker-solix",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/anker-solix/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/anker-solix/chargers",desc:"EV chargers on the linked Anker account"},{method:"GET",path:"/api/integrations/anker-solix/chargers/{sn}/control",desc:"Control mode, token state and live CSMS session for one charger"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"(Re)issue the charger's control token"},{method:"DELETE",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"Revoke the control token"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/{action}",desc:"One OCPP command: start, stop, limit, clear-limit, availability, reset, unlock, trigger, config"},{method:"GET",path:"/api/integrations/greencell",desc:"Resolved Greencell settings (secrets masked)"},{method:"PUT",path:"/api/integrations/greencell",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/greencell/health",desc:"Live probe: connect to the broker and broadcast for devices"},{method:"GET",path:"/api/integrations/greencell/chargers",desc:"Greencell chargers answering on the configured MQTT broker"},{method:"GET",path:"/api/integrations/greencell/chargers/{sn}/state",desc:"Live EVSE state, access level, power and per-phase current/voltage"}],U=[{method:"GET",path:"/ocpp/{serial}",desc:"WebSocket the charger dials out to; OCPP Basic auth with the serial + its control token"}],le=[{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"}],z=[{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)"}],K=[{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/server-config",desc:"This server's display name"},{method:"PUT",path:"/api/admin/server-config",desc:"Rename this server (applied + persisted)"},{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(P,I)=>(y(),T("div",Ep,[u("div",Pp,[ee(lc,{"on-dark":h(Ct)==="dark",class:"h-7"},null,8,["on-dark"]),u("span",Cp,m(h(f)("app.apiServer")),1),I[4]||(I[4]=u("div",{class:"flex-1"},null,-1)),h(he)?(y(),T("span",Ap,[$e(m(h(he).email),1),h(he).organizationName?(y(),T("span",$p," · "+m(h(he).organizationName),1)):F("",!0)])):F("",!0),h(he)?(y(),T("span",Op,m(h(he).role),1)):F("",!0),u("select",{class:"dh-select !w-auto !py-1 !text-xs",value:h(En),"aria-label":h(f)("sections.overview"),onChange:I[0]||(I[0]=J=>h(Wl)(J.target.value))},[(y(!0),T(re,null,Ce(i.value,J=>(y(),T("option",{key:J.code,value:J.code},m(J.label),9,Rp))),128))],40,Dp),u("button",{class:"dh-btn-ghost",title:h(Ct)==="dark"?h(f)("app.switchToLight"):h(f)("app.switchToDark"),onClick:I[1]||(I[1]=(...J)=>h(fi)&&h(fi)(...J))},[h(Ct)==="dark"?(y(),T("svg",Ip,[...I[2]||(I[2]=[u("circle",{cx:"12",cy:"12",r:"4"},null,-1),u("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)])])):(y(),T("svg",jp,[...I[3]||(I[3]=[u("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)])])),$e(" "+m(h(f)("app.theme")),1)],8,zp),h(Rt)?(y(),T("button",{key:2,class:"dh-btn-ghost",onClick:o},m(h(f)("app.signOut")),1)):F("",!0)]),t.value?(y(),T("p",Up,m(h(f)("app.loading")),1)):h(Rt)?(y(),T(re,{key:2},[u("nav",Np,[(y(!0),T(re,null,Ce(n.value,J=>(y(),T("button",{key:J.id,class:Ee(["dh-btn-ghost",s.value===J.id?"border-accent text-brandtext":""]),onClick:wt=>s.value=J.id},m(J.label),11,Mp))),128))]),s.value==="overview"?(y(),et($c,{key:0})):s.value==="users"?(y(),et(Wd,{key:1})):s.value==="orgs"?(y(),et(fp,{key:2})):s.value==="server"?(y(),et(au,{key:3})):s.value==="pocketbase"?(y(),et(qc,{key:4})):s.value==="webapp"?(y(),et(ku,{key:5})):s.value==="plugins"?(y(),et(gd,{key:6})):s.value==="api"?(y(),T(re,{key:7},[ee(fe,{title:h(f)("api.groupPublic"),auth:h(f)("api.authNone"),endpoints:r},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIdentity"),auth:h(f)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCars"),auth:h(f)("api.authBearer"),endpoints:l},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupService"),auth:h(f)("api.authBearer"),endpoints:g},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupTechnical"),auth:h(f)("api.authBearer"),endpoints:d},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupParts"),auth:h(f)("api.authBearer"),endpoints:b},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupFuel"),auth:h(f)("api.authBearer"),endpoints:E},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCharging"),auth:h(f)("api.authBearer"),endpoints:A},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupMaintenance"),auth:h(f)("api.authBearer"),endpoints:V},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupDocuments"),auth:h(f)("api.authBearer"),endpoints:x},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupReminders"),auth:h(f)("api.authBearer"),endpoints:N},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAttachments"),auth:h(f)("api.authBearer"),endpoints:R,note:Bp},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupProviders"),auth:h(f)("api.authBearer"),endpoints:G},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIntegrations"),auth:h(f)("api.authBearer"),endpoints:Z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupOcpp"),auth:h(f)("api.authCharger"),endpoints:U},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAccount"),auth:h(f)("api.authBearer"),endpoints:le},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupManagement"),auth:h(f)("api.authManager"),endpoints:z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupSuperadmin"),auth:h(f)("api.authSuperadmin"),endpoints:K},null,8,["title","auth"])],64)):F("",!0),!h(gs)&&s.value==="overview"?(y(),T("p",Lp,m(h(f)("app.standardUserNote")),1)):F("",!0)],64)):(y(),et(vc,{key:1})),u("p",Fp,m(h(f)("app.footer")),1)]))}};sl(Hp).mount("#app"); +**/let an;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{an=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const _o=an?e=>an.createHTML(e):e=>e,ka="http://www.w3.org/2000/svg",Ta="http://www.w3.org/1998/Math/MathML",tt=typeof document<"u"?document:null,Qn=tt&&tt.createElement("template"),Sa={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"?tt.createElementNS(ka,e):t==="mathml"?tt.createElementNS(Ta,e):s?tt.createElement(e,{is:s}):tt.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>tt.createTextNode(e),createComment:e=>tt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>tt.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=_o(n==="svg"?`${e}`:n==="mathml"?`${e}`:e);const a=Qn.content;if(n==="svg"||n==="mathml"){const l=a.firstChild;for(;l.firstChild;)a.appendChild(l.firstChild);a.removeChild(l)}t.insertBefore(a,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},Ea=Symbol("_vtc");function Pa(e,t,s){const n=e[Ea];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Ca=Symbol("_vsh"),Aa=Symbol(""),$a=/(?:^|;)\s*display\s*:/;function Oa(e,t,s){const n=e.style,i=ue(s);let o=!1;if(s&&!i){if(t)if(ue(t))for(const r of t.split(";")){const a=r.slice(0,r.indexOf(":")).trim();s[a]==null&&Ft(n,a,"")}else for(const r in t)s[r]==null&&Ft(n,r,"");for(const r in s){r==="display"&&(o=!0);const a=s[r];a!=null?Ra(e,r,!ue(t)&&t?t[r]:void 0,a)||Ft(n,r,a):Ft(n,r,"")}}else if(i){if(t!==s){const r=n[Aa];r&&(s+=";"+r),n.cssText=s,o=$a.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Ca]&&(n.display="none"))}const ti=/\s*!important$/;function Ft(e,t,s){if(L(s))s.forEach(n=>Ft(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Da(e,t);ti.test(s)?e.setProperty(ft(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Da(e,t){const s=qs[t];if(s)return s;let n=je(t);if(n!=="filter"&&n in e)return qs[t]=n;n=_i(n);for(let i=0;iZs||(Ma.then(()=>Zs=0),Zs=Date.now());function Fa(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(),a=[n];for(let l=0;le.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ba=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?Pa(e,n,r):t==="style"?Oa(e,s,n):Ss(t)?Es(t)||Ia(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ha(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&&(Va(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ue(n)))?oi(e,je(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),ii(e,t,n,r))};function Ha(e,t,s,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&ai(t)&&W(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 ai(t)&&ue(s)?!1:t in e}function Va(e,t){const s=e._def.props;if(!s)return!1;const n=je(t);return Array.isArray(s)?s.some(i=>je(i)===n):Object.keys(s).some(i=>je(i)===n)}const pt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return L(t)?s=>ps(t,s):t};function Ga(e){e.target.composing=!0}function li(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ie=Symbol("_assign");function ci(e,t,s){return t&&(e=e.trim()),s&&(e=Cs(e)),e}const be={created(e,{modifiers:{lazy:t,trim:s,number:n}},i){e[Ie]=pt(i);const o=n||i.props&&i.props.type==="number";ot(e,t?"change":"input",r=>{r.target.composing||e[Ie](ci(e.value,s,o))}),(s||o)&&ot(e,"change",()=>{e.value=ci(e.value,s,o)}),t||(ot(e,"compositionstart",Ga),ot(e,"compositionend",li),ot(e,"change",li))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:s,modifiers:{lazy:n,trim:i,number:o}},r){if(e[Ie]=pt(r),e.composing)return;const a=(o||e.type==="number")&&!/^0\d/.test(e.value)?Cs(e.value):e.value,l=t??"";if(a===l)return;const g=e.getRootNode();(g instanceof Document||g instanceof ShadowRoot)&&g.activeElement===e&&e.type!=="range"&&(n&&t===s||i&&e.value.trim()===l)||(e.value=l)}},Ka={deep:!0,created(e,t,s){e[Ie]=pt(s),ot(e,"change",()=>{const n=e._modelValue,i=Ot(e),o=e.checked,r=e[Ie];if(L(n)){const a=fn(n,i),l=a!==-1;if(o&&!l)r(n.concat(i));else if(!o&&l){const g=[...n];g.splice(a,1),r(g)}}else if(zt(n)){const a=new Set(n);o?a.add(i):a.delete(i),r(a)}else r(wo(e,o))})},mounted:ui,beforeUpdate(e,t,s){e[Ie]=pt(s),ui(e,t,s)}};function ui(e,{value:t,oldValue:s},n){e._modelValue=t;let i;if(L(t))i=fn(t,n.props.value)>-1;else if(zt(t))i=t.has(n.props.value);else{if(t===s)return;i=ut(t,wo(e,!0))}e.checked!==i&&(e.checked=i)}const Wa={created(e,{value:t},s){e.checked=ut(t,s.props.value),e[Ie]=pt(s),ot(e,"change",()=>{e[Ie](Ot(e))})},beforeUpdate(e,{value:t,oldValue:s},n){e[Ie]=pt(n),t!==s&&(e.checked=ut(t,n.props.value))}},ks={deep:!0,created(e,{value:t,modifiers:{number:s}},n){const i=zt(t);ot(e,"change",()=>{const o=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>s?Cs(Ot(r)):Ot(r));e[Ie](e.multiple?i?new Set(o):o:o[0]),e._assigning=!0,Fi(()=>{e._assigning=!1})}),e[Ie]=pt(n)},mounted(e,{value:t}){di(e,t)},beforeUpdate(e,t,s){e[Ie]=pt(s)},updated(e,{value:t}){e._assigning||di(e,t)}};function di(e,t){const s=e.multiple,n=L(t);if(!(s&&!n&&!zt(t))){for(let i=0,o=e.options.length;iString(g)===String(a)):r.selected=fn(t,a)>-1}else r.selected=t.has(a);else if(ut(Ot(r),t)){e.selectedIndex!==i&&(e.selectedIndex=i);return}}!s&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Ot(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 qa={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 Za(e,t){switch(e){case"SELECT":return ks;case"TEXTAREA":return be;default:switch(t){case"checkbox":return Ka;case"radio":return Wa;default:return be}}}function ds(e,t,s,n,i){const r=Za(e.tagName,s.props&&s.props.type)[i];r&&r(e,t,s,n)}const Ja=["ctrl","shift","alt","meta"],Ya={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)=>Ja.some(s=>e[`${s}Key`]&&!t.includes(s))},Xa=(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=ft(i.key);if(t.some(r=>r===o||Qa[r]===o))return e(i)}))},el=_e({patchProp:Ba},Sa);let pi;function tl(){return pi||(pi=ia(el))}const sl=((...e)=>{const t=tl().createApp(...e),{mount:s}=t;return t.mount=n=>{const i=il(n);if(!i)return;const o=t._component;!W(o)&&!o.render&&!o.template&&(o.template=i.innerHTML),i.nodeType===1&&(i.textContent="");const r=s(i,!1,nl(i));return i instanceof Element&&(i.removeAttribute("v-cloak"),i.setAttribute("data-v-app","")),r},t});function nl(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function il(e){return ue(e)?document.querySelector(e):e}const ko="dh-panel-theme";function ol(){var e;try{const t=localStorage.getItem(ko);if(t==="dark"||t==="light")return t}catch{}return(e=window.matchMedia)!=null&&e.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light"}const Ct=H(ol());function To(e){Ct.value=e,document.documentElement.classList.toggle("dark",e==="dark");try{localStorage.setItem(ko,e)}catch{}}function fi(){To(Ct.value==="dark"?"light":"dark")}To(Ct.value);const rl={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."},al={overview:"Overview",users:"Users",orgs:"Organizations",server:"API Server",pocketbase:"PocketBase",webapp:"Web App",plugins:"Plugins",api:"API"},ll={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"},cl={title:"Status",unreachable:"unreachable",checking:"Checking…",apiServer:"API Server",pocketBase:"PocketBase",webApp:"Web App",thisProcess:"this process"},ul={create:"Create",save:"Save",cancel:"Cancel",edit:"Edit",delete:"Delete",rename:"Rename",empty:"—",name:"Name",email:"Email",role:"Role",organization:"Organization"},dl={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."},pl={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.'},fl={title:"API Server",subtitle:"How this server identifies itself to the clients that connect to it",name:"Server name",nameHint:"Shown by clients that can be pointed at more than one DriverVault, such as the Web App's server switcher. Reported by /api/health.",saveApply:"Save & apply",persistedEnv:"persisted to .env",savedNotice:"Saved. The new name applies to the next request."},hl={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."},gl={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."},ml={title:"Plugins",subtitle:"Third-party service integrations",categories:{vehicles:"Car manufacturers",chargers:"EV chargers",notifications:"Notifications","apis-external":"Other APIs","drives-external":"Remote drives","drives-local":"Local drives"},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.'},bl={colEndpoint:"Endpoint",colDescription:"Description",authNone:"No auth",authBearer:"Bearer token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Charger credentials",groupPublic:"Public",groupIdentity:"Identity",groupCars:"Cars",groupService:"Service records",groupTechnical:"Technical checks",groupParts:"Parts",groupFuel:"Fuel",groupCharging:"Charging",groupMaintenance:"Maintenance",groupDocuments:"Documents",groupReminders:"Reminders",groupAttachments:"Attachments",groupProviders:"Vehicle providers",groupIntegrations:"Integrations",groupOcpp:"OCPP",groupAccount:"Account",groupManagement:"Management",groupSuperadmin:"Superadmin"},vl={app:rl,sections:al,login:ll,status:cl,common:ul,users:dl,orgs:pl,server:fl,pocketbase:hl,webapp:gl,plugins:ml,api:bl},yl={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."},_l={overview:"Przegląd",users:"Użytkownicy",orgs:"Organizacje",server:"Serwer API",pocketbase:"PocketBase",webapp:"Aplikacja webowa",plugins:"Wtyczki",api:"API"},wl={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"},xl={title:"Status",unreachable:"niedostępny",checking:"Sprawdzanie…",apiServer:"Serwer API",pocketBase:"PocketBase",webApp:"Aplikacja webowa",thisProcess:"ten proces"},kl={create:"Utwórz",save:"Zapisz",cancel:"Anuluj",edit:"Edytuj",delete:"Usuń",rename:"Zmień nazwę",empty:"—",name:"Nazwa",email:"E-mail",role:"Rola",organization:"Organizacja"},Tl={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ąć."},Sl={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."},El={title:"Serwer API",subtitle:"Jak ten serwer przedstawia się klientom, które się z nim łączą",name:"Nazwa serwera",nameHint:"Widoczna w klientach, które można skierować na więcej niż jeden DriverVault, na przykład w przełączniku serwerów aplikacji webowej. Zwracana przez /api/health.",saveApply:"Zapisz i zastosuj",persistedEnv:"zapisano w .env",savedNotice:"Zapisano. Nowa nazwa obowiązuje od następnego żądania."},Pl={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."},Cl={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."},Al={title:"Wtyczki",subtitle:"Integracje z usługami zewnętrznymi",categories:{vehicles:"Producenci samochodów",chargers:"Ładowarki EV",notifications:"Powiadomienia","apis-external":"Pozostałe API","drives-external":"Dyski zdalne","drives-local":"Dyski lokalne"},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."},$l={colEndpoint:"Punkt końcowy",colDescription:"Opis",authNone:"Bez uwierzytelniania",authBearer:"Token Bearer",authManager:"Administrator / superadministrator",authSuperadmin:"Superadministrator",authCharger:"Dane logowania ładowarki",groupPublic:"Publiczne",groupIdentity:"Tożsamość",groupCars:"Samochody",groupService:"Wpisy serwisowe",groupTechnical:"Przeglądy techniczne",groupParts:"Części",groupFuel:"Paliwo",groupCharging:"Ładowanie",groupMaintenance:"Naprawy",groupDocuments:"Dokumenty",groupReminders:"Przypomnienia",groupAttachments:"Załączniki",groupProviders:"Dostawcy pojazdów",groupIntegrations:"Integracje",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Zarządzanie",groupSuperadmin:"Superadministrator"},Ol={app:yl,sections:_l,login:wl,status:xl,common:kl,users:Tl,orgs:Sl,server:El,pocketbase:Pl,webapp:Cl,plugins:Al,api:$l},Dl={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."},Rl={overview:"Oversigt",users:"Brugere",orgs:"Organisationer",server:"API-server",pocketbase:"PocketBase",webapp:"Webapp",plugins:"Plugins",api:"API"},zl={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"},Il={title:"Status",unreachable:"utilgængelig",checking:"Tjekker…",apiServer:"API-server",pocketBase:"PocketBase",webApp:"Webapp",thisProcess:"denne proces"},jl={create:"Opret",save:"Gem",cancel:"Annuller",edit:"Rediger",delete:"Slet",rename:"Omdøb",empty:"—",name:"Navn",email:"E-mail",role:"Rolle",organization:"Organisation"},Ul={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."},Nl={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."},Ml={title:"API-server",subtitle:"Hvordan denne server identificerer sig over for de klienter, der forbinder til den",name:"Servernavn",nameHint:"Vises af klienter, der kan pege på mere end én DriverVault, for eksempel webappens serverskifter. Returneres af /api/health.",saveApply:"Gem og anvend",persistedEnv:"gemt i .env",savedNotice:"Gemt. Det nye navn gælder fra næste anmodning."},Ll={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."},Fl={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."},Bl={title:"Plugins",subtitle:"Integrationer med tredjepartstjenester",categories:{vehicles:"Bilproducenter",chargers:"EV-ladere",notifications:"Notifikationer","apis-external":"Øvrige API'er","drives-external":"Eksterne drev","drives-local":"Lokale drev"},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.'},Hl={colEndpoint:"Endpoint",colDescription:"Beskrivelse",authNone:"Ingen godkendelse",authBearer:"Bearer-token",authManager:"Admin / superadmin",authSuperadmin:"Superadmin",authCharger:"Laderens loginoplysninger",groupPublic:"Offentlig",groupIdentity:"Identitet",groupCars:"Biler",groupService:"Serviceposter",groupTechnical:"Syn",groupParts:"Reservedele",groupFuel:"Brændstof",groupCharging:"Opladning",groupMaintenance:"Værksted",groupDocuments:"Dokumenter",groupReminders:"Påmindelser",groupAttachments:"Vedhæftede filer",groupProviders:"Køretøjsudbydere",groupIntegrations:"Integrationer",groupOcpp:"OCPP",groupAccount:"Konto",groupManagement:"Administration",groupSuperadmin:"Superadmin"},Vl={app:Dl,sections:Rl,login:zl,status:Il,common:jl,users:Ul,orgs:Nl,server:Ml,pocketbase:Ll,webapp:Fl,plugins:Bl,api:Hl},So="dh-panel-lang",Eo="en",Dt={en:vl,pl:Ol,da:Vl},Gl=Object.keys(Dt);function Kl(){try{const t=localStorage.getItem(So);if(t&&Dt[t])return t}catch{}const e=(navigator.language||"en").split("-")[0];return Dt[e]?e:Eo}const En=H(Kl());function Wl(e){if(Dt[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 ql(e,t){return t?e.replace(/\{(\w+)\}/g,(s,n)=>t[n]==null?s:String(t[n])):e}function Zl(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 f(e,t){const s=En.value;let n=hi(Dt[s],e);if(n==null&&(n=hi(Dt[Eo],e)),n==null)return e;if(typeof n=="object"){if((t==null?void 0:t.n)==null)return e;n=Zl(n,t.n,s)}return typeof n!="string"?e:ql(n,t)}function gi(e,t,s){const i=f(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 ln="dh-panel-token";function Jl(){try{return localStorage.getItem(ln)||""}catch{return""}}const Rt=H(Jl()),he=H(null),De=Oe(()=>{var e;return((e=he.value)==null?void 0:e.role)==="superadmin"}),gs=Oe(()=>{var e,t;return((e=he.value)==null?void 0:e.role)==="admin"||((t=he.value)==null?void 0:t.role)==="superadmin"});function Po(e){Rt.value=e;try{e?localStorage.setItem(ln,e):localStorage.removeItem(ln)}catch{}}class Yl extends Error{constructor(t,s,n){super(t),this.status=s,this.body=n}}function Xl(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 ae(e,{method:t="GET",body:s,auth:n=!0}={}){const i={};s!==void 0&&(i["Content-Type"]="application/json"),n&&Rt.value&&(i.Authorization=Rt.value);const o=await fetch(e,{method:t,headers:i,body:s===void 0?void 0:JSON.stringify(s)}),r=await o.text();let a=null;try{a=r?JSON.parse(r):null}catch{a=null}if(!o.ok)throw o.status===401&&n&&Pn(),new Yl(Xl(a,o.status),o.status,a);return a}async function Ql(e,t){const s=await ae("/api/auth/login",{method:"POST",body:{email:e,password:t},auth:!1});return Po(s.token),await Ts(),he.value}async function Ts(){return he.value=await ae("/api/identity"),he.value}function Pn(){Po(""),he.value=null}async function ec(){if(!Rt.value)return null;try{return await Ts()}catch{return Pn(),null}}const tc={class:"inline-flex items-center gap-2.5 select-none"},sc={class:"h-full w-auto shrink-0",viewBox:"0 0 48 48",fill:"none","aria-hidden":"true"},nc={transform:"translate(7 0) skewX(-13)"},ic=["fill"],oc=["fill"],rc=["fill"],ac={key:0,class:"text-[1.35em] font-extrabold italic leading-none tracking-[-0.03em]"},lc={__name:"Logo",props:{iconOnly:{type:Boolean,default:!1},onDark:{type:Boolean,default:!1}},setup(e){return(t,s)=>(y(),T("span",tc,[(y(),T("svg",sc,[u("g",nc,[u("rect",{x:"9",y:"16",width:"6",height:"16",rx:"3",fill:e.onDark?"#60A5FA":"var(--brand-700)"},null,8,ic),u("rect",{x:"19",y:"12",width:"6",height:"24",rx:"3",fill:e.onDark?"#93C5FD":"var(--brand-500)"},null,8,oc),u("rect",{x:"29",y:"8",width:"6",height:"32",rx:"3",fill:e.onDark?"#ffffff":"var(--brand-400)"},null,8,rc)])])),e.iconOnly?F("",!0):(y(),T("span",ac,[u("span",{class:Ee(e.onDark?"text-white":"text-strong")},"Driver",2),u("span",{class:Ee(e.onDark?"text-brand-400":"text-brandtext")},"Vault",2)])),s[0]||(s[0]=u("span",{class:"sr-only"},"DriverVault",-1))]))}},cc={class:"mx-auto flex w-full max-w-sm flex-col gap-5 pt-24"},uc={class:"dh-card p-6"},dc={class:"text-lg font-bold tracking-[-0.02em] text-strong"},pc={class:"mt-1 mb-5 text-sm text-body"},fc={class:"dh-label",for:"login-email"},hc={class:"dh-label",for:"login-password"},gc={key:0,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},mc=["disabled"],bc={class:"eyebrow text-center"},vc={__name:"LoginView",emits:["authenticated"],setup(e,{emit:t}){const s=t,n=H(""),i=H(""),o=H(""),r=H(!1),a=Oe(()=>n.value.trim()!==""&&i.value!==""&&!r.value);async function l(){if(a.value){o.value="",r.value=!0;try{const g=await Ql(n.value.trim(),i.value);s("authenticated",g)}catch(g){o.value=g.status===400||g.status===404?f("login.invalid"):g.message||f("login.failed"),i.value=""}finally{r.value=!1}}}return(g,d)=>(y(),T("div",cc,[u("div",uc,[u("h1",dc,m(h(f)("login.title")),1),u("p",pc,m(h(f)("login.subtitle")),1),u("form",{class:"flex flex-col gap-4",onSubmit:Xa(l,["prevent"])},[u("div",null,[u("label",fc,m(h(f)("login.email")),1),pe(u("input",{id:"login-email","onUpdate:modelValue":d[0]||(d[0]=b=>n.value=b),class:"dh-input",type:"email",autocomplete:"username",autofocus:"",placeholder:"you@example.com"},null,512),[[be,n.value]])]),u("div",null,[u("label",hc,m(h(f)("login.password")),1),pe(u("input",{id:"login-password","onUpdate:modelValue":d[1]||(d[1]=b=>i.value=b),class:"dh-input",type:"password",autocomplete:"current-password",placeholder:"••••••••"},null,512),[[be,i.value]])]),o.value?(y(),T("p",gc,m(o.value),1)):F("",!0),u("button",{class:"dh-btn w-full",type:"submit",disabled:!a.value},m(r.value?h(f)("login.submitting"):h(f)("login.submit")),9,mc)],32)]),u("p",bc,m(h(f)("login.authNote")),1)]))}},yc={class:"dh-card overflow-hidden"},_c={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},wc={class:"text-base font-bold tracking-[-0.02em] text-strong"},xc={key:0,class:"dh-pill bg-danger-soft text-danger"},kc={key:0,class:"px-5 py-4 text-sm text-danger"},Tc={key:1,class:"w-full text-left text-sm"},Sc={class:"px-5 py-3 font-medium text-strong"},Ec={class:"data px-5 py-3 text-xs text-muted"},Pc={class:"data px-5 py-3 text-right text-xs text-muted"},Cc={class:"px-5 py-3 text-right"},Ac={key:2,class:"px-5 py-4 text-sm text-muted"},$c={__name:"StatusCard",setup(e){const t=H(null),s=H("");let n=null;async function i(){try{t.value=await ae("/api/status",{auth:!1}),s.value=""}catch(a){t.value=null,s.value=a.message||f("status.unreachable")}}const o=Oe(()=>{var a,l,g;return[{key:"apiServer",label:f("status.apiServer"),h:(a=t.value)==null?void 0:a.apiServer},{key:"pocketBase",label:f("status.pocketBase"),h:(l=t.value)==null?void 0:l.pocketBase},{key:"webApp",label:f("status.webApp"),h:(g=t.value)==null?void 0:g.webApp}]});lt(()=>{i(),n=setInterval(i,1e4)}),kn(()=>clearInterval(n));const r=a=>a==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger";return(a,l)=>(y(),T("div",yc,[u("div",_c,[u("div",wc,m(h(f)("status.title")),1),s.value?(y(),T("span",xc,[l[0]||(l[0]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(h(f)("status.unreachable")),1)])):F("",!0)]),s.value?(y(),T("div",kc,m(s.value),1)):t.value?(y(),T("table",Tc,[u("tbody",null,[(y(!0),T(re,null,Ce(o.value,g=>(y(),T("tr",{key:g.key,class:"border-t border-subtle first:border-t-0"},[u("td",Sc,m(g.label),1),u("td",Ec,m(g.h.url||h(f)("status.thisProcess")),1),u("td",Pc,m(g.h.latencyMs!=null?g.h.latencyMs+"ms":h(f)("common.empty")),1),u("td",Cc,[u("span",{class:Ee(["dh-pill",r(g.h.status)])},[l[1]||(l[1]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(g.h.status),1)],2)])]))),128))])])):(y(),T("div",Ac,m(h(f)("status.checking")),1))]))}},Oc={class:"dh-card overflow-hidden"},Dc={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Rc={class:"text-base font-bold tracking-[-0.02em] text-strong"},zc={class:"mt-0.5 text-xs text-muted"},Ic={class:"flex flex-col gap-4 px-5 py-4"},jc={class:"dh-label",for:"pb-url"},Uc={class:"grid gap-4 sm:grid-cols-2"},Nc={class:"dh-label",for:"pb-email"},Mc={class:"dh-label",for:"pb-password"},Lc=["placeholder"],Fc={key:0,class:"data text-xs text-muted"},Bc={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},Hc={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},Vc={class:"flex items-center gap-2"},Gc=["disabled"],Kc=["disabled"],Wc={class:"eyebrow"},qc={__name:"PocketBaseCard",setup(e){const t=H(null),s=H({url:"",adminEmail:"",adminPassword:""}),n=H(null),i=H(""),o=H(""),r=H(!1);async function a(){try{t.value=await ae("/api/admin/pb-config"),s.value={url:t.value.url,adminEmail:t.value.adminEmail,adminPassword:""},n.value=t.value.probe}catch(d){i.value=d.message}}lt(a);async function l(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/pb-config/test",{method:"POST",body:s.value}),o.value=n.value.superuser?f("pocketbase.testOk"):n.value.reachable?f("pocketbase.testReachableNoAuth"):f("pocketbase.testUnreachable")}catch(d){i.value=d.message}finally{r.value=!1}}async function g(){i.value="",o.value="",r.value=!0;try{const d=await ae("/api/admin/pb-config",{method:"PUT",body:s.value});t.value=d.config,n.value=d.config.probe,s.value.adminPassword="",o.value=d.warning||f("pocketbase.savedNotice")}catch(d){i.value=d.message}finally{r.value=!1}}return(d,b)=>{var E,A;return y(),T("div",Oc,[u("div",Dc,[u("div",null,[u("div",Rc,m(h(f)("pocketbase.title")),1),u("p",zc,m(h(f)("pocketbase.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.superuser?"bg-success-soft text-success":n.value.reachable?"bg-warning-soft text-warning":"bg-danger-soft text-danger"])},[b[3]||(b[3]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.superuser?h(f)("pocketbase.connected"):n.value.reachable?h(f)("pocketbase.noSuperuser"):h(f)("pocketbase.unreachable")),1)],2)):F("",!0)]),u("div",Ic,[u("div",null,[u("label",jc,m(h(f)("pocketbase.baseUrl")),1),pe(u("input",{id:"pb-url","onUpdate:modelValue":b[0]||(b[0]=V=>s.value.url=V),class:"dh-input",placeholder:"http://10.2.1.10:8027"},null,512),[[be,s.value.url]])]),u("div",Uc,[u("div",null,[u("label",Nc,m(h(f)("pocketbase.superuserEmail")),1),pe(u("input",{id:"pb-email","onUpdate:modelValue":b[1]||(b[1]=V=>s.value.adminEmail=V),class:"dh-input",autocomplete:"off"},null,512),[[be,s.value.adminEmail]])]),u("div",null,[u("label",Mc,m(h(f)("pocketbase.superuserPassword")),1),pe(u("input",{id:"pb-password","onUpdate:modelValue":b[2]||(b[2]=V=>s.value.adminPassword=V),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:(E=t.value)!=null&&E.adminConfigured?h(f)("pocketbase.passwordUnchanged"):h(f)("pocketbase.passwordNotSet")},null,8,Lc),[[be,s.value.adminPassword]])])]),(A=n.value)!=null&&A.detail?(y(),T("p",Fc,m(n.value.detail),1)):F("",!0),o.value?(y(),T("p",Bc,m(o.value),1)):F("",!0),i.value?(y(),T("p",Hc,m(i.value),1)):F("",!0),u("div",Vc,[u("button",{class:"dh-btn",disabled:r.value,onClick:g},m(h(f)("pocketbase.saveApply")),9,Gc),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:l},m(h(f)("pocketbase.testConnection")),9,Kc),b[4]||(b[4]=u("span",{class:"flex-1"},null,-1)),u("span",Wc,m(h(f)("pocketbase.persistedEnv")),1)])])])}}},Zc={class:"dh-card overflow-hidden"},Jc={class:"border-b border-subtle px-5 py-4"},Yc={class:"text-base font-bold tracking-[-0.02em] text-strong"},Xc={class:"mt-0.5 text-xs text-muted"},Qc={class:"flex flex-col gap-4 px-5 py-4"},eu={class:"dh-label",for:"server-name"},tu={class:"mt-1 text-xs text-muted"},su={key:0,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},nu={key:1,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},iu={class:"flex items-center gap-2"},ou=["disabled"],ru={class:"eyebrow"},au={__name:"ServerCard",setup(e){const t=H({name:""}),s=H(""),n=H(""),i=H(!1);async function o(){try{const a=await ae("/api/admin/server-config");t.value={name:a.name}}catch(a){s.value=a.message}}lt(o);async function r(){s.value="",n.value="",i.value=!0;try{const a=await ae("/api/admin/server-config",{method:"PUT",body:{name:t.value.name}});t.value={name:a.config.name},n.value=a.warning||f("server.savedNotice")}catch(a){s.value=a.message}finally{i.value=!1}}return(a,l)=>(y(),T("div",Zc,[u("div",Jc,[u("div",Yc,m(h(f)("server.title")),1),u("p",Xc,m(h(f)("server.subtitle")),1)]),u("div",Qc,[u("div",null,[u("label",eu,m(h(f)("server.name")),1),pe(u("input",{id:"server-name","onUpdate:modelValue":l[0]||(l[0]=g=>t.value.name=g),class:"dh-input",maxlength:"64",placeholder:"DriverVault API Server",onKeyup:xo(r,["enter"])},null,544),[[be,t.value.name]]),u("p",tu,m(h(f)("server.nameHint")),1)]),n.value?(y(),T("p",su,m(n.value),1)):F("",!0),s.value?(y(),T("p",nu,m(s.value),1)):F("",!0),u("div",iu,[u("button",{class:"dh-btn",disabled:i.value,onClick:r},m(h(f)("server.saveApply")),9,ou),l[1]||(l[1]=u("span",{class:"flex-1"},null,-1)),u("span",ru,m(h(f)("server.persistedEnv")),1)])])]))}},lu={class:"dh-card overflow-hidden"},cu={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},uu={class:"text-base font-bold tracking-[-0.02em] text-strong"},du={class:"mt-0.5 text-xs text-muted"},pu={class:"flex flex-col gap-4 px-5 py-4"},fu={class:"dh-label",for:"web-url"},hu={class:"dh-label",for:"web-origins"},gu={class:"mt-1 text-xs text-muted"},mu={key:0,class:"data text-xs text-muted"},bu={key:1,class:"rounded-control bg-info-soft px-3 py-2 text-xs text-info"},vu={key:2,class:"rounded-control bg-danger-soft px-3 py-2 text-xs text-danger"},yu={class:"flex items-center gap-2"},_u=["disabled"],wu=["disabled"],xu={class:"eyebrow"},ku={__name:"WebAppCard",setup(e){const t=H(null),s=H({url:"",origins:""}),n=H(null),i=H(""),o=H(""),r=H(!1),a=E=>E.split(",").map(A=>A.trim()).filter(Boolean);function l(E){t.value=E,s.value={url:E.url,origins:(E.allowOrigins||[]).join(", ")},n.value=E.probe}async function g(){try{l(await ae("/api/admin/webapp-config"))}catch(E){i.value=E.message}}lt(g);async function d(){i.value="",o.value="",r.value=!0;try{n.value=await ae("/api/admin/webapp-config/test",{method:"POST",body:{url:s.value.url}}),o.value=n.value.status==="ok"?f("webapp.testOk"):f("webapp.testFailed")}catch(E){i.value=E.message}finally{r.value=!1}}async function b(){i.value="",o.value="",r.value=!0;try{const E=await ae("/api/admin/webapp-config",{method:"PUT",body:{url:s.value.url,allowOrigins:a(s.value.origins)}});l(E.config),o.value=E.warning||f("webapp.savedNotice")}catch(E){i.value=E.message}finally{r.value=!1}}return(E,A)=>{var V;return y(),T("div",lu,[u("div",cu,[u("div",null,[u("div",uu,m(h(f)("webapp.title")),1),u("p",du,m(h(f)("webapp.subtitle")),1)]),n.value?(y(),T("span",{key:0,class:Ee(["dh-pill",n.value.status==="ok"?"bg-success-soft text-success":"bg-danger-soft text-danger"])},[A[2]||(A[2]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(" "+m(n.value.status==="ok"?h(f)("webapp.reachable"):h(f)("webapp.unreachable")),1)],2)):F("",!0)]),u("div",pu,[u("div",null,[u("label",fu,m(h(f)("webapp.baseUrl")),1),pe(u("input",{id:"web-url","onUpdate:modelValue":A[0]||(A[0]=x=>s.value.url=x),class:"dh-input",placeholder:"http://localhost:8090"},null,512),[[be,s.value.url]])]),u("div",null,[u("label",hu,m(h(f)("webapp.allowedOrigins")),1),pe(u("input",{id:"web-origins","onUpdate:modelValue":A[1]||(A[1]=x=>s.value.origins=x),class:"dh-input",placeholder:"http://localhost:8090, https://app.example.com"},null,512),[[be,s.value.origins]]),u("p",gu,[$e(m(h(gi)("webapp.originsHint","star").before),1),A[3]||(A[3]=u("span",{class:"data"},"*",-1)),$e(m(h(gi)("webapp.originsHint","star").after),1)])]),(V=n.value)!=null&&V.error?(y(),T("p",mu,m(n.value.error),1)):F("",!0),o.value?(y(),T("p",bu,m(o.value),1)):F("",!0),i.value?(y(),T("p",vu,m(i.value),1)):F("",!0),u("div",yu,[u("button",{class:"dh-btn",disabled:r.value,onClick:b},m(h(f)("webapp.saveApply")),9,_u),u("button",{class:"dh-btn-ghost",disabled:r.value,onClick:d},m(h(f)("webapp.testConnection")),9,wu),A[4]||(A[4]=u("span",{class:"flex-1"},null,-1)),u("span",xu,m(h(f)("webapp.persistedEnv")),1)])])])}}},Tu={class:"dh-card overflow-hidden"},Su={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Eu={class:"text-base font-bold tracking-[-0.02em] text-strong"},Pu={class:"mt-0.5 text-xs text-muted"},Cu={key:0,class:"border-b border-subtle bg-sunken px-5 py-4"},Au={class:"grid gap-3 sm:grid-cols-3"},$u={class:"dh-label"},Ou={class:"dh-label"},Du={class:"dh-label"},Ru=["disabled"],zu={key:1,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Iu={key:2,class:"px-5 py-6 text-center text-sm text-muted"},ju={key:3,class:"flex flex-wrap gap-1.5 border-b border-subtle px-5 py-3"},Uu=["onClick"],Nu={class:"dh-pill bg-sunken text-muted"},Mu={class:"flex items-center gap-3 px-5 py-3"},Lu=["onClick"],Fu={class:"font-semibold text-strong"},Bu={class:"dh-pill bg-sunken text-muted"},Hu={key:0,class:"text-xs text-muted"},Vu=["disabled","onClick"],Gu=["disabled","onClick"],Ku={key:0,class:"bg-sunken px-5 py-4"},Wu={key:0,class:"data mb-3 text-xs text-muted"},qu={key:1,class:"grid gap-3 sm:grid-cols-2"},Zu={class:"dh-label"},Ju={key:0,class:"text-danger"},Yu=["onUpdate:modelValue"],Xu={key:0,value:""},Qu=["value"],ed=["onUpdate:modelValue","type","placeholder"],td={key:2,class:"mt-1 text-xs text-muted"},sd={key:2,class:"text-xs text-muted"},nd={key:3,class:"mt-4"},id={class:"eyebrow mb-1.5"},od={class:"data flex flex-col gap-1 text-xs text-muted"},rd={class:"text-strong"},ad={key:0},ld={key:1},cd={key:4,class:"data mt-3 text-xs text-body"},ud={class:"mt-4 flex items-center gap-2"},dd=["disabled","onClick"],pd=["disabled","onClick"],fd=["disabled","onClick"],hd={key:5,class:"eyebrow mt-2"},gd={__name:"PluginsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=Yt({}),r=Yt({}),a=H(!1),l=H({name:"",baseURL:"",provider:""}),g=H(""),d=["vehicles","chargers","notifications","apis-external","drives-external","drives-local"],b=z=>d.includes(z.category)?z.category:"apis-external",E=Oe(()=>{var K;const z={};for(const P of t.value)(z[K=b(P)]||(z[K]=[])).push(P);return d.filter(P=>z[P]).map(P=>({id:P,label:f(`plugins.categories.${P}`),plugins:z[P]}))}),A=Oe(()=>E.value.find(z=>z.id===g.value)||E.value[0]),V=Oe(()=>{var z;return((z=A.value)==null?void 0:z.plugins)||[]});async function x(){try{const z=await ae("/api/admin/plugins");t.value=z.plugins||[],s.value=""}catch(z){s.value=z.message}}lt(x);function N(z){var P;if(i.value===z.name){i.value=null;return}const K={};for(const I of z.configFields||[])K[I.key]=((P=z.config)==null?void 0:P[I.key])??"";o[z.name]=K,i.value=z.name}async function R(z,K){n.value=!0,r[z.name]="";try{const P=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"PUT",body:{enabled:K,config:o[z.name]??{}}});r[z.name]=P.warning||f("plugins.saved"),await x()}catch(P){r[z.name]=P.message}finally{n.value=!1}}async function G(z){n.value=!0,r[z.name]=f("plugins.checking");try{const K=await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}/health`,{method:"POST"});r[z.name]=`${K.health.status}${K.health.detail?" — "+K.health.detail:""}`,await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}async function Z(z){if(confirm(f("plugins.confirmRemove",{name:z.name}))){n.value=!0;try{await ae(`/api/admin/plugins/${encodeURIComponent(z.name)}`,{method:"DELETE"}),i.value===z.name&&(i.value=null),await x()}catch(K){r[z.name]=K.message}finally{n.value=!1}}}async function U(){n.value=!0,s.value="";try{await ae("/api/admin/plugins",{method:"POST",body:l.value}),l.value={name:"",baseURL:"",provider:""},a.value=!1,await x()}catch(z){s.value=z.message}finally{n.value=!1}}const le=z=>z==="ok"?"bg-success-soft text-success":z==="degraded"?"bg-warning-soft text-warning":"bg-danger-soft text-danger";return(z,K)=>(y(),T("div",Tu,[u("div",Su,[u("div",null,[u("div",Eu,m(h(f)("plugins.title")),1),u("p",Pu,m(h(f)("plugins.subtitle")),1)]),u("button",{class:"dh-btn-ghost",onClick:K[0]||(K[0]=P=>a.value=!a.value)},m(a.value?h(f)("plugins.cancelRegister"):h(f)("plugins.registerExternal")),1)]),a.value?(y(),T("div",Cu,[u("div",Au,[u("div",null,[u("label",$u,m(h(f)("plugins.name")),1),pe(u("input",{"onUpdate:modelValue":K[1]||(K[1]=P=>l.value.name=P),class:"dh-input",placeholder:"acme-parts"},null,512),[[be,l.value.name]])]),u("div",null,[u("label",Ou,m(h(f)("plugins.baseUrl")),1),pe(u("input",{"onUpdate:modelValue":K[2]||(K[2]=P=>l.value.baseURL=P),class:"dh-input",placeholder:"http://127.0.0.1:9100"},null,512),[[be,l.value.baseURL]])]),u("div",null,[u("label",Du,m(h(f)("plugins.provider")),1),pe(u("input",{"onUpdate:modelValue":K[3]||(K[3]=P=>l.value.provider=P),class:"dh-input",placeholder:"ACME Corp"},null,512),[[be,l.value.provider]])])]),u("button",{class:"dh-btn mt-3",disabled:n.value||!l.value.name||!l.value.baseURL,onClick:U},m(h(f)("plugins.register")),9,Ru)])):F("",!0),s.value?(y(),T("p",zu,m(s.value),1)):F("",!0),t.value.length?F("",!0):(y(),T("p",Iu,m(h(f)("plugins.empty")),1)),E.value.length>1?(y(),T("nav",ju,[(y(!0),T(re,null,Ce(E.value,P=>{var I;return y(),T("button",{key:P.id,class:Ee(["dh-btn-ghost",((I=A.value)==null?void 0:I.id)===P.id?"border-accent text-brandtext":""]),onClick:J=>g.value=P.id},[$e(m(P.label)+" ",1),u("span",Nu,m(P.plugins.length),1)],10,Uu)}),128))])):F("",!0),(y(!0),T(re,null,Ce(V.value,P=>(y(),T("div",{key:P.name,class:"border-t border-subtle first:border-t-0"},[u("div",Mu,[u("button",{class:"flex flex-1 items-center gap-3 text-left",onClick:I=>N(P)},[u("span",Fu,m(P.name),1),u("span",Bu,m(P.kind||h(f)("plugins.builtin")),1),P.provider?(y(),T("span",Hu,m(P.provider),1)):F("",!0),P.health?(y(),T("span",{key:1,class:Ee(["dh-pill",le(P.health.status)])},[K[4]||(K[4]=u("span",{class:"h-1.5 w-1.5 rounded-full bg-current"},null,-1)),$e(m(P.health.status),1)],2)):F("",!0)],8,Lu),u("span",{class:Ee(["dh-pill",P.enabled?"bg-success-soft text-success":"bg-sunken text-muted"])},m(P.enabled?h(f)("plugins.enabled"):h(f)("plugins.disabled")),3),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>G(P)},m(h(f)("plugins.health")),9,Vu),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:I=>N(P)},m(i.value===P.name?h(f)("plugins.close"):h(f)("plugins.configure")),9,Gu)]),i.value===P.name?(y(),T("div",Ku,[P.baseURL?(y(),T("div",Wu,m(P.baseURL),1)):F("",!0),(P.configFields||[]).length?(y(),T("div",qu,[(y(!0),T(re,null,Ce(P.configFields,I=>(y(),T("div",{key:I.key},[u("label",Zu,[$e(m(I.label||I.key),1),I.required?(y(),T("span",Ju," *")):F("",!0)]),I.type==="select"?pe((y(),T("select",{key:0,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-select"},[I.required?F("",!0):(y(),T("option",Xu,m(h(f)("plugins.notSet")),1)),(y(!0),T(re,null,Ce(I.options||[],J=>(y(),T("option",{key:J.value,value:J.value},m(J.label||J.value),9,Qu))),128))],8,Yu)),[[ks,o[P.name][I.key]]]):pe((y(),T("input",{key:1,"onUpdate:modelValue":J=>o[P.name][I.key]=J,class:"dh-input",type:I.type==="password"?"password":I.type==="number"?"number":"text",placeholder:I.default||"",autocomplete:"off"},null,8,ed)),[[qa,o[P.name][I.key]]]),I.help?(y(),T("p",td,m(I.help),1)):F("",!0)]))),128))])):(y(),T("p",sd,m(h(f)("plugins.noConfig")),1)),(P.capabilities||[]).length?(y(),T("div",nd,[u("div",id,m(h(f)("plugins.capabilities")),1),u("ul",od,[(y(!0),T(re,null,Ce(P.capabilities,I=>(y(),T("li",{key:I.id},[u("span",rd,m(I.id),1),I.method||I.endpoint?(y(),T("span",ad," — "+m(I.method)+" "+m(I.endpoint),1)):F("",!0),I.description?(y(),T("span",ld," · "+m(I.description),1)):F("",!0)]))),128))])])):F("",!0),r[P.name]?(y(),T("p",cd,m(r[P.name]),1)):F("",!0),u("div",ud,[u("button",{class:"dh-btn",disabled:n.value,onClick:I=>R(P,!0)},m(P.enabled?h(f)("plugins.save"):h(f)("plugins.saveEnable")),9,dd),P.enabled?(y(),T("button",{key:0,class:"dh-btn-ghost",disabled:n.value,onClick:I=>R(P,!1)},m(h(f)("plugins.disable")),9,pd)):F("",!0),K[5]||(K[5]=u("span",{class:"flex-1"},null,-1)),P.kind==="external"?(y(),T("button",{key:1,class:"dh-btn-danger",disabled:n.value,onClick:I=>Z(P)},m(h(f)("plugins.remove")),9,fd)):F("",!0)]),P.kind!=="external"?(y(),T("p",hd,m(h(f)("plugins.builtinNote")),1)):F("",!0)])):F("",!0)]))),128))]))}},md={class:"dh-card overflow-hidden"},bd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},vd={class:"text-base font-bold tracking-[-0.02em] text-strong"},yd={class:"mt-0.5 text-xs text-muted"},_d={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},wd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},xd={class:"grid gap-3 sm:grid-cols-2"},kd={class:"dh-label"},Td={class:"dh-label"},Sd={class:"dh-label"},Ed=["placeholder"],Pd={class:"dh-label"},Cd=["value"],Ad={key:0},$d={class:"dh-label"},Od={value:""},Dd=["value"],Rd={class:"mt-3 flex items-center gap-2"},zd=["disabled"],Id=["disabled"],jd={key:2,class:"px-5 py-6 text-center text-sm text-muted"},Ud={key:3,class:"w-full text-left text-sm"},Nd={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},Md={class:"data px-5 py-2.5 text-xs text-strong"},Ld={key:0,class:"eyebrow ml-1"},Fd={class:"px-5 py-2.5 text-body"},Bd={class:"px-5 py-2.5 text-body"},Hd={class:"px-5 py-2.5"},Vd={class:"px-5 py-2.5 text-right whitespace-nowrap"},Gd=["onClick"],Kd=["disabled","onClick"],Wd={__name:"UsersCard",setup(e){const t=H([]),s=H([]),n=H(""),i=H(!1),o=H(null),r=H({}),a=Oe(()=>De.value?["user","admin","superadmin"]:["user","admin"]);async function l(){try{const[x,N]=await Promise.all([ae("/api/users"),ae("/api/orgs")]);t.value=x.users||[],s.value=N.organizations||[],n.value=""}catch(x){n.value=x.message}}lt(l);function g(){var x;o.value="new",r.value={email:"",name:"",password:"",role:"user",organization:De.value?"":((x=he.value)==null?void 0:x.organization)||""}}function d(x){o.value=x.id,r.value={email:x.email,name:x.name||"",password:"",role:x.role,organization:x.organization||""}}function b(){o.value=null,n.value=""}async function E(){i.value=!0,n.value="";try{if(o.value==="new")await ae("/api/users",{method:"POST",body:r.value});else{const x={...r.value};x.password||delete x.password,await ae(`/api/users/${o.value}`,{method:"PATCH",body:x})}o.value=null,await l()}catch(x){n.value=x.message}finally{i.value=!1}}async function A(x){if(confirm(f("users.confirmDelete",{email:x.email}))){i.value=!0,n.value="";try{await ae(`/api/users/${x.id}`,{method:"DELETE"}),await l()}catch(N){n.value=N.message}finally{i.value=!1}}}const V=x=>x==="superadmin"?"bg-info-soft text-info":x==="admin"?"bg-warning-soft text-warning":"bg-sunken text-muted";return(x,N)=>(y(),T("div",md,[u("div",bd,[u("div",null,[u("div",vd,m(h(f)("users.title")),1),u("p",yd,m(h(De)?h(f)("users.allOrgs"):h(f)("users.yourOrg")),1)]),u("button",{class:"dh-btn",onClick:g},m(h(f)("users.newUser")),1)]),n.value?(y(),T("p",_d,m(n.value),1)):F("",!0),o.value?(y(),T("div",wd,[u("div",xd,[u("div",null,[u("label",kd,m(h(f)("common.email")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>r.value.email=R),class:"dh-input",type:"email",autocomplete:"off"},null,512),[[be,r.value.email]])]),u("div",null,[u("label",Td,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[1]||(N[1]=R=>r.value.name=R),class:"dh-input",autocomplete:"off"},null,512),[[be,r.value.name]])]),u("div",null,[u("label",Sd,m(o.value==="new"?h(f)("users.password"):h(f)("users.passwordUnchanged")),1),pe(u("input",{"onUpdate:modelValue":N[2]||(N[2]=R=>r.value.password=R),class:"dh-input",type:"password",autocomplete:"new-password",placeholder:h(f)("users.passwordPlaceholder")},null,8,Ed),[[be,r.value.password]])]),u("div",null,[u("label",Pd,m(h(f)("common.role")),1),pe(u("select",{"onUpdate:modelValue":N[3]||(N[3]=R=>r.value.role=R),class:"dh-select"},[(y(!0),T(re,null,Ce(a.value,R=>(y(),T("option",{key:R,value:R},m(R),9,Cd))),128))],512),[[ks,r.value.role]])]),h(De)?(y(),T("div",Ad,[u("label",$d,m(h(f)("common.organization")),1),pe(u("select",{"onUpdate:modelValue":N[4]||(N[4]=R=>r.value.organization=R),class:"dh-select"},[u("option",Od,m(h(f)("users.orgNone")),1),(y(!0),T(re,null,Ce(s.value,R=>(y(),T("option",{key:R.id,value:R.id},m(R.name),9,Dd))),128))],512),[[ks,r.value.organization]])])):F("",!0)]),u("div",Rd,[u("button",{class:"dh-btn",disabled:i.value,onClick:E},m(o.value==="new"?h(f)("common.create"):h(f)("common.save")),9,zd),u("button",{class:"dh-btn-ghost",disabled:i.value,onClick:b},m(h(f)("common.cancel")),9,Id)])])):F("",!0),t.value.length?(y(),T("table",Ud,[u("thead",null,[u("tr",Nd,[u("th",null,m(h(f)("common.email")),1),u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("common.organization")),1),u("th",null,m(h(f)("common.role")),1),N[5]||(N[5]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>{var G,Z;return y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",Md,[$e(m(R.email)+" ",1),R.id===((G=h(he))==null?void 0:G.id)?(y(),T("span",Ld,m(h(f)("users.you")),1)):F("",!0)]),u("td",Fd,m(R.name||h(f)("common.empty")),1),u("td",Bd,m(R.organizationName||h(f)("common.empty")),1),u("td",Hd,[u("span",{class:Ee(["dh-pill",V(R.role)])},m(R.role),3)]),u("td",Vd,[u("button",{class:"dh-btn-ghost",onClick:U=>d(R)},m(h(f)("common.edit")),9,Gd),R.id!==((Z=h(he))==null?void 0:Z.id)?(y(),T("button",{key:0,class:"dh-btn-danger ml-1.5",disabled:i.value,onClick:U=>A(R)},m(h(f)("common.delete")),9,Kd)):F("",!0)])])}),128))])])):(y(),T("p",jd,m(h(f)("users.empty")),1))]))}},qd={class:"dh-card overflow-hidden"},Zd={class:"flex items-center justify-between border-b border-subtle px-5 py-4"},Jd={class:"text-base font-bold tracking-[-0.02em] text-strong"},Yd={class:"mt-0.5 text-xs text-muted"},Xd={key:0,class:"border-b border-subtle px-5 py-3 text-xs text-danger"},Qd={key:1,class:"border-b border-subtle bg-sunken px-5 py-4"},ep={class:"dh-label"},tp=["placeholder"],sp={class:"mt-3 flex items-center gap-2"},np=["disabled"],ip=["disabled"],op={key:2,class:"px-5 py-6 text-center text-sm text-muted"},rp={key:3,class:"w-full text-left text-sm"},ap={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},lp={class:"px-5 py-2.5 font-medium text-strong"},cp={class:"data px-5 py-2.5 text-xs text-muted"},up={class:"px-5 py-2.5 text-right whitespace-nowrap"},dp=["onClick"],pp=["disabled","onClick"],fp={__name:"OrgsCard",setup(e){const t=H([]),s=H(""),n=H(!1),i=H(null),o=H(""),r=Oe(()=>{var x;return((x=he.value)==null?void 0:x.organization)||""}),a=Oe(()=>De.value||!r.value);function l(x){return De.value||x.id===r.value}async function g(){if(!gs.value){t.value=[];return}try{const x=await ae("/api/orgs");t.value=x.organizations||[],s.value=""}catch(x){s.value=x.message}}lt(g);function d(){i.value="new",o.value=""}function b(x){i.value=x.id,o.value=x.name}function E(){i.value=null,s.value=""}async function A(){n.value=!0,s.value="";try{i.value==="new"?(await ae("/api/orgs",{method:"POST",body:{name:o.value}}),De.value||await Ts()):await ae(`/api/orgs/${i.value}`,{method:"PATCH",body:{name:o.value}}),i.value=null,await g()}catch(x){s.value=x.message}finally{n.value=!1}}async function V(x){const N=!De.value&&x.id===r.value;if(confirm(f(N?"orgs.confirmDeleteOwn":"orgs.confirmDelete",{name:x.name}))){n.value=!0,s.value="";try{await ae(`/api/orgs/${x.id}`,{method:"DELETE"}),N&&await Ts(),await g()}catch(G){s.value=G.message}finally{n.value=!1}}}return(x,N)=>(y(),T("div",qd,[u("div",Zd,[u("div",null,[u("div",Jd,m(h(De)?h(f)("orgs.title"):h(f)("common.organization")),1),u("p",Yd,m(h(De)?h(f)("orgs.subtitle"):r.value?h(f)("orgs.subtitleOwn"):h(f)("orgs.subtitleNone")),1)]),a.value?(y(),T("button",{key:0,class:"dh-btn",onClick:d},m(h(f)("orgs.newOrg")),1)):F("",!0)]),s.value?(y(),T("p",Xd,m(s.value),1)):F("",!0),i.value?(y(),T("div",Qd,[u("label",ep,m(h(f)("common.name")),1),pe(u("input",{"onUpdate:modelValue":N[0]||(N[0]=R=>o.value=R),class:"dh-input",placeholder:h(f)("orgs.namePlaceholder"),onKeyup:xo(A,["enter"])},null,40,tp),[[be,o.value]]),u("div",sp,[u("button",{class:"dh-btn",disabled:n.value||!o.value.trim(),onClick:A},m(i.value==="new"?h(f)("common.create"):h(f)("common.save")),9,np),u("button",{class:"dh-btn-ghost",disabled:n.value,onClick:E},m(h(f)("common.cancel")),9,ip)])])):F("",!0),t.value.length?(y(),T("table",rp,[u("thead",null,[u("tr",ap,[u("th",null,m(h(f)("common.name")),1),u("th",null,m(h(f)("orgs.colId")),1),N[1]||(N[1]=u("th",null,null,-1))])]),u("tbody",null,[(y(!0),T(re,null,Ce(t.value,R=>(y(),T("tr",{key:R.id,class:"border-t border-subtle transition-colors hover:bg-sunken"},[u("td",lp,m(R.name),1),u("td",cp,m(R.id),1),u("td",up,[l(R)?(y(),T(re,{key:0},[u("button",{class:"dh-btn-ghost",onClick:G=>b(R)},m(h(f)("common.rename")),9,dp),u("button",{class:"dh-btn-danger ml-1.5",disabled:n.value,onClick:G=>V(R)},m(h(f)("common.delete")),9,pp)],64)):F("",!0)])]))),128))])])):(y(),T("p",op,m(a.value&&!h(De)?h(f)("orgs.createHint"):h(f)("orgs.empty")),1))]))}},hp={class:"dh-card overflow-hidden"},gp={class:"border-b border-subtle px-5 py-4"},mp={class:"flex items-center justify-between"},bp={class:"text-base font-bold tracking-[-0.02em] text-strong"},vp={class:"eyebrow"},yp={key:0,class:"mt-1.5 text-xs text-muted"},_p={class:"overflow-x-auto"},wp={class:"w-full text-left text-sm"},xp={class:"[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium"},kp={class:"data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap"},Tp={class:"text-strong"},Sp={class:"border-t border-subtle px-5 py-2.5 text-body"},fe={__name:"EndpointTable",props:{title:String,auth:String,endpoints:Array,note:String},setup(e){const t={GET:"text-success",POST:"text-brandtext",PUT:"text-info",PATCH:"text-warning",DELETE:"text-danger"};return(s,n)=>(y(),T("div",hp,[u("div",gp,[u("div",mp,[u("div",bp,m(e.title),1),u("span",vp,m(e.auth),1)]),e.note?(y(),T("p",yp,m(e.note),1)):F("",!0)]),u("div",_p,[u("table",wp,[u("thead",null,[u("tr",xp,[u("th",null,m(h(f)("api.colEndpoint")),1),u("th",null,m(h(f)("api.colDescription")),1)])]),u("tbody",null,[(y(!0),T(re,null,Ce(e.endpoints,i=>(y(),T("tr",{key:i.method+i.path,class:"transition-colors hover:bg-sunken"},[u("td",kp,[u("span",{class:Ee(["font-semibold",t[i.method]])},m(i.method),3),u("span",Tp,m(i.path),1)]),u("td",Sp,m(i.desc),1)]))),128))])])])]))}},Ep={class:"mx-auto flex max-w-[1368px] flex-col gap-6 px-6 pt-12 pb-16"},Pp={class:"flex items-center gap-3"},Cp={class:"eyebrow mt-1.5"},Ap={key:0,class:"data hidden text-xs text-muted sm:inline"},$p={key:0},Op={key:1,class:"dh-pill bg-info-soft text-info"},Dp=["value","aria-label"],Rp=["value"],zp=["title"],Ip={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"},jp={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"},Up={key:0,class:"eyebrow py-16 text-center"},Np={class:"flex flex-wrap gap-1.5"},Mp=["onClick"],Lp={key:8,class:"eyebrow text-center"},Fp={class:"eyebrow text-center"},Bp="{records} is any of service-records, technical-checks, maintenance, fuel-entries, charging-sessions, car-documents, parts.",Hp={__name:"App",setup(e){const t=H(!0),s=H("overview");lt(async()=>{await ec(),t.value=!1});const n=Oe(()=>{const P=[{id:"overview",label:f("sections.overview")}];return gs.value&&P.push({id:"users",label:f("sections.users")}),(gs.value||he.value)&&P.push({id:"orgs",label:f("sections.orgs")}),De.value&&P.push({id:"server",label:f("sections.server")},{id:"pocketbase",label:f("sections.pocketbase")},{id:"webapp",label:f("sections.webapp")},{id:"plugins",label:f("sections.plugins")}),P.push({id:"api",label:f("sections.api")}),P}),i=Oe(()=>Gl.map(P=>{let I=P;try{I=new Intl.DisplayNames([P],{type:"language"}).of(P)||P}catch{}return{code:P,label:I.charAt(0).toUpperCase()+I.slice(1)}}));function o(){Pn(),s.value="overview"}const r=[{method:"GET",path:"/api/health",desc:"Liveness probe (no auth)"},{method:"GET",path:"/healthz",desc:"The same probe under the conventional container path"},{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"}],l=[{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:"PUT",path:"/api/cars/{id}/view",desc:"Save the car's layout — hidden tabs/fields/columns and their order"},{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}/technical-checks",desc:"A car's roadworthiness inspections"},{method:"GET",path:"/api/cars/{id}/parts",desc:"A car's parts catalog"},{method:"GET",path:"/api/cars/{id}/fuel-entries",desc:"A car's refuelings"},{method:"GET",path:"/api/cars/{id}/fuel-stats",desc:"Consumption + cost totals from the fuel log"},{method:"GET",path:"/api/cars/{id}/charging-sessions",desc:"A car's charging sessions"},{method:"GET",path:"/api/cars/{id}/charging-stats",desc:"Energy + cost totals from the charging log"},{method:"GET",path:"/api/cars/{id}/maintenance",desc:"A car's maintenance log"},{method:"GET",path:"/api/cars/{id}/documents",desc:"A car's documents"},{method:"GET",path:"/api/cars/{id}/reminders",desc:"A car's reminders"},{method:"GET",path:"/api/cars/{id}/provider",desc:"Live snapshot from the car's connected service"},{method:"POST",path:"/api/cars/{id}/provider",desc:"Link the car to a provider vehicle (an empty provider unlinks)"},{method:"POST",path:"/api/cars/{id}/provider/sync",desc:"Re-apply the provider's data to the car"},{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)"}],g=[{method:"GET",path:"/api/service-records",desc:"List one car's service records (?car={id})"},{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"}],d=[{method:"GET",path:"/api/technical-checks",desc:"List one car's inspections (?car={id})"},{method:"POST",path:"/api/technical-checks",desc:"Log an inspection"},{method:"GET",path:"/api/technical-checks/{id}",desc:"Fetch one inspection"},{method:"PATCH",path:"/api/technical-checks/{id}",desc:"Update an inspection"},{method:"DELETE",path:"/api/technical-checks/{id}",desc:"Delete an inspection"}],b=[{method:"GET",path:"/api/parts",desc:"List one car's parts (?car={id})"},{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"}],E=[{method:"GET",path:"/api/fuel-entries",desc:"List one car's refuelings (?car={id})"},{method:"POST",path:"/api/fuel-entries",desc:"Log a refueling"},{method:"GET",path:"/api/fuel-entries/{id}",desc:"Fetch one refueling"},{method:"PATCH",path:"/api/fuel-entries/{id}",desc:"Update a refueling"},{method:"DELETE",path:"/api/fuel-entries/{id}",desc:"Delete a refueling"}],A=[{method:"GET",path:"/api/charging-sessions",desc:"List one car's charging sessions (?car={id})"},{method:"POST",path:"/api/charging-sessions",desc:"Log a charging session"},{method:"GET",path:"/api/charging-sessions/{id}",desc:"Fetch one session"},{method:"PATCH",path:"/api/charging-sessions/{id}",desc:"Update a session"},{method:"DELETE",path:"/api/charging-sessions/{id}",desc:"Delete a session"}],V=[{method:"GET",path:"/api/maintenance",desc:"List one car's maintenance jobs (?car={id})"},{method:"POST",path:"/api/maintenance",desc:"Log a maintenance job"},{method:"GET",path:"/api/maintenance/{id}",desc:"Fetch one job"},{method:"PATCH",path:"/api/maintenance/{id}",desc:"Update a job"},{method:"DELETE",path:"/api/maintenance/{id}",desc:"Delete a job"}],x=[{method:"GET",path:"/api/car-documents",desc:"List one car's documents (?car={id})"},{method:"POST",path:"/api/car-documents",desc:"Add a document"},{method:"GET",path:"/api/car-documents/{id}",desc:"Fetch one document"},{method:"PATCH",path:"/api/car-documents/{id}",desc:"Update a document"},{method:"DELETE",path:"/api/car-documents/{id}",desc:"Delete a document"}],N=[{method:"GET",path:"/api/reminders",desc:"List one car's reminders (?car={id})"},{method:"POST",path:"/api/reminders",desc:"Create a reminder"},{method:"GET",path:"/api/reminders/{id}",desc:"Fetch one reminder"},{method:"PATCH",path:"/api/reminders/{id}",desc:"Update a reminder"},{method:"DELETE",path:"/api/reminders/{id}",desc:"Delete a reminder"},{method:"POST",path:"/api/reminders/{id}/complete",desc:"Mark done — a recurring reminder rolls forward from now"}],R=[{method:"POST",path:"/api/{records}/{id}/file",desc:"Attach a file, replacing any previous one (PDF or image, max 10 MB)"},{method:"GET",path:"/api/{records}/{id}/file",desc:"Download the attachment (car access re-checked on every request)"},{method:"DELETE",path:"/api/{records}/{id}/file",desc:"Detach and delete the file"}],G=[{method:"GET",path:"/api/vehicle-providers",desc:"Registered providers and whether the caller can use each one"},{method:"GET",path:"/api/vehicle-providers/{provider}/vehicles",desc:"Vehicles on the caller's provider account, as importable cars"},{method:"POST",path:"/api/vehicle-providers/{provider}/import",desc:"Create a car from a provider vehicle (409 if already imported)"}],Z=[{method:"GET",path:"/api/integrations/toyota",desc:"Resolved Toyota Connected settings (secrets masked)"},{method:"PUT",path:"/api/integrations/toyota",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/toyota/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/toyota/vehicles",desc:"Raw MyToyota vehicle payload"},{method:"GET",path:"/api/integrations/anker-solix",desc:"Resolved Anker Solix settings (secrets masked)"},{method:"PUT",path:"/api/integrations/anker-solix",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/anker-solix/health",desc:"Live probe with the resolved credentials"},{method:"GET",path:"/api/integrations/anker-solix/chargers",desc:"EV chargers on the linked Anker account"},{method:"GET",path:"/api/integrations/anker-solix/chargers/{sn}/control",desc:"Control mode, token state and live CSMS session for one charger"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"(Re)issue the charger's control token"},{method:"DELETE",path:"/api/integrations/anker-solix/chargers/{sn}/control/token",desc:"Revoke the control token"},{method:"POST",path:"/api/integrations/anker-solix/chargers/{sn}/{action}",desc:"One OCPP command: start, stop, limit, clear-limit, availability, reset, unlock, trigger, config"},{method:"GET",path:"/api/integrations/greencell",desc:"Resolved Greencell settings (secrets masked)"},{method:"PUT",path:"/api/integrations/greencell",desc:"Save the caller's own layer (user or org scope)"},{method:"POST",path:"/api/integrations/greencell/health",desc:"Live probe: connect to the broker and broadcast for devices"},{method:"GET",path:"/api/integrations/greencell/chargers",desc:"Greencell chargers answering on the configured MQTT broker"},{method:"GET",path:"/api/integrations/greencell/chargers/{sn}/state",desc:"Live EVSE state, access level, power and per-phase current/voltage"}],U=[{method:"GET",path:"/ocpp/{serial}",desc:"WebSocket the charger dials out to; OCPP Basic auth with the serial + its control token"}],le=[{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"}],z=[{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)"}],K=[{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/server-config",desc:"This server's display name"},{method:"PUT",path:"/api/admin/server-config",desc:"Rename this server (applied + persisted)"},{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(P,I)=>(y(),T("div",Ep,[u("div",Pp,[ee(lc,{"on-dark":h(Ct)==="dark",class:"h-7"},null,8,["on-dark"]),u("span",Cp,m(h(f)("app.apiServer")),1),I[4]||(I[4]=u("div",{class:"flex-1"},null,-1)),h(he)?(y(),T("span",Ap,[$e(m(h(he).email),1),h(he).organizationName?(y(),T("span",$p," · "+m(h(he).organizationName),1)):F("",!0)])):F("",!0),h(he)?(y(),T("span",Op,m(h(he).role),1)):F("",!0),u("select",{class:"dh-select !w-auto !py-1 !text-xs",value:h(En),"aria-label":h(f)("sections.overview"),onChange:I[0]||(I[0]=J=>h(Wl)(J.target.value))},[(y(!0),T(re,null,Ce(i.value,J=>(y(),T("option",{key:J.code,value:J.code},m(J.label),9,Rp))),128))],40,Dp),u("button",{class:"dh-btn-ghost",title:h(Ct)==="dark"?h(f)("app.switchToLight"):h(f)("app.switchToDark"),onClick:I[1]||(I[1]=(...J)=>h(fi)&&h(fi)(...J))},[h(Ct)==="dark"?(y(),T("svg",Ip,[...I[2]||(I[2]=[u("circle",{cx:"12",cy:"12",r:"4"},null,-1),u("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)])])):(y(),T("svg",jp,[...I[3]||(I[3]=[u("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)])])),$e(" "+m(h(f)("app.theme")),1)],8,zp),h(Rt)?(y(),T("button",{key:2,class:"dh-btn-ghost",onClick:o},m(h(f)("app.signOut")),1)):F("",!0)]),t.value?(y(),T("p",Up,m(h(f)("app.loading")),1)):h(Rt)?(y(),T(re,{key:2},[u("nav",Np,[(y(!0),T(re,null,Ce(n.value,J=>(y(),T("button",{key:J.id,class:Ee(["dh-btn-ghost",s.value===J.id?"border-accent text-brandtext":""]),onClick:wt=>s.value=J.id},m(J.label),11,Mp))),128))]),s.value==="overview"?(y(),et($c,{key:0})):s.value==="users"?(y(),et(Wd,{key:1})):s.value==="orgs"?(y(),et(fp,{key:2})):s.value==="server"?(y(),et(au,{key:3})):s.value==="pocketbase"?(y(),et(qc,{key:4})):s.value==="webapp"?(y(),et(ku,{key:5})):s.value==="plugins"?(y(),et(gd,{key:6})):s.value==="api"?(y(),T(re,{key:7},[ee(fe,{title:h(f)("api.groupPublic"),auth:h(f)("api.authNone"),endpoints:r},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIdentity"),auth:h(f)("api.authBearer"),endpoints:a},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCars"),auth:h(f)("api.authBearer"),endpoints:l},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupService"),auth:h(f)("api.authBearer"),endpoints:g},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupTechnical"),auth:h(f)("api.authBearer"),endpoints:d},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupParts"),auth:h(f)("api.authBearer"),endpoints:b},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupFuel"),auth:h(f)("api.authBearer"),endpoints:E},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupCharging"),auth:h(f)("api.authBearer"),endpoints:A},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupMaintenance"),auth:h(f)("api.authBearer"),endpoints:V},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupDocuments"),auth:h(f)("api.authBearer"),endpoints:x},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupReminders"),auth:h(f)("api.authBearer"),endpoints:N},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAttachments"),auth:h(f)("api.authBearer"),endpoints:R,note:Bp},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupProviders"),auth:h(f)("api.authBearer"),endpoints:G},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupIntegrations"),auth:h(f)("api.authBearer"),endpoints:Z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupOcpp"),auth:h(f)("api.authCharger"),endpoints:U},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupAccount"),auth:h(f)("api.authBearer"),endpoints:le},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupManagement"),auth:h(f)("api.authManager"),endpoints:z},null,8,["title","auth"]),ee(fe,{title:h(f)("api.groupSuperadmin"),auth:h(f)("api.authSuperadmin"),endpoints:K},null,8,["title","auth"])],64)):F("",!0),!h(gs)&&s.value==="overview"?(y(),T("p",Lp,m(h(f)("app.standardUserNote")),1)):F("",!0)],64)):(y(),et(vc,{key:1})),u("p",Fp,m(h(f)("app.footer")),1)]))}};sl(Hp).mount("#app"); diff --git a/API Server/internal/api/dist/assets/index-C26jpIre.css b/API Server/internal/api/dist/assets/index-C26jpIre.css deleted file mode 100644 index e7c7c53..0000000 --- a/API Server/internal/api/dist/assets/index-C26jpIre.css +++ /dev/null @@ -1 +0,0 @@ -@import"https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;0,700;0,800;1,700;1,800&family=DM+Mono:ital,wght@0,400;0,500&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-control:12px;--radius-card:18px;--radius-pill:999px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-full{height:100%}.\!w-auto{width:auto!important}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-auto{width:auto}.w-full{width:100%}.max-w-4xl{max-width:var(--container-4xl)}.max-w-sm{max-width:var(--container-sm)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-control{border-radius:12px}.rounded-full{border-radius:3.40282e38px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-accent{border-color:var(--accent)}.border-subtle{border-color:var(--border-subtle)}.bg-current{background-color:currentColor}.bg-danger-soft{background-color:var(--danger-100)}.bg-info-soft{background-color:var(--info-100)}.bg-success-soft{background-color:var(--success-100)}.bg-sunken{background-color:var(--surface-sunken)}.bg-warning-soft{background-color:var(--warning-100)}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.\!py-1{padding-block:var(--spacing)!important}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[1\.35em\]{font-size:1.35em}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.03em\]{--tw-tracking:-.03em;letter-spacing:-.03em}.whitespace-nowrap{white-space:nowrap}.text-body{color:var(--text-body)}.text-brand-400{color:var(--brand-400)}.text-brandtext{color:var(--text-brand)}.text-danger{color:var(--danger-600)}.text-info{color:var(--info-600)}.text-muted{color:var(--text-muted)}.text-strong{color:var(--text-strong)}.text-success{color:var(--success-600)}.text-warning{color:var(--warning-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}@media(hover:hover){.hover\:bg-sunken:hover{background-color:var(--surface-sunken)}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&\>th\]\:px-5>th{padding-inline:calc(var(--spacing) * 5)}.\[\&\>th\]\:py-2\.5>th{padding-block:calc(var(--spacing) * 2.5)}.\[\&\>th\]\:font-medium>th{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}}:root{color-scheme:light;--brand-900:#0b1730;--brand-800:#0f1e3d;--brand-700:#1e40af;--brand-600:#2563eb;--brand-500:#3b82f6;--brand-400:#60a5fa;--brand-300:#93c5fd;--brand-200:#c7dbfb;--brand-100:#e8f0fd;--ink-900:#0f1e3d;--ink-700:#28374f;--ink-600:#3e4e68;--ink-500:#5c6b85;--ink-400:#7a8aa6;--ink-300:#b4bece;--ink-200:#d6deea;--ink-100:#e4e9f2;--ink-50:#eef2f8;--ink-25:#f7f9fc;--white:#fff;--success-600:#1f8a5b;--success-100:#e1f3ea;--warning-600:#d9822b;--warning-100:#fbeddd;--danger-600:#dc2a45;--danger-100:#fbe3e7;--info-600:#2563eb;--info-100:#e8f0fd;--surface-page:var(--ink-25);--surface-card:var(--white);--surface-sunken:var(--ink-50);--border-subtle:var(--ink-100);--border-default:var(--ink-200);--border-strong:var(--ink-300);--text-strong:var(--ink-900);--text-body:var(--ink-600);--text-muted:var(--ink-400);--text-brand:var(--brand-700);--accent:var(--brand-600);--accent-hover:var(--brand-700);--focus-ring:var(--brand-400);--shadow-xs:0 1px 2px #0f1e3d0f;--shadow-sm:0 1px 2px #0f1e3d0a, 0 2px 6px #0f1e3d0f;--shadow-md:0 1px 2px #0f1e3d0a, 0 12px 30px -12px #0f1e3d24;--font-display:"Archivo", system-ui, sans-serif;--font-sans:"Archivo", system-ui, sans-serif;--font-mono:"DM Mono", ui-monospace, "SF Mono", monospace}html.dark{color-scheme:dark;--success-100:#12352a;--warning-100:#3a2a16;--danger-100:#3a1620;--info-100:#122a4d;--surface-page:#0b1730;--surface-card:#13233f;--surface-sunken:#0f1e38;--border-subtle:#21324f;--border-default:#2c3f5e;--border-strong:#3c5173;--text-strong:#f2f6fc;--text-body:#b7c4d9;--text-muted:#7c8ca8;--text-brand:#93c5fd;--accent:#3b82f6;--accent-hover:#60a5fa;--focus-ring:#60a5fa;--success-600:#35b27a;--warning-600:#e0a03a;--danger-600:#e85c74;--shadow-xs:0 1px 2px #0006;--shadow-sm:0 1px 2px #0006, 0 2px 6px #0006;--shadow-md:0 1px 2px #00000059, 0 12px 30px -12px #0000008c}html,body,#app{height:100%}body{font-family:var(--font-sans);background:var(--surface-page);color:var(--text-body);-webkit-font-smoothing:antialiased;margin:0}.eyebrow{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);font-size:11px}.data{font-family:var(--font-mono);letter-spacing:.02em;font-variant-numeric:tabular-nums}.dh-btn-ghost{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);height:34px;color:var(--text-strong);font-family:var(--font-sans);cursor:pointer;justify-content:center;align-items:center;gap:8px;padding:0 12px;font-size:.8125rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-ghost:hover{background:var(--surface-sunken);border-color:var(--border-strong)}.dh-btn-ghost:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn{border-radius:var(--radius-control);background:var(--accent);color:#fff;height:34px;font-family:var(--font-sans);cursor:pointer;border:1px solid #0000;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:.8125rem;font-weight:600;transition:background-color .14s;display:inline-flex}.dh-btn:hover:not(:disabled){background:var(--accent-hover)}.dh-btn:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn:disabled,.dh-btn-ghost:disabled,.dh-btn-danger:disabled{opacity:.55;cursor:not-allowed}.dh-btn-danger{border-radius:var(--radius-control);border:1px solid var(--border-default);height:30px;color:var(--danger-600);font-family:var(--font-sans);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:6px;padding:0 10px;font-size:.75rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-danger:hover:not(:disabled){background:var(--danger-100);border-color:var(--danger-600)}.dh-input,.dh-select{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);width:100%;height:36px;color:var(--text-strong);font-family:var(--font-sans);padding:0 10px;font-size:.8125rem;transition:border-color .14s}.dh-input::placeholder{color:var(--text-muted)}.dh-input:focus,.dh-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-label{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);margin-bottom:5px;font-size:10px;display:block}.dh-pill{border-radius:var(--radius-pill);font-family:var(--font-mono);white-space:nowrap;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:500;display:inline-flex}.dh-card{border:1px solid var(--border-subtle);background:var(--surface-card);border-radius:var(--radius-card);box-shadow:var(--shadow-sm)}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false} diff --git a/API Server/internal/api/dist/assets/index-_8IdQ1wh.css b/API Server/internal/api/dist/assets/index-_8IdQ1wh.css new file mode 100644 index 0000000..43e6581 --- /dev/null +++ b/API Server/internal/api/dist/assets/index-_8IdQ1wh.css @@ -0,0 +1 @@ +@import"https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;0,700;0,800;1,700;1,800&family=DM+Mono:ital,wght@0,400;0,500&display=swap";/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--shadow-xs:var(--shadow-xs);--shadow-sm:var(--shadow-sm);--shadow-md:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--radius-control:12px;--radius-card:18px;--radius-pill:999px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-full{height:100%}.\!w-auto{width:auto!important}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-auto{width:auto}.w-full{width:100%}.max-w-\[1368px\]{max-width:1368px}.max-w-sm{max-width:var(--container-sm)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded-control{border-radius:12px}.rounded-full{border-radius:3.40282e38px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-accent{border-color:var(--accent)}.border-subtle{border-color:var(--border-subtle)}.bg-current{background-color:currentColor}.bg-danger-soft{background-color:var(--danger-100)}.bg-info-soft{background-color:var(--info-100)}.bg-success-soft{background-color:var(--success-100)}.bg-sunken{background-color:var(--surface-sunken)}.bg-warning-soft{background-color:var(--warning-100)}.p-6{padding:calc(var(--spacing) * 6)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.\!py-1{padding-block:var(--spacing)!important}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-12{padding-top:calc(var(--spacing) * 12)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pb-16{padding-bottom:calc(var(--spacing) * 16)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.\!text-xs{font-size:var(--text-xs)!important;line-height:var(--tw-leading,var(--text-xs--line-height))!important}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[1\.35em\]{font-size:1.35em}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.02em\]{--tw-tracking:-.02em;letter-spacing:-.02em}.tracking-\[-0\.03em\]{--tw-tracking:-.03em;letter-spacing:-.03em}.whitespace-nowrap{white-space:nowrap}.text-body{color:var(--text-body)}.text-brand-400{color:var(--brand-400)}.text-brandtext{color:var(--text-brand)}.text-danger{color:var(--danger-600)}.text-info{color:var(--info-600)}.text-muted{color:var(--text-muted)}.text-strong{color:var(--text-strong)}.text-success{color:var(--success-600)}.text-warning{color:var(--warning-600)}.text-white{color:var(--color-white)}.italic{font-style:italic}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}@media(hover:hover){.hover\:bg-sunken:hover{background-color:var(--surface-sunken)}}@media(min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.\[\&\>th\]\:px-5>th{padding-inline:calc(var(--spacing) * 5)}.\[\&\>th\]\:py-2\.5>th{padding-block:calc(var(--spacing) * 2.5)}.\[\&\>th\]\:font-medium>th{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}}:root{color-scheme:light;--brand-900:#0b1730;--brand-800:#0f1e3d;--brand-700:#1e40af;--brand-600:#2563eb;--brand-500:#3b82f6;--brand-400:#60a5fa;--brand-300:#93c5fd;--brand-200:#c7dbfb;--brand-100:#e8f0fd;--ink-900:#0f1e3d;--ink-700:#28374f;--ink-600:#3e4e68;--ink-500:#5c6b85;--ink-400:#7a8aa6;--ink-300:#b4bece;--ink-200:#d6deea;--ink-100:#e4e9f2;--ink-50:#eef2f8;--ink-25:#f7f9fc;--white:#fff;--success-600:#1f8a5b;--success-100:#e1f3ea;--warning-600:#d9822b;--warning-100:#fbeddd;--danger-600:#dc2a45;--danger-100:#fbe3e7;--info-600:#2563eb;--info-100:#e8f0fd;--surface-page:var(--ink-25);--surface-card:var(--white);--surface-sunken:var(--ink-50);--border-subtle:var(--ink-100);--border-default:var(--ink-200);--border-strong:var(--ink-300);--text-strong:var(--ink-900);--text-body:var(--ink-600);--text-muted:var(--ink-400);--text-brand:var(--brand-700);--accent:var(--brand-600);--accent-hover:var(--brand-700);--focus-ring:var(--brand-400);--shadow-xs:0 1px 2px #0f1e3d0f;--shadow-sm:0 1px 2px #0f1e3d0a, 0 2px 6px #0f1e3d0f;--shadow-md:0 1px 2px #0f1e3d0a, 0 12px 30px -12px #0f1e3d24;--font-display:"Archivo", system-ui, sans-serif;--font-sans:"Archivo", system-ui, sans-serif;--font-mono:"DM Mono", ui-monospace, "SF Mono", monospace}html.dark{color-scheme:dark;--success-100:#12352a;--warning-100:#3a2a16;--danger-100:#3a1620;--info-100:#122a4d;--surface-page:#0b1730;--surface-card:#13233f;--surface-sunken:#0f1e38;--border-subtle:#21324f;--border-default:#2c3f5e;--border-strong:#3c5173;--text-strong:#f2f6fc;--text-body:#b7c4d9;--text-muted:#7c8ca8;--text-brand:#93c5fd;--accent:#3b82f6;--accent-hover:#60a5fa;--focus-ring:#60a5fa;--success-600:#35b27a;--warning-600:#e0a03a;--danger-600:#e85c74;--shadow-xs:0 1px 2px #0006;--shadow-sm:0 1px 2px #0006, 0 2px 6px #0006;--shadow-md:0 1px 2px #00000059, 0 12px 30px -12px #0000008c}html,body,#app{height:100%}body{font-family:var(--font-sans);background:var(--surface-page);color:var(--text-body);-webkit-font-smoothing:antialiased;margin:0}.eyebrow{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);font-size:11px}.data{font-family:var(--font-mono);letter-spacing:.02em;font-variant-numeric:tabular-nums}.dh-btn-ghost{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);height:34px;color:var(--text-strong);font-family:var(--font-sans);cursor:pointer;justify-content:center;align-items:center;gap:8px;padding:0 12px;font-size:.8125rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-ghost:hover{background:var(--surface-sunken);border-color:var(--border-strong)}.dh-btn-ghost:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn{border-radius:var(--radius-control);background:var(--accent);color:#fff;height:34px;font-family:var(--font-sans);cursor:pointer;border:1px solid #0000;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:.8125rem;font-weight:600;transition:background-color .14s;display:inline-flex}.dh-btn:hover:not(:disabled){background:var(--accent-hover)}.dh-btn:focus-visible{box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-btn:disabled,.dh-btn-ghost:disabled,.dh-btn-danger:disabled{opacity:.55;cursor:not-allowed}.dh-btn-danger{border-radius:var(--radius-control);border:1px solid var(--border-default);height:30px;color:var(--danger-600);font-family:var(--font-sans);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:6px;padding:0 10px;font-size:.75rem;font-weight:600;transition:background-color .14s,border-color .14s;display:inline-flex}.dh-btn-danger:hover:not(:disabled){background:var(--danger-100);border-color:var(--danger-600)}.dh-input,.dh-select{border-radius:var(--radius-control);border:1px solid var(--border-default);background:var(--surface-card);width:100%;height:36px;color:var(--text-strong);font-family:var(--font-sans);padding:0 10px;font-size:.8125rem;transition:border-color .14s}.dh-input::placeholder{color:var(--text-muted)}.dh-input:focus,.dh-select:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring);outline:none}.dh-label{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.16em;color:var(--text-muted);margin-bottom:5px;font-size:10px;display:block}.dh-pill{border-radius:var(--radius-pill);font-family:var(--font-mono);white-space:nowrap;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:500;display:inline-flex}.dh-card{border:1px solid var(--border-subtle);background:var(--surface-card);border-radius:var(--radius-card);box-shadow:var(--shadow-sm)}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false} diff --git a/API Server/internal/api/dist/index.html b/API Server/internal/api/dist/index.html index 87ce2ec..3832a77 100644 --- a/API Server/internal/api/dist/index.html +++ b/API Server/internal/api/dist/index.html @@ -6,8 +6,8 @@ DriverVault · API Server - - + +
diff --git a/API Server/panel/src/App.vue b/API Server/panel/src/App.vue index b8fbb21..c3de40b 100644 --- a/API Server/panel/src/App.vue +++ b/API Server/panel/src/App.vue @@ -261,7 +261,7 @@ const superadminApi = [