diff --git a/404.html b/404.html new file mode 100644 index 00000000..773e472a --- /dev/null +++ b/404.html @@ -0,0 +1,22 @@ + + + + + + 404 | @jmondi/oauth2-server + + + + + + + + + + + +
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/adapters/index.html b/adapters/index.html new file mode 100644 index 00000000..85898d47 --- /dev/null +++ b/adapters/index.html @@ -0,0 +1,33 @@ + + + + + + Adapters | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Adapters

Adapters are a set of helper functions to provide framework specific integration into @jmondi/oauth2-server. Currently, Express and Fastify are both supported.

Express

https://expressjs.com/

typescript
import {
+  requestFromExpress,
+  handleExpressResponse,
+  handleExpressError,
+} from "@jmondi/oauth2-server/express"
typescript
requestFromExpress(req: Express.Request): OAuthRequest;

Helper function to return an OAuthRequest from an Express.Request.

typescript
handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void;

Helper function that handles the express response after authorization.

typescript
handleExpressError(res: Express.Response, e: unknown | OAuthException): void;

Helper function that handles the express response if an error was thrown.

Fastify

https://www.fastify.io/

typescript
import {
+  requestFromFastify,
+  handleFastifyReply,
+  handleFastifyError,
+} from "@jmondi/oauth2-server/fastify"

The following functions are imported directly from the adapter instead of the root package.

typescript
requestFromFastify(req: FastifyRequest): OAuthRequest;

Helper function to return an OAuthRequest from an FastifyRequest.

typescript
handleFastifyReply(fastifyReply: FasitfyReply, oauthResponse: OAuthResponse): void;

Helper function that handles the express response after authorization.

typescript
handleFastifyError(reply: FasitfyReply, e: unknown | OAuthException): void;

