API panel: document the whole REST surface, not half of it
The API section's tables are hand-maintained and carry a comment saying they
mirror the routes in server.go. They had stopped: 60 rows against 141 routes,
so 81 endpoints were reachable and undocumented. Everything added since the
tables were written is in that gap - technical checks, fuel, charging,
maintenance, documents, reminders, attachments, the vehicle-provider and
integration surfaces, and the OCPP socket - along with the per-car
sub-resources (fuel-stats, charging-stats, the provider routes) and
PUT /api/cars/{id}/view. Ten new groups, 60 rows to 123, and nothing listed
that no longer exists.
Checked by extracting every mux.Handle route from server.go and diffing it
against every row in the tables rather than by reading both lists: the seven
attachmentRoutes calls expand to their 21 concrete routes, the three static
panel paths are excluded, and the diff is empty in both directions. That
script is not committed - it is a one-off, and a real guard belongs in the Go
tests where it can see the mux, which is worth doing if these tables drift
again.
The flat list endpoints require ?car={id} - they refuse a cross-car listing
so access can be enforced - so the ones that do now say it. Attachments are
documented once with {records} standing for the seven collections that take a
file, because all seven behave identically and seven copies of three rows
would bury that. EndpointTable grew an optional note line under the header to
say what {records} means.
Two things fixed while in there. PUT rendered uncolored - methodClass has had
no PUT entry since the superadmin group started using it - and the longest
paths, the per-charger OCPP control routes, overran the card and were clipped
by its overflow-hidden rather than scrolling; the table sits in an
overflow-x-auto wrapper now. Thirteen of the eighteen tables scroll at phone
width, four of them before this commit's rows were added.
Group titles are translated in all three languages, plus one new auth label
for the OCPP socket, which authenticates the charger with OCPP Basic auth
rather than a bearer token. The endpoint descriptions stay English:
TRANSLATIONS.md calls them developer reference documentation, and this commit
does not reopen that.
Verified by go build ./... and go vet ./internal/api, and by driving the
panel in a browser against a mock API Server standing in for the real one -
all eighteen tables render, the {records} note and the PUT color show, the
Polish titles resolve, and no table clips at 375px. dist is rebuilt so the
embedded panel matches the source.
Not verified: nothing ran against a live API Server, so the descriptions are
checked against the handlers' code and comments rather than against
responses. The mock only answers /api/identity and /api/status, which is
enough to get past the login gate and reach the section.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a25b31842d
commit
b4e99240c6
10 files changed
+203
-46
No files matched your search
@@ -1,17 +0,0 @@
|
|||||||
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/**
|
|
||||||
* @vue/shared v3.5.39
|
|
||||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
||||||
* @license MIT
|
|
||||||
**/function cn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const Y={},xt=[],Ke=()=>{},mi=()=>!1,Ts=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),he=Object.assign,un=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},Ao=Object.prototype.hasOwnProperty,G=(e,t)=>Ao.call(e,t),M=Array.isArray,kt=e=>es(e)==="[object Map]",zt=e=>es(e)==="[object Set]",Rn=e=>es(e)==="[object Date]",V=e=>typeof e=="function",ne=e=>typeof e=="string",We=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",bi=e=>(Z(e)||V(e))&&V(e.then)&&V(e.catch),vi=Object.prototype.toString,es=e=>vi.call(e),Oo=e=>es(e).slice(8,-1),_i=e=>es(e)==="[object Object]",dn=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ft=cn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),$s=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},zo=/-\w/g,Ce=$s(e=>e.replace(zo,t=>t.slice(1).toUpperCase())),Io=/\B([A-Z])/g,dt=$s(e=>e.replace(Io,"-$1").toLowerCase()),yi=$s(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ds=$s(e=>e?`on${yi(e)}`:""),Ve=(e,t)=>!Object.is(e,t),fs=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},wi=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Cs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let jn;const Ps=()=>jn||(jn=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function fn(e){if(M(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],i=ne(n)?Uo(n):fn(n);if(i)for(const o in i)t[o]=i[o]}return t}else if(ne(e)||Z(e))return e}const Ro=/;(?![^(]*\))/g,jo=/:([^]+)/,No=/\/\*[^]*?\*\//g;function Uo(e){const t={};return e.replace(No,"").split(Ro).forEach(s=>{if(s){const n=s.split(jo);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Oe(e){let t="";if(ne(e))t=e;else if(M(e))for(let s=0;s<e.length;s++){const n=Oe(e[s]);n&&(t+=n+" ")}else if(Z(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const Do="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Mo=cn(Do);function xi(e){return!!e||e===""}function Lo(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=at(e[n],t[n]);return s}function at(e,t){if(e===t)return!0;let s=Rn(e),n=Rn(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=We(e),n=We(t),s||n)return e===t;if(s=M(e),n=M(t),s||n)return s&&n?Lo(e,t):!1;if(s=Z(e),n=Z(t),s||n){if(!s||!n)return!1;const i=Object.keys(e).length,o=Object.keys(t).length;if(i!==o)return!1;for(const r in e){const l=e.hasOwnProperty(r),a=t.hasOwnProperty(r);if(l&&!a||!l&&a||!at(e[r],t[r]))return!1}}return String(e)===String(t)}function pn(e,t){return e.findIndex(s=>at(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),m=e=>ne(e)?e:e==null?"":M(e)||Z(e)&&(e.toString===vi||!V(e.toString))?ki(e)?m(e.value):JSON.stringify(e,Si,2):String(e),Si=(e,t)=>ki(t)?Si(e,t.value):kt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ms(n,o)+" =>"]=i,s),{})}:zt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ms(s))}:We(t)?Ms(t):Z(t)&&!M(t)&&!_i(t)?String(t):t,Ms=(e,t="")=>{var s;return We(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
|
|
||||||
* @vue/reactivity v3.5.39
|
|
||||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
||||||
* @license MIT
|
|
||||||
**/let ce;class Fo{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ce&&(ce.active?(this.parent=ce,this.index=(ce.scopes||(ce.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=ce;try{return ce=this,t()}finally{ce=s}}}on(){++this._on===1&&(this.prevScope=ce,ce=this)}off(){if(this._on>0&&--this._on===0){if(ce===this)ce=this.prevScope;else{let t=ce;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const i=this.parent.scopes.pop();i&&i!==this&&(this.parent.scopes[this.index]=i,i.index=this.index)}this.parent=void 0}}}function Bo(){return ce}let Q;const Ls=new WeakSet;class Ti{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ce&&(ce.active?ce.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Ls.has(this)&&(Ls.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||$i(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,Nn(this),Ci(this);const t=Q,s=Pe;Q=this,Pe=!0;try{return this.fn()}finally{Pi(this),Q=t,Pe=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)mn(t);this.deps=this.depsTail=void 0,Nn(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Ls.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){Js(this)&&this.run()}get dirty(){return Js(this)}}let Ei=0,Bt,Ht;function $i(e,t=!1){if(e.flags|=8,t){e.next=Ht,Ht=e;return}e.next=Bt,Bt=e}function hn(){Ei++}function gn(){if(--Ei>0)return;if(Ht){let t=Ht;for(Ht=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Bt;){let t=Bt;for(Bt=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Ci(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Pi(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),mn(n),Ho(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Js(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Ai(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ai(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===qt)||(e.globalVersion=qt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Js(e))))return;e.flags|=2;const t=e.dep,s=Q,n=Pe;Q=e,Pe=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||Ve(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{Q=s,Pe=n,Pi(e),e.flags&=-3}}function mn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)mn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ho(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Pe=!0;const Oi=[];function Ge(){Oi.push(Pe),Pe=!1}function qe(){const e=Oi.pop();Pe=e===void 0?!0:e}function Nn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=Q;Q=void 0;try{t()}finally{Q=s}}}let qt=0;class Vo{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class bn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Q||!Pe||Q===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==Q)s=this.activeLink=new Vo(Q,this),Q.deps?(s.prevDep=Q.depsTail,Q.depsTail.nextDep=s,Q.depsTail=s):Q.deps=Q.depsTail=s,zi(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=Q.depsTail,s.nextDep=void 0,Q.depsTail.nextDep=s,Q.depsTail=s,Q.deps===s&&(Q.deps=n)}return s}trigger(t){this.version++,qt++,this.notify(t)}Line truncated
|
|
||||||
* @vue/runtime-core v3.5.39
|
|
||||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
||||||
* @license MIT
|
|
||||||
**/function ts(e,t,s,n){try{return n?e(...n):e()}catch(i){Os(i,t,s)}}function Ie(e,t,s,n){if(V(e)){const i=ts(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Os(o,t,s)}),i}if(M(e)){const i=[];for(let o=0;o<e.length;o++)i.push(Ie(e[o],t,s,n));return i}}function Os(e,t,s,n=!0){const i=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:r}=t&&t.appContext.config||Y;if(t){let l=t.parent;const a=t.proxy,p=`https://vuejs.org/error-reference/#runtime-${s}`;for(;l;){const d=l.ec;if(d){for(let b=0;b<d.length;b++)if(d[b](e,a,p)===!1)return}l=l.parent}if(o){Ge(),ts(o,null,10,[e,a,p]),qe();return}}gr(e,s,i,n,r)}function gr(e,t,s,n=!0,i=!1){if(i)throw e;console.error(e)}const be=[];let Fe=-1;const St=[];let lt=null,wt=0;const Li=Promise.resolve();let bs=null;function Fi(e){const t=bs||Li;return e?t.then(this?e.bind(this):e):t}function mr(e){let t=Fe+1,s=be.length;for(;t<s;){const n=t+s>>>1,i=be[n],o=Yt(i);o<e||o===e&&i.flags&2?t=n+1:s=n}return t}function wn(e){if(!(e.flags&1)){const t=Yt(e),s=be[be.length-1];!s||!(e.flags&2)&&t>=Yt(s)?be.push(e):be.splice(mr(t),0,e),e.flags|=1,Bi()}}function Bi(){bs||(bs=Li.then(Vi))}function br(e){M(e)?St.push(...e):lt&&e.id===-1?lt.splice(wt+1,0,e):e.flags&1||(St.push(e),e.flags|=1),Bi()}function Dn(e,t,s=Fe+1){for(;s<be.length;s++){const n=be[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;be.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function Hi(e){if(St.length){const t=[...new Set(St)].sort((s,n)=>Yt(s)-Yt(n));if(St.length=0,lt){lt.push(...t);return}for(lt=t,wt=0;wt<lt.length;wt++){const s=lt[wt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}lt=null,wt=0}}const Yt=e=>e.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(Fe=0;Fe<be.length;Fe++){const t=be[Fe];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),ts(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Fe<be.length;Fe++){const t=be[Fe];t&&(t.flags&=-2)}Fe=-1,be.length=0,Hi(),bs=null,(be.length||St.length)&&Vi()}}let ke=null,Ki=null;function vs(e){const t=ke;return ke=e,Ki=e&&e.type.__scopeId||null,t}function vr(e,t=ke,s){if(!t||e._n)return e;const n=(...i)=>{n._d&&Zn(-1);const o=vs(t);let r;try{r=e(...i)}finally{vs(o),n._d&&Zn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function re(e,t){if(ke===null)return e;const s=js(ke),n=e.dirs||(e.dirs=[]);for(let i=0;i<t.length;i++){let[o,r,l,a=Y]=t[i];o&&(V(o)&&(o={mounted:o,updated:o}),o.deep&&et(r),n.push({dir:o,instance:s,value:r,oldValue:void 0,arg:l,modifiers:a}))}return e}function gt(e,t,s,n){const i=e.dirs,o=t&&t.dirs;for(let r=0;r<i.length;r++){const l=i[r];o&&(l.oldValue=o[r].value);let a=l.dir[n];a&&(Ge(),Ie(a,s,8,[e.el,l,e,t]),qe())}}function _r(e,t){if(ve){let s=ve.provides;const n=ve.parent&&ve.parent.provides;n===s&&(s=ve.provides=Object.create(n)),s[e]=t}}function ps(e,t,s=!1){const n=ml();if(n||Tt){let i=Tt?Tt._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(i&&e in i)return i[e];if(arguments.length>1)return s&&V(t)?t.call(n&&n.proxy):t}}const yr=Symbol.for("v-scx"),wr=()=>ps(yr);function Hs(e,t,s){return Wi(e,t,s)}function Wi(e,t,s=Y){const{immediate:n,deep:i,flush:o,once:r}=s,l=he({},s),a=t&&n||!t&&o!=="post";let p;if(Qt){if(o==="sync"){const O=wr();p=O.__watcherHandles||(O.__watcherHandles=[])}else if(!a){const O=()=>{};return O.stop=Ke,O.resume=Ke,O.pause=Ke,O}}const d=ve;l.call=(O,F,_)=>Ie(O,d,F,_);let b=!1;o==="post"?l.scheduler=O=>{_e(O,d&&d.suspense)}:o!=="sync"&&(b=!0,l.scheduler=(O,F)=>{F?O():wn(O)}),l.augmentJob=O=>{t&&(O.flags|=4),b&&(O.flags|=2,d&&(O.id=d.uid,O.i=d))};const C=hr(e,t,l);return Qt&&(p?p.push(C):a&&C()),C}function xr(e,t,s){const n=this.proxy,i=ne(e)?e.includes(".")?Gi(n,e):()=>n[e]:e.bind(n,n);let o;V(t)?o=t:(o=t.handler,s=t);const r=ss(this),l=Wi(i,o.bind(n),s);return r(),l}function Gi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;i<s.length&&n;i++)n=n[s[i]];return n}}const kr=Symbol("_vte"),Sr=e=>e.__isTeleport,Vs=Symbol("_leaveCb");function xn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,xn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function qi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Mn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const _s=new WeakMap;function Vt(e,t,s,n,i=!1){if(M(e)){e.forEach((_,E)=>Vt(_,t&&(M(t)?t[E]:t),s,n,i));return}if(Kt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Vt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?js(n.component):n.el,r=i?null:o,{i:l,r:a}=e,p=t&&t.r,d=l.refs===Y?l.refs={}:l.refs,b=l.setupState,C=W(b),O=b===Y?mi:_=>Mn(d,_)?!1:G(C,_),F=(_,E)=>!(E&&Mn(d,E));if(p!=null&&p!==a){if(Ln(t),ne(p))d[p]=null,O(p)&&(b[p]=null);else if(pe(p)){const _=t;F(p,_.k)&&(p.value=null),_.k&&(d[_.k]=null)}}if(V(a)){Ge();try{ts(a,l,12,[r,d])}finally{qe()}}else{const _=ne(a),E=pe(a);if(_||E){const w=()=>{if(e.f){con
Line truncated
|
|
||||||
* @vue/runtime-dom v3.5.39
|
|
||||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
||||||
* @license MIT
|
|
||||||
**/let ln;const Xn=typeof window<"u"&&window.trustedTypes;if(Xn)try{ln=Xn.createPolicy("vue",{createHTML:e=>e})}catch{}const yo=ln?e=>ln.createHTML(e):e=>e,kl="http://www.w3.org/2000/svg",Sl="http://www.w3.org/1998/Math/MathML",Ye=typeof document<"u"?document:null,Qn=Ye&&Ye.createElement("template"),Tl={insert:(e,t,s)=>{t.insertBefore(e,s||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,s,n)=>{const i=t==="svg"?Ye.createElementNS(kl,e):t==="mathml"?Ye.createElementNS(Sl,e):s?Ye.createElement(e,{is:s}):Ye.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ye.createTextNode(e),createComment:e=>Ye.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ye.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,s,n,i,o){const r=s?s.previousSibling:t.lastChild;if(i&&(i===o||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),s),!(i===o||!(i=i.nextSibling)););else{Qn.innerHTML=yo(n==="svg"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`:e);const l=Qn.content;if(n==="svg"||n==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,s)}return[r?r.nextSibling:t.firstChild,s?s.previousSibling:t.lastChild]}},El=Symbol("_vtc");function $l(e,t,s){const n=e[El];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):s?e.setAttribute("class",t):e.className=t}const ei=Symbol("_vod"),Cl=Symbol("_vsh"),Pl=Symbol(""),Al=/(?:^|;)\s*display\s*:/;function Ol(e,t,s){const n=e.style,i=ne(s);let o=!1;if(s&&!i){if(t)if(ne(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();s[l]==null&&Lt(n,l,"")}else for(const r in t)s[r]==null&&Lt(n,r,"");for(const r in s){r==="display"&&(o=!0);const l=s[r];l!=null?Il(e,r,!ne(t)&&t?t[r]:void 0,l)||Lt(n,r,l):Lt(n,r,"")}}else if(i){if(t!==s){const r=n[Pl];r&&(s+=";"+r),n.cssText=s,o=Al.test(s)}}else t&&e.removeAttribute("style");ei in e&&(e[ei]=o?n.display:"",e[Cl]&&(n.display="none"))}const ti=/\s*!important$/;function Lt(e,t,s){if(M(s))s.forEach(n=>Lt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=zl(e,t);ti.test(s)?e.setProperty(dt(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function zl(e,t){const s=qs[t];if(s)return s;let n=Ce(t);if(n!=="filter"&&n in e)return qs[t]=n;n=yi(n);for(let i=0;i<si.length;i++){const o=si[i]+n;if(o in e)return qs[t]=o}return t}function Il(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ne(n)&&s===n}const ni="http://www.w3.org/1999/xlink";function ii(e,t,s,n,i,o=Mo(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(ni,t.slice(6,t.length)):e.setAttributeNS(ni,t,s):s==null||o&&!xi(s)?e.removeAttribute(t):e.setAttribute(t,o?"":We(s)?String(s):s)}function oi(e,t,s,n,i){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?yo(s):s);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const l=o==="OPTION"?e.getAttribute("value")||"":e.value,a=s==null?e.type==="checkbox"?"on":"":String(s);(l!==a||!("_value"in e))&&(e.value=a),s==null&&e.removeAttribute(t),e._value=s;return}let r=!1;if(s===""||s==null){const l=typeof e[t];l==="boolean"?s=xi(s):s==null&&l==="string"?(s="",r=!0):l==="number"&&(s=0,r=!0)}try{e[t]=s}catch{}r&&e.removeAttribute(i||t)}function tt(e,t,s,n){e.addEventListener(t,s,n)}function Rl(e,t,s,n){e.removeEventListener(t,s,n)}const ri=Symbol("_vei");function jl(e,t,s,n,i=null){const o=e[ri]||(e[ri]={}),r=o[t];if(n&&r)r.value=n;else{const[l,a]=Dl(t);if(n){const p=o[t]=Fl(n,i);tt(e,l,p,a)}else r&&(Rl(e,l,r,a),o[t]=void 0)}}const Nl=/(Once|Passive|Capture)$/,Ul=/^on:?(?:Once|Passive|Capture)$/;function Dl(e){let t,s;for(;(s=e.match(Nl))&&!Ul.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):dt(e.slice(2)),t]}let Zs=0;const Ml=Promise.resolve(),Ll=()=>Zs||(Ml.then(()=>Zs=0),Zs=Date.now());function Fl(e,t){const s=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=s.attached)return;const i=s.value;if(M(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),l=[n];for(let a=0;a<r.length&&!n._stopped;a++){const p=r[a];p&&Ie(p,t,5,l)}}else Ie(i,t,5,[n])};return s.value=e,s.attached=Ll(),s}const li=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Bl=(e,t,s,n,i,o)=>{const r=i==="svg";t==="class"?$l(e,n,r):t==="style"?Ol(e,s,n):Ts(t)?Es(t)||jl(e,t,s,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Hl(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&&(Vl(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ne(n)))?oi(e,Ce(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._fals
Line truncated
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/*! 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);--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);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--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{.container{widthLine truncated
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const o of i)if(o.type==="childList")for(const r of o.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function s(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function n(i){if(i.ep)return;i.ep=!0;const o=s(i);fetch(i.href,o)}})();/**
|
||||||
|
* @vue/shared v3.5.39
|
||||||
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||||
|
* @license MIT
|
||||||
|
**/function cn(e){const t=Object.create(null);for(const s of e.split(","))t[s]=1;return s=>s in t}const X={},St=[],Je=()=>{},mi=()=>!1,Ts=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Es=e=>e.startsWith("onUpdate:"),ve=Object.assign,un=(e,t)=>{const s=e.indexOf(t);s>-1&&e.splice(s,1)},$o=Object.prototype.hasOwnProperty,W=(e,t)=>$o.call(e,t),M=Array.isArray,Tt=e=>ss(e)==="[object Map]",Dt=e=>ss(e)==="[object Set]",Dn=e=>ss(e)==="[object Date]",V=e=>typeof e=="function",oe=e=>typeof e=="string",Ye=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",bi=e=>(Z(e)||V(e))&&V(e.then)&&V(e.catch),vi=Object.prototype.toString,ss=e=>vi.call(e),Oo=e=>ss(e).slice(8,-1),yi=e=>ss(e)==="[object Object]",dn=e=>oe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ht=cn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Ps=e=>{const t=Object.create(null);return(s=>t[s]||(t[s]=e(s)))},Ro=/-\w/g,De=Ps(e=>e.replace(Ro,t=>t.slice(1).toUpperCase())),zo=/\B([A-Z])/g,ht=Ps(e=>e.replace(zo,"-$1").toLowerCase()),_i=Ps(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ns=Ps(e=>e?`on${_i(e)}`:""),Ze=(e,t)=>!Object.is(e,t),ps=(e,...t)=>{for(let s=0;s<e.length;s++)e[s](...t)},wi=(e,t,s,n=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:n,value:s})},Cs=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let In;const As=()=>In||(In=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function pn(e){if(M(e)){const t={};for(let s=0;s<e.length;s++){const n=e[s],i=oe(n)?Uo(n):pn(n);if(i)for(const o in i)t[o]=i[o]}return t}else if(oe(e)||Z(e))return e}const Do=/;(?![^(]*\))/g,Io=/:([^]+)/,jo=/\/\*[^]*?\*\//g;function Uo(e){const t={};return e.replace(jo,"").split(Do).forEach(s=>{if(s){const n=s.split(Io);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ue(e){let t="";if(oe(e))t=e;else if(M(e))for(let s=0;s<e.length;s++){const n=Ue(e[s]);n&&(t+=n+" ")}else if(Z(e))for(const s in e)e[s]&&(t+=s+" ");return t.trim()}const No="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Mo=cn(No);function xi(e){return!!e||e===""}function Lo(e,t){if(e.length!==t.length)return!1;let s=!0;for(let n=0;s&&n<e.length;n++)s=dt(e[n],t[n]);return s}function dt(e,t){if(e===t)return!0;let s=Dn(e),n=Dn(t);if(s||n)return s&&n?e.getTime()===t.getTime():!1;if(s=Ye(e),n=Ye(t),s||n)return e===t;if(s=M(e),n=M(t),s||n)return s&&n?Lo(e,t):!1;if(s=Z(e),n=Z(t),s||n){if(!s||!n)return!1;const i=Object.keys(e).length,o=Object.keys(t).length;if(i!==o)return!1;for(const r in e){const a=e.hasOwnProperty(r),l=t.hasOwnProperty(r);if(a&&!l||!a&&l||!dt(e[r],t[r]))return!1}}return String(e)===String(t)}function fn(e,t){return e.findIndex(s=>dt(s,t))}const ki=e=>!!(e&&e.__v_isRef===!0),m=e=>oe(e)?e:e==null?"":M(e)||Z(e)&&(e.toString===vi||!V(e.toString))?ki(e)?m(e.value):JSON.stringify(e,Si,2):String(e),Si=(e,t)=>ki(t)?Si(e,t.value):Tt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((s,[n,i],o)=>(s[Ms(n,o)+" =>"]=i,s),{})}:Dt(t)?{[`Set(${t.size})`]:[...t.values()].map(s=>Ms(s))}:Ye(t)?Ms(t):Z(t)&&!M(t)&&!yi(t)?String(t):t,Ms=(e,t="")=>{var s;return Ye(e)?`Symbol(${(s=e.description)!=null?s:t})`:e};/**
|
||||||
|
* @vue/reactivity v3.5.39
|
||||||
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||||
|
* @license MIT
|
||||||
|
**/let he;class Fo{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&he&&(he.active?(this.parent=he,this.index=(he.scopes||(he.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].pause();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,s;if(this.scopes)for(t=0,s=this.scopes.length;t<s;t++)this.scopes[t].resume();for(t=0,s=this.effects.length;t<s;t++)this.effects[t].resume()}}run(t){if(this._active){const s=he;try{return he=this,t()}finally{he=s}}}on(){++this._on===1&&(this.prevScope=he,he=this)}off(){if(this._on>0&&--this._on===0){if(he===this)he=this.prevScope;else{let t=he;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let s,n;for(s=0,n=this.effects.length;s<n;s++)this.effects[s].stop();for(this.effects.length=0,s=0,n=this.cleanups.length;s<n;s++)this.cleanups[s]();if(this.cleanups.length=0,this.scopes){for(s=0,n=this.scopes.length;s<n;s++)this.scopes[s].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const i=this.parent.scopes.pop();i&&i!==this&&(this.parent.scopes[this.index]=i,i.index=this.index)}this.parent=void 0}}}function Bo(){return he}let ee;const Ls=new WeakSet;class Ti{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,he&&(he.active?he.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Ls.has(this)&&(Ls.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||Pi(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,jn(this),Ci(this);const t=ee,s=Ie;ee=this,Ie=!0;try{return this.fn()}finally{Ai(this),ee=t,Ie=s,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)mn(t);this.deps=this.depsTail=void 0,jn(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Ls.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){Js(this)&&this.run()}get dirty(){return Js(this)}}let Ei=0,Vt,Gt;function Pi(e,t=!1){if(e.flags|=8,t){e.next=Gt,Gt=e;return}e.next=Vt,Vt=e}function hn(){Ei++}function gn(){if(--Ei>0)return;if(Gt){let t=Gt;for(Gt=void 0;t;){const s=t.next;t.next=void 0,t.flags&=-9,t=s}}let e;for(;Vt;){let t=Vt;for(Vt=void 0;t;){const s=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(n){e||(e=n)}t=s}}if(e)throw e}function Ci(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Ai(e){let t,s=e.depsTail,n=s;for(;n;){const i=n.prevDep;n.version===-1?(n===s&&(s=i),mn(n),Ho(n)):t=n,n.dep.activeLink=n.prevActiveLink,n.prevActiveLink=void 0,n=i}e.deps=t,e.depsTail=s}function Js(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&($i(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function $i(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Jt)||(e.globalVersion=Jt,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!Js(e))))return;e.flags|=2;const t=e.dep,s=ee,n=Ie;ee=e,Ie=!0;try{Ci(e);const i=e.fn(e._value);(t.version===0||Ze(i,e._value))&&(e.flags|=128,e._value=i,t.version++)}catch(i){throw t.version++,i}finally{ee=s,Ie=n,Ai(e),e.flags&=-3}}function mn(e,t=!1){const{dep:s,prevSub:n,nextSub:i}=e;if(n&&(n.nextSub=i,e.prevSub=void 0),i&&(i.prevSub=n,e.nextSub=void 0),s.subs===e&&(s.subs=n,!n&&s.computed)){s.computed.flags&=-5;for(let o=s.computed.deps;o;o=o.nextDep)mn(o,!0)}!t&&!--s.sc&&s.map&&s.map.delete(s.key)}function Ho(e){const{prevDep:t,nextDep:s}=e;t&&(t.nextDep=s,e.prevDep=void 0),s&&(s.prevDep=t,e.nextDep=void 0)}let Ie=!0;const Oi=[];function Xe(){Oi.push(Ie),Ie=!1}function Qe(){const e=Oi.pop();Ie=e===void 0?!0:e}function jn(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const s=ee;ee=void 0;try{t()}finally{ee=s}}}let Jt=0;class Vo{constructor(t,s){this.sub=t,this.dep=s,this.version=s.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class bn{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ee||!Ie||ee===this.computed)return;let s=this.activeLink;if(s===void 0||s.sub!==ee)s=this.activeLink=new Vo(ee,this),ee.deps?(s.prevDep=ee.depsTail,ee.depsTail.nextDep=s,ee.depsTail=s):ee.deps=ee.depsTail=s,Ri(s);else if(s.version===-1&&(s.version=this.version,s.nextDep)){const n=s.nextDep;n.prevDep=s.prevDep,s.prevDep&&(s.prevDep.nextDep=n),s.prevDep=ee.depsTail,s.nextDep=void 0,ee.depsTail.nextDep=s,ee.depsTail=s,ee.deps===s&&(ee.deps=n)}return s}trigger(t){this.versiLine truncated
|
||||||
|
* @vue/runtime-core v3.5.39
|
||||||
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||||
|
* @license MIT
|
||||||
|
**/function ns(e,t,s,n){try{return n?e(...n):e()}catch(i){Os(i,t,s)}}function Me(e,t,s,n){if(V(e)){const i=ns(e,t,s,n);return i&&bi(i)&&i.catch(o=>{Os(o,t,s)}),i}if(M(e)){const i=[];for(let o=0;o<e.length;o++)i.push(Me(e[o],t,s,n));return i}}function Os(e,t,s,n=!0){const i=t?t.vnode:null,{errorHandler:o,throwUnhandledErrorInProduction:r}=t&&t.appContext.config||X;if(t){let a=t.parent;const l=t.proxy,g=`https://vuejs.org/error-reference/#runtime-${s}`;for(;a;){const d=a.ec;if(d){for(let b=0;b<d.length;b++)if(d[b](e,l,g)===!1)return}a=a.parent}if(o){Xe(),ns(o,null,10,[e,l,g]),Qe();return}}gr(e,s,i,n,r)}function gr(e,t,s,n=!0,i=!1){if(i)throw e;console.error(e)}const we=[];let Ke=-1;const Et=[];let ut=null,kt=0;const Li=Promise.resolve();let bs=null;function Fi(e){const t=bs||Li;return e?t.then(this?e.bind(this):e):t}function mr(e){let t=Ke+1,s=we.length;for(;t<s;){const n=t+s>>>1,i=we[n],o=Qt(i);o<e||o===e&&i.flags&2?t=n+1:s=n}return t}function wn(e){if(!(e.flags&1)){const t=Qt(e),s=we[we.length-1];!s||!(e.flags&2)&&t>=Qt(s)?we.push(e):we.splice(mr(t),0,e),e.flags|=1,Bi()}}function Bi(){bs||(bs=Li.then(Vi))}function br(e){M(e)?Et.push(...e):ut&&e.id===-1?ut.splice(kt+1,0,e):e.flags&1||(Et.push(e),e.flags|=1),Bi()}function Nn(e,t,s=Ke+1){for(;s<we.length;s++){const n=we[s];if(n&&n.flags&2){if(e&&n.id!==e.uid)continue;we.splice(s,1),s--,n.flags&4&&(n.flags&=-2),n(),n.flags&4||(n.flags&=-2)}}}function Hi(e){if(Et.length){const t=[...new Set(Et)].sort((s,n)=>Qt(s)-Qt(n));if(Et.length=0,ut){ut.push(...t);return}for(ut=t,kt=0;kt<ut.length;kt++){const s=ut[kt];s.flags&4&&(s.flags&=-2),s.flags&8||s(),s.flags&=-2}ut=null,kt=0}}const Qt=e=>e.id==null?e.flags&2?-1:1/0:e.id;function Vi(e){try{for(Ke=0;Ke<we.length;Ke++){const t=we[Ke];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),ns(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Ke<we.length;Ke++){const t=we[Ke];t&&(t.flags&=-2)}Ke=-1,we.length=0,Hi(),bs=null,(we.length||Et.length)&&Vi()}}let Ae=null,Gi=null;function vs(e){const t=Ae;return Ae=e,Gi=e&&e.type.__scopeId||null,t}function vr(e,t=Ae,s){if(!t||e._n)return e;const n=(...i)=>{n._d&&Zn(-1);const o=vs(t);let r;try{r=e(...i)}finally{vs(o),n._d&&Zn(1)}return r};return n._n=!0,n._c=!0,n._d=!0,n}function le(e,t){if(Ae===null)return e;const s=Is(Ae),n=e.dirs||(e.dirs=[]);for(let i=0;i<t.length;i++){let[o,r,a,l=X]=t[i];o&&(V(o)&&(o={mounted:o,updated:o}),o.deep&&ot(r),n.push({dir:o,instance:s,value:r,oldValue:void 0,arg:a,modifiers:l}))}return e}function bt(e,t,s,n){const i=e.dirs,o=t&&t.dirs;for(let r=0;r<i.length;r++){const a=i[r];o&&(a.oldValue=o[r].value);let l=a.dir[n];l&&(Xe(),Me(l,s,8,[e.el,a,e,t]),Qe())}}function yr(e,t){if(xe){let s=xe.provides;const n=xe.parent&&xe.parent.provides;n===s&&(s=xe.provides=Object.create(n)),s[e]=t}}function fs(e,t,s=!1){const n=ma();if(n||Pt){let i=Pt?Pt._context.provides:n?n.parent==null||n.ce?n.vnode.appContext&&n.vnode.appContext.provides:n.parent.provides:void 0;if(i&&e in i)return i[e];if(arguments.length>1)return s&&V(t)?t.call(n&&n.proxy):t}}const _r=Symbol.for("v-scx"),wr=()=>fs(_r);function Hs(e,t,s){return Ki(e,t,s)}function Ki(e,t,s=X){const{immediate:n,deep:i,flush:o,once:r}=s,a=ve({},s),l=t&&n||!t&&o!=="post";let g;if(ts){if(o==="sync"){const $=wr();g=$.__watcherHandles||($.__watcherHandles=[])}else if(!l){const $=()=>{};return $.stop=Je,$.resume=Je,$.pause=Je,$}}const d=xe;a.call=($,F,k)=>Me($,d,F,k);let b=!1;o==="post"?a.scheduler=$=>{ke($,d&&d.suspense)}:o!=="sync"&&(b=!0,a.scheduler=($,F)=>{F?$():wn($)}),a.augmentJob=$=>{t&&($.flags|=4),b&&($.flags|=2,d&&($.id=d.uid,$.i=d))};const P=hr(e,t,a);return ts&&(g?g.push(P):l&&P()),P}function xr(e,t,s){const n=this.proxy,i=oe(e)?e.includes(".")?Wi(n,e):()=>n[e]:e.bind(n,n);let o;V(t)?o=t:(o=t.handler,s=t);const r=is(this),a=Ki(i,o.bind(n),s);return r(),a}function Wi(e,t){const s=t.split(".");return()=>{let n=e;for(let i=0;i<s.length&&n;i++)n=n[s[i]];return n}}const kr=Symbol("_vte"),Sr=e=>e.__isTeleport,Vs=Symbol("_leaveCb");function xn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,xn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function qi(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Mn(e,t){let s;return!!((s=Object.getOwnPropertyDescriptor(e,t))&&!s.configurable)}const ys=new WeakMap;function Kt(e,t,s,n,i=!1){if(M(e)){e.forEach((k,O)=>Kt(k,t&&(M(t)?t[O]:t),s,n,i));return}if(Wt(n)&&!i){n.shapeFlag&512&&n.type.__asyncResolved&&n.component.subTree.component&&Kt(e,t,s,n.component.subTree);return}const o=n.shapeFlag&4?Is(n.component):n.el,r=i?null:o,{i:a,r:l}=e,g=t&&t.r,d=a.refs===X?a.refs={}:a.refs,b=a.setupState,P=K(b),$=b===X?mi:k=>Mn(d,k)?!1:W(P,k),F=(k,O)=>!(O&&Mn(d,O));if(g!=null&&g!==l){if(Ln(t),oe(g))d[g]=null,$(g)&&(b[g]=null);else if(be(g)){const k=t;F(g,k.k)&&(g.value=null),k.k&&(d[k.k]=null)}}if(V(l)){Xe();try{ns(l,a,12,[r,d])}finally{Qe()}}else{const k=oe(l),O=be(l);if(k||O){const E=()=>{if(e.f){con
Line truncated
|
||||||
|
* @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",Sa="http://www.w3.org/1998/Math/MathML",st=typeof document<"u"?document:null,Qn=st&&st.createElement("template"),Ta={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"?st.createElementNS(ka,e):t==="mathml"?st.createElementNS(Sa,e):s?st.createElement(e,{is:s}):st.createElement(e);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>st.createTextNode(e),createComment:e=>st.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>st.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"?`<svg>${e}</svg>`:n==="mathml"?`<math>${e}</math>`: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=oe(s);let o=!1;if(s&&!i){if(t)if(oe(t))for(const r of t.split(";")){const a=r.slice(0,r.indexOf(":")).trim();s[a]==null&&Bt(n,a,"")}else for(const r in t)s[r]==null&&Bt(n,r,"");for(const r in s){r==="display"&&(o=!0);const a=s[r];a!=null?za(e,r,!oe(t)&&t?t[r]:void 0,a)||Bt(n,r,a):Bt(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 Bt(e,t,s){if(M(s))s.forEach(n=>Bt(e,t,n));else if(s==null&&(s=""),t.startsWith("--"))e.setProperty(t,s);else{const n=Ra(e,t);ti.test(s)?e.setProperty(ht(n),s.replace(ti,""),"important"):e[n]=s}}const si=["Webkit","Moz","ms"],qs={};function Ra(e,t){const s=qs[t];if(s)return s;let n=De(t);if(n!=="filter"&&n in e)return qs[t]=n;n=_i(n);for(let i=0;i<si.length;i++){const o=si[i]+n;if(o in e)return qs[t]=o}return t}function za(e,t,s,n){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&oe(n)&&s===n}const ni="http://www.w3.org/1999/xlink";function ii(e,t,s,n,i,o=Mo(t)){n&&t.startsWith("xlink:")?s==null?e.removeAttributeNS(ni,t.slice(6,t.length)):e.setAttributeNS(ni,t,s):s==null||o&&!xi(s)?e.removeAttribute(t):e.setAttribute(t,o?"":Ye(s)?String(s):s)}function oi(e,t,s,n,i){if(t==="innerHTML"||t==="textContent"){s!=null&&(e[t]=t==="innerHTML"?_o(s):s);return}const o=e.tagName;if(t==="value"&&o!=="PROGRESS"&&!o.includes("-")){const a=o==="OPTION"?e.getAttribute("value")||"":e.value,l=s==null?e.type==="checkbox"?"on":"":String(s);(a!==l||!("_value"in e))&&(e.value=l),s==null&&e.removeAttribute(t),e._value=s;return}let r=!1;if(s===""||s==null){const a=typeof e[t];a==="boolean"?s=xi(s):s==null&&a==="string"?(s="",r=!0):a==="number"&&(s=0,r=!0)}try{e[t]=s}catch{}r&&e.removeAttribute(i||t)}function rt(e,t,s,n){e.addEventListener(t,s,n)}function Da(e,t,s,n){e.removeEventListener(t,s,n)}const ri=Symbol("_vei");function Ia(e,t,s,n,i=null){const o=e[ri]||(e[ri]={}),r=o[t];if(n&&r)r.value=n;else{const[a,l]=Na(t);if(n){const g=o[t]=Fa(n,i);rt(e,a,g,l)}else r&&(Da(e,a,r,l),o[t]=void 0)}}const ja=/(Once|Passive|Capture)$/,Ua=/^on:?(?:Once|Passive|Capture)$/;function Na(e){let t,s;for(;(s=e.match(ja))&&!Ua.test(e);)t||(t={}),e=e.slice(0,e.length-s[1].length),t[s[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):ht(e.slice(2)),t]}let Zs=0;const Ma=Promise.resolve(),La=()=>Zs||(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(M(i)){const o=n.stopImmediatePropagation;n.stopImmediatePropagation=()=>{o.call(n),n._stopped=!0};const r=i.slice(),a=[n];for(let l=0;l<r.length&&!n._stopped;l++){const g=r[l];g&&Me(g,t,5,a)}}else Me(i,t,5,[n])};return s.value=e,s.attached=La(),s}const ai=e=>e.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):Ts(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)||!oe(n)))?oi(e,De(t),n,o,t):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._fals
Line truncated
|
||||||
@@ -1 +0,0 @@
|
|||||||
/*! 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);--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);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--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{.mx-auto{margin-Line truncated
|
|
||||||
+2
-2
@@ -6,8 +6,8 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="theme-color" content="#2563eb" />
|
<meta name="theme-color" content="#2563eb" />
|
||||||
<title>DriverVault · API Server</title>
|
<title>DriverVault · API Server</title>
|
||||||
<script type="module" crossorigin src="/assets/index-B4_v9nDZ.js"></script>
|
<script type="module" crossorigin src="/assets/index-D2BCqgpA.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-D3MeNcl7.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CGuUVjJH.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ const barFills = computed(() =>
|
|||||||
// registered in internal/api/server.go.
|
// registered in internal/api/server.go.
|
||||||
const publicApi = [
|
const publicApi = [
|
||||||
{ method: "GET", path: "/api/health", desc: "Liveness probe (no auth)" },
|
{ 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: "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: "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" },
|
{ method: "GET", path: "/api/auth/validate", desc: "Check whether a token is still valid" },
|
||||||
@@ -93,30 +94,128 @@ const carsApi = [
|
|||||||
{ method: "POST", path: "/api/cars", desc: "Create a car" },
|
{ method: "POST", path: "/api/cars", desc: "Create a car" },
|
||||||
{ method: "GET", path: "/api/cars/{id}", desc: "Fetch one car" },
|
{ method: "GET", path: "/api/cars/{id}", desc: "Fetch one car" },
|
||||||
{ method: "PATCH", path: "/api/cars/{id}", desc: "Update a 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 and their order" },
|
||||||
{ method: "DELETE", path: "/api/cars/{id}", desc: "Delete a car (owner only)" },
|
{ 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}/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}/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: "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: "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)" },
|
{ method: "DELETE", path: "/api/cars/{id}/shares/{userId}", desc: "Revoke a share (owner)" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const serviceApi = [
|
const serviceApi = [
|
||||||
{ method: "GET", path: "/api/service-records", desc: "List service records" },
|
{ 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: "POST", path: "/api/service-records", desc: "Log a service record" },
|
||||||
{ method: "GET", path: "/api/service-records/{id}", desc: "Fetch one record" },
|
{ method: "GET", path: "/api/service-records/{id}", desc: "Fetch one record" },
|
||||||
{ method: "PATCH", path: "/api/service-records/{id}", desc: "Update a record" },
|
{ method: "PATCH", path: "/api/service-records/{id}", desc: "Update a record" },
|
||||||
{ method: "DELETE", path: "/api/service-records/{id}", desc: "Delete a record" },
|
{ method: "DELETE", path: "/api/service-records/{id}", desc: "Delete a record" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const technicalApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
const partsApi = [
|
const partsApi = [
|
||||||
{ method: "GET", path: "/api/parts", desc: "List parts" },
|
{ method: "GET", path: "/api/parts", desc: "List one car's parts (?car={id})" },
|
||||||
{ method: "POST", path: "/api/parts", desc: "Add a part" },
|
{ method: "POST", path: "/api/parts", desc: "Add a part" },
|
||||||
{ method: "GET", path: "/api/parts/{id}", desc: "Fetch one part" },
|
{ method: "GET", path: "/api/parts/{id}", desc: "Fetch one part" },
|
||||||
{ method: "PATCH", path: "/api/parts/{id}", desc: "Update a part" },
|
{ method: "PATCH", path: "/api/parts/{id}", desc: "Update a part" },
|
||||||
{ method: "DELETE", path: "/api/parts/{id}", desc: "Delete a part" },
|
{ method: "DELETE", path: "/api/parts/{id}", desc: "Delete a part" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const fuelApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const chargingApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const maintenanceApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const documentsApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const remindersApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// One optional file per record, on identical terms for every collection that
|
||||||
|
// takes one, so the three routes are documented once with {records} standing
|
||||||
|
// for any of them (see the note under the table).
|
||||||
|
const attachmentsApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const attachmentsNote =
|
||||||
|
"{records} is any of service-records, technical-checks, maintenance, fuel-entries, charging-sessions, car-documents, parts.";
|
||||||
|
|
||||||
|
const providersApi = [
|
||||||
|
{ 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)" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const integrationsApi = [
|
||||||
|
{ 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" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const ocppApi = [
|
||||||
|
{ method: "GET", path: "/ocpp/{serial}", desc: "WebSocket the charger dials out to; OCPP Basic auth with the serial + its control token" },
|
||||||
|
];
|
||||||
|
|
||||||
const accountApi = [
|
const accountApi = [
|
||||||
{ method: "GET", path: "/api/me", desc: "Current user profile" },
|
{ method: "GET", path: "/api/me", desc: "Current user profile" },
|
||||||
{ method: "PATCH", path: "/api/me", desc: "Update profile" },
|
{ method: "PATCH", path: "/api/me", desc: "Update profile" },
|
||||||
@@ -159,6 +258,7 @@ const superadminApi = [
|
|||||||
{ method: "DELETE", path: "/api/admin/plugins/{name}", desc: "Remove an external plugin" },
|
{ 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" },
|
{ method: "POST", path: "/api/admin/plugins/{name}/health", desc: "Run a health check now" },
|
||||||
];
|
];
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -259,7 +359,22 @@ const superadminApi = [
|
|||||||
<EndpointTable :title="t('api.groupIdentity')" :auth="t('api.authBearer')" :endpoints="identityApi" />
|
<EndpointTable :title="t('api.groupIdentity')" :auth="t('api.authBearer')" :endpoints="identityApi" />
|
||||||
<EndpointTable :title="t('api.groupCars')" :auth="t('api.authBearer')" :endpoints="carsApi" />
|
<EndpointTable :title="t('api.groupCars')" :auth="t('api.authBearer')" :endpoints="carsApi" />
|
||||||
<EndpointTable :title="t('api.groupService')" :auth="t('api.authBearer')" :endpoints="serviceApi" />
|
<EndpointTable :title="t('api.groupService')" :auth="t('api.authBearer')" :endpoints="serviceApi" />
|
||||||
|
<EndpointTable :title="t('api.groupTechnical')" :auth="t('api.authBearer')" :endpoints="technicalApi" />
|
||||||
<EndpointTable :title="t('api.groupParts')" :auth="t('api.authBearer')" :endpoints="partsApi" />
|
<EndpointTable :title="t('api.groupParts')" :auth="t('api.authBearer')" :endpoints="partsApi" />
|
||||||
|
<EndpointTable :title="t('api.groupFuel')" :auth="t('api.authBearer')" :endpoints="fuelApi" />
|
||||||
|
<EndpointTable :title="t('api.groupCharging')" :auth="t('api.authBearer')" :endpoints="chargingApi" />
|
||||||
|
<EndpointTable :title="t('api.groupMaintenance')" :auth="t('api.authBearer')" :endpoints="maintenanceApi" />
|
||||||
|
<EndpointTable :title="t('api.groupDocuments')" :auth="t('api.authBearer')" :endpoints="documentsApi" />
|
||||||
|
<EndpointTable :title="t('api.groupReminders')" :auth="t('api.authBearer')" :endpoints="remindersApi" />
|
||||||
|
<EndpointTable
|
||||||
|
:title="t('api.groupAttachments')"
|
||||||
|
:auth="t('api.authBearer')"
|
||||||
|
:endpoints="attachmentsApi"
|
||||||
|
:note="attachmentsNote"
|
||||||
|
/>
|
||||||
|
<EndpointTable :title="t('api.groupProviders')" :auth="t('api.authBearer')" :endpoints="providersApi" />
|
||||||
|
<EndpointTable :title="t('api.groupIntegrations')" :auth="t('api.authBearer')" :endpoints="integrationsApi" />
|
||||||
|
<EndpointTable :title="t('api.groupOcpp')" :auth="t('api.authCharger')" :endpoints="ocppApi" />
|
||||||
<EndpointTable :title="t('api.groupAccount')" :auth="t('api.authBearer')" :endpoints="accountApi" />
|
<EndpointTable :title="t('api.groupAccount')" :auth="t('api.authBearer')" :endpoints="accountApi" />
|
||||||
<EndpointTable :title="t('api.groupManagement')" :auth="t('api.authManager')" :endpoints="managementApi" />
|
<EndpointTable :title="t('api.groupManagement')" :auth="t('api.authManager')" :endpoints="managementApi" />
|
||||||
<EndpointTable :title="t('api.groupSuperadmin')" :auth="t('api.authSuperadmin')" :endpoints="superadminApi" />
|
<EndpointTable :title="t('api.groupSuperadmin')" :auth="t('api.authSuperadmin')" :endpoints="superadminApi" />
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ defineProps({
|
|||||||
title: String,
|
title: String,
|
||||||
auth: String,
|
auth: String,
|
||||||
endpoints: Array, // [{ method, path, desc }]
|
endpoints: Array, // [{ method, path, desc }]
|
||||||
|
note: String, // optional line under the header, e.g. what a {placeholder} stands for
|
||||||
});
|
});
|
||||||
|
|
||||||
const methodClass = {
|
const methodClass = {
|
||||||
GET: "text-success",
|
GET: "text-success",
|
||||||
POST: "text-brandtext",
|
POST: "text-brandtext",
|
||||||
|
PUT: "text-info",
|
||||||
PATCH: "text-warning",
|
PATCH: "text-warning",
|
||||||
DELETE: "text-danger",
|
DELETE: "text-danger",
|
||||||
};
|
};
|
||||||
@@ -17,30 +19,37 @@ const methodClass = {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dh-card overflow-hidden">
|
<div class="dh-card overflow-hidden">
|
||||||
<div class="flex items-center justify-between border-b border-subtle px-5 py-4">
|
<div class="border-b border-subtle px-5 py-4">
|
||||||
<div class="text-base font-bold tracking-[-0.02em] text-strong">{{ title }}</div>
|
<div class="flex items-center justify-between">
|
||||||
<span class="eyebrow">{{ auth }}</span>
|
<div class="text-base font-bold tracking-[-0.02em] text-strong">{{ title }}</div>
|
||||||
|
<span class="eyebrow">{{ auth }}</span>
|
||||||
|
</div>
|
||||||
|
<p v-if="note" class="mt-1.5 text-xs text-muted">{{ note }}</p>
|
||||||
|
</div>
|
||||||
|
<!-- The longest paths (the per-charger OCPP control routes) outrun a narrow
|
||||||
|
window, so the table scrolls inside the card rather than being clipped. -->
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="w-full text-left text-sm">
|
||||||
|
<thead>
|
||||||
|
<tr class="[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium">
|
||||||
|
<th>{{ t("api.colEndpoint") }}</th>
|
||||||
|
<th>{{ t("api.colDescription") }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="e in endpoints"
|
||||||
|
:key="e.method + e.path"
|
||||||
|
class="transition-colors hover:bg-sunken"
|
||||||
|
>
|
||||||
|
<td class="data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap">
|
||||||
|
<span class="font-semibold" :class="methodClass[e.method]">{{ e.method }}</span>
|
||||||
|
<span class="text-strong"> {{ e.path }}</span>
|
||||||
|
</td>
|
||||||
|
<td class="border-t border-subtle px-5 py-2.5 text-body">{{ e.desc }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<table class="w-full text-left text-sm">
|
|
||||||
<thead>
|
|
||||||
<tr class="[&>th]:eyebrow [&>th]:px-5 [&>th]:py-2.5 [&>th]:font-medium">
|
|
||||||
<th>{{ t("api.colEndpoint") }}</th>
|
|
||||||
<th>{{ t("api.colDescription") }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr
|
|
||||||
v-for="e in endpoints"
|
|
||||||
:key="e.method + e.path"
|
|
||||||
class="transition-colors hover:bg-sunken"
|
|
||||||
>
|
|
||||||
<td class="data border-t border-subtle px-5 py-2.5 text-xs whitespace-nowrap">
|
|
||||||
<span class="font-semibold" :class="methodClass[e.method]">{{ e.method }}</span>
|
|
||||||
<span class="text-strong"> {{ e.path }}</span>
|
|
||||||
</td>
|
|
||||||
<td class="border-t border-subtle px-5 py-2.5 text-body">{{ e.desc }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -167,11 +167,22 @@
|
|||||||
"authBearer": "Bearer-token",
|
"authBearer": "Bearer-token",
|
||||||
"authManager": "Admin / superadmin",
|
"authManager": "Admin / superadmin",
|
||||||
"authSuperadmin": "Superadmin",
|
"authSuperadmin": "Superadmin",
|
||||||
|
"authCharger": "Laderens loginoplysninger",
|
||||||
"groupPublic": "Offentlig",
|
"groupPublic": "Offentlig",
|
||||||
"groupIdentity": "Identitet",
|
"groupIdentity": "Identitet",
|
||||||
"groupCars": "Biler",
|
"groupCars": "Biler",
|
||||||
"groupService": "Serviceposter",
|
"groupService": "Serviceposter",
|
||||||
|
"groupTechnical": "Syn",
|
||||||
"groupParts": "Reservedele",
|
"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",
|
"groupAccount": "Konto",
|
||||||
"groupManagement": "Administration",
|
"groupManagement": "Administration",
|
||||||
"groupSuperadmin": "Superadmin"
|
"groupSuperadmin": "Superadmin"
|
||||||
|
|||||||
@@ -167,11 +167,22 @@
|
|||||||
"authBearer": "Bearer token",
|
"authBearer": "Bearer token",
|
||||||
"authManager": "Admin / superadmin",
|
"authManager": "Admin / superadmin",
|
||||||
"authSuperadmin": "Superadmin",
|
"authSuperadmin": "Superadmin",
|
||||||
|
"authCharger": "Charger credentials",
|
||||||
"groupPublic": "Public",
|
"groupPublic": "Public",
|
||||||
"groupIdentity": "Identity",
|
"groupIdentity": "Identity",
|
||||||
"groupCars": "Cars",
|
"groupCars": "Cars",
|
||||||
"groupService": "Service records",
|
"groupService": "Service records",
|
||||||
|
"groupTechnical": "Technical checks",
|
||||||
"groupParts": "Parts",
|
"groupParts": "Parts",
|
||||||
|
"groupFuel": "Fuel",
|
||||||
|
"groupCharging": "Charging",
|
||||||
|
"groupMaintenance": "Maintenance",
|
||||||
|
"groupDocuments": "Documents",
|
||||||
|
"groupReminders": "Reminders",
|
||||||
|
"groupAttachments": "Attachments",
|
||||||
|
"groupProviders": "Vehicle providers",
|
||||||
|
"groupIntegrations": "Integrations",
|
||||||
|
"groupOcpp": "OCPP",
|
||||||
"groupAccount": "Account",
|
"groupAccount": "Account",
|
||||||
"groupManagement": "Management",
|
"groupManagement": "Management",
|
||||||
"groupSuperadmin": "Superadmin"
|
"groupSuperadmin": "Superadmin"
|
||||||
|
|||||||
@@ -167,11 +167,22 @@
|
|||||||
"authBearer": "Token Bearer",
|
"authBearer": "Token Bearer",
|
||||||
"authManager": "Administrator / superadministrator",
|
"authManager": "Administrator / superadministrator",
|
||||||
"authSuperadmin": "Superadministrator",
|
"authSuperadmin": "Superadministrator",
|
||||||
|
"authCharger": "Dane logowania ładowarki",
|
||||||
"groupPublic": "Publiczne",
|
"groupPublic": "Publiczne",
|
||||||
"groupIdentity": "Tożsamość",
|
"groupIdentity": "Tożsamość",
|
||||||
"groupCars": "Samochody",
|
"groupCars": "Samochody",
|
||||||
"groupService": "Wpisy serwisowe",
|
"groupService": "Wpisy serwisowe",
|
||||||
|
"groupTechnical": "Przeglądy techniczne",
|
||||||
"groupParts": "Części",
|
"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",
|
"groupAccount": "Konto",
|
||||||
"groupManagement": "Zarządzanie",
|
"groupManagement": "Zarządzanie",
|
||||||
"groupSuperadmin": "Superadministrator"
|
"groupSuperadmin": "Superadministrator"
|
||||||
|
|||||||
Reference in new issue
Block a user