Helper function that handles the express response if an error was thrown.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/assets/adapters_index.md.PFJHoqKF.js b/assets/adapters_index.md.PFJHoqKF.js new file mode 100644 index 00000000..c054b594 --- /dev/null +++ b/assets/adapters_index.md.PFJHoqKF.js @@ -0,0 +1,9 @@ +import{_ as s,c as e,o as a,U as i}from"./chunks/framework.XQuvpNW4.js";const y=JSON.parse('{"title":"Adapters","description":"","frontmatter":{"title":"Adapters"},"headers":[],"relativePath":"adapters/index.md","filePath":"adapters/index.md"}'),t={name:"adapters/index.md"},p=i(`

Adapters

Adapters are a set of helper functions to provide framework specific integration into @jmondi/oauth2-server. Currently, Express and Fastify are both supported.

Express

https://expressjs.com/

typescript
import {
+  requestFromExpress,
+  handleExpressResponse,
+  handleExpressError,
+} from "@jmondi/oauth2-server/express"
typescript
requestFromExpress(req: Express.Request): OAuthRequest;

Helper function to return an OAuthRequest from an Express.Request.

typescript
handleExpressResponse(expressResponse: Express.Response, oauthResponse: OAuthResponse): void;

Helper function that handles the express response after authorization.

typescript
handleExpressError(res: Express.Response, e: unknown | OAuthException): void;

Helper function that handles the express response if an error was thrown.

Fastify

https://www.fastify.io/

typescript
import {
+  requestFromFastify,
+  handleFastifyReply,
+  handleFastifyError,
+} from "@jmondi/oauth2-server/fastify"

The following functions are imported directly from the adapter instead of the root package.

typescript
requestFromFastify(req: FastifyRequest): OAuthRequest;

Helper function to return an OAuthRequest from an FastifyRequest.

typescript
handleFastifyReply(fastifyReply: FasitfyReply, oauthResponse: OAuthResponse): void;

Helper function that handles the express response after authorization.

typescript
handleFastifyError(reply: FasitfyReply, e: unknown | OAuthException): void;

Helper function that handles the express response if an error was thrown.

`,21),n=[p];function h(r,l,o,d,k,c){return a(),e("div",null,n)}const u=s(t,[["render",h]]);export{y as __pageData,u as default}; diff --git a/assets/adapters_index.md.PFJHoqKF.lean.js b/assets/adapters_index.md.PFJHoqKF.lean.js new file mode 100644 index 00000000..663d24af --- /dev/null +++ b/assets/adapters_index.md.PFJHoqKF.lean.js @@ -0,0 +1 @@ +import{_ as s,c as e,o as a,U as i}from"./chunks/framework.XQuvpNW4.js";const y=JSON.parse('{"title":"Adapters","description":"","frontmatter":{"title":"Adapters"},"headers":[],"relativePath":"adapters/index.md","filePath":"adapters/index.md"}'),t={name:"adapters/index.md"},p=i("",21),n=[p];function h(r,l,o,d,k,c){return a(),e("div",null,n)}const u=s(t,[["render",h]]);export{y as __pageData,u as default}; diff --git a/assets/app.WhyVwq6F.js b/assets/app.WhyVwq6F.js new file mode 100644 index 00000000..7e801fc3 --- /dev/null +++ b/assets/app.WhyVwq6F.js @@ -0,0 +1,7 @@ +import{v as s,a1 as i,a2 as u,a3 as c,a4 as l,a5 as f,a6 as d,a7 as m,a8 as h,a9 as A,aa as g,ab as v,d as P,u as y,j as C,z as w,ac as _,ad as b,ae as E,af as R}from"./chunks/framework.XQuvpNW4.js";import{t as D}from"./chunks/theme.B3UUe-eO.js";function p(e){if(e.extends){const a=p(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const o=p(D),j=P({name:"VitePressApp",setup(){const{site:e}=y();return C(()=>{w(()=>{document.documentElement.lang=e.value.lang,document.documentElement.dir=e.value.dir})}),e.value.router.prefetchLinks&&_(),b(),E(),o.setup&&o.setup(),()=>R(o.Layout)}});async function L(){const e=S(),a=O();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),o.enhanceApp&&await o.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function O(){return h(j)}function S(){let e=s,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=v(()=>import(n),__vite__mapDeps([]))),s&&(e=!1),r},o.NotFound)}s&&L().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{L as createApp}; +function __vite__mapDeps(indexes) { + if (!__vite__mapDeps.viteFileDeps) { + __vite__mapDeps.viteFileDeps = [] + } + return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) +} \ No newline at end of file diff --git a/assets/chunks/framework.XQuvpNW4.js b/assets/chunks/framework.XQuvpNW4.js new file mode 100644 index 00000000..a19bf76c --- /dev/null +++ b/assets/chunks/framework.XQuvpNW4.js @@ -0,0 +1 @@ +function ui(e,t){const n=new Set(e.split(","));return t?i=>n.has(i.toLowerCase()):i=>n.has(i)}const te={},yt=[],Ee=()=>{},ir=()=>!1,Ut=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),pi=e=>e.startsWith("onUpdate:"),oe=Object.assign,di=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},sr=Object.prototype.hasOwnProperty,Y=(e,t)=>sr.call(e,t),H=Array.isArray,vt=e=>yn(e)==="[object Map]",Ls=e=>yn(e)==="[object Set]",K=e=>typeof e=="function",ne=e=>typeof e=="string",At=e=>typeof e=="symbol",Z=e=>e!==null&&typeof e=="object",Ps=e=>(Z(e)||K(e))&&K(e.then)&&K(e.catch),Ms=Object.prototype.toString,yn=e=>Ms.call(e),or=e=>yn(e).slice(8,-1),Is=e=>yn(e)==="[object Object]",mi=e=>ne(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Pt=ui(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),vn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},rr=/-(\w)/g,Me=vn(e=>e.replace(rr,(t,n)=>n?n.toUpperCase():"")),lr=/\B([A-Z])/g,ut=vn(e=>e.replace(lr,"-$1").toLowerCase()),_n=vn(e=>e.charAt(0).toUpperCase()+e.slice(1)),rn=vn(e=>e?`on${_n(e)}`:""),Ze=(e,t)=>!Object.is(e,t),kn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},ar=e=>{const t=parseFloat(e);return isNaN(t)?e:t},cr=e=>{const t=ne(e)?Number(e):NaN;return isNaN(t)?e:t};let Hi;const Ns=()=>Hi||(Hi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function hi(e){if(H(e)){const t={};for(let n=0;n{if(n){const i=n.split(ur);i.length>1&&(t[i[0].trim()]=i[1].trim())}}),t}function gi(e){let t="";if(ne(e))t=e;else if(H(e))for(let n=0;nne(e)?e:e==null?"":H(e)||Z(e)&&(e.toString===Ms||!K(e.toString))?JSON.stringify(e,ks,2):String(e),ks=(e,t)=>t&&t.__v_isRef?ks(e,t.value):vt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[i,s],o)=>(n[$n(i,o)+" =>"]=s,n),{})}:Ls(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>$n(n))}:At(t)?$n(t):Z(t)&&!H(t)&&!Is(t)?String(t):t,$n=(e,t="")=>{var n;return At(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};let ve;class gr{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=ve,!t&&ve&&(this.index=(ve.scopes||(ve.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=ve;try{return ve=this,t()}finally{ve=n}}}on(){ve=this}off(){ve=this.parent}stop(t){if(this._active){let n,i;for(n=0,i=this.effects.length;n=2))break;dt(),this._queryings--}return this._dirtyLevel>=2}set dirty(t){this._dirtyLevel=t?3:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=Ge,n=lt;try{return Ge=!0,lt=this,this._runnings++,Vi(this),this.fn()}finally{Di(this),this._runnings--,lt=n,Ge=t}}stop(){var t;this.active&&(Vi(this),Di(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function vr(e){return e.value}function Vi(e){e._trackId++,e._depsLength=0}function Di(e){if(e.deps&&e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},fn=new WeakMap,at=Symbol(""),Qn=Symbol("");function xe(e,t,n){if(Ge&<){let i=fn.get(e);i||fn.set(e,i=new Map);let s=i.get(n);s||i.set(n,s=Us(()=>i.delete(n))),Ds(lt,s)}}function ke(e,t,n,i,s,o){const r=fn.get(e);if(!r)return;let l=[];if(t==="clear")l=[...r.values()];else if(n==="length"&&H(e)){const a=Number(i);r.forEach((f,p)=>{(p==="length"||!At(p)&&p>=a)&&l.push(f)})}else switch(n!==void 0&&l.push(r.get(n)),t){case"add":H(e)?mi(n)&&l.push(r.get("length")):(l.push(r.get(at)),vt(e)&&l.push(r.get(Qn)));break;case"delete":H(e)||(l.push(r.get(at)),vt(e)&&l.push(r.get(Qn)));break;case"set":vt(e)&&l.push(r.get(at));break}yi();for(const a of l)a&&Bs(a,3);vi()}function _r(e,t){var n;return(n=fn.get(e))==null?void 0:n.get(t)}const br=ui("__proto__,__v_isRef,__isVue"),Ks=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(At)),Bi=wr();function wr(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const i=J(this);for(let o=0,r=this.length;o{e[t]=function(...n){pt(),yi();const i=J(this)[t].apply(this,n);return vi(),dt(),i}}),e}function Cr(e){const t=J(this);return xe(t,"has",e),t.hasOwnProperty(e)}class qs{constructor(t=!1,n=!1){this._isReadonly=t,this._shallow=n}get(t,n,i){const s=this._isReadonly,o=this._shallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return o;if(n==="__v_raw")return i===(s?o?Fr:Ys:o?Gs:zs).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(i)?t:void 0;const r=H(t);if(!s){if(r&&Y(Bi,n))return Reflect.get(Bi,n,i);if(n==="hasOwnProperty")return Cr}const l=Reflect.get(t,n,i);return(At(n)?Ks.has(n):br(n))||(s||xe(t,"get",n),o)?l:pe(l)?r&&mi(n)?l:l.value:Z(l)?s?Cn(l):wn(l):l}}class Ws extends qs{constructor(t=!1){super(!1,t)}set(t,n,i,s){let o=t[n];if(!this._shallow){const a=Et(o);if(!gt(i)&&!Et(i)&&(o=J(o),i=J(i)),!H(t)&&pe(o)&&!pe(i))return a?!1:(o.value=i,!0)}const r=H(t)&&mi(n)?Number(n)e,bn=e=>Reflect.getPrototypeOf(e);function Wt(e,t,n=!1,i=!1){e=e.__v_raw;const s=J(e),o=J(t);n||(Ze(t,o)&&xe(s,"get",t),xe(s,"get",o));const{has:r}=bn(s),l=i?_i:n?Ci:$t;if(r.call(s,t))return l(e.get(t));if(r.call(s,o))return l(e.get(o));e!==s&&e.get(t)}function zt(e,t=!1){const n=this.__v_raw,i=J(n),s=J(e);return t||(Ze(e,s)&&xe(i,"has",e),xe(i,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function Gt(e,t=!1){return e=e.__v_raw,!t&&xe(J(e),"iterate",at),Reflect.get(e,"size",e)}function Ui(e){e=J(e);const t=J(this);return bn(t).has.call(t,e)||(t.add(e),ke(t,"add",e,e)),this}function Ki(e,t){t=J(t);const n=J(this),{has:i,get:s}=bn(n);let o=i.call(n,e);o||(e=J(e),o=i.call(n,e));const r=s.call(n,e);return n.set(e,t),o?Ze(t,r)&&ke(n,"set",e,t):ke(n,"add",e,t),this}function qi(e){const t=J(this),{has:n,get:i}=bn(t);let s=n.call(t,e);s||(e=J(e),s=n.call(t,e)),i&&i.call(t,e);const o=t.delete(e);return s&&ke(t,"delete",e,void 0),o}function Wi(){const e=J(this),t=e.size!==0,n=e.clear();return t&&ke(e,"clear",void 0,void 0),n}function Yt(e,t){return function(i,s){const o=this,r=o.__v_raw,l=J(r),a=t?_i:e?Ci:$t;return!e&&xe(l,"iterate",at),r.forEach((f,p)=>i.call(s,a(f),a(p),o))}}function Jt(e,t,n){return function(...i){const s=this.__v_raw,o=J(s),r=vt(o),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,f=s[e](...i),p=n?_i:t?Ci:$t;return!t&&xe(o,"iterate",a?Qn:at),{next(){const{value:d,done:g}=f.next();return g?{value:d,done:g}:{value:l?[p(d[0]),p(d[1])]:p(d),done:g}},[Symbol.iterator](){return this}}}}function Ve(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function jr(){const e={get(o){return Wt(this,o)},get size(){return Gt(this)},has:zt,add:Ui,set:Ki,delete:qi,clear:Wi,forEach:Yt(!1,!1)},t={get(o){return Wt(this,o,!1,!0)},get size(){return Gt(this)},has:zt,add:Ui,set:Ki,delete:qi,clear:Wi,forEach:Yt(!1,!0)},n={get(o){return Wt(this,o,!0)},get size(){return Gt(this,!0)},has(o){return zt.call(this,o,!0)},add:Ve("add"),set:Ve("set"),delete:Ve("delete"),clear:Ve("clear"),forEach:Yt(!0,!1)},i={get(o){return Wt(this,o,!0,!0)},get size(){return Gt(this,!0)},has(o){return zt.call(this,o,!0)},add:Ve("add"),set:Ve("set"),delete:Ve("delete"),clear:Ve("clear"),forEach:Yt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=Jt(o,!1,!1),n[o]=Jt(o,!0,!1),t[o]=Jt(o,!1,!0),i[o]=Jt(o,!0,!0)}),[e,n,t,i]}const[Rr,Or,Lr,Pr]=jr();function bi(e,t){const n=t?e?Pr:Lr:e?Or:Rr;return(i,s,o)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?i:Reflect.get(Y(n,s)&&s in i?n:i,s,o)}const Mr={get:bi(!1,!1)},Ir={get:bi(!1,!0)},Nr={get:bi(!0,!1)},zs=new WeakMap,Gs=new WeakMap,Ys=new WeakMap,Fr=new WeakMap;function kr(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function $r(e){return e.__v_skip||!Object.isExtensible(e)?0:kr(or(e))}function wn(e){return Et(e)?e:wi(e,!1,Sr,Mr,zs)}function Hr(e){return wi(e,!1,Ar,Ir,Gs)}function Cn(e){return wi(e,!0,Tr,Nr,Ys)}function wi(e,t,n,i,s){if(!Z(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=s.get(e);if(o)return o;const r=$r(e);if(r===0)return e;const l=new Proxy(e,r===2?i:n);return s.set(e,l),l}function _t(e){return Et(e)?_t(e.__v_raw):!!(e&&e.__v_isReactive)}function Et(e){return!!(e&&e.__v_isReadonly)}function gt(e){return!!(e&&e.__v_isShallow)}function Js(e){return _t(e)||Et(e)}function J(e){const t=e&&e.__v_raw;return t?J(t):e}function Mt(e){return cn(e,"__v_skip",!0),e}const $t=e=>Z(e)?wn(e):e,Ci=e=>Z(e)?Cn(e):e;class Xs{constructor(t,n,i,s){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new xi(()=>t(this._value),()=>un(this,1)),this.effect.computed=this,this.effect.active=this._cacheable=!s,this.__v_isReadonly=i}get value(){const t=J(this);return Ei(t),(!t._cacheable||t.effect.dirty)&&Ze(t._value,t._value=t.effect.run())&&un(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function Vr(e,t,n=!1){let i,s;const o=K(e);return o?(i=e,s=Ee):(i=e.get,s=e.set),new Xs(i,s,o||!s,n)}function Ei(e){Ge&<&&(e=J(e),Ds(lt,e.dep||(e.dep=Us(()=>e.dep=void 0,e instanceof Xs?e:void 0))))}function un(e,t=3,n){e=J(e);const i=e.dep;i&&Bs(i,t)}function pe(e){return!!(e&&e.__v_isRef===!0)}function ge(e){return Zs(e,!1)}function Qs(e){return Zs(e,!0)}function Zs(e,t){return pe(e)?e:new Dr(e,t)}class Dr{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:J(t),this._value=n?t:$t(t)}get value(){return Ei(this),this._value}set value(t){const n=this.__v_isShallow||gt(t)||Et(t);t=n?t:J(t),Ze(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:$t(t),un(this,3))}}function eo(e){return pe(e)?e.value:e}const Br={get:(e,t,n)=>eo(Reflect.get(e,t,n)),set:(e,t,n,i)=>{const s=e[t];return pe(s)&&!pe(n)?(s.value=n,!0):Reflect.set(e,t,n,i)}};function to(e){return _t(e)?e:new Proxy(e,Br)}class Ur{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:i}=t(()=>Ei(this),()=>un(this));this._get=n,this._set=i}get value(){return this._get()}set value(t){this._set(t)}}function Kr(e){return new Ur(e)}class qr{constructor(t,n,i){this._object=t,this._key=n,this._defaultValue=i,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return _r(J(this._object),this._key)}}class Wr{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function zr(e,t,n){return pe(e)?e:K(e)?new Wr(e):Z(e)&&arguments.length>1?Gr(e,t,n):ge(e)}function Gr(e,t,n){const i=e[t];return pe(i)?i:new qr(e,t,n)}function Ye(e,t,n,i){let s;try{s=i?e(...i):e()}catch(o){En(o,t,n)}return s}function Se(e,t,n,i){if(K(e)){const o=Ye(e,t,n,i);return o&&Ps(o)&&o.catch(r=>{En(r,t,n)}),o}const s=[];for(let o=0;o>>1,s=fe[i],o=Vt(s);oPe&&fe.splice(t,1)}function Qr(e){H(e)?bt.push(...e):(!Fe||!Fe.includes(e,e.allowRecurse?ot+1:ot))&&bt.push(e),io()}function zi(e,t,n=Ht?Pe+1:0){for(;nVt(n)-Vt(i)),ot=0;ote.id==null?1/0:e.id,Zr=(e,t)=>{const n=Vt(e)-Vt(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function so(e){Zn=!1,Ht=!0,fe.sort(Zr);try{for(Pe=0;Pene(b)?b.trim():b)),d&&(s=n.map(ar))}let l,a=i[l=rn(t)]||i[l=rn(Me(t))];!a&&o&&(a=i[l=rn(ut(t))]),a&&Se(a,e,6,s);const f=i[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Se(f,e,6,s)}}function oo(e,t,n=!1){const i=t.emitsCache,s=i.get(e);if(s!==void 0)return s;const o=e.emits;let r={},l=!1;if(!K(e)){const a=f=>{const p=oo(f,t,!0);p&&(l=!0,oe(r,p))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(Z(e)&&i.set(e,null),null):(H(o)?o.forEach(a=>r[a]=null):oe(r,o),Z(e)&&i.set(e,r),r)}function Tn(e,t){return!e||!Ut(t)?!1:(t=t.slice(2).replace(/Once$/,""),Y(e,t[0].toLowerCase()+t.slice(1))||Y(e,ut(t))||Y(e,t))}let ue=null,An=null;function dn(e){const t=ue;return ue=e,An=e&&e.type.__scopeId||null,t}function Oc(e){An=e}function Lc(){An=null}function tl(e,t=ue,n){if(!t||e._n)return e;const i=(...s)=>{i._d&&os(-1);const o=dn(t);let r;try{r=e(...s)}finally{dn(o),i._d&&os(1)}return r};return i._n=!0,i._c=!0,i._d=!0,i}function Hn(e){const{type:t,vnode:n,proxy:i,withProxy:s,props:o,propsOptions:[r],slots:l,attrs:a,emit:f,render:p,renderCache:d,data:g,setupState:b,ctx:L,inheritAttrs:M}=e;let $,U;const X=dn(e);try{if(n.shapeFlag&4){const x=s||i,C=x;$=Ae(p.call(C,x,d,o,b,g,L)),U=a}else{const x=t;$=Ae(x.length>1?x(o,{attrs:a,slots:l,emit:f}):x(o,null)),U=t.props?a:nl(a)}}catch(x){Ft.length=0,En(x,e,1),$=ce(_e)}let m=$;if(U&&M!==!1){const x=Object.keys(U),{shapeFlag:C}=m;x.length&&C&7&&(r&&x.some(pi)&&(U=il(U,r)),m=et(m,U))}return n.dirs&&(m=et(m),m.dirs=m.dirs?m.dirs.concat(n.dirs):n.dirs),n.transition&&(m.transition=n.transition),$=m,dn(X),$}const nl=e=>{let t;for(const n in e)(n==="class"||n==="style"||Ut(n))&&((t||(t={}))[n]=e[n]);return t},il=(e,t)=>{const n={};for(const i in e)(!pi(i)||!(i.slice(9)in t))&&(n[i]=e[i]);return n};function sl(e,t,n){const{props:i,children:s,component:o}=e,{props:r,children:l,patchFlag:a}=t,f=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return i?Gi(i,r,f):!!r;if(a&8){const p=t.dynamicProps;for(let d=0;de.__isSuspense;function ao(e,t){t&&t.pendingBranch?H(e)?t.effects.push(...e):t.effects.push(e):Qr(e)}const ll=Symbol.for("v-scx"),al=()=>Ct(ll);function co(e,t){return jn(e,null,t)}function Ic(e,t){return jn(e,null,{flush:"post"})}const Xt={};function Je(e,t,n){return jn(e,t,n)}function jn(e,t,{immediate:n,deep:i,flush:s,once:o,onTrack:r,onTrigger:l}=te){var a;if(t&&o){const C=t;t=(...D)=>{C(...D),x()}}const f=$s()===((a=le)==null?void 0:a.scope)?le:null;let p,d=!1,g=!1;if(pe(e)?(p=()=>e.value,d=gt(e)):_t(e)?(p=gt(e)||i===!1?()=>ze(e,1):()=>ze(e),d=!0):H(e)?(g=!0,d=e.some(C=>_t(C)||gt(C)),p=()=>e.map(C=>{if(pe(C))return C.value;if(_t(C))return ze(C,gt(C)||i===!1?1:void 0);if(K(C))return Ye(C,f,2)})):K(e)?t?p=()=>Ye(e,f,2):p=()=>{if(!(f&&f.isUnmounted))return b&&b(),Se(e,f,3,[L])}:p=Ee,t&&i){const C=p;p=()=>ze(C())}let b,L=C=>{b=m.onStop=()=>{Ye(C,f,4),b=m.onStop=void 0}},M;if(In)if(L=Ee,t?n&&Se(t,f,3,[p(),g?[]:void 0,L]):p(),s==="sync"){const C=al();M=C.__watcherHandles||(C.__watcherHandles=[])}else return Ee;let $=g?new Array(e.length).fill(Xt):Xt;const U=()=>{if(!(!m.active||!m.dirty))if(t){const C=m.run();(i||d||(g?C.some((D,V)=>Ze(D,$[V])):Ze(C,$)))&&(b&&b(),Se(t,f,3,[C,$===Xt?void 0:g&&$[0]===Xt?[]:$,L]),$=C)}else m.run()};U.allowRecurse=!!t;let X;s==="sync"?X=U:s==="post"?X=()=>me(U,f&&f.suspense):(U.pre=!0,f&&(U.id=f.uid),X=()=>Ti(U));const m=new xi(p,Ee,X),x=()=>{m.stop(),f&&f.scope&&di(f.scope.effects,m)};return t?n?U():$=m.run():s==="post"?me(m.run.bind(m),f&&f.suspense):m.run(),M&&M.push(x),x}function cl(e,t,n){const i=this.proxy,s=ne(e)?e.includes(".")?fo(i,e):()=>i[e]:e.bind(i,i);let o;K(t)?o=t:(o=t.handler,n=t);const r=le;Tt(this);const l=jn(s,o.bind(i),n);return r?Tt(r):ct(),l}function fo(e,t){const n=t.split(".");return()=>{let i=e;for(let s=0;s0){if(n>=t)return e;n++}if(i=i||new Set,i.has(e))return e;if(i.add(e),pe(e))ze(e.value,t,n,i);else if(H(e))for(let s=0;s{ze(s,t,n,i)});else if(Is(e))for(const s in e)ze(e[s],t,n,i);return e}function Le(e,t,n,i){const s=e.dirs,o=t&&t.dirs;for(let r=0;r{e.isMounted=!0}),xo(()=>{e.isUnmounting=!0}),e}const be=[Function,Array],uo={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:be,onEnter:be,onAfterEnter:be,onEnterCancelled:be,onBeforeLeave:be,onLeave:be,onAfterLeave:be,onLeaveCancelled:be,onBeforeAppear:be,onAppear:be,onAfterAppear:be,onAppearCancelled:be},ul={name:"BaseTransition",props:uo,setup(e,{slots:t}){const n=Mn(),i=fl();let s;return()=>{const o=t.default&&mo(t.default(),!0);if(!o||!o.length)return;let r=o[0];if(o.length>1){for(const M of o)if(M.type!==_e){r=M;break}}const l=J(e),{mode:a}=l;if(i.isLeaving)return Vn(r);const f=Ji(r);if(!f)return Vn(r);const p=ei(f,l,i,n);ti(f,p);const d=n.subTree,g=d&&Ji(d);let b=!1;const{getTransitionKey:L}=f.type;if(L){const M=L();s===void 0?s=M:M!==s&&(s=M,b=!0)}if(g&&g.type!==_e&&(!rt(f,g)||b)){const M=ei(g,l,i,n);if(ti(g,M),a==="out-in")return i.isLeaving=!0,M.afterLeave=()=>{i.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},Vn(r);a==="in-out"&&f.type!==_e&&(M.delayLeave=($,U,X)=>{const m=po(i,g);m[String(g.key)]=g,$[Ke]=()=>{U(),$[Ke]=void 0,delete p.delayedLeave},p.delayedLeave=X})}return r}}},pl=ul;function po(e,t){const{leavingVNodes:n}=e;let i=n.get(t.type);return i||(i=Object.create(null),n.set(t.type,i)),i}function ei(e,t,n,i){const{appear:s,mode:o,persisted:r=!1,onBeforeEnter:l,onEnter:a,onAfterEnter:f,onEnterCancelled:p,onBeforeLeave:d,onLeave:g,onAfterLeave:b,onLeaveCancelled:L,onBeforeAppear:M,onAppear:$,onAfterAppear:U,onAppearCancelled:X}=t,m=String(e.key),x=po(n,e),C=(O,A)=>{O&&Se(O,i,9,A)},D=(O,A)=>{const T=A[1];C(O,A),H(O)?O.every(q=>q.length<=1)&&T():O.length<=1&&T()},V={mode:o,persisted:r,beforeEnter(O){let A=l;if(!n.isMounted)if(s)A=M||l;else return;O[Ke]&&O[Ke](!0);const T=x[m];T&&rt(e,T)&&T.el[Ke]&&T.el[Ke](),C(A,[O])},enter(O){let A=a,T=f,q=p;if(!n.isMounted)if(s)A=$||a,T=U||f,q=X||p;else return;let R=!1;const W=O[Qt]=se=>{R||(R=!0,se?C(q,[O]):C(T,[O]),V.delayedLeave&&V.delayedLeave(),O[Qt]=void 0)};A?D(A,[O,W]):W()},leave(O,A){const T=String(e.key);if(O[Qt]&&O[Qt](!0),n.isUnmounting)return A();C(d,[O]);let q=!1;const R=O[Ke]=W=>{q||(q=!0,A(),W?C(L,[O]):C(b,[O]),O[Ke]=void 0,x[T]===e&&delete x[T])};x[T]=e,g?D(g,[O,R]):R()},clone(O){return ei(O,t,n,i)}};return V}function Vn(e){if(Rn(e))return e=et(e),e.children=null,e}function Ji(e){return Rn(e)?e.children?e.children[0]:void 0:e}function ti(e,t){e.shapeFlag&6&&e.component?ti(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 mo(e,t=!1,n){let i=[],s=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader,Rn=e=>e.type.__isKeepAlive;function dl(e,t){go(e,"a",t)}function ml(e,t){go(e,"da",t)}function go(e,t,n=le){const i=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(On(t,i,n),n){let s=n.parent;for(;s&&s.parent;)Rn(s.parent.vnode)&&hl(i,t,n,s),s=s.parent}}function hl(e,t,n,i){const s=On(t,e,i,!0);Ln(()=>{di(i[t],s)},n)}function On(e,t,n=le,i=!1){if(n){const s=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...r)=>{if(n.isUnmounted)return;pt(),Tt(n);const l=Se(t,n,e,r);return ct(),dt(),l});return i?s.unshift(o):s.push(o),o}}const He=e=>(t,n=le)=>(!In||e==="sp")&&On(e,(...i)=>t(...i),n),gl=He("bm"),jt=He("m"),xl=He("bu"),yl=He("u"),xo=He("bum"),Ln=He("um"),vl=He("sp"),_l=He("rtg"),bl=He("rtc");function wl(e,t=le){On("ec",e,t)}function Nc(e,t,n,i){let s;const o=n&&n[i];if(H(e)||ne(e)){s=new Array(e.length);for(let r=0,l=e.length;rt(r,l,void 0,o&&o[l]));else{const r=Object.keys(e);s=new Array(r.length);for(let l=0,a=r.length;lxn(t)?!(t.type===_e||t.type===he&&!yo(t.children)):!0)?e:null}function kc(e,t){const n={};for(const i in e)n[t&&/[A-Z]/.test(i)?`on:${i}`:rn(i)]=e[i];return n}const ni=e=>e?No(e)?Pi(e)||e.proxy:ni(e.parent):null,It=oe(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ni(e.parent),$root:e=>ni(e.root),$emit:e=>e.emit,$options:e=>ji(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,Ti(e.update)}),$nextTick:e=>e.n||(e.n=Sn.bind(e.proxy)),$watch:e=>cl.bind(e)}),Dn=(e,t)=>e!==te&&!e.__isScriptSetup&&Y(e,t),Cl={get({_:e},t){const{ctx:n,setupState:i,data:s,props:o,accessCache:r,type:l,appContext:a}=e;let f;if(t[0]!=="$"){const b=r[t];if(b!==void 0)switch(b){case 1:return i[t];case 2:return s[t];case 4:return n[t];case 3:return o[t]}else{if(Dn(i,t))return r[t]=1,i[t];if(s!==te&&Y(s,t))return r[t]=2,s[t];if((f=e.propsOptions[0])&&Y(f,t))return r[t]=3,o[t];if(n!==te&&Y(n,t))return r[t]=4,n[t];ii&&(r[t]=0)}}const p=It[t];let d,g;if(p)return t==="$attrs"&&xe(e,"get",t),p(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==te&&Y(n,t))return r[t]=4,n[t];if(g=a.config.globalProperties,Y(g,t))return g[t]},set({_:e},t,n){const{data:i,setupState:s,ctx:o}=e;return Dn(s,t)?(s[t]=n,!0):i!==te&&Y(i,t)?(i[t]=n,!0):Y(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:i,appContext:s,propsOptions:o}},r){let l;return!!n[r]||e!==te&&Y(e,r)||Dn(t,r)||(l=o[0])&&Y(l,r)||Y(i,r)||Y(It,r)||Y(s.config.globalProperties,r)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Y(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function $c(){return El().slots}function El(){const e=Mn();return e.setupContext||(e.setupContext=ko(e))}function Xi(e){return H(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let ii=!0;function Sl(e){const t=ji(e),n=e.proxy,i=e.ctx;ii=!1,t.beforeCreate&&Qi(t.beforeCreate,e,"bc");const{data:s,computed:o,methods:r,watch:l,provide:a,inject:f,created:p,beforeMount:d,mounted:g,beforeUpdate:b,updated:L,activated:M,deactivated:$,beforeDestroy:U,beforeUnmount:X,destroyed:m,unmounted:x,render:C,renderTracked:D,renderTriggered:V,errorCaptured:O,serverPrefetch:A,expose:T,inheritAttrs:q,components:R,directives:W,filters:se}=t;if(f&&Tl(f,i,null),r)for(const G in r){const N=r[G];K(N)&&(i[G]=N.bind(n))}if(s){const G=s.call(n,n);Z(G)&&(e.data=wn(G))}if(ii=!0,o)for(const G in o){const N=o[G],Ie=K(N)?N.bind(n,n):K(N.get)?N.get.bind(n,n):Ee,Kt=!K(N)&&K(N.set)?N.set.bind(n):Ee,tt=ie({get:Ie,set:Kt});Object.defineProperty(i,G,{enumerable:!0,configurable:!0,get:()=>tt.value,set:Re=>tt.value=Re})}if(l)for(const G in l)vo(l[G],i,n,G);if(a){const G=K(a)?a.call(n):a;Reflect.ownKeys(G).forEach(N=>{Pl(N,G[N])})}p&&Qi(p,e,"c");function F(G,N){H(N)?N.forEach(Ie=>G(Ie.bind(n))):N&&G(N.bind(n))}if(F(gl,d),F(jt,g),F(xl,b),F(yl,L),F(dl,M),F(ml,$),F(wl,O),F(bl,D),F(_l,V),F(xo,X),F(Ln,x),F(vl,A),H(T))if(T.length){const G=e.exposed||(e.exposed={});T.forEach(N=>{Object.defineProperty(G,N,{get:()=>n[N],set:Ie=>n[N]=Ie})})}else e.exposed||(e.exposed={});C&&e.render===Ee&&(e.render=C),q!=null&&(e.inheritAttrs=q),R&&(e.components=R),W&&(e.directives=W)}function Tl(e,t,n=Ee){H(e)&&(e=si(e));for(const i in e){const s=e[i];let o;Z(s)?"default"in s?o=Ct(s.from||i,s.default,!0):o=Ct(s.from||i):o=Ct(s),pe(o)?Object.defineProperty(t,i,{enumerable:!0,configurable:!0,get:()=>o.value,set:r=>o.value=r}):t[i]=o}}function Qi(e,t,n){Se(H(e)?e.map(i=>i.bind(t.proxy)):e.bind(t.proxy),t,n)}function vo(e,t,n,i){const s=i.includes(".")?fo(n,i):()=>n[i];if(ne(e)){const o=t[e];K(o)&&Je(s,o)}else if(K(e))Je(s,e.bind(n));else if(Z(e))if(H(e))e.forEach(o=>vo(o,t,n,i));else{const o=K(e.handler)?e.handler.bind(n):t[e.handler];K(o)&&Je(s,o,e)}}function ji(e){const t=e.type,{mixins:n,extends:i}=t,{mixins:s,optionsCache:o,config:{optionMergeStrategies:r}}=e.appContext,l=o.get(t);let a;return l?a=l:!s.length&&!n&&!i?a=t:(a={},s.length&&s.forEach(f=>mn(a,f,r,!0)),mn(a,t,r)),Z(t)&&o.set(t,a),a}function mn(e,t,n,i=!1){const{mixins:s,extends:o}=t;o&&mn(e,o,n,!0),s&&s.forEach(r=>mn(e,r,n,!0));for(const r in t)if(!(i&&r==="expose")){const l=Al[r]||n&&n[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const Al={data:Zi,props:es,emits:es,methods:Lt,computed:Lt,beforeCreate:de,created:de,beforeMount:de,mounted:de,beforeUpdate:de,updated:de,beforeDestroy:de,beforeUnmount:de,destroyed:de,unmounted:de,activated:de,deactivated:de,errorCaptured:de,serverPrefetch:de,components:Lt,directives:Lt,watch:Rl,provide:Zi,inject:jl};function Zi(e,t){return t?e?function(){return oe(K(e)?e.call(this,this):e,K(t)?t.call(this,this):t)}:t:e}function jl(e,t){return Lt(si(e),si(t))}function si(e){if(H(e)){const t={};for(let n=0;n1)return n&&K(t)?t.call(i&&i.proxy):t}}function Ml(e,t,n,i=!1){const s={},o={};cn(o,Pn,1),e.propsDefaults=Object.create(null),bo(e,t,s,o);for(const r in e.propsOptions[0])r in s||(s[r]=void 0);n?e.props=i?s:Hr(s):e.type.props?e.props=s:e.props=o,e.attrs=o}function Il(e,t,n,i){const{props:s,attrs:o,vnode:{patchFlag:r}}=e,l=J(s),[a]=e.propsOptions;let f=!1;if((i||r>0)&&!(r&16)){if(r&8){const p=e.vnode.dynamicProps;for(let d=0;d{a=!0;const[g,b]=wo(d,t,!0);oe(r,g),b&&l.push(...b)};!n&&t.mixins.length&&t.mixins.forEach(p),e.extends&&p(e.extends),e.mixins&&e.mixins.forEach(p)}if(!o&&!a)return Z(e)&&i.set(e,yt),yt;if(H(o))for(let p=0;p-1,b[1]=M<0||L-1||Y(b,"default"))&&l.push(d)}}}const f=[r,l];return Z(e)&&i.set(e,f),f}function ts(e){return e[0]!=="$"}function ns(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function is(e,t){return ns(e)===ns(t)}function ss(e,t){return H(t)?t.findIndex(n=>is(n,e)):K(t)&&is(t,e)?0:-1}const Co=e=>e[0]==="_"||e==="$stable",Ri=e=>H(e)?e.map(Ae):[Ae(e)],Nl=(e,t,n)=>{if(t._n)return t;const i=tl((...s)=>Ri(t(...s)),n);return i._c=!1,i},Eo=(e,t,n)=>{const i=e._ctx;for(const s in e){if(Co(s))continue;const o=e[s];if(K(o))t[s]=Nl(s,o,i);else if(o!=null){const r=Ri(o);t[s]=()=>r}}},So=(e,t)=>{const n=Ri(t);e.slots.default=()=>n},Fl=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=J(t),cn(t,"_",n)):Eo(t,e.slots={})}else e.slots={},t&&So(e,t);cn(e.slots,Pn,1)},kl=(e,t,n)=>{const{vnode:i,slots:s}=e;let o=!0,r=te;if(i.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(oe(s,t),!n&&l===1&&delete s._):(o=!t.$stable,Eo(t,s)),r=t}else t&&(So(e,t),r={default:1});if(o)for(const l in s)!Co(l)&&r[l]==null&&delete s[l]};function gn(e,t,n,i,s=!1){if(H(e)){e.forEach((g,b)=>gn(g,t&&(H(t)?t[b]:t),n,i,s));return}if(wt(i)&&!s)return;const o=i.shapeFlag&4?Pi(i.component)||i.component.proxy:i.el,r=s?null:o,{i:l,r:a}=e,f=t&&t.r,p=l.refs===te?l.refs={}:l.refs,d=l.setupState;if(f!=null&&f!==a&&(ne(f)?(p[f]=null,Y(d,f)&&(d[f]=null)):pe(f)&&(f.value=null)),K(a))Ye(a,l,12,[r,p]);else{const g=ne(a),b=pe(a);if(g||b){const L=()=>{if(e.f){const M=g?Y(d,a)?d[a]:p[a]:a.value;s?H(M)&&di(M,o):H(M)?M.includes(o)||M.push(o):g?(p[a]=[o],Y(d,a)&&(d[a]=p[a])):(a.value=[o],e.k&&(p[e.k]=a.value))}else g?(p[a]=r,Y(d,a)&&(d[a]=r)):b&&(a.value=r,e.k&&(p[e.k]=r))};r?(L.id=-1,me(L,n)):L()}}}let De=!1;const $l=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Hl=e=>e.namespaceURI.includes("MathML"),Zt=e=>{if($l(e))return"svg";if(Hl(e))return"mathml"},en=e=>e.nodeType===8;function Vl(e){const{mt:t,p:n,o:{patchProp:i,createText:s,nextSibling:o,parentNode:r,remove:l,insert:a,createComment:f}}=e,p=(m,x)=>{if(!x.hasChildNodes()){n(null,m,x),pn(),x._vnode=m;return}De=!1,d(x.firstChild,m,null,null,null),pn(),x._vnode=m,De&&console.error("Hydration completed but contains mismatches.")},d=(m,x,C,D,V,O=!1)=>{const A=en(m)&&m.data==="[",T=()=>M(m,x,C,D,V,A),{type:q,ref:R,shapeFlag:W,patchFlag:se}=x;let ae=m.nodeType;x.el=m,se===-2&&(O=!1,x.dynamicChildren=null);let F=null;switch(q){case St:ae!==3?x.children===""?(a(x.el=s(""),r(m),m),F=m):F=T():(m.data!==x.children&&(De=!0,m.data=x.children),F=o(m));break;case _e:X(m)?(F=o(m),U(x.el=m.content.firstChild,m,C)):ae!==8||A?F=T():F=o(m);break;case Nt:if(A&&(m=o(m),ae=m.nodeType),ae===1||ae===3){F=m;const G=!x.children.length;for(let N=0;N{O=O||!!x.dynamicChildren;const{type:A,props:T,patchFlag:q,shapeFlag:R,dirs:W,transition:se}=x,ae=A==="input"||A==="option";if(ae||q!==-1){W&&Le(x,null,C,"created");let F=!1;if(X(m)){F=To(D,se)&&C&&C.vnode.props&&C.vnode.props.appear;const N=m.content.firstChild;F&&se.beforeEnter(N),U(N,m,C),x.el=m=N}if(R&16&&!(T&&(T.innerHTML||T.textContent))){let N=b(m.firstChild,x,m,C,D,V,O);for(;N;){De=!0;const Ie=N;N=N.nextSibling,l(Ie)}}else R&8&&m.textContent!==x.children&&(De=!0,m.textContent=x.children);if(T)if(ae||!O||q&48)for(const N in T)(ae&&(N.endsWith("value")||N==="indeterminate")||Ut(N)&&!Pt(N)||N[0]===".")&&i(m,N,null,T[N],void 0,void 0,C);else T.onClick&&i(m,"onClick",null,T.onClick,void 0,void 0,C);let G;(G=T&&T.onVnodeBeforeMount)&&we(G,C,x),W&&Le(x,null,C,"beforeMount"),((G=T&&T.onVnodeMounted)||W||F)&&ao(()=>{G&&we(G,C,x),F&&se.enter(m),W&&Le(x,null,C,"mounted")},D)}return m.nextSibling},b=(m,x,C,D,V,O,A)=>{A=A||!!x.dynamicChildren;const T=x.children,q=T.length;for(let R=0;R{const{slotScopeIds:A}=x;A&&(V=V?V.concat(A):A);const T=r(m),q=b(o(m),x,T,C,D,V,O);return q&&en(q)&&q.data==="]"?o(x.anchor=q):(De=!0,a(x.anchor=f("]"),T,q),q)},M=(m,x,C,D,V,O)=>{if(De=!0,x.el=null,O){const q=$(m);for(;;){const R=o(m);if(R&&R!==q)l(R);else break}}const A=o(m),T=r(m);return l(m),n(null,x,T,A,C,D,Zt(T),V),A},$=(m,x="[",C="]")=>{let D=0;for(;m;)if(m=o(m),m&&en(m)&&(m.data===x&&D++,m.data===C)){if(D===0)return o(m);D--}return m},U=(m,x,C)=>{const D=x.parentNode;D&&D.replaceChild(m,x);let V=C;for(;V;)V.vnode.el===x&&(V.vnode.el=V.subTree.el=m),V=V.parent},X=m=>m.nodeType===1&&m.tagName.toLowerCase()==="template";return[p,d]}const me=ao;function Dl(e){return Bl(e,Vl)}function Bl(e,t){const n=Ns();n.__VUE__=!0;const{insert:i,remove:s,patchProp:o,createElement:r,createText:l,createComment:a,setText:f,setElementText:p,parentNode:d,nextSibling:g,setScopeId:b=Ee,insertStaticContent:L}=e,M=(c,u,h,y=null,v=null,E=null,j=void 0,w=null,S=!!u.dynamicChildren)=>{if(c===u)return;c&&!rt(c,u)&&(y=qt(c),Re(c,v,E,!0),c=null),u.patchFlag===-2&&(S=!1,u.dynamicChildren=null);const{type:_,ref:P,shapeFlag:k}=u;switch(_){case St:$(c,u,h,y);break;case _e:U(c,u,h,y);break;case Nt:c==null&&X(u,h,y,j);break;case he:R(c,u,h,y,v,E,j,w,S);break;default:k&1?C(c,u,h,y,v,E,j,w,S):k&6?W(c,u,h,y,v,E,j,w,S):(k&64||k&128)&&_.process(c,u,h,y,v,E,j,w,S,mt)}P!=null&&v&&gn(P,c&&c.ref,E,u||c,!u)},$=(c,u,h,y)=>{if(c==null)i(u.el=l(u.children),h,y);else{const v=u.el=c.el;u.children!==c.children&&f(v,u.children)}},U=(c,u,h,y)=>{c==null?i(u.el=a(u.children||""),h,y):u.el=c.el},X=(c,u,h,y)=>{[c.el,c.anchor]=L(c.children,u,h,y,c.el,c.anchor)},m=({el:c,anchor:u},h,y)=>{let v;for(;c&&c!==u;)v=g(c),i(c,h,y),c=v;i(u,h,y)},x=({el:c,anchor:u})=>{let h;for(;c&&c!==u;)h=g(c),s(c),c=h;s(u)},C=(c,u,h,y,v,E,j,w,S)=>{u.type==="svg"?j="svg":u.type==="math"&&(j="mathml"),c==null?D(u,h,y,v,E,j,w,S):A(c,u,v,E,j,w,S)},D=(c,u,h,y,v,E,j,w)=>{let S,_;const{props:P,shapeFlag:k,transition:I,dirs:B}=c;if(S=c.el=r(c.type,E,P&&P.is,P),k&8?p(S,c.children):k&16&&O(c.children,S,null,y,v,Bn(c,E),j,w),B&&Le(c,null,y,"created"),V(S,c,c.scopeId,j,y),P){for(const Q in P)Q!=="value"&&!Pt(Q)&&o(S,Q,null,P[Q],E,c.children,y,v,Ne);"value"in P&&o(S,"value",null,P.value,E),(_=P.onVnodeBeforeMount)&&we(_,y,c)}B&&Le(c,null,y,"beforeMount");const z=To(v,I);z&&I.beforeEnter(S),i(S,u,h),((_=P&&P.onVnodeMounted)||z||B)&&me(()=>{_&&we(_,y,c),z&&I.enter(S),B&&Le(c,null,y,"mounted")},v)},V=(c,u,h,y,v)=>{if(h&&b(c,h),y)for(let E=0;E{for(let _=S;_{const w=u.el=c.el;let{patchFlag:S,dynamicChildren:_,dirs:P}=u;S|=c.patchFlag&16;const k=c.props||te,I=u.props||te;let B;if(h&&nt(h,!1),(B=I.onVnodeBeforeUpdate)&&we(B,h,u,c),P&&Le(u,c,h,"beforeUpdate"),h&&nt(h,!0),_?T(c.dynamicChildren,_,w,h,y,Bn(u,v),E):j||N(c,u,w,null,h,y,Bn(u,v),E,!1),S>0){if(S&16)q(w,u,k,I,h,y,v);else if(S&2&&k.class!==I.class&&o(w,"class",null,I.class,v),S&4&&o(w,"style",k.style,I.style,v),S&8){const z=u.dynamicProps;for(let Q=0;Q{B&&we(B,h,u,c),P&&Le(u,c,h,"updated")},y)},T=(c,u,h,y,v,E,j)=>{for(let w=0;w{if(h!==y){if(h!==te)for(const w in h)!Pt(w)&&!(w in y)&&o(c,w,h[w],null,j,u.children,v,E,Ne);for(const w in y){if(Pt(w))continue;const S=y[w],_=h[w];S!==_&&w!=="value"&&o(c,w,_,S,j,u.children,v,E,Ne)}"value"in y&&o(c,"value",h.value,y.value,j)}},R=(c,u,h,y,v,E,j,w,S)=>{const _=u.el=c?c.el:l(""),P=u.anchor=c?c.anchor:l("");let{patchFlag:k,dynamicChildren:I,slotScopeIds:B}=u;B&&(w=w?w.concat(B):B),c==null?(i(_,h,y),i(P,h,y),O(u.children,h,P,v,E,j,w,S)):k>0&&k&64&&I&&c.dynamicChildren?(T(c.dynamicChildren,I,h,v,E,j,w),(u.key!=null||v&&u===v.subTree)&&Ao(c,u,!0)):N(c,u,h,P,v,E,j,w,S)},W=(c,u,h,y,v,E,j,w,S)=>{u.slotScopeIds=w,c==null?u.shapeFlag&512?v.ctx.activate(u,h,y,j,S):se(u,h,y,v,E,j,S):ae(c,u,S)},se=(c,u,h,y,v,E,j)=>{const w=c.component=Xl(c,y,v);if(Rn(c)&&(w.ctx.renderer=mt),Ql(w),w.asyncDep){if(v&&v.registerDep(w,F),!c.el){const S=w.subTree=ce(_e);U(null,S,u,h)}}else F(w,c,u,h,v,E,j)},ae=(c,u,h)=>{const y=u.component=c.component;if(sl(c,u,h))if(y.asyncDep&&!y.asyncResolved){G(y,u,h);return}else y.next=u,Xr(y.update),y.effect.dirty=!0,y.update();else u.el=c.el,y.vnode=u},F=(c,u,h,y,v,E,j)=>{const w=()=>{if(c.isMounted){let{next:P,bu:k,u:I,parent:B,vnode:z}=c;{const ht=jo(c);if(ht){P&&(P.el=z.el,G(c,P,j)),ht.asyncDep.then(()=>{c.isUnmounted||w()});return}}let Q=P,ee;nt(c,!1),P?(P.el=z.el,G(c,P,j)):P=z,k&&kn(k),(ee=P.props&&P.props.onVnodeBeforeUpdate)&&we(ee,B,P,z),nt(c,!0);const re=Hn(c),Te=c.subTree;c.subTree=re,M(Te,re,d(Te.el),qt(Te),c,v,E),P.el=re.el,Q===null&&ol(c,re.el),I&&me(I,v),(ee=P.props&&P.props.onVnodeUpdated)&&me(()=>we(ee,B,P,z),v)}else{let P;const{el:k,props:I}=u,{bm:B,m:z,parent:Q}=c,ee=wt(u);if(nt(c,!1),B&&kn(B),!ee&&(P=I&&I.onVnodeBeforeMount)&&we(P,Q,u),nt(c,!0),k&&Fn){const re=()=>{c.subTree=Hn(c),Fn(k,c.subTree,c,v,null)};ee?u.type.__asyncLoader().then(()=>!c.isUnmounted&&re()):re()}else{const re=c.subTree=Hn(c);M(null,re,h,y,c,v,E),u.el=re.el}if(z&&me(z,v),!ee&&(P=I&&I.onVnodeMounted)){const re=u;me(()=>we(P,Q,re),v)}(u.shapeFlag&256||Q&&wt(Q.vnode)&&Q.vnode.shapeFlag&256)&&c.a&&me(c.a,v),c.isMounted=!0,u=h=y=null}},S=c.effect=new xi(w,Ee,()=>Ti(_),c.scope),_=c.update=()=>{S.dirty&&S.run()};_.id=c.uid,nt(c,!0),_()},G=(c,u,h)=>{u.component=c;const y=c.vnode.props;c.vnode=u,c.next=null,Il(c,u.props,y,h),kl(c,u.children,h),pt(),zi(c),dt()},N=(c,u,h,y,v,E,j,w,S=!1)=>{const _=c&&c.children,P=c?c.shapeFlag:0,k=u.children,{patchFlag:I,shapeFlag:B}=u;if(I>0){if(I&128){Kt(_,k,h,y,v,E,j,w,S);return}else if(I&256){Ie(_,k,h,y,v,E,j,w,S);return}}B&8?(P&16&&Ne(_,v,E),k!==_&&p(h,k)):P&16?B&16?Kt(_,k,h,y,v,E,j,w,S):Ne(_,v,E,!0):(P&8&&p(h,""),B&16&&O(k,h,y,v,E,j,w,S))},Ie=(c,u,h,y,v,E,j,w,S)=>{c=c||yt,u=u||yt;const _=c.length,P=u.length,k=Math.min(_,P);let I;for(I=0;IP?Ne(c,v,E,!0,!1,k):O(u,h,y,v,E,j,w,S,k)},Kt=(c,u,h,y,v,E,j,w,S)=>{let _=0;const P=u.length;let k=c.length-1,I=P-1;for(;_<=k&&_<=I;){const B=c[_],z=u[_]=S?qe(u[_]):Ae(u[_]);if(rt(B,z))M(B,z,h,null,v,E,j,w,S);else break;_++}for(;_<=k&&_<=I;){const B=c[k],z=u[I]=S?qe(u[I]):Ae(u[I]);if(rt(B,z))M(B,z,h,null,v,E,j,w,S);else break;k--,I--}if(_>k){if(_<=I){const B=I+1,z=BI)for(;_<=k;)Re(c[_],v,E,!0),_++;else{const B=_,z=_,Q=new Map;for(_=z;_<=I;_++){const ye=u[_]=S?qe(u[_]):Ae(u[_]);ye.key!=null&&Q.set(ye.key,_)}let ee,re=0;const Te=I-z+1;let ht=!1,Fi=0;const Rt=new Array(Te);for(_=0;_=Te){Re(ye,v,E,!0);continue}let Oe;if(ye.key!=null)Oe=Q.get(ye.key);else for(ee=z;ee<=I;ee++)if(Rt[ee-z]===0&&rt(ye,u[ee])){Oe=ee;break}Oe===void 0?Re(ye,v,E,!0):(Rt[Oe-z]=_+1,Oe>=Fi?Fi=Oe:ht=!0,M(ye,u[Oe],h,null,v,E,j,w,S),re++)}const ki=ht?Ul(Rt):yt;for(ee=ki.length-1,_=Te-1;_>=0;_--){const ye=z+_,Oe=u[ye],$i=ye+1{const{el:E,type:j,transition:w,children:S,shapeFlag:_}=c;if(_&6){tt(c.component.subTree,u,h,y);return}if(_&128){c.suspense.move(u,h,y);return}if(_&64){j.move(c,u,h,mt);return}if(j===he){i(E,u,h);for(let k=0;kw.enter(E),v);else{const{leave:k,delayLeave:I,afterLeave:B}=w,z=()=>i(E,u,h),Q=()=>{k(E,()=>{z(),B&&B()})};I?I(E,z,Q):Q()}else i(E,u,h)},Re=(c,u,h,y=!1,v=!1)=>{const{type:E,props:j,ref:w,children:S,dynamicChildren:_,shapeFlag:P,patchFlag:k,dirs:I}=c;if(w!=null&&gn(w,null,h,c,!0),P&256){u.ctx.deactivate(c);return}const B=P&1&&I,z=!wt(c);let Q;if(z&&(Q=j&&j.onVnodeBeforeUnmount)&&we(Q,u,c),P&6)nr(c.component,h,y);else{if(P&128){c.suspense.unmount(h,y);return}B&&Le(c,null,u,"beforeUnmount"),P&64?c.type.remove(c,u,h,v,mt,y):_&&(E!==he||k>0&&k&64)?Ne(_,u,h,!1,!0):(E===he&&k&384||!v&&P&16)&&Ne(S,u,h),y&&Ii(c)}(z&&(Q=j&&j.onVnodeUnmounted)||B)&&me(()=>{Q&&we(Q,u,c),B&&Le(c,null,u,"unmounted")},h)},Ii=c=>{const{type:u,el:h,anchor:y,transition:v}=c;if(u===he){tr(h,y);return}if(u===Nt){x(c);return}const E=()=>{s(h),v&&!v.persisted&&v.afterLeave&&v.afterLeave()};if(c.shapeFlag&1&&v&&!v.persisted){const{leave:j,delayLeave:w}=v,S=()=>j(h,E);w?w(c.el,E,S):S()}else E()},tr=(c,u)=>{let h;for(;c!==u;)h=g(c),s(c),c=h;s(u)},nr=(c,u,h)=>{const{bum:y,scope:v,update:E,subTree:j,um:w}=c;y&&kn(y),v.stop(),E&&(E.active=!1,Re(j,c,u,h)),w&&me(w,u),me(()=>{c.isUnmounted=!0},u),u&&u.pendingBranch&&!u.isUnmounted&&c.asyncDep&&!c.asyncResolved&&c.suspenseId===u.pendingId&&(u.deps--,u.deps===0&&u.resolve())},Ne=(c,u,h,y=!1,v=!1,E=0)=>{for(let j=E;jc.shapeFlag&6?qt(c.component.subTree):c.shapeFlag&128?c.suspense.next():g(c.anchor||c.el),Ni=(c,u,h)=>{c==null?u._vnode&&Re(u._vnode,null,null,!0):M(u._vnode||null,c,u,null,null,null,h),zi(),pn(),u._vnode=c},mt={p:M,um:Re,m:tt,r:Ii,mt:se,mc:O,pc:N,pbc:T,n:qt,o:e};let Nn,Fn;return t&&([Nn,Fn]=t(mt)),{render:Ni,hydrate:Nn,createApp:Ll(Ni,Nn)}}function Bn({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function nt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function To(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Ao(e,t,n=!1){const i=e.children,s=t.children;if(H(i)&&H(s))for(let o=0;o>1,e[n[l]]0&&(t[i]=n[o-1]),n[o]=i)}}for(o=n.length,r=n[o-1];o-- >0;)n[o]=r,r=t[r];return n}function jo(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:jo(t)}const Kl=e=>e.__isTeleport,he=Symbol.for("v-fgt"),St=Symbol.for("v-txt"),_e=Symbol.for("v-cmt"),Nt=Symbol.for("v-stc"),Ft=[];let je=null;function Ro(e=!1){Ft.push(je=e?null:[])}function ql(){Ft.pop(),je=Ft[Ft.length-1]||null}let Dt=1;function os(e){Dt+=e}function Oo(e){return e.dynamicChildren=Dt>0?je||yt:null,ql(),Dt>0&&je&&je.push(e),e}function Hc(e,t,n,i,s,o){return Oo(Mo(e,t,n,i,s,o,!0))}function Lo(e,t,n,i,s){return Oo(ce(e,t,n,i,s,!0))}function xn(e){return e?e.__v_isVNode===!0:!1}function rt(e,t){return e.type===t.type&&e.key===t.key}const Pn="__vInternal",Po=({key:e})=>e??null,ln=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ne(e)||pe(e)||K(e)?{i:ue,r:e,k:t,f:!!n}:e:null);function Mo(e,t=null,n=null,i=0,s=null,o=e===he?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Po(t),ref:t&&ln(t),scopeId:An,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:i,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:ue};return l?(Oi(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=ne(n)?8:16),Dt>0&&!r&&je&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&je.push(a),a}const ce=Wl;function Wl(e,t=null,n=null,i=0,s=null,o=!1){if((!e||e===ro)&&(e=_e),xn(e)){const l=et(e,t,!0);return n&&Oi(l,n),Dt>0&&!o&&je&&(l.shapeFlag&6?je[je.indexOf(e)]=l:je.push(l)),l.patchFlag|=-2,l}if(na(e)&&(e=e.__vccOpts),t){t=zl(t);let{class:l,style:a}=t;l&&!ne(l)&&(t.class=gi(l)),Z(a)&&(Js(a)&&!H(a)&&(a=oe({},a)),t.style=hi(a))}const r=ne(e)?1:rl(e)?128:Kl(e)?64:Z(e)?4:K(e)?2:0;return Mo(e,t,n,i,s,r,o,!0)}function zl(e){return e?Js(e)||Pn in e?oe({},e):e:null}function et(e,t,n=!1){const{props:i,ref:s,patchFlag:o,children:r}=e,l=t?Gl(i||{},t):i;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Po(l),ref:t&&t.ref?n&&s?H(s)?s.concat(ln(t)):[s,ln(t)]:ln(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:r,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==he?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&et(e.ssContent),ssFallback:e.ssFallback&&et(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Io(e=" ",t=0){return ce(St,null,e,t)}function Vc(e,t){const n=ce(Nt,null,e);return n.staticCount=t,n}function Dc(e="",t=!1){return t?(Ro(),Lo(_e,null,e)):ce(_e,null,e)}function Ae(e){return e==null||typeof e=="boolean"?ce(_e):H(e)?ce(he,null,e.slice()):typeof e=="object"?qe(e):ce(St,null,String(e))}function qe(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:et(e)}function Oi(e,t){let n=0;const{shapeFlag:i}=e;if(t==null)t=null;else if(H(t))n=16;else if(typeof t=="object")if(i&65){const s=t.default;s&&(s._c&&(s._d=!1),Oi(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!(Pn in t)?t._ctx=ue:s===3&&ue&&(ue.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else K(t)?(t={default:t,_ctx:ue},n=32):(t=String(t),i&64?(n=16,t=[Io(t)]):n=8);e.children=t,e.shapeFlag|=n}function Gl(...e){const t={};for(let n=0;nle||ue;let Li,ri;{const e=Ns(),t=(n,i)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(i),o=>{s.length>1?s.forEach(r=>r(o)):s[0](o)}};Li=t("__VUE_INSTANCE_SETTERS__",n=>le=n),ri=t("__VUE_SSR_SETTERS__",n=>In=n)}const Tt=e=>{Li(e),e.scope.on()},ct=()=>{le&&le.scope.off(),Li(null)};function No(e){return e.vnode.shapeFlag&4}let In=!1;function Ql(e,t=!1){t&&ri(t);const{props:n,children:i}=e.vnode,s=No(e);Ml(e,n,s,t),Fl(e,i);const o=s?Zl(e,t):void 0;return t&&ri(!1),o}function Zl(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Mt(new Proxy(e.ctx,Cl));const{setup:i}=n;if(i){const s=e.setupContext=i.length>1?ko(e):null;Tt(e),pt();const o=Ye(i,e,0,[e.props,s]);if(dt(),ct(),Ps(o)){if(o.then(ct,ct),t)return o.then(r=>{rs(e,r,t)}).catch(r=>{En(r,e,0)});e.asyncDep=o}else rs(e,o,t)}else Fo(e,t)}function rs(e,t,n){K(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Z(t)&&(e.setupState=to(t)),Fo(e,n)}let ls;function Fo(e,t,n){const i=e.type;if(!e.render){if(!t&&ls&&!i.render){const s=i.template||ji(e).template;if(s){const{isCustomElement:o,compilerOptions:r}=e.appContext.config,{delimiters:l,compilerOptions:a}=i,f=oe(oe({isCustomElement:o,delimiters:l},r),a);i.render=ls(s,f)}}e.render=i.render||Ee}{Tt(e),pt();try{Sl(e)}finally{dt(),ct()}}}function ea(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return xe(e,"get","$attrs"),t[n]}}))}function ko(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return ea(e)},slots:e.slots,emit:e.emit,expose:t}}function Pi(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(to(Mt(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in It)return It[n](e)},has(t,n){return n in t||n in It}}))}function ta(e,t=!0){return K(e)?e.displayName||e.name:e.name||t&&e.__name}function na(e){return K(e)&&"__vccOpts"in e}const ie=(e,t)=>Vr(e,t,In);function li(e,t,n){const i=arguments.length;return i===2?Z(t)&&!H(t)?xn(t)?ce(e,null,[t]):ce(e,t):ce(e,null,t):(i>3?n=Array.prototype.slice.call(arguments,2):i===3&&xn(n)&&(n=[n]),ce(e,t,n))}const ia="3.4.3",sa="http://www.w3.org/2000/svg",oa="http://www.w3.org/1998/Math/MathML",We=typeof document<"u"?document:null,as=We&&We.createElement("template"),ra={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,i)=>{const s=t==="svg"?We.createElementNS(sa,e):t==="mathml"?We.createElementNS(oa,e):We.createElement(e,n?{is:n}:void 0);return e==="select"&&i&&i.multiple!=null&&s.setAttribute("multiple",i.multiple),s},createText:e=>We.createTextNode(e),createComment:e=>We.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>We.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,i,s,o){const r=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{as.innerHTML=i==="svg"?`${e}`:i==="mathml"?`${e}`:e;const l=as.content;if(i==="svg"||i==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[r?r.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Be="transition",Ot="animation",Bt=Symbol("_vtc"),$o=(e,{slots:t})=>li(pl,la(e),t);$o.displayName="Transition";const Ho={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};$o.props=oe({},uo,Ho);const it=(e,t=[])=>{H(e)?e.forEach(n=>n(...t)):e&&e(...t)},cs=e=>e?H(e)?e.some(t=>t.length>1):e.length>1:!1;function la(e){const t={};for(const R in e)R in Ho||(t[R]=e[R]);if(e.css===!1)return t;const{name:n="v",type:i,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:r=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:f=r,appearToClass:p=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:b=`${n}-leave-to`}=e,L=aa(s),M=L&&L[0],$=L&&L[1],{onBeforeEnter:U,onEnter:X,onEnterCancelled:m,onLeave:x,onLeaveCancelled:C,onBeforeAppear:D=U,onAppear:V=X,onAppearCancelled:O=m}=t,A=(R,W,se)=>{st(R,W?p:l),st(R,W?f:r),se&&se()},T=(R,W)=>{R._isLeaving=!1,st(R,d),st(R,b),st(R,g),W&&W()},q=R=>(W,se)=>{const ae=R?V:X,F=()=>A(W,R,se);it(ae,[W,F]),fs(()=>{st(W,R?a:o),Ue(W,R?p:l),cs(ae)||us(W,i,M,F)})};return oe(t,{onBeforeEnter(R){it(U,[R]),Ue(R,o),Ue(R,r)},onBeforeAppear(R){it(D,[R]),Ue(R,a),Ue(R,f)},onEnter:q(!1),onAppear:q(!0),onLeave(R,W){R._isLeaving=!0;const se=()=>T(R,W);Ue(R,d),ua(),Ue(R,g),fs(()=>{R._isLeaving&&(st(R,d),Ue(R,b),cs(x)||us(R,i,$,se))}),it(x,[R,se])},onEnterCancelled(R){A(R,!1),it(m,[R])},onAppearCancelled(R){A(R,!0),it(O,[R])},onLeaveCancelled(R){T(R),it(C,[R])}})}function aa(e){if(e==null)return null;if(Z(e))return[Un(e.enter),Un(e.leave)];{const t=Un(e);return[t,t]}}function Un(e){return cr(e)}function Ue(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Bt]||(e[Bt]=new Set)).add(t)}function st(e,t){t.split(/\s+/).forEach(i=>i&&e.classList.remove(i));const n=e[Bt];n&&(n.delete(t),n.size||(e[Bt]=void 0))}function fs(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let ca=0;function us(e,t,n,i){const s=e._endId=++ca,o=()=>{s===e._endId&&i()};if(n)return setTimeout(o,n);const{type:r,timeout:l,propCount:a}=fa(e,t);if(!r)return i();const f=r+"end";let p=0;const d=()=>{e.removeEventListener(f,g),o()},g=b=>{b.target===e&&++p>=a&&d()};setTimeout(()=>{p(n[L]||"").split(", "),s=i(`${Be}Delay`),o=i(`${Be}Duration`),r=ps(s,o),l=i(`${Ot}Delay`),a=i(`${Ot}Duration`),f=ps(l,a);let p=null,d=0,g=0;t===Be?r>0&&(p=Be,d=r,g=o.length):t===Ot?f>0&&(p=Ot,d=f,g=a.length):(d=Math.max(r,f),p=d>0?r>f?Be:Ot:null,g=p?p===Be?o.length:a.length:0);const b=p===Be&&/\b(transform|all)(,|$)/.test(i(`${Be}Property`).toString());return{type:p,timeout:d,propCount:g,hasTransform:b}}function ps(e,t){for(;e.lengthds(n)+ds(e[i])))}function ds(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function ua(){return document.body.offsetHeight}function pa(e,t,n){const i=e[Bt];i&&(t=(t?[t,...i]:[...i]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const da=Symbol("_vod"),ma=Symbol("");function ha(e,t,n){const i=e.style,s=ne(n);if(n&&!s){if(t&&!ne(t))for(const o in t)n[o]==null&&ai(i,o,"");for(const o in n)ai(i,o,n[o])}else{const o=i.display;if(s){if(t!==n){const r=i[ma];r&&(n+=";"+r),i.cssText=n}}else t&&e.removeAttribute("style");da in e&&(i.display=o)}}const ms=/\s*!important$/;function ai(e,t,n){if(H(n))n.forEach(i=>ai(e,t,i));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const i=ga(e,t);ms.test(n)?e.setProperty(ut(i),n.replace(ms,""),"important"):e[i]=n}}const hs=["Webkit","Moz","ms"],Kn={};function ga(e,t){const n=Kn[t];if(n)return n;let i=Me(t);if(i!=="filter"&&i in e)return Kn[t]=i;i=_n(i);for(let s=0;sqn||(Ca.then(()=>qn=0),qn=Date.now());function Sa(e,t){const n=i=>{if(!i._vts)i._vts=Date.now();else if(i._vts<=n.attached)return;Se(Ta(i,n.value),t,5,[i])};return n.value=e,n.attached=Ea(),n}function Ta(e,t){if(H(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(i=>s=>!s._stopped&&i&&i(s))}else return t}const vs=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Aa=(e,t,n,i,s,o,r,l,a)=>{const f=s==="svg";t==="class"?pa(e,i,f):t==="style"?ha(e,n,i):Ut(t)?pi(t)||ba(e,t,n,i,r):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ja(e,t,i,f))?ya(e,t,i,o,r,l,a):(t==="true-value"?e._trueValue=i:t==="false-value"&&(e._falseValue=i),xa(e,t,i,f))};function ja(e,t,n,i){if(i)return!!(t==="innerHTML"||t==="textContent"||t in e&&vs(t)&&K(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return vs(t)&&ne(n)?!1:t in e}const Ra=["ctrl","shift","alt","meta"],Oa={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)=>Ra.some(n=>e[`${n}Key`]&&!t.includes(n))},Bc=(e,t)=>{const n=e._withMods||(e._withMods={}),i=t.join(".");return n[i]||(n[i]=(s,...o)=>{for(let r=0;r{const n=e._withKeys||(e._withKeys={}),i=t.join(".");return n[i]||(n[i]=s=>{if(!("key"in s))return;const o=ut(s.key);if(t.some(r=>r===o||La[r]===o))return e(s)})},Pa=oe({patchProp:Aa},ra);let Wn,_s=!1;function Ma(){return Wn=_s?Wn:Dl(Pa),_s=!0,Wn}const Kc=(...e)=>{const t=Ma().createApp(...e),{mount:n}=t;return t.mount=i=>{const s=Na(i);if(s)return n(s,!0,Ia(s))},t};function Ia(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Na(e){return ne(e)?document.querySelector(e):e}const qc=(e,t)=>{const n=e.__vccOpts||e;for(const[i,s]of t)n[i]=s;return n},Fa="modulepreload",ka=function(e){return"/ts-oauth2-server/"+e},bs={},Wc=function(t,n,i){let s=Promise.resolve();if(n&&n.length>0){const o=document.getElementsByTagName("link");s=Promise.all(n.map(r=>{if(r=ka(r),r in bs)return;bs[r]=!0;const l=r.endsWith(".css"),a=l?'[rel="stylesheet"]':"";if(!!i)for(let d=o.length-1;d>=0;d--){const g=o[d];if(g.href===r&&(!l||g.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${r}"]${a}`))return;const p=document.createElement("link");if(p.rel=l?"stylesheet":Fa,l||(p.as="script",p.crossOrigin=""),p.href=r,document.head.appendChild(p),l)return new Promise((d,g)=>{p.addEventListener("load",d),p.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${r}`)))})}))}return s.then(()=>t()).catch(o=>{const r=new Event("vite:preloadError",{cancelable:!0});if(r.payload=o,window.dispatchEvent(r),!r.defaultPrevented)throw o})},$a=window.__VP_SITE_DATA__;function Mi(e){return $s()?(yr(e),!0):!1}function Xe(e){return typeof e=="function"?e():eo(e)}const Vo=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Ha=Object.prototype.toString,Va=e=>Ha.call(e)==="[object Object]",kt=()=>{},ci=Da();function Da(){var e,t;return Vo&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Ba(e,t){function n(...i){return new Promise((s,o)=>{Promise.resolve(e(()=>t.apply(this,i),{fn:t,thisArg:this,args:i})).then(s).catch(o)})}return n}const Do=e=>e();function Ua(e=Do){const t=ge(!0);function n(){t.value=!1}function i(){t.value=!0}const s=(...o)=>{t.value&&e(...o)};return{isActive:Cn(t),pause:n,resume:i,eventFilter:s}}function Ka(e){return e||Mn()}function Bo(...e){if(e.length!==1)return zr(...e);const t=e[0];return typeof t=="function"?Cn(Kr(()=>({get:t,set:kt}))):ge(t)}function qa(e,t,n={}){const{eventFilter:i=Do,...s}=n;return Je(e,Ba(i,t),s)}function Wa(e,t,n={}){const{eventFilter:i,...s}=n,{eventFilter:o,pause:r,resume:l,isActive:a}=Ua(i);return{stop:qa(e,t,{...s,eventFilter:o}),pause:r,resume:l,isActive:a}}function Uo(e,t=!0,n){Ka()?jt(e,n):t?e():Sn(e)}function xt(e){var t;const n=Xe(e);return(t=n==null?void 0:n.$el)!=null?t:n}const $e=Vo?window:void 0;function Qe(...e){let t,n,i,s;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,i,s]=e,t=$e):[t,n,i,s]=e,!t)return kt;Array.isArray(n)||(n=[n]),Array.isArray(i)||(i=[i]);const o=[],r=()=>{o.forEach(p=>p()),o.length=0},l=(p,d,g,b)=>(p.addEventListener(d,g,b),()=>p.removeEventListener(d,g,b)),a=Je(()=>[xt(t),Xe(s)],([p,d])=>{if(r(),!p)return;const g=Va(d)?{...d}:d;o.push(...n.flatMap(b=>i.map(L=>l(p,b,L,g))))},{immediate:!0,flush:"post"}),f=()=>{a(),r()};return Mi(f),f}let ws=!1;function zc(e,t,n={}){const{window:i=$e,ignore:s=[],capture:o=!0,detectIframe:r=!1}=n;if(!i)return kt;ci&&!ws&&(ws=!0,Array.from(i.document.body.children).forEach(g=>g.addEventListener("click",kt)),i.document.documentElement.addEventListener("click",kt));let l=!0;const a=g=>s.some(b=>{if(typeof b=="string")return Array.from(i.document.querySelectorAll(b)).some(L=>L===g.target||g.composedPath().includes(L));{const L=xt(b);return L&&(g.target===L||g.composedPath().includes(L))}}),p=[Qe(i,"click",g=>{const b=xt(e);if(!(!b||b===g.target||g.composedPath().includes(b))){if(g.detail===0&&(l=!a(g)),!l){l=!0;return}t(g)}},{passive:!0,capture:o}),Qe(i,"pointerdown",g=>{const b=xt(e);l=!a(g)&&!!(b&&!g.composedPath().includes(b))},{passive:!0}),r&&Qe(i,"blur",g=>{setTimeout(()=>{var b;const L=xt(e);((b=i.document.activeElement)==null?void 0:b.tagName)==="IFRAME"&&!(L!=null&&L.contains(i.document.activeElement))&&t(g)},0)})].filter(Boolean);return()=>p.forEach(g=>g())}function za(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function Gc(...e){let t,n,i={};e.length===3?(t=e[0],n=e[1],i=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],i=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:s=$e,eventName:o="keydown",passive:r=!1,dedupe:l=!1}=i,a=za(t);return Qe(s,o,p=>{p.repeat&&Xe(l)||a(p)&&n(p)},r)}function Ga(){const e=ge(!1);return Mn()&&jt(()=>{e.value=!0}),e}function Ya(e){const t=Ga();return ie(()=>(t.value,!!e()))}function Ja(e,t={}){const{window:n=$e}=t,i=Ya(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let s;const o=ge(!1),r=f=>{o.value=f.matches},l=()=>{s&&("removeEventListener"in s?s.removeEventListener("change",r):s.removeListener(r))},a=co(()=>{i.value&&(l(),s=n.matchMedia(Xe(e)),"addEventListener"in s?s.addEventListener("change",r):s.addListener(r),o.value=s.matches)});return Mi(()=>{a(),l(),s=void 0}),o}const tn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},nn="__vueuse_ssr_handlers__",Xa=Qa();function Qa(){return nn in tn||(tn[nn]=tn[nn]||{}),tn[nn]}function Ko(e,t){return Xa[e]||t}function Za(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const ec={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},Cs="vueuse-storage";function tc(e,t,n,i={}){var s;const{flush:o="pre",deep:r=!0,listenToStorageChanges:l=!0,writeDefaults:a=!0,mergeDefaults:f=!1,shallow:p,window:d=$e,eventFilter:g,onError:b=A=>{console.error(A)},initOnMounted:L}=i,M=(p?Qs:ge)(typeof t=="function"?t():t);if(!n)try{n=Ko("getDefaultStorage",()=>{var A;return(A=$e)==null?void 0:A.localStorage})()}catch(A){b(A)}if(!n)return M;const $=Xe(t),U=Za($),X=(s=i.serializer)!=null?s:ec[U],{pause:m,resume:x}=Wa(M,()=>C(M.value),{flush:o,deep:r,eventFilter:g});return d&&l&&Uo(()=>{Qe(d,"storage",O),Qe(d,Cs,V),L&&O()}),L||O(),M;function C(A){try{if(A==null)n.removeItem(e);else{const T=X.write(A),q=n.getItem(e);q!==T&&(n.setItem(e,T),d&&d.dispatchEvent(new CustomEvent(Cs,{detail:{key:e,oldValue:q,newValue:T,storageArea:n}})))}}catch(T){b(T)}}function D(A){const T=A?A.newValue:n.getItem(e);if(T==null)return a&&$!=null&&n.setItem(e,X.write($)),$;if(!A&&f){const q=X.read(T);return typeof f=="function"?f(q,$):U==="object"&&!Array.isArray(q)?{...$,...q}:q}else return typeof T!="string"?T:X.read(T)}function V(A){O(A.detail)}function O(A){if(!(A&&A.storageArea!==n)){if(A&&A.key==null){M.value=$;return}if(!(A&&A.key!==e)){m();try{(A==null?void 0:A.newValue)!==X.write(M.value)&&(M.value=D(A))}catch(T){b(T)}finally{A?Sn(x):x()}}}}}function qo(e){return Ja("(prefers-color-scheme: dark)",e)}function nc(e={}){const{selector:t="html",attribute:n="class",initialValue:i="auto",window:s=$e,storage:o,storageKey:r="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:a,emitAuto:f,disableTransition:p=!0}=e,d={auto:"",light:"light",dark:"dark",...e.modes||{}},g=qo({window:s}),b=ie(()=>g.value?"dark":"light"),L=a||(r==null?Bo(i):tc(r,i,o,{window:s,listenToStorageChanges:l})),M=ie(()=>L.value==="auto"?b.value:L.value),$=Ko("updateHTMLAttrs",(x,C,D)=>{const V=typeof x=="string"?s==null?void 0:s.document.querySelector(x):xt(x);if(!V)return;let O;if(p&&(O=s.document.createElement("style"),O.appendChild(document.createTextNode("*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),s.document.head.appendChild(O)),C==="class"){const A=D.split(/\s/g);Object.values(d).flatMap(T=>(T||"").split(/\s/g)).filter(Boolean).forEach(T=>{A.includes(T)?V.classList.add(T):V.classList.remove(T)})}else V.setAttribute(C,D);p&&(s.getComputedStyle(O).opacity,document.head.removeChild(O))});function U(x){var C;$(t,n,(C=d[x])!=null?C:x)}function X(x){e.onChanged?e.onChanged(x,U):U(x)}Je(M,X,{flush:"post",immediate:!0}),Uo(()=>X(M.value));const m=ie({get(){return f?L.value:M.value},set(x){L.value=x}});try{return Object.assign(m,{store:L,system:b,state:M})}catch{return m}}function ic(e={}){const{valueDark:t="dark",valueLight:n="",window:i=$e}=e,s=nc({...e,onChanged:(l,a)=>{var f;e.onChanged?(f=e.onChanged)==null||f.call(e,l==="dark",a,l):a(l)},modes:{dark:t,light:n}}),o=ie(()=>s.system?s.system.value:qo({window:i}).value?"dark":"light");return ie({get(){return s.value==="dark"},set(l){const a=l?"dark":"light";o.value===a?s.value="auto":s.value=a}})}function zn(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function Wo(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const sn=new WeakMap;function Yc(e,t=!1){const n=ge(t);let i=null,s;Je(Bo(e),l=>{const a=zn(Xe(l));if(a){const f=a;sn.get(f)||sn.set(f,s),n.value&&(f.style.overflow="hidden")}},{immediate:!0});const o=()=>{const l=zn(Xe(e));!l||n.value||(ci&&(i=Qe(l,"touchmove",a=>{sc(a)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},r=()=>{var l;const a=zn(Xe(e));!a||!n.value||(ci&&(i==null||i()),a.style.overflow=(l=sn.get(a))!=null?l:"",sn.delete(a),n.value=!1)};return Mi(r),ie({get(){return n.value},set(l){l?o():r()}})}function Jc(e={}){const{window:t=$e,behavior:n="auto"}=e;if(!t)return{x:ge(0),y:ge(0)};const i=ge(t.scrollX),s=ge(t.scrollY),o=ie({get(){return i.value},set(l){scrollTo({left:l,behavior:n})}}),r=ie({get(){return s.value},set(l){scrollTo({top:l,behavior:n})}});return Qe(t,"scroll",()=>{i.value=t.scrollX,s.value=t.scrollY},{capture:!1,passive:!0}),{x:o,y:r}}const zo=/^(?:[a-z]+:|\/\/)/i,oc="vitepress-theme-appearance",Go=/#.*$/,rc=/(index)?\.(md|html)$/,Ce=typeof document<"u",Yo={relativePath:"",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function lc(e,t,n=!1){if(t===void 0)return!1;if(e=Es(`/${e}`),n)return new RegExp(t).test(e);if(Es(t)!==e)return!1;const i=t.match(Go);return i?(Ce?location.hash:"")===i[0]:!0}function Es(e){return decodeURI(e).replace(Go,"").replace(rc,"")}function ac(e){return zo.test(e)}function cc(e,t){var i,s,o,r,l,a,f;const n=Object.keys(e.locales).find(p=>p!=="root"&&!ac(p)&&lc(t,`/${p}/`,!0))||"root";return Object.assign({},e,{localeIndex:n,lang:((i=e.locales[n])==null?void 0:i.lang)??e.lang,dir:((s=e.locales[n])==null?void 0:s.dir)??e.dir,title:((o=e.locales[n])==null?void 0:o.title)??e.title,titleTemplate:((r=e.locales[n])==null?void 0:r.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:Xo(e.head,((a=e.locales[n])==null?void 0:a.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function Jo(e,t){const n=t.title||e.title,i=t.titleTemplate??e.titleTemplate;if(typeof i=="string"&&i.includes(":title"))return i.replace(/:title/g,n);const s=fc(e.title,i);return n===s.slice(3)?n:`${n}${s}`}function fc(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function uc(e,t){const[n,i]=t;if(n!=="meta")return!1;const s=Object.entries(i)[0];return s==null?!1:e.some(([o,r])=>o===n&&r[s[0]]===s[1])}function Xo(e,t){return[...e.filter(n=>!uc(t,n)),...t]}const pc=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,dc=/^[a-z]:/i;function Ss(e){const t=dc.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(pc,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const mc=Symbol(),ft=Qs($a);function Xc(e){const t=ie(()=>cc(ft.value,e.data.relativePath)),n=t.value.appearance,i=n==="force-dark"?ge(!0):n?ic({storageKey:oc,initialValue:()=>typeof n=="string"?n:"auto",...typeof n=="object"?n:{}}):ge(!1);return{site:t,theme:ie(()=>t.value.themeConfig),page:ie(()=>e.data),frontmatter:ie(()=>e.data.frontmatter),params:ie(()=>e.data.params),lang:ie(()=>t.value.lang),dir:ie(()=>e.data.frontmatter.dir||t.value.dir||"ltr"),localeIndex:ie(()=>t.value.localeIndex||"root"),title:ie(()=>Jo(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:i}}function hc(){const e=Ct(mc);if(!e)throw new Error("vitepress data not properly injected in app");return e}const gc={"3g2":"video/3gpp2","3gp":"video/3gpp","3gpp":"video/3gpp","3mf":"model/3mf",aac:"audio/aac",ac:"application/pkix-attr-cert",adp:"audio/adpcm",adts:"audio/aac",ai:"application/postscript",aml:"application/automationml-aml+xml",amlx:"application/automationml-amlx+zip",amr:"audio/amr",apng:"image/apng",appcache:"text/cache-manifest",appinstaller:"application/appinstaller",appx:"application/appx",appxbundle:"application/appxbundle",asc:"application/pgp-keys",atom:"application/atom+xml",atomcat:"application/atomcat+xml",atomdeleted:"application/atomdeleted+xml",atomsvc:"application/atomsvc+xml",au:"audio/basic",avci:"image/avci",avcs:"image/avcs",avif:"image/avif",aw:"application/applixware",bdoc:"application/bdoc",bin:"application/octet-stream",bmp:"image/bmp",bpk:"application/octet-stream",btf:"image/prs.btif",btif:"image/prs.btif",buffer:"application/octet-stream",ccxml:"application/ccxml+xml",cdfx:"application/cdfx+xml",cdmia:"application/cdmi-capability",cdmic:"application/cdmi-container",cdmid:"application/cdmi-domain",cdmio:"application/cdmi-object",cdmiq:"application/cdmi-queue",cer:"application/pkix-cert",cgm:"image/cgm",cjs:"application/node",class:"application/java-vm",coffee:"text/coffeescript",conf:"text/plain",cpl:"application/cpl+xml",cpt:"application/mac-compactpro",crl:"application/pkix-crl",css:"text/css",csv:"text/csv",cu:"application/cu-seeme",cwl:"application/cwl",cww:"application/prs.cww",davmount:"application/davmount+xml",dbk:"application/docbook+xml",deb:"application/octet-stream",def:"text/plain",deploy:"application/octet-stream",dib:"image/bmp","disposition-notification":"message/disposition-notification",dist:"application/octet-stream",distz:"application/octet-stream",dll:"application/octet-stream",dmg:"application/octet-stream",dms:"application/octet-stream",doc:"application/msword",dot:"application/msword",dpx:"image/dpx",drle:"image/dicom-rle",dsc:"text/prs.lines.tag",dssc:"application/dssc+der",dtd:"application/xml-dtd",dump:"application/octet-stream",dwd:"application/atsc-dwd+xml",ear:"application/java-archive",ecma:"application/ecmascript",elc:"application/octet-stream",emf:"image/emf",eml:"message/rfc822",emma:"application/emma+xml",emotionml:"application/emotionml+xml",eps:"application/postscript",epub:"application/epub+zip",exe:"application/octet-stream",exi:"application/exi",exp:"application/express",exr:"image/aces",ez:"application/andrew-inset",fdf:"application/fdf",fdt:"application/fdt+xml",fits:"image/fits",g3:"image/g3fax",gbr:"application/rpki-ghostbusters",geojson:"application/geo+json",gif:"image/gif",glb:"model/gltf-binary",gltf:"model/gltf+json",gml:"application/gml+xml",gpx:"application/gpx+xml",gram:"application/srgs",grxml:"application/srgs+xml",gxf:"application/gxf",gz:"application/gzip",h261:"video/h261",h263:"video/h263",h264:"video/h264",heic:"image/heic",heics:"image/heic-sequence",heif:"image/heif",heifs:"image/heif-sequence",hej2:"image/hej2k",held:"application/atsc-held+xml",hjson:"application/hjson",hlp:"application/winhlp",hqx:"application/mac-binhex40",hsj2:"image/hsj2",htm:"text/html",html:"text/html",ics:"text/calendar",ief:"image/ief",ifb:"text/calendar",iges:"model/iges",igs:"model/iges",img:"application/octet-stream",in:"text/plain",ini:"text/plain",ink:"application/inkml+xml",inkml:"application/inkml+xml",ipfix:"application/ipfix",iso:"application/octet-stream",its:"application/its+xml",jade:"text/jade",jar:"application/java-archive",jhc:"image/jphc",jls:"image/jls",jp2:"image/jp2",jpe:"image/jpeg",jpeg:"image/jpeg",jpf:"image/jpx",jpg:"image/jpeg",jpg2:"image/jp2",jpgm:"image/jpm",jpgv:"video/jpeg",jph:"image/jph",jpm:"image/jpm",jpx:"image/jpx",js:"text/javascript",json:"application/json",json5:"application/json5",jsonld:"application/ld+json",jsonml:"application/jsonml+json",jsx:"text/jsx",jt:"model/jt",jxr:"image/jxr",jxra:"image/jxra",jxrs:"image/jxrs",jxs:"image/jxs",jxsc:"image/jxsc",jxsi:"image/jxsi",jxss:"image/jxss",kar:"audio/midi",ktx:"image/ktx",ktx2:"image/ktx2",less:"text/less",lgr:"application/lgr+xml",list:"text/plain",litcoffee:"text/coffeescript",log:"text/plain",lostxml:"application/lost+xml",lrf:"application/octet-stream",m1v:"video/mpeg",m21:"application/mp21",m2a:"audio/mpeg",m2v:"video/mpeg",m3a:"audio/mpeg",m4a:"audio/mp4",m4p:"application/mp4",m4s:"video/iso.segment",ma:"application/mathematica",mads:"application/mads+xml",maei:"application/mmt-aei+xml",man:"text/troff",manifest:"text/cache-manifest",map:"application/json",mar:"application/octet-stream",markdown:"text/markdown",mathml:"application/mathml+xml",mb:"application/mathematica",mbox:"application/mbox",md:"text/markdown",mdx:"text/mdx",me:"text/troff",mesh:"model/mesh",meta4:"application/metalink4+xml",metalink:"application/metalink+xml",mets:"application/mets+xml",mft:"application/rpki-manifest",mid:"audio/midi",midi:"audio/midi",mime:"message/rfc822",mj2:"video/mj2",mjp2:"video/mj2",mjs:"text/javascript",mml:"text/mathml",mods:"application/mods+xml",mov:"video/quicktime",mp2:"audio/mpeg",mp21:"application/mp21",mp2a:"audio/mpeg",mp3:"audio/mpeg",mp4:"video/mp4",mp4a:"audio/mp4",mp4s:"application/mp4",mp4v:"video/mp4",mpd:"application/dash+xml",mpe:"video/mpeg",mpeg:"video/mpeg",mpf:"application/media-policy-dataset+xml",mpg:"video/mpeg",mpg4:"video/mp4",mpga:"audio/mpeg",mpp:"application/dash-patch+xml",mrc:"application/marc",mrcx:"application/marcxml+xml",ms:"text/troff",mscml:"application/mediaservercontrol+xml",msh:"model/mesh",msi:"application/octet-stream",msix:"application/msix",msixbundle:"application/msixbundle",msm:"application/octet-stream",msp:"application/octet-stream",mtl:"model/mtl",musd:"application/mmt-usd+xml",mxf:"application/mxf",mxmf:"audio/mobile-xmf",mxml:"application/xv+xml",n3:"text/n3",nb:"application/mathematica",nq:"application/n-quads",nt:"application/n-triples",obj:"model/obj",oda:"application/oda",oga:"audio/ogg",ogg:"audio/ogg",ogv:"video/ogg",ogx:"application/ogg",omdoc:"application/omdoc+xml",onepkg:"application/onenote",onetmp:"application/onenote",onetoc:"application/onenote",onetoc2:"application/onenote",opf:"application/oebps-package+xml",opus:"audio/ogg",otf:"font/otf",owl:"application/rdf+xml",oxps:"application/oxps",p10:"application/pkcs10",p7c:"application/pkcs7-mime",p7m:"application/pkcs7-mime",p7s:"application/pkcs7-signature",p8:"application/pkcs8",pdf:"application/pdf",pfr:"application/font-tdpfr",pgp:"application/pgp-encrypted",pkg:"application/octet-stream",pki:"application/pkixcmp",pkipath:"application/pkix-pkipath",pls:"application/pls+xml",png:"image/png",prc:"model/prc",prf:"application/pics-rules",provx:"application/provenance+xml",ps:"application/postscript",pskcxml:"application/pskc+xml",pti:"image/prs.pti",qt:"video/quicktime",raml:"application/raml+yaml",rapd:"application/route-apd+xml",rdf:"application/rdf+xml",relo:"application/p2p-overlay+xml",rif:"application/reginfo+xml",rl:"application/resource-lists+xml",rld:"application/resource-lists-diff+xml",rmi:"audio/midi",rnc:"application/relax-ng-compact-syntax",rng:"application/xml",roa:"application/rpki-roa",roff:"text/troff",rq:"application/sparql-query",rs:"application/rls-services+xml",rsat:"application/atsc-rsat+xml",rsd:"application/rsd+xml",rsheet:"application/urc-ressheet+xml",rss:"application/rss+xml",rtf:"text/rtf",rtx:"text/richtext",rusd:"application/route-usd+xml",s3m:"audio/s3m",sbml:"application/sbml+xml",scq:"application/scvp-cv-request",scs:"application/scvp-cv-response",sdp:"application/sdp",senmlx:"application/senml+xml",sensmlx:"application/sensml+xml",ser:"application/java-serialized-object",setpay:"application/set-payment-initiation",setreg:"application/set-registration-initiation",sgi:"image/sgi",sgm:"text/sgml",sgml:"text/sgml",shex:"text/shex",shf:"application/shf+xml",shtml:"text/html",sieve:"application/sieve",sig:"application/pgp-signature",sil:"audio/silk",silo:"model/mesh",siv:"application/sieve",slim:"text/slim",slm:"text/slim",sls:"application/route-s-tsid+xml",smi:"application/smil+xml",smil:"application/smil+xml",snd:"audio/basic",so:"application/octet-stream",spdx:"text/spdx",spp:"application/scvp-vp-response",spq:"application/scvp-vp-request",spx:"audio/ogg",sql:"application/sql",sru:"application/sru+xml",srx:"application/sparql-results+xml",ssdl:"application/ssdl+xml",ssml:"application/ssml+xml",stk:"application/hyperstudio",stl:"model/stl",stpx:"model/step+xml",stpxz:"model/step-xml+zip",stpz:"model/step+zip",styl:"text/stylus",stylus:"text/stylus",svg:"image/svg+xml",svgz:"image/svg+xml",swidtag:"application/swid+xml",t:"text/troff",t38:"image/t38",td:"application/urc-targetdesc+xml",tei:"application/tei+xml",teicorpus:"application/tei+xml",text:"text/plain",tfi:"application/thraud+xml",tfx:"image/tiff-fx",tif:"image/tiff",tiff:"image/tiff",toml:"application/toml",tr:"text/troff",trig:"application/trig",ts:"video/mp2t",tsd:"application/timestamped-data",tsv:"text/tab-separated-values",ttc:"font/collection",ttf:"font/ttf",ttl:"text/turtle",ttml:"application/ttml+xml",txt:"text/plain",u3d:"model/u3d",u8dsn:"message/global-delivery-status",u8hdr:"message/global-headers",u8mdn:"message/global-disposition-notification",u8msg:"message/global",ubj:"application/ubjson",uri:"text/uri-list",uris:"text/uri-list",urls:"text/uri-list",vcard:"text/vcard",vrml:"model/vrml",vtt:"text/vtt",vxml:"application/voicexml+xml",war:"application/java-archive",wasm:"application/wasm",wav:"audio/wav",weba:"audio/webm",webm:"video/webm",webmanifest:"application/manifest+json",webp:"image/webp",wgsl:"text/wgsl",wgt:"application/widget",wif:"application/watcherinfo+xml",wmf:"image/wmf",woff:"font/woff",woff2:"font/woff2",wrl:"model/vrml",wsdl:"application/wsdl+xml",wspolicy:"application/wspolicy+xml",x3d:"model/x3d+xml",x3db:"model/x3d+fastinfoset",x3dbz:"model/x3d+binary",x3dv:"model/x3d-vrml",x3dvz:"model/x3d+vrml",x3dz:"model/x3d+xml",xaml:"application/xaml+xml",xav:"application/xcap-att+xml",xca:"application/xcap-caps+xml",xcs:"application/calendar+xml",xdf:"application/xcap-diff+xml",xdssc:"application/dssc+xml",xel:"application/xcap-el+xml",xenc:"application/xenc+xml",xer:"application/patch-ops-error+xml",xfdf:"application/xfdf",xht:"application/xhtml+xml",xhtml:"application/xhtml+xml",xhvml:"application/xv+xml",xlf:"application/xliff+xml",xm:"audio/xm",xml:"text/xml",xns:"application/xcap-ns+xml",xop:"application/xop+xml",xpl:"application/xproc+xml",xsd:"application/xml",xsf:"application/prs.xsf+xml",xsl:"application/xml",xslt:"application/xml",xspf:"application/xspf+xml",xvm:"application/xv+xml",xvml:"application/xv+xml",yaml:"text/yaml",yang:"application/yang",yin:"application/yin+xml",yml:"text/yaml",zip:"application/zip"};function xc(e){let t=(""+e).trim().toLowerCase(),n=t.lastIndexOf(".");return gc[~n?t.substring(++n):t]}function yc(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function Ts(e){return zo.test(e)||!e.startsWith("/")?e:yc(ft.value.base,e)}function vc(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),Ce){const n="/ts-oauth2-server/";t=Ss(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let i=__VP_HASH_MAP__[t.toLowerCase()];if(i||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",i=__VP_HASH_MAP__[t.toLowerCase()]),!i)return null;t=`${n}assets/${t}.${i}.js`}else t=`./${Ss(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let an=[];function Qc(e){an.push(e),Ln(()=>{an=an.filter(t=>t!==e)})}const _c=Symbol(),Qo="http://a.com",bc=()=>({path:"/",component:null,data:Yo});function Zc(e,t){const n=wn(bc()),i={route:n,go:s};async function s(l=Ce?location.href:"/"){var a,f;l=fi(l),await((a=i.onBeforeRouteChange)==null?void 0:a.call(i,l))!==!1&&(Rs(l),await r(l),await((f=i.onAfterRouteChanged)==null?void 0:f.call(i,l)))}let o=null;async function r(l,a=0,f=!1){var g;if(await((g=i.onBeforePageLoad)==null?void 0:g.call(i,l))===!1)return;const p=new URL(l,Qo),d=o=p.pathname;try{let b=await e(d);if(!b)throw new Error(`Page not found: ${d}`);if(o===d){o=null;const{default:L,__pageData:M}=b;if(!L)throw new Error(`Invalid route component: ${L}`);n.path=Ce?d:Ts(d),n.component=Mt(L),n.data=Mt(M),Ce&&Sn(()=>{let $=ft.value.base+M.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!ft.value.cleanUrls&&!$.endsWith("/")&&($+=".html"),$!==p.pathname&&(p.pathname=$,l=$+p.search+p.hash,history.replaceState(null,"",l)),p.hash&&!a){let U=null;try{U=document.getElementById(decodeURIComponent(p.hash).slice(1))}catch(X){console.warn(X)}if(U){As(U,p.hash);return}}window.scrollTo(0,a)})}}catch(b){if(!/fetch|Page not found/.test(b.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(b),!f)try{const L=await fetch(ft.value.base+"hashmap.json");window.__VP_HASH_MAP__=await L.json(),await r(l,a,!0);return}catch{}o===d&&(o=null,n.path=Ce?d:Ts(d),n.component=t?Mt(t):null,n.data=Yo)}}return Ce&&(window.addEventListener("click",l=>{if(l.target.closest("button"))return;const f=l.target.closest("a");if(f&&!f.closest(".vp-raw")&&(f instanceof SVGElement||!f.download)){const{target:p}=f,{href:d,origin:g,pathname:b,hash:L,search:M}=new URL(f.href instanceof SVGAnimatedString?f.href.animVal:f.href,f.baseURI),$=window.location,U=xc(b);!l.ctrlKey&&!l.shiftKey&&!l.altKey&&!l.metaKey&&!p&&g===$.origin&&(!U||U==="text/html")&&(l.preventDefault(),b===$.pathname&&M===$.search?(L!==$.hash&&(history.pushState(null,"",L),window.dispatchEvent(new Event("hashchange"))),L?As(f,L,f.classList.contains("header-anchor")):(Rs(d),window.scrollTo(0,0))):s(d))}},{capture:!0}),window.addEventListener("popstate",async l=>{var a;await r(fi(location.href),l.state&&l.state.scrollPosition||0),(a=i.onAfterRouteChanged)==null||a.call(i,location.href)}),window.addEventListener("hashchange",l=>{l.preventDefault()})),i}function wc(){const e=Ct(_c);if(!e)throw new Error("useRouter() is called without provider.");return e}function Zo(){return wc().route}function As(e,t,n=!1){let i=null;try{i=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(s){console.warn(s)}if(i){let s=function(){!n||Math.abs(f-window.scrollY)>window.innerHeight?window.scrollTo(0,f):window.scrollTo({left:0,top:f,behavior:"smooth"})},o=ft.value.scrollOffset,r=0,l=24;if(typeof o=="object"&&"padding"in o&&(l=o.padding,o=o.selector),typeof o=="number")r=o;else if(typeof o=="string")r=js(o,l);else if(Array.isArray(o))for(const p of o){const d=js(p,l);if(d){r=d;break}}const a=parseInt(window.getComputedStyle(i).paddingTop,10),f=window.scrollY+i.getBoundingClientRect().top-r+a;requestAnimationFrame(s)}}function js(e,t){const n=document.querySelector(e);if(!n)return 0;const i=n.getBoundingClientRect().bottom;return i<0?0:i+t}function Rs(e){Ce&&e!==fi(location.href)&&(history.replaceState({scrollPosition:window.scrollY},document.title),history.pushState(null,"",e))}function fi(e){const t=new URL(e,Qo);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),ft.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const Gn=()=>an.forEach(e=>e()),ef=ho({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Zo(),{site:n}=hc();return()=>li(e.as,n.value.contentProps??{style:{position:"relative"}},[t.component?li(t.component,{onVnodeMounted:Gn,onVnodeUpdated:Gn,onVnodeUnmounted:Gn}):"404 Page Not Found"])}}),tf=ho({setup(e,{slots:t}){const n=ge(!1);return jt(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function nf(){Ce&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const i=(n=t.parentElement)==null?void 0:n.parentElement;if(!i)return;const s=Array.from(i.querySelectorAll("input")).indexOf(t);if(s<0)return;const o=i.querySelector(".blocks");if(!o)return;const r=Array.from(o.children).find(f=>f.classList.contains("active"));if(!r)return;const l=o.children[s];if(!l||r===l)return;r.classList.remove("active"),l.classList.add("active");const a=i==null?void 0:i.querySelector(`label[for="${t.id}"]`);a==null||a.scrollIntoView({block:"nearest"})}})}function sf(){if(Ce){const e=new WeakMap;window.addEventListener("click",t=>{var i;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const s=n.parentElement,o=(i=n.nextElementSibling)==null?void 0:i.nextElementSibling;if(!s||!o)return;const r=/language-(shellscript|shell|bash|sh|zsh)/.test(s.className),l=[".vp-copy-ignore",".diff.remove"],a=o.cloneNode(!0);a.querySelectorAll(l.join(",")).forEach(p=>p.remove());let f=a.textContent||"";r&&(f=f.replace(/^ *(\$|>) /gm,"").trim()),Cc(f).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const p=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,p)})}})}}async function Cc(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const i=document.getSelection(),s=i?i.rangeCount>0&&i.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),s&&(i.removeAllRanges(),i.addRange(s)),n&&n.focus()}}function of(e,t){let n=[],i=!0;const s=o=>{if(i){i=!1;return}const r=o.map(Os);n.forEach((l,a)=>{const f=r.findIndex(p=>p==null?void 0:p.isEqualNode(l??null));f!==-1?delete r[f]:(l==null||l.remove(),delete n[a])}),r.forEach(l=>l&&document.head.appendChild(l)),n=[...n,...r].filter(Boolean)};co(()=>{const o=e.data,r=t.value,l=o&&o.description,a=o&&o.frontmatter.head||[],f=Jo(r,o);f!==document.title&&(document.title=f);const p=l||r.description;let d=document.querySelector("meta[name=description]");d?d.getAttribute("content")!==p&&d.setAttribute("content",p):Os(["meta",{name:"description",content:p}]),s(Xo(r.head,Sc(a)))})}function Os([e,t,n]){const i=document.createElement(e);for(const s in t)i.setAttribute(s,t[s]);return n&&(i.innerHTML=n),e==="script"&&!t.async&&(i.async=!1),i}function Ec(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function Sc(e){return e.filter(t=>!Ec(t))}const Yn=new Set,er=()=>document.createElement("link"),Tc=e=>{const t=er();t.rel="prefetch",t.href=e,document.head.appendChild(t)},Ac=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let on;const jc=Ce&&(on=er())&&on.relList&&on.relList.supports&&on.relList.supports("prefetch")?Tc:Ac;function rf(){if(!Ce||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const i=()=>{n&&n.disconnect(),n=new IntersectionObserver(o=>{o.forEach(r=>{if(r.isIntersecting){const l=r.target;n.unobserve(l);const{pathname:a}=l;if(!Yn.has(a)){Yn.add(a);const f=vc(a);f&&jc(f)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(o=>{const{hostname:r,pathname:l}=new URL(o.href instanceof SVGAnimatedString?o.href.animVal:o.href,o.baseURI),a=l.match(/\.\w+$/);a&&a[0]!==".html"||o.target!=="_blank"&&r===location.hostname&&(l!==location.pathname?n.observe(o):Yn.add(l))})})};jt(i);const s=Zo();Je(()=>s.path,i),Ln(()=>{n&&n.disconnect()})}export{Bc as $,Ln as A,Ic as B,yl as C,Pc as D,Nc as E,he as F,Qs as G,Qc as H,ce as I,Mc as J,zo as K,Zo as L,Gl as M,Ct as N,zc as O,Gc as P,hi as Q,Sn as R,Jc as S,$o as T,Vc as U,Cn as V,Yc as W,Pl as X,Uc as Y,kc as Z,qc as _,Io as a,$c as a0,of as a1,_c as a2,Xc as a3,mc as a4,ef as a5,tf as a6,ft as a7,Kc as a8,Zc as a9,vc as aa,Wc as ab,rf as ac,sf as ad,nf as ae,li as af,Lo as b,Hc as c,ho as d,Dc as e,Ts as f,ie as g,ge as h,ac as i,jt as j,Mo as k,xc as l,eo as m,gi as n,Ro as o,Oc as p,Lc as q,Fc as r,lc as s,Rc as t,hc as u,Ce as v,tl as w,Ja as x,Je as y,co as z}; diff --git a/assets/chunks/theme.B3UUe-eO.js b/assets/chunks/theme.B3UUe-eO.js new file mode 100644 index 00000000..39b9f1a9 --- /dev/null +++ b/assets/chunks/theme.B3UUe-eO.js @@ -0,0 +1 @@ +import{d as g,o as a,c as l,r as d,n as C,a as H,t as V,b as $,w as h,T as ue,e as f,_ as m,u as De,i as Oe,l as xe,f as de,g as b,h as S,j as U,k as c,m as r,p as E,q as F,s as G,v as W,x as ie,y as j,z as X,A as ve,B as be,C as Ge,D as q,F as M,E as B,G as ye,H as ee,I as _,J as x,K as Pe,L as te,M as J,N as se,O as Ue,P as je,Q as qe,R as Ke,S as we,U as Re,V as We,W as Ve,X as Le,Y as Ye,Z as Je,$ as Ze,a0 as Qe}from"./framework.XQuvpNW4.js";const Xe=g({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(a(),l("span",{class:C(["VPBadge",e.type])},[d(e.$slots,"default",{},()=>[H(V(e.text),1)])],2))}}),et={key:0,class:"VPBackdrop"},tt=g({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(a(),$(ue,{name:"fade"},{default:h(()=>[e.show?(a(),l("div",et)):f("",!0)]),_:1}))}}),st=m(tt,[["__scopeId","data-v-fda50202"]]),P=De;function nt(s,e){let t,n=!1;return()=>{t&&clearTimeout(t),n?t=setTimeout(s,e):(s(),(n=!0)&&setTimeout(()=>n=!1,e))}}function le(s){return/^\//.test(s)?s:`/${s}`}function he(s){const{pathname:e,search:t,hash:n,protocol:o}=new URL(s,"http://a.com");if(Oe(s)||s.startsWith("#")||!o.startsWith("http")||/\.(?!html|md)\w+($|\?)/i.test(s)&&xe(s))return s;const{site:i}=P(),u=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,i.value.cleanUrls?"":".html")}${t}${n}`);return de(u)}function Y({removeCurrent:s=!0,correspondingLink:e=!1}={}){const{site:t,localeIndex:n,page:o,theme:i}=P(),u=b(()=>{var v,k;return{label:(v=t.value.locales[n.value])==null?void 0:v.label,link:((k=t.value.locales[n.value])==null?void 0:k.link)||(n.value==="root"?"/":`/${n.value}/`)}});return{localeLinks:b(()=>Object.entries(t.value.locales).flatMap(([v,k])=>s&&u.value.label===k.label?[]:{text:k.label,link:ot(k.link||(v==="root"?"/":`/${v}/`),i.value.i18nRouting!==!1&&e,o.value.relativePath.slice(u.value.link.length-1),!t.value.cleanUrls)})),currentLang:u}}function ot(s,e,t,n){return e?s.replace(/\/$/,"")+le(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,n?".html":"")):s}const at=s=>(E("data-v-b3b1a313"),s=s(),F(),s),rt={class:"NotFound"},it={class:"code"},lt={class:"title"},ct=at(()=>c("div",{class:"divider"},null,-1)),ut={class:"quote"},dt={class:"action"},vt=["href","aria-label"],ht=g({__name:"NotFound",setup(s){const{site:e,theme:t}=P(),{localeLinks:n}=Y({removeCurrent:!1}),o=S("/");return U(()=>{var u;const i=window.location.pathname.replace(e.value.base,"").replace(/(^.*?\/).*$/,"/$1");n.value.length&&(o.value=((u=n.value.find(({link:p})=>p.startsWith(i)))==null?void 0:u.link)||n.value[0].link)}),(i,u)=>{var p,v,k,y,w;return a(),l("div",rt,[c("p",it,V(((p=r(t).notFound)==null?void 0:p.code)??"404"),1),c("h1",lt,V(((v=r(t).notFound)==null?void 0:v.title)??"PAGE NOT FOUND"),1),ct,c("blockquote",ut,V(((k=r(t).notFound)==null?void 0:k.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),c("div",dt,[c("a",{class:"link",href:r(de)(o.value),"aria-label":((y=r(t).notFound)==null?void 0:y.linkLabel)??"go to home"},V(((w=r(t).notFound)==null?void 0:w.linkText)??"Take me home"),9,vt)])])}}}),pt=m(ht,[["__scopeId","data-v-b3b1a313"]]);function Se(s,e){if(Array.isArray(s))return Z(s);if(s==null)return[];e=le(e);const t=Object.keys(s).sort((o,i)=>i.split("/").length-o.split("/").length).find(o=>e.startsWith(le(o))),n=t?s[t]:[];return Array.isArray(n)?Z(n):Z(n.items,n.base)}function _t(s){const e=[];let t=0;for(const n in s){const o=s[n];if(o.items){t=e.push(o);continue}e[t]||e.push({items:[]}),e[t].items.push(o)}return e}function ft(s){const e=[];function t(n){for(const o of n)o.text&&o.link&&e.push({text:o.text,link:o.link,docFooterText:o.docFooterText}),o.items&&t(o.items)}return t(s),e}function ce(s,e){return Array.isArray(e)?e.some(t=>ce(s,t)):G(s,e.link)?!0:e.items?ce(s,e.items):!1}function Z(s,e){return[...s].map(t=>{const n={...t},o=n.base||e;return o&&n.link&&(n.link=o+n.link),n.items&&(n.items=Z(n.items,o)),n})}function D(){const{frontmatter:s,page:e,theme:t}=P(),n=ie("(min-width: 960px)"),o=S(!1),i=b(()=>{const N=t.value.sidebar,L=e.value.relativePath;return N?Se(N,L):[]}),u=S(i.value);j(i,(N,L)=>{JSON.stringify(N)!==JSON.stringify(L)&&(u.value=i.value)});const p=b(()=>s.value.sidebar!==!1&&u.value.length>0&&s.value.layout!=="home"),v=b(()=>k?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),k=b(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),y=b(()=>p.value&&n.value),w=b(()=>p.value?_t(u.value):[]);function T(){o.value=!0}function I(){o.value=!1}function A(){o.value?I():T()}return{isOpen:o,sidebar:u,sidebarGroups:w,hasSidebar:p,hasAside:k,leftAside:v,isSidebarEnabled:y,open:T,close:I,toggle:A}}function mt(s,e){let t;X(()=>{t=s.value?document.activeElement:void 0}),U(()=>{window.addEventListener("keyup",n)}),ve(()=>{window.removeEventListener("keyup",n)});function n(o){o.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}const Me=S(W?location.hash:"");W&&window.addEventListener("hashchange",()=>{Me.value=location.hash});function gt(s){const{page:e}=P(),t=S(!1),n=b(()=>s.value.collapsed!=null),o=b(()=>!!s.value.link),i=S(!1),u=()=>{i.value=G(e.value.relativePath,s.value.link)};j([e,s,Me],u),U(u);const p=b(()=>i.value?!0:s.value.items?ce(e.value.relativePath,s.value.items):!1),v=b(()=>!!(s.value.items&&s.value.items.length));X(()=>{t.value=!!(n.value&&s.value.collapsed)}),be(()=>{(i.value||p.value)&&(t.value=!1)});function k(){n.value&&(t.value=!t.value)}return{collapsed:t,collapsible:n,isLink:o,isActiveLink:i,hasActiveLink:p,hasChildren:v,toggle:k}}function $t(){const{hasSidebar:s}=D(),e=ie("(min-width: 960px)"),t=ie("(min-width: 1280px)");return{isAsideEnabled:b(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const kt=71;function Ie(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function pe(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const n=Number(t.tagName[1]);return{title:bt(t),link:"#"+t.id,level:n}});return yt(e,s)}function bt(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function yt(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[n,o]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;s=s.filter(u=>u.level>=n&&u.level<=o);const i=[];e:for(let u=0;u=0;v--){const k=s[v];if(k.level{requestAnimationFrame(i),window.addEventListener("scroll",n)}),Ge(()=>{u(location.hash)}),ve(()=>{window.removeEventListener("scroll",n)});function i(){if(!t.value)return;const p=[].slice.call(s.value.querySelectorAll(".outline-link")),v=[].slice.call(document.querySelectorAll(".content .header-anchor")).filter(I=>p.some(A=>A.hash===I.hash&&I.offsetParent!==null)),k=window.scrollY,y=window.innerHeight,w=document.body.offsetHeight,T=Math.abs(k+y-w)<1;if(v.length&&T){u(v[v.length-1].hash);return}for(let I=0;I{const o=q("VPDocOutlineItem",!0);return a(),l("ul",{class:C(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),l(M,null,B(t.headers,({children:i,link:u,title:p})=>(a(),l("li",null,[c("a",{class:"outline-link",href:u,onClick:e,title:p},V(p),9,Vt),i!=null&&i.length?(a(),$(o,{key:0,headers:i},null,8,["headers"])):f("",!0)]))),256))],2)}}}),Te=m(Lt,[["__scopeId","data-v-e7812efa"]]),St=s=>(E("data-v-742b9ac6"),s=s(),F(),s),Mt={class:"content"},It={class:"outline-title",role:"heading","aria-level":"2"},Tt={"aria-labelledby":"doc-outline-aria-label"},Ct=St(()=>c("span",{class:"visually-hidden",id:"doc-outline-aria-label"}," Table of Contents for current page ",-1)),Nt=g({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=P(),n=ye([]);ee(()=>{n.value=pe(e.value.outline??t.value.outline)});const o=S(),i=S();return Pt(o,i),(u,p)=>(a(),l("div",{class:C(["VPDocAsideOutline",{"has-outline":n.value.length>0}]),ref_key:"container",ref:o,role:"navigation"},[c("div",Mt,[c("div",{class:"outline-marker",ref_key:"marker",ref:i},null,512),c("div",It,V(r(Ie)(r(t))),1),c("nav",Tt,[Ct,_(Te,{headers:n.value,root:!0},null,8,["headers"])])])],2))}}),At=m(Nt,[["__scopeId","data-v-742b9ac6"]]),Bt={class:"VPDocAsideCarbonAds"},Ht=g({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,n)=>(a(),l("div",Bt,[_(r(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),zt=s=>(E("data-v-1f4bf028"),s=s(),F(),s),Et={class:"VPDocAside"},Ft=zt(()=>c("div",{class:"spacer"},null,-1)),Dt=g({__name:"VPDocAside",setup(s){const{theme:e}=P();return(t,n)=>(a(),l("div",Et,[d(t.$slots,"aside-top",{},void 0,!0),d(t.$slots,"aside-outline-before",{},void 0,!0),_(At),d(t.$slots,"aside-outline-after",{},void 0,!0),Ft,d(t.$slots,"aside-ads-before",{},void 0,!0),r(e).carbonAds?(a(),$(Ht,{key:0,"carbon-ads":r(e).carbonAds},null,8,["carbon-ads"])):f("",!0),d(t.$slots,"aside-ads-after",{},void 0,!0),d(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Ot=m(Dt,[["__scopeId","data-v-1f4bf028"]]);function xt(){const{theme:s,page:e}=P();return b(()=>{const{text:t="Edit this page",pattern:n=""}=s.value.editLink||{};let o;return typeof n=="function"?o=n(e.value):o=n.replace(/:path/g,e.value.filePath),{url:o,text:t}})}function Gt(){const{page:s,theme:e,frontmatter:t}=P();return b(()=>{var v,k,y,w,T,I,A,N;const n=Se(e.value.sidebar,s.value.relativePath),o=ft(n),i=o.findIndex(L=>G(s.value.relativePath,L.link)),u=((v=e.value.docFooter)==null?void 0:v.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((k=e.value.docFooter)==null?void 0:k.next)===!1&&!t.value.next||t.value.next===!1;return{prev:u?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((y=o[i-1])==null?void 0:y.docFooterText)??((w=o[i-1])==null?void 0:w.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((T=o[i-1])==null?void 0:T.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((I=o[i+1])==null?void 0:I.docFooterText)??((A=o[i+1])==null?void 0:A.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((N=o[i+1])==null?void 0:N.link)}}})}const Ut={},jt={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},qt=c("path",{d:"M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"},null,-1),Kt=c("path",{d:"M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"},null,-1),Rt=[qt,Kt];function Wt(s,e){return a(),l("svg",jt,Rt)}const Yt=m(Ut,[["render",Wt]]),z=g({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=b(()=>e.tag??(e.href?"a":"span")),n=b(()=>e.href&&Pe.test(e.href));return(o,i)=>(a(),$(x(t.value),{class:C(["VPLink",{link:o.href,"vp-external-link-icon":n.value,"no-icon":o.noIcon}]),href:o.href?r(he)(o.href):void 0,target:o.target??(n.value?"_blank":void 0),rel:o.rel??(n.value?"noreferrer":void 0)},{default:h(()=>[d(o.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),Jt={class:"VPLastUpdated"},Zt=["datetime"],Qt=g({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,frontmatter:n,lang:o}=P(),i=b(()=>new Date(n.value.lastUpdated??t.value.lastUpdated)),u=b(()=>i.value.toISOString()),p=S("");return U(()=>{X(()=>{var v,k,y;p.value=new Intl.DateTimeFormat((k=(v=e.value.lastUpdated)==null?void 0:v.formatOptions)!=null&&k.forceLocale?o.value:void 0,((y=e.value.lastUpdated)==null?void 0:y.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(i.value)})}),(v,k)=>{var y;return a(),l("p",Jt,[H(V(((y=r(e).lastUpdated)==null?void 0:y.text)||r(e).lastUpdatedText||"Last updated")+": ",1),c("time",{datetime:u.value},V(p.value),9,Zt)])}}}),Xt=m(Qt,[["__scopeId","data-v-4dc7cc60"]]),es={key:0,class:"VPDocFooter"},ts={key:0,class:"edit-info"},ss={key:0,class:"edit-link"},ns={key:1,class:"last-updated"},os={key:1,class:"prev-next"},as={class:"pager"},rs=["innerHTML"],is=["innerHTML"],ls={class:"pager"},cs=["innerHTML"],us=["innerHTML"],ds=g({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:n}=P(),o=xt(),i=Gt(),u=b(()=>e.value.editLink&&n.value.editLink!==!1),p=b(()=>t.value.lastUpdated&&n.value.lastUpdated!==!1),v=b(()=>u.value||p.value||i.value.prev||i.value.next);return(k,y)=>{var w,T,I,A;return v.value?(a(),l("footer",es,[d(k.$slots,"doc-footer-before",{},void 0,!0),u.value||p.value?(a(),l("div",ts,[u.value?(a(),l("div",ss,[_(z,{class:"edit-link-button",href:r(o).url,"no-icon":!0},{default:h(()=>[_(Yt,{class:"edit-link-icon","aria-label":"edit icon"}),H(" "+V(r(o).text),1)]),_:1},8,["href"])])):f("",!0),p.value?(a(),l("div",ns,[_(Xt)])):f("",!0)])):f("",!0),(w=r(i).prev)!=null&&w.link||(T=r(i).next)!=null&&T.link?(a(),l("nav",os,[c("div",as,[(I=r(i).prev)!=null&&I.link?(a(),$(z,{key:0,class:"pager-link prev",href:r(i).prev.link},{default:h(()=>{var N;return[c("span",{class:"desc",innerHTML:((N=r(e).docFooter)==null?void 0:N.prev)||"Previous page"},null,8,rs),c("span",{class:"title",innerHTML:r(i).prev.text},null,8,is)]}),_:1},8,["href"])):f("",!0)]),c("div",ls,[(A=r(i).next)!=null&&A.link?(a(),$(z,{key:0,class:"pager-link next",href:r(i).next.link},{default:h(()=>{var N;return[c("span",{class:"desc",innerHTML:((N=r(e).docFooter)==null?void 0:N.next)||"Next page"},null,8,cs),c("span",{class:"title",innerHTML:r(i).next.text},null,8,us)]}),_:1},8,["href"])):f("",!0)])])):f("",!0)])):f("",!0)}}}),vs=m(ds,[["__scopeId","data-v-bb4d37df"]]),hs=s=>(E("data-v-31dd4b0a"),s=s(),F(),s),ps={class:"container"},_s=hs(()=>c("div",{class:"aside-curtain"},null,-1)),fs={class:"aside-container"},ms={class:"aside-content"},gs={class:"content"},$s={class:"content-container"},ks={class:"main"},bs=g({__name:"VPDoc",setup(s){const{theme:e}=P(),t=te(),{hasSidebar:n,hasAside:o,leftAside:i}=D(),u=b(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(p,v)=>{const k=q("Content");return a(),l("div",{class:C(["VPDoc",{"has-sidebar":r(n),"has-aside":r(o)}])},[d(p.$slots,"doc-top",{},void 0,!0),c("div",ps,[r(o)?(a(),l("div",{key:0,class:C(["aside",{"left-aside":r(i)}])},[_s,c("div",fs,[c("div",ms,[_(Ot,null,{"aside-top":h(()=>[d(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":h(()=>[d(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":h(()=>[d(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":h(()=>[d(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":h(()=>[d(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":h(()=>[d(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):f("",!0),c("div",gs,[c("div",$s,[d(p.$slots,"doc-before",{},void 0,!0),c("main",ks,[_(k,{class:C(["vp-doc",[u.value,r(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),_(vs,null,{"doc-footer-before":h(()=>[d(p.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),d(p.$slots,"doc-after",{},void 0,!0)])])]),d(p.$slots,"doc-bottom",{},void 0,!0)],2)}}}),ys=m(bs,[["__scopeId","data-v-31dd4b0a"]]),Ps=g({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{}},setup(s){const e=s,t=b(()=>e.href&&Pe.test(e.href)),n=b(()=>e.tag||e.href?"a":"button");return(o,i)=>(a(),$(x(n.value),{class:C(["VPButton",[o.size,o.theme]]),href:o.href?r(he)(o.href):void 0,target:t.value?"_blank":void 0,rel:t.value?"noreferrer":void 0},{default:h(()=>[H(V(o.text),1)]),_:1},8,["class","href","target","rel"]))}}),ws=m(Ps,[["__scopeId","data-v-40be9b68"]]),Vs=["src","alt"],Ls=g({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const n=q("VPImage",!0);return e.image?(a(),l(M,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),l("img",J({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:r(de)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,Vs)):(a(),l(M,{key:1},[_(n,J({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),_(n,J({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):f("",!0)}}}),Q=m(Ls,[["__scopeId","data-v-311b0b50"]]),Ss=s=>(E("data-v-d6a8a56d"),s=s(),F(),s),Ms={class:"container"},Is={class:"main"},Ts={key:0,class:"name"},Cs=["innerHTML"],Ns=["innerHTML"],As=["innerHTML"],Bs={key:0,class:"actions"},Hs={key:0,class:"image"},zs={class:"image-container"},Es=Ss(()=>c("div",{class:"image-bg"},null,-1)),Fs=g({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=se("hero-image-slot-exists");return(t,n)=>(a(),l("div",{class:C(["VPHero",{"has-image":t.image||r(e)}])},[c("div",Ms,[c("div",Is,[d(t.$slots,"home-hero-info",{},()=>[t.name?(a(),l("h1",Ts,[c("span",{innerHTML:t.name,class:"clip"},null,8,Cs)])):f("",!0),t.text?(a(),l("p",{key:1,innerHTML:t.text,class:"text"},null,8,Ns)):f("",!0),t.tagline?(a(),l("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,As)):f("",!0)],!0),t.actions?(a(),l("div",Bs,[(a(!0),l(M,null,B(t.actions,o=>(a(),l("div",{key:o.link,class:"action"},[_(ws,{tag:"a",size:"medium",theme:o.theme,text:o.text,href:o.link},null,8,["theme","text","href"])]))),128))])):f("",!0)]),t.image||r(e)?(a(),l("div",Hs,[c("div",zs,[Es,d(t.$slots,"home-hero-image",{},()=>[t.image?(a(),$(Q,{key:0,class:"image-src",image:t.image},null,8,["image"])):f("",!0)],!0)])])):f("",!0)])],2))}}),Ds=m(Fs,[["__scopeId","data-v-d6a8a56d"]]),Os=g({__name:"VPHomeHero",setup(s){const{frontmatter:e}=P();return(t,n)=>r(e).hero?(a(),$(Ds,{key:0,class:"VPHomeHero",name:r(e).hero.name,text:r(e).hero.text,tagline:r(e).hero.tagline,image:r(e).hero.image,actions:r(e).hero.actions},{"home-hero-info":h(()=>[d(t.$slots,"home-hero-info")]),"home-hero-image":h(()=>[d(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):f("",!0)}}),xs={},Gs={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Us=c("path",{d:"M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"},null,-1),js=[Us];function qs(s,e){return a(),l("svg",Gs,js)}const Ks=m(xs,[["render",qs]]),Rs={class:"box"},Ws={key:0,class:"icon"},Ys=["innerHTML"],Js=["innerHTML"],Zs=["innerHTML"],Qs={key:4,class:"link-text"},Xs={class:"link-text-value"},en=g({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(a(),$(z,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:h(()=>[c("article",Rs,[typeof e.icon=="object"&&e.icon.wrap?(a(),l("div",Ws,[_(Q,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),$(Q,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),l("div",{key:2,class:"icon",innerHTML:e.icon},null,8,Ys)):f("",!0),c("h2",{class:"title",innerHTML:e.title},null,8,Js),e.details?(a(),l("p",{key:3,class:"details",innerHTML:e.details},null,8,Zs)):f("",!0),e.linkText?(a(),l("div",Qs,[c("p",Xs,[H(V(e.linkText)+" ",1),_(Ks,{class:"link-text-icon"})])])):f("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),tn=m(en,[["__scopeId","data-v-67a48382"]]),sn={key:0,class:"VPFeatures"},nn={class:"container"},on={class:"items"},an=g({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=b(()=>{const n=e.features.length;if(n){if(n===2)return"grid-2";if(n===3)return"grid-3";if(n%3===0)return"grid-6";if(n>3)return"grid-4"}else return});return(n,o)=>n.features?(a(),l("div",sn,[c("div",nn,[c("div",on,[(a(!0),l(M,null,B(n.features,i=>(a(),l("div",{key:i.title,class:C(["item",[t.value]])},[_(tn,{icon:i.icon,title:i.title,details:i.details,link:i.link,"link-text":i.linkText,rel:i.rel,target:i.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):f("",!0)}}),rn=m(an,[["__scopeId","data-v-cfea7819"]]),ln=g({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=P();return(t,n)=>r(e).features?(a(),$(rn,{key:0,class:"VPHomeFeatures",features:r(e).features},null,8,["features"])):f("",!0)}}),cn={class:"VPHome"},un=g({__name:"VPHome",setup(s){return(e,t)=>{const n=q("Content");return a(),l("div",cn,[d(e.$slots,"home-hero-before",{},void 0,!0),_(Os,null,{"home-hero-info":h(()=>[d(e.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":h(()=>[d(e.$slots,"home-hero-image",{},void 0,!0)]),_:3}),d(e.$slots,"home-hero-after",{},void 0,!0),d(e.$slots,"home-features-before",{},void 0,!0),_(ln),d(e.$slots,"home-features-after",{},void 0,!0),_(n)])}}}),dn=m(un,[["__scopeId","data-v-24527f03"]]),vn={},hn={class:"VPPage"};function pn(s,e){const t=q("Content");return a(),l("div",hn,[d(s.$slots,"page-top"),_(t),d(s.$slots,"page-bottom")])}const _n=m(vn,[["render",pn]]),fn=g({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=P(),{hasSidebar:n}=D();return(o,i)=>(a(),l("div",{class:C(["VPContent",{"has-sidebar":r(n),"is-home":r(t).layout==="home"}]),id:"VPContent"},[r(e).isNotFound?d(o.$slots,"not-found",{key:0},()=>[_(pt)],!0):r(t).layout==="page"?(a(),$(_n,{key:1},{"page-top":h(()=>[d(o.$slots,"page-top",{},void 0,!0)]),"page-bottom":h(()=>[d(o.$slots,"page-bottom",{},void 0,!0)]),_:3})):r(t).layout==="home"?(a(),$(dn,{key:2},{"home-hero-before":h(()=>[d(o.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info":h(()=>[d(o.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":h(()=>[d(o.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":h(()=>[d(o.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":h(()=>[d(o.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":h(()=>[d(o.$slots,"home-features-after",{},void 0,!0)]),_:3})):r(t).layout&&r(t).layout!=="doc"?(a(),$(x(r(t).layout),{key:3})):(a(),$(ys,{key:4},{"doc-top":h(()=>[d(o.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":h(()=>[d(o.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":h(()=>[d(o.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":h(()=>[d(o.$slots,"doc-before",{},void 0,!0)]),"doc-after":h(()=>[d(o.$slots,"doc-after",{},void 0,!0)]),"aside-top":h(()=>[d(o.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":h(()=>[d(o.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":h(()=>[d(o.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":h(()=>[d(o.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":h(()=>[d(o.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":h(()=>[d(o.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),mn=m(fn,[["__scopeId","data-v-9cc6e550"]]),gn={class:"container"},$n=["innerHTML"],kn=["innerHTML"],bn=g({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=P(),{hasSidebar:n}=D();return(o,i)=>r(e).footer&&r(t).footer!==!1?(a(),l("footer",{key:0,class:C(["VPFooter",{"has-sidebar":r(n)}])},[c("div",gn,[r(e).footer.message?(a(),l("p",{key:0,class:"message",innerHTML:r(e).footer.message},null,8,$n)):f("",!0),r(e).footer.copyright?(a(),l("p",{key:1,class:"copyright",innerHTML:r(e).footer.copyright},null,8,kn)):f("",!0)])],2)):f("",!0)}}),yn=m(bn,[["__scopeId","data-v-511ea0bf"]]);function Ce(){const{theme:s,frontmatter:e}=P(),t=ye([]),n=b(()=>t.value.length>0);return ee(()=>{t.value=pe(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:n}}const Pn={},wn={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Vn=c("path",{d:"M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"},null,-1),Ln=[Vn];function Sn(s,e){return a(),l("svg",wn,Ln)}const Ne=m(Pn,[["render",Sn]]),Mn={class:"header"},In={class:"outline"},Tn=g({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=P(),n=S(!1),o=S(0),i=S(),u=S();Ue(i,()=>{n.value=!1}),je("Escape",()=>{n.value=!1}),ee(()=>{n.value=!1});function p(){n.value=!n.value,o.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function v(y){y.target.classList.contains("outline-link")&&(u.value&&(u.value.style.transition="none"),Ke(()=>{n.value=!1}))}function k(){n.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(y,w)=>(a(),l("div",{class:"VPLocalNavOutlineDropdown",style:qe({"--vp-vh":o.value+"px"}),ref_key:"main",ref:i},[y.headers.length>0?(a(),l("button",{key:0,onClick:p,class:C({open:n.value})},[H(V(r(Ie)(r(t)))+" ",1),_(Ne,{class:"icon"})],2)):(a(),l("button",{key:1,onClick:k},V(r(t).returnToTopLabel||"Return to top"),1)),_(ue,{name:"flyout"},{default:h(()=>[n.value?(a(),l("div",{key:0,ref_key:"items",ref:u,class:"items",onClick:v},[c("div",Mn,[c("a",{class:"top-link",href:"#",onClick:k},V(r(t).returnToTopLabel||"Return to top"),1)]),c("div",In,[_(Te,{headers:y.headers},null,8,["headers"])])],512)):f("",!0)]),_:1})],4))}}),Cn=m(Tn,[["__scopeId","data-v-5f66bb3b"]]),Nn={},An={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Bn=c("path",{d:"M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"},null,-1),Hn=c("path",{d:"M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"},null,-1),zn=c("path",{d:"M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"},null,-1),En=c("path",{d:"M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"},null,-1),Fn=[Bn,Hn,zn,En];function Dn(s,e){return a(),l("svg",An,Fn)}const On=m(Nn,[["render",Dn]]),xn={class:"container"},Gn=["aria-expanded"],Un={class:"menu-text"},jn=g({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=P(),{hasSidebar:n}=D(),{headers:o}=Ce(),{y:i}=we(),u=S(0);U(()=>{u.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),ee(()=>{o.value=pe(t.value.outline??e.value.outline)});const p=b(()=>o.value.length===0),v=b(()=>p.value&&!n.value),k=b(()=>({VPLocalNav:!0,"has-sidebar":n.value,empty:p.value,fixed:v.value}));return(y,w)=>r(t).layout!=="home"&&(!v.value||r(i)>=u.value)?(a(),l("div",{key:0,class:C(k.value)},[c("div",xn,[r(n)?(a(),l("button",{key:0,class:"menu","aria-expanded":y.open,"aria-controls":"VPSidebarNav",onClick:w[0]||(w[0]=T=>y.$emit("open-menu"))},[_(On,{class:"menu-icon"}),c("span",Un,V(r(e).sidebarMenuLabel||"Menu"),1)],8,Gn)):f("",!0),_(Cn,{headers:r(o),navHeight:u.value},null,8,["headers","navHeight"])])],2)):f("",!0)}}),qn=m(jn,[["__scopeId","data-v-3f38562d"]]);function Kn(){const s=S(!1);function e(){s.value=!0,window.addEventListener("resize",o)}function t(){s.value=!1,window.removeEventListener("resize",o)}function n(){s.value?t():e()}function o(){window.outerWidth>=768&&t()}const i=te();return j(()=>i.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:n}}const Rn={},Wn={class:"VPSwitch",type:"button",role:"switch"},Yn={class:"check"},Jn={key:0,class:"icon"};function Zn(s,e){return a(),l("button",Wn,[c("span",Yn,[s.$slots.default?(a(),l("span",Jn,[d(s.$slots,"default",{},void 0,!0)])):f("",!0)])])}const Qn=m(Rn,[["render",Zn],["__scopeId","data-v-2a3bed0a"]]),Xn={},eo={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},to=c("path",{d:"M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"},null,-1),so=[to];function no(s,e){return a(),l("svg",eo,so)}const oo=m(Xn,[["render",no]]),ao={},ro={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},io=Re('',9),lo=[io];function co(s,e){return a(),l("svg",ro,lo)}const uo=m(ao,[["render",co]]),vo=g({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=P(),n=se("toggle-appearance",()=>{e.value=!e.value}),o=b(()=>e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme");return(i,u)=>(a(),$(Qn,{title:o.value,class:"VPSwitchAppearance","aria-checked":r(e),onClick:r(n)},{default:h(()=>[_(uo,{class:"sun"}),_(oo,{class:"moon"})]),_:1},8,["title","aria-checked","onClick"]))}}),_e=m(vo,[["__scopeId","data-v-3cf77669"]]),ho={key:0,class:"VPNavBarAppearance"},po=g({__name:"VPNavBarAppearance",setup(s){const{site:e}=P();return(t,n)=>r(e).appearance&&r(e).appearance!=="force-dark"?(a(),l("div",ho,[_(_e)])):f("",!0)}}),_o=m(po,[["__scopeId","data-v-d3b998cb"]]),fe=S();let Ae=!1,re=0;function fo(s){const e=S(!1);if(W){!Ae&&mo(),re++;const t=j(fe,n=>{var o,i,u;n===s.el.value||(o=s.el.value)!=null&&o.contains(n)?(e.value=!0,(i=s.onFocus)==null||i.call(s)):(e.value=!1,(u=s.onBlur)==null||u.call(s))});ve(()=>{t(),re--,re||go()})}return We(e)}function mo(){document.addEventListener("focusin",Be),Ae=!0,fe.value=document.activeElement}function go(){document.removeEventListener("focusin",Be)}function Be(){fe.value=document.activeElement}const $o={},ko={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},bo=c("path",{d:"M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"},null,-1),yo=[bo];function Po(s,e){return a(),l("svg",ko,yo)}const He=m($o,[["render",Po]]),wo={},Vo={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},Lo=c("circle",{cx:"12",cy:"12",r:"2"},null,-1),So=c("circle",{cx:"19",cy:"12",r:"2"},null,-1),Mo=c("circle",{cx:"5",cy:"12",r:"2"},null,-1),Io=[Lo,So,Mo];function To(s,e){return a(),l("svg",Vo,Io)}const Co=m(wo,[["render",To]]),No={class:"VPMenuLink"},Ao=g({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=P();return(t,n)=>(a(),l("div",No,[_(z,{class:C({active:r(G)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:h(()=>[H(V(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),ne=m(Ao,[["__scopeId","data-v-471767ad"]]),Bo={class:"VPMenuGroup"},Ho={key:0,class:"title"},zo=g({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),l("div",Bo,[e.text?(a(),l("p",Ho,V(e.text),1)):f("",!0),(a(!0),l(M,null,B(e.items,n=>(a(),l(M,null,["link"in n?(a(),$(ne,{key:0,item:n},null,8,["item"])):f("",!0)],64))),256))]))}}),Eo=m(zo,[["__scopeId","data-v-10eeda13"]]),Fo={class:"VPMenu"},Do={key:0,class:"items"},Oo=g({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(a(),l("div",Fo,[e.items?(a(),l("div",Do,[(a(!0),l(M,null,B(e.items,n=>(a(),l(M,{key:n.text},["link"in n?(a(),$(ne,{key:0,item:n},null,8,["item"])):(a(),$(Eo,{key:1,text:n.text,items:n.items},null,8,["text","items"]))],64))),128))])):f("",!0),d(e.$slots,"default",{},void 0,!0)]))}}),xo=m(Oo,[["__scopeId","data-v-7fa80d24"]]),Go=["aria-expanded","aria-label"],Uo={key:0,class:"text"},jo=["innerHTML"],qo={class:"menu"},Ko=g({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=S(!1),t=S();fo({el:t,onBlur:n});function n(){e.value=!1}return(o,i)=>(a(),l("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:i[1]||(i[1]=u=>e.value=!0),onMouseleave:i[2]||(i[2]=u=>e.value=!1)},[c("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":o.label,onClick:i[0]||(i[0]=u=>e.value=!e.value)},[o.button||o.icon?(a(),l("span",Uo,[o.icon?(a(),$(x(o.icon),{key:0,class:"option-icon"})):f("",!0),o.button?(a(),l("span",{key:1,innerHTML:o.button},null,8,jo)):f("",!0),_(He,{class:"text-icon"})])):(a(),$(Co,{key:1,class:"icon"}))],8,Go),c("div",qo,[_(xo,{items:o.items},{default:h(()=>[d(o.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),me=m(Ko,[["__scopeId","data-v-d984d571"]]),Ro={discord:'Discord',facebook:'Facebook',github:'GitHub',instagram:'Instagram',linkedin:'LinkedIn',mastodon:'Mastodon',slack:'Slack',twitter:'Twitter',x:'X',youtube:'YouTube'},Wo=["href","aria-label","innerHTML"],Yo=g({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=b(()=>typeof e.icon=="object"?e.icon.svg:Ro[e.icon]);return(n,o)=>(a(),l("a",{class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,Wo))}}),Jo=m(Yo,[["__scopeId","data-v-71f82a9c"]]),Zo={class:"VPSocialLinks"},Qo=g({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(a(),l("div",Zo,[(a(!0),l(M,null,B(e.links,({link:n,icon:o,ariaLabel:i})=>(a(),$(Jo,{key:n,icon:o,link:n,ariaLabel:i},null,8,["icon","link","ariaLabel"]))),128))]))}}),ge=m(Qo,[["__scopeId","data-v-e07a6729"]]),Xo={key:0,class:"group translations"},ea={class:"trans-title"},ta={key:1,class:"group"},sa={class:"item appearance"},na={class:"label"},oa={class:"appearance-action"},aa={key:2,class:"group"},ra={class:"item social-links"},ia=g({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=P(),{localeLinks:n,currentLang:o}=Y({correspondingLink:!0}),i=b(()=>n.value.length&&o.value.label||e.value.appearance||t.value.socialLinks);return(u,p)=>i.value?(a(),$(me,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:h(()=>[r(n).length&&r(o).label?(a(),l("div",Xo,[c("p",ea,V(r(o).label),1),(a(!0),l(M,null,B(r(n),v=>(a(),$(ne,{key:v.link,item:v},null,8,["item"]))),128))])):f("",!0),r(e).appearance&&r(e).appearance!=="force-dark"?(a(),l("div",ta,[c("div",sa,[c("p",na,V(r(t).darkModeSwitchLabel||"Appearance"),1),c("div",oa,[_(_e)])])])):f("",!0),r(t).socialLinks?(a(),l("div",aa,[c("div",ra,[_(ge,{class:"social-links-list",links:r(t).socialLinks},null,8,["links"])])])):f("",!0)]),_:1})):f("",!0)}}),la=m(ia,[["__scopeId","data-v-cbc1e7bf"]]),ca=s=>(E("data-v-09ffc4dc"),s=s(),F(),s),ua=["aria-expanded"],da=ca(()=>c("span",{class:"container"},[c("span",{class:"top"}),c("span",{class:"middle"}),c("span",{class:"bottom"})],-1)),va=[da],ha=g({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(a(),l("button",{type:"button",class:C(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=n=>e.$emit("click"))},va,10,ua))}}),pa=m(ha,[["__scopeId","data-v-09ffc4dc"]]),_a=["innerHTML"],fa=g({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=P();return(t,n)=>(a(),$(z,{class:C({VPNavBarMenuLink:!0,active:r(G)(r(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:h(()=>[c("span",{innerHTML:t.item.text},null,8,_a)]),_:1},8,["class","href","target","rel"]))}}),ma=m(fa,[["__scopeId","data-v-4db78c14"]]),ga=g({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=P(),n=i=>"link"in i?G(t.value.relativePath,i.link,!!e.item.activeMatch):i.items.some(n),o=b(()=>n(e.item));return(i,u)=>(a(),$(me,{class:C({VPNavBarMenuGroup:!0,active:r(G)(r(t).relativePath,i.item.activeMatch,!!i.item.activeMatch)||o.value}),button:i.item.text,items:i.item.items},null,8,["class","button","items"]))}}),$a=s=>(E("data-v-d92b6212"),s=s(),F(),s),ka={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},ba=$a(()=>c("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),ya=g({__name:"VPNavBarMenu",setup(s){const{theme:e}=P();return(t,n)=>r(e).nav?(a(),l("nav",ka,[ba,(a(!0),l(M,null,B(r(e).nav,o=>(a(),l(M,{key:o.text},["link"in o?(a(),$(ma,{key:0,item:o},null,8,["item"])):(a(),$(ga,{key:1,item:o},null,8,["item"]))],64))),128))])):f("",!0)}}),Pa=m(ya,[["__scopeId","data-v-d92b6212"]]);function wa(s){const{localeIndex:e,theme:t}=P();function n(o){var A,N,L;const i=o.split("."),u=(A=t.value.search)==null?void 0:A.options,p=u&&typeof u=="object",v=p&&((L=(N=u.locales)==null?void 0:N[e.value])==null?void 0:L.translations)||null,k=p&&u.translations||null;let y=v,w=k,T=s;const I=i.pop();for(const K of i){let O=null;const R=T==null?void 0:T[K];R&&(O=T=R);const oe=w==null?void 0:w[K];oe&&(O=w=oe);const ae=y==null?void 0:y[K];ae&&(O=y=ae),R||(T=O),oe||(w=O),ae||(y=O)}return(y==null?void 0:y[I])??(w==null?void 0:w[I])??(T==null?void 0:T[I])??""}return n}const Va=["aria-label"],La={class:"DocSearch-Button-Container"},Sa=c("svg",{class:"DocSearch-Search-Icon",width:"20",height:"20",viewBox:"0 0 20 20","aria-label":"search icon"},[c("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none","fill-rule":"evenodd","stroke-linecap":"round","stroke-linejoin":"round"})],-1),Ma={class:"DocSearch-Button-Placeholder"},Ia=c("span",{class:"DocSearch-Button-Keys"},[c("kbd",{class:"DocSearch-Button-Key"}),c("kbd",{class:"DocSearch-Button-Key"},"K")],-1),ke=g({__name:"VPNavBarSearchButton",setup(s){const t=wa({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(n,o)=>(a(),l("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":r(t)("button.buttonAriaLabel")},[c("span",La,[Sa,c("span",Ma,V(r(t)("button.buttonText")),1)]),Ia],8,Va))}}),Ta={class:"VPNavBarSearch"},Ca={id:"local-search"},Na={key:1,id:"docsearch"},Aa=g({__name:"VPNavBarSearch",setup(s){const e=()=>null,t=()=>null,{theme:n}=P(),o=S(!1),i=S(!1);U(()=>{});function u(){o.value||(o.value=!0,setTimeout(p,16))}function p(){const y=new Event("keydown");y.key="k",y.metaKey=!0,window.dispatchEvent(y),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||p()},16)}const v=S(!1),k="";return(y,w)=>{var T;return a(),l("div",Ta,[r(k)==="local"?(a(),l(M,{key:0},[v.value?(a(),$(r(e),{key:0,onClose:w[0]||(w[0]=I=>v.value=!1)})):f("",!0),c("div",Ca,[_(ke,{onClick:w[1]||(w[1]=I=>v.value=!0)})])],64)):r(k)==="algolia"?(a(),l(M,{key:1},[o.value?(a(),$(r(t),{key:0,algolia:((T=r(n).search)==null?void 0:T.options)??r(n).algolia,onVnodeBeforeMount:w[2]||(w[2]=I=>i.value=!0)},null,8,["algolia"])):f("",!0),i.value?f("",!0):(a(),l("div",Na,[_(ke,{onClick:u})]))],64)):f("",!0)])}}}),Ba=g({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=P();return(t,n)=>r(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavBarSocialLinks",links:r(e).socialLinks},null,8,["links"])):f("",!0)}}),Ha=m(Ba,[["__scopeId","data-v-fcd1192c"]]),za=["href"],Ea=g({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=P(),{hasSidebar:n}=D(),{currentLang:o}=Y();return(i,u)=>(a(),l("div",{class:C(["VPNavBarTitle",{"has-sidebar":r(n)}])},[c("a",{class:"title",href:r(t).logoLink??r(he)(r(o).link)},[d(i.$slots,"nav-bar-title-before",{},void 0,!0),r(t).logo?(a(),$(Q,{key:0,class:"logo",image:r(t).logo},null,8,["image"])):f("",!0),r(t).siteTitle?(a(),l(M,{key:1},[H(V(r(t).siteTitle),1)],64)):r(t).siteTitle===void 0?(a(),l(M,{key:2},[H(V(r(e).title),1)],64)):f("",!0),d(i.$slots,"nav-bar-title-after",{},void 0,!0)],8,za)],2))}}),Fa=m(Ea,[["__scopeId","data-v-26e79017"]]),Da={},Oa={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},xa=c("path",{d:"M0 0h24v24H0z",fill:"none"},null,-1),Ga=c("path",{d:" M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z ",class:"css-c4d79v"},null,-1),Ua=[xa,Ga];function ja(s,e){return a(),l("svg",Oa,Ua)}const ze=m(Da,[["render",ja]]),qa={class:"items"},Ka={class:"title"},Ra=g({__name:"VPNavBarTranslations",setup(s){const{theme:e}=P(),{localeLinks:t,currentLang:n}=Y({correspondingLink:!0});return(o,i)=>r(t).length&&r(n).label?(a(),$(me,{key:0,class:"VPNavBarTranslations",icon:ze,label:r(e).langMenuLabel||"Change language"},{default:h(()=>[c("div",qa,[c("p",Ka,V(r(n).label),1),(a(!0),l(M,null,B(r(t),u=>(a(),$(ne,{key:u.link,item:u},null,8,["item"]))),128))])]),_:1},8,["label"])):f("",!0)}}),Wa=m(Ra,[["__scopeId","data-v-33b812cb"]]),Ya=s=>(E("data-v-096a19da"),s=s(),F(),s),Ja={class:"wrapper"},Za={class:"container"},Qa={class:"title"},Xa={class:"content"},er={class:"content-body"},tr=Ya(()=>c("div",{class:"divider"},[c("div",{class:"divider-line"})],-1)),sr=g({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const{y:e}=we(),{hasSidebar:t}=D(),{hasLocalNav:n}=Ce(),{frontmatter:o}=P(),i=S({});return be(()=>{i.value={"has-sidebar":t.value,"has-local-nav":n.value,top:o.value.layout==="home"&&e.value===0}}),(u,p)=>(a(),l("div",{class:C(["VPNavBar",i.value])},[c("div",Ja,[c("div",Za,[c("div",Qa,[_(Fa,null,{"nav-bar-title-before":h(()=>[d(u.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":h(()=>[d(u.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),c("div",Xa,[c("div",er,[d(u.$slots,"nav-bar-content-before",{},void 0,!0),_(Aa,{class:"search"}),_(Pa,{class:"menu"}),_(Wa,{class:"translations"}),_(_o,{class:"appearance"}),_(Ha,{class:"social-links"}),_(la,{class:"extra"}),d(u.$slots,"nav-bar-content-after",{},void 0,!0),_(pa,{class:"hamburger",active:u.isScreenOpen,onClick:p[0]||(p[0]=v=>u.$emit("toggle-screen"))},null,8,["active"])])])])]),tr],2))}}),nr=m(sr,[["__scopeId","data-v-096a19da"]]),or={key:0,class:"VPNavScreenAppearance"},ar={class:"text"},rr=g({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=P();return(n,o)=>r(e).appearance&&r(e).appearance!=="force-dark"?(a(),l("div",or,[c("p",ar,V(r(t).darkModeSwitchLabel||"Appearance"),1),_(_e)])):f("",!0)}}),ir=m(rr,[["__scopeId","data-v-eac3ec4a"]]),lr=g({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=se("close-screen");return(t,n)=>(a(),$(z,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:r(e)},{default:h(()=>[H(V(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),cr=m(lr,[["__scopeId","data-v-0bb67861"]]),ur={},dr={xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24"},vr=c("path",{d:"M18.9,10.9h-6v-6c0-0.6-0.4-1-1-1s-1,0.4-1,1v6h-6c-0.6,0-1,0.4-1,1s0.4,1,1,1h6v6c0,0.6,0.4,1,1,1s1-0.4,1-1v-6h6c0.6,0,1-0.4,1-1S19.5,10.9,18.9,10.9z"},null,-1),hr=[vr];function pr(s,e){return a(),l("svg",dr,hr)}const _r=m(ur,[["render",pr]]),fr=g({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=se("close-screen");return(t,n)=>(a(),$(z,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:r(e)},{default:h(()=>[H(V(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Ee=m(fr,[["__scopeId","data-v-c9499b62"]]),mr={class:"VPNavScreenMenuGroupSection"},gr={key:0,class:"title"},$r=g({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),l("div",mr,[e.text?(a(),l("p",gr,V(e.text),1)):f("",!0),(a(!0),l(M,null,B(e.items,n=>(a(),$(Ee,{key:n.text,item:n},null,8,["item"]))),128))]))}}),kr=m($r,[["__scopeId","data-v-fcf881b9"]]),br=["aria-controls","aria-expanded"],yr=["innerHTML"],Pr=["id"],wr={key:1,class:"group"},Vr=g({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=S(!1),n=b(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function o(){t.value=!t.value}return(i,u)=>(a(),l("div",{class:C(["VPNavScreenMenuGroup",{open:t.value}])},[c("button",{class:"button","aria-controls":n.value,"aria-expanded":t.value,onClick:o},[c("span",{class:"button-text",innerHTML:i.text},null,8,yr),_(_r,{class:"button-icon"})],8,br),c("div",{id:n.value,class:"items"},[(a(!0),l(M,null,B(i.items,p=>(a(),l(M,{key:p.text},["link"in p?(a(),l("div",{key:p.text,class:"item"},[_(Ee,{item:p},null,8,["item"])])):(a(),l("div",wr,[_(kr,{text:p.text,items:p.items},null,8,["text","items"])]))],64))),128))],8,Pr)],2))}}),Lr=m(Vr,[["__scopeId","data-v-e90ec729"]]),Sr={key:0,class:"VPNavScreenMenu"},Mr=g({__name:"VPNavScreenMenu",setup(s){const{theme:e}=P();return(t,n)=>r(e).nav?(a(),l("nav",Sr,[(a(!0),l(M,null,B(r(e).nav,o=>(a(),l(M,{key:o.text},["link"in o?(a(),$(cr,{key:0,item:o},null,8,["item"])):(a(),$(Lr,{key:1,text:o.text||"",items:o.items},null,8,["text","items"]))],64))),128))])):f("",!0)}}),Ir=g({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=P();return(t,n)=>r(e).socialLinks?(a(),$(ge,{key:0,class:"VPNavScreenSocialLinks",links:r(e).socialLinks},null,8,["links"])):f("",!0)}}),Tr={class:"list"},Cr=g({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=Y({correspondingLink:!0}),n=S(!1);function o(){n.value=!n.value}return(i,u)=>r(e).length&&r(t).label?(a(),l("div",{key:0,class:C(["VPNavScreenTranslations",{open:n.value}])},[c("button",{class:"title",onClick:o},[_(ze,{class:"icon lang"}),H(" "+V(r(t).label)+" ",1),_(He,{class:"icon chevron"})]),c("ul",Tr,[(a(!0),l(M,null,B(r(e),p=>(a(),l("li",{key:p.link,class:"item"},[_(z,{class:"link",href:p.link},{default:h(()=>[H(V(p.text),1)]),_:2},1032,["href"])]))),128))])],2)):f("",!0)}}),Nr=m(Cr,[["__scopeId","data-v-ca22a98e"]]),Ar={class:"container"},Br=g({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=S(null),t=Ve(W?document.body:null);return(n,o)=>(a(),$(ue,{name:"fade",onEnter:o[0]||(o[0]=i=>t.value=!0),onAfterLeave:o[1]||(o[1]=i=>t.value=!1)},{default:h(()=>[n.open?(a(),l("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[c("div",Ar,[d(n.$slots,"nav-screen-content-before",{},void 0,!0),_(Mr,{class:"menu"}),_(Nr,{class:"translations"}),_(ir,{class:"appearance"}),_(Ir,{class:"social-links"}),d(n.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):f("",!0)]),_:3}))}}),Hr=m(Br,[["__scopeId","data-v-05143d15"]]),zr={key:0,class:"VPNav"},Er=g({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:n}=Kn(),{frontmatter:o}=P(),i=b(()=>o.value.navbar!==!1);return Le("close-screen",t),X(()=>{W&&document.documentElement.classList.toggle("hide-nav",!i.value)}),(u,p)=>i.value?(a(),l("header",zr,[_(nr,{"is-screen-open":r(e),onToggleScreen:r(n)},{"nav-bar-title-before":h(()=>[d(u.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":h(()=>[d(u.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":h(()=>[d(u.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":h(()=>[d(u.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),_(Hr,{open:r(e)},{"nav-screen-content-before":h(()=>[d(u.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":h(()=>[d(u.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):f("",!0)}}),Fr=m(Er,[["__scopeId","data-v-e89ada44"]]),Dr=s=>(E("data-v-1d929f5a"),s=s(),F(),s),Or=["role","tabindex"],xr=Dr(()=>c("div",{class:"indicator"},null,-1)),Gr={key:1,class:"items"},Ur=g({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:n,isLink:o,isActiveLink:i,hasActiveLink:u,hasChildren:p,toggle:v}=gt(b(()=>e.item)),k=b(()=>p.value?"section":"div"),y=b(()=>o.value?"a":"div"),w=b(()=>p.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),T=b(()=>o.value?void 0:"button"),I=b(()=>[[`level-${e.depth}`],{collapsible:n.value},{collapsed:t.value},{"is-link":o.value},{"is-active":i.value},{"has-active":u.value}]);function A(L){"key"in L&&L.key!=="Enter"||!e.item.link&&v()}function N(){e.item.link&&v()}return(L,K)=>{const O=q("VPSidebarItem",!0);return a(),$(x(k.value),{class:C(["VPSidebarItem",I.value])},{default:h(()=>[L.item.text?(a(),l("div",J({key:0,class:"item",role:T.value},Je(L.item.items?{click:A,keydown:A}:{},!0),{tabindex:L.item.items&&0}),[xr,L.item.link?(a(),$(z,{key:0,tag:y.value,class:"link",href:L.item.link,rel:L.item.rel,target:L.item.target},{default:h(()=>[(a(),$(x(w.value),{class:"text",innerHTML:L.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),$(x(w.value),{key:1,class:"text",innerHTML:L.item.text},null,8,["innerHTML"])),L.item.collapsed!=null?(a(),l("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:N,onKeydown:Ye(N,["enter"]),tabindex:"0"},[_(Ne,{class:"caret-icon"})],32)):f("",!0)],16,Or)):f("",!0),L.item.items&&L.item.items.length?(a(),l("div",Gr,[L.depth<5?(a(!0),l(M,{key:0},B(L.item.items,R=>(a(),$(O,{key:R.text,item:R,depth:L.depth+1},null,8,["item","depth"]))),128)):f("",!0)])):f("",!0)]),_:1},8,["class"])}}}),jr=m(Ur,[["__scopeId","data-v-1d929f5a"]]),Fe=s=>(E("data-v-eeab08bd"),s=s(),F(),s),qr=Fe(()=>c("div",{class:"curtain"},null,-1)),Kr={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},Rr=Fe(()=>c("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),Wr=g({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:e,hasSidebar:t}=D(),n=s,o=S(null),i=Ve(W?document.body:null);return j([n,o],()=>{var u;n.open?(i.value=!0,(u=o.value)==null||u.focus()):i.value=!1},{immediate:!0,flush:"post"}),(u,p)=>r(t)?(a(),l("aside",{key:0,class:C(["VPSidebar",{open:u.open}]),ref_key:"navEl",ref:o,onClick:p[0]||(p[0]=Ze(()=>{},["stop"]))},[qr,c("nav",Kr,[Rr,d(u.$slots,"sidebar-nav-before",{},void 0,!0),(a(!0),l(M,null,B(r(e),v=>(a(),l("div",{key:v.text,class:"group"},[_(jr,{item:v,depth:0},null,8,["item"])]))),128)),d(u.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):f("",!0)}}),Yr=m(Wr,[["__scopeId","data-v-eeab08bd"]]),Jr=g({__name:"VPSkipLink",setup(s){const e=te(),t=S();j(()=>e.path,()=>t.value.focus());function n({target:o}){const i=document.getElementById(decodeURIComponent(o.hash).slice(1));if(i){const u=()=>{i.removeAttribute("tabindex"),i.removeEventListener("blur",u)};i.setAttribute("tabindex","-1"),i.addEventListener("blur",u),i.focus(),window.scrollTo(0,0)}}return(o,i)=>(a(),l(M,null,[c("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),c("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n}," Skip to content ")],64))}}),Zr=m(Jr,[["__scopeId","data-v-1ebf7576"]]),Qr=g({__name:"Layout",setup(s){const{isOpen:e,open:t,close:n}=D(),o=te();j(()=>o.path,n),mt(e,n);const{frontmatter:i}=P(),u=Qe(),p=b(()=>!!u["home-hero-image"]);return Le("hero-image-slot-exists",p),(v,k)=>{const y=q("Content");return r(i).layout!==!1?(a(),l("div",{key:0,class:C(["Layout",r(i).pageClass])},[d(v.$slots,"layout-top",{},void 0,!0),_(Zr),_(st,{class:"backdrop",show:r(e),onClick:r(n)},null,8,["show","onClick"]),_(Fr,null,{"nav-bar-title-before":h(()=>[d(v.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":h(()=>[d(v.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":h(()=>[d(v.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":h(()=>[d(v.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":h(()=>[d(v.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":h(()=>[d(v.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),_(qn,{open:r(e),onOpenMenu:r(t)},null,8,["open","onOpenMenu"]),_(Yr,{open:r(e)},{"sidebar-nav-before":h(()=>[d(v.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":h(()=>[d(v.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),_(mn,null,{"page-top":h(()=>[d(v.$slots,"page-top",{},void 0,!0)]),"page-bottom":h(()=>[d(v.$slots,"page-bottom",{},void 0,!0)]),"not-found":h(()=>[d(v.$slots,"not-found",{},void 0,!0)]),"home-hero-before":h(()=>[d(v.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info":h(()=>[d(v.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-image":h(()=>[d(v.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":h(()=>[d(v.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":h(()=>[d(v.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":h(()=>[d(v.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":h(()=>[d(v.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":h(()=>[d(v.$slots,"doc-before",{},void 0,!0)]),"doc-after":h(()=>[d(v.$slots,"doc-after",{},void 0,!0)]),"doc-top":h(()=>[d(v.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":h(()=>[d(v.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":h(()=>[d(v.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":h(()=>[d(v.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":h(()=>[d(v.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":h(()=>[d(v.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":h(()=>[d(v.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":h(()=>[d(v.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),_(yn),d(v.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),$(y,{key:1}))}}}),Xr=m(Qr,[["__scopeId","data-v-1de9594d"]]),ti={Layout:Xr,enhanceApp:({app:s})=>{s.component("Badge",Xe)}};export{ti as t}; diff --git a/assets/configuration_index.md.5FRNy3W7.js b/assets/configuration_index.md.5FRNy3W7.js new file mode 100644 index 00000000..b78246e8 --- /dev/null +++ b/assets/configuration_index.md.5FRNy3W7.js @@ -0,0 +1,14 @@ +import{_ as s,c as i,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Configuration","description":"","frontmatter":{},"headers":[],"relativePath":"configuration/index.md","filePath":"configuration/index.md"}'),e={name:"configuration/index.md"},n=a(`

Configuration

INFO

The default configuration is great for most users. You might not need to tweak anything here.

The authorization server has a few optional settings with the following default values;

ts
type AuthorizationServerOptions = {
+  requiresPKCE: true;
+  requiresS256: false;
+  notBeforeLeeway: 0;
+  tokenCID: "id" | "name";
+}
OptionNumberDefaultDetails
requiresPKCEbooleantruePKCE is enabled by default and recommended for all users. To support a legacy client without PKCE, disable this option. [Learn more]
requiresS256booleantrueDisabled by default. If you want to require all clients to use S256, you can enable that here. [Learn more]
notBeforeLeewaynumber0Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value.
tokenCID"id" or "name""id"Sets the JWT accessToken.cid to either the client.id or client.name.

In 3.x the default is "id", in v2.x the default was "name". [Learn more]

To configure these options, pass the value in as the last argument:

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  new JwtService("secret-key"),
+  {
+    requiresS256: true,
+  }
+);
`,7),l=[n];function r(h,o,p,d,k,c){return t(),i("div",null,l)}const E=s(e,[["render",r]]);export{g as __pageData,E as default}; diff --git a/assets/configuration_index.md.5FRNy3W7.lean.js b/assets/configuration_index.md.5FRNy3W7.lean.js new file mode 100644 index 00000000..94cb1d3a --- /dev/null +++ b/assets/configuration_index.md.5FRNy3W7.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Configuration","description":"","frontmatter":{},"headers":[],"relativePath":"configuration/index.md","filePath":"configuration/index.md"}'),e={name:"configuration/index.md"},n=a("",7),l=[n];function r(h,o,p,d,k,c){return t(),i("div",null,l)}const E=s(e,[["render",r]]);export{g as __pageData,E as default}; diff --git a/assets/entities_index.md.5CEqU3ab.js b/assets/entities_index.md.5CEqU3ab.js new file mode 100644 index 00000000..e01a9c4d --- /dev/null +++ b/assets/entities_index.md.5CEqU3ab.js @@ -0,0 +1,32 @@ +import{_ as s,c as i,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const E=JSON.parse('{"title":"Entity Interfaces","description":"","frontmatter":{"title":"Entity Interfaces"},"headers":[],"relativePath":"entities/index.md","filePath":"entities/index.md"}'),n={name:"entities/index.md"},e=t(`

Entity Interfaces

Client Entity

This entity represents the client that wants to access the resource server. The client will retrieve an access token from our authorization server and use it to access the resource server.

  • URI must be an absolute URI
  • The endpoint may include application/x-www-form-urlencoded formatted query component which must be retained when adding additional query params
  • the endpoint URI must not include a fragment component
typescript
interface OAuthClient {
+  id: string;
+  name: string;
+  secret?: string;
+  redirectUris: string[];
+  allowedGrants: GrantIdentifier[];
+  scopes: OAuthScope[];
+}

Auth Code Entity

The auth code is used to retrieve an access token from the authorization server.

typescript
interface OAuthAuthCode {
+  code: string;
+  redirectUri?: string;
+  codeChallenge?: string;
+  codeChallengeMethod?: CodeChallengeMethod;
+  expiresAt: Date;
+  user?: OAuthUser;
+  client: OAuthClient;
+  scopes: OAuthScope[];
+}

TIP

ts
type CodeChallengeMethod = "S256" | "plain";

Token Entity

The access and refresh token that can be used to authenticate into the resource server. The originatingAuthCodeId will be present only for tokens originating from the authorization code grant; see the revokeDescendantsOf() method on the Token Repository for its significance.

typescript
interface OAuthToken {
+  accessToken: string;
+  accessTokenExpiresAt: Date;
+  refreshToken?: string | null;
+  refreshTokenExpiresAt?: Date | null;
+  client: OAuthClient;
+  user?: OAuthUser | null;
+  scopes: OAuthScope[];
+  originatingAuthCodeId?: string;
+}

User Entity

The resource owner

typescript
interface OAuthUser {
+  id: string;
+  [key: string]: any;
+}

Scope Entity

Scopes are a way to limit an app’s access to a user’s data.

https://www.oauth.com/oauth2-servers/scope/

typescript
interface OAuthScope {
+  name: string;
+  [key: string]: any;
+}
`,19),h=[e];function l(p,k,r,d,o,g){return a(),i("div",null,h)}const y=s(n,[["render",l]]);export{E as __pageData,y as default}; diff --git a/assets/entities_index.md.5CEqU3ab.lean.js b/assets/entities_index.md.5CEqU3ab.lean.js new file mode 100644 index 00000000..7eb624e5 --- /dev/null +++ b/assets/entities_index.md.5CEqU3ab.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const E=JSON.parse('{"title":"Entity Interfaces","description":"","frontmatter":{"title":"Entity Interfaces"},"headers":[],"relativePath":"entities/index.md","filePath":"entities/index.md"}'),n={name:"entities/index.md"},e=t("",19),h=[e];function l(p,k,r,d,o,g){return a(),i("div",null,h)}const y=s(n,[["render",l]]);export{E as __pageData,y as default}; diff --git a/assets/getting_started_index.md._XNrAxOH.js b/assets/getting_started_index.md._XNrAxOH.js new file mode 100644 index 00000000..05444aa7 --- /dev/null +++ b/assets/getting_started_index.md._XNrAxOH.js @@ -0,0 +1,72 @@ +import{_ as s,c as i,o as a,U as n}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"getting_started/index.md","filePath":"getting_started/index.md"}'),t={name:"getting_started/index.md"},e=n(`

Getting Started

Install

npm

bash
pnpm add @jmondi/oauth2-server
bash
npm install --save @jmondi/oauth2-server
bash
yarn add @jmondi/oauth2-server

The Authorization Server

The AuthorizationServer depends on the repositories. By default, no grants are enabled; each grant is opt-in and must be enabled when creating the AuthorizationServer.

You can enable any grant types you would like to support.

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  "secret-key",
+  {} // optional configuration
+);
+authorizationServer.enableGrantType("client_credentials");
+authorizationServer.enableGrantType("refresh_token");
+authorizationServer.enableGrantType({
+  grant: "authorization_code",
+  userRepository, 
+  authorizationCodeRepository,
+});

See the configuration documentation for a full list of config options.

The Token Endpoint

The /token endpoint is a back channel endpoint that issues a usable access token.

typescript
app.post("/token", async (req: Express.Request, res: Express.Response) => {
+  try {
+    const oauthResponse = await authorizationServer.respondToAccessTokenRequest(req);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+    return;
+  }
+});

The Authorize Endpoint

The /authorize endpoint is a front channel endpoint that issues an authorization code. The authorization code can then be exchanged to the AuthorizationServer endpoint for a useable access token.

The endpoint should redirect the user to login, and then to accept the scopes requested by the application, and only when the user accepts, should it send the user back to the clients redirect uri.

typescript
import { requestFromExpress } from "@jmondi/oauth2-server/express";
+
+app.get("/authorize", async (req: Express.Request, res: Express.Response) => {
+  try {
+    // Validate the HTTP request and return an AuthorizationRequest.
+    const authRequest = await authorizationServer.validateAuthorizationRequest(request, requestFromExpress(req));
+
+    // You will probably redirect the user to a login endpoint. 
+    if (!req.user) {
+      req.redirect("/login")
+      return;
+    }
+    // After login, the user should be redirected back with user in the session.
+    // You will need to manage the authorization query on the round trip.
+    // The auth request object can be serialized and saved into a user's session.
+
+    // Once the user has logged in set the user on the AuthorizationRequest
+    authRequest.user = req.user;
+    
+    // Once the user has approved or denied the client update the status
+    // (true = approved, false = denied)
+    authRequest.isAuthorizationApproved = getIsAuthorizationApprovedFromSession();
+
+    // If the user has not approved the client's authorization request, 
+    // the user should be redirected to the approval screen.
+    if (!authRequest.isAuthorizationApproved) {
+      // This form will ask the user to approve the client and the scopes requested.
+      // "Do you authorize Jason to: read contacts? write contacts?"
+      req.redirect("/scopes")
+      return;
+    }
+
+    // At this point the user has approved the client for authorization.
+    // Any last authorization requests such as Two Factor Authentication (2FA) can happen here.
+
+
+    // Redirect back to redirect_uri with \`code\` and \`state\` as url query params.
+    const oauthResponse = await authorizationServer.completeAuthorizationRequest(authRequest);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+  }
+});

Revoke Token

Note

Implementing this endpoint is optional, but recommended. RFC7009 “OAuth 2.0 Token Revocation”

The /token/revoke endpoint is a back channel endpoint that revokes an existing token.

typescript
app.post("/token/revoke", async (req: Express.Request, res: Express.Response) => {
+  try {
+    const oauthResponse = await authorizationServer.revoke(req);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+    return;
+  }
+});
`,20),h=[e];function p(l,k,r,d,E,o){return a(),i("div",null,h)}const y=s(t,[["render",p]]);export{c as __pageData,y as default}; diff --git a/assets/getting_started_index.md._XNrAxOH.lean.js b/assets/getting_started_index.md._XNrAxOH.lean.js new file mode 100644 index 00000000..f15a9c31 --- /dev/null +++ b/assets/getting_started_index.md._XNrAxOH.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,U as n}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"getting_started/index.md","filePath":"getting_started/index.md"}'),t={name:"getting_started/index.md"},e=n("",20),h=[e];function p(l,k,r,d,E,o){return a(),i("div",null,h)}const y=s(t,[["render",p]]);export{c as __pageData,y as default}; diff --git a/assets/glossary_index.md.ThoJe1Xe.js b/assets/glossary_index.md.ThoJe1Xe.js new file mode 100644 index 00000000..42c40012 --- /dev/null +++ b/assets/glossary_index.md.ThoJe1Xe.js @@ -0,0 +1 @@ +import{_ as a,c as r,k as e,a as s,t as o,U as n,o as i}from"./chunks/framework.XQuvpNW4.js";const x=JSON.parse('{"title":"Glossary","description":"","frontmatter":{"title":"Glossary"},"headers":[],"relativePath":"glossary/index.md","filePath":"glossary/index.md"}'),c={name:"glossary/index.md"},l={id:"frontmatter-title",tabindex:"-1"},h=e("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),d=n('

Resource Server

The resource server is the OAuth 2.0 term for your API server. The resource server handles authenticated requests after the client has obtained an access token.

Client

The application attempting to gain access to the resource server. The client must have an OAuthClient

',4);function _(t,u,m,p,f,v){return i(),r("div",null,[e("h1",l,[s(o(t.$frontmatter.title)+" ",1),h]),d])}const y=a(c,[["render",_]]);export{x as __pageData,y as default}; diff --git a/assets/glossary_index.md.ThoJe1Xe.lean.js b/assets/glossary_index.md.ThoJe1Xe.lean.js new file mode 100644 index 00000000..cbeb099e --- /dev/null +++ b/assets/glossary_index.md.ThoJe1Xe.lean.js @@ -0,0 +1 @@ +import{_ as a,c as r,k as e,a as s,t as o,U as n,o as i}from"./chunks/framework.XQuvpNW4.js";const x=JSON.parse('{"title":"Glossary","description":"","frontmatter":{"title":"Glossary"},"headers":[],"relativePath":"glossary/index.md","filePath":"glossary/index.md"}'),c={name:"glossary/index.md"},l={id:"frontmatter-title",tabindex:"-1"},h=e("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),d=n("",4);function _(t,u,m,p,f,v){return i(),r("div",null,[e("h1",l,[s(o(t.$frontmatter.title)+" ",1),h]),d])}const y=a(c,[["render",_]]);export{x as __pageData,y as default}; diff --git a/assets/grants_authorization_code.md.NywG-h7F.js b/assets/grants_authorization_code.md.NywG-h7F.js new file mode 100644 index 00000000..b8fb8c41 --- /dev/null +++ b/assets/grants_authorization_code.md.NywG-h7F.js @@ -0,0 +1,50 @@ +import{_ as i,c as s,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const y=JSON.parse('{"title":"Authorization Code Grant (w/ PKCE)","description":"","frontmatter":{},"headers":[],"relativePath":"grants/authorization_code.md","filePath":"grants/authorization_code.md"}'),l={name:"grants/authorization_code.md"},h=t(`

Authorization Code Grant (w/ PKCE)

A temporary code that the client will exchange for an access token. The user authorizes the application, they are redirected back to the application with a temporary code in the URL. The application exchanges that code for the access token.

Flow

Part One

The client redirects the user to the /authorize with the following query parameters:

  • response_type must be set to code
  • client_id is the client identifier you received when you first created the application
  • redirect_uri indicates the URL to return the user to after authorization is complete, such as org.example.app://redirect
  • state is a random string generated by your application, which you’ll verify later
  • code_challenge must match the The code challenge as generated below,
  • code_challenge_method – Either plain or S256, depending on whether the challenge is the plain verifier string or the SHA256 hash of the string. If this parameter is omitted, the server will assume plain.

TIP

The client secret should never be used during the Part One of the authorization_code flow.

View sample authorization_code (part 1) request
http
GET /authorize HTTP/1.1
+Host: example.com
+
+response_type=code
+&client_id=xxxxxxx
+&redirect_uri=http://localhost
+&scope="contacts.read contacts.write"
+&state=abcdefghijklmnopqrstuvwxyz123456789
+&code_challenge=92d3b56942866d1edf02c33339b7c3dc37c6201282bb238cb47f0d3289f28a93f1bdd8af6ca9913aed0c4c
+&code_challenge_method=S256

The user will be asked to login to the authorization server and approve the client and requested scopes.

If the user approves the client, they will be redirected from the authorization server to the provided redirect_uri with the following fields in the query string:

  • code is the authorization code that will soon be exchanged for a token
  • state is the random string provided and should be compared against the initially provided state
View sample authorization_code (part 1) response
http
HTTP/1.1 302 Found
+Location: http://localhost&code=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3QiLCJhdXRoX2NvZGVfaWQiOiJteS1zdXBlci1zZWNyZXQtYXV0aC1jb2RlIiwic2NvcGVzIjpbXSwiZXhwaXJlX3RpbWUiOjE2MDE3NTM3MzMsImNvZGVfY2hhbGxlbmdlIjoiT0RRd1pHTTRZelpsTnpNeU1qUXlaREF4WWpFNU1XWmtZMlJrTmpKbU1UbGxNbUkwTnpJMFpEbGtNR0psWWpGbE1tTXhPV1kyWkRJMVpEZGpNak13WWciLCJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2In0.OIEtZN5BHNaB4Mz0plUpGAP93EHyoil2smJiG3S_2BM&state=abcdefghijklmnopqrstuvwxyz123456789

Part Two

The client sends a POST to the /token endpoint with the following body:

  • grant_type must be set to authorization_code
  • client_id is the client identifier you received when you first created the application
  • client_secret (optional) is the client secret and should only be provided if the client is confidential
  • redirect_uri
  • code_verifier
  • code is the authorization code from the query string

Private Key Leak Potential

Clients such as Browser Based Apps and Native Mobile Apps should NEVER have or use a client_secret. That means the client_secret should be omitted both when initially creating the OAuthClient entity, and when making requests.

View sample authorization_code (part 2) request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=authorization_code
+&client_id=xxxxxxxxxx
+&client_secret=xxxxxxxxxx
+&redirect_uri=http://localhost
+&code_verifier=OTJkM2I1Njk0Mjg2NmQxZWRmMDJjMzMzMzliN2MzZGMzN2M2MjAxMjgyYmIyMzhjYjQ3ZjBkMzI4OWYyOGE5M2YxYmRkOGFmNmNhOTkxM2FlZDBjNGM
+&code=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3QiLCJhdXRoX2NvZGVfaWQiOiJteS1zdXBlci1zZWNyZXQtYXV0aC1jb2RlIiwic2NvcGVzIjpbXSwiZXhwaXJlX3RpbWUiOjE2MDE3NTM3MzMsImNvZGVfY2hhbGxlbmdlIjoiT0RRd1pHTTRZelpsTnpNeU1qUXlaREF4WWpFNU1XWmtZMlJrTmpKbU1UbGxNbUkwTnpJMFpEbGtNR0psWWpGbE1tTXhPV1kyWkRJMVpEZGpNak13WWciLCJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2In0.OIEtZN5BHNaB4Mz0plUpGAP93EHyoil2smJiG3S_2BM

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample authorization_code (part 2) response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE3NTUxMDQsIm5iZiI6MTYwMTc1MTUwNCwiaWF0IjoxNjAxNzUxNTA0LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGF1dGggY29kZSBjbGllbnQiLCJzY29wZSI6IiJ9.-V9x03iz-3ISRMdj9m1-FCKjmtfjvv6wqnBj6VZdW28',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsImFjY2Vzc190b2tlbl9pZCI6Im5ldyB0b2tlbiIsInJlZnJlc2hfdG9rZW5faWQiOiJ0aGlzLWlzLW15LXN1cGVyLXNlY3JldC1yZWZyZXNoLXRva2VuIiwic2NvcGUiOiIiLCJleHBpcmVfdGltZSI6MTYwMTc1NTEwNCwiaWF0IjoxNjAxNzUxNTAzfQ.J_RUFD5-158atTmI98R95vowZWi4mUEXYCO7iNwzpK4',
+  scope: 'contacts.read contacts.write'
+}

PKCE

PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent several attacks and to be able to securely perform the OAuth exchange from public clients.

By default, PKCE is enabled and encouraged for all users. If you need to support a legacy client system without PKCE, you can disable PKCE with the authorization server using the requiresPKCE configuration option.

Code Verifier

The code_verifier is part of the extended “PKCE” and helps mitigate the threat of having authorization codes intercepted.

Before initializing Part One of the authorization code flow, the client first creats a code_verifier. This is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

We can do this in Node using the native crypto package and a base64urlencode function:

typescript
import crypto from "node:crypto";
+
+const code_verifier = crypto.randomBytes(43).toString("hex");

@see https://www.oauth.com/oauth2-servers/pkce/authorization-request/

Code Challenge

Now we need to create a code_challenge from our code_verifier.

For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.

typescript
const code_challenge = base64urlencode(
+  crypto.createHash("sha256")
+    .update(code_verifier)
+    .digest()
+);

Clients that do not have the ability to perform a SHA256 hash are permitted to use the plain code_verifier string as the code_challenge.

typescript
const code_challenge = code_verifier;
Need a base64urlencode function?
typescript
function base64urlencode(str: string) {
+  return Buffer.from(str)
+    .toString("base64")
+    .replace(/\\+/g, "-")
+    .replace(/\\//g, "_")
+    .replace(/=/g, "");
+}

Revocation

Authorization codes are only valid for a single use. In addition, they can be explicitly revoked on a server that supports RFC7009 “OAuth 2.0 Token Revocation”.

An authorization code revocation request will include the following parameters:

  • token is the authorization code previously issued to the client
  • token_type_hint (optional) should be set to authorization_code
View sample revoke authorization_code request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+token_type_hint=authorization_code
+&refresh_token=xxxxxxxxx

The authorization server will respond with the following response

View sample revoke authorization_code response
http
HTTP/1.1 200 OK
+Cache-Control: no-store
+Pragma: no-cache
`,43),e=[h];function n(k,p,r,o,d,c){return a(),s("div",null,e)}const E=i(l,[["render",n]]);export{y as __pageData,E as default}; diff --git a/assets/grants_authorization_code.md.NywG-h7F.lean.js b/assets/grants_authorization_code.md.NywG-h7F.lean.js new file mode 100644 index 00000000..5d7c13ad --- /dev/null +++ b/assets/grants_authorization_code.md.NywG-h7F.lean.js @@ -0,0 +1 @@ +import{_ as i,c as s,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const y=JSON.parse('{"title":"Authorization Code Grant (w/ PKCE)","description":"","frontmatter":{},"headers":[],"relativePath":"grants/authorization_code.md","filePath":"grants/authorization_code.md"}'),l={name:"grants/authorization_code.md"},h=t("",43),e=[h];function n(k,p,r,o,d,c){return a(),s("div",null,e)}const E=i(l,[["render",n]]);export{y as __pageData,E as default}; diff --git a/assets/grants_client_credentials.md.WBW6QGI4.js b/assets/grants_client_credentials.md.WBW6QGI4.js new file mode 100644 index 00000000..46dfff84 --- /dev/null +++ b/assets/grants_client_credentials.md.WBW6QGI4.js @@ -0,0 +1,23 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Client Credentials Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/client_credentials.md","filePath":"grants/client_credentials.md"}'),l={name:"grants/client_credentials.md"},n=a(`

Client Credentials Grant

When applications request an access token to access their own resources, not on behalf of a user.

TIP

The client_credentials grant should only be used by clients that can hold a secret. No Browser or Native Mobile Apps should be using this grant.

Flow

The client sends a POST to the /token endpoint with the following body:

  • grant_type must be set to client_credentials
  • client_id is the client identifier you received when you first created the application
  • client_secret is the client secret
  • scope is a string with a space delimited list of requested scopes. The requested scopes must be valid for the client.
View sample client_credentials request

Did you know? You can authenticate by passing the client_id and client_secret as a query string, or through basic auth.

http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=client_credentials
+&client_id=xxxxxxxxxx
+&client_secret=xxxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic MTpzdXBlci1zZWNyZXQtc2VjcmV0
+
+grant_type=client_credentials
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response.

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and can be used to authenticate into the resource server
  • scope is a space delimited list of scopes the token has access to
View sample client_credentials response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+ 
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE3MDY0NjYsIm5iZiI6MTYwMTcwMjg2NiwiaWF0IjoxNjAxNzAyODY2LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.KcXoCP6u9uhvtOoistLBskESA0tyT2I1SDe5Yn9iM4I',
+  scope: 'contacts.create contacts.read'
+}
`,10),e=[n];function h(k,p,r,c,d,o){return t(),s("div",null,e)}const F=i(l,[["render",h]]);export{g as __pageData,F as default}; diff --git a/assets/grants_client_credentials.md.WBW6QGI4.lean.js b/assets/grants_client_credentials.md.WBW6QGI4.lean.js new file mode 100644 index 00000000..2dcd6b2f --- /dev/null +++ b/assets/grants_client_credentials.md.WBW6QGI4.lean.js @@ -0,0 +1 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Client Credentials Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/client_credentials.md","filePath":"grants/client_credentials.md"}'),l={name:"grants/client_credentials.md"},n=a("",10),e=[n];function h(k,p,r,c,d,o){return t(),s("div",null,e)}const F=i(l,[["render",h]]);export{g as __pageData,F as default}; diff --git a/assets/grants_implicit.md.A2UquZbS.js b/assets/grants_implicit.md.A2UquZbS.js new file mode 100644 index 00000000..2cfdac0c --- /dev/null +++ b/assets/grants_implicit.md.A2UquZbS.js @@ -0,0 +1 @@ +import{_ as t,c as e,o as a,U as i}from"./chunks/framework.XQuvpNW4.js";const u=JSON.parse('{"title":"Implicit Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/implicit.md","filePath":"grants/implicit.md"}'),r={name:"grants/implicit.md"},o=i('

Implicit Grant

Not Recommended

Using the Implicit Grant is no longer best practice

This grant is supported, but not documented. Industry best practice recommends using the Authorization Code Grant without a client secret for native and browser-based apps.

Please look at these great resources:

',5),l=[o];function c(n,s,p,m,d,h){return a(),e("div",null,l)}const f=t(r,[["render",c]]);export{u as __pageData,f as default}; diff --git a/assets/grants_implicit.md.A2UquZbS.lean.js b/assets/grants_implicit.md.A2UquZbS.lean.js new file mode 100644 index 00000000..01619ce1 --- /dev/null +++ b/assets/grants_implicit.md.A2UquZbS.lean.js @@ -0,0 +1 @@ +import{_ as t,c as e,o as a,U as i}from"./chunks/framework.XQuvpNW4.js";const u=JSON.parse('{"title":"Implicit Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/implicit.md","filePath":"grants/implicit.md"}'),r={name:"grants/implicit.md"},o=i("",5),l=[o];function c(n,s,p,m,d,h){return a(),e("div",null,l)}const f=t(r,[["render",c]]);export{u as __pageData,f as default}; diff --git a/assets/grants_index.md.Wp7i96iB.js b/assets/grants_index.md.Wp7i96iB.js new file mode 100644 index 00000000..ebcf8ddc --- /dev/null +++ b/assets/grants_index.md.Wp7i96iB.js @@ -0,0 +1,39 @@ +import{_ as s,c as e,k as a,a as t,t as p,U as i,o as r}from"./chunks/framework.XQuvpNW4.js";const m=JSON.parse('{"title":"Which Grant?","description":"","frontmatter":{"title":"Which Grant?"},"headers":[],"relativePath":"grants/index.md","filePath":"grants/index.md"}'),l={name:"grants/index.md"},c={id:"frontmatter-title",tabindex:"-1"},o=a("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),h=i(`

Grants are different ways a client can obtain an access_token that will authorize it to use the resource server.

Deciding which grant to use depends on the type of client the end user will be using.

+-------+
+| Start |
++-------+
+    V
+    |
+    
+    |
++------------------------+              +-----------------------+
+| Have a refresh token?  |>----Yes----->|  Refresh Token Grant  |
++------------------------+              +-----------------------+
+    V
+    |
+    No
+    |
++---------------------+                
+|     Who is the      |                  +--------------------------+
+| Access token owner? |>---A Machine---->| Client Credentials Grant |
++---------------------+                  +--------------------------+
+    V
+    |
+    |
+   A User
+    |
+    |
++----------------------+                
+| What type of client? |   
++----------------------+     
+    |
+    |                                 +---------------------------+
+    |>-----------Server App---------->| Auth Code Grant with PKCE |
+    |                                 +---------------------------+
+    |
+    |                                 +---------------------------+
+    |>-------Browser Based App------->| Auth Code Grant with PKCE |
+    |                                 +---------------------------+
+    |
+    |                                 +---------------------------+
+    |>-------Native Mobile App------->| Auth Code Grant with PKCE |
+                                      +---------------------------+

Refresh Token Grant

If the client already has a refresh token, it can use the Refresh Token Grant to obtain a new access token without requiring the user's interaction. This grant is useful for long-lived sessions and background processes.

Client Credentials Grant

If the access token owner is a machine, such as a server or an application acting on its own behalf, rather than an individual user, the client can use the Client Credentials Grant. This grant is designed for scenarios where the client needs to access resources autonomously without the context of a specific user.

Auth Code Grant with PKCE

If the access token owner is a user, the recommended grant is the Authorization Code Grant with Proof Key for Code Exchange (PKCE). This grant involves a series of steps where the client redirects the user to the authorization server, the user grants access, and the server provides an authorization code that the client exchanges for an access token. PKCE adds an extra layer of security to protect against authorization code interception attacks.

`,9);function d(n,u,g,f,_,k){return r(),e("div",null,[a("h1",c,[t(p(n.$frontmatter.title)+" ",1),o]),h])}const w=s(l,[["render",d]]);export{m as __pageData,w as default}; diff --git a/assets/grants_index.md.Wp7i96iB.lean.js b/assets/grants_index.md.Wp7i96iB.lean.js new file mode 100644 index 00000000..c72c6944 --- /dev/null +++ b/assets/grants_index.md.Wp7i96iB.lean.js @@ -0,0 +1 @@ +import{_ as s,c as e,k as a,a as t,t as p,U as i,o as r}from"./chunks/framework.XQuvpNW4.js";const m=JSON.parse('{"title":"Which Grant?","description":"","frontmatter":{"title":"Which Grant?"},"headers":[],"relativePath":"grants/index.md","filePath":"grants/index.md"}'),l={name:"grants/index.md"},c={id:"frontmatter-title",tabindex:"-1"},o=a("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),h=i("",9);function d(n,u,g,f,_,k){return r(),e("div",null,[a("h1",c,[t(p(n.$frontmatter.title)+" ",1),o]),h])}const w=s(l,[["render",d]]);export{m as __pageData,w as default}; diff --git a/assets/grants_password.md.cVz9lIu2.js b/assets/grants_password.md.cVz9lIu2.js new file mode 100644 index 00000000..841cbf4f --- /dev/null +++ b/assets/grants_password.md.cVz9lIu2.js @@ -0,0 +1,28 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Password Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/password.md","filePath":"grants/password.md"}'),l={name:"grants/password.md"},h=a(`

Password Grant

The Password Grant is for first party clients that are able to hold secrets (ie not Browser or Native Mobile Apps)

TIP

The client_credentials grant should only be used by clients that can hold a secret

Flow

A complete refresh token request will include the following parameters:

  • grant_type must be set to password
  • client_id is the client identifier you received when you first created the application
  • client_secret if the client is confidential (has a secret), this must be provided
  • username
  • password
  • scope (optional)
View sample password grant request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password
+&client_id=xxxxxxxxx
+&client_secret=xxxxxxxxx
+&username=xxxxxxxxx
+&password=xxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN
+
+grant_type=password
+&username=xxxxxxxxx
+&password=xxxxxxxxx
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample password grant response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyOTksIm5iZiI6MTYwMTc2MzY5OSwiaWF0IjoxNjAxNzYzNjk5LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.sX6SWc2Af8jn-izFnrLgNIcNuZz_tRLl2p7M3CzQwKg',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3Mjk5LCJpYXQiOjE2MDE3NjM2OTh9.SSa7miIdk3bxyzg0f3M9jKBXWjPgD4QEw-AU3SYvBk0',
+  scope: 'contacts.read contacts.write'
+}
`,10),k=[h];function n(e,p,r,y,d,g){return t(),s("div",null,k)}const F=i(l,[["render",n]]);export{c as __pageData,F as default}; diff --git a/assets/grants_password.md.cVz9lIu2.lean.js b/assets/grants_password.md.cVz9lIu2.lean.js new file mode 100644 index 00000000..f295d103 --- /dev/null +++ b/assets/grants_password.md.cVz9lIu2.lean.js @@ -0,0 +1 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Password Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/password.md","filePath":"grants/password.md"}'),l={name:"grants/password.md"},h=a("",10),k=[h];function n(e,p,r,y,d,g){return t(),s("div",null,k)}const F=i(l,[["render",n]]);export{c as __pageData,F as default}; diff --git a/assets/grants_refresh_token.md.5g7Gdlsd.js b/assets/grants_refresh_token.md.5g7Gdlsd.js new file mode 100644 index 00000000..a4330d9f --- /dev/null +++ b/assets/grants_refresh_token.md.5g7Gdlsd.js @@ -0,0 +1,34 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Refresh Token Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/refresh_token.md","filePath":"grants/refresh_token.md"}'),l={name:"grants/refresh_token.md"},h=a(`

Refresh Token Grant

Access tokens eventually expire. The refresh token grant enables the client to obtain a new access_token from an existing refresh_token.

Flow

A complete refresh token request will include the following parameters:

  • grant_type must be set to refresh_token
  • client_id is the client identifier you received when you first created the application
  • client_secret if the client is confidential (has a secret), this must be provided
  • refresh_token must be the signed token previously issued to the client
  • scope (optional) the requested scope must not include any additional scopes that were not previously issued to the original token
View sample refresh_token request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=refresh_token
+&refresh_token=xxxxxxxxx
+&client_id=xxxxxxxxx
+&client_secret=xxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=refresh_token
+&refresh_token=xxxxxxxxx
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample refresh_token response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyMTIsIm5iZiI6MTYwMTc2MzYxMiwiaWF0IjoxNjAxNzYzNjEyLCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.PO4eKSDVsFuKvebEXndWbZsprgzjkzEfHI7cl4N0YpM',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3MjEyLCJpYXQiOjE2MDE3NjM2MTF9.du4KfAzelSA8hzBaqGlrSvPtH-BxOcoUBXW4HS3pJkM',
+  scope: 'contacts.read contacts.write'
+}

Revocation

Refresh tokens are only valid for a single use. In addition, they can be explicitly revoked on a server that supports RFC7009 “OAuth 2.0 Token Revocation”.

A refresh token revocation request will include the following parameters:

  • token is the signed token previously issued to the client
  • token_type_hint (optional) should be set to refresh_token
View sample revoke refresh_token request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+token_type_hint=refresh_token
+&refresh_token=xxxxxxxxx

The authorization server will respond with the following response

View sample revoke refresh_token response
http
HTTP/1.1 200 OK
+Cache-Control: no-store
+Pragma: no-cache
`,16),k=[h];function n(e,p,r,d,o,y){return t(),s("div",null,k)}const F=i(l,[["render",n]]);export{c as __pageData,F as default}; diff --git a/assets/grants_refresh_token.md.5g7Gdlsd.lean.js b/assets/grants_refresh_token.md.5g7Gdlsd.lean.js new file mode 100644 index 00000000..62ecc1f9 --- /dev/null +++ b/assets/grants_refresh_token.md.5g7Gdlsd.lean.js @@ -0,0 +1 @@ +import{_ as i,c as s,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const c=JSON.parse('{"title":"Refresh Token Grant","description":"","frontmatter":{},"headers":[],"relativePath":"grants/refresh_token.md","filePath":"grants/refresh_token.md"}'),l={name:"grants/refresh_token.md"},h=a("",16),k=[h];function n(e,p,r,d,o,y){return t(),s("div",null,k)}const F=i(l,[["render",n]]);export{c as __pageData,F as default}; diff --git a/assets/index.md.U7wYHgJ-.js b/assets/index.md.U7wYHgJ-.js new file mode 100644 index 00000000..b1b7529f --- /dev/null +++ b/assets/index.md.U7wYHgJ-.js @@ -0,0 +1 @@ +import{_ as e,c as r,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const _=JSON.parse('{"title":"TypeScript OAuth2.0 Server","description":"","frontmatter":{},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),o={name:"index.md"},i=a('

TypeScript OAuth2.0 Server

🇺🇦 Support Ukraine 🇺🇦

@jmondi/oauth2-server is a standards compliant implementation of an OAuth 2.0 authorization server for Node, written in TypeScript.

Requires node >= 16

Out of the box it supports the following grants:

The following RFCs are implemented:

',8),n=[i];function l(s,h,p,c,f,d){return t(),r("div",null,n)}const g=e(o,[["render",l]]);export{_ as __pageData,g as default}; diff --git a/assets/index.md.U7wYHgJ-.lean.js b/assets/index.md.U7wYHgJ-.lean.js new file mode 100644 index 00000000..8a80d605 --- /dev/null +++ b/assets/index.md.U7wYHgJ-.lean.js @@ -0,0 +1 @@ +import{_ as e,c as r,o as t,U as a}from"./chunks/framework.XQuvpNW4.js";const _=JSON.parse('{"title":"TypeScript OAuth2.0 Server","description":"","frontmatter":{},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),o={name:"index.md"},i=a("",8),n=[i];function l(s,h,p,c,f,d){return t(),r("div",null,n)}const g=e(o,[["render",l]]);export{_ as __pageData,g as default}; diff --git a/assets/inter-italic-cyrillic-ext.OVycGSDq.woff2 b/assets/inter-italic-cyrillic-ext.OVycGSDq.woff2 new file mode 100644 index 00000000..2a687296 Binary files /dev/null and b/assets/inter-italic-cyrillic-ext.OVycGSDq.woff2 differ diff --git a/assets/inter-italic-cyrillic.-nLMcIwj.woff2 b/assets/inter-italic-cyrillic.-nLMcIwj.woff2 new file mode 100644 index 00000000..f6403515 Binary files /dev/null and b/assets/inter-italic-cyrillic.-nLMcIwj.woff2 differ diff --git a/assets/inter-italic-greek-ext.hznxWNZO.woff2 b/assets/inter-italic-greek-ext.hznxWNZO.woff2 new file mode 100644 index 00000000..00218960 Binary files /dev/null and b/assets/inter-italic-greek-ext.hznxWNZO.woff2 differ diff --git a/assets/inter-italic-greek.PSfer2Kc.woff2 b/assets/inter-italic-greek.PSfer2Kc.woff2 new file mode 100644 index 00000000..71c265f8 Binary files /dev/null and b/assets/inter-italic-greek.PSfer2Kc.woff2 differ diff --git a/assets/inter-italic-latin-ext.RnFly65-.woff2 b/assets/inter-italic-latin-ext.RnFly65-.woff2 new file mode 100644 index 00000000..9c1b9440 Binary files /dev/null and b/assets/inter-italic-latin-ext.RnFly65-.woff2 differ diff --git a/assets/inter-italic-latin.27E69YJn.woff2 b/assets/inter-italic-latin.27E69YJn.woff2 new file mode 100644 index 00000000..01fcf207 Binary files /dev/null and b/assets/inter-italic-latin.27E69YJn.woff2 differ diff --git a/assets/inter-italic-vietnamese.xzQHe1q1.woff2 b/assets/inter-italic-vietnamese.xzQHe1q1.woff2 new file mode 100644 index 00000000..e4f788ee Binary files /dev/null and b/assets/inter-italic-vietnamese.xzQHe1q1.woff2 differ diff --git a/assets/inter-roman-cyrillic-ext.8T9wMG5w.woff2 b/assets/inter-roman-cyrillic-ext.8T9wMG5w.woff2 new file mode 100644 index 00000000..28593ccb Binary files /dev/null and b/assets/inter-roman-cyrillic-ext.8T9wMG5w.woff2 differ diff --git a/assets/inter-roman-cyrillic.jIZ9REo5.woff2 b/assets/inter-roman-cyrillic.jIZ9REo5.woff2 new file mode 100644 index 00000000..a20adc16 Binary files /dev/null and b/assets/inter-roman-cyrillic.jIZ9REo5.woff2 differ diff --git a/assets/inter-roman-greek-ext.9JiNzaSO.woff2 b/assets/inter-roman-greek-ext.9JiNzaSO.woff2 new file mode 100644 index 00000000..e3b0be76 Binary files /dev/null and b/assets/inter-roman-greek-ext.9JiNzaSO.woff2 differ diff --git a/assets/inter-roman-greek.Cb5wWeGA.woff2 b/assets/inter-roman-greek.Cb5wWeGA.woff2 new file mode 100644 index 00000000..f790e047 Binary files /dev/null and b/assets/inter-roman-greek.Cb5wWeGA.woff2 differ diff --git a/assets/inter-roman-latin-ext.GZWE-KO4.woff2 b/assets/inter-roman-latin-ext.GZWE-KO4.woff2 new file mode 100644 index 00000000..715bd903 Binary files /dev/null and b/assets/inter-roman-latin-ext.GZWE-KO4.woff2 differ diff --git a/assets/inter-roman-latin.bvIUbFQP.woff2 b/assets/inter-roman-latin.bvIUbFQP.woff2 new file mode 100644 index 00000000..a540b7af Binary files /dev/null and b/assets/inter-roman-latin.bvIUbFQP.woff2 differ diff --git a/assets/inter-roman-vietnamese.paY3CzEB.woff2 b/assets/inter-roman-vietnamese.paY3CzEB.woff2 new file mode 100644 index 00000000..5a9f9cb9 Binary files /dev/null and b/assets/inter-roman-vietnamese.paY3CzEB.woff2 differ diff --git a/assets/migration_v2_to_v3.md.m7zLJwap.js b/assets/migration_v2_to_v3.md.m7zLJwap.js new file mode 100644 index 00000000..930c5ab8 --- /dev/null +++ b/assets/migration_v2_to_v3.md.m7zLJwap.js @@ -0,0 +1,28 @@ +import{_ as s,c as i,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Migrating from v2 to v3","description":"","frontmatter":{},"headers":[],"relativePath":"migration/v2_to_v3.md","filePath":"migration/v2_to_v3.md"}'),e={name:"migration/v2_to_v3.md"},n=t(`

Migrating from v2 to v3

Upgrade Time Estimate: ESM? 10 minutes; no-ESM? Varies

This package is now pure ESM

The package is now entirely ESM (ECMAScript Modules). More details about this change can be found in Sindre Sorhus's writeup.

AuthorizationServer Updates

In v2.x, AuthorizationServer constructor required all repositories. In v3.x, it has been simplified.

Before (v2.x):

typescript
const authorizationServer = new AuthorizationServer(
+  authCodeRepository,
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  userRepository,
+  jwtService,
+  {
+    requiresS256: false, 
+    tokenCID: "name",
+  }
+);

After (v3.x):

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  new JwtService("secret-key"),
+  {
+    requiresS256: true,  
+    tokenCID: "id",
+  }
+);

Enabling Grants

In v3, enableGrantType has been updated for the "authorization_code" and "password" grants.

Authorization Code Grant

AuthorizationCodeGrant now requires a AuthorizationCodeRepository and a UserRepository.

Before (v2.x):

typescript
authorizationServer.enableGrantType("authorization_code");

After (v3.x):

typescript
authorizationServer.enableGrantType({
+  grant: "authorization_code",
+  userRepository, 
+  authorizationCodeRepository,
+});

Password Grant

PasswordGrant now requires a UserRepository.

Before (v2.x):

typescript
authorizationServer.enableGrantType("password");

After (v3.x):

typescript
authorizationServer.enableGrantType({
+  grant: "password",
+  userRepository, 
+});

AuthorizationServerOptions Default Configuration Updates

The default options for AuthorizationServer have been modified to better align with the OAuth 2.0 specification:

Optionv2.x Valuev3.x Value
requiresS256falsetrue
tokenCID"name""id"

Removed setOptions Method

The undocumented, public method setOptions has been removed in v3. Options can be set during AuthorizationServer initialization.

generateRandomToken Function Fix

A bug in the generateRandomToken function has been fixed in v3.x.

`,32),o=[n];function r(p,h,l,d,k,c){return a(),i("div",null,o)}const u=s(e,[["render",r]]);export{g as __pageData,u as default}; diff --git a/assets/migration_v2_to_v3.md.m7zLJwap.lean.js b/assets/migration_v2_to_v3.md.m7zLJwap.lean.js new file mode 100644 index 00000000..86edf09f --- /dev/null +++ b/assets/migration_v2_to_v3.md.m7zLJwap.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,U as t}from"./chunks/framework.XQuvpNW4.js";const g=JSON.parse('{"title":"Migrating from v2 to v3","description":"","frontmatter":{},"headers":[],"relativePath":"migration/v2_to_v3.md","filePath":"migration/v2_to_v3.md"}'),e={name:"migration/v2_to_v3.md"},n=t("",32),o=[n];function r(p,h,l,d,k,c){return a(),i("div",null,o)}const u=s(e,[["render",r]]);export{g as __pageData,u as default}; diff --git a/assets/repositories_index.md.mkPMphhv.js b/assets/repositories_index.md.mkPMphhv.js new file mode 100644 index 00000000..ab8ca972 --- /dev/null +++ b/assets/repositories_index.md.mkPMphhv.js @@ -0,0 +1,94 @@ +import{_ as s,c as i,o as a,U as n}from"./chunks/framework.XQuvpNW4.js";const o=JSON.parse('{"title":"Repository Interfaces","description":"","frontmatter":{},"headers":[],"relativePath":"repositories/index.md","filePath":"repositories/index.md"}'),t={name:"repositories/index.md"},h=n(`

Repository Interfaces

Auth Code Repository

OAuthAuthCodeRepository interface is utilized for managing OAuth authorization codes. It contains methods for retrieving an authorization code entity by its identifier, issuing a new authorization code, persisting an authorization code in the storage, checking if an authorization code has been revoked, and revoking an authorization code.

typescript
interface OAuthAuthCodeRepository {
+
+  // Fetch auth code entity from storage by code
+  getByIdentifier(authCodeCode: string): Promise<OAuthAuthCode>;
+
+  // An async call that should return an OAuthAuthCode that has not been 
+  // persisted to storage yet.
+  issueAuthCode(
+    client: OAuthClient, 
+    user: OAuthUser | undefined, 
+    scopes: OAuthScope[]
+  ): OAuthAuthCode | Promise<OAuthAuthCode>;
+
+  // An async call that should persist an OAuthAuthCode into your storage.
+  persist(authCode: OAuthAuthCode): Promise<void>;
+
+  // This async method is called when an auth code is validated by the 
+  // authorization server. Return \`true\` if the auth code has been 
+  // manually revoked. If the code is still valid return \`false\`
+  isRevoked(authCodeCode: string): Promise<boolean>;
+
+  revoke(authCodeCode: string): Promise<void>;
+}

Client Repository

OAuthClientRepository interface is used for managing OAuth clients. It includes methods for fetching a client entity from storage by the client ID and for validating the client using the grant type and client secret.

typescript
interface OAuthClientRepository {
+  // Fetch client entity from storage by client_id
+  getByIdentifier(clientId: string): Promise<OAuthClient>;
+
+  // check the grant type and secret against the client
+  isClientValid(
+    grantType: GrantIdentifier, 
+    client: OAuthClient, 
+    clientSecret?: string
+  ): Promise<boolean>;
+}

Scope Repository

The OAuthScopeRepository interface handles scope management. It defines methods for finding all scopes by their names and for finalizing the scopes. In the finalization, additional scopes can be added or removed after they've been validated against the client scopes.

typescript
interface OAuthScopeRepository {
+  // Find all scopes by scope names
+  getAllByIdentifiers(scopeNames: string[]): Promise<OAuthScope[]>;
+
+  // Scopes have already been validated against the client, if you arent 
+  // doing anything fancy with scopes, you can just \`return scopes\`,
+  // Otherwise, now is your chance to add or remove any final scopes 
+  // after they have already been validated against the client scopes
+  finalize(
+    scopes: OAuthScope[],
+    identifier: GrantIdentifier,
+    client: OAuthClient,
+    user_id?: string,
+  ): Promise<OAuthScope[]>;
+}

Token Repository

OAuthTokenRepository interface manages OAuth tokens. It contains methods for issuing a new token, persisting a token in the storage, issuing a refresh token, revoking tokens, and fetching a refresh token entity by the refresh token.

typescript
interface OAuthTokenRepository {
+  // An async call that should return an OAuthToken that has not been 
+  // persisted to storage yet.
+  issueToken(
+    client: OAuthClient,
+    scopes: OAuthScope[],
+    user?: OAuthUser
+  ): Promise<OAuthToken>;
+
+  // An async call that should persist an OAuthToken into your storage.
+  persist(accessToken: OAuthToken): Promise<void>;
+
+  // An async call that enhances an already-persisted OAuthToken with
+  // refresh token fields.
+  issueRefreshToken(
+    accessToken: OAuthToken,
+    client: OAuthClient,
+  ): Promise<OAuthToken>
+
+  // This async method is called when a refresh token is used to reissue 
+  // an access token. The original access token is revoked, and a new
+  // access token is issued.
+  revoke(accessToken: OAuthToken): Promise<void>;
+
+  // This async method, if implemented, will be called by the authorization
+  // code grant if the original authorization code is reused.
+  // See https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2 for why.
+  revokeDescendantsOf?(authCodeId: string): Promise<void>;
+
+  // This async method is called when an access token is validated by the 
+  // authorization server. Return \`true\` if the access token has been 
+  // manually revoked. If the token is still valid return \`false\`
+  isRefreshTokenRevoked(refreshToken: OAuthToken): Promise<boolean>;
+
+  // Fetch refresh token entity from storage by refresh token
+  getByRefreshToken(refreshTokenToken: string): Promise<OAuthToken>;
+}

User Repository

The OAuthUserRepository interface handles user management. It defines methods for fetching a user entity from storage by their credentials and optional grant type and client. This may involve validating the user's credentials.

typescript
interface OAuthUserRepository {
+
+  // Fetch user entity from storage by identifier. A provided password may 
+  // be used to validate the users credentials. Grant type and client are provided
+  // for additional checks if desired
+  getUserByCredentials(
+    identifier: string,
+    password?: string,
+    grantType?: GrantIdentifier,
+    client?: OAuthClient,
+  ): Promise<OAuthUser | undefined>;
+}
`,16),e=[h];function l(k,p,r,d,y,g){return a(),i("div",null,e)}const c=s(t,[["render",l]]);export{o as __pageData,c as default}; diff --git a/assets/repositories_index.md.mkPMphhv.lean.js b/assets/repositories_index.md.mkPMphhv.lean.js new file mode 100644 index 00000000..470b2b3e --- /dev/null +++ b/assets/repositories_index.md.mkPMphhv.lean.js @@ -0,0 +1 @@ +import{_ as s,c as i,o as a,U as n}from"./chunks/framework.XQuvpNW4.js";const o=JSON.parse('{"title":"Repository Interfaces","description":"","frontmatter":{},"headers":[],"relativePath":"repositories/index.md","filePath":"repositories/index.md"}'),t={name:"repositories/index.md"},h=n("",16),e=[h];function l(k,p,r,d,y,g){return a(),i("div",null,e)}const c=s(t,[["render",l]]);export{o as __pageData,c as default}; diff --git a/assets/sources_index.md.nDiyFoDc.js b/assets/sources_index.md.nDiyFoDc.js new file mode 100644 index 00000000..27a6b11a --- /dev/null +++ b/assets/sources_index.md.nDiyFoDc.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,U as o}from"./chunks/framework.XQuvpNW4.js";const m=JSON.parse('{"title":"Sources","description":"","frontmatter":{},"headers":[],"relativePath":"sources/index.md","filePath":"sources/index.md"}'),s={name:"sources/index.md"},a=o('

Sources

This project was influenced by the PHP League OAuth2 Server and shares a lot of the same ideas.

https://github.com/thephpleague/oauth2-server

https://tools.ietf.org/html/rfc6749#section-4.4

https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/

https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/

https://tools.ietf.org/html/rfc6749#section-4.1

https://tools.ietf.org/html/rfc7009

https://tools.ietf.org/html/rfc7636

https://www.oauth.com/oauth2-servers/pkce/

https://www.oauth.com/oauth2-servers/pkce/authorization-request/

',11),h=[a];function c(n,p,l,f,i,u){return r(),t("div",null,h)}const d=e(s,[["render",c]]);export{m as __pageData,d as default}; diff --git a/assets/sources_index.md.nDiyFoDc.lean.js b/assets/sources_index.md.nDiyFoDc.lean.js new file mode 100644 index 00000000..9e128dbe --- /dev/null +++ b/assets/sources_index.md.nDiyFoDc.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as r,U as o}from"./chunks/framework.XQuvpNW4.js";const m=JSON.parse('{"title":"Sources","description":"","frontmatter":{},"headers":[],"relativePath":"sources/index.md","filePath":"sources/index.md"}'),s={name:"sources/index.md"},a=o("",11),h=[a];function c(n,p,l,f,i,u){return r(),t("div",null,h)}const d=e(s,[["render",c]]);export{m as __pageData,d as default}; diff --git a/assets/style.xdMTZl-I.css b/assets/style.xdMTZl-I.css new file mode 100644 index 00000000..c905ce29 --- /dev/null +++ b/assets/style.xdMTZl-I.css @@ -0,0 +1 @@ +@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-cyrillic.jIZ9REo5.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-cyrillic-ext.8T9wMG5w.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-greek.Cb5wWeGA.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-greek-ext.9JiNzaSO.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-latin.bvIUbFQP.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-latin-ext.GZWE-KO4.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/ts-oauth2-server/assets/inter-roman-vietnamese.paY3CzEB.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-cyrillic.-nLMcIwj.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-cyrillic-ext.OVycGSDq.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-greek.PSfer2Kc.woff2) format("woff2");unicode-range:U+0370-03FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-greek-ext.hznxWNZO.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-latin.27E69YJn.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-latin-ext.RnFly65-.woff2) format("woff2");unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter var;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/ts-oauth2-server/assets/inter-italic-vietnamese.xzQHe1q1.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+1EA0-1EF9,U+20AB}@font-face{font-family:Chinese Quotes;src:local("PingFang SC Regular"),local("PingFang SC"),local("SimHei"),local("Source Han Sans SC");unicode-range:U+2018,U+2019,U+201C,U+201D}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Chinese Quotes", "Inter var", "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Helvetica, Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E")}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-green-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-green-1);--vp-code-line-diff-remove-color: var(--vp-c-red-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-red-1);--vp-code-line-warning-color: var(--vp-c-yellow-soft);--vp-code-line-error-color: var(--vp-c-red-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-brand-soft);--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-gray-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-brand-1);--vp-badge-tip-bg: var(--vp-c-brand-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{display:inline-block;margin:auto 2px -2px}mjx-container>svg{margin:auto}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-brand-1)}.custom-block.tip a:hover{color:var(--vp-c-brand-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s}.vp-doc blockquote>p{margin:0;font-size:16px;color:var(--vp-c-text-2);transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin-bottom:4px;text-align:center;letter-spacing:1px;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:11px}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-fda50202]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-fda50202],.VPBackdrop.fade-leave-to[data-v-fda50202]{opacity:0}.VPBackdrop.fade-leave-active[data-v-fda50202]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-fda50202]{display:none}}.NotFound[data-v-b3b1a313]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-b3b1a313]{padding:96px 32px 168px}}.code[data-v-b3b1a313]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-b3b1a313]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-b3b1a313]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-b3b1a313]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-b3b1a313]{padding-top:20px}.link[data-v-b3b1a313]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-b3b1a313]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-e7812efa]{position:relative;z-index:1}.nested[data-v-e7812efa]{padding-right:16px;padding-left:16px}.outline-link[data-v-e7812efa]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-e7812efa]:hover,.outline-link.active[data-v-e7812efa]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-e7812efa]{padding-left:13px}.VPDocAsideOutline[data-v-742b9ac6]{display:none}.VPDocAsideOutline.has-outline[data-v-742b9ac6]{display:block}.content[data-v-742b9ac6]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-742b9ac6]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-742b9ac6]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-1f4bf028]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-1f4bf028]{flex-grow:1}.VPDocAside[data-v-1f4bf028] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-1f4bf028] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-1f4bf028] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-4dc7cc60]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-4dc7cc60]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-bb4d37df]{margin-top:64px}.edit-info[data-v-bb4d37df]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-bb4d37df]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-bb4d37df]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-bb4d37df]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-bb4d37df]{margin-right:8px;width:14px;height:14px;fill:currentColor}.prev-next[data-v-bb4d37df]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-bb4d37df]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-bb4d37df]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-bb4d37df]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-bb4d37df]{margin-left:auto;text-align:right}.desc[data-v-bb4d37df]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-bb4d37df]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-31dd4b0a]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-31dd4b0a]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-31dd4b0a]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-31dd4b0a]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-31dd4b0a]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-31dd4b0a]{display:flex;justify-content:center}.VPDoc .aside[data-v-31dd4b0a]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-31dd4b0a]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-31dd4b0a]{max-width:1104px}}.container[data-v-31dd4b0a]{margin:0 auto;width:100%}.aside[data-v-31dd4b0a]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-31dd4b0a]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-31dd4b0a]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-31dd4b0a]::-webkit-scrollbar{display:none}.aside-curtain[data-v-31dd4b0a]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-31dd4b0a]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-31dd4b0a]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-31dd4b0a]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-31dd4b0a]{order:1;margin:0;min-width:640px}}.content-container[data-v-31dd4b0a]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-31dd4b0a]{max-width:688px}.external-link-icon-enabled :is(.vp-doc a[href*="://"][data-v-31dd4b0a],.vp-doc a[target=_blank][data-v-31dd4b0a]):after{content:"";color:currentColor}.VPButton[data-v-40be9b68]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-40be9b68]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-40be9b68]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-40be9b68]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-40be9b68]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-40be9b68]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-40be9b68]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-40be9b68]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-40be9b68]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-40be9b68]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-40be9b68]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-40be9b68]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-40be9b68]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-311b0b50]{display:none}.dark .VPImage.light[data-v-311b0b50]{display:none}.VPHero[data-v-d6a8a56d]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-d6a8a56d]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-d6a8a56d]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-d6a8a56d]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-d6a8a56d]{flex-direction:row}}.main[data-v-d6a8a56d]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-d6a8a56d]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-d6a8a56d]{text-align:left}}@media (min-width: 960px){.main[data-v-d6a8a56d]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-d6a8a56d]{max-width:592px}}.name[data-v-d6a8a56d],.text[data-v-d6a8a56d]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-d6a8a56d],.VPHero.has-image .text[data-v-d6a8a56d]{margin:0 auto}.name[data-v-d6a8a56d]{color:var(--vp-home-hero-name-color)}.clip[data-v-d6a8a56d]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-d6a8a56d],.text[data-v-d6a8a56d]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-d6a8a56d],.text[data-v-d6a8a56d]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-d6a8a56d],.VPHero.has-image .text[data-v-d6a8a56d]{margin:0}}.tagline[data-v-d6a8a56d]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-d6a8a56d]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-d6a8a56d]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-d6a8a56d]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-d6a8a56d]{margin:0}}.actions[data-v-d6a8a56d]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-d6a8a56d]{justify-content:center}@media (min-width: 640px){.actions[data-v-d6a8a56d]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-d6a8a56d]{justify-content:flex-start}}.action[data-v-d6a8a56d]{flex-shrink:0;padding:6px}.image[data-v-d6a8a56d]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-d6a8a56d]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-d6a8a56d]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-d6a8a56d]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-d6a8a56d]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-d6a8a56d]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-d6a8a56d]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-d6a8a56d]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-d6a8a56d]{width:320px;height:320px}}[data-v-d6a8a56d] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-d6a8a56d] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-d6a8a56d] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-67a48382]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-67a48382]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-67a48382]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-67a48382]>.VPImage{margin-bottom:20px}.icon[data-v-67a48382]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-67a48382]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-67a48382]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-67a48382]{padding-top:8px}.link-text-value[data-v-67a48382]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-67a48382]{display:inline-block;margin-left:6px;width:14px;height:14px;fill:currentColor}.VPFeatures[data-v-cfea7819]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-cfea7819]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-cfea7819]{padding:0 64px}}.container[data-v-cfea7819]{margin:0 auto;max-width:1152px}.items[data-v-cfea7819]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-cfea7819]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-cfea7819],.item.grid-4[data-v-cfea7819],.item.grid-6[data-v-cfea7819]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-cfea7819],.item.grid-4[data-v-cfea7819]{width:50%}.item.grid-3[data-v-cfea7819],.item.grid-6[data-v-cfea7819]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-cfea7819]{width:25%}}.VPHome[data-v-24527f03]{padding-bottom:96px}.VPHome[data-v-24527f03] .VPHomeSponsors{margin-top:112px;margin-bottom:-128px}@media (min-width: 768px){.VPHome[data-v-24527f03]{padding-bottom:128px}}.VPContent[data-v-9cc6e550]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-9cc6e550]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-9cc6e550]{margin:0}@media (min-width: 960px){.VPContent[data-v-9cc6e550]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-9cc6e550]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-9cc6e550]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-511ea0bf]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-511ea0bf]{display:none}.VPFooter[data-v-511ea0bf] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-511ea0bf] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-511ea0bf]{padding:32px}}.container[data-v-511ea0bf]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-511ea0bf],.copyright[data-v-511ea0bf]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-5f66bb3b]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-5f66bb3b]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-5f66bb3b]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-5f66bb3b]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-5f66bb3b]{color:var(--vp-c-text-1)}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-5f66bb3b]{font-size:14px}}.icon[data-v-5f66bb3b]{display:inline-block;vertical-align:middle;margin-left:2px;width:14px;height:14px;fill:currentColor}.open>.icon[data-v-5f66bb3b]{transform:rotate(90deg)}.items[data-v-5f66bb3b]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-5f66bb3b]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-5f66bb3b]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-5f66bb3b]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-5f66bb3b]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-5f66bb3b]{transition:all .2s ease-out}.flyout-leave-active[data-v-5f66bb3b]{transition:all .15s ease-in}.flyout-enter-from[data-v-5f66bb3b],.flyout-leave-to[data-v-5f66bb3b]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-3f38562d]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-3f38562d]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-3f38562d]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-3f38562d]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-3f38562d]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-3f38562d]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-3f38562d]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-3f38562d]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-3f38562d]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-3f38562d]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-3f38562d]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-3f38562d]{display:none}}.menu-icon[data-v-3f38562d]{margin-right:8px;width:16px;height:16px;fill:currentColor}.VPOutlineDropdown[data-v-3f38562d]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-3f38562d]{padding:12px 32px 11px}}.VPSwitch[data-v-2a3bed0a]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-2a3bed0a]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-2a3bed0a]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-2a3bed0a]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-2a3bed0a] svg{position:absolute;top:3px;left:3px;width:12px;height:12px;fill:var(--vp-c-text-2)}.dark .icon[data-v-2a3bed0a] svg{fill:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-3cf77669]{opacity:1}.moon[data-v-3cf77669],.dark .sun[data-v-3cf77669]{opacity:0}.dark .moon[data-v-3cf77669]{opacity:1}.dark .VPSwitchAppearance[data-v-3cf77669] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-d3b998cb]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-d3b998cb]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-471767ad]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-471767ad]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-471767ad]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-471767ad]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-10eeda13]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-10eeda13]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-10eeda13]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-10eeda13]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-7fa80d24]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-7fa80d24] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-7fa80d24] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-7fa80d24] .group:last-child{padding-bottom:0}.VPMenu[data-v-7fa80d24] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-7fa80d24] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-7fa80d24] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-7fa80d24] .action{padding-left:24px}.VPFlyout[data-v-d984d571]{position:relative}.VPFlyout[data-v-d984d571]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-d984d571]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-d984d571]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-d984d571]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-d984d571]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-d984d571],.button[aria-expanded=true]+.menu[data-v-d984d571]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-d984d571]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-d984d571]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-d984d571]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-d984d571]{margin-right:0;width:16px;height:16px;fill:currentColor}.text-icon[data-v-d984d571]{margin-left:4px;width:14px;height:14px;fill:currentColor}.icon[data-v-d984d571]{width:20px;height:20px;fill:currentColor;transition:fill .25s}.menu[data-v-d984d571]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-71f82a9c]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-71f82a9c]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-71f82a9c]>svg{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-e07a6729]{display:flex;justify-content:center}.VPNavBarExtra[data-v-cbc1e7bf]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-cbc1e7bf]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-cbc1e7bf]{display:none}}.trans-title[data-v-cbc1e7bf]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-cbc1e7bf],.item.social-links[data-v-cbc1e7bf]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-cbc1e7bf]{min-width:176px}.appearance-action[data-v-cbc1e7bf]{margin-right:-2px}.social-links-list[data-v-cbc1e7bf]{margin:-4px -8px}.VPNavBarHamburger[data-v-09ffc4dc]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-09ffc4dc]{display:none}}.container[data-v-09ffc4dc]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-09ffc4dc]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-09ffc4dc]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-09ffc4dc]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-09ffc4dc]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-09ffc4dc]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-09ffc4dc]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-09ffc4dc],.VPNavBarHamburger.active:hover .middle[data-v-09ffc4dc],.VPNavBarHamburger.active:hover .bottom[data-v-09ffc4dc]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-09ffc4dc],.middle[data-v-09ffc4dc],.bottom[data-v-09ffc4dc]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-09ffc4dc]{top:0;left:0;transform:translate(0)}.middle[data-v-09ffc4dc]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-09ffc4dc]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-4db78c14]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-4db78c14],.VPNavBarMenuLink[data-v-4db78c14]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-d92b6212]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-d92b6212]{display:flex}}/*! @docsearch/css 3.5.2 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-fcd1192c]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-fcd1192c]{display:flex;align-items:center}}.title[data-v-26e79017]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-26e79017]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-26e79017]{border-bottom-color:var(--vp-c-divider)}}[data-v-26e79017] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-33b812cb]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-33b812cb]{display:flex;align-items:center}}.title[data-v-33b812cb]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-096a19da]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .5s}.VPNavBar.has-local-nav[data-v-096a19da]{background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar.has-local-nav[data-v-096a19da]{background-color:transparent}.VPNavBar[data-v-096a19da]:not(.has-sidebar):not(.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-096a19da]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-096a19da]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-096a19da]{padding:0}}.container[data-v-096a19da]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-096a19da],.container>.content[data-v-096a19da]{pointer-events:none}.container[data-v-096a19da] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-096a19da]{max-width:100%}}.title[data-v-096a19da]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-096a19da]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-096a19da]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-096a19da]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-096a19da]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-096a19da]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-096a19da]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.top) .content-body[data-v-096a19da]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.top) .content-body[data-v-096a19da]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-096a19da]{column-gap:.5rem}}.menu+.translations[data-v-096a19da]:before,.menu+.appearance[data-v-096a19da]:before,.menu+.social-links[data-v-096a19da]:before,.translations+.appearance[data-v-096a19da]:before,.appearance+.social-links[data-v-096a19da]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-096a19da]:before,.translations+.appearance[data-v-096a19da]:before{margin-right:16px}.appearance+.social-links[data-v-096a19da]:before{margin-left:16px}.social-links[data-v-096a19da]{margin-right:-8px}.divider[data-v-096a19da]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-096a19da]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-096a19da]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-096a19da]{width:100%;height:1px;transition:background-color .5s}.VPNavBar.has-local-nav .divider-line[data-v-096a19da]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.top) .divider-line[data-v-096a19da]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.top) .divider[data-v-096a19da]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-eac3ec4a]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-eac3ec4a]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-0bb67861]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-0bb67861]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-c9499b62]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-c9499b62]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-fcf881b9]{display:block}.title[data-v-fcf881b9]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-e90ec729]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-e90ec729]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-e90ec729]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-e90ec729]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-e90ec729]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-e90ec729]{transform:rotate(45deg)}.button[data-v-e90ec729]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-e90ec729]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-e90ec729]{width:14px;height:14px;fill:var(--vp-c-text-2);transition:fill .5s,transform .25s}.group[data-v-e90ec729]:first-child{padding-top:0}.group+.group[data-v-e90ec729],.group+.item[data-v-e90ec729]{padding-top:4px}.VPNavScreenTranslations[data-v-ca22a98e]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-ca22a98e]{height:auto}.title[data-v-ca22a98e]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-ca22a98e]{width:16px;height:16px;fill:currentColor}.icon.lang[data-v-ca22a98e]{margin-right:8px}.icon.chevron[data-v-ca22a98e]{margin-left:4px}.list[data-v-ca22a98e]{padding:4px 0 0 24px}.link[data-v-ca22a98e]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-05143d15]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .5s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-05143d15],.VPNavScreen.fade-leave-active[data-v-05143d15]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-05143d15],.VPNavScreen.fade-leave-active .container[data-v-05143d15]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-05143d15],.VPNavScreen.fade-leave-to[data-v-05143d15]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-05143d15],.VPNavScreen.fade-leave-to .container[data-v-05143d15]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-05143d15]{display:none}}.container[data-v-05143d15]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-05143d15],.menu+.appearance[data-v-05143d15],.translations+.appearance[data-v-05143d15]{margin-top:24px}.menu+.social-links[data-v-05143d15]{margin-top:16px}.appearance+.social-links[data-v-05143d15]{margin-top:16px}.VPNav[data-v-e89ada44]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-e89ada44]{position:fixed}}.VPSidebarItem.level-0[data-v-1d929f5a]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-1d929f5a]{padding-bottom:10px}.item[data-v-1d929f5a]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-1d929f5a]{cursor:pointer}.indicator[data-v-1d929f5a]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-1d929f5a],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-1d929f5a],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-1d929f5a],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-1d929f5a]{background-color:var(--vp-c-brand-1)}.link[data-v-1d929f5a]{display:flex;align-items:center;flex-grow:1}.text[data-v-1d929f5a]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-1d929f5a]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-1d929f5a],.VPSidebarItem.level-2 .text[data-v-1d929f5a],.VPSidebarItem.level-3 .text[data-v-1d929f5a],.VPSidebarItem.level-4 .text[data-v-1d929f5a],.VPSidebarItem.level-5 .text[data-v-1d929f5a]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-1d929f5a],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-1d929f5a],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-1d929f5a],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-1d929f5a],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-1d929f5a],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-1d929f5a]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-1.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-2.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-3.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-4.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-5.has-active>.item>.text[data-v-1d929f5a],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-1d929f5a],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-1d929f5a],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-1d929f5a],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-1d929f5a],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-1d929f5a],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-1d929f5a]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-1d929f5a],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-1d929f5a],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-1d929f5a],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-1d929f5a],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-1d929f5a],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-1d929f5a]{color:var(--vp-c-brand-1)}.caret[data-v-1d929f5a]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-1d929f5a]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-1d929f5a]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-1d929f5a]{width:18px;height:18px;fill:currentColor;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-1d929f5a]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-1d929f5a],.VPSidebarItem.level-2 .items[data-v-1d929f5a],.VPSidebarItem.level-3 .items[data-v-1d929f5a],.VPSidebarItem.level-4 .items[data-v-1d929f5a],.VPSidebarItem.level-5 .items[data-v-1d929f5a]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-1d929f5a]{display:none}.VPSidebar[data-v-eeab08bd]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-eeab08bd]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-eeab08bd]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-eeab08bd]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-eeab08bd]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-eeab08bd]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-eeab08bd]{outline:0}.group+.group[data-v-eeab08bd]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-eeab08bd]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSkipLink[data-v-1ebf7576]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-1ebf7576]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-1ebf7576]{top:14px;left:16px}}.Layout[data-v-1de9594d]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-a475d9a5]{border-top:1px solid var(--vp-c-gutter);padding:88px 24px 96px;background-color:var(--vp-c-bg)}.container[data-v-a475d9a5]{margin:0 auto;max-width:1152px}.love[data-v-a475d9a5]{margin:0 auto;width:28px;height:28px;color:var(--vp-c-text-3)}.icon[data-v-a475d9a5]{width:28px;height:28px;fill:currentColor}.message[data-v-a475d9a5]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-a475d9a5]{padding-top:32px}.action[data-v-a475d9a5]{padding-top:40px;text-align:center}.VPTeamPage[data-v-1146db5f]{padding-bottom:96px}@media (min-width: 768px){.VPTeamPage[data-v-1146db5f]{padding-bottom:128px}}.VPTeamPageSection+.VPTeamPageSection[data-v-1146db5f-s],.VPTeamMembers+.VPTeamPageSection[data-v-1146db5f-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-1146db5f-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-1146db5f-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-1146db5f-s],.VPTeamMembers+.VPTeamPageSection[data-v-1146db5f-s]{margin-top:96px}}.VPTeamMembers[data-v-1146db5f-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-1146db5f-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-1146db5f-s]{padding:0 64px}}.VPTeamPageTitle[data-v-5b7e7723]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-5b7e7723]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-5b7e7723]{padding:80px 64px 48px}}.title[data-v-5b7e7723]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-5b7e7723]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-5b7e7723]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-5b7e7723]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-3e75f5d9]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-3e75f5d9]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-3e75f5d9]{padding:0 64px}}.title[data-v-3e75f5d9]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-3e75f5d9]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-3e75f5d9]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-3e75f5d9]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-3e75f5d9]{padding-top:40px}.VPTeamMembersItem[data-v-2129d21b]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-2129d21b]{padding:32px}.VPTeamMembersItem.small .data[data-v-2129d21b]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-2129d21b]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-2129d21b]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-2129d21b]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-2129d21b]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-2129d21b]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-2129d21b]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-2129d21b]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-2129d21b]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-2129d21b]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-2129d21b]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-2129d21b]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-2129d21b]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-2129d21b]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-2129d21b]{text-align:center}.avatar[data-v-2129d21b]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-2129d21b]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-2129d21b]{margin:0;font-weight:600}.affiliation[data-v-2129d21b]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-2129d21b]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-2129d21b]:hover{color:var(--vp-c-brand-1)}.desc[data-v-2129d21b]{margin:0 auto}.desc[data-v-2129d21b] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-2129d21b]{display:flex;justify-content:center;height:56px}.sp-link[data-v-2129d21b]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-2129d21b]:hover,.sp .sp-link.link[data-v-2129d21b]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-2129d21b]{margin-right:8px;width:16px;height:16px;fill:currentColor}.VPTeamMembers.small .container[data-v-990293a1]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-990293a1]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-990293a1]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-990293a1]{max-width:876px}.VPTeamMembers.medium .container[data-v-990293a1]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-990293a1]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-990293a1]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-990293a1]{max-width:760px}.container[data-v-990293a1]{display:grid;gap:24px;margin:0 auto;max-width:1152px}ul.table-of-contents{list-style-type:none;margin:1rem 0 0 .5rem;padding:0;line-height:1}ul.table-of-contents ul{margin-left:1rem}.table-of-contents li{text-indent:-5px}.table-of-contents li:before{content:"- ";text-indent:-5px} diff --git a/assets/utils_index.md.mGNYhLTf.js b/assets/utils_index.md.mGNYhLTf.js new file mode 100644 index 00000000..3a8fed62 --- /dev/null +++ b/assets/utils_index.md.mGNYhLTf.js @@ -0,0 +1,10 @@ +import{_ as i,c as e,k as s,a as t,t as n,U as l,o as r}from"./chunks/framework.XQuvpNW4.js";const _=JSON.parse('{"title":"Utils","description":"","frontmatter":{"title":"Utils"},"headers":[],"relativePath":"utils/index.md","filePath":"utils/index.md"}'),h={name:"utils/index.md"},p={id:"frontmatter-title",tabindex:"-1"},k=s("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),d=l(`

JwtService

@see JwtService

Using jsonwebtoken

Example Extra Params Usage

typescript
import { JwtService } from '@jmondi/oauth2-server';
+
+export class MyCustomJwtService extends JwtService {
+  extraTokenFields({ user, client }: ExtraAccessTokenFieldArgs) {
+    return {
+      email: user?.email,
+      client_id: client.id,
+    }
+  }
+}

DateInterval

using ms

`,7);function o(a,c,E,g,m,u){return r(),e("div",null,[s("h1",p,[t(n(a.$frontmatter.title)+" ",1),k]),d])}const F=i(h,[["render",o]]);export{_ as __pageData,F as default}; diff --git a/assets/utils_index.md.mGNYhLTf.lean.js b/assets/utils_index.md.mGNYhLTf.lean.js new file mode 100644 index 00000000..825add22 --- /dev/null +++ b/assets/utils_index.md.mGNYhLTf.lean.js @@ -0,0 +1 @@ +import{_ as i,c as e,k as s,a as t,t as n,U as l,o as r}from"./chunks/framework.XQuvpNW4.js";const _=JSON.parse('{"title":"Utils","description":"","frontmatter":{"title":"Utils"},"headers":[],"relativePath":"utils/index.md","filePath":"utils/index.md"}'),h={name:"utils/index.md"},p={id:"frontmatter-title",tabindex:"-1"},k=s("a",{class:"header-anchor",href:"#frontmatter-title","aria-label":'Permalink to "{{ $frontmatter.title }}"'},"​",-1),d=l("",7);function o(a,c,E,g,m,u){return r(),e("div",null,[s("h1",p,[t(n(a.$frontmatter.title)+" ",1),k]),d])}const F=i(h,[["render",o]]);export{_ as __pageData,F as default}; diff --git a/configuration/index.html b/configuration/index.html new file mode 100644 index 00000000..9a9d7478 --- /dev/null +++ b/configuration/index.html @@ -0,0 +1,38 @@ + + + + + + Configuration | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Configuration

INFO

The default configuration is great for most users. You might not need to tweak anything here.

The authorization server has a few optional settings with the following default values;

ts
type AuthorizationServerOptions = {
+  requiresPKCE: true;
+  requiresS256: false;
+  notBeforeLeeway: 0;
+  tokenCID: "id" | "name";
+}
OptionNumberDefaultDetails
requiresPKCEbooleantruePKCE is enabled by default and recommended for all users. To support a legacy client without PKCE, disable this option. [Learn more]
requiresS256booleantrueDisabled by default. If you want to require all clients to use S256, you can enable that here. [Learn more]
notBeforeLeewaynumber0Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value.
tokenCID"id" or "name""id"Sets the JWT accessToken.cid to either the client.id or client.name.

In 3.x the default is "id", in v2.x the default was "name". [Learn more]

To configure these options, pass the value in as the last argument:

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  new JwtService("secret-key"),
+  {
+    requiresS256: true,
+  }
+);

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/entities/index.html b/entities/index.html new file mode 100644 index 00000000..29b69eb3 --- /dev/null +++ b/entities/index.html @@ -0,0 +1,56 @@ + + + + + + Entity Interfaces | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Entity Interfaces

Client Entity

This entity represents the client that wants to access the resource server. The client will retrieve an access token from our authorization server and use it to access the resource server.

  • URI must be an absolute URI
  • The endpoint may include application/x-www-form-urlencoded formatted query component which must be retained when adding additional query params
  • the endpoint URI must not include a fragment component
typescript
interface OAuthClient {
+  id: string;
+  name: string;
+  secret?: string;
+  redirectUris: string[];
+  allowedGrants: GrantIdentifier[];
+  scopes: OAuthScope[];
+}

Auth Code Entity

The auth code is used to retrieve an access token from the authorization server.

typescript
interface OAuthAuthCode {
+  code: string;
+  redirectUri?: string;
+  codeChallenge?: string;
+  codeChallengeMethod?: CodeChallengeMethod;
+  expiresAt: Date;
+  user?: OAuthUser;
+  client: OAuthClient;
+  scopes: OAuthScope[];
+}

TIP

ts
type CodeChallengeMethod = "S256" | "plain";

Token Entity

The access and refresh token that can be used to authenticate into the resource server. The originatingAuthCodeId will be present only for tokens originating from the authorization code grant; see the revokeDescendantsOf() method on the Token Repository for its significance.

typescript
interface OAuthToken {
+  accessToken: string;
+  accessTokenExpiresAt: Date;
+  refreshToken?: string | null;
+  refreshTokenExpiresAt?: Date | null;
+  client: OAuthClient;
+  user?: OAuthUser | null;
+  scopes: OAuthScope[];
+  originatingAuthCodeId?: string;
+}

User Entity

The resource owner

typescript
interface OAuthUser {
+  id: string;
+  [key: string]: any;
+}

Scope Entity

Scopes are a way to limit an app’s access to a user’s data.

https://www.oauth.com/oauth2-servers/scope/

typescript
interface OAuthScope {
+  name: string;
+  [key: string]: any;
+}

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/getting_started/index.html b/getting_started/index.html new file mode 100644 index 00000000..37da3314 --- /dev/null +++ b/getting_started/index.html @@ -0,0 +1,96 @@ + + + + + + Getting Started | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Getting Started

Install

npm

bash
pnpm add @jmondi/oauth2-server
bash
npm install --save @jmondi/oauth2-server
bash
yarn add @jmondi/oauth2-server

The Authorization Server

The AuthorizationServer depends on the repositories. By default, no grants are enabled; each grant is opt-in and must be enabled when creating the AuthorizationServer.

You can enable any grant types you would like to support.

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  "secret-key",
+  {} // optional configuration
+);
+authorizationServer.enableGrantType("client_credentials");
+authorizationServer.enableGrantType("refresh_token");
+authorizationServer.enableGrantType({
+  grant: "authorization_code",
+  userRepository, 
+  authorizationCodeRepository,
+});

See the configuration documentation for a full list of config options.

The Token Endpoint

The /token endpoint is a back channel endpoint that issues a usable access token.

typescript
app.post("/token", async (req: Express.Request, res: Express.Response) => {
+  try {
+    const oauthResponse = await authorizationServer.respondToAccessTokenRequest(req);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+    return;
+  }
+});

The Authorize Endpoint

The /authorize endpoint is a front channel endpoint that issues an authorization code. The authorization code can then be exchanged to the AuthorizationServer endpoint for a useable access token.

The endpoint should redirect the user to login, and then to accept the scopes requested by the application, and only when the user accepts, should it send the user back to the clients redirect uri.

typescript
import { requestFromExpress } from "@jmondi/oauth2-server/express";
+
+app.get("/authorize", async (req: Express.Request, res: Express.Response) => {
+  try {
+    // Validate the HTTP request and return an AuthorizationRequest.
+    const authRequest = await authorizationServer.validateAuthorizationRequest(request, requestFromExpress(req));
+
+    // You will probably redirect the user to a login endpoint. 
+    if (!req.user) {
+      req.redirect("/login")
+      return;
+    }
+    // After login, the user should be redirected back with user in the session.
+    // You will need to manage the authorization query on the round trip.
+    // The auth request object can be serialized and saved into a user's session.
+
+    // Once the user has logged in set the user on the AuthorizationRequest
+    authRequest.user = req.user;
+    
+    // Once the user has approved or denied the client update the status
+    // (true = approved, false = denied)
+    authRequest.isAuthorizationApproved = getIsAuthorizationApprovedFromSession();
+
+    // If the user has not approved the client's authorization request, 
+    // the user should be redirected to the approval screen.
+    if (!authRequest.isAuthorizationApproved) {
+      // This form will ask the user to approve the client and the scopes requested.
+      // "Do you authorize Jason to: read contacts? write contacts?"
+      req.redirect("/scopes")
+      return;
+    }
+
+    // At this point the user has approved the client for authorization.
+    // Any last authorization requests such as Two Factor Authentication (2FA) can happen here.
+
+
+    // Redirect back to redirect_uri with `code` and `state` as url query params.
+    const oauthResponse = await authorizationServer.completeAuthorizationRequest(authRequest);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+  }
+});

Revoke Token

Note

Implementing this endpoint is optional, but recommended. RFC7009 “OAuth 2.0 Token Revocation”

The /token/revoke endpoint is a back channel endpoint that revokes an existing token.

typescript
app.post("/token/revoke", async (req: Express.Request, res: Express.Response) => {
+  try {
+    const oauthResponse = await authorizationServer.revoke(req);
+    return handleExpressResponse(res, oauthResponse);
+  } catch (e) {
+    handleExpressError(e, res);
+    return;
+  }
+});

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/glossary/index.html b/glossary/index.html new file mode 100644 index 00000000..55352d95 --- /dev/null +++ b/glossary/index.html @@ -0,0 +1,25 @@ + + + + + + Glossary | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Glossary

Resource Server

The resource server is the OAuth 2.0 term for your API server. The resource server handles authenticated requests after the client has obtained an access token.

Client

The application attempting to gain access to the resource server. The client must have an OAuthClient

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/authorization_code.html b/grants/authorization_code.html new file mode 100644 index 00000000..5fb90962 --- /dev/null +++ b/grants/authorization_code.html @@ -0,0 +1,74 @@ + + + + + + Authorization Code Grant (w/ PKCE) | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Authorization Code Grant (w/ PKCE)

A temporary code that the client will exchange for an access token. The user authorizes the application, they are redirected back to the application with a temporary code in the URL. The application exchanges that code for the access token.

Flow

Part One

The client redirects the user to the /authorize with the following query parameters:

  • response_type must be set to code
  • client_id is the client identifier you received when you first created the application
  • redirect_uri indicates the URL to return the user to after authorization is complete, such as org.example.app://redirect
  • state is a random string generated by your application, which you’ll verify later
  • code_challenge must match the The code challenge as generated below,
  • code_challenge_method – Either plain or S256, depending on whether the challenge is the plain verifier string or the SHA256 hash of the string. If this parameter is omitted, the server will assume plain.

TIP

The client secret should never be used during the Part One of the authorization_code flow.

View sample authorization_code (part 1) request
http
GET /authorize HTTP/1.1
+Host: example.com
+
+response_type=code
+&client_id=xxxxxxx
+&redirect_uri=http://localhost
+&scope="contacts.read contacts.write"
+&state=abcdefghijklmnopqrstuvwxyz123456789
+&code_challenge=92d3b56942866d1edf02c33339b7c3dc37c6201282bb238cb47f0d3289f28a93f1bdd8af6ca9913aed0c4c
+&code_challenge_method=S256

The user will be asked to login to the authorization server and approve the client and requested scopes.

If the user approves the client, they will be redirected from the authorization server to the provided redirect_uri with the following fields in the query string:

  • code is the authorization code that will soon be exchanged for a token
  • state is the random string provided and should be compared against the initially provided state
View sample authorization_code (part 1) response
http
HTTP/1.1 302 Found
+Location: http://localhost&code=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3QiLCJhdXRoX2NvZGVfaWQiOiJteS1zdXBlci1zZWNyZXQtYXV0aC1jb2RlIiwic2NvcGVzIjpbXSwiZXhwaXJlX3RpbWUiOjE2MDE3NTM3MzMsImNvZGVfY2hhbGxlbmdlIjoiT0RRd1pHTTRZelpsTnpNeU1qUXlaREF4WWpFNU1XWmtZMlJrTmpKbU1UbGxNbUkwTnpJMFpEbGtNR0psWWpGbE1tTXhPV1kyWkRJMVpEZGpNak13WWciLCJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2In0.OIEtZN5BHNaB4Mz0plUpGAP93EHyoil2smJiG3S_2BM&state=abcdefghijklmnopqrstuvwxyz123456789

Part Two

The client sends a POST to the /token endpoint with the following body:

  • grant_type must be set to authorization_code
  • client_id is the client identifier you received when you first created the application
  • client_secret (optional) is the client secret and should only be provided if the client is confidential
  • redirect_uri
  • code_verifier
  • code is the authorization code from the query string

Private Key Leak Potential

Clients such as Browser Based Apps and Native Mobile Apps should NEVER have or use a client_secret. That means the client_secret should be omitted both when initially creating the OAuthClient entity, and when making requests.

View sample authorization_code (part 2) request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=authorization_code
+&client_id=xxxxxxxxxx
+&client_secret=xxxxxxxxxx
+&redirect_uri=http://localhost
+&code_verifier=OTJkM2I1Njk0Mjg2NmQxZWRmMDJjMzMzMzliN2MzZGMzN2M2MjAxMjgyYmIyMzhjYjQ3ZjBkMzI4OWYyOGE5M2YxYmRkOGFmNmNhOTkxM2FlZDBjNGM
+&code=eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3QiLCJhdXRoX2NvZGVfaWQiOiJteS1zdXBlci1zZWNyZXQtYXV0aC1jb2RlIiwic2NvcGVzIjpbXSwiZXhwaXJlX3RpbWUiOjE2MDE3NTM3MzMsImNvZGVfY2hhbGxlbmdlIjoiT0RRd1pHTTRZelpsTnpNeU1qUXlaREF4WWpFNU1XWmtZMlJrTmpKbU1UbGxNbUkwTnpJMFpEbGtNR0psWWpGbE1tTXhPV1kyWkRJMVpEZGpNak13WWciLCJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2In0.OIEtZN5BHNaB4Mz0plUpGAP93EHyoil2smJiG3S_2BM

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample authorization_code (part 2) response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE3NTUxMDQsIm5iZiI6MTYwMTc1MTUwNCwiaWF0IjoxNjAxNzUxNTA0LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGF1dGggY29kZSBjbGllbnQiLCJzY29wZSI6IiJ9.-V9x03iz-3ISRMdj9m1-FCKjmtfjvv6wqnBj6VZdW28',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiJhdXRoY29kZWNsaWVudCIsImFjY2Vzc190b2tlbl9pZCI6Im5ldyB0b2tlbiIsInJlZnJlc2hfdG9rZW5faWQiOiJ0aGlzLWlzLW15LXN1cGVyLXNlY3JldC1yZWZyZXNoLXRva2VuIiwic2NvcGUiOiIiLCJleHBpcmVfdGltZSI6MTYwMTc1NTEwNCwiaWF0IjoxNjAxNzUxNTAzfQ.J_RUFD5-158atTmI98R95vowZWi4mUEXYCO7iNwzpK4',
+  scope: 'contacts.read contacts.write'
+}

PKCE

PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent several attacks and to be able to securely perform the OAuth exchange from public clients.

By default, PKCE is enabled and encouraged for all users. If you need to support a legacy client system without PKCE, you can disable PKCE with the authorization server using the requiresPKCE configuration option.

Code Verifier

The code_verifier is part of the extended “PKCE” and helps mitigate the threat of having authorization codes intercepted.

Before initializing Part One of the authorization code flow, the client first creats a code_verifier. This is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.

We can do this in Node using the native crypto package and a base64urlencode function:

typescript
import crypto from "node:crypto";
+
+const code_verifier = crypto.randomBytes(43).toString("hex");

@see https://www.oauth.com/oauth2-servers/pkce/authorization-request/

Code Challenge

Now we need to create a code_challenge from our code_verifier.

For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.

typescript
const code_challenge = base64urlencode(
+  crypto.createHash("sha256")
+    .update(code_verifier)
+    .digest()
+);

Clients that do not have the ability to perform a SHA256 hash are permitted to use the plain code_verifier string as the code_challenge.

typescript
const code_challenge = code_verifier;
Need a base64urlencode function?
typescript
function base64urlencode(str: string) {
+  return Buffer.from(str)
+    .toString("base64")
+    .replace(/\+/g, "-")
+    .replace(/\//g, "_")
+    .replace(/=/g, "");
+}

Revocation

Authorization codes are only valid for a single use. In addition, they can be explicitly revoked on a server that supports RFC7009 “OAuth 2.0 Token Revocation”.

An authorization code revocation request will include the following parameters:

  • token is the authorization code previously issued to the client
  • token_type_hint (optional) should be set to authorization_code
View sample revoke authorization_code request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+token_type_hint=authorization_code
+&refresh_token=xxxxxxxxx

The authorization server will respond with the following response

View sample revoke authorization_code response
http
HTTP/1.1 200 OK
+Cache-Control: no-store
+Pragma: no-cache

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/client_credentials.html b/grants/client_credentials.html new file mode 100644 index 00000000..c3fc404c --- /dev/null +++ b/grants/client_credentials.html @@ -0,0 +1,47 @@ + + + + + + Client Credentials Grant | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Client Credentials Grant

When applications request an access token to access their own resources, not on behalf of a user.

TIP

The client_credentials grant should only be used by clients that can hold a secret. No Browser or Native Mobile Apps should be using this grant.

Flow

The client sends a POST to the /token endpoint with the following body:

  • grant_type must be set to client_credentials
  • client_id is the client identifier you received when you first created the application
  • client_secret is the client secret
  • scope is a string with a space delimited list of requested scopes. The requested scopes must be valid for the client.
View sample client_credentials request

Did you know? You can authenticate by passing the client_id and client_secret as a query string, or through basic auth.

http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=client_credentials
+&client_id=xxxxxxxxxx
+&client_secret=xxxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic MTpzdXBlci1zZWNyZXQtc2VjcmV0
+
+grant_type=client_credentials
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response.

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and can be used to authenticate into the resource server
  • scope is a space delimited list of scopes the token has access to
View sample client_credentials response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+ 
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE3MDY0NjYsIm5iZiI6MTYwMTcwMjg2NiwiaWF0IjoxNjAxNzAyODY2LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.KcXoCP6u9uhvtOoistLBskESA0tyT2I1SDe5Yn9iM4I',
+  scope: 'contacts.create contacts.read'
+}

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/implicit.html b/grants/implicit.html new file mode 100644 index 00000000..6c819d87 --- /dev/null +++ b/grants/implicit.html @@ -0,0 +1,25 @@ + + + + + + Implicit Grant | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Implicit Grant

Not Recommended

Using the Implicit Grant is no longer best practice

This grant is supported, but not documented. Industry best practice recommends using the Authorization Code Grant without a client secret for native and browser-based apps.

Please look at these great resources:

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/index.html b/grants/index.html new file mode 100644 index 00000000..fe5ec1bd --- /dev/null +++ b/grants/index.html @@ -0,0 +1,63 @@ + + + + + + Which Grant? | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Which Grant?

Grants are different ways a client can obtain an access_token that will authorize it to use the resource server.

Deciding which grant to use depends on the type of client the end user will be using.

+-------+
+| Start |
++-------+
+    V
+    |
+    
+    |
++------------------------+              +-----------------------+
+| Have a refresh token?  |>----Yes----->|  Refresh Token Grant  |
++------------------------+              +-----------------------+
+    V
+    |
+    No
+    |
++---------------------+                
+|     Who is the      |                  +--------------------------+
+| Access token owner? |>---A Machine---->| Client Credentials Grant |
++---------------------+                  +--------------------------+
+    V
+    |
+    |
+   A User
+    |
+    |
++----------------------+                
+| What type of client? |   
++----------------------+     
+    |
+    |                                 +---------------------------+
+    |>-----------Server App---------->| Auth Code Grant with PKCE |
+    |                                 +---------------------------+
+    |
+    |                                 +---------------------------+
+    |>-------Browser Based App------->| Auth Code Grant with PKCE |
+    |                                 +---------------------------+
+    |
+    |                                 +---------------------------+
+    |>-------Native Mobile App------->| Auth Code Grant with PKCE |
+                                      +---------------------------+

Refresh Token Grant

If the client already has a refresh token, it can use the Refresh Token Grant to obtain a new access token without requiring the user's interaction. This grant is useful for long-lived sessions and background processes.

Client Credentials Grant

If the access token owner is a machine, such as a server or an application acting on its own behalf, rather than an individual user, the client can use the Client Credentials Grant. This grant is designed for scenarios where the client needs to access resources autonomously without the context of a specific user.

Auth Code Grant with PKCE

If the access token owner is a user, the recommended grant is the Authorization Code Grant with Proof Key for Code Exchange (PKCE). This grant involves a series of steps where the client redirects the user to the authorization server, the user grants access, and the server provides an authorization code that the client exchanges for an access token. PKCE adds an extra layer of security to protect against authorization code interception attacks.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/password.html b/grants/password.html new file mode 100644 index 00000000..65af360a --- /dev/null +++ b/grants/password.html @@ -0,0 +1,52 @@ + + + + + + Password Grant | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Password Grant

The Password Grant is for first party clients that are able to hold secrets (ie not Browser or Native Mobile Apps)

TIP

The client_credentials grant should only be used by clients that can hold a secret

Flow

A complete refresh token request will include the following parameters:

  • grant_type must be set to password
  • client_id is the client identifier you received when you first created the application
  • client_secret if the client is confidential (has a secret), this must be provided
  • username
  • password
  • scope (optional)
View sample password grant request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=password
+&client_id=xxxxxxxxx
+&client_secret=xxxxxxxxx
+&username=xxxxxxxxx
+&password=xxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN
+
+grant_type=password
+&username=xxxxxxxxx
+&password=xxxxxxxxx
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample password grant response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyOTksIm5iZiI6MTYwMTc2MzY5OSwiaWF0IjoxNjAxNzYzNjk5LCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.sX6SWc2Af8jn-izFnrLgNIcNuZz_tRLl2p7M3CzQwKg',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3Mjk5LCJpYXQiOjE2MDE3NjM2OTh9.SSa7miIdk3bxyzg0f3M9jKBXWjPgD4QEw-AU3SYvBk0',
+  scope: 'contacts.read contacts.write'
+}

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/grants/refresh_token.html b/grants/refresh_token.html new file mode 100644 index 00000000..a41f60d7 --- /dev/null +++ b/grants/refresh_token.html @@ -0,0 +1,58 @@ + + + + + + Refresh Token Grant | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Refresh Token Grant

Access tokens eventually expire. The refresh token grant enables the client to obtain a new access_token from an existing refresh_token.

Flow

A complete refresh token request will include the following parameters:

  • grant_type must be set to refresh_token
  • client_id is the client identifier you received when you first created the application
  • client_secret if the client is confidential (has a secret), this must be provided
  • refresh_token must be the signed token previously issued to the client
  • scope (optional) the requested scope must not include any additional scopes that were not previously issued to the original token
View sample refresh_token request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=refresh_token
+&refresh_token=xxxxxxxxx
+&client_id=xxxxxxxxx
+&client_secret=xxxxxxxxx
+&scope="contacts.read contacts.write"
http
POST /token HTTP/1.1
+Host: example.com
+Authorization: Basic Y4NmE4MzFhZGFkNzU2YWRhN
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=refresh_token
+&refresh_token=xxxxxxxxx
+&scope="contacts.read contacts.write"

The authorization server will respond with the following response

  • token_type will always be Bearer
  • expires_in is the time the token will live in seconds
  • access_token is a JWT signed token and is used to authenticate into the resource server
  • refresh_token is a JWT signed token and can be used in with the refresh grant
  • scope is a space delimited list of scopes the token has access to
View sample refresh_token response
http
HTTP/1.1 200 OK
+Content-Type: application/json; charset=UTF-8
+Cache-Control: no-store
+Pragma: no-cache
+
+{
+  token_type: 'Bearer',
+  expires_in: 3600,
+  access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1MTJhYjlhNC1jNzg2LTQ4YTYtOGFkNi05NGM1M2E4ZGM2NTEiLCJleHAiOjE2MDE3NjcyMTIsIm5iZiI6MTYwMTc2MzYxMiwiaWF0IjoxNjAxNzYzNjEyLCJqdGkiOiJuZXcgdG9rZW4iLCJjaWQiOiJ0ZXN0IGNsaWVudCIsInNjb3BlIjoiIn0.PO4eKSDVsFuKvebEXndWbZsprgzjkzEfHI7cl4N0YpM',
+  refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiIzNTYxNWYyZi0xM2ZhLTQ3MzEtODNhMS05ZTM0NTU2YWIzOTAiLCJhY2Nlc3NfdG9rZW5faWQiOiJuZXcgdG9rZW4iLCJyZWZyZXNoX3Rva2VuX2lkIjoidGhpcy1pcy1teS1zdXBlci1zZWNyZXQtcmVmcmVzaC10b2tlbiIsInNjb3BlIjoiIiwidXNlcl9pZCI6IjUxMmFiOWE0LWM3ODYtNDhhNi04YWQ2LTk0YzUzYThkYzY1MSIsImV4cGlyZV90aW1lIjoxNjAxNzY3MjEyLCJpYXQiOjE2MDE3NjM2MTF9.du4KfAzelSA8hzBaqGlrSvPtH-BxOcoUBXW4HS3pJkM',
+  scope: 'contacts.read contacts.write'
+}

Revocation

Refresh tokens are only valid for a single use. In addition, they can be explicitly revoked on a server that supports RFC7009 “OAuth 2.0 Token Revocation”.

A refresh token revocation request will include the following parameters:

  • token is the signed token previously issued to the client
  • token_type_hint (optional) should be set to refresh_token
View sample revoke refresh_token request
http
POST /token HTTP/1.1
+Host: example.com
+Content-Type: application/x-www-form-urlencoded
+
+token_type_hint=refresh_token
+&refresh_token=xxxxxxxxx

The authorization server will respond with the following response

View sample revoke refresh_token response
http
HTTP/1.1 200 OK
+Cache-Control: no-store
+Pragma: no-cache

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json new file mode 100644 index 00000000..3f7fd7cf --- /dev/null +++ b/hashmap.json @@ -0,0 +1 @@ +{"glossary_index.md":"ThoJe1Xe","getting_started_index.md":"_XNrAxOH","entities_index.md":"5CEqU3ab","index.md":"U7wYHgJ-","grants_index.md":"Wp7i96iB","grants_implicit.md":"A2UquZbS","grants_password.md":"cVz9lIu2","configuration_index.md":"5FRNy3W7","migration_v2_to_v3.md":"m7zLJwap","sources_index.md":"nDiyFoDc","grants_client_credentials.md":"WBW6QGI4","utils_index.md":"mGNYhLTf","adapters_index.md":"PFJHoqKF","repositories_index.md":"mkPMphhv","grants_refresh_token.md":"5g7Gdlsd","grants_authorization_code.md":"NywG-h7F"} diff --git a/index.html b/index.html new file mode 100644 index 00000000..a10889f7 --- /dev/null +++ b/index.html @@ -0,0 +1,25 @@ + + + + + + TypeScript OAuth2.0 Server | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

TypeScript OAuth2.0 Server

🇺🇦 Support Ukraine 🇺🇦

@jmondi/oauth2-server is a standards compliant implementation of an OAuth 2.0 authorization server for Node, written in TypeScript.

Requires node >= 16

Out of the box it supports the following grants:

The following RFCs are implemented:

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/migration/v2_to_v3.html b/migration/v2_to_v3.html new file mode 100644 index 00000000..f70c4378 --- /dev/null +++ b/migration/v2_to_v3.html @@ -0,0 +1,52 @@ + + + + + + Migrating from v2 to v3 | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Migrating from v2 to v3

Upgrade Time Estimate: ESM? 10 minutes; no-ESM? Varies

This package is now pure ESM

The package is now entirely ESM (ECMAScript Modules). More details about this change can be found in Sindre Sorhus's writeup.

AuthorizationServer Updates

In v2.x, AuthorizationServer constructor required all repositories. In v3.x, it has been simplified.

Before (v2.x):

typescript
const authorizationServer = new AuthorizationServer(
+  authCodeRepository,
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  userRepository,
+  jwtService,
+  {
+    requiresS256: false, 
+    tokenCID: "name",
+  }
+);

After (v3.x):

typescript
const authorizationServer = new AuthorizationServer(
+  clientRepository,
+  accessTokenRepository,
+  scopeRepository,
+  new JwtService("secret-key"),
+  {
+    requiresS256: true,  
+    tokenCID: "id",
+  }
+);

Enabling Grants

In v3, enableGrantType has been updated for the "authorization_code" and "password" grants.

Authorization Code Grant

AuthorizationCodeGrant now requires a AuthorizationCodeRepository and a UserRepository.

Before (v2.x):

typescript
authorizationServer.enableGrantType("authorization_code");

After (v3.x):

typescript
authorizationServer.enableGrantType({
+  grant: "authorization_code",
+  userRepository, 
+  authorizationCodeRepository,
+});

Password Grant

PasswordGrant now requires a UserRepository.

Before (v2.x):

typescript
authorizationServer.enableGrantType("password");

After (v3.x):

typescript
authorizationServer.enableGrantType({
+  grant: "password",
+  userRepository, 
+});

AuthorizationServerOptions Default Configuration Updates

The default options for AuthorizationServer have been modified to better align with the OAuth 2.0 specification:

Optionv2.x Valuev3.x Value
requiresS256falsetrue
tokenCID"name""id"

Removed setOptions Method

The undocumented, public method setOptions has been removed in v3. Options can be set during AuthorizationServer initialization.

generateRandomToken Function Fix

A bug in the generateRandomToken function has been fixed in v3.x.

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/repositories/index.html b/repositories/index.html new file mode 100644 index 00000000..64e9f7ca --- /dev/null +++ b/repositories/index.html @@ -0,0 +1,118 @@ + + + + + + Repository Interfaces | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Repository Interfaces

Auth Code Repository

OAuthAuthCodeRepository interface is utilized for managing OAuth authorization codes. It contains methods for retrieving an authorization code entity by its identifier, issuing a new authorization code, persisting an authorization code in the storage, checking if an authorization code has been revoked, and revoking an authorization code.

typescript
interface OAuthAuthCodeRepository {
+
+  // Fetch auth code entity from storage by code
+  getByIdentifier(authCodeCode: string): Promise<OAuthAuthCode>;
+
+  // An async call that should return an OAuthAuthCode that has not been 
+  // persisted to storage yet.
+  issueAuthCode(
+    client: OAuthClient, 
+    user: OAuthUser | undefined, 
+    scopes: OAuthScope[]
+  ): OAuthAuthCode | Promise<OAuthAuthCode>;
+
+  // An async call that should persist an OAuthAuthCode into your storage.
+  persist(authCode: OAuthAuthCode): Promise<void>;
+
+  // This async method is called when an auth code is validated by the 
+  // authorization server. Return `true` if the auth code has been 
+  // manually revoked. If the code is still valid return `false`
+  isRevoked(authCodeCode: string): Promise<boolean>;
+
+  revoke(authCodeCode: string): Promise<void>;
+}

Client Repository

OAuthClientRepository interface is used for managing OAuth clients. It includes methods for fetching a client entity from storage by the client ID and for validating the client using the grant type and client secret.

typescript
interface OAuthClientRepository {
+  // Fetch client entity from storage by client_id
+  getByIdentifier(clientId: string): Promise<OAuthClient>;
+
+  // check the grant type and secret against the client
+  isClientValid(
+    grantType: GrantIdentifier, 
+    client: OAuthClient, 
+    clientSecret?: string
+  ): Promise<boolean>;
+}

Scope Repository

The OAuthScopeRepository interface handles scope management. It defines methods for finding all scopes by their names and for finalizing the scopes. In the finalization, additional scopes can be added or removed after they've been validated against the client scopes.

typescript
interface OAuthScopeRepository {
+  // Find all scopes by scope names
+  getAllByIdentifiers(scopeNames: string[]): Promise<OAuthScope[]>;
+
+  // Scopes have already been validated against the client, if you arent 
+  // doing anything fancy with scopes, you can just `return scopes`,
+  // Otherwise, now is your chance to add or remove any final scopes 
+  // after they have already been validated against the client scopes
+  finalize(
+    scopes: OAuthScope[],
+    identifier: GrantIdentifier,
+    client: OAuthClient,
+    user_id?: string,
+  ): Promise<OAuthScope[]>;
+}

Token Repository

OAuthTokenRepository interface manages OAuth tokens. It contains methods for issuing a new token, persisting a token in the storage, issuing a refresh token, revoking tokens, and fetching a refresh token entity by the refresh token.

typescript
interface OAuthTokenRepository {
+  // An async call that should return an OAuthToken that has not been 
+  // persisted to storage yet.
+  issueToken(
+    client: OAuthClient,
+    scopes: OAuthScope[],
+    user?: OAuthUser
+  ): Promise<OAuthToken>;
+
+  // An async call that should persist an OAuthToken into your storage.
+  persist(accessToken: OAuthToken): Promise<void>;
+
+  // An async call that enhances an already-persisted OAuthToken with
+  // refresh token fields.
+  issueRefreshToken(
+    accessToken: OAuthToken,
+    client: OAuthClient,
+  ): Promise<OAuthToken>
+
+  // This async method is called when a refresh token is used to reissue 
+  // an access token. The original access token is revoked, and a new
+  // access token is issued.
+  revoke(accessToken: OAuthToken): Promise<void>;
+
+  // This async method, if implemented, will be called by the authorization
+  // code grant if the original authorization code is reused.
+  // See https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2 for why.
+  revokeDescendantsOf?(authCodeId: string): Promise<void>;
+
+  // This async method is called when an access token is validated by the 
+  // authorization server. Return `true` if the access token has been 
+  // manually revoked. If the token is still valid return `false`
+  isRefreshTokenRevoked(refreshToken: OAuthToken): Promise<boolean>;
+
+  // Fetch refresh token entity from storage by refresh token
+  getByRefreshToken(refreshTokenToken: string): Promise<OAuthToken>;
+}

User Repository

The OAuthUserRepository interface handles user management. It defines methods for fetching a user entity from storage by their credentials and optional grant type and client. This may involve validating the user's credentials.

typescript
interface OAuthUserRepository {
+
+  // Fetch user entity from storage by identifier. A provided password may 
+  // be used to validate the users credentials. Grant type and client are provided
+  // for additional checks if desired
+  getUserByCredentials(
+    identifier: string,
+    password?: string,
+    grantType?: GrantIdentifier,
+    client?: OAuthClient,
+  ): Promise<OAuthUser | undefined>;
+}

Released under the MIT License.

+ + + + \ No newline at end of file diff --git a/sources/index.html b/sources/index.html new file mode 100644 index 00000000..64382ede --- /dev/null +++ b/sources/index.html @@ -0,0 +1,25 @@ + + + + + + Sources | @jmondi/oauth2-server + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/utils/index.html b/utils/index.html new file mode 100644 index 00000000..73eb7754 --- /dev/null +++ b/utils/index.html @@ -0,0 +1,34 @@ + + + + + + Utils | @jmondi/oauth2-server + + + + + + + + + + + + + + +
Skip to content

Utils

JwtService

@see JwtService

Using jsonwebtoken

Example Extra Params Usage

typescript
import { JwtService } from '@jmondi/oauth2-server';
+
+export class MyCustomJwtService extends JwtService {
+  extraTokenFields({ user, client }: ExtraAccessTokenFieldArgs) {
+    return {
+      email: user?.email,
+      client_id: client.id,
+    }
+  }
+}

DateInterval

using ms

Released under the MIT License.

+ + + + \ No newline at end of file