diff --git a/404.html b/404.html new file mode 100644 index 0000000..27da2a0 --- /dev/null +++ b/404.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + +

404

There's nothing here.
Take me home
+ + + diff --git a/assets/404.html-CB0hfWEP.js b/assets/404.html-CB0hfWEP.js new file mode 100644 index 0000000..9a28be3 --- /dev/null +++ b/assets/404.html-CB0hfWEP.js @@ -0,0 +1 @@ +import{_ as e,c as o,e as n,o as a}from"./app-Djq7wF8p.js";const l={};function r(s,t){return a(),o("div",null,t[0]||(t[0]=[n("p",null,"404 Not Found",-1)]))}const _=e(l,[["render",r],["__file","404.html.vue"]]),i=JSON.parse('{"path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"filePathRelative":null}');export{_ as comp,i as data}; diff --git a/assets/Androidmakers2023Kotlinshortlink-7XGfMd7N.svg b/assets/Androidmakers2023Kotlinshortlink-7XGfMd7N.svg new file mode 100644 index 0000000..53959f7 --- /dev/null +++ b/assets/Androidmakers2023Kotlinshortlink-7XGfMd7N.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/Kotlin-Beyond-Android-B6J4ER4N.png b/assets/Kotlin-Beyond-Android-B6J4ER4N.png new file mode 100644 index 0000000..cb22227 Binary files /dev/null and b/assets/Kotlin-Beyond-Android-B6J4ER4N.png differ diff --git a/assets/Kotlin-Beyond-Android-CYulNy7n.js b/assets/Kotlin-Beyond-Android-CYulNy7n.js new file mode 100644 index 0000000..38cc57e --- /dev/null +++ b/assets/Kotlin-Beyond-Android-CYulNy7n.js @@ -0,0 +1 @@ +const n="/learning-kotlin/assets/Kotlin-Beyond-Android-B6J4ER4N.png";export{n as _}; diff --git a/assets/app-Djq7wF8p.js b/assets/app-Djq7wF8p.js new file mode 100644 index 0000000..e316fc8 --- /dev/null +++ b/assets/app-Djq7wF8p.js @@ -0,0 +1,43 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index.html-28L8qS8U.js","assets/logo_worldline-dinT9MYm.js","assets/index.html-Dz4P2gMg.js","assets/index.html-zXMBiwyM.js","assets/kotlin-wasm-webapp-R4_9ho9v.js","assets/index.html-CcuJhM9n.js","assets/kmp_codelab-CiTPMWjt.js","assets/index.html-D-c6bFFq.js","assets/kotlin-used-for-Bdlavnqs.js","assets/index.html-CIUQNmed.js","assets/Kotlin-Beyond-Android-CYulNy7n.js","assets/index.html-BHDS7_46.js","assets/index.html-BZTbG60u.js","assets/index.html-BwZborl3.js","assets/index.html-jwVfesBb.js"])))=>i.map(i=>d[i]); +const ld="modulepreload",ad=function(e){return"/learning-kotlin/"+e},Wi={},De=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const i=document.querySelector("meta[property=csp-nonce]"),l=(i==null?void 0:i.nonce)||(i==null?void 0:i.getAttribute("nonce"));o=Promise.allSettled(n.map(a=>{if(a=ad(a),a in Wi)return;Wi[a]=!0;const u=a.endsWith(".css"),f=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${f}`))return;const c=document.createElement("link");if(c.rel=u?"stylesheet":ld,u||(c.as="script"),c.crossOrigin="",c.href=a,l&&c.setAttribute("nonce",l),document.head.appendChild(c),u)return new Promise((d,p)=>{c.addEventListener("load",d),c.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${a}`)))})}))}function s(i){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=i,window.dispatchEvent(l),!l.defaultPrevented)throw i}return o.then(i=>{for(const l of i||[])l.status==="rejected"&&s(l.reason);return t().catch(s)})};/** +* @vue/shared v3.5.10 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function Yn(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const ke={},Dn=[],Tt=()=>{},ud=()=>!1,Mr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Xs=e=>e.startsWith("onUpdate:"),Fe=Object.assign,Js=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},cd=Object.prototype.hasOwnProperty,ge=(e,t)=>cd.call(e,t),re=Array.isArray,Nn=e=>xo(e)==="[object Map]",hu=e=>xo(e)==="[object Set]",oe=e=>typeof e=="function",xe=e=>typeof e=="string",cn=e=>typeof e=="symbol",Ce=e=>e!==null&&typeof e=="object",mu=e=>(Ce(e)||oe(e))&&oe(e.then)&&oe(e.catch),gu=Object.prototype.toString,xo=e=>gu.call(e),fd=e=>xo(e).slice(8,-1),vu=e=>xo(e)==="[object Object]",Zs=e=>xe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Vn=Yn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),To=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},dd=/-(\w)/g,rt=To(e=>e.replace(dd,(t,n)=>n?n.toUpperCase():"")),pd=/\B([A-Z])/g,Ht=To(e=>e.replace(pd,"-$1").toLowerCase()),Fr=To(e=>e.charAt(0).toUpperCase()+e.slice(1)),Jo=To(e=>e?`on${Fr(e)}`:""),nn=(e,t)=>!Object.is(e,t),Zo=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},hd=e=>{const t=parseFloat(e);return isNaN(t)?e:t},md=e=>{const t=xe(e)?Number(e):NaN;return isNaN(t)?e:t};let qi;const _u=()=>qi||(qi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Xn(e){if(re(e)){const t={};for(let n=0;n{if(n){const r=n.split(vd);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function bd(e){let t="";if(!e||xe(e))return t;for(const n in e){const r=e[n];if(xe(r)||typeof r=="number"){const o=n.startsWith("--")?n:Ht(n);t+=`${o}:${r};`}}return t}function nt(e){let t="";if(xe(e))t=e;else if(re(e))for(let n=0;n?@[\\\]^`{|}~]/g;function Cd(e,t){return e.replace(Ad,n=>`\\${n}`)}const bu=e=>!!(e&&e.__v_isRef===!0),Ie=e=>xe(e)?e:e==null?"":re(e)||Ce(e)&&(e.toString===gu||!oe(e.toString))?bu(e)?Ie(e.value):JSON.stringify(e,Eu,2):String(e),Eu=(e,t)=>bu(t)?Eu(e,t.value):Nn(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,o],s)=>(n[Qo(r,s)+" =>"]=o,n),{})}:hu(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Qo(n))}:cn(t)?Qo(t):Ce(t)&&!re(t)&&!vu(t)?String(t):t,Qo=(e,t="")=>{var n;return cn(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.10 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Xe;class xd{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=Xe,!t&&Xe&&(this.index=(Xe.scopes||(Xe.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0)return;let e;for(;Ln;){let t=Ln,n;for(;t;)t.flags&1||(t.flags&=-9),t=t.next;for(t=Ln,Ln=void 0;t;){if(n=t.next,t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(r){e||(e=r)}t=n}}if(e)throw e}function Cu(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function xu(e){let t,n=e.depsTail,r=n;for(;r;){const o=r.prevDep;r.version===-1?(r===n&&(n=o),ni(r),Od(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0,r=o}e.deps=t,e.depsTail=n}function ks(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Tu(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Tu(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===kr))return;e.globalVersion=kr;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!ks(e)){e.flags&=-3;return}const n=we,r=_t;we=e,_t=!0;try{Cu(e);const o=e.fn(e._value);(t.version===0||nn(o,e._value))&&(e._value=o,t.version++)}catch(o){throw t.version++,o}finally{we=n,_t=r,xu(e),e.flags&=-3}}function ni(e,t=!1){const{dep:n,prevSub:r,nextSub:o}=e;if(r&&(r.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r),!n.subs&&n.computed){n.computed.flags&=-5;for(let s=n.computed.deps;s;s=s.nextDep)ni(s,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function Od(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let _t=!0;const Ou=[];function $t(){Ou.push(_t),_t=!1}function Ut(){const e=Ou.pop();_t=e===void 0?!0:e}function Yi(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=we;we=void 0;try{t()}finally{we=n}}}let kr=0;class Pd{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Oo{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.target=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!we||!_t||we===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==we)n=this.activeLink=new Pd(we,this),we.deps?(n.prevDep=we.depsTail,we.depsTail.nextDep=n,we.depsTail=n):we.deps=we.depsTail=n,Pu(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const r=n.nextDep;r.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=r),n.prevDep=we.depsTail,n.nextDep=void 0,we.depsTail.nextDep=n,we.depsTail=n,we.deps===n&&(we.deps=r)}return n}trigger(t){this.version++,kr++,this.notify(t)}notify(t){ei();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{ti()}}}function Pu(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let r=t.deps;r;r=r.nextDep)Pu(r)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const go=new WeakMap,Sn=Symbol(""),Ss=Symbol(""),Sr=Symbol("");function Ge(e,t,n){if(_t&&we){let r=go.get(e);r||go.set(e,r=new Map);let o=r.get(n);o||(r.set(n,o=new Oo),o.target=e,o.map=r,o.key=n),o.track()}}function Bt(e,t,n,r,o,s){const i=go.get(e);if(!i){kr++;return}const l=a=>{a&&a.trigger()};if(ei(),t==="clear")i.forEach(l);else{const a=re(e),u=a&&Zs(n);if(a&&n==="length"){const f=Number(r);i.forEach((c,d)=>{(d==="length"||d===Sr||!cn(d)&&d>=f)&&l(c)})}else switch(n!==void 0&&l(i.get(n)),u&&l(i.get(Sr)),t){case"add":a?u&&l(i.get("length")):(l(i.get(Sn)),Nn(e)&&l(i.get(Ss)));break;case"delete":a||(l(i.get(Sn)),Nn(e)&&l(i.get(Ss)));break;case"set":Nn(e)&&l(i.get(Sn));break}}ti()}function Id(e,t){const n=go.get(e);return n&&n.get(t)}function Tn(e){const t=fe(e);return t===e?t:(Ge(t,"iterate",Sr),ht(e)?t:t.map(We))}function Po(e){return Ge(e=fe(e),"iterate",Sr),e}const Ld={__proto__:null,[Symbol.iterator](){return ts(this,Symbol.iterator,We)},concat(...e){return Tn(this).concat(...e.map(t=>re(t)?Tn(t):t))},entries(){return ts(this,"entries",e=>(e[1]=We(e[1]),e))},every(e,t){return Lt(this,"every",e,t,void 0,arguments)},filter(e,t){return Lt(this,"filter",e,t,n=>n.map(We),arguments)},find(e,t){return Lt(this,"find",e,t,We,arguments)},findIndex(e,t){return Lt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Lt(this,"findLast",e,t,We,arguments)},findLastIndex(e,t){return Lt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Lt(this,"forEach",e,t,void 0,arguments)},includes(...e){return ns(this,"includes",e)},indexOf(...e){return ns(this,"indexOf",e)},join(e){return Tn(this).join(e)},lastIndexOf(...e){return ns(this,"lastIndexOf",e)},map(e,t){return Lt(this,"map",e,t,void 0,arguments)},pop(){return sr(this,"pop")},push(...e){return sr(this,"push",e)},reduce(e,...t){return Xi(this,"reduce",e,t)},reduceRight(e,...t){return Xi(this,"reduceRight",e,t)},shift(){return sr(this,"shift")},some(e,t){return Lt(this,"some",e,t,void 0,arguments)},splice(...e){return sr(this,"splice",e)},toReversed(){return Tn(this).toReversed()},toSorted(e){return Tn(this).toSorted(e)},toSpliced(...e){return Tn(this).toSpliced(...e)},unshift(...e){return sr(this,"unshift",e)},values(){return ts(this,"values",We)}};function ts(e,t,n){const r=Po(e),o=r[t]();return r!==e&&!ht(e)&&(o._next=o.next,o.next=()=>{const s=o._next();return s.value&&(s.value=n(s.value)),s}),o}const Rd=Array.prototype;function Lt(e,t,n,r,o,s){const i=Po(e),l=i!==e&&!ht(e),a=i[t];if(a!==Rd[t]){const c=a.apply(e,s);return l?We(c):c}let u=n;i!==e&&(l?u=function(c,d){return n.call(this,We(c),d,e)}:n.length>2&&(u=function(c,d){return n.call(this,c,d,e)}));const f=a.call(i,u,r);return l&&o?o(f):f}function Xi(e,t,n,r){const o=Po(e);let s=n;return o!==e&&(ht(e)?n.length>3&&(s=function(i,l,a){return n.call(this,i,l,a,e)}):s=function(i,l,a){return n.call(this,i,We(l),a,e)}),o[t](s,...r)}function ns(e,t,n){const r=fe(e);Ge(r,"iterate",Sr);const o=r[t](...n);return(o===-1||o===!1)&&ii(n[0])?(n[0]=fe(n[0]),r[t](...n)):o}function sr(e,t,n=[]){$t(),ei();const r=fe(e)[t].apply(e,n);return ti(),Ut(),r}const Dd=Yn("__proto__,__v_isRef,__isVue"),Iu=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(cn));function Nd(e){cn(e)||(e=String(e));const t=fe(this);return Ge(t,"has",e),t.hasOwnProperty(e)}class Lu{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){const o=this._isReadonly,s=this._isShallow;if(n==="__v_isReactive")return!o;if(n==="__v_isReadonly")return o;if(n==="__v_isShallow")return s;if(n==="__v_raw")return r===(o?s?Gd:Vu:s?Nu:Du).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const i=re(t);if(!o){let a;if(i&&(a=Ld[n]))return a;if(n==="hasOwnProperty")return Nd}const l=Reflect.get(t,n,Ne(t)?t:r);return(cn(n)?Iu.has(n):Dd(n))||(o||Ge(t,"get",n),s)?l:Ne(l)?i&&Zs(n)?l:l.value:Ce(l)?o?Lo(l):Br(l):l}}class Ru extends Lu{constructor(t=!1){super(!1,t)}set(t,n,r,o){let s=t[n];if(!this._isShallow){const a=Cn(s);if(!ht(r)&&!Cn(r)&&(s=fe(s),r=fe(r)),!re(t)&&Ne(s)&&!Ne(r))return a?!1:(s.value=r,!0)}const i=re(t)&&Zs(n)?Number(n)e,Io=e=>Reflect.getPrototypeOf(e);function qr(e,t,n=!1,r=!1){e=e.__v_raw;const o=fe(e),s=fe(t);n||(nn(t,s)&&Ge(o,"get",t),Ge(o,"get",s));const{has:i}=Io(o),l=r?ri:n?li:We;if(i.call(o,t))return l(e.get(t));if(i.call(o,s))return l(e.get(s));e!==o&&e.get(t)}function Gr(e,t=!1){const n=this.__v_raw,r=fe(n),o=fe(e);return t||(nn(e,o)&&Ge(r,"has",e),Ge(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Yr(e,t=!1){return e=e.__v_raw,!t&&Ge(fe(e),"iterate",Sn),Reflect.get(e,"size",e)}function Ji(e,t=!1){!t&&!ht(e)&&!Cn(e)&&(e=fe(e));const n=fe(this);return Io(n).has.call(n,e)||(n.add(e),Bt(n,"add",e,e)),this}function Zi(e,t,n=!1){!n&&!ht(t)&&!Cn(t)&&(t=fe(t));const r=fe(this),{has:o,get:s}=Io(r);let i=o.call(r,e);i||(e=fe(e),i=o.call(r,e));const l=s.call(r,e);return r.set(e,t),i?nn(t,l)&&Bt(r,"set",e,t):Bt(r,"add",e,t),this}function Qi(e){const t=fe(this),{has:n,get:r}=Io(t);let o=n.call(t,e);o||(e=fe(e),o=n.call(t,e)),r&&r.call(t,e);const s=t.delete(e);return o&&Bt(t,"delete",e,void 0),s}function el(){const e=fe(this),t=e.size!==0,n=e.clear();return t&&Bt(e,"clear",void 0,void 0),n}function Xr(e,t){return function(r,o){const s=this,i=s.__v_raw,l=fe(i),a=t?ri:e?li:We;return!e&&Ge(l,"iterate",Sn),i.forEach((u,f)=>r.call(o,a(u),a(f),s))}}function Jr(e,t,n){return function(...r){const o=this.__v_raw,s=fe(o),i=Nn(s),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,u=o[e](...r),f=n?ri:t?li:We;return!t&&Ge(s,"iterate",a?Ss:Sn),{next(){const{value:c,done:d}=u.next();return d?{value:c,done:d}:{value:l?[f(c[0]),f(c[1])]:f(c),done:d}},[Symbol.iterator](){return this}}}}function Kt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function Hd(){const e={get(s){return qr(this,s)},get size(){return Yr(this)},has:Gr,add:Ji,set:Zi,delete:Qi,clear:el,forEach:Xr(!1,!1)},t={get(s){return qr(this,s,!1,!0)},get size(){return Yr(this)},has:Gr,add(s){return Ji.call(this,s,!0)},set(s,i){return Zi.call(this,s,i,!0)},delete:Qi,clear:el,forEach:Xr(!1,!0)},n={get(s){return qr(this,s,!0)},get size(){return Yr(this,!0)},has(s){return Gr.call(this,s,!0)},add:Kt("add"),set:Kt("set"),delete:Kt("delete"),clear:Kt("clear"),forEach:Xr(!0,!1)},r={get(s){return qr(this,s,!0,!0)},get size(){return Yr(this,!0)},has(s){return Gr.call(this,s,!0)},add:Kt("add"),set:Kt("set"),delete:Kt("delete"),clear:Kt("clear"),forEach:Xr(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(s=>{e[s]=Jr(s,!1,!1),n[s]=Jr(s,!0,!1),t[s]=Jr(s,!1,!0),r[s]=Jr(s,!0,!0)}),[e,n,t,r]}const[$d,Ud,jd,zd]=Hd();function oi(e,t){const n=t?e?zd:jd:e?Ud:$d;return(r,o,s)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(ge(n,o)&&o in r?n:r,o,s)}const Kd={get:oi(!1,!1)},Wd={get:oi(!1,!0)},qd={get:oi(!0,!1)};const Du=new WeakMap,Nu=new WeakMap,Vu=new WeakMap,Gd=new WeakMap;function Yd(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Xd(e){return e.__v_skip||!Object.isExtensible(e)?0:Yd(fd(e))}function Br(e){return Cn(e)?e:si(e,!1,Md,Kd,Du)}function Mu(e){return si(e,!1,Bd,Wd,Nu)}function Lo(e){return si(e,!0,Fd,qd,Vu)}function si(e,t,n,r,o){if(!Ce(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const s=o.get(e);if(s)return s;const i=Xd(e);if(i===0)return e;const l=new Proxy(e,i===2?r:n);return o.set(e,l),l}function Mn(e){return Cn(e)?Mn(e.__v_raw):!!(e&&e.__v_isReactive)}function Cn(e){return!!(e&&e.__v_isReadonly)}function ht(e){return!!(e&&e.__v_isShallow)}function ii(e){return e?!!e.__v_raw:!1}function fe(e){const t=e&&e.__v_raw;return t?fe(t):e}function Jd(e){return!ge(e,"__v_skip")&&Object.isExtensible(e)&&jn(e,"__v_skip",!0),e}const We=e=>Ce(e)?Br(e):e,li=e=>Ce(e)?Lo(e):e;function Ne(e){return e?e.__v_isRef===!0:!1}function ce(e){return Fu(e,!1)}function Ot(e){return Fu(e,!0)}function Fu(e,t){return Ne(e)?e:new Zd(e,t)}class Zd{constructor(t,n){this.dep=new Oo,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:fe(t),this._value=n?t:We(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,r=this.__v_isShallow||ht(t)||Cn(t);t=r?t:fe(t),nn(t,n)&&(this._rawValue=t,this._value=r?t:We(t),this.dep.trigger())}}function Qt(e){return Ne(e)?e.value:e}const Qd={get:(e,t,n)=>t==="__v_raw"?e:Qt(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return Ne(o)&&!Ne(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function Bu(e){return Mn(e)?e:new Proxy(e,Qd)}class ep{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Oo,{get:r,set:o}=t(n.track.bind(n),n.trigger.bind(n));this._get=r,this._set=o}get value(){return this._value=this._get()}set value(t){this._set(t)}}function tp(e){return new ep(e)}function ai(e){const t=re(e)?new Array(e.length):{};for(const n in e)t[n]=Hu(e,n);return t}class np{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return Id(fe(this._object),this._key)}}class rp{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function op(e,t,n){return Ne(e)?e:oe(e)?new rp(e):Ce(e)&&arguments.length>1?Hu(e,t,n):ce(e)}function Hu(e,t,n){const r=e[t];return Ne(r)?r:new np(e,t,n)}class sp{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Oo(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=kr-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=r}notify(){if(this.flags|=16,!(this.flags&8)&&we!==this)return Au(this),!0}get value(){const t=this.dep.track();return Tu(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function ip(e,t,n=!1){let r,o;return oe(e)?r=e:(r=e.get,o=e.set),new sp(r,o,n)}const Zr={},vo=new WeakMap;let vn;function lp(e,t=!1,n=vn){if(n){let r=vo.get(n);r||vo.set(n,r=[]),r.push(e)}}function ap(e,t,n=ke){const{immediate:r,deep:o,once:s,scheduler:i,augmentJob:l,call:a}=n,u=b=>o?b:ht(b)||o===!1||o===0?Ft(b,1):Ft(b);let f,c,d,p,v=!1,_=!1;if(Ne(e)?(c=()=>e.value,v=ht(e)):Mn(e)?(c=()=>u(e),v=!0):re(e)?(_=!0,v=e.some(b=>Mn(b)||ht(b)),c=()=>e.map(b=>{if(Ne(b))return b.value;if(Mn(b))return u(b);if(oe(b))return a?a(b,2):b()})):oe(e)?t?c=a?()=>a(e,2):e:c=()=>{if(d){$t();try{d()}finally{Ut()}}const b=vn;vn=f;try{return a?a(e,3,[p]):e(p)}finally{vn=b}}:c=Tt,t&&o){const b=c,R=o===!0?1/0:o;c=()=>Ft(b(),R)}const y=ku(),E=()=>{f.stop(),y&&Js(y.effects,f)};if(s&&t){const b=t;t=(...R)=>{b(...R),E()}}let S=_?new Array(e.length).fill(Zr):Zr;const h=b=>{if(!(!(f.flags&1)||!f.dirty&&!b))if(t){const R=f.run();if(o||v||(_?R.some((j,M)=>nn(j,S[M])):nn(R,S))){d&&d();const j=vn;vn=f;try{const M=[R,S===Zr?void 0:_&&S[0]===Zr?[]:S,p];a?a(t,3,M):t(...M),S=R}finally{vn=j}}}else f.run()};return l&&l(h),f=new Su(c),f.scheduler=i?()=>i(h,!1):h,p=b=>lp(b,!1,f),d=f.onStop=()=>{const b=vo.get(f);if(b){if(a)a(b,4);else for(const R of b)R();vo.delete(f)}},t?r?h(!0):S=f.run():i?i(h.bind(null,!0),!0):f.run(),E.pause=f.pause.bind(f),E.resume=f.resume.bind(f),E.stop=E,E}function Ft(e,t=1/0,n){if(t<=0||!Ce(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,Ne(e))Ft(e.value,t,n);else if(re(e))for(let r=0;r{Ft(r,t,n)});else if(vu(e)){for(const r in e)Ft(e[r],t,n);for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&Ft(e[r],t,n)}return e}/** +* @vue/runtime-core v3.5.10 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const gr=[];let rs=!1;function Gt(e,...t){if(rs)return;rs=!0,$t();const n=gr.length?gr[gr.length-1].component:null,r=n&&n.appContext.config.warnHandler,o=up();if(r)Jn(r,n,11,[e+t.map(s=>{var i,l;return(l=(i=s.toString)==null?void 0:i.call(s))!=null?l:JSON.stringify(s)}).join(""),n&&n.proxy,o.map(({vnode:s})=>`at <${Tc(n,s.type)}>`).join(` +`),o]);else{const s=[`[Vue warn]: ${e}`,...t];o.length&&s.push(` +`,...cp(o)),console.warn(...s)}Ut(),rs=!1}function up(){let e=gr[gr.length-1];if(!e)return[];const t=[];for(;e;){const n=t[0];n&&n.vnode===e?n.recurseCount++:t.push({vnode:e,recurseCount:0});const r=e.component&&e.component.parent;e=r&&r.vnode}return t}function cp(e){const t=[];return e.forEach((n,r)=>{t.push(...r===0?[]:[` +`],...fp(n))}),t}function fp({vnode:e,recurseCount:t}){const n=t>0?`... (${t} recursive calls)`:"",r=e.component?e.component.parent==null:!1,o=` at <${Tc(e.component,e.type,r)}`,s=">"+n;return e.props?[o,...dp(e.props),s]:[o+s]}function dp(e){const t=[],n=Object.keys(e);return n.slice(0,3).forEach(r=>{t.push(...$u(r,e[r]))}),n.length>3&&t.push(" ..."),t}function $u(e,t,n){return xe(t)?(t=JSON.stringify(t),n?t:[`${e}=${t}`]):typeof t=="number"||typeof t=="boolean"||t==null?n?t:[`${e}=${t}`]:Ne(t)?(t=$u(e,fe(t.value),!0),n?t:[`${e}=Ref<`,t,">"]):oe(t)?[`${e}=fn${t.name?`<${t.name}>`:""}`]:(t=fe(t),n?t:[`${e}=`,t])}function Jn(e,t,n,r){try{return r?e(...r):e()}catch(o){Hr(o,t,n)}}function yt(e,t,n,r){if(oe(e)){const o=Jn(e,t,n,r);return o&&mu(o)&&o.catch(s=>{Hr(s,t,n)}),o}if(re(e)){const o=[];for(let s=0;s>>1,o=Je[r],s=Ar(o);s=Ar(n)?Je.push(e):Je.splice(hp(t),0,e),e.flags|=1,ju()}}function ju(){!wr&&!ws&&(ws=!0,ui=Uu.then(zu))}function mp(e){re(e)?Fn.push(...e):Yt&&e.id===-1?Yt.splice(In+1,0,e):e.flags&1||(Fn.push(e),e.flags|=1),ju()}function tl(e,t,n=wr?wt+1:0){for(;nAr(n)-Ar(r));if(Fn.length=0,Yt){Yt.push(...t);return}for(Yt=t,In=0;Ine.id==null?e.flags&2?-1:1/0:e.id;function zu(e){ws=!1,wr=!0;try{for(wt=0;wtxt.emit(o,...s)),fr=[]):typeof window<"u"&&window.HTMLElement&&!((r=(n=window.navigator)==null?void 0:n.userAgent)!=null&&r.includes("jsdom"))?((t.__VUE_DEVTOOLS_HOOK_REPLAY__=t.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push(s=>{Ku(s,t)}),setTimeout(()=>{xt||(t.__VUE_DEVTOOLS_HOOK_REPLAY__=null,As=!0,fr=[])},3e3)):(As=!0,fr=[])}function gp(e,t){Ro("app:init",e,t,{Fragment:_e,Text:tn,Comment:ze,Static:Hn})}function vp(e){Ro("app:unmount",e)}const _p=fi("component:added"),Wu=fi("component:updated"),yp=fi("component:removed"),bp=e=>{xt&&typeof xt.cleanupBuffer=="function"&&!xt.cleanupBuffer(e)&&yp(e)};/*! #__NO_SIDE_EFFECTS__ */function fi(e){return t=>{Ro(e,t.appContext.app,t.uid,t.parent?t.parent.uid:void 0,t)}}function Ep(e,t,n){Ro("component:emit",e.appContext.app,e,t,n)}let Ue=null,qu=null;function yo(e){const t=Ue;return Ue=e,qu=e&&e.type.__scopeId||null,t}function Ve(e,t=Ue,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&ml(-1);const s=yo(t);let i;try{i=e(...o)}finally{yo(s),r._d&&ml(1)}return Wu(t),i};return r._n=!0,r._c=!0,r._d=!0,r}function bo(e,t){if(Ue===null)return e;const n=Fo(Ue),r=e.dirs||(e.dirs=[]);for(let o=0;oe.__isTeleport,Xt=Symbol("_leaveCb"),Qr=Symbol("_enterCb");function Sp(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Be(()=>{e.isMounted=!0}),No(()=>{e.isUnmounting=!0}),e}const ft=[Function,Array],Yu={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ft,onEnter:ft,onAfterEnter:ft,onEnterCancelled:ft,onBeforeLeave:ft,onLeave:ft,onAfterLeave:ft,onLeaveCancelled:ft,onBeforeAppear:ft,onAppear:ft,onAfterAppear:ft,onAppearCancelled:ft},Xu=e=>{const t=e.subTree;return t.component?Xu(t.component):t},wp={name:"BaseTransition",props:Yu,setup(e,{slots:t}){const n=Ur(),r=Sp();return()=>{const o=t.default&&Qu(t.default(),!0);if(!o||!o.length)return;const s=Ju(o),i=fe(e),{mode:l}=i;if(r.isLeaving)return os(s);const a=nl(s);if(!a)return os(s);let u=Cs(a,i,r,n,d=>u=d);a.type!==ze&&Cr(a,u);const f=n.subTree,c=f&&nl(f);if(c&&c.type!==ze&&!bn(a,c)&&Xu(n).type!==ze){const d=Cs(c,i,r,n);if(Cr(c,d),l==="out-in"&&a.type!==ze)return r.isLeaving=!0,d.afterLeave=()=>{r.isLeaving=!1,n.job.flags&8||n.update(),delete d.afterLeave},os(s);l==="in-out"&&a.type!==ze&&(d.delayLeave=(p,v,_)=>{const y=Zu(r,c);y[String(c.key)]=c,p[Xt]=()=>{v(),p[Xt]=void 0,delete u.delayedLeave},u.delayedLeave=_})}return s}}};function Ju(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ze){t=n;break}}return t}const Ap=wp;function Zu(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function Cs(e,t,n,r,o){const{appear:s,mode:i,persisted:l=!1,onBeforeEnter:a,onEnter:u,onAfterEnter:f,onEnterCancelled:c,onBeforeLeave:d,onLeave:p,onAfterLeave:v,onLeaveCancelled:_,onBeforeAppear:y,onAppear:E,onAfterAppear:S,onAppearCancelled:h}=t,b=String(e.key),R=Zu(n,e),j=(U,x)=>{U&&yt(U,r,9,x)},M=(U,x)=>{const H=x[1];j(U,x),re(U)?U.every(A=>A.length<=1)&&H():U.length<=1&&H()},w={mode:i,persisted:l,beforeEnter(U){let x=a;if(!n.isMounted)if(s)x=y||a;else return;U[Xt]&&U[Xt](!0);const H=R[b];H&&bn(e,H)&&H.el[Xt]&&H.el[Xt](),j(x,[U])},enter(U){let x=u,H=f,A=c;if(!n.isMounted)if(s)x=E||u,H=S||f,A=h||c;else return;let D=!1;const J=U[Qr]=ee=>{D||(D=!0,ee?j(A,[U]):j(H,[U]),w.delayedLeave&&w.delayedLeave(),U[Qr]=void 0)};x?M(x,[U,J]):J()},leave(U,x){const H=String(e.key);if(U[Qr]&&U[Qr](!0),n.isUnmounting)return x();j(d,[U]);let A=!1;const D=U[Xt]=J=>{A||(A=!0,x(),J?j(_,[U]):j(v,[U]),U[Xt]=void 0,R[H]===e&&delete R[H])};R[H]=e,p?M(p,[U,D]):D()},clone(U){const x=Cs(U,t,n,r,o);return o&&o(x),x}};return w}function os(e){if($r(e))return e=on(e),e.children=null,e}function nl(e){if(!$r(e))return Gu(e.type)&&e.children?Ju(e.children):e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&oe(n.default))return n.default()}}function Cr(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Cr(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 Qu(e,t=!1,n){let r=[],o=0;for(let s=0;s1)for(let s=0;sEo(v,t&&(re(t)?t[_]:t),n,r,o));return}if(wn(r)&&!o)return;const s=r.shapeFlag&4?Fo(r.component):r.el,i=o?null:s,{i:l,r:a}=e,u=t&&t.r,f=l.refs===ke?l.refs={}:l.refs,c=l.setupState,d=fe(c),p=c===ke?()=>!1:v=>ge(d,v);if(u!=null&&u!==a&&(xe(u)?(f[u]=null,p(u)&&(c[u]=null)):Ne(u)&&(u.value=null)),oe(a))Jn(a,l,12,[i,f]);else{const v=xe(a),_=Ne(a);if(v||_){const y=()=>{if(e.f){const E=v?p(a)?c[a]:f[a]:a.value;o?re(E)&&Js(E,s):re(E)?E.includes(s)||E.push(s):v?(f[a]=[s],p(a)&&(c[a]=f[a])):(a.value=[s],e.k&&(f[e.k]=a.value))}else v?(f[a]=i,p(a)&&(c[a]=i)):_&&(a.value=i,e.k&&(f[e.k]=i))};i?(y.id=-1,lt(y,n)):y()}}}let rl=!1;const dn=()=>{rl||(console.error("Hydration completed but contains mismatches."),rl=!0)},Cp=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",xp=e=>e.namespaceURI.includes("MathML"),eo=e=>{if(e.nodeType===1){if(Cp(e))return"svg";if(xp(e))return"mathml"}},yn=e=>e.nodeType===8;function Tp(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:s,parentNode:i,remove:l,insert:a,createComment:u}}=e,f=(h,b)=>{if(!b.hasChildNodes()){Gt("Attempting to hydrate existing markup but container is empty. Performing full mount instead."),n(null,h,b),_o(),b._vnode=h;return}c(b.firstChild,h,null,null,null),_o(),b._vnode=h},c=(h,b,R,j,M,w=!1)=>{w=w||!!b.dynamicChildren;const U=yn(h)&&h.data==="[",x=()=>_(h,b,R,j,M,U),{type:H,ref:A,shapeFlag:D,patchFlag:J}=b;let ee=h.nodeType;b.el=h,jn(h,"__vnode",b,!0),jn(h,"__vueParentComponent",R,!0),J===-2&&(w=!1,b.dynamicChildren=null);let P=null;switch(H){case tn:ee!==3?b.children===""?(a(b.el=o(""),i(h),h),P=h):P=x():(h.data!==b.children&&(Gt("Hydration text mismatch in",h.parentNode,` + - rendered on server: ${JSON.stringify(h.data)} + - expected on client: ${JSON.stringify(b.children)}`),dn(),h.data=b.children),P=s(h));break;case ze:S(h)?(P=s(h),E(b.el=h.content.firstChild,h,R)):ee!==8||U?P=x():P=s(h);break;case Hn:if(U&&(h=s(h),ee=h.nodeType),ee===1||ee===3){P=h;const N=!b.children.length;for(let K=0;K{w=w||!!b.dynamicChildren;const{type:U,props:x,patchFlag:H,shapeFlag:A,dirs:D,transition:J}=b,ee=U==="input"||U==="option";if(ee||H!==-1){D&&At(b,null,R,"created");let P=!1;if(S(h)){P=mc(j,J)&&R&&R.vnode.props&&R.vnode.props.appear;const K=h.content.firstChild;P&&J.beforeEnter(K),E(K,h,R),b.el=h=K}if(A&16&&!(x&&(x.innerHTML||x.textContent))){let K=p(h.firstChild,b,h,R,j,M,w),ue=!1;for(;K;){dr(h,1)||(ue||(Gt("Hydration children mismatch on",h,` +Server rendered element contains more child nodes than client vdom.`),ue=!0),dn());const ye=K;K=K.nextSibling,l(ye)}}else if(A&8){let K=b.children;K[0]===` +`&&(h.tagName==="PRE"||h.tagName==="TEXTAREA")&&(K=K.slice(1)),h.textContent!==K&&(dr(h,0)||(Gt("Hydration text content mismatch on",h,` + - rendered on server: ${h.textContent} + - expected on client: ${b.children}`),dn()),h.textContent=b.children)}if(x){const K=h.tagName.includes("-");for(const ue in x)!(D&&D.some(ye=>ye.dir.created))&&Op(h,ue,x[ue],b,R)&&dn(),(ee&&(ue.endsWith("value")||ue==="indeterminate")||Mr(ue)&&!Vn(ue)||ue[0]==="."||K)&&r(h,ue,null,x[ue],void 0,R)}let N;(N=x&&x.onVnodeBeforeMount)&&dt(N,R,b),D&&At(b,null,R,"beforeMount"),((N=x&&x.onVnodeMounted)||D||P)&&kc(()=>{N&&dt(N,R,b),P&&J.enter(h),D&&At(b,null,R,"mounted")},j)}return h.nextSibling},p=(h,b,R,j,M,w,U)=>{U=U||!!b.dynamicChildren;const x=b.children,H=x.length;let A=!1;for(let D=0;D{const{slotScopeIds:U}=b;U&&(M=M?M.concat(U):U);const x=i(h),H=p(s(h),b,x,R,j,M,w);return H&&yn(H)&&H.data==="]"?s(b.anchor=H):(dn(),a(b.anchor=u("]"),x,H),H)},_=(h,b,R,j,M,w)=>{if(dr(h.parentElement,1)||(Gt(`Hydration node mismatch: +- rendered on server:`,h,h.nodeType===3?"(text)":yn(h)&&h.data==="["?"(start of fragment)":"",` +- expected on client:`,b.type),dn()),b.el=null,w){const H=y(h);for(;;){const A=s(h);if(A&&A!==H)l(A);else break}}const U=s(h),x=i(h);return l(h),n(null,b,x,U,R,j,eo(x),M),U},y=(h,b="[",R="]")=>{let j=0;for(;h;)if(h=s(h),h&&yn(h)&&(h.data===b&&j++,h.data===R)){if(j===0)return s(h);j--}return h},E=(h,b,R)=>{const j=b.parentNode;j&&j.replaceChild(h,b);let M=R;for(;M;)M.vnode.el===b&&(M.vnode.el=M.subTree.el=h),M=M.parent},S=h=>h.nodeType===1&&h.tagName==="TEMPLATE";return[f,c]}function Op(e,t,n,r,o){let s,i,l,a;if(t==="class")l=e.getAttribute("class"),a=nt(n),Pp(ol(l||""),ol(a))||(s=2,i="class");else if(t==="style"){l=e.getAttribute("style")||"",a=xe(n)?n:bd(Xn(n));const u=sl(l),f=sl(a);if(r.dirs)for(const{dir:c,value:d}of r.dirs)c.name==="show"&&!d&&f.set("display","none");o&&ec(o,r,f),Ip(u,f)||(s=3,i="style")}else(e instanceof SVGElement&&Sd(t)||e instanceof HTMLElement&&(Gi(t)||kd(t)))&&(Gi(t)?(l=e.hasAttribute(t),a=Qs(n)):n==null?(l=e.hasAttribute(t),a=!1):(e.hasAttribute(t)?l=e.getAttribute(t):t==="value"&&e.tagName==="TEXTAREA"?l=e.value:l=!1,a=wd(n)?String(n):!1),l!==a&&(s=4,i=t));if(s!=null&&!dr(e,s)){const u=d=>d===!1?"(not rendered)":`${i}="${d}"`,f=`Hydration ${tc[s]} mismatch on`,c=` + - rendered on server: ${u(l)} + - expected on client: ${u(a)} + Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead. + You should fix the source of the mismatch.`;return Gt(f,e,c),!0}return!1}function ol(e){return new Set(e.trim().split(/\s+/))}function Pp(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}function sl(e){const t=new Map;for(const n of e.split(";")){let[r,o]=n.split(":");r=r.trim(),o=o&&o.trim(),r&&o&&t.set(r,o)}return t}function Ip(e,t){if(e.size!==t.size)return!1;for(const[n,r]of e)if(r!==t.get(n))return!1;return!0}function ec(e,t,n){const r=e.subTree;if(e.getCssVars&&(t===r||r&&r.type===_e&&r.children.includes(t))){const o=e.getCssVars();for(const s in o)n.set(`--${Cd(s)}`,String(o[s]))}t===r&&e.parent&&ec(e.parent,e.vnode,n)}const il="data-allow-mismatch",tc={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function dr(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(il);)e=e.parentElement;const n=e&&e.getAttribute(il);if(n==null)return!1;if(n==="")return!0;{const r=n.split(",");return t===0&&r.includes("children")?!0:n.split(",").includes(tc[t])}}function Lp(e,t){if(yn(e)&&e.data==="["){let n=1,r=e.nextSibling;for(;r;){if(r.nodeType===1){if(t(r)===!1)break}else if(yn(r))if(r.data==="]"){if(--n===0)break}else r.data==="["&&n++;r=r.nextSibling}}else t(e)}const wn=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function Rp(e){oe(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,hydrate:s,timeout:i,suspensible:l=!0,onError:a}=e;let u=null,f,c=0;const d=()=>(c++,u=null,p()),p=()=>{let v;return u||(v=u=t().catch(_=>{if(_=_ instanceof Error?_:new Error(String(_)),a)return new Promise((y,E)=>{a(_,()=>y(d()),()=>E(_),c+1)});throw _}).then(_=>v!==u&&u?u:(_&&(_.__esModule||_[Symbol.toStringTag]==="Module")&&(_=_.default),f=_,_)))};return he({name:"AsyncComponentWrapper",__asyncLoader:p,__asyncHydrate(v,_,y){const E=s?()=>{const S=s(y,h=>Lp(v,h));S&&(_.bum||(_.bum=[])).push(S)}:y;f?E():p().then(()=>!_.isUnmounted&&E())},get __asyncResolved(){return f},setup(){const v=$e;if(di(v),f)return()=>ss(f,v);const _=h=>{u=null,Hr(h,v,13,!r)};if(l&&v.suspense||zr)return p().then(h=>()=>ss(h,v)).catch(h=>(_(h),()=>r?ae(r,{error:h}):null));const y=ce(!1),E=ce(),S=ce(!!o);return o&&setTimeout(()=>{S.value=!1},o),i!=null&&setTimeout(()=>{if(!y.value&&!E.value){const h=new Error(`Async component timed out after ${i}ms.`);_(h),E.value=h}},i),p().then(()=>{y.value=!0,v.parent&&$r(v.parent.vnode)&&v.parent.update()}).catch(h=>{_(h),E.value=h}),()=>{if(y.value&&f)return ss(f,v);if(E.value&&r)return ae(r,{error:E.value});if(n&&!S.value)return ae(n)}}})}function ss(e,t){const{ref:n,props:r,children:o,ce:s}=t.vnode,i=ae(e,r,o);return i.ref=n,i.ce=s,delete t.vnode.ce,i}const $r=e=>e.type.__isKeepAlive;function Dp(e,t){nc(e,"a",t)}function Np(e,t){nc(e,"da",t)}function nc(e,t,n=$e){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Do(t,r,n),n){let o=n.parent;for(;o&&o.parent;)$r(o.parent.vnode)&&Vp(r,t,n,o),o=o.parent}}function Vp(e,t,n,r){const o=Do(t,e,r,!0);Vo(()=>{Js(r[t],o)},n)}function Do(e,t,n=$e,r=!1){if(n){const o=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...i)=>{$t();const l=jr(n),a=yt(t,n,e,i);return l(),Ut(),a});return r?o.unshift(s):o.push(s),s}}const jt=e=>(t,n=$e)=>{(!zr||e==="sp")&&Do(e,(...r)=>t(...r),n)},Mp=jt("bm"),Be=jt("m"),Fp=jt("bu"),Bp=jt("u"),No=jt("bum"),Vo=jt("um"),Hp=jt("sp"),$p=jt("rtg"),Up=jt("rtc");function jp(e,t=$e){Do("ec",e,t)}const zp="components";function pi(e,t){return Wp(zp,e,!0,t)||e}const Kp=Symbol.for("v-ndc");function Wp(e,t,n=!0,r=!1){const o=Ue||$e;if(o){const s=o.type;{const l=xc(s,!1);if(l&&(l===t||l===rt(t)||l===Fr(rt(t))))return s}const i=ll(o[e]||s[e],t)||ll(o.appContext[e],t);return!i&&r?s:i}}function ll(e,t){return e&&(e[t]||e[rt(t)]||e[Fr(rt(t))])}function rn(e,t,n,r){let o;const s=n,i=re(e);if(i||xe(e)){const l=i&&Mn(e);let a=!1;l&&(a=!ht(e),e=Po(e)),o=new Array(e.length);for(let u=0,f=e.length;ut(l,a,void 0,s));else{const l=Object.keys(e);o=new Array(l.length);for(let a=0,u=l.length;aTr(t)?!(t.type===ze||t.type===_e&&!rc(t.children)):!0)?e:null}const xs=e=>e?Ac(e)?Fo(e):xs(e.parent):null,vr=Fe(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=>xs(e.parent),$root:e=>xs(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>hi(e),$forceUpdate:e=>e.f||(e.f=()=>{ci(e.update)}),$nextTick:e=>e.n||(e.n=Zn.bind(e.proxy)),$watch:e=>dh.bind(e)}),is=(e,t)=>e!==ke&&!e.__isScriptSetup&&ge(e,t),qp={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:o,props:s,accessCache:i,type:l,appContext:a}=e;let u;if(t[0]!=="$"){const p=i[t];if(p!==void 0)switch(p){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return s[t]}else{if(is(r,t))return i[t]=1,r[t];if(o!==ke&&ge(o,t))return i[t]=2,o[t];if((u=e.propsOptions[0])&&ge(u,t))return i[t]=3,s[t];if(n!==ke&&ge(n,t))return i[t]=4,n[t];Ts&&(i[t]=0)}}const f=vr[t];let c,d;if(f)return t==="$attrs"&&Ge(e.attrs,"get",""),f(e);if((c=l.__cssModules)&&(c=c[t]))return c;if(n!==ke&&ge(n,t))return i[t]=4,n[t];if(d=a.config.globalProperties,ge(d,t))return d[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:s}=e;return is(o,t)?(o[t]=n,!0):r!==ke&&ge(r,t)?(r[t]=n,!0):ge(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(s[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:s}},i){let l;return!!n[i]||e!==ke&&ge(e,i)||is(t,i)||(l=s[0])&&ge(l,i)||ge(r,i)||ge(vr,i)||ge(o.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ge(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function al(e){return re(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ts=!0;function Gp(e){const t=hi(e),n=e.proxy,r=e.ctx;Ts=!1,t.beforeCreate&&ul(t.beforeCreate,e,"bc");const{data:o,computed:s,methods:i,watch:l,provide:a,inject:u,created:f,beforeMount:c,mounted:d,beforeUpdate:p,updated:v,activated:_,deactivated:y,beforeDestroy:E,beforeUnmount:S,destroyed:h,unmounted:b,render:R,renderTracked:j,renderTriggered:M,errorCaptured:w,serverPrefetch:U,expose:x,inheritAttrs:H,components:A,directives:D,filters:J}=t;if(u&&Yp(u,r,null),i)for(const N in i){const K=i[N];oe(K)&&(r[N]=K.bind(n))}if(o){const N=o.call(n,n);Ce(N)&&(e.data=Br(N))}if(Ts=!0,s)for(const N in s){const K=s[N],ue=oe(K)?K.bind(n,n):oe(K.get)?K.get.bind(n,n):Tt,ye=!oe(K)&&oe(K.set)?K.set.bind(n):Tt,Te=F({get:ue,set:ye});Object.defineProperty(r,N,{enumerable:!0,configurable:!0,get:()=>Te.value,set:be=>Te.value=be})}if(l)for(const N in l)oc(l[N],r,n,N);if(a){const N=oe(a)?a.call(n):a;Reflect.ownKeys(N).forEach(K=>{en(K,N[K])})}f&&ul(f,e,"c");function P(N,K){re(K)?K.forEach(ue=>N(ue.bind(n))):K&&N(K.bind(n))}if(P(Mp,c),P(Be,d),P(Fp,p),P(Bp,v),P(Dp,_),P(Np,y),P(jp,w),P(Up,j),P($p,M),P(No,S),P(Vo,b),P(Hp,U),re(x))if(x.length){const N=e.exposed||(e.exposed={});x.forEach(K=>{Object.defineProperty(N,K,{get:()=>n[K],set:ue=>n[K]=ue})})}else e.exposed||(e.exposed={});R&&e.render===Tt&&(e.render=R),H!=null&&(e.inheritAttrs=H),A&&(e.components=A),D&&(e.directives=D),U&&di(e)}function Yp(e,t,n=Tt){re(e)&&(e=Os(e));for(const r in e){const o=e[r];let s;Ce(o)?"default"in o?s=qe(o.from||r,o.default,!0):s=qe(o.from||r):s=qe(o),Ne(s)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>s.value,set:i=>s.value=i}):t[r]=s}}function ul(e,t,n){yt(re(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function oc(e,t,n,r){let o=r.includes(".")?yc(n,r):()=>n[r];if(xe(e)){const s=t[e];oe(s)&&je(o,s)}else if(oe(e))je(o,e.bind(n));else if(Ce(e))if(re(e))e.forEach(s=>oc(s,t,n,r));else{const s=oe(e.handler)?e.handler.bind(n):t[e.handler];oe(s)&&je(o,s,e)}}function hi(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:s,config:{optionMergeStrategies:i}}=e.appContext,l=s.get(t);let a;return l?a=l:!o.length&&!n&&!r?a=t:(a={},o.length&&o.forEach(u=>ko(a,u,i,!0)),ko(a,t,i)),Ce(t)&&s.set(t,a),a}function ko(e,t,n,r=!1){const{mixins:o,extends:s}=t;s&&ko(e,s,n,!0),o&&o.forEach(i=>ko(e,i,n,!0));for(const i in t)if(!(r&&i==="expose")){const l=Xp[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const Xp={data:cl,props:fl,emits:fl,methods:pr,computed:pr,beforeCreate:Ye,created:Ye,beforeMount:Ye,mounted:Ye,beforeUpdate:Ye,updated:Ye,beforeDestroy:Ye,beforeUnmount:Ye,destroyed:Ye,unmounted:Ye,activated:Ye,deactivated:Ye,errorCaptured:Ye,serverPrefetch:Ye,components:pr,directives:pr,watch:Zp,provide:cl,inject:Jp};function cl(e,t){return t?e?function(){return Fe(oe(e)?e.call(this,this):e,oe(t)?t.call(this,this):t)}:t:e}function Jp(e,t){return pr(Os(e),Os(t))}function Os(e){if(re(e)){const t={};for(let n=0;n1)return n&&oe(t)?t.call(r&&r.proxy):t}}const ic={},lc=()=>Object.create(ic),ac=e=>Object.getPrototypeOf(e)===ic;function th(e,t,n,r=!1){const o={},s=lc();e.propsDefaults=Object.create(null),uc(e,t,o,s);for(const i in e.propsOptions[0])i in o||(o[i]=void 0);n?e.props=r?o:Mu(o):e.type.props?e.props=o:e.props=s,e.attrs=s}function nh(e,t,n,r){const{props:o,attrs:s,vnode:{patchFlag:i}}=e,l=fe(o),[a]=e.propsOptions;let u=!1;if((r||i>0)&&!(i&16)){if(i&8){const f=e.vnode.dynamicProps;for(let c=0;c{a=!0;const[d,p]=cc(c,t,!0);Fe(i,d),p&&l.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(f),e.extends&&f(e.extends),e.mixins&&e.mixins.forEach(f)}if(!s&&!a)return Ce(e)&&r.set(e,Dn),Dn;if(re(s))for(let f=0;fe[0]==="_"||e==="$stable",mi=e=>re(e)?e.map(pt):[pt(e)],oh=(e,t,n)=>{if(t._n)return t;const r=Ve((...o)=>mi(t(...o)),n);return r._c=!1,r},dc=(e,t,n)=>{const r=e._ctx;for(const o in e){if(fc(o))continue;const s=e[o];if(oe(s))t[o]=oh(o,s,r);else if(s!=null){const i=mi(s);t[o]=()=>i}}},pc=(e,t)=>{const n=mi(t);e.slots.default=()=>n},hc=(e,t,n)=>{for(const r in t)(n||r!=="_")&&(e[r]=t[r])},sh=(e,t,n)=>{const r=e.slots=lc();if(e.vnode.shapeFlag&32){const o=t._;o?(hc(r,t,n),n&&jn(r,"_",o,!0)):dc(t,r)}else t&&pc(e,t)},ih=(e,t,n)=>{const{vnode:r,slots:o}=e;let s=!0,i=ke;if(r.shapeFlag&32){const l=t._;l?n&&l===1?s=!1:hc(o,t,n):(s=!t.$stable,dc(t,o)),i=t}else t&&(pc(e,t),i={default:1});if(s)for(const l in o)!fc(l)&&i[l]==null&&delete o[l]},lt=kc;function lh(e){return ah(e,Tp)}function ah(e,t){const n=_u();n.__VUE__=!0,Ku(n.__VUE_DEVTOOLS_GLOBAL_HOOK__,n);const{insert:r,remove:o,patchProp:s,createElement:i,createText:l,createComment:a,setText:u,setElementText:f,parentNode:c,nextSibling:d,setScopeId:p=Tt,insertStaticContent:v}=e,_=(m,g,k,O=null,C=null,L=null,W=void 0,$=null,B=!!g.dynamicChildren)=>{if(m===g)return;m&&!bn(m,g)&&(O=T(m),be(m,C,L,!0),m=null),g.patchFlag===-2&&(B=!1,g.dynamicChildren=null);const{type:V,ref:te,shapeFlag:G}=g;switch(V){case tn:y(m,g,k,O);break;case ze:E(m,g,k,O);break;case Hn:m==null&&S(g,k,O,W);break;case _e:A(m,g,k,O,C,L,W,$,B);break;default:G&1?R(m,g,k,O,C,L,W,$,B):G&6?D(m,g,k,O,C,L,W,$,B):(G&64||G&128)&&V.process(m,g,k,O,C,L,W,$,B,Z)}te!=null&&C&&Eo(te,m&&m.ref,L,g||m,!g)},y=(m,g,k,O)=>{if(m==null)r(g.el=l(g.children),k,O);else{const C=g.el=m.el;g.children!==m.children&&u(C,g.children)}},E=(m,g,k,O)=>{m==null?r(g.el=a(g.children||""),k,O):g.el=m.el},S=(m,g,k,O)=>{[m.el,m.anchor]=v(m.children,g,k,O,m.el,m.anchor)},h=({el:m,anchor:g},k,O)=>{let C;for(;m&&m!==g;)C=d(m),r(m,k,O),m=C;r(g,k,O)},b=({el:m,anchor:g})=>{let k;for(;m&&m!==g;)k=d(m),o(m),m=k;o(g)},R=(m,g,k,O,C,L,W,$,B)=>{g.type==="svg"?W="svg":g.type==="math"&&(W="mathml"),m==null?j(g,k,O,C,L,W,$,B):U(m,g,C,L,W,$,B)},j=(m,g,k,O,C,L,W,$)=>{let B,V;const{props:te,shapeFlag:G,transition:Q,dirs:se}=m;if(B=m.el=i(m.type,L,te&&te.is,te),G&8?f(B,m.children):G&16&&w(m.children,B,null,O,C,ls(m,L),W,$),se&&At(m,null,O,"created"),M(B,m,m.scopeId,W,O),te){for(const Se in te)Se!=="value"&&!Vn(Se)&&s(B,Se,null,te[Se],L,O);"value"in te&&s(B,"value",null,te.value,L),(V=te.onVnodeBeforeMount)&&dt(V,O,m)}jn(B,"__vnode",m,!0),jn(B,"__vueParentComponent",O,!0),se&&At(m,null,O,"beforeMount");const pe=mc(C,Q);pe&&Q.beforeEnter(B),r(B,g,k),((V=te&&te.onVnodeMounted)||pe||se)&<(()=>{V&&dt(V,O,m),pe&&Q.enter(B),se&&At(m,null,O,"mounted")},C)},M=(m,g,k,O,C)=>{if(k&&p(m,k),O)for(let L=0;L{for(let V=B;V{const $=g.el=m.el;$.__vnode=g;let{patchFlag:B,dynamicChildren:V,dirs:te}=g;B|=m.patchFlag&16;const G=m.props||ke,Q=g.props||ke;let se;if(k&&pn(k,!1),(se=Q.onVnodeBeforeUpdate)&&dt(se,k,g,m),te&&At(g,m,k,"beforeUpdate"),k&&pn(k,!0),(G.innerHTML&&Q.innerHTML==null||G.textContent&&Q.textContent==null)&&f($,""),V?x(m.dynamicChildren,V,$,k,O,ls(g,C),L):W||K(m,g,$,null,k,O,ls(g,C),L,!1),B>0){if(B&16)H($,G,Q,k,C);else if(B&2&&G.class!==Q.class&&s($,"class",null,Q.class,C),B&4&&s($,"style",G.style,Q.style,C),B&8){const pe=g.dynamicProps;for(let Se=0;Se{se&&dt(se,k,g,m),te&&At(g,m,k,"updated")},O)},x=(m,g,k,O,C,L,W)=>{for(let $=0;${if(g!==k){if(g!==ke)for(const L in g)!Vn(L)&&!(L in k)&&s(m,L,g[L],null,C,O);for(const L in k){if(Vn(L))continue;const W=k[L],$=g[L];W!==$&&L!=="value"&&s(m,L,$,W,C,O)}"value"in k&&s(m,"value",g.value,k.value,C)}},A=(m,g,k,O,C,L,W,$,B)=>{const V=g.el=m?m.el:l(""),te=g.anchor=m?m.anchor:l("");let{patchFlag:G,dynamicChildren:Q,slotScopeIds:se}=g;se&&($=$?$.concat(se):se),m==null?(r(V,k,O),r(te,k,O),w(g.children||[],k,te,C,L,W,$,B)):G>0&&G&64&&Q&&m.dynamicChildren?(x(m.dynamicChildren,Q,k,C,L,W,$),(g.key!=null||C&&g===C.subTree)&&gc(m,g,!0)):K(m,g,k,te,C,L,W,$,B)},D=(m,g,k,O,C,L,W,$,B)=>{g.slotScopeIds=$,m==null?g.shapeFlag&512?C.ctx.activate(g,k,O,W,B):J(g,k,O,C,L,W,B):ee(m,g,B)},J=(m,g,k,O,C,L,W)=>{const $=m.component=Ch(m,O,C);if($r(m)&&($.ctx.renderer=Z),xh($,!1,W),$.asyncDep){if(C&&C.registerDep($,P,W),!m.el){const B=$.subTree=ae(ze);E(null,B,g,k)}}else P($,m,g,k,C,L,W)},ee=(m,g,k)=>{const O=g.component=m.component;if(vh(m,g,k))if(O.asyncDep&&!O.asyncResolved){N(O,g,k);return}else O.next=g,O.update();else g.el=m.el,O.vnode=g},P=(m,g,k,O,C,L,W)=>{const $=()=>{if(m.isMounted){let{next:G,bu:Q,u:se,parent:pe,vnode:Se}=m;{const st=vc(m);if(st){G&&(G.el=Se.el,N(m,G,W)),st.asyncDep.then(()=>{m.isUnmounted||$()});return}}let ve=G,ot;pn(m,!1),G?(G.el=Se.el,N(m,G,W)):G=Se,Q&&Zo(Q),(ot=G.props&&G.props.onVnodeBeforeUpdate)&&dt(ot,pe,G,Se),pn(m,!0);const Ke=as(m),vt=m.subTree;m.subTree=Ke,_(vt,Ke,c(vt.el),T(vt),m,C,L),G.el=Ke.el,ve===null&&_h(m,Ke.el),se&<(se,C),(ot=G.props&&G.props.onVnodeUpdated)&<(()=>dt(ot,pe,G,Se),C),Wu(m)}else{let G;const{el:Q,props:se}=g,{bm:pe,m:Se,parent:ve,root:ot,type:Ke}=m,vt=wn(g);if(pn(m,!1),pe&&Zo(pe),!vt&&(G=se&&se.onVnodeBeforeMount)&&dt(G,ve,g),pn(m,!0),Q&&Ee){const st=()=>{m.subTree=as(m),Ee(Q,m.subTree,m,C,null)};vt&&Ke.__asyncHydrate?Ke.__asyncHydrate(Q,m,st):st()}else{ot.ce&&ot.ce._injectChildStyle(Ke);const st=m.subTree=as(m);_(null,st,k,O,m,C,L),g.el=st.el}if(Se&<(Se,C),!vt&&(G=se&&se.onVnodeMounted)){const st=g;lt(()=>dt(G,ve,st),C)}(g.shapeFlag&256||ve&&wn(ve.vnode)&&ve.vnode.shapeFlag&256)&&m.a&<(m.a,C),m.isMounted=!0,_p(m),g=k=O=null}};m.scope.on();const B=m.effect=new Su($);m.scope.off();const V=m.update=B.run.bind(B),te=m.job=B.runIfDirty.bind(B);te.i=m,te.id=m.uid,B.scheduler=()=>ci(te),pn(m,!0),V()},N=(m,g,k)=>{g.component=m;const O=m.vnode.props;m.vnode=g,m.next=null,nh(m,g.props,O,k),ih(m,g.children,k),$t(),tl(m),Ut()},K=(m,g,k,O,C,L,W,$,B=!1)=>{const V=m&&m.children,te=m?m.shapeFlag:0,G=g.children,{patchFlag:Q,shapeFlag:se}=g;if(Q>0){if(Q&128){ye(V,G,k,O,C,L,W,$,B);return}else if(Q&256){ue(V,G,k,O,C,L,W,$,B);return}}se&8?(te&16&&et(V,C,L),G!==V&&f(k,G)):te&16?se&16?ye(V,G,k,O,C,L,W,$,B):et(V,C,L,!0):(te&8&&f(k,""),se&16&&w(G,k,O,C,L,W,$,B))},ue=(m,g,k,O,C,L,W,$,B)=>{m=m||Dn,g=g||Dn;const V=m.length,te=g.length,G=Math.min(V,te);let Q;for(Q=0;Qte?et(m,C,L,!0,!1,G):w(g,k,O,C,L,W,$,B,G)},ye=(m,g,k,O,C,L,W,$,B)=>{let V=0;const te=g.length;let G=m.length-1,Q=te-1;for(;V<=G&&V<=Q;){const se=m[V],pe=g[V]=B?Jt(g[V]):pt(g[V]);if(bn(se,pe))_(se,pe,k,null,C,L,W,$,B);else break;V++}for(;V<=G&&V<=Q;){const se=m[G],pe=g[Q]=B?Jt(g[Q]):pt(g[Q]);if(bn(se,pe))_(se,pe,k,null,C,L,W,$,B);else break;G--,Q--}if(V>G){if(V<=Q){const se=Q+1,pe=seQ)for(;V<=G;)be(m[V],C,L,!0),V++;else{const se=V,pe=V,Se=new Map;for(V=pe;V<=Q;V++){const it=g[V]=B?Jt(g[V]):pt(g[V]);it.key!=null&&Se.set(it.key,V)}let ve,ot=0;const Ke=Q-pe+1;let vt=!1,st=0;const or=new Array(Ke);for(V=0;V=Ke){be(it,C,L,!0);continue}let kt;if(it.key!=null)kt=Se.get(it.key);else for(ve=pe;ve<=Q;ve++)if(or[ve-pe]===0&&bn(it,g[ve])){kt=ve;break}kt===void 0?be(it,C,L,!0):(or[kt-pe]=V+1,kt>=st?st=kt:vt=!0,_(it,g[kt],k,null,C,L,W,$,B),ot++)}const zi=vt?uh(or):Dn;for(ve=zi.length-1,V=Ke-1;V>=0;V--){const it=pe+V,kt=g[it],Ki=it+1{const{el:L,type:W,transition:$,children:B,shapeFlag:V}=m;if(V&6){Te(m.component.subTree,g,k,O);return}if(V&128){m.suspense.move(g,k,O);return}if(V&64){W.move(m,g,k,Z);return}if(W===_e){r(L,g,k);for(let G=0;G$.enter(L),C);else{const{leave:G,delayLeave:Q,afterLeave:se}=$,pe=()=>r(L,g,k),Se=()=>{G(L,()=>{pe(),se&&se()})};Q?Q(L,pe,Se):Se()}else r(L,g,k)},be=(m,g,k,O=!1,C=!1)=>{const{type:L,props:W,ref:$,children:B,dynamicChildren:V,shapeFlag:te,patchFlag:G,dirs:Q,cacheIndex:se}=m;if(G===-2&&(C=!1),$!=null&&Eo($,null,k,m,!0),se!=null&&(g.renderCache[se]=void 0),te&256){g.ctx.deactivate(m);return}const pe=te&1&&Q,Se=!wn(m);let ve;if(Se&&(ve=W&&W.onVnodeBeforeUnmount)&&dt(ve,g,m),te&6)Qe(m.component,k,O);else{if(te&128){m.suspense.unmount(k,O);return}pe&&At(m,null,g,"beforeUnmount"),te&64?m.type.remove(m,g,k,Z,O):V&&!V.hasOnce&&(L!==_e||G>0&&G&64)?et(V,g,k,!1,!0):(L===_e&&G&384||!C&&te&16)&&et(B,g,k),O&&Ze(m)}(Se&&(ve=W&&W.onVnodeUnmounted)||pe)&<(()=>{ve&&dt(ve,g,m),pe&&At(m,null,g,"unmounted")},k)},Ze=m=>{const{type:g,el:k,anchor:O,transition:C}=m;if(g===_e){gt(k,O);return}if(g===Hn){b(m);return}const L=()=>{o(k),C&&!C.persisted&&C.afterLeave&&C.afterLeave()};if(m.shapeFlag&1&&C&&!C.persisted){const{leave:W,delayLeave:$}=C,B=()=>W(k,L);$?$(m.el,L,B):B()}else L()},gt=(m,g)=>{let k;for(;m!==g;)k=d(m),o(m),m=k;o(g)},Qe=(m,g,k)=>{const{bum:O,scope:C,job:L,subTree:W,um:$,m:B,a:V}=m;pl(B),pl(V),O&&Zo(O),C.stop(),L&&(L.flags|=8,be(W,m,g,k)),$&<($,g),lt(()=>{m.isUnmounted=!0},g),g&&g.pendingBranch&&!g.isUnmounted&&m.asyncDep&&!m.asyncResolved&&m.suspenseId===g.pendingId&&(g.deps--,g.deps===0&&g.resolve()),bp(m)},et=(m,g,k,O=!1,C=!1,L=0)=>{for(let W=L;W{if(m.shapeFlag&6)return T(m.component.subTree);if(m.shapeFlag&128)return m.suspense.next();const g=d(m.anchor||m.el),k=g&&g[kp];return k?d(k):g};let q=!1;const z=(m,g,k)=>{m==null?g._vnode&&be(g._vnode,null,null,!0):_(g._vnode||null,m,g,null,null,null,k),g._vnode=m,q||(q=!0,tl(),_o(),q=!1)},Z={p:_,um:be,m:Te,r:Ze,mt:J,mc:w,pc:K,pbc:x,n:T,o:e};let de,Ee;return t&&([de,Ee]=t(Z)),{render:z,hydrate:de,createApp:eh(z,de)}}function ls({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 pn({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function mc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function gc(e,t,n=!1){const r=e.children,o=t.children;if(re(r)&&re(o))for(let s=0;s>1,e[n[l]]0&&(t[r]=n[s-1]),n[s]=r)}}for(s=n.length,i=n[s-1];s-- >0;)n[s]=i,i=t[i];return n}function vc(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:vc(t)}function pl(e){if(e)for(let t=0;tqe(ch);function _c(e,t){return gi(e,null,t)}function je(e,t,n){return gi(e,t,n)}function gi(e,t,n=ke){const{immediate:r,deep:o,flush:s,once:i}=n,l=Fe({},n);let a;if(zr)if(s==="sync"){const d=fh();a=d.__watcherHandles||(d.__watcherHandles=[])}else if(!t||r)l.once=!0;else{const d=()=>{};return d.stop=Tt,d.resume=Tt,d.pause=Tt,d}const u=$e;l.call=(d,p,v)=>yt(d,u,p,v);let f=!1;s==="post"?l.scheduler=d=>{lt(d,u&&u.suspense)}:s!=="sync"&&(f=!0,l.scheduler=(d,p)=>{p?d():ci(d)}),l.augmentJob=d=>{t&&(d.flags|=4),f&&(d.flags|=2,u&&(d.id=u.uid,d.i=u))};const c=ap(e,t,l);return a&&a.push(c),c}function dh(e,t,n){const r=this.proxy,o=xe(e)?e.includes(".")?yc(r,e):()=>r[e]:e.bind(r,r);let s;oe(t)?s=t:(s=t.handler,n=t);const i=jr(this),l=gi(o,s.bind(r),n);return i(),l}function yc(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;ot==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${rt(t)}Modifiers`]||e[`${Ht(t)}Modifiers`];function hh(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||ke;let o=n;const s=t.startsWith("update:"),i=s&&ph(r,t.slice(7));i&&(i.trim&&(o=n.map(f=>xe(f)?f.trim():f)),i.number&&(o=n.map(hd))),Ep(e,t,o);let l,a=r[l=Jo(t)]||r[l=Jo(rt(t))];!a&&s&&(a=r[l=Jo(Ht(t))]),a&&yt(a,e,6,o);const u=r[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,yt(u,e,6,o)}}function bc(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const s=e.emits;let i={},l=!1;if(!oe(e)){const a=u=>{const f=bc(u,t,!0);f&&(l=!0,Fe(i,f))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!s&&!l?(Ce(e)&&r.set(e,null),null):(re(s)?s.forEach(a=>i[a]=null):Fe(i,s),Ce(e)&&r.set(e,i),i)}function Mo(e,t){return!e||!Mr(t)?!1:(t=t.slice(2).replace(/Once$/,""),ge(e,t[0].toLowerCase()+t.slice(1))||ge(e,Ht(t))||ge(e,t))}function as(e){const{type:t,vnode:n,proxy:r,withProxy:o,propsOptions:[s],slots:i,attrs:l,emit:a,render:u,renderCache:f,props:c,data:d,setupState:p,ctx:v,inheritAttrs:_}=e,y=yo(e);let E,S;try{if(n.shapeFlag&4){const b=o||r,R=b;E=pt(u.call(R,b,f,c,p,d,v)),S=l}else{const b=t;E=pt(b.length>1?b(c,{attrs:l,slots:i,emit:a}):b(c,null)),S=t.props?l:mh(l)}}catch(b){_r.length=0,Hr(b,e,1),E=ae(ze)}let h=E;if(S&&_!==!1){const b=Object.keys(S),{shapeFlag:R}=h;b.length&&R&7&&(s&&b.some(Xs)&&(S=gh(S,s)),h=on(h,S,!1,!0))}return n.dirs&&(h=on(h,null,!1,!0),h.dirs=h.dirs?h.dirs.concat(n.dirs):n.dirs),n.transition&&Cr(h,n.transition),E=h,yo(y),E}const mh=e=>{let t;for(const n in e)(n==="class"||n==="style"||Mr(n))&&((t||(t={}))[n]=e[n]);return t},gh=(e,t)=>{const n={};for(const r in e)(!Xs(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function vh(e,t,n){const{props:r,children:o,component:s}=e,{props:i,children:l,patchFlag:a}=t,u=s.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return r?hl(r,i,u):!!i;if(a&8){const f=t.dynamicProps;for(let c=0;ce.__isSuspense;function kc(e,t){t&&t.pendingBranch?re(e)?t.effects.push(...e):t.effects.push(e):mp(e)}const _e=Symbol.for("v-fgt"),tn=Symbol.for("v-txt"),ze=Symbol.for("v-cmt"),Hn=Symbol.for("v-stc"),_r=[];let at=null;function Y(e=!1){_r.push(at=e?null:[])}function yh(){_r.pop(),at=_r[_r.length-1]||null}let xr=1;function ml(e){xr+=e,e<0&&at&&(at.hasOnce=!0)}function Sc(e){return e.dynamicChildren=xr>0?at||Dn:null,yh(),xr>0&&at&&at.push(e),e}function ne(e,t,n,r,o,s){return Sc(ie(e,t,n,r,o,s,!0))}function Re(e,t,n,r,o){return Sc(ae(e,t,n,r,o,!0))}function Tr(e){return e?e.__v_isVNode===!0:!1}function bn(e,t){return e.type===t.type&&e.key===t.key}const wc=({key:e})=>e??null,uo=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?xe(e)||Ne(e)||oe(e)?{i:Ue,r:e,k:t,f:!!n}:e:null);function ie(e,t=null,n=null,r=0,o=null,s=e===_e?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&wc(t),ref:t&&uo(t),scopeId:qu,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:s,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:Ue};return l?(vi(a,n),s&128&&e.normalize(a)):n&&(a.shapeFlag|=xe(n)?8:16),xr>0&&!i&&at&&(a.patchFlag>0||s&6)&&a.patchFlag!==32&&at.push(a),a}const ae=bh;function bh(e,t=null,n=null,r=0,o=null,s=!1){if((!e||e===Kp)&&(e=ze),Tr(e)){const l=on(e,t,!0);return n&&vi(l,n),xr>0&&!s&&at&&(l.shapeFlag&6?at[at.indexOf(e)]=l:at.push(l)),l.patchFlag=-2,l}if(Rh(e)&&(e=e.__vccOpts),t){t=Eh(t);let{class:l,style:a}=t;l&&!xe(l)&&(t.class=nt(l)),Ce(a)&&(ii(a)&&!re(a)&&(a=Fe({},a)),t.style=Xn(a))}const i=xe(e)?1:Ec(e)?128:Gu(e)?64:Ce(e)?4:oe(e)?2:0;return ie(e,t,n,r,o,i,s,!0)}function Eh(e){return e?ii(e)||ac(e)?Fe({},e):e:null}function on(e,t,n=!1,r=!1){const{props:o,ref:s,patchFlag:i,children:l,transition:a}=e,u=t?Sh(o||{},t):o,f={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&wc(u),ref:t&&t.ref?n&&s?re(s)?s.concat(uo(t)):[s,uo(t)]:uo(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==_e?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&on(e.ssContent),ssFallback:e.ssFallback&&on(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&r&&Cr(f,a.clone(f)),f}function sn(e=" ",t=0){return ae(tn,null,e,t)}function kh(e,t){const n=ae(Hn,null,e);return n.staticCount=t,n}function Me(e="",t=!1){return t?(Y(),Re(ze,null,e)):ae(ze,null,e)}function pt(e){return e==null||typeof e=="boolean"?ae(ze):re(e)?ae(_e,null,e.slice()):Tr(e)?Jt(e):ae(tn,null,String(e))}function Jt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:on(e)}function vi(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(re(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),vi(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!ac(t)?t._ctx=Ue:o===3&&Ue&&(Ue.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else oe(t)?(t={default:t,_ctx:Ue},n=32):(t=String(t),r&64?(n=16,t=[sn(t)]):n=8);e.children=t,e.shapeFlag|=n}function Sh(...e){const t={};for(let n=0;n$e||Ue;let So,Is;{const e=_u(),t=(n,r)=>{let o;return(o=e[n])||(o=e[n]=[]),o.push(r),s=>{o.length>1?o.forEach(i=>i(s)):o[0](s)}};So=t("__VUE_INSTANCE_SETTERS__",n=>$e=n),Is=t("__VUE_SSR_SETTERS__",n=>zr=n)}const jr=e=>{const t=$e;return So(e),e.scope.on(),()=>{e.scope.off(),So(t)}},gl=()=>{$e&&$e.scope.off(),So(null)};function Ac(e){return e.vnode.shapeFlag&4}let zr=!1;function xh(e,t=!1,n=!1){t&&Is(t);const{props:r,children:o}=e.vnode,s=Ac(e);th(e,r,s,t),sh(e,o,n);const i=s?Th(e,t):void 0;return t&&Is(!1),i}function Th(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,qp);const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?Ph(e):null,s=jr(e);$t();const i=Jn(r,e,0,[e.props,o]);if(Ut(),s(),mu(i)){if(wn(e)||di(e),i.then(gl,gl),t)return i.then(l=>{vl(e,l,t)}).catch(l=>{Hr(l,e,0)});e.asyncDep=i}else vl(e,i,t)}else Cc(e,t)}function vl(e,t,n){oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ce(t)&&(e.devtoolsRawSetupState=t,e.setupState=Bu(t)),Cc(e,n)}let _l;function Cc(e,t,n){const r=e.type;if(!e.render){if(!t&&_l&&!r.render){const o=r.template||hi(e).template;if(o){const{isCustomElement:s,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:a}=r,u=Fe(Fe({isCustomElement:s,delimiters:l},i),a);r.render=_l(o,u)}}e.render=r.render||Tt}{const o=jr(e);$t();try{Gp(e)}finally{Ut(),o()}}}const Oh={get(e,t){return Ge(e,"get",""),e[t]}};function Ph(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Oh),slots:e.slots,emit:e.emit,expose:t}}function Fo(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Bu(Jd(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in vr)return vr[n](e)},has(t,n){return n in t||n in vr}})):e.proxy}const Ih=/(?:^|[-_])(\w)/g,Lh=e=>e.replace(Ih,t=>t.toUpperCase()).replace(/[-_]/g,"");function xc(e,t=!0){return oe(e)?e.displayName||e.name:e.name||t&&e.__name}function Tc(e,t,n=!1){let r=xc(t);if(!r&&t.__file){const o=t.__file.match(/([^/\\]+)\.\w+$/);o&&(r=o[1])}if(!r&&e&&e.parent){const o=s=>{for(const i in s)if(s[i]===t)return i};r=o(e.components||e.parent.type.components)||o(e.appContext.components)}return r?Lh(r):n?"App":"Anonymous"}function Rh(e){return oe(e)&&"__vccOpts"in e}const F=(e,t)=>ip(e,t,zr);function le(e,t,n){const r=arguments.length;return r===2?Ce(t)&&!re(t)?Tr(t)?ae(e,null,[t]):ae(e,t):ae(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Tr(n)&&(n=[n]),ae(e,t,n))}const yl="3.5.10";/** +* @vue/runtime-dom v3.5.10 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ls;const bl=typeof window<"u"&&window.trustedTypes;if(bl)try{Ls=bl.createPolicy("vue",{createHTML:e=>e})}catch{}const Oc=Ls?e=>Ls.createHTML(e):e=>e,Dh="http://www.w3.org/2000/svg",Nh="http://www.w3.org/1998/Math/MathML",Vt=typeof document<"u"?document:null,El=Vt&&Vt.createElement("template"),Vh={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t==="svg"?Vt.createElementNS(Dh,e):t==="mathml"?Vt.createElementNS(Nh,e):n?Vt.createElement(e,{is:n}):Vt.createElement(e);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Vt.createTextNode(e),createComment:e=>Vt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Vt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,s){const i=n?n.previousSibling:t.lastChild;if(o&&(o===s||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===s||!(o=o.nextSibling)););else{El.innerHTML=Oc(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const l=El.content;if(r==="svg"||r==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Wt="transition",ir="animation",Or=Symbol("_vtc"),Pc={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},Mh=Fe({},Yu,Pc),Fh=e=>(e.displayName="Transition",e.props=Mh,e),Bo=Fh((e,{slots:t})=>le(Ap,Bh(e),t)),hn=(e,t=[])=>{re(e)?e.forEach(n=>n(...t)):e&&e(...t)},kl=e=>e?re(e)?e.some(t=>t.length>1):e.length>1:!1;function Bh(e){const t={};for(const A in e)A in Pc||(t[A]=e[A]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:s=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=s,appearActiveClass:u=i,appearToClass:f=l,leaveFromClass:c=`${n}-leave-from`,leaveActiveClass:d=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,v=Hh(o),_=v&&v[0],y=v&&v[1],{onBeforeEnter:E,onEnter:S,onEnterCancelled:h,onLeave:b,onLeaveCancelled:R,onBeforeAppear:j=E,onAppear:M=S,onAppearCancelled:w=h}=t,U=(A,D,J)=>{mn(A,D?f:l),mn(A,D?u:i),J&&J()},x=(A,D)=>{A._isLeaving=!1,mn(A,c),mn(A,p),mn(A,d),D&&D()},H=A=>(D,J)=>{const ee=A?M:S,P=()=>U(D,A,J);hn(ee,[D,P]),Sl(()=>{mn(D,A?a:s),qt(D,A?f:l),kl(ee)||wl(D,r,_,P)})};return Fe(t,{onBeforeEnter(A){hn(E,[A]),qt(A,s),qt(A,i)},onBeforeAppear(A){hn(j,[A]),qt(A,a),qt(A,u)},onEnter:H(!1),onAppear:H(!0),onLeave(A,D){A._isLeaving=!0;const J=()=>x(A,D);qt(A,c),qt(A,d),jh(),Sl(()=>{A._isLeaving&&(mn(A,c),qt(A,p),kl(b)||wl(A,r,y,J))}),hn(b,[A,J])},onEnterCancelled(A){U(A,!1),hn(h,[A])},onAppearCancelled(A){U(A,!0),hn(w,[A])},onLeaveCancelled(A){x(A),hn(R,[A])}})}function Hh(e){if(e==null)return null;if(Ce(e))return[us(e.enter),us(e.leave)];{const t=us(e);return[t,t]}}function us(e){return md(e)}function qt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Or]||(e[Or]=new Set)).add(t)}function mn(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[Or];n&&(n.delete(t),n.size||(e[Or]=void 0))}function Sl(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let $h=0;function wl(e,t,n,r){const o=e._endId=++$h,s=()=>{o===e._endId&&r()};if(n!=null)return setTimeout(s,n);const{type:i,timeout:l,propCount:a}=Uh(e,t);if(!i)return r();const u=i+"end";let f=0;const c=()=>{e.removeEventListener(u,d),s()},d=p=>{p.target===e&&++f>=a&&c()};setTimeout(()=>{f(n[v]||"").split(", "),o=r(`${Wt}Delay`),s=r(`${Wt}Duration`),i=Al(o,s),l=r(`${ir}Delay`),a=r(`${ir}Duration`),u=Al(l,a);let f=null,c=0,d=0;t===Wt?i>0&&(f=Wt,c=i,d=s.length):t===ir?u>0&&(f=ir,c=u,d=a.length):(c=Math.max(i,u),f=c>0?i>u?Wt:ir:null,d=f?f===Wt?s.length:a.length:0);const p=f===Wt&&/\b(transform|all)(,|$)/.test(r(`${Wt}Property`).toString());return{type:f,timeout:c,propCount:d,hasTransform:p}}function Al(e,t){for(;e.lengthCl(n)+Cl(e[r])))}function Cl(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function jh(){return document.body.offsetHeight}function zh(e,t,n){const r=e[Or];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const wo=Symbol("_vod"),Ic=Symbol("_vsh"),Ao={beforeMount(e,{value:t},{transition:n}){e[wo]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):lr(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),lr(e,!0),r.enter(e)):r.leave(e,()=>{lr(e,!1)}):lr(e,t))},beforeUnmount(e,{value:t}){lr(e,t)}};function lr(e,t){e.style.display=t?e[wo]:"none",e[Ic]=!t}const Kh=Symbol(""),Wh=/(^|;)\s*display\s*:/;function qh(e,t,n){const r=e.style,o=xe(n);let s=!1;if(n&&!o){if(t)if(xe(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&co(r,l,"")}else for(const i in t)n[i]==null&&co(r,i,"");for(const i in n)i==="display"&&(s=!0),co(r,i,n[i])}else if(o){if(t!==n){const i=r[Kh];i&&(n+=";"+i),r.cssText=n,s=Wh.test(n)}}else t&&e.removeAttribute("style");wo in e&&(e[wo]=s?r.display:"",e[Ic]&&(r.display="none"))}const xl=/\s*!important$/;function co(e,t,n){if(re(n))n.forEach(r=>co(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=Gh(e,t);xl.test(n)?e.setProperty(Ht(r),n.replace(xl,""),"important"):e[r]=n}}const Tl=["Webkit","Moz","ms"],cs={};function Gh(e,t){const n=cs[t];if(n)return n;let r=rt(t);if(r!=="filter"&&r in e)return cs[t]=r;r=Fr(r);for(let o=0;ofs||(Qh.then(()=>fs=0),fs=Date.now());function tm(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;yt(nm(r,n.value),t,5,[r])};return n.value=e,n.attached=em(),n}function nm(e,t){if(re(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const Dl=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,rm=(e,t,n,r,o,s)=>{const i=o==="svg";t==="class"?zh(e,r,i):t==="style"?qh(e,n,r):Mr(t)?Xs(t)||Jh(e,t,n,r,s):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):om(e,t,r,i))?(Il(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Pl(e,t,r,i,s,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!xe(r))?Il(e,rt(t),r):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Pl(e,t,r,i))};function om(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Dl(t)&&oe(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 o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Dl(t)&&xe(n)?!1:t in e}const sm={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},im=(e,t)=>{const n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=o=>{if(!("key"in o))return;const s=Ht(o.key);if(t.some(i=>i===s||sm[i]===s))return e(o)})},lm=Fe({patchProp:rm},Vh);let ds,Nl=!1;function am(){return ds=Nl?ds:lh(lm),Nl=!0,ds}const um=(...e)=>{const t=am().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=fm(r);if(o)return n(o,!0,cm(o))},t};function cm(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function fm(e){return xe(e)?document.querySelector(e):e}var Kr=e=>/^[a-z][a-z0-9+.-]*:/.test(e)||e.startsWith("//"),dm=/.md((\?|#).*)?$/,pm=(e,t="/")=>Kr(e)||e.startsWith("/")&&!e.startsWith(t)&&!dm.test(e),Ho=e=>/^(https?:)?\/\//.test(e),Vl=e=>{if(!e||e.endsWith("/"))return e;let t=e.replace(/(^|\/)README.md$/i,"$1index.html");return t.endsWith(".md")?t=`${t.substring(0,t.length-3)}.html`:t.endsWith(".html")||(t=`${t}.html`),t.endsWith("/index.html")&&(t=t.substring(0,t.length-10)),t},hm="http://.",mm=(e,t)=>{if(!e.startsWith("/")&&t){const n=t.slice(0,t.lastIndexOf("/"));return Vl(new URL(`${n}/${e}`,hm).pathname)}return Vl(e)},gm=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const s=o.split("/").length-r.split("/").length;return s!==0?s:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},vm=/(#|\?)/,Lc=e=>{const[t,...n]=e.split(vm);return{pathname:t,hashAndQueries:n.join("")}},_m=["link","meta","script","style","noscript","template"],ym=["title","base"],bm=([e,t,n])=>ym.includes(e)?e:_m.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,o])=>typeof o=="boolean"?o?[r,""]:null:[r,o]).filter(r=>r!=null).sort(([r],[o])=>r.localeCompare(o)),n]):null,Em=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=bm(r);o&&!t.has(o)&&(t.add(o),n.push(r))}),n},km=e=>e.endsWith("/")||e.endsWith(".html")?e:`${e}/`,Rc=e=>e.endsWith("/")?e.slice(0,-1):e,Dc=e=>e.startsWith("/")?e.slice(1):e,_i=e=>Object.prototype.toString.call(e)==="[object Object]",mt=e=>typeof e=="string";const Sm=JSON.parse("{}"),wm=Object.fromEntries([["/",{loader:()=>De(()=>import("./index.html-28L8qS8U.js"),__vite__mapDeps([0,1])),meta:{title:"Welcome"}}],["/en/",{loader:()=>De(()=>import("./index.html-Dz4P2gMg.js"),__vite__mapDeps([2,1])),meta:{title:"Welcome"}}],["/fr/",{loader:()=>De(()=>import("./index.html-CeMqYfna.js"),[]),meta:{title:""}}],["/en/backend-development/",{loader:()=>De(()=>import("./index.html-B08ZAEqY.js"),[]),meta:{title:"📚 Backend development"}}],["/en/front-development/",{loader:()=>De(()=>import("./index.html-zXMBiwyM.js"),__vite__mapDeps([3,4])),meta:{title:"📚 Frontend development"}}],["/en/kotlin-features/",{loader:()=>De(()=>import("./index.html-COrAJfz9.js"),[]),meta:{title:"📚 Kotlin language features"}}],["/en/kotlin-features-advanced/",{loader:()=>De(()=>import("./index.html-2LK4oqoY.js"),[]),meta:{title:"📚 Advanced and other Kotlin features"}}],["/en/other-technologies/",{loader:()=>De(()=>import("./index.html-CcuJhM9n.js"),__vite__mapDeps([5,6])),meta:{title:"🛠 Let's make a cross-plaform app !"}}],["/en/presentation/",{loader:()=>De(()=>import("./index.html-D-c6bFFq.js"),__vite__mapDeps([7,8])),meta:{title:"🚀 Presentation of Kotlin"}}],["/en/workshops/",{loader:()=>De(()=>import("./index.html-CIUQNmed.js"),__vite__mapDeps([9,10])),meta:{title:"📅 Workshops"}}],["/fr/backend-development/",{loader:()=>De(()=>import("./index.html-DgauC6Dk.js"),[]),meta:{title:"📚 Développement du backend"}}],["/fr/front-development/",{loader:()=>De(()=>import("./index.html-BHDS7_46.js"),__vite__mapDeps([11,4])),meta:{title:"📚 Développement frontend"}}],["/fr/kotlin-features/",{loader:()=>De(()=>import("./index.html-2g5kMIFT.js"),[]),meta:{title:"📚 Fonctionnalités du langage Kotlin"}}],["/fr/kotlin-features-advanced/",{loader:()=>De(()=>import("./index.html-DI1rj2RX.js"),[]),meta:{title:"📚 Fonctionnalités avancées de Kotlin"}}],["/fr/other-technologies/",{loader:()=>De(()=>import("./index.html-BZTbG60u.js"),__vite__mapDeps([12,6])),meta:{title:"🛠 Construisons une app multiplateforme !"}}],["/fr/presentation/",{loader:()=>De(()=>import("./index.html-BwZborl3.js"),__vite__mapDeps([13,8])),meta:{title:"🚀 Présentation de Kotlin"}}],["/fr/workshops/",{loader:()=>De(()=>import("./index.html-jwVfesBb.js"),__vite__mapDeps([14,10])),meta:{title:"📅 Workshops"}}],["/404.html",{loader:()=>De(()=>import("./404.html-CB0hfWEP.js"),[]),meta:{title:""}}]]);function Am(){return Nc().__VUE_DEVTOOLS_GLOBAL_HOOK__}function Nc(){return typeof navigator<"u"&&typeof window<"u"?window:typeof globalThis<"u"?globalThis:{}}const Cm=typeof Proxy=="function",xm="devtools-plugin:setup",Tm="plugin:settings:set";let On,Rs;function Om(){var e;return On!==void 0||(typeof window<"u"&&window.performance?(On=!0,Rs=window.performance):typeof globalThis<"u"&&(!((e=globalThis.perf_hooks)===null||e===void 0)&&e.performance)?(On=!0,Rs=globalThis.perf_hooks.performance):On=!1),On}function Pm(){return Om()?Rs.now():Date.now()}class Im{constructor(t,n){this.target=null,this.targetQueue=[],this.onQueue=[],this.plugin=t,this.hook=n;const r={};if(t.settings)for(const i in t.settings){const l=t.settings[i];r[i]=l.defaultValue}const o=`__vue-devtools-plugin-settings__${t.id}`;let s=Object.assign({},r);try{const i=localStorage.getItem(o),l=JSON.parse(i);Object.assign(s,l)}catch{}this.fallbacks={getSettings(){return s},setSettings(i){try{localStorage.setItem(o,JSON.stringify(i))}catch{}s=i},now(){return Pm()}},n&&n.on(Tm,(i,l)=>{i===this.plugin.id&&this.fallbacks.setSettings(l)}),this.proxiedOn=new Proxy({},{get:(i,l)=>this.target?this.target.on[l]:(...a)=>{this.onQueue.push({method:l,args:a})}}),this.proxiedTarget=new Proxy({},{get:(i,l)=>this.target?this.target[l]:l==="on"?this.proxiedOn:Object.keys(this.fallbacks).includes(l)?(...a)=>(this.targetQueue.push({method:l,args:a,resolve:()=>{}}),this.fallbacks[l](...a)):(...a)=>new Promise(u=>{this.targetQueue.push({method:l,args:a,resolve:u})})})}async setRealTarget(t){this.target=t;for(const n of this.onQueue)this.target.on[n.method](...n.args);for(const n of this.targetQueue)n.resolve(await this.target[n.method](...n.args))}}function Lm(e,t){const n=e,r=Nc(),o=Am(),s=Cm&&n.enableEarlyProxy;if(o&&(r.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__||!s))o.emit(xm,e,t);else{const i=s?new Im(n,o):null;(r.__VUE_DEVTOOLS_PLUGINS__=r.__VUE_DEVTOOLS_PLUGINS__||[]).push({pluginDescriptor:n,setupFn:t,proxy:i}),i&&t(i.proxiedTarget)}}/*! + * vue-router v4.4.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */const Mt=typeof document<"u";function Vc(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Rm(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&Vc(e.default)}const me=Object.assign;function ps(e,t){const n={};for(const r in t){const o=t[r];n[r]=ut(o)?o.map(e):e(o)}return n}const yr=()=>{},ut=Array.isArray,Mc=/#/g,Dm=/&/g,Nm=/\//g,Vm=/=/g,Mm=/\?/g,Fc=/\+/g,Fm=/%5B/g,Bm=/%5D/g,Bc=/%5E/g,Hm=/%60/g,Hc=/%7B/g,$m=/%7C/g,$c=/%7D/g,Um=/%20/g;function yi(e){return encodeURI(""+e).replace($m,"|").replace(Fm,"[").replace(Bm,"]")}function jm(e){return yi(e).replace(Hc,"{").replace($c,"}").replace(Bc,"^")}function Ds(e){return yi(e).replace(Fc,"%2B").replace(Um,"+").replace(Mc,"%23").replace(Dm,"%26").replace(Hm,"`").replace(Hc,"{").replace($c,"}").replace(Bc,"^")}function zm(e){return Ds(e).replace(Vm,"%3D")}function Km(e){return yi(e).replace(Mc,"%23").replace(Mm,"%3F")}function Wm(e){return e==null?"":Km(e).replace(Nm,"%2F")}function zn(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const qm=/\/$/,Gm=e=>e.replace(qm,"");function hs(e,t,n="/"){let r,o={},s="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return l=0&&(a=-1),a>-1&&(r=t.slice(0,a),s=t.slice(a+1,l>-1?l:t.length),o=e(s)),l>-1&&(r=r||t.slice(0,l),i=t.slice(l,t.length)),r=Zm(r??t,n),{fullPath:r+(s&&"?")+s+i,path:r,query:o,hash:zn(i)}}function Ym(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function Ml(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Xm(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&ln(t.matched[r],n.matched[o])&&Uc(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function ln(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Uc(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!Jm(e[n],t[n]))return!1;return!0}function Jm(e,t){return ut(e)?Fl(e,t):ut(t)?Fl(t,e):e===t}function Fl(e,t){return ut(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function Zm(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),o=r[r.length-1];(o===".."||o===".")&&r.push("");let s=n.length-1,i,l;for(i=0;i1&&s--;else break;return n.slice(0,s).join("/")+"/"+r.slice(i).join("/")}const Nt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var Pr;(function(e){e.pop="pop",e.push="push"})(Pr||(Pr={}));var br;(function(e){e.back="back",e.forward="forward",e.unknown=""})(br||(br={}));function Qm(e){if(!e)if(Mt){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Gm(e)}const eg=/^[^#]+#/;function tg(e,t){return e.replace(eg,"#")+t}function ng(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const $o=()=>({left:window.scrollX,top:window.scrollY});function rg(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),o=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=ng(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function Bl(e,t){return(history.state?history.state.position-t:-1)+e}const Ns=new Map;function og(e,t){Ns.set(e,t)}function sg(e){const t=Ns.get(e);return Ns.delete(e),t}let ig=()=>location.protocol+"//"+location.host;function jc(e,t){const{pathname:n,search:r,hash:o}=t,s=e.indexOf("#");if(s>-1){let l=o.includes(e.slice(s))?e.slice(s).length:1,a=o.slice(l);return a[0]!=="/"&&(a="/"+a),Ml(a,"")}return Ml(n,e)+r+o}function lg(e,t,n,r){let o=[],s=[],i=null;const l=({state:d})=>{const p=jc(e,location),v=n.value,_=t.value;let y=0;if(d){if(n.value=p,t.value=d,i&&i===v){i=null;return}y=_?d.position-_.position:0}else r(p);o.forEach(E=>{E(n.value,v,{delta:y,type:Pr.pop,direction:y?y>0?br.forward:br.back:br.unknown})})};function a(){i=n.value}function u(d){o.push(d);const p=()=>{const v=o.indexOf(d);v>-1&&o.splice(v,1)};return s.push(p),p}function f(){const{history:d}=window;d.state&&d.replaceState(me({},d.state,{scroll:$o()}),"")}function c(){for(const d of s)d();s=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",f)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",f,{passive:!0}),{pauseListeners:a,listen:u,destroy:c}}function Hl(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?$o():null}}function ag(e){const{history:t,location:n}=window,r={value:jc(e,n)},o={value:t.state};o.value||s(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function s(a,u,f){const c=e.indexOf("#"),d=c>-1?(n.host&&document.querySelector("base")?e:e.slice(c))+a:ig()+e+a;try{t[f?"replaceState":"pushState"](u,"",d),o.value=u}catch(p){console.error(p),n[f?"replace":"assign"](d)}}function i(a,u){const f=me({},t.state,Hl(o.value.back,a,o.value.forward,!0),u,{position:o.value.position});s(a,f,!0),r.value=a}function l(a,u){const f=me({},o.value,t.state,{forward:a,scroll:$o()});s(f.current,f,!0);const c=me({},Hl(r.value,a,null),{position:f.position+1},u);s(a,c,!1),r.value=a}return{location:r,state:o,push:l,replace:i}}function ug(e){e=Qm(e);const t=ag(e),n=lg(e,t.state,t.location,t.replace);function r(s,i=!0){i||n.pauseListeners(),history.go(s)}const o=me({location:"",base:e,go:r,createHref:tg.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}function zc(e){return typeof e=="string"||e&&typeof e=="object"}function Kc(e){return typeof e=="string"||typeof e=="symbol"}const Wc=Symbol("");var $l;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})($l||($l={}));function Kn(e,t){return me(new Error,{type:e,[Wc]:!0},t)}function Rt(e,t){return e instanceof Error&&Wc in e&&(t==null||!!(e.type&t))}const Ul="[^/]+?",cg={sensitive:!1,strict:!1,start:!0,end:!0},fg=/[.+*?^${}()[\]/\\]/g;function dg(e,t){const n=me({},cg,t),r=[];let o=n.start?"^":"";const s=[];for(const u of e){const f=u.length?[]:[90];n.strict&&!u.length&&(o+="/");for(let c=0;ct.length?t.length===1&&t[0]===80?1:-1:0}function qc(e,t){let n=0;const r=e.score,o=t.score;for(;n0&&t[t.length-1]<0}const hg={type:0,value:""},mg=/[a-zA-Z0-9_]/;function gg(e){if(!e)return[[]];if(e==="/")return[[hg]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(p){throw new Error(`ERR (${n})/"${u}": ${p}`)}let n=0,r=n;const o=[];let s;function i(){s&&o.push(s),s=[]}let l=0,a,u="",f="";function c(){u&&(n===0?s.push({type:0,value:u}):n===1||n===2||n===3?(s.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),s.push({type:1,value:u,regexp:f,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),u="")}function d(){u+=a}for(;l{i(h)}:yr}function i(c){if(Kc(c)){const d=r.get(c);d&&(r.delete(c),n.splice(n.indexOf(d),1),d.children.forEach(i),d.alias.forEach(i))}else{const d=n.indexOf(c);d>-1&&(n.splice(d,1),c.record.name&&r.delete(c.record.name),c.children.forEach(i),c.alias.forEach(i))}}function l(){return n}function a(c){const d=Eg(c,n);n.splice(d,0,c),c.record.name&&!Wl(c)&&r.set(c.record.name,c)}function u(c,d){let p,v={},_,y;if("name"in c&&c.name){if(p=r.get(c.name),!p)throw Kn(1,{location:c});y=p.record.name,v=me(zl(d.params,p.keys.filter(h=>!h.optional).concat(p.parent?p.parent.keys.filter(h=>h.optional):[]).map(h=>h.name)),c.params&&zl(c.params,p.keys.map(h=>h.name))),_=p.stringify(v)}else if(c.path!=null)_=c.path,p=n.find(h=>h.re.test(_)),p&&(v=p.parse(_),y=p.record.name);else{if(p=d.name?r.get(d.name):n.find(h=>h.re.test(d.path)),!p)throw Kn(1,{location:c,currentLocation:d});y=p.record.name,v=me({},d.params,c.params),_=p.stringify(v)}const E=[];let S=p;for(;S;)E.unshift(S.record),S=S.parent;return{name:y,path:_,params:v,matched:E,meta:bg(E)}}e.forEach(c=>s(c));function f(){n.length=0,r.clear()}return{addRoute:s,resolve:u,removeRoute:i,clearRoutes:f,getRoutes:l,getRecordMatcher:o}}function zl(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function Kl(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:yg(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function yg(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function Wl(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function bg(e){return e.reduce((t,n)=>me(t,n.meta),{})}function ql(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Eg(e,t){let n=0,r=t.length;for(;n!==r;){const s=n+r>>1;qc(e,t[s])<0?r=s:n=s+1}const o=kg(e);return o&&(r=t.lastIndexOf(o,r-1)),r}function kg(e){let t=e;for(;t=t.parent;)if(Gc(t)&&qc(e,t)===0)return t}function Gc({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Sg(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let o=0;os&&Ds(s)):[r&&Ds(r)]).forEach(s=>{s!==void 0&&(t+=(t.length?"&":"")+n,s!=null&&(t+="="+s))})}return t}function wg(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=ut(r)?r.map(o=>o==null?null:""+o):r==null?r:""+r)}return t}const Ag=Symbol(""),Yl=Symbol(""),Uo=Symbol(""),bi=Symbol(""),Vs=Symbol("");function ar(){let e=[];function t(r){return e.push(r),()=>{const o=e.indexOf(r);o>-1&&e.splice(o,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Zt(e,t,n,r,o,s=i=>i()){const i=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise((l,a)=>{const u=d=>{d===!1?a(Kn(4,{from:n,to:t})):d instanceof Error?a(d):zc(d)?a(Kn(2,{from:t,to:d})):(i&&r.enterCallbacks[o]===i&&typeof d=="function"&&i.push(d),l())},f=s(()=>e.call(r&&r.instances[o],t,n,u));let c=Promise.resolve(f);e.length<3&&(c=c.then(u)),c.catch(d=>a(d))})}function ms(e,t,n,r,o=s=>s()){const s=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(Vc(a)){const f=(a.__vccOpts||a)[t];f&&s.push(Zt(f,n,r,i,l,o))}else{let u=a();s.push(()=>u.then(f=>{if(!f)throw new Error(`Couldn't resolve component "${l}" at "${i.path}"`);const c=Rm(f)?f.default:f;i.mods[l]=f,i.components[l]=c;const p=(c.__vccOpts||c)[t];return p&&Zt(p,n,r,i,l,o)()}))}}return s}function Xl(e){const t=qe(Uo),n=qe(bi),r=F(()=>{const a=Qt(e.to);return t.resolve(a)}),o=F(()=>{const{matched:a}=r.value,{length:u}=a,f=a[u-1],c=n.matched;if(!f||!c.length)return-1;const d=c.findIndex(ln.bind(null,f));if(d>-1)return d;const p=Jl(a[u-2]);return u>1&&Jl(f)===p&&c[c.length-1].path!==p?c.findIndex(ln.bind(null,a[u-2])):d}),s=F(()=>o.value>-1&&Og(n.params,r.value.params)),i=F(()=>o.value>-1&&o.value===n.matched.length-1&&Uc(n.params,r.value.params));function l(a={}){return Tg(a)?t[Qt(e.replace)?"replace":"push"](Qt(e.to)).catch(yr):Promise.resolve()}if(Mt){const a=Ur();if(a){const u={route:r.value,isActive:s.value,isExactActive:i.value,error:null};a.__vrl_devtools=a.__vrl_devtools||[],a.__vrl_devtools.push(u),_c(()=>{u.route=r.value,u.isActive=s.value,u.isExactActive=i.value,u.error=zc(Qt(e.to))?null:'Invalid "to" value'},{flush:"post"})}}return{route:r,href:F(()=>r.value.href),isActive:s,isExactActive:i,navigate:l}}const Cg=he({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Xl,setup(e,{slots:t}){const n=Br(Xl(e)),{options:r}=qe(Uo),o=F(()=>({[Zl(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Zl(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const s=t.default&&t.default(n);return e.custom?s:le("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},s)}}}),xg=Cg;function Tg(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Og(e,t){for(const n in t){const r=t[n],o=e[n];if(typeof r=="string"){if(r!==o)return!1}else if(!ut(o)||o.length!==r.length||r.some((s,i)=>s!==o[i]))return!1}return!0}function Jl(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Zl=(e,t,n)=>e??t??n,Pg=he({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=qe(Vs),o=F(()=>e.route||r.value),s=qe(Yl,0),i=F(()=>{let u=Qt(s);const{matched:f}=o.value;let c;for(;(c=f[u])&&!c.components;)u++;return u}),l=F(()=>o.value.matched[i.value]);en(Yl,F(()=>i.value+1)),en(Ag,l),en(Vs,o);const a=ce();return je(()=>[a.value,l.value,e.name],([u,f,c],[d,p,v])=>{f&&(f.instances[c]=u,p&&p!==f&&u&&u===d&&(f.leaveGuards.size||(f.leaveGuards=p.leaveGuards),f.updateGuards.size||(f.updateGuards=p.updateGuards))),u&&f&&(!p||!ln(f,p)||!d)&&(f.enterCallbacks[c]||[]).forEach(_=>_(u))},{flush:"post"}),()=>{const u=o.value,f=e.name,c=l.value,d=c&&c.components[f];if(!d)return Ql(n.default,{Component:d,route:u});const p=c.props[f],v=p?p===!0?u.params:typeof p=="function"?p(u):p:null,y=le(d,me({},v,t,{onVnodeUnmounted:E=>{E.component.isUnmounted&&(c.instances[f]=null)},ref:a}));if(Mt&&y.ref){const E={depth:i.value,name:c.name,path:c.path,meta:c.meta};(ut(y.ref)?y.ref.map(h=>h.i):[y.ref.i]).forEach(h=>{h.__vrv_devtools=E})}return Ql(n.default,{Component:y,route:u})||y}}});function Ql(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Ig=Pg;function ur(e,t){const n=me({},e,{matched:e.matched.map(r=>Ug(r,["instances","children","aliasOf"]))});return{_custom:{type:null,readOnly:!0,display:e.fullPath,tooltip:t,value:n}}}function to(e){return{_custom:{display:e}}}let Lg=0;function Rg(e,t,n){if(t.__hasDevtools)return;t.__hasDevtools=!0;const r=Lg++;Lm({id:"org.vuejs.router"+(r?"."+r:""),label:"Vue Router",packageName:"vue-router",homepage:"https://router.vuejs.org",logo:"https://router.vuejs.org/logo.png",componentStateTypes:["Routing"],app:e},o=>{typeof o.now!="function"&&console.warn("[Vue Router]: You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html."),o.on.inspectComponent((f,c)=>{f.instanceData&&f.instanceData.state.push({type:"Routing",key:"$route",editable:!1,value:ur(t.currentRoute.value,"Current Route")})}),o.on.visitComponentTree(({treeNode:f,componentInstance:c})=>{if(c.__vrv_devtools){const d=c.__vrv_devtools;f.tags.push({label:(d.name?`${d.name.toString()}: `:"")+d.path,textColor:0,tooltip:"This component is rendered by <router-view>",backgroundColor:Yc})}ut(c.__vrl_devtools)&&(c.__devtoolsApi=o,c.__vrl_devtools.forEach(d=>{let p=d.route.path,v=Zc,_="",y=0;d.error?(p=d.error,v=Fg,y=Bg):d.isExactActive?(v=Jc,_="This is exactly active"):d.isActive&&(v=Xc,_="This link is active"),f.tags.push({label:p,textColor:y,tooltip:_,backgroundColor:v})}))}),je(t.currentRoute,()=>{a(),o.notifyComponentUpdate(),o.sendInspectorTree(l),o.sendInspectorState(l)});const s="router:navigations:"+r;o.addTimelineLayer({id:s,label:`Router${r?" "+r:""} Navigations`,color:4237508}),t.onError((f,c)=>{o.addTimelineEvent({layerId:s,event:{title:"Error during Navigation",subtitle:c.fullPath,logType:"error",time:o.now(),data:{error:f},groupId:c.meta.__navigationId}})});let i=0;t.beforeEach((f,c)=>{const d={guard:to("beforeEach"),from:ur(c,"Current Location during this navigation"),to:ur(f,"Target location")};Object.defineProperty(f.meta,"__navigationId",{value:i++}),o.addTimelineEvent({layerId:s,event:{time:o.now(),title:"Start of navigation",subtitle:f.fullPath,data:d,groupId:f.meta.__navigationId}})}),t.afterEach((f,c,d)=>{const p={guard:to("afterEach")};d?(p.failure={_custom:{type:Error,readOnly:!0,display:d?d.message:"",tooltip:"Navigation Failure",value:d}},p.status=to("❌")):p.status=to("✅"),p.from=ur(c,"Current Location during this navigation"),p.to=ur(f,"Target location"),o.addTimelineEvent({layerId:s,event:{title:"End of navigation",subtitle:f.fullPath,time:o.now(),data:p,logType:d?"warning":"default",groupId:f.meta.__navigationId}})});const l="router-inspector:"+r;o.addInspector({id:l,label:"Routes"+(r?" "+r:""),icon:"book",treeFilterPlaceholder:"Search routes"});function a(){if(!u)return;const f=u;let c=n.getRoutes().filter(d=>!d.parent||!d.parent.record.components);c.forEach(tf),f.filter&&(c=c.filter(d=>Ms(d,f.filter.toLowerCase()))),c.forEach(d=>ef(d,t.currentRoute.value)),f.rootNodes=c.map(Qc)}let u;o.on.getInspectorTree(f=>{u=f,f.app===e&&f.inspectorId===l&&a()}),o.on.getInspectorState(f=>{if(f.app===e&&f.inspectorId===l){const d=n.getRoutes().find(p=>p.record.__vd_id===f.nodeId);d&&(f.state={options:Ng(d)})}}),o.sendInspectorTree(l),o.sendInspectorState(l)})}function Dg(e){return e.optional?e.repeatable?"*":"?":e.repeatable?"+":""}function Ng(e){const{record:t}=e,n=[{editable:!1,key:"path",value:t.path}];return t.name!=null&&n.push({editable:!1,key:"name",value:t.name}),n.push({editable:!1,key:"regexp",value:e.re}),e.keys.length&&n.push({editable:!1,key:"keys",value:{_custom:{type:null,readOnly:!0,display:e.keys.map(r=>`${r.name}${Dg(r)}`).join(" "),tooltip:"Param keys",value:e.keys}}}),t.redirect!=null&&n.push({editable:!1,key:"redirect",value:t.redirect}),e.alias.length&&n.push({editable:!1,key:"aliases",value:e.alias.map(r=>r.record.path)}),Object.keys(e.record.meta).length&&n.push({editable:!1,key:"meta",value:e.record.meta}),n.push({key:"score",editable:!1,value:{_custom:{type:null,readOnly:!0,display:e.score.map(r=>r.join(", ")).join(" | "),tooltip:"Score used to sort routes",value:e.score}}}),n}const Yc=15485081,Xc=2450411,Jc=8702998,Vg=2282478,Zc=16486972,Mg=6710886,Fg=16704226,Bg=12131356;function Qc(e){const t=[],{record:n}=e;n.name!=null&&t.push({label:String(n.name),textColor:0,backgroundColor:Vg}),n.aliasOf&&t.push({label:"alias",textColor:0,backgroundColor:Zc}),e.__vd_match&&t.push({label:"matches",textColor:0,backgroundColor:Yc}),e.__vd_exactActive&&t.push({label:"exact",textColor:0,backgroundColor:Jc}),e.__vd_active&&t.push({label:"active",textColor:0,backgroundColor:Xc}),n.redirect&&t.push({label:typeof n.redirect=="string"?`redirect: ${n.redirect}`:"redirects",textColor:16777215,backgroundColor:Mg});let r=n.__vd_id;return r==null&&(r=String(Hg++),n.__vd_id=r),{id:r,label:n.path,tags:t,children:e.children.map(Qc)}}let Hg=0;const $g=/^\/(.*)\/([a-z]*)$/;function ef(e,t){const n=t.matched.length&&ln(t.matched[t.matched.length-1],e.record);e.__vd_exactActive=e.__vd_active=n,n||(e.__vd_active=t.matched.some(r=>ln(r,e.record))),e.children.forEach(r=>ef(r,t))}function tf(e){e.__vd_match=!1,e.children.forEach(tf)}function Ms(e,t){const n=String(e.re).match($g);if(e.__vd_match=!1,!n||n.length<3)return!1;if(new RegExp(n[1].replace(/\$$/,""),n[2]).test(t))return e.children.forEach(i=>Ms(i,t)),e.record.path!=="/"||t==="/"?(e.__vd_match=e.re.test(t),!0):!1;const o=e.record.path.toLowerCase(),s=zn(o);return!t.startsWith("/")&&(s.includes(t)||o.includes(t))||s.startsWith(t)||o.startsWith(t)||e.record.name&&String(e.record.name).includes(t)?!0:e.children.some(i=>Ms(i,t))}function Ug(e,t){const n={};for(const r in e)t.includes(r)||(n[r]=e[r]);return n}function jg(e){const t=_g(e.routes,e),n=e.parseQuery||Sg,r=e.stringifyQuery||Gl,o=e.history,s=ar(),i=ar(),l=ar(),a=Ot(Nt);let u=Nt;Mt&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const f=ps.bind(null,T=>""+T),c=ps.bind(null,Wm),d=ps.bind(null,zn);function p(T,q){let z,Z;return Kc(T)?(z=t.getRecordMatcher(T),Z=q):Z=T,t.addRoute(Z,z)}function v(T){const q=t.getRecordMatcher(T);q&&t.removeRoute(q)}function _(){return t.getRoutes().map(T=>T.record)}function y(T){return!!t.getRecordMatcher(T)}function E(T,q){if(q=me({},q||a.value),typeof T=="string"){const g=hs(n,T,q.path),k=t.resolve({path:g.path},q),O=o.createHref(g.fullPath);return me(g,k,{params:d(k.params),hash:zn(g.hash),redirectedFrom:void 0,href:O})}let z;if(T.path!=null)z=me({},T,{path:hs(n,T.path,q.path).path});else{const g=me({},T.params);for(const k in g)g[k]==null&&delete g[k];z=me({},T,{params:c(g)}),q.params=c(q.params)}const Z=t.resolve(z,q),de=T.hash||"";Z.params=f(d(Z.params));const Ee=Ym(r,me({},T,{hash:jm(de),path:Z.path})),m=o.createHref(Ee);return me({fullPath:Ee,hash:de,query:r===Gl?wg(T.query):T.query||{}},Z,{redirectedFrom:void 0,href:m})}function S(T){return typeof T=="string"?hs(n,T,a.value.path):me({},T)}function h(T,q){if(u!==T)return Kn(8,{from:q,to:T})}function b(T){return M(T)}function R(T){return b(me(S(T),{replace:!0}))}function j(T){const q=T.matched[T.matched.length-1];if(q&&q.redirect){const{redirect:z}=q;let Z=typeof z=="function"?z(T):z;return typeof Z=="string"&&(Z=Z.includes("?")||Z.includes("#")?Z=S(Z):{path:Z},Z.params={}),me({query:T.query,hash:T.hash,params:Z.path!=null?{}:T.params},Z)}}function M(T,q){const z=u=E(T),Z=a.value,de=T.state,Ee=T.force,m=T.replace===!0,g=j(z);if(g)return M(me(S(g),{state:typeof g=="object"?me({},de,g.state):de,force:Ee,replace:m}),q||z);const k=z;k.redirectedFrom=q;let O;return!Ee&&Xm(r,Z,z)&&(O=Kn(16,{to:k,from:Z}),Te(Z,Z,!0,!1)),(O?Promise.resolve(O):x(k,Z)).catch(C=>Rt(C)?Rt(C,2)?C:ye(C):K(C,k,Z)).then(C=>{if(C){if(Rt(C,2))return M(me({replace:m},S(C.to),{state:typeof C.to=="object"?me({},de,C.to.state):de,force:Ee}),q||k)}else C=A(k,Z,!0,m,de);return H(k,Z,C),C})}function w(T,q){const z=h(T,q);return z?Promise.reject(z):Promise.resolve()}function U(T){const q=gt.values().next().value;return q&&typeof q.runWithContext=="function"?q.runWithContext(T):T()}function x(T,q){let z;const[Z,de,Ee]=zg(T,q);z=ms(Z.reverse(),"beforeRouteLeave",T,q);for(const g of Z)g.leaveGuards.forEach(k=>{z.push(Zt(k,T,q))});const m=w.bind(null,T,q);return z.push(m),et(z).then(()=>{z=[];for(const g of s.list())z.push(Zt(g,T,q));return z.push(m),et(z)}).then(()=>{z=ms(de,"beforeRouteUpdate",T,q);for(const g of de)g.updateGuards.forEach(k=>{z.push(Zt(k,T,q))});return z.push(m),et(z)}).then(()=>{z=[];for(const g of Ee)if(g.beforeEnter)if(ut(g.beforeEnter))for(const k of g.beforeEnter)z.push(Zt(k,T,q));else z.push(Zt(g.beforeEnter,T,q));return z.push(m),et(z)}).then(()=>(T.matched.forEach(g=>g.enterCallbacks={}),z=ms(Ee,"beforeRouteEnter",T,q,U),z.push(m),et(z))).then(()=>{z=[];for(const g of i.list())z.push(Zt(g,T,q));return z.push(m),et(z)}).catch(g=>Rt(g,8)?g:Promise.reject(g))}function H(T,q,z){l.list().forEach(Z=>U(()=>Z(T,q,z)))}function A(T,q,z,Z,de){const Ee=h(T,q);if(Ee)return Ee;const m=q===Nt,g=Mt?history.state:{};z&&(Z||m?o.replace(T.fullPath,me({scroll:m&&g&&g.scroll},de)):o.push(T.fullPath,de)),a.value=T,Te(T,q,z,m),ye()}let D;function J(){D||(D=o.listen((T,q,z)=>{if(!Qe.listening)return;const Z=E(T),de=j(Z);if(de){M(me(de,{replace:!0}),Z).catch(yr);return}u=Z;const Ee=a.value;Mt&&og(Bl(Ee.fullPath,z.delta),$o()),x(Z,Ee).catch(m=>Rt(m,12)?m:Rt(m,2)?(M(m.to,Z).then(g=>{Rt(g,20)&&!z.delta&&z.type===Pr.pop&&o.go(-1,!1)}).catch(yr),Promise.reject()):(z.delta&&o.go(-z.delta,!1),K(m,Z,Ee))).then(m=>{m=m||A(Z,Ee,!1),m&&(z.delta&&!Rt(m,8)?o.go(-z.delta,!1):z.type===Pr.pop&&Rt(m,20)&&o.go(-1,!1)),H(Z,Ee,m)}).catch(yr)}))}let ee=ar(),P=ar(),N;function K(T,q,z){ye(T);const Z=P.list();return Z.length?Z.forEach(de=>de(T,q,z)):console.error(T),Promise.reject(T)}function ue(){return N&&a.value!==Nt?Promise.resolve():new Promise((T,q)=>{ee.add([T,q])})}function ye(T){return N||(N=!T,J(),ee.list().forEach(([q,z])=>T?z(T):q()),ee.reset()),T}function Te(T,q,z,Z){const{scrollBehavior:de}=e;if(!Mt||!de)return Promise.resolve();const Ee=!z&&sg(Bl(T.fullPath,0))||(Z||!z)&&history.state&&history.state.scroll||null;return Zn().then(()=>de(T,q,Ee)).then(m=>m&&rg(m)).catch(m=>K(m,T,q))}const be=T=>o.go(T);let Ze;const gt=new Set,Qe={currentRoute:a,listening:!0,addRoute:p,removeRoute:v,clearRoutes:t.clearRoutes,hasRoute:y,getRoutes:_,resolve:E,options:e,push:b,replace:R,go:be,back:()=>be(-1),forward:()=>be(1),beforeEach:s.add,beforeResolve:i.add,afterEach:l.add,onError:P.add,isReady:ue,install(T){const q=this;T.component("RouterLink",xg),T.component("RouterView",Ig),T.config.globalProperties.$router=q,Object.defineProperty(T.config.globalProperties,"$route",{enumerable:!0,get:()=>Qt(a)}),Mt&&!Ze&&a.value===Nt&&(Ze=!0,b(o.location).catch(de=>{}));const z={};for(const de in Nt)Object.defineProperty(z,de,{get:()=>a.value[de],enumerable:!0});T.provide(Uo,q),T.provide(bi,Mu(z)),T.provide(Vs,a);const Z=T.unmount;gt.add(T),T.unmount=function(){gt.delete(T),gt.size<1&&(u=Nt,D&&D(),D=null,a.value=Nt,Ze=!1,N=!1),Z()},Mt&&Rg(T,q,t)}};function et(T){return T.reduce((q,z)=>q.then(()=>U(z)),Promise.resolve())}return Qe}function zg(e,t){const n=[],r=[],o=[],s=Math.max(t.matched.length,e.matched.length);for(let i=0;iln(u,l))?r.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(u=>ln(u,a))||o.push(a))}return[n,r,o]}function fn(){return qe(Uo)}function zt(e){return qe(bi)}var Ei=Symbol(""),Pt=()=>{const e=qe(Ei);if(!e)throw new Error("useClientData() is called without provider.");return e},Kg=()=>Pt().pageComponent,Qn=()=>Pt().pageData,Et=()=>Pt().pageFrontmatter,Wg=()=>Pt().pageHead,qg=()=>Pt().pageLang,Gg=()=>Pt().pageLayout,er=()=>Pt().routeLocale,Yg=()=>Pt().routes,nf=()=>Pt().siteData,ki=()=>Pt().siteLocaleData,Xg=Symbol(""),Fs=Ot(Sm),$n=Ot(wm),rf=(e,t)=>{const n=mm(e,t);if($n.value[n])return n;const r=encodeURI(n);if($n.value[r])return r;const o=Fs.value[n]||Fs.value[r];return o||n},Ir=(e,t)=>{const{pathname:n,hashAndQueries:r}=Lc(e),o=rf(n,t),s=o+r;return $n.value[o]?{...$n.value[o],path:s,notFound:!1}:{...$n.value["/404.html"],path:s,notFound:!0}},Jg=(e,t)=>{const{pathname:n,hashAndQueries:r}=Lc(e);return rf(n,t)+r},Zg=e=>{if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget){const t=e.currentTarget.getAttribute("target");if(t!=null&&t.match(/\b_blank\b/i))return}return e.preventDefault(),!0}},jo=he({name:"RouteLink",props:{to:{type:String,required:!0},active:Boolean,activeClass:{type:String,default:"route-link-active"}},slots:Object,setup(e,{slots:t}){const n=fn(),r=zt(),o=F(()=>e.to.startsWith("#")||e.to.startsWith("?")?e.to:`/learning-kotlin/${Jg(e.to,r.path).substring(1)}`);return()=>le("a",{class:["route-link",{[e.activeClass]:e.active}],href:o.value,onClick:(s={})=>{Zg(s)&&n.push(e.to).catch()}},t.default())}}),tr=he({name:"AutoLink",props:{config:{type:Object,required:!0}},slots:Object,setup(e,{slots:t}){const n=op(e,"config"),r=zt(),o=nf(),s=F(()=>Kr(n.value.link)),i=F(()=>n.value.target||(s.value?"_blank":void 0)),l=F(()=>i.value==="_blank"),a=F(()=>!s.value&&!l.value),u=F(()=>n.value.rel||(l.value?"noopener noreferrer":null)),f=F(()=>n.value.ariaLabel??n.value.text),c=F(()=>{if(n.value.exact)return!1;const p=Object.keys(o.value.locales);return p.length?p.every(v=>v!==n.value.link):n.value.link!=="/"}),d=F(()=>a.value?n.value.activeMatch?(n.value.activeMatch instanceof RegExp?n.value.activeMatch:new RegExp(n.value.activeMatch,"u")).test(r.path):c.value?r.path.startsWith(n.value.link):r.path===n.value.link:!1);return()=>{const{before:p,after:v,default:_}=t,y=(_==null?void 0:_(n.value))??[p==null?void 0:p(n.value),n.value.text,v==null?void 0:v(n.value)];return a.value?le(jo,{class:"auto-link",to:n.value.link,active:d.value,"aria-label":f.value},()=>y):le("a",{class:"auto-link external-link",href:n.value.link,"aria-label":f.value,rel:u.value,target:i.value},y)}}}),Si=he({name:"ClientOnly",setup(e,t){const n=ce(!1);return Be(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),wi=he({name:"Content",props:{path:{type:String,required:!1,default:""}},setup(e){const t=Kg(),n=F(()=>{if(!e.path)return t.value;const r=Ir(e.path);return Rp(async()=>r.loader().then(({comp:o})=>o))});return()=>le(n.value)}}),Qg="Layout",ev="en-US",gn=Br({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageHead:(e,t,n)=>{const r=mt(t.description)?t.description:n.description,o=[...Array.isArray(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Em(o)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||ev,resolvePageLayout:(e,t)=>{const n=mt(e.frontmatter.layout)?e.frontmatter.layout:Qg;if(!t[n])throw new Error(`[vuepress] Cannot resolve layout: ${n}`);return t[n]},resolveRouteLocale:(e,t)=>gm(e,decodeURI(t)),resolveSiteLocaleData:({base:e,locales:t,...n},r)=>{var o;return{...n,...t[r],head:[...((o=t[r])==null?void 0:o.head)??[],...n.head]}}}),It=(e={})=>e,zo=e=>Ho(e)?e:`/learning-kotlin/${Dc(e)}`;function Ko(e){return ku()?(Td(e),!0):!1}function bt(e){return typeof e=="function"?e():Qt(e)}const Ai=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const tv=Object.prototype.toString,nv=e=>tv.call(e)==="[object Object]",Bs=()=>{};function of(e,t){function n(...r){return new Promise((o,s)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(o).catch(s)})}return n}const sf=e=>e();function rv(e,t={}){let n,r,o=Bs;const s=l=>{clearTimeout(l),o(),o=Bs};return l=>{const a=bt(e),u=bt(t.maxWait);return n&&s(n),a<=0||u!==void 0&&u<=0?(r&&(s(r),r=null),Promise.resolve(l())):new Promise((f,c)=>{o=t.rejectOnCancel?c:f,u&&!r&&(r=setTimeout(()=>{n&&s(n),r=null,f(l())},u)),n=setTimeout(()=>{r&&s(r),r=null,f(l())},a)})}}function ov(e=sf){const t=ce(!0);function n(){t.value=!1}function r(){t.value=!0}const o=(...s)=>{t.value&&e(...s)};return{isActive:Lo(t),pause:n,resume:r,eventFilter:o}}function sv(e){let t;function n(){return t||(t=e()),t}return n.reset=async()=>{const r=t;t=void 0,r&&await r},n}function iv(e){return Ur()}function lv(e,t=200,n={}){return of(rv(t,n),e)}function av(e,t,n={}){const{eventFilter:r=sf,...o}=n;return je(e,of(r,t),o)}function uv(e,t,n={}){const{eventFilter:r,...o}=n,{eventFilter:s,pause:i,resume:l,isActive:a}=ov(r);return{stop:av(e,t,{...o,eventFilter:s}),pause:i,resume:l,isActive:a}}function Ci(e,t=!0,n){iv()?Be(e,n):t?e():Zn(e)}function cv(e,t,n={}){const{immediate:r=!0}=n,o=ce(!1);let s=null;function i(){s&&(clearTimeout(s),s=null)}function l(){o.value=!1,i()}function a(...u){i(),o.value=!0,s=setTimeout(()=>{o.value=!1,s=null,e(...u)},bt(t))}return r&&(o.value=!0,Ai&&a()),Ko(l),{isPending:Lo(o),start:a,stop:l}}function fv(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,o=Ne(e),s=ce(e);function i(l){if(arguments.length)return s.value=l,s.value;{const a=bt(n);return s.value=s.value===a?bt(r):a,s.value}}return o?i:[s,i]}const an=Ai?window:void 0,lf=Ai?window.navigator:void 0;function En(e){var t;const n=bt(e);return(t=n==null?void 0:n.$el)!=null?t:n}function ct(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,o]=e,t=an):[t,n,r,o]=e,!t)return Bs;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const s=[],i=()=>{s.forEach(f=>f()),s.length=0},l=(f,c,d,p)=>(f.addEventListener(c,d,p),()=>f.removeEventListener(c,d,p)),a=je(()=>[En(t),bt(o)],([f,c])=>{if(i(),!f)return;const d=nv(c)?{...c}:c;s.push(...n.flatMap(p=>r.map(v=>l(f,p,v,d))))},{immediate:!0,flush:"post"}),u=()=>{a(),i()};return Ko(u),u}function dv(){const e=ce(!1),t=Ur();return t&&Be(()=>{e.value=!0},t),e}function Wo(e){const t=dv();return F(()=>(t.value,!!e()))}function xi(e,t={}){const{window:n=an}=t,r=Wo(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let o;const s=ce(!1),i=u=>{s.value=u.matches},l=()=>{o&&("removeEventListener"in o?o.removeEventListener("change",i):o.removeListener(i))},a=_c(()=>{r.value&&(l(),o=n.matchMedia(bt(e)),"addEventListener"in o?o.addEventListener("change",i):o.addListener(i),s.value=o.matches)});return Ko(()=>{a(),l(),o=void 0}),s}function ea(e,t={}){const{controls:n=!1,navigator:r=lf}=t,o=Wo(()=>r&&"permissions"in r),s=Ot(),i=typeof e=="string"?{name:e}:e,l=Ot(),a=()=>{var f,c;l.value=(c=(f=s.value)==null?void 0:f.state)!=null?c:"prompt"};ct(s,"change",a);const u=sv(async()=>{if(o.value){if(!s.value)try{s.value=await r.permissions.query(i)}catch{s.value=void 0}finally{a()}if(n)return fe(s.value)}});return u(),n?{state:l,isSupported:o,query:u}:l}function pv(e={}){const{navigator:t=lf,read:n=!1,source:r,copiedDuring:o=1500,legacy:s=!1}=e,i=Wo(()=>t&&"clipboard"in t),l=ea("clipboard-read"),a=ea("clipboard-write"),u=F(()=>i.value||s),f=ce(""),c=ce(!1),d=cv(()=>c.value=!1,o);function p(){i.value&&E(l.value)?t.clipboard.readText().then(S=>{f.value=S}):f.value=y()}u.value&&n&&ct(["copy","cut"],p);async function v(S=bt(r)){u.value&&S!=null&&(i.value&&E(a.value)?await t.clipboard.writeText(S):_(S),f.value=S,c.value=!0,d.start())}function _(S){const h=document.createElement("textarea");h.value=S??"",h.style.position="absolute",h.style.opacity="0",document.body.appendChild(h),h.select(),document.execCommand("copy"),h.remove()}function y(){var S,h,b;return(b=(h=(S=document==null?void 0:document.getSelection)==null?void 0:S.call(document))==null?void 0:h.toString())!=null?b:""}function E(S){return S==="granted"||S==="prompt"}return{isSupported:u,text:f,copied:c,copy:v}}const no=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},ro="__vueuse_ssr_handlers__",hv=mv();function mv(){return ro in no||(no[ro]=no[ro]||{}),no[ro]}function gv(e,t){return hv[e]||t}function vv(e){return xi("(prefers-color-scheme: dark)",e)}function _v(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 yv={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()}},ta="vueuse-storage";function Ti(e,t,n,r={}){var o;const{flush:s="pre",deep:i=!0,listenToStorageChanges:l=!0,writeDefaults:a=!0,mergeDefaults:u=!1,shallow:f,window:c=an,eventFilter:d,onError:p=x=>{console.error(x)},initOnMounted:v}=r,_=(f?Ot:ce)(typeof t=="function"?t():t);if(!n)try{n=gv("getDefaultStorage",()=>{var x;return(x=an)==null?void 0:x.localStorage})()}catch(x){p(x)}if(!n)return _;const y=bt(t),E=_v(y),S=(o=r.serializer)!=null?o:yv[E],{pause:h,resume:b}=uv(_,()=>j(_.value),{flush:s,deep:i,eventFilter:d});c&&l&&Ci(()=>{n instanceof Storage?ct(c,"storage",w):ct(c,ta,U),v&&w()}),v||w();function R(x,H){if(c){const A={key:e,oldValue:x,newValue:H,storageArea:n};c.dispatchEvent(n instanceof Storage?new StorageEvent("storage",A):new CustomEvent(ta,{detail:A}))}}function j(x){try{const H=n.getItem(e);if(x==null)R(H,null),n.removeItem(e);else{const A=S.write(x);H!==A&&(n.setItem(e,A),R(H,A))}}catch(H){p(H)}}function M(x){const H=x?x.newValue:n.getItem(e);if(H==null)return a&&y!=null&&n.setItem(e,S.write(y)),y;if(!x&&u){const A=S.read(H);return typeof u=="function"?u(A,y):E==="object"&&!Array.isArray(A)?{...y,...A}:A}else return typeof H!="string"?H:S.read(H)}function w(x){if(!(x&&x.storageArea!==n)){if(x&&x.key==null){_.value=y;return}if(!(x&&x.key!==e)){h();try{(x==null?void 0:x.newValue)!==S.write(_.value)&&(_.value=M(x))}catch(H){p(H)}finally{x?Zn(b):b()}}}}function U(x){w(x.detail)}return _}function bv(e,t,n={}){const{window:r=an,...o}=n;let s;const i=Wo(()=>r&&"ResizeObserver"in r),l=()=>{s&&(s.disconnect(),s=void 0)},a=F(()=>{const c=bt(e);return Array.isArray(c)?c.map(d=>En(d)):[En(c)]}),u=je(a,c=>{if(l(),i.value&&r){s=new ResizeObserver(t);for(const d of c)d&&s.observe(d,o)}},{immediate:!0,flush:"post"}),f=()=>{l(),u()};return Ko(f),{isSupported:i,stop:f}}function Ev(e,t={width:0,height:0},n={}){const{window:r=an,box:o="content-box"}=n,s=F(()=>{var c,d;return(d=(c=En(e))==null?void 0:c.namespaceURI)==null?void 0:d.includes("svg")}),i=ce(t.width),l=ce(t.height),{stop:a}=bv(e,([c])=>{const d=o==="border-box"?c.borderBoxSize:o==="content-box"?c.contentBoxSize:c.devicePixelContentBoxSize;if(r&&s.value){const p=En(e);if(p){const v=p.getBoundingClientRect();i.value=v.width,l.value=v.height}}else if(d){const p=Array.isArray(d)?d:[d];i.value=p.reduce((v,{inlineSize:_})=>v+_,0),l.value=p.reduce((v,{blockSize:_})=>v+_,0)}else i.value=c.contentRect.width,l.value=c.contentRect.height},n);Ci(()=>{const c=En(e);c&&(i.value="offsetWidth"in c?c.offsetWidth:t.width,l.value="offsetHeight"in c?c.offsetHeight:t.height)});const u=je(()=>En(e),c=>{i.value=c?t.width:0,l.value=c?t.height:0});function f(){a(),u()}return{width:i,height:l,stop:f}}function kv(e={}){const{window:t=an,behavior:n="auto"}=e;if(!t)return{x:ce(0),y:ce(0)};const r=ce(t.scrollX),o=ce(t.scrollY),s=F({get(){return r.value},set(l){scrollTo({left:l,behavior:n})}}),i=F({get(){return o.value},set(l){scrollTo({top:l,behavior:n})}});return ct(t,"scroll",()=>{r.value=t.scrollX,o.value=t.scrollY},{capture:!1,passive:!0}),{x:s,y:i}}function Sv(e={}){const{window:t=an,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:o=!0,includeScrollbar:s=!0,type:i="inner"}=e,l=ce(n),a=ce(r),u=()=>{t&&(i==="outer"?(l.value=t.outerWidth,a.value=t.outerHeight):s?(l.value=t.innerWidth,a.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,a.value=t.document.documentElement.clientHeight))};if(u(),Ci(u),ct("resize",u,{passive:!0}),o){const f=xi("(orientation: portrait)");je(f,()=>u())}return{width:l,height:a}}const na=async(e,t)=>{const{path:n,query:r}=e.currentRoute.value,{scrollBehavior:o}=e.options;e.options.scrollBehavior=void 0,await e.replace({path:n,query:r,hash:t}),e.options.scrollBehavior=o},wv=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:r=5})=>{const o=fn();ct("scroll",lv(()=>{var v,_;const i=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(i-0)c.some(E=>E.hash===y.hash));for(let y=0;y=(((v=E.parentElement)==null?void 0:v.offsetTop)??0)-r,b=!S||i<(((_=S.parentElement)==null?void 0:_.offsetTop)??0)-r;if(!(h&&b))continue;const j=decodeURIComponent(o.currentRoute.value.hash),M=decodeURIComponent(E.hash);if(j===M)return;if(f){for(let w=y+1;w{if(t===!1)return[];const[n,r]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t,o=e.filter(i=>i.level>=n&&i.level<=r),s=[];e:for(let i=0;i=0;a--){const u=o[a];if(u.level{let n;if(t.length){const r=e.cloneNode(!0);r.querySelectorAll(t.join(",")).forEach(o=>{o.remove()}),n=r.textContent||""}else n=e.textContent||"";return n.trim()},Rv=({selector:e=[...new Array(6)].map((r,o)=>`[vp-content] h${o+1}`).join(","),levels:t=2,ignore:n=[]}={})=>{const r=Array.from(document.querySelectorAll(e)).filter(o=>o.id&&o.hasChildNodes()).map(o=>{const s=Number(o.tagName[1]);return{element:o,title:Lv(o,n),link:`#${o.id}`,slug:o.id,level:s}});return Iv(r,t)},af=(e,t)=>{var r;const n=(r=Ur())==null?void 0:r.appContext.components;return n?e in n||rt(e)in n||Fr(rt(e))in n:!1},uf=e=>new Promise(t=>{setTimeout(t,e)}),Oi=e=>{const t=er();return F(()=>e[t.value]??{})},Dv=()=>{const e=Yg();return F(()=>Object.keys(e.value))},Nv=e=>typeof e<"u",cf=(e,t)=>mt(e)&&e.startsWith(t),{keys:Vv}=Object,ff=e=>cf(e,"/");var Mv={"/en/":{backToTop:"Back to top"},"/fr/":{backToTop:"Retour en haut"},"/":{backToTop:"Back to top"}};const Fv=he({name:"BackToTop",setup(){const e=Et(),t=Oi(Mv),n=Ot(),{height:r}=Ev(n),{height:o}=Sv(),{y:s}=kv(),i=F(()=>e.value.backToTop!==!1&&s.value>100),l=F(()=>s.value/(r.value-o.value)*100);return Be(()=>{n.value=document.body}),()=>le(Bo,{name:"back-to-top"},()=>i.value?le("button",{type:"button",class:"vp-back-to-top-button","aria-label":t.value.backToTop,onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},[le("span",{class:"vp-scroll-progress",role:"progressbar","aria-labelledby":"loadinglabel","aria-valuenow":l.value},le("svg",le("circle",{cx:"26",cy:"26",r:"24",fill:"none",stroke:"currentColor","stroke-width":"4","stroke-dasharray":`${Math.PI*l.value*.48} ${Math.PI*(100-l.value)*.48}`}))),le("div",{class:"back-to-top-icon"})]):null)}}),Bv=It({rootComponents:[Fv]}),Hv=Object.freeze(Object.defineProperty({__proto__:null,default:Bv},Symbol.toStringTag,{value:"Module"})),$v=/language-(shellscript|shell|bash|sh|zsh)/,Uv=({delay:e=500,duration:t=2e3,locales:n,selector:r,showInMobile:o,ignoreSelector:s=[],transform:i})=>{const l=xi("(max-width: 419px)"),a=F(()=>!l.value||o),u=Oi(n),f=Qn(),c=y=>{var S;if(y.hasAttribute("copy-code"))return;const E=document.createElement("button");E.type="button",E.classList.add("vp-copy-code-button"),E.setAttribute("aria-label",u.value.copy),E.setAttribute("data-copied",u.value.copied),(S=y.parentElement)==null||S.insertBefore(E,y),y.setAttribute("copy-code","")};je(()=>[f.value.path,a.value],async()=>{document.body.classList.toggle("no-copy-code",!a.value),a.value&&(await Zn(),await uf(e),document.querySelectorAll(r.join(",")).forEach(c))},{immediate:!0});const{copy:p}=pv({legacy:!0}),v=new WeakMap,_=async(y,E,S)=>{const h=E.cloneNode(!0);s.length&&h.querySelectorAll(s.join(",")).forEach(j=>{j.remove()}),i&&i(h);let b=h.textContent||"";if($v.test(y.className)&&(b=b.replace(/^ *(\$|>) /gm,"")),await p(b),t<=0)return;S.classList.add("copied"),clearTimeout(v.get(S));const R=setTimeout(()=>{S.classList.remove("copied"),S.blur(),v.delete(S)},t);v.set(S,R)};ct("click",y=>{const E=y.target;if(a.value&&E.matches('div[class*="language-"] > button.vp-copy-code-button')){const S=E.parentElement,h=E.nextElementSibling;if(!S||!h)return;_(S,h,E)}})};var jv=[],zv={"/en/":{copy:"Copy code",copied:"Copied"},"/fr/":{copy:"Copier le code",copied:"Copié"},"/":{copy:"Copy code",copied:"Copied"}},Kv=['[vp-content] div[class*="language-"] pre'];const Wv=It({setup:()=>{Uv({selector:Kv,ignoreSelector:jv,locales:zv,duration:2e3,delay:500,showInMobile:!1})}}),qv=Object.freeze(Object.defineProperty({__proto__:null,default:Wv},Symbol.toStringTag,{value:"Module"})),Gv=It({setup(){ct("beforeprint",()=>{document.querySelectorAll("details").forEach(e=>{e.open=!0})})}}),Yv=Object.freeze(Object.defineProperty({__proto__:null,default:Gv},Symbol.toStringTag,{value:"Module"}));/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const ra=(e,t)=>{e.classList.add(t)},oa=(e,t)=>{e.classList.remove(t)},Xv=e=>{var t;(t=e==null?void 0:e.parentNode)==null||t.removeChild(e)},gs=(e,t,n)=>en?n:e,sa=e=>(-1+e)*100,Jv=(()=>{const e=[],t=()=>{const n=e.shift();n&&n(t)};return n=>{e.push(n),e.length===1&&t()}})(),Zv=e=>e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(t,n)=>n.toUpperCase()),oo=(()=>{const e=["Webkit","O","Moz","ms"],t={},n=s=>{const{style:i}=document.body;if(s in i)return s;const l=s.charAt(0).toUpperCase()+s.slice(1);let a=e.length;for(;a--;){const u=`${e[a]}${l}`;if(u in i)return u}return s},r=s=>{const i=Zv(s);return t[i]??(t[i]=n(i))},o=(s,i,l)=>{s.style[r(i)]=l};return(s,i)=>{for(const l in i){const a=i[l];Object.hasOwn(i,l)&&Nv(a)&&o(s,l,a)}}})(),Dt={minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},Pe={percent:null,isRendered:()=>!!document.getElementById("nprogress"),set:e=>{const{speed:t,easing:n}=Dt,r=Pe.isStarted(),o=gs(e,Dt.minimum,1);Pe.percent=o===1?null:o;const s=Pe.render(!r),i=s.querySelector(Dt.barSelector);return s.offsetWidth,Jv(l=>{oo(i,{transform:`translate3d(${sa(o)}%,0,0)`,transition:`all ${t}ms ${n}`}),o===1?(oo(s,{transition:"none",opacity:"1"}),s.offsetWidth,setTimeout(()=>{oo(s,{transition:`all ${t}ms linear`,opacity:"0"}),setTimeout(()=>{Pe.remove(),l()},t)},t)):setTimeout(()=>{l()},t)}),Pe},isStarted:()=>typeof Pe.percent=="number",start:()=>{Pe.percent||Pe.set(0);const e=()=>{setTimeout(()=>{Pe.percent&&(Pe.trickle(),e())},Dt.trickleSpeed)};return e(),Pe},done:e=>!e&&!Pe.percent?Pe:Pe.increase(.3+.5*Math.random()).set(1),increase:e=>{let{percent:t}=Pe;return t?(t=gs(t+(typeof e=="number"?e:(1-t)*gs(Math.random()*t,.1,.95)),0,.994),Pe.set(t)):Pe.start()},trickle:()=>Pe.increase(Math.random()*Dt.trickleRate),render:e=>{if(Pe.isRendered())return document.getElementById("nprogress");ra(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=Dt.template;const n=t.querySelector(Dt.barSelector),r=document.querySelector(Dt.parent),o=e?"-100":sa(Pe.percent??0);return oo(n,{transition:"all 0 linear",transform:`translate3d(${o}%,0,0)`}),r&&(r!==document.body&&ra(r,"nprogress-custom-parent"),r.appendChild(t)),t},remove:()=>{oa(document.documentElement,"nprogress-busy"),oa(document.querySelector(Dt.parent),"nprogress-custom-parent"),Xv(document.getElementById("nprogress"))}},Qv=()=>{Be(()=>{const e=fn(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||Pe.start()}),e.afterEach(n=>{t.add(n.path),Pe.done()})})},e_=It({setup(){Qv()}}),t_=Object.freeze(Object.defineProperty({__proto__:null,default:e_},Symbol.toStringTag,{value:"Module"})),n_=({selector:e='div[class*="language-"].has-collapsed-lines > .collapsed-lines'}={})=>{ct("click",t=>{const n=t.target;if(n.matches(e)){const r=n.parentElement;r!=null&&r.classList.toggle("collapsed")&&r.scrollIntoView({block:"center",behavior:"instant"})}})},r_={setup(){n_()}},o_=Object.freeze(Object.defineProperty({__proto__:null,default:r_},Symbol.toStringTag,{value:"Module"})),s_="VUEPRESS_CODE_TAB_STORE",so=Ti(s_,{}),i_=he({name:"CodeTabs",props:{active:{type:Number,default:0},data:{type:Array,required:!0},id:{type:String,required:!0},tabId:{type:String,default:""}},slots:Object,setup(e,{slots:t}){const n=ce(e.active),r=Ot([]),o=()=>{e.tabId&&(so.value[e.tabId]=e.data[n.value].id)},s=(u=n.value)=>{n.value=u{n.value=u>0?u-1:r.value.length-1,r.value[n.value].focus()},l=(u,f)=>{u.key===" "||u.key==="Enter"?(u.preventDefault(),n.value=f):u.key==="ArrowRight"?(u.preventDefault(),s()):u.key==="ArrowLeft"&&(u.preventDefault(),i()),e.tabId&&(so.value[e.tabId]=e.data[n.value].id)},a=()=>{if(e.tabId){const u=e.data.findIndex(({id:f})=>so.value[e.tabId]===f);if(u!==-1)return u}return e.active};return Be(()=>{n.value=a(),je(()=>so.value[e.tabId],(u,f)=>{if(e.tabId&&u!==f){const c=e.data.findIndex(({id:d})=>d===u);c!==-1&&(n.value=c)}})}),()=>e.data.length?le("div",{class:"vp-code-tabs"},[le("div",{class:"vp-code-tabs-nav",role:"tablist"},e.data.map(({id:u},f)=>{const c=f===n.value;return le("button",{type:"button",ref:d=>{d&&(r.value[f]=d)},class:["vp-code-tab-nav",{active:c}],role:"tab","aria-controls":`codetab-${e.id}-${f}`,"aria-selected":c,onClick:()=>{n.value=f,o()},onKeydown:d=>{l(d,f)}},t[`title${f}`]({value:u,isActive:c}))})),e.data.map(({id:u},f)=>{const c=f===n.value;return le("div",{class:["vp-code-tab",{active:c}],id:`codetab-${e.id}-${f}`,role:"tabpanel","aria-expanded":c},[le("div",{class:"vp-code-tab-title"},t[`title${f}`]({value:u,isActive:c})),t[`tab${f}`]({value:u,isActive:c})])})]):null}}),l_="VUEPRESS_TAB_STORE",vs=Ti(l_,{}),a_=he({name:"Tabs",props:{active:{type:Number,default:0},data:{type:Array,required:!0},id:{type:String,required:!0},tabId:{type:String,default:""}},slots:Object,setup(e,{slots:t}){const n=ce(e.active),r=Ot([]),o=()=>{e.tabId&&(vs.value[e.tabId]=e.data[n.value].id)},s=(u=n.value)=>{n.value=u{n.value=u>0?u-1:r.value.length-1,r.value[n.value].focus()},l=(u,f)=>{u.key===" "||u.key==="Enter"?(u.preventDefault(),n.value=f):u.key==="ArrowRight"?(u.preventDefault(),s()):u.key==="ArrowLeft"&&(u.preventDefault(),i()),o()},a=()=>{if(e.tabId){const u=e.data.findIndex(({id:f})=>vs.value[e.tabId]===f);if(u!==-1)return u}return e.active};return Be(()=>{n.value=a(),je(()=>vs.value[e.tabId],(u,f)=>{if(e.tabId&&u!==f){const c=e.data.findIndex(({id:d})=>d===u);c!==-1&&(n.value=c)}})}),()=>e.data.length?le("div",{class:"vp-tabs"},[le("div",{class:"vp-tabs-nav",role:"tablist"},e.data.map(({id:u},f)=>{const c=f===n.value;return le("button",{type:"button",ref:d=>{d&&(r.value[f]=d)},class:["vp-tab-nav",{active:c}],role:"tab","aria-controls":`tab-${e.id}-${f}`,"aria-selected":c,onClick:()=>{n.value=f,o()},onKeydown:d=>{l(d,f)}},t[`title${f}`]({value:u,isActive:c}))})),e.data.map(({id:u},f)=>{const c=f===n.value;return le("div",{class:["vp-tab",{active:c}],id:`tab-${e.id}-${f}`,role:"tabpanel","aria-expanded":c},[le("div",{class:"vp-tab-title"},t[`title${f}`]({value:u,isActive:c})),t[`tab${f}`]({value:u,isActive:c})])})]):null}}),u_={enhance:({app:e})=>{e.component("CodeTabs",i_),e.component("Tabs",a_)}},c_=Object.freeze(Object.defineProperty({__proto__:null,default:u_},Symbol.toStringTag,{value:"Module"}));var f_=Object.create,df=Object.defineProperty,d_=Object.getOwnPropertyDescriptor,Pi=Object.getOwnPropertyNames,p_=Object.getPrototypeOf,h_=Object.prototype.hasOwnProperty,m_=(e,t)=>function(){return e&&(t=(0,e[Pi(e)[0]])(e=0)),t},g_=(e,t)=>function(){return t||(0,e[Pi(e)[0]])((t={exports:{}}).exports,t),t.exports},v_=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Pi(t))!h_.call(e,o)&&o!==n&&df(e,o,{get:()=>t[o],enumerable:!(r=d_(t,o))||r.enumerable});return e},__=(e,t,n)=>(n=e!=null?f_(p_(e)):{},v_(df(n,"default",{value:e,enumerable:!0}),e)),Wr=m_({"../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.43.0_@types+node@20.16.5__@swc+core@1.5.29_jiti@1.21.6__ldnw4a7r4ccknnz6q542psuydy/node_modules/tsup/assets/esm_shims.js"(){}}),y_=g_({"../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js"(e,t){Wr(),t.exports=r;function n(s){return s instanceof Buffer?Buffer.from(s):new s.constructor(s.buffer.slice(),s.byteOffset,s.length)}function r(s){if(s=s||{},s.circles)return o(s);const i=new Map;if(i.set(Date,c=>new Date(c)),i.set(Map,(c,d)=>new Map(a(Array.from(c),d))),i.set(Set,(c,d)=>new Set(a(Array.from(c),d))),s.constructorHandlers)for(const c of s.constructorHandlers)i.set(c[0],c[1]);let l=null;return s.proto?f:u;function a(c,d){const p=Object.keys(c),v=new Array(p.length);for(let _=0;_new Date(p)),a.set(Map,(p,v)=>new Map(f(Array.from(p),v))),a.set(Set,(p,v)=>new Set(f(Array.from(p),v))),s.constructorHandlers)for(const p of s.constructorHandlers)a.set(p[0],p[1]);let u=null;return s.proto?d:c;function f(p,v){const _=Object.keys(p),y=new Array(_.length);for(let E=0;E<_.length;E++){const S=_[E],h=p[S];if(typeof h!="object"||h===null)y[S]=h;else if(h.constructor!==Object&&(u=a.get(h.constructor)))y[S]=u(h,v);else if(ArrayBuffer.isView(h))y[S]=n(h);else{const b=i.indexOf(h);b!==-1?y[S]=l[b]:y[S]=v(h)}}return y}function c(p){if(typeof p!="object"||p===null)return p;if(Array.isArray(p))return f(p,c);if(p.constructor!==Object&&(u=a.get(p.constructor)))return u(p,c);const v={};i.push(p),l.push(v);for(const _ in p){if(Object.hasOwnProperty.call(p,_)===!1)continue;const y=p[_];if(typeof y!="object"||y===null)v[_]=y;else if(y.constructor!==Object&&(u=a.get(y.constructor)))v[_]=u(y,c);else if(ArrayBuffer.isView(y))v[_]=n(y);else{const E=i.indexOf(y);E!==-1?v[_]=l[E]:v[_]=c(y)}}return i.pop(),l.pop(),v}function d(p){if(typeof p!="object"||p===null)return p;if(Array.isArray(p))return f(p,d);if(p.constructor!==Object&&(u=a.get(p.constructor)))return u(p,d);const v={};i.push(p),l.push(v);for(const _ in p){const y=p[_];if(typeof y!="object"||y===null)v[_]=y;else if(y.constructor!==Object&&(u=a.get(y.constructor)))v[_]=u(y,d);else if(ArrayBuffer.isView(y))v[_]=n(y);else{const E=i.indexOf(y);E!==-1?v[_]=l[E]:v[_]=d(y)}}return i.pop(),l.pop(),v}}}});Wr();Wr();Wr();var b_=typeof navigator<"u",X=typeof window<"u"?window:typeof globalThis<"u"?globalThis:typeof global<"u"?global:{};typeof X.chrome<"u"&&X.chrome.devtools;b_&&(X.self,X.top);typeof navigator<"u"&&navigator.userAgent.toLowerCase().includes("electron");Wr();var E_=__(y_()),k_=/(?:^|[-_/])(\w)/g;function S_(e,t){return t?t.toUpperCase():""}function w_(e){return e&&`${e}`.replace(k_,S_)}function A_(e,t){const n=e.replace(/^[a-z]:/i,"").replace(/\\/g,"/"),r=n.lastIndexOf("/"),o=n.substring(r+1);{const s=o.lastIndexOf(t);return o.substring(0,s)}}var ia=(0,E_.default)({circles:!0});const C_={trailing:!0};function qo(e,t=25,n={}){if(n={...C_,...n},!Number.isFinite(t))throw new TypeError("Expected `wait` to be a finite number");let r,o,s=[],i,l;const a=(u,f)=>(i=x_(e,u,f),i.finally(()=>{if(i=null,n.trailing&&l&&!o){const c=a(u,l);return l=null,c}}),i);return function(...u){return i?(n.trailing&&(l=u),i):new Promise(f=>{const c=!o&&n.leading;clearTimeout(o),o=setTimeout(()=>{o=null;const d=n.leading?r:a(this,u);for(const p of s)p(d);s=[]},t),c?(r=a(this,u),f(r)):s.push(f)})}}async function x_(e,t,n){return await e.apply(t,n)}function Hs(e,t={},n){for(const r in e){const o=e[r],s=n?`${n}:${r}`:r;typeof o=="object"&&o!==null?Hs(o,t,s):typeof o=="function"&&(t[s]=o)}return t}const T_={run:e=>e()},O_=()=>T_,pf=typeof console.createTask<"u"?console.createTask:O_;function P_(e,t){const n=t.shift(),r=pf(n);return e.reduce((o,s)=>o.then(()=>r.run(()=>s(...t))),Promise.resolve())}function I_(e,t){const n=t.shift(),r=pf(n);return Promise.all(e.map(o=>r.run(()=>o(...t))))}function _s(e,t){for(const n of[...e])n(t)}class L_{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(t,n,r={}){if(!t||typeof n!="function")return()=>{};const o=t;let s;for(;this._deprecatedHooks[t];)s=this._deprecatedHooks[t],t=s.to;if(s&&!r.allowDeprecated){let i=s.message;i||(i=`${o} hook has been deprecated`+(s.to?`, please use ${s.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(i)||(console.warn(i),this._deprecatedMessages.add(i))}if(!n.name)try{Object.defineProperty(n,"name",{get:()=>"_"+t.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[t]=this._hooks[t]||[],this._hooks[t].push(n),()=>{n&&(this.removeHook(t,n),n=void 0)}}hookOnce(t,n){let r,o=(...s)=>(typeof r=="function"&&r(),r=void 0,o=void 0,n(...s));return r=this.hook(t,o),r}removeHook(t,n){if(this._hooks[t]){const r=this._hooks[t].indexOf(n);r!==-1&&this._hooks[t].splice(r,1),this._hooks[t].length===0&&delete this._hooks[t]}}deprecateHook(t,n){this._deprecatedHooks[t]=typeof n=="string"?{to:n}:n;const r=this._hooks[t]||[];delete this._hooks[t];for(const o of r)this.hook(t,o)}deprecateHooks(t){Object.assign(this._deprecatedHooks,t);for(const n in t)this.deprecateHook(n,t[n])}addHooks(t){const n=Hs(t),r=Object.keys(n).map(o=>this.hook(o,n[o]));return()=>{for(const o of r.splice(0,r.length))o()}}removeHooks(t){const n=Hs(t);for(const r in n)this.removeHook(r,n[r])}removeAllHooks(){for(const t in this._hooks)delete this._hooks[t]}callHook(t,...n){return n.unshift(t),this.callHookWith(P_,t,...n)}callHookParallel(t,...n){return n.unshift(t),this.callHookWith(I_,t,...n)}callHookWith(t,n,...r){const o=this._before||this._after?{name:n,args:r,context:{}}:void 0;this._before&&_s(this._before,o);const s=t(n in this._hooks?[...this._hooks[n]]:[],r);return s instanceof Promise?s.finally(()=>{this._after&&o&&_s(this._after,o)}):(this._after&&o&&_s(this._after,o),s)}beforeEach(t){return this._before=this._before||[],this._before.push(t),()=>{if(this._before!==void 0){const n=this._before.indexOf(t);n!==-1&&this._before.splice(n,1)}}}afterEach(t){return this._after=this._after||[],this._after.push(t),()=>{if(this._after!==void 0){const n=this._after.indexOf(t);n!==-1&&this._after.splice(n,1)}}}}function hf(){return new L_}var R_=Object.create,mf=Object.defineProperty,D_=Object.getOwnPropertyDescriptor,Ii=Object.getOwnPropertyNames,N_=Object.getPrototypeOf,V_=Object.prototype.hasOwnProperty,M_=(e,t)=>function(){return e&&(t=(0,e[Ii(e)[0]])(e=0)),t},gf=(e,t)=>function(){return t||(0,e[Ii(e)[0]])((t={exports:{}}).exports,t),t.exports},F_=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ii(t))!V_.call(e,o)&&o!==n&&mf(e,o,{get:()=>t[o],enumerable:!(r=D_(t,o))||r.enumerable});return e},B_=(e,t,n)=>(n=e!=null?R_(N_(e)):{},F_(mf(n,"default",{value:e,enumerable:!0}),e)),I=M_({"../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.43.0_@types+node@20.16.5__@swc+core@1.5.29_jiti@1.21.6__ldnw4a7r4ccknnz6q542psuydy/node_modules/tsup/assets/esm_shims.js"(){}}),H_=gf({"../../node_modules/.pnpm/speakingurl@14.0.1/node_modules/speakingurl/lib/speakingurl.js"(e,t){I(),function(n){var r={À:"A",Á:"A",Â:"A",Ã:"A",Ä:"Ae",Å:"A",Æ:"AE",Ç:"C",È:"E",É:"E",Ê:"E",Ë:"E",Ì:"I",Í:"I",Î:"I",Ï:"I",Ð:"D",Ñ:"N",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"Oe",Ő:"O",Ø:"O",Ù:"U",Ú:"U",Û:"U",Ü:"Ue",Ű:"U",Ý:"Y",Þ:"TH",ß:"ss",à:"a",á:"a",â:"a",ã:"a",ä:"ae",å:"a",æ:"ae",ç:"c",è:"e",é:"e",ê:"e",ë:"e",ì:"i",í:"i",î:"i",ï:"i",ð:"d",ñ:"n",ò:"o",ó:"o",ô:"o",õ:"o",ö:"oe",ő:"o",ø:"o",ù:"u",ú:"u",û:"u",ü:"ue",ű:"u",ý:"y",þ:"th",ÿ:"y","ẞ":"SS",ا:"a",أ:"a",إ:"i",آ:"aa",ؤ:"u",ئ:"e",ء:"a",ب:"b",ت:"t",ث:"th",ج:"j",ح:"h",خ:"kh",د:"d",ذ:"th",ر:"r",ز:"z",س:"s",ش:"sh",ص:"s",ض:"dh",ط:"t",ظ:"z",ع:"a",غ:"gh",ف:"f",ق:"q",ك:"k",ل:"l",م:"m",ن:"n",ه:"h",و:"w",ي:"y",ى:"a",ة:"h",ﻻ:"la",ﻷ:"laa",ﻹ:"lai",ﻵ:"laa",گ:"g",چ:"ch",پ:"p",ژ:"zh",ک:"k",ی:"y","َ":"a","ً":"an","ِ":"e","ٍ":"en","ُ":"u","ٌ":"on","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9",က:"k",ခ:"kh",ဂ:"g",ဃ:"ga",င:"ng",စ:"s",ဆ:"sa",ဇ:"z","စျ":"za",ည:"ny",ဋ:"t",ဌ:"ta",ဍ:"d",ဎ:"da",ဏ:"na",တ:"t",ထ:"ta",ဒ:"d",ဓ:"da",န:"n",ပ:"p",ဖ:"pa",ဗ:"b",ဘ:"ba",မ:"m",ယ:"y",ရ:"ya",လ:"l",ဝ:"w",သ:"th",ဟ:"h",ဠ:"la",အ:"a","ြ":"y","ျ":"ya","ွ":"w","ြွ":"yw","ျွ":"ywa","ှ":"h",ဧ:"e","၏":"-e",ဣ:"i",ဤ:"-i",ဉ:"u",ဦ:"-u",ဩ:"aw","သြော":"aw",ဪ:"aw","၀":"0","၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","္":"","့":"","း":"",č:"c",ď:"d",ě:"e",ň:"n",ř:"r",š:"s",ť:"t",ů:"u",ž:"z",Č:"C",Ď:"D",Ě:"E",Ň:"N",Ř:"R",Š:"S",Ť:"T",Ů:"U",Ž:"Z",ހ:"h",ށ:"sh",ނ:"n",ރ:"r",ބ:"b",ޅ:"lh",ކ:"k",އ:"a",ވ:"v",މ:"m",ފ:"f",ދ:"dh",ތ:"th",ލ:"l",ގ:"g",ޏ:"gn",ސ:"s",ޑ:"d",ޒ:"z",ޓ:"t",ޔ:"y",ޕ:"p",ޖ:"j",ޗ:"ch",ޘ:"tt",ޙ:"hh",ޚ:"kh",ޛ:"th",ޜ:"z",ޝ:"sh",ޞ:"s",ޟ:"d",ޠ:"t",ޡ:"z",ޢ:"a",ޣ:"gh",ޤ:"q",ޥ:"w","ަ":"a","ާ":"aa","ި":"i","ީ":"ee","ު":"u","ޫ":"oo","ެ":"e","ޭ":"ey","ޮ":"o","ޯ":"oa","ް":"",ა:"a",ბ:"b",გ:"g",დ:"d",ე:"e",ვ:"v",ზ:"z",თ:"t",ი:"i",კ:"k",ლ:"l",მ:"m",ნ:"n",ო:"o",პ:"p",ჟ:"zh",რ:"r",ს:"s",ტ:"t",უ:"u",ფ:"p",ქ:"k",ღ:"gh",ყ:"q",შ:"sh",ჩ:"ch",ც:"ts",ძ:"dz",წ:"ts",ჭ:"ch",ხ:"kh",ჯ:"j",ჰ:"h",α:"a",β:"v",γ:"g",δ:"d",ε:"e",ζ:"z",η:"i",θ:"th",ι:"i",κ:"k",λ:"l",μ:"m",ν:"n",ξ:"ks",ο:"o",π:"p",ρ:"r",σ:"s",τ:"t",υ:"y",φ:"f",χ:"x",ψ:"ps",ω:"o",ά:"a",έ:"e",ί:"i",ό:"o",ύ:"y",ή:"i",ώ:"o",ς:"s",ϊ:"i",ΰ:"y",ϋ:"y",ΐ:"i",Α:"A",Β:"B",Γ:"G",Δ:"D",Ε:"E",Ζ:"Z",Η:"I",Θ:"TH",Ι:"I",Κ:"K",Λ:"L",Μ:"M",Ν:"N",Ξ:"KS",Ο:"O",Π:"P",Ρ:"R",Σ:"S",Τ:"T",Υ:"Y",Φ:"F",Χ:"X",Ψ:"PS",Ω:"O",Ά:"A",Έ:"E",Ί:"I",Ό:"O",Ύ:"Y",Ή:"I",Ώ:"O",Ϊ:"I",Ϋ:"Y",ā:"a",ē:"e",ģ:"g",ī:"i",ķ:"k",ļ:"l",ņ:"n",ū:"u",Ā:"A",Ē:"E",Ģ:"G",Ī:"I",Ķ:"k",Ļ:"L",Ņ:"N",Ū:"U",Ќ:"Kj",ќ:"kj",Љ:"Lj",љ:"lj",Њ:"Nj",њ:"nj",Тс:"Ts",тс:"ts",ą:"a",ć:"c",ę:"e",ł:"l",ń:"n",ś:"s",ź:"z",ż:"z",Ą:"A",Ć:"C",Ę:"E",Ł:"L",Ń:"N",Ś:"S",Ź:"Z",Ż:"Z",Є:"Ye",І:"I",Ї:"Yi",Ґ:"G",є:"ye",і:"i",ї:"yi",ґ:"g",ă:"a",Ă:"A",ș:"s",Ș:"S",ț:"t",Ț:"T",ţ:"t",Ţ:"T",а:"a",б:"b",в:"v",г:"g",д:"d",е:"e",ё:"yo",ж:"zh",з:"z",и:"i",й:"i",к:"k",л:"l",м:"m",н:"n",о:"o",п:"p",р:"r",с:"s",т:"t",у:"u",ф:"f",х:"kh",ц:"c",ч:"ch",ш:"sh",щ:"sh",ъ:"",ы:"y",ь:"",э:"e",ю:"yu",я:"ya",А:"A",Б:"B",В:"V",Г:"G",Д:"D",Е:"E",Ё:"Yo",Ж:"Zh",З:"Z",И:"I",Й:"I",К:"K",Л:"L",М:"M",Н:"N",О:"O",П:"P",Р:"R",С:"S",Т:"T",У:"U",Ф:"F",Х:"Kh",Ц:"C",Ч:"Ch",Ш:"Sh",Щ:"Sh",Ъ:"",Ы:"Y",Ь:"",Э:"E",Ю:"Yu",Я:"Ya",ђ:"dj",ј:"j",ћ:"c",џ:"dz",Ђ:"Dj",Ј:"j",Ћ:"C",Џ:"Dz",ľ:"l",ĺ:"l",ŕ:"r",Ľ:"L",Ĺ:"L",Ŕ:"R",ş:"s",Ş:"S",ı:"i",İ:"I",ğ:"g",Ğ:"G",ả:"a",Ả:"A",ẳ:"a",Ẳ:"A",ẩ:"a",Ẩ:"A",đ:"d",Đ:"D",ẹ:"e",Ẹ:"E",ẽ:"e",Ẽ:"E",ẻ:"e",Ẻ:"E",ế:"e",Ế:"E",ề:"e",Ề:"E",ệ:"e",Ệ:"E",ễ:"e",Ễ:"E",ể:"e",Ể:"E",ỏ:"o",ọ:"o",Ọ:"o",ố:"o",Ố:"O",ồ:"o",Ồ:"O",ổ:"o",Ổ:"O",ộ:"o",Ộ:"O",ỗ:"o",Ỗ:"O",ơ:"o",Ơ:"O",ớ:"o",Ớ:"O",ờ:"o",Ờ:"O",ợ:"o",Ợ:"O",ỡ:"o",Ỡ:"O",Ở:"o",ở:"o",ị:"i",Ị:"I",ĩ:"i",Ĩ:"I",ỉ:"i",Ỉ:"i",ủ:"u",Ủ:"U",ụ:"u",Ụ:"U",ũ:"u",Ũ:"U",ư:"u",Ư:"U",ứ:"u",Ứ:"U",ừ:"u",Ừ:"U",ự:"u",Ự:"U",ữ:"u",Ữ:"U",ử:"u",Ử:"ư",ỷ:"y",Ỷ:"y",ỳ:"y",Ỳ:"Y",ỵ:"y",Ỵ:"Y",ỹ:"y",Ỹ:"Y",ạ:"a",Ạ:"A",ấ:"a",Ấ:"A",ầ:"a",Ầ:"A",ậ:"a",Ậ:"A",ẫ:"a",Ẫ:"A",ắ:"a",Ắ:"A",ằ:"a",Ằ:"A",ặ:"a",Ặ:"A",ẵ:"a",Ẵ:"A","⓪":"0","①":"1","②":"2","③":"3","④":"4","⑤":"5","⑥":"6","⑦":"7","⑧":"8","⑨":"9","⑩":"10","⑪":"11","⑫":"12","⑬":"13","⑭":"14","⑮":"15","⑯":"16","⑰":"17","⑱":"18","⑲":"18","⑳":"18","⓵":"1","⓶":"2","⓷":"3","⓸":"4","⓹":"5","⓺":"6","⓻":"7","⓼":"8","⓽":"9","⓾":"10","⓿":"0","⓫":"11","⓬":"12","⓭":"13","⓮":"14","⓯":"15","⓰":"16","⓱":"17","⓲":"18","⓳":"19","⓴":"20","Ⓐ":"A","Ⓑ":"B","Ⓒ":"C","Ⓓ":"D","Ⓔ":"E","Ⓕ":"F","Ⓖ":"G","Ⓗ":"H","Ⓘ":"I","Ⓙ":"J","Ⓚ":"K","Ⓛ":"L","Ⓜ":"M","Ⓝ":"N","Ⓞ":"O","Ⓟ":"P","Ⓠ":"Q","Ⓡ":"R","Ⓢ":"S","Ⓣ":"T","Ⓤ":"U","Ⓥ":"V","Ⓦ":"W","Ⓧ":"X","Ⓨ":"Y","Ⓩ":"Z","ⓐ":"a","ⓑ":"b","ⓒ":"c","ⓓ":"d","ⓔ":"e","ⓕ":"f","ⓖ":"g","ⓗ":"h","ⓘ":"i","ⓙ":"j","ⓚ":"k","ⓛ":"l","ⓜ":"m","ⓝ":"n","ⓞ":"o","ⓟ":"p","ⓠ":"q","ⓡ":"r","ⓢ":"s","ⓣ":"t","ⓤ":"u","ⓦ":"v","ⓥ":"w","ⓧ":"x","ⓨ":"y","ⓩ":"z","“":'"',"”":'"',"‘":"'","’":"'","∂":"d",ƒ:"f","™":"(TM)","©":"(C)",œ:"oe",Œ:"OE","®":"(R)","†":"+","℠":"(SM)","…":"...","˚":"o",º:"o",ª:"a","•":"*","၊":",","။":".",$:"USD","€":"EUR","₢":"BRN","₣":"FRF","£":"GBP","₤":"ITL","₦":"NGN","₧":"ESP","₩":"KRW","₪":"ILS","₫":"VND","₭":"LAK","₮":"MNT","₯":"GRD","₱":"ARS","₲":"PYG","₳":"ARA","₴":"UAH","₵":"GHS","¢":"cent","¥":"CNY",元:"CNY",円:"YEN","﷼":"IRR","₠":"EWE","฿":"THB","₨":"INR","₹":"INR","₰":"PF","₺":"TRY","؋":"AFN","₼":"AZN",лв:"BGN","៛":"KHR","₡":"CRC","₸":"KZT",ден:"MKD",zł:"PLN","₽":"RUB","₾":"GEL"},o=["်","ް"],s={"ာ":"a","ါ":"a","ေ":"e","ဲ":"e","ိ":"i","ီ":"i","ို":"o","ု":"u","ူ":"u","ေါင်":"aung","ော":"aw","ော်":"aw","ေါ":"aw","ေါ်":"aw","်":"်","က်":"et","ိုက်":"aik","ောက်":"auk","င်":"in","ိုင်":"aing","ောင်":"aung","စ်":"it","ည်":"i","တ်":"at","ိတ်":"eik","ုတ်":"ok","ွတ်":"ut","ေတ်":"it","ဒ်":"d","ိုဒ်":"ok","ုဒ်":"ait","န်":"an","ာန်":"an","ိန်":"ein","ုန်":"on","ွန်":"un","ပ်":"at","ိပ်":"eik","ုပ်":"ok","ွပ်":"ut","န်ုပ်":"nub","မ်":"an","ိမ်":"ein","ုမ်":"on","ွမ်":"un","ယ်":"e","ိုလ်":"ol","ဉ်":"in","ံ":"an","ိံ":"ein","ုံ":"on","ައް":"ah","ަށް":"ah"},i={en:{},az:{ç:"c",ə:"e",ğ:"g",ı:"i",ö:"o",ş:"s",ü:"u",Ç:"C",Ə:"E",Ğ:"G",İ:"I",Ö:"O",Ş:"S",Ü:"U"},cs:{č:"c",ď:"d",ě:"e",ň:"n",ř:"r",š:"s",ť:"t",ů:"u",ž:"z",Č:"C",Ď:"D",Ě:"E",Ň:"N",Ř:"R",Š:"S",Ť:"T",Ů:"U",Ž:"Z"},fi:{ä:"a",Ä:"A",ö:"o",Ö:"O"},hu:{ä:"a",Ä:"A",ö:"o",Ö:"O",ü:"u",Ü:"U",ű:"u",Ű:"U"},lt:{ą:"a",č:"c",ę:"e",ė:"e",į:"i",š:"s",ų:"u",ū:"u",ž:"z",Ą:"A",Č:"C",Ę:"E",Ė:"E",Į:"I",Š:"S",Ų:"U",Ū:"U"},lv:{ā:"a",č:"c",ē:"e",ģ:"g",ī:"i",ķ:"k",ļ:"l",ņ:"n",š:"s",ū:"u",ž:"z",Ā:"A",Č:"C",Ē:"E",Ģ:"G",Ī:"i",Ķ:"k",Ļ:"L",Ņ:"N",Š:"S",Ū:"u",Ž:"Z"},pl:{ą:"a",ć:"c",ę:"e",ł:"l",ń:"n",ó:"o",ś:"s",ź:"z",ż:"z",Ą:"A",Ć:"C",Ę:"e",Ł:"L",Ń:"N",Ó:"O",Ś:"S",Ź:"Z",Ż:"Z"},sv:{ä:"a",Ä:"A",ö:"o",Ö:"O"},sk:{ä:"a",Ä:"A"},sr:{љ:"lj",њ:"nj",Љ:"Lj",Њ:"Nj",đ:"dj",Đ:"Dj"},tr:{Ü:"U",Ö:"O",ü:"u",ö:"o"}},l={ar:{"∆":"delta","∞":"la-nihaya","♥":"hob","&":"wa","|":"aw","<":"aqal-men",">":"akbar-men","∑":"majmou","¤":"omla"},az:{},ca:{"∆":"delta","∞":"infinit","♥":"amor","&":"i","|":"o","<":"menys que",">":"mes que","∑":"suma dels","¤":"moneda"},cs:{"∆":"delta","∞":"nekonecno","♥":"laska","&":"a","|":"nebo","<":"mensi nez",">":"vetsi nez","∑":"soucet","¤":"mena"},de:{"∆":"delta","∞":"unendlich","♥":"Liebe","&":"und","|":"oder","<":"kleiner als",">":"groesser als","∑":"Summe von","¤":"Waehrung"},dv:{"∆":"delta","∞":"kolunulaa","♥":"loabi","&":"aai","|":"noonee","<":"ah vure kuda",">":"ah vure bodu","∑":"jumula","¤":"faisaa"},en:{"∆":"delta","∞":"infinity","♥":"love","&":"and","|":"or","<":"less than",">":"greater than","∑":"sum","¤":"currency"},es:{"∆":"delta","∞":"infinito","♥":"amor","&":"y","|":"u","<":"menos que",">":"mas que","∑":"suma de los","¤":"moneda"},fa:{"∆":"delta","∞":"bi-nahayat","♥":"eshgh","&":"va","|":"ya","<":"kamtar-az",">":"bishtar-az","∑":"majmooe","¤":"vahed"},fi:{"∆":"delta","∞":"aarettomyys","♥":"rakkaus","&":"ja","|":"tai","<":"pienempi kuin",">":"suurempi kuin","∑":"summa","¤":"valuutta"},fr:{"∆":"delta","∞":"infiniment","♥":"Amour","&":"et","|":"ou","<":"moins que",">":"superieure a","∑":"somme des","¤":"monnaie"},ge:{"∆":"delta","∞":"usasruloba","♥":"siqvaruli","&":"da","|":"an","<":"naklebi",">":"meti","∑":"jami","¤":"valuta"},gr:{},hu:{"∆":"delta","∞":"vegtelen","♥":"szerelem","&":"es","|":"vagy","<":"kisebb mint",">":"nagyobb mint","∑":"szumma","¤":"penznem"},it:{"∆":"delta","∞":"infinito","♥":"amore","&":"e","|":"o","<":"minore di",">":"maggiore di","∑":"somma","¤":"moneta"},lt:{"∆":"delta","∞":"begalybe","♥":"meile","&":"ir","|":"ar","<":"maziau nei",">":"daugiau nei","∑":"suma","¤":"valiuta"},lv:{"∆":"delta","∞":"bezgaliba","♥":"milestiba","&":"un","|":"vai","<":"mazak neka",">":"lielaks neka","∑":"summa","¤":"valuta"},my:{"∆":"kwahkhyaet","∞":"asaonasme","♥":"akhyait","&":"nhin","|":"tho","<":"ngethaw",">":"kyithaw","∑":"paungld","¤":"ngwekye"},mk:{},nl:{"∆":"delta","∞":"oneindig","♥":"liefde","&":"en","|":"of","<":"kleiner dan",">":"groter dan","∑":"som","¤":"valuta"},pl:{"∆":"delta","∞":"nieskonczonosc","♥":"milosc","&":"i","|":"lub","<":"mniejsze niz",">":"wieksze niz","∑":"suma","¤":"waluta"},pt:{"∆":"delta","∞":"infinito","♥":"amor","&":"e","|":"ou","<":"menor que",">":"maior que","∑":"soma","¤":"moeda"},ro:{"∆":"delta","∞":"infinit","♥":"dragoste","&":"si","|":"sau","<":"mai mic ca",">":"mai mare ca","∑":"suma","¤":"valuta"},ru:{"∆":"delta","∞":"beskonechno","♥":"lubov","&":"i","|":"ili","<":"menshe",">":"bolshe","∑":"summa","¤":"valjuta"},sk:{"∆":"delta","∞":"nekonecno","♥":"laska","&":"a","|":"alebo","<":"menej ako",">":"viac ako","∑":"sucet","¤":"mena"},sr:{},tr:{"∆":"delta","∞":"sonsuzluk","♥":"ask","&":"ve","|":"veya","<":"kucuktur",">":"buyuktur","∑":"toplam","¤":"para birimi"},uk:{"∆":"delta","∞":"bezkinechnist","♥":"lubov","&":"i","|":"abo","<":"menshe",">":"bilshe","∑":"suma","¤":"valjuta"},vn:{"∆":"delta","∞":"vo cuc","♥":"yeu","&":"va","|":"hoac","<":"nho hon",">":"lon hon","∑":"tong","¤":"tien te"}},a=[";","?",":","@","&","=","+","$",",","/"].join(""),u=[";","?",":","@","&","=","+","$",","].join(""),f=[".","!","~","*","'","(",")"].join(""),c=function(y,E){var S="-",h="",b="",R=!0,j={},M,w,U,x,H,A,D,J,ee,P,N,K,ue,ye,Te="";if(typeof y!="string")return"";if(typeof E=="string"&&(S=E),D=l.en,J=i.en,typeof E=="object"){M=E.maintainCase||!1,j=E.custom&&typeof E.custom=="object"?E.custom:j,U=+E.truncate>1&&E.truncate||!1,x=E.uric||!1,H=E.uricNoSlash||!1,A=E.mark||!1,R=!(E.symbols===!1||E.lang===!1),S=E.separator||S,x&&(Te+=a),H&&(Te+=u),A&&(Te+=f),D=E.lang&&l[E.lang]&&R?l[E.lang]:R?l.en:{},J=E.lang&&i[E.lang]?i[E.lang]:E.lang===!1||E.lang===!0?{}:i.en,E.titleCase&&typeof E.titleCase.length=="number"&&Array.prototype.toString.call(E.titleCase)?(E.titleCase.forEach(function(be){j[be+""]=be+""}),w=!0):w=!!E.titleCase,E.custom&&typeof E.custom.length=="number"&&Array.prototype.toString.call(E.custom)&&E.custom.forEach(function(be){j[be+""]=be+""}),Object.keys(j).forEach(function(be){var Ze;be.length>1?Ze=new RegExp("\\b"+p(be)+"\\b","gi"):Ze=new RegExp(p(be),"gi"),y=y.replace(Ze,j[be])});for(N in j)Te+=N}for(Te+=S,Te=p(Te),y=y.replace(/(^\s+|\s+$)/g,""),ue=!1,ye=!1,P=0,K=y.length;P=0?(b+=N,N=""):ye===!0?(N=s[b]+r[N],b=""):N=ue&&r[N].match(/[A-Za-z0-9]/)?" "+r[N]:r[N],ue=!1,ye=!1):N in s?(b+=N,N="",P===K-1&&(N=s[b]),ye=!0):D[N]&&!(x&&a.indexOf(N)!==-1)&&!(H&&u.indexOf(N)!==-1)?(N=ue||h.substr(-1).match(/[A-Za-z0-9]/)?S+D[N]:D[N],N+=y[P+1]!==void 0&&y[P+1].match(/[A-Za-z0-9]/)?S:"",ue=!0):(ye===!0?(N=s[b]+N,b="",ye=!1):ue&&(/[A-Za-z0-9]/.test(N)||h.substr(-1).match(/A-Za-z0-9]/))&&(N=" "+N),ue=!1),h+=N.replace(new RegExp("[^\\w\\s"+Te+"_-]","g"),S);return w&&(h=h.replace(/(\w)(\S*)/g,function(be,Ze,gt){var Qe=Ze.toUpperCase()+(gt!==null?gt:"");return Object.keys(j).indexOf(Qe.toLowerCase())<0?Qe:Qe.toLowerCase()})),h=h.replace(/\s+/g,S).replace(new RegExp("\\"+S+"+","g"),S).replace(new RegExp("(^\\"+S+"+|\\"+S+"+$)","g"),""),U&&h.length>U&&(ee=h.charAt(U)===S,h=h.slice(0,U),ee||(h=h.slice(0,h.lastIndexOf(S)))),!M&&!w&&(h=h.toLowerCase()),h},d=function(y){return function(S){return c(S,y)}},p=function(y){return y.replace(/[-\\^$*+?.()|[\]{}\/]/g,"\\$&")},v=function(_,y){for(var E in y)if(y[E]===_)return!0};if(typeof t<"u"&&t.exports)t.exports=c,t.exports.createSlug=d;else if(typeof define<"u"&&define.amd)define([],function(){return c});else try{if(n.getSlug||n.createSlug)throw"speakingurl: globals exists /(getSlug|createSlug)/";n.getSlug=c,n.createSlug=d}catch{}}(e)}}),$_=gf({"../../node_modules/.pnpm/speakingurl@14.0.1/node_modules/speakingurl/index.js"(e,t){I(),t.exports=H_()}});I();I();I();I();I();I();I();function U_(e){return!!(e&&e.__v_isReadonly)}function vf(e){return U_(e)?vf(e.__v_raw):!!(e&&e.__v_isReactive)}function ys(e){return!!(e&&e.__v_isRef===!0)}function hr(e){const t=e&&e.__v_raw;return t?hr(t):e}var j_=Symbol.for("v-fgt");I();function z_(e){return e.name||e._componentTag||e.__VUE_DEVTOOLS_COMPONENT_GUSSED_NAME__||e.__name}function K_(e){const t=e.__file;if(t)return w_(A_(t,".vue"))}function la(e,t){return e.type.__VUE_DEVTOOLS_COMPONENT_GUSSED_NAME__=t,t}function Li(e){if(e.__VUE_DEVTOOLS_NEXT_APP_RECORD__)return e.__VUE_DEVTOOLS_NEXT_APP_RECORD__;if(e.root)return e.appContext.app.__VUE_DEVTOOLS_NEXT_APP_RECORD__}async function W_(e){const{app:t,uid:n,instance:r}=e;try{if(r.__VUE_DEVTOOLS_NEXT_UID__)return r.__VUE_DEVTOOLS_NEXT_UID__;const o=await Li(t);if(!o)return null;const s=o.rootInstance===r;return`${o.id}:${s?"root":n}`}catch{}}function _f(e){var t;return((t=e.subTree)==null?void 0:t.type)===j_}function Go(e){var t,n,r;const o=z_((e==null?void 0:e.type)||{});if(o)return o;if((e==null?void 0:e.root)===e)return"Root";for(const i in(n=(t=e.parent)==null?void 0:t.type)==null?void 0:n.components)if(e.parent.type.components[i]===(e==null?void 0:e.type))return la(e,i);for(const i in(r=e.appContext)==null?void 0:r.components)if(e.appContext.components[i]===(e==null?void 0:e.type))return la(e,i);const s=K_((e==null?void 0:e.type)||{});return s||"Anonymous Component"}function $s(e,t){return t=t||`${e.id}:root`,e.instanceMap.get(t)||e.instanceMap.get(":root")}var q_=class{constructor(){this.refEditor=new G_}set(e,t,n,r){const o=Array.isArray(t)?t:t.split(".");for(;o.length>1;){const l=o.shift();e instanceof Map&&(e=e.get(l)),e instanceof Set?e=Array.from(e.values())[l]:e=e[l],this.refEditor.isRef(e)&&(e=this.refEditor.get(e))}const s=o[0],i=this.refEditor.get(e)[s];r?r(e,s,n):this.refEditor.isRef(i)?this.refEditor.set(i,n):e[s]=n}get(e,t){const n=Array.isArray(t)?t:t.split(".");for(let r=0;r"u")return!1;const r=Array.isArray(t)?t.slice():t.split("."),o=n?2:1;for(;e&&r.length>o;){const s=r.shift();e=e[s],this.refEditor.isRef(e)&&(e=this.refEditor.get(e))}return e!=null&&Object.prototype.hasOwnProperty.call(e,r[0])}createDefaultSetCallback(e){return(t,n,r)=>{if((e.remove||e.newKey)&&(Array.isArray(t)?t.splice(n,1):hr(t)instanceof Map?t.delete(n):hr(t)instanceof Set?t.delete(Array.from(t.values())[n]):Reflect.deleteProperty(t,n)),!e.remove){const o=t[e.newKey||n];this.refEditor.isRef(o)?this.refEditor.set(o,r):hr(t)instanceof Map?t.set(e.newKey||n,r):hr(t)instanceof Set?t.add(r):t[e.newKey||n]=r}}}},G_=class{set(e,t){if(ys(e))e.value=t;else{if(e instanceof Set&&Array.isArray(t)){e.clear(),t.forEach(o=>e.add(o));return}const n=Object.keys(t);if(e instanceof Map){const o=new Set(e.keys());n.forEach(s=>{e.set(s,Reflect.get(t,s)),o.delete(s)}),o.forEach(s=>e.delete(s));return}const r=new Set(Object.keys(e));n.forEach(o=>{Reflect.set(e,o,Reflect.get(t,o)),r.delete(o)}),r.forEach(o=>Reflect.deleteProperty(e,o))}}get(e){return ys(e)?e.value:e}isRef(e){return ys(e)||vf(e)}};I();function Ri(e){return _f(e)?Y_(e.subTree):e.subTree?[e.subTree.el]:[]}function Y_(e){if(!e.children)return[];const t=[];return e.children.forEach(n=>{n.component?t.push(...Ri(n.component)):n!=null&&n.el&&t.push(n.el)}),t}I();I();function X_(){const e={top:0,bottom:0,left:0,right:0,get width(){return e.right-e.left},get height(){return e.bottom-e.top}};return e}var io;function J_(e){return io||(io=document.createRange()),io.selectNode(e),io.getBoundingClientRect()}function Z_(e){const t=X_();if(!e.children)return t;for(let n=0,r=e.children.length;ne.bottom)&&(e.bottom=t.bottom),(!e.left||t.lefte.right)&&(e.right=t.right),e}var aa={top:0,left:0,right:0,bottom:0,width:0,height:0};function xn(e){const t=e.subTree.el;return typeof window>"u"?aa:_f(e)?Z_(e.subTree):(t==null?void 0:t.nodeType)===1?t==null?void 0:t.getBoundingClientRect():e.subTree.component?xn(e.subTree.component):aa}var yf="__vue-devtools-component-inspector__",bf="__vue-devtools-component-inspector__card__",Ef="__vue-devtools-component-inspector__name__",kf="__vue-devtools-component-inspector__indicator__",Sf={display:"block",zIndex:2147483640,position:"fixed",backgroundColor:"#42b88325",border:"1px solid #42b88350",borderRadius:"5px",transition:"all 0.1s ease-in",pointerEvents:"none"},e0={fontFamily:"Arial, Helvetica, sans-serif",padding:"5px 8px",borderRadius:"4px",textAlign:"left",position:"absolute",left:0,color:"#e9e9e9",fontSize:"14px",fontWeight:600,lineHeight:"24px",backgroundColor:"#42b883",boxShadow:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)"},t0={display:"inline-block",fontWeight:400,fontStyle:"normal",fontSize:"12px",opacity:.7};function nr(){return document.getElementById(yf)}function n0(){return document.getElementById(bf)}function r0(){return document.getElementById(kf)}function o0(){return document.getElementById(Ef)}function Di(e){return{left:`${Math.round(e.left*100)/100}px`,top:`${Math.round(e.top*100)/100}px`,width:`${Math.round(e.width*100)/100}px`,height:`${Math.round(e.height*100)/100}px`}}function Ni(e){var t;const n=document.createElement("div");n.id=(t=e.elementId)!=null?t:yf,Object.assign(n.style,{...Sf,...Di(e.bounds),...e.style});const r=document.createElement("span");r.id=bf,Object.assign(r.style,{...e0,top:e.bounds.top<35?0:"-35px"});const o=document.createElement("span");o.id=Ef,o.innerHTML=`<${e.name}>  `;const s=document.createElement("i");return s.id=kf,s.innerHTML=`${Math.round(e.bounds.width*100)/100} x ${Math.round(e.bounds.height*100)/100}`,Object.assign(s.style,t0),r.appendChild(o),r.appendChild(s),n.appendChild(r),document.body.appendChild(n),n}function Vi(e){const t=nr(),n=n0(),r=o0(),o=r0();t&&(Object.assign(t.style,{...Sf,...Di(e.bounds)}),Object.assign(n.style,{top:e.bounds.top<35?0:"-35px"}),r.innerHTML=`<${e.name}>  `,o.innerHTML=`${Math.round(e.bounds.width*100)/100} x ${Math.round(e.bounds.height*100)/100}`)}function s0(e){const t=xn(e),n=Go(e);nr()?Vi({bounds:t,name:n}):Ni({bounds:t,name:n})}function wf(){const e=nr();e&&(e.style.display="none")}var Us=null;function js(e){const t=e.target;if(t){const n=t.__vueParentComponent;if(n&&(Us=n,n.vnode.el)){const o=xn(n),s=Go(n);nr()?Vi({bounds:o,name:s}):Ni({bounds:o,name:s})}}}function i0(e,t){var n;if(e.preventDefault(),e.stopPropagation(),Us){const r=(n=tt.value)==null?void 0:n.app;W_({app:r,uid:r.uid,instance:Us}).then(o=>{t(o)})}}var Co=null;function l0(){wf(),window.removeEventListener("mouseover",js),window.removeEventListener("click",Co,!0),Co=null}function a0(){return window.addEventListener("mouseover",js),new Promise(e=>{function t(n){n.preventDefault(),n.stopPropagation(),i0(n,r=>{window.removeEventListener("click",t,!0),Co=null,window.removeEventListener("mouseover",js);const o=nr();o&&(o.style.display="none"),e(JSON.stringify({id:r}))})}Co=t,window.addEventListener("click",t,!0)})}function u0(e){const t=$s(tt.value,e.id);if(t){const[n]=Ri(t);if(typeof n.scrollIntoView=="function")n.scrollIntoView({behavior:"smooth"});else{const r=xn(t),o=document.createElement("div"),s={...Di(r),position:"absolute"};Object.assign(o.style,s),document.body.appendChild(o),o.scrollIntoView({behavior:"smooth"}),setTimeout(()=>{document.body.removeChild(o)},2e3)}setTimeout(()=>{const r=xn(t);if(r.width||r.height){const o=Go(t),s=nr();s?Vi({...e,name:o,bounds:r}):Ni({...e,name:o,bounds:r}),setTimeout(()=>{s&&(s.style.display="none")},1500)}},1200)}}I();var ua,ca;(ca=(ua=X).__VUE_DEVTOOLS_COMPONENT_INSPECTOR_ENABLED__)!=null||(ua.__VUE_DEVTOOLS_COMPONENT_INSPECTOR_ENABLED__=!0);function c0(e){let t=0;const n=setInterval(()=>{X.__VUE_INSPECTOR__&&(clearInterval(n),t+=30,e()),t>=5e3&&clearInterval(n)},30)}function f0(){const e=X.__VUE_INSPECTOR__,t=e.openInEditor;e.openInEditor=async(...n)=>{e.disable(),t(...n)}}function d0(){return new Promise(e=>{function t(){f0(),e(X.__VUE_INSPECTOR__)}X.__VUE_INSPECTOR__?t():c0(()=>{t()})})}I();I();I();I();I();var fa,da;(da=(fa=X).__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS)!=null||(fa.__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS=[]);var p0=new Proxy(X.__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS,{get(e,t,n){return Reflect.get(e,t,n)}});function h0(e,t){p0.push({...e,descriptorId:t.id,appRecord:Li(t.app)})}var pa,ha;(ha=(pa=X).__VUE_DEVTOOLS_KIT_INSPECTOR__)!=null||(pa.__VUE_DEVTOOLS_KIT_INSPECTOR__=[]);var Mi=new Proxy(X.__VUE_DEVTOOLS_KIT_INSPECTOR__,{get(e,t,n){return Reflect.get(e,t,n)}}),Af=qo(()=>{rr.hooks.callHook("sendInspectorToClient",Cf())});function m0(e,t){Mi.push({options:e,descriptor:t,treeFilter:"",selectedNodeId:"",appRecord:Li(t.app)}),Af()}function Cf(){return Mi.filter(e=>e.descriptor.app===tt.value.app).filter(e=>e.descriptor.id!=="components").map(e=>{var t;const n=e.descriptor,r=e.options;return{id:r.id,label:r.label,logo:n.logo,icon:`custom-ic-baseline-${(t=r==null?void 0:r.icon)==null?void 0:t.replace(/_/g,"-")}`,packageName:n.packageName,homepage:n.homepage,pluginId:n.id}})}function fo(e,t){return Mi.find(n=>n.options.id===e&&(t?n.descriptor.app===t:!0))}function g0(){const e=hf();return e.hook("addInspector",({inspector:t,plugin:n})=>{m0(t,n.descriptor)}),e.hook("sendInspectorTree",async({inspectorId:t,plugin:n})=>{var r;if(!t||!((r=n==null?void 0:n.descriptor)!=null&&r.app))return;const o=fo(t,n.descriptor.app),s={app:n.descriptor.app,inspectorId:t,filter:(o==null?void 0:o.treeFilter)||"",rootNodes:[]};await new Promise(i=>{e.callHookWith(async l=>{await Promise.all(l.map(a=>a(s))),i()},"getInspectorTree")}),e.callHookWith(async i=>{await Promise.all(i.map(l=>l({inspectorId:t,rootNodes:s.rootNodes})))},"sendInspectorTreeToClient")}),e.hook("sendInspectorState",async({inspectorId:t,plugin:n})=>{var r;if(!t||!((r=n==null?void 0:n.descriptor)!=null&&r.app))return;const o=fo(t,n.descriptor.app),s={app:n.descriptor.app,inspectorId:t,nodeId:(o==null?void 0:o.selectedNodeId)||"",state:null},i={currentTab:`custom-inspector:${t}`};s.nodeId&&await new Promise(l=>{e.callHookWith(async a=>{await Promise.all(a.map(u=>u(s,i))),l()},"getInspectorState")}),e.callHookWith(async l=>{await Promise.all(l.map(a=>a({inspectorId:t,nodeId:s.nodeId,state:s.state})))},"sendInspectorStateToClient")}),e.hook("customInspectorSelectNode",({inspectorId:t,nodeId:n,plugin:r})=>{const o=fo(t,r.descriptor.app);o&&(o.selectedNodeId=n)}),e.hook("timelineLayerAdded",({options:t,plugin:n})=>{h0(t,n.descriptor)}),e.hook("timelineEventAdded",({options:t,plugin:n})=>{e.callHookWith(async r=>{await Promise.all(r.map(o=>o(t)))},"sendTimelineEventToClient")}),e.hook("getComponentInstances",async({app:t})=>{const n=t.__VUE_DEVTOOLS_NEXT_APP_RECORD__;if(!n)return null;const r=n.id.toString();return[...n.instanceMap].filter(([s])=>s.split(":")[0]===r).map(([,s])=>s)}),e.hook("getComponentBounds",async({instance:t})=>xn(t)),e.hook("getComponentName",({instance:t})=>Go(t)),e.hook("componentHighlight",({uid:t})=>{const n=tt.value.instanceMap.get(t);n&&s0(n)}),e.hook("componentUnhighlight",()=>{wf()}),e}var ma,ga;(ga=(ma=X).__VUE_DEVTOOLS_KIT_APP_RECORDS__)!=null||(ma.__VUE_DEVTOOLS_KIT_APP_RECORDS__=[]);var va,_a;(_a=(va=X).__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__)!=null||(va.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__={});var ya,ba;(ba=(ya=X).__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__)!=null||(ya.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__="");var Ea,ka;(ka=(Ea=X).__VUE_DEVTOOLS_KIT_CUSTOM_TABS__)!=null||(Ea.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__=[]);var Sa,wa;(wa=(Sa=X).__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__)!=null||(Sa.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__=[]);var kn="__VUE_DEVTOOLS_KIT_GLOBAL_STATE__";function v0(){return{connected:!1,clientConnected:!1,vitePluginDetected:!0,appRecords:[],activeAppRecordId:"",tabs:[],commands:[],highPerfModeEnabled:!0,devtoolsClientDetected:{}}}var Aa,Ca;(Ca=(Aa=X)[kn])!=null||(Aa[kn]=v0());var _0=qo(e=>{rr.hooks.callHook("devtoolsStateUpdated",{state:e})});qo((e,t)=>{rr.hooks.callHook("devtoolsConnectedUpdated",{state:e,oldState:t})});var Yo=new Proxy(X.__VUE_DEVTOOLS_KIT_APP_RECORDS__,{get(e,t,n){return t==="value"?X.__VUE_DEVTOOLS_KIT_APP_RECORDS__:X.__VUE_DEVTOOLS_KIT_APP_RECORDS__[t]}}),tt=new Proxy(X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__,{get(e,t,n){return t==="value"?X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__:t==="id"?X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__:X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__[t]}});function xf(){_0({...X[kn],appRecords:Yo.value,activeAppRecordId:tt.id,tabs:X.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__,commands:X.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__})}function y0(e){X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__=e,xf()}function b0(e){X.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__=e,xf()}var An=new Proxy(X[kn],{get(e,t){return t==="appRecords"?Yo:t==="activeAppRecordId"?tt.id:t==="tabs"?X.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__:t==="commands"?X.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__:X[kn][t]},deleteProperty(e,t){return delete e[t],!0},set(e,t,n){return{...X[kn]},e[t]=n,X[kn][t]=n,!0}});function E0(e={}){var t,n,r;const{file:o,host:s,baseUrl:i=window.location.origin,line:l=0,column:a=0}=e;if(o){if(s==="chrome-extension"){const u=o.replace(/\\/g,"\\\\"),f=(n=(t=window.VUE_DEVTOOLS_CONFIG)==null?void 0:t.openInEditorHost)!=null?n:"/";fetch(`${f}__open-in-editor?file=${encodeURI(o)}`).then(c=>{if(!c.ok){const d=`Opening component ${u} failed`;console.log(`%c${d}`,"color:red")}})}else if(An.vitePluginDetected){const u=(r=X.__VUE_DEVTOOLS_OPEN_IN_EDITOR_BASE_URL__)!=null?r:i;X.__VUE_INSPECTOR__.openInEditor(u,o,l,a)}}}I();I();I();I();I();var xa,Ta;(Ta=(xa=X).__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__)!=null||(xa.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__=[]);var Fi=new Proxy(X.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__,{get(e,t,n){return Reflect.get(e,t,n)}});function zs(e){const t={};return Object.keys(e).forEach(n=>{t[n]=e[n].defaultValue}),t}function Bi(e){return`__VUE_DEVTOOLS_NEXT_PLUGIN_SETTINGS__${e}__`}function k0(e){var t,n,r;const o=(n=(t=Fi.find(s=>{var i;return s[0].id===e&&!!((i=s[0])!=null&&i.settings)}))==null?void 0:t[0])!=null?n:null;return(r=o==null?void 0:o.settings)!=null?r:null}function Tf(e,t){var n,r,o;const s=Bi(e);if(s){const i=localStorage.getItem(s);if(i)return JSON.parse(i)}if(e){const i=(r=(n=Fi.find(l=>l[0].id===e))==null?void 0:n[0])!=null?r:null;return zs((o=i==null?void 0:i.settings)!=null?o:{})}return zs(t)}function S0(e,t){const n=Bi(e);localStorage.getItem(n)||localStorage.setItem(n,JSON.stringify(zs(t)))}function w0(e,t,n){const r=Bi(e),o=localStorage.getItem(r),s=JSON.parse(o||"{}"),i={...s,[t]:n};localStorage.setItem(r,JSON.stringify(i)),rr.hooks.callHookWith(l=>{l.forEach(a=>a({pluginId:e,key:t,oldValue:s[t],newValue:n,settings:i}))},"setPluginSettings")}I();I();I();I();I();I();I();I();I();I();I();var Oa,Pa,Ct=(Pa=(Oa=X).__VUE_DEVTOOLS_HOOK)!=null?Pa:Oa.__VUE_DEVTOOLS_HOOK=hf(),A0={vueAppInit(e){Ct.hook("app:init",e)},vueAppUnmount(e){Ct.hook("app:unmount",e)},vueAppConnected(e){Ct.hook("app:connected",e)},componentAdded(e){return Ct.hook("component:added",e)},componentUpdated(e){return Ct.hook("component:updated",e)},componentRemoved(e){return Ct.hook("component:removed",e)},setupDevtoolsPlugin(e){Ct.hook("devtools-plugin:setup",e)}},Of={on:A0,setupDevToolsPlugin(e,t){return Ct.callHook("devtools-plugin:setup",e,t)}},C0=class{constructor({plugin:e,ctx:t}){this.hooks=t.hooks,this.plugin=e}get on(){return{visitComponentTree:e=>{this.hooks.hook("visitComponentTree",e)},inspectComponent:e=>{this.hooks.hook("inspectComponent",e)},editComponentState:e=>{this.hooks.hook("editComponentState",e)},getInspectorTree:e=>{this.hooks.hook("getInspectorTree",e)},getInspectorState:e=>{this.hooks.hook("getInspectorState",e)},editInspectorState:e=>{this.hooks.hook("editInspectorState",e)},inspectTimelineEvent:e=>{this.hooks.hook("inspectTimelineEvent",e)},timelineCleared:e=>{this.hooks.hook("timelineCleared",e)},setPluginSettings:e=>{this.hooks.hook("setPluginSettings",e)}}}notifyComponentUpdate(e){var t;const n=Cf().find(r=>r.packageName===this.plugin.descriptor.packageName);if(n!=null&&n.id){if(e){const r=[e.appContext.app,e.uid,(t=e.parent)==null?void 0:t.uid,e];Ct.callHook("component:updated",...r)}else Ct.callHook("component:updated");this.hooks.callHook("sendInspectorState",{inspectorId:n.id,plugin:this.plugin})}}addInspector(e){this.hooks.callHook("addInspector",{inspector:e,plugin:this.plugin}),this.plugin.descriptor.settings&&S0(e.id,this.plugin.descriptor.settings)}sendInspectorTree(e){this.hooks.callHook("sendInspectorTree",{inspectorId:e,plugin:this.plugin})}sendInspectorState(e){this.hooks.callHook("sendInspectorState",{inspectorId:e,plugin:this.plugin})}selectInspectorNode(e,t){this.hooks.callHook("customInspectorSelectNode",{inspectorId:e,nodeId:t,plugin:this.plugin})}now(){return Date.now()}addTimelineLayer(e){this.hooks.callHook("timelineLayerAdded",{options:e,plugin:this.plugin})}addTimelineEvent(e){this.hooks.callHook("timelineEventAdded",{options:e,plugin:this.plugin})}getSettings(e){return Tf(e??this.plugin.descriptor.id,this.plugin.descriptor.settings)}getComponentInstances(e){return this.hooks.callHook("getComponentInstances",{app:e})}getComponentBounds(e){return this.hooks.callHook("getComponentBounds",{instance:e})}getComponentName(e){return this.hooks.callHook("getComponentName",{instance:e})}highlightElement(e){const t=e.__VUE_DEVTOOLS_NEXT_UID__;return this.hooks.callHook("componentHighlight",{uid:t})}unhighlightElement(){return this.hooks.callHook("componentUnhighlight")}},x0=C0;I();I();I();I();var T0="__vue_devtool_undefined__",O0="__vue_devtool_infinity__",P0="__vue_devtool_negative_infinity__",I0="__vue_devtool_nan__";I();I();var L0={[T0]:"undefined",[I0]:"NaN",[O0]:"Infinity",[P0]:"-Infinity"};Object.entries(L0).reduce((e,[t,n])=>(e[n]=t,e),{});I();I();I();var Ia,La;(La=(Ia=X).__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__)!=null||(Ia.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__=new Set);function R0(e,t){return Of.setupDevToolsPlugin(e,t)}function D0(e,t){const[n,r]=e;if(n.app!==t)return;const o=new x0({plugin:{setupFn:r,descriptor:n},ctx:rr});n.packageName==="vuex"&&o.on.editInspectorState(s=>{o.sendInspectorState(s.inspectorId)}),r(o)}function N0(e){X.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.has(e)||(X.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.add(e),Fi.forEach(t=>{D0(t,e)}))}I();I();var Lr="__VUE_DEVTOOLS_ROUTER__",Wn="__VUE_DEVTOOLS_ROUTER_INFO__",Ra,Da;(Da=(Ra=X)[Wn])!=null||(Ra[Wn]={currentRoute:null,routes:[]});var Na,Va;(Va=(Na=X)[Lr])!=null||(Na[Lr]={});new Proxy(X[Wn],{get(e,t){return X[Wn][t]}});new Proxy(X[Lr],{get(e,t){if(t==="value")return X[Lr]}});function V0(e){const t=new Map;return((e==null?void 0:e.getRoutes())||[]).filter(n=>!t.has(n.path)&&t.set(n.path,1))}function Hi(e){return e.map(t=>{let{path:n,name:r,children:o,meta:s}=t;return o!=null&&o.length&&(o=Hi(o)),{path:n,name:r,children:o,meta:s}})}function M0(e){if(e){const{fullPath:t,hash:n,href:r,path:o,name:s,matched:i,params:l,query:a}=e;return{fullPath:t,hash:n,href:r,path:o,name:s,params:l,query:a,matched:Hi(i)}}return e}function F0(e,t){function n(){var r;const o=(r=e.app)==null?void 0:r.config.globalProperties.$router,s=M0(o==null?void 0:o.currentRoute.value),i=Hi(V0(o)),l=console.warn;console.warn=()=>{},X[Wn]={currentRoute:s?ia(s):{},routes:ia(i)},X[Lr]=o,console.warn=l}n(),Of.on.componentUpdated(qo(()=>{var r;((r=t.value)==null?void 0:r.app)===e.app&&(n(),rr.hooks.callHook("routerInfoUpdated",{state:X[Wn]}))},200))}function B0(e){return{async getInspectorTree(t){const n={...t,app:tt.value.app,rootNodes:[]};return await new Promise(r=>{e.callHookWith(async o=>{await Promise.all(o.map(s=>s(n))),r()},"getInspectorTree")}),n.rootNodes},async getInspectorState(t){const n={...t,app:tt.value.app,state:null},r={currentTab:`custom-inspector:${t.inspectorId}`};return await new Promise(o=>{e.callHookWith(async s=>{await Promise.all(s.map(i=>i(n,r))),o()},"getInspectorState")}),n.state},editInspectorState(t){const n=new q_,r={...t,app:tt.value.app,set:(o,s=t.path,i=t.state.value,l)=>{n.set(o,s,i,l||n.createDefaultSetCallback(t.state))}};e.callHookWith(o=>{o.forEach(s=>s(r))},"editInspectorState")},sendInspectorState(t){const n=fo(t);e.callHook("sendInspectorState",{inspectorId:t,plugin:{descriptor:n.descriptor,setupFn:()=>({})}})},inspectComponentInspector(){return a0()},cancelInspectComponentInspector(){return l0()},getComponentRenderCode(t){const n=$s(tt.value,t);if(n)return(n==null?void 0:n.type)instanceof Function?n.type.toString():n.render.toString()},scrollToComponent(t){return u0({id:t})},openInEditor:E0,getVueInspector:d0,toggleApp(t){const n=Yo.value.find(r=>r.id===t);n&&(b0(t),y0(n),F0(n,tt),Af(),N0(n.app))},inspectDOM(t){const n=$s(tt.value,t);if(n){const[r]=Ri(n);r&&(X.__VUE_DEVTOOLS_INSPECT_DOM_TARGET__=r)}},updatePluginSettings(t,n,r){w0(t,n,r)},getPluginSettings(t){return{options:k0(t),values:Tf(t)}}}}I();var Ma,Fa;(Fa=(Ma=X).__VUE_DEVTOOLS_ENV__)!=null||(Ma.__VUE_DEVTOOLS_ENV__={vitePluginDetected:!1});var Ba=g0(),Ha,$a;($a=(Ha=X).__VUE_DEVTOOLS_KIT_CONTEXT__)!=null||(Ha.__VUE_DEVTOOLS_KIT_CONTEXT__={hooks:Ba,get state(){return{...An,activeAppRecordId:tt.id,activeAppRecord:tt.value,appRecords:Yo.value}},api:B0(Ba)});var rr=X.__VUE_DEVTOOLS_KIT_CONTEXT__;I();B_($_());var Ua,ja;(ja=(Ua=X).__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__)!=null||(Ua.__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__={id:0,appIds:new Set});I();function H0(e){An.highPerfModeEnabled=e??!An.highPerfModeEnabled}I();I();I();function $0(e){An.devtoolsClientDetected={...An.devtoolsClientDetected,...e};const t=Object.values(An.devtoolsClientDetected).some(Boolean);H0(!t)}var za,Ka;(Ka=(za=X).__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__)!=null||(za.__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__=$0);I();I();I();I();I();I();I();var U0=class{constructor(){this.keyToValue=new Map,this.valueToKey=new Map}set(e,t){this.keyToValue.set(e,t),this.valueToKey.set(t,e)}getByKey(e){return this.keyToValue.get(e)}getByValue(e){return this.valueToKey.get(e)}clear(){this.keyToValue.clear(),this.valueToKey.clear()}},Pf=class{constructor(e){this.generateIdentifier=e,this.kv=new U0}register(e,t){this.kv.getByValue(e)||(t||(t=this.generateIdentifier(e)),this.kv.set(t,e))}clear(){this.kv.clear()}getIdentifier(e){return this.kv.getByValue(e)}getValue(e){return this.kv.getByKey(e)}},j0=class extends Pf{constructor(){super(e=>e.name),this.classToAllowedProps=new Map}register(e,t){typeof t=="object"?(t.allowProps&&this.classToAllowedProps.set(e,t.allowProps),super.register(e,t.identifier)):super.register(e,t)}getAllowedProps(e){return this.classToAllowedProps.get(e)}};I();I();function z0(e){if("values"in Object)return Object.values(e);const t=[];for(const n in e)e.hasOwnProperty(n)&&t.push(e[n]);return t}function K0(e,t){const n=z0(e);if("find"in n)return n.find(t);const r=n;for(let o=0;ot(r,n))}function po(e,t){return e.indexOf(t)!==-1}function Wa(e,t){for(let n=0;nt.isApplicable(e))}findByName(e){return this.transfomers[e]}};I();I();var q0=e=>Object.prototype.toString.call(e).slice(8,-1),If=e=>typeof e>"u",G0=e=>e===null,Rr=e=>typeof e!="object"||e===null||e===Object.prototype?!1:Object.getPrototypeOf(e)===null?!0:Object.getPrototypeOf(e)===Object.prototype,Ks=e=>Rr(e)&&Object.keys(e).length===0,un=e=>Array.isArray(e),Y0=e=>typeof e=="string",X0=e=>typeof e=="number"&&!isNaN(e),J0=e=>typeof e=="boolean",Z0=e=>e instanceof RegExp,Dr=e=>e instanceof Map,Nr=e=>e instanceof Set,Lf=e=>q0(e)==="Symbol",Q0=e=>e instanceof Date&&!isNaN(e.valueOf()),e1=e=>e instanceof Error,qa=e=>typeof e=="number"&&isNaN(e),t1=e=>J0(e)||G0(e)||If(e)||X0(e)||Y0(e)||Lf(e),n1=e=>typeof e=="bigint",r1=e=>e===1/0||e===-1/0,o1=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),s1=e=>e instanceof URL;I();var Rf=e=>e.replace(/\./g,"\\."),bs=e=>e.map(String).map(Rf).join("."),Er=e=>{const t=[];let n="";for(let o=0;onull,()=>{}),St(n1,"bigint",e=>e.toString(),e=>typeof BigInt<"u"?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),St(Q0,"Date",e=>e.toISOString(),e=>new Date(e)),St(e1,"Error",(e,t)=>{const n={name:e.name,message:e.message};return t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n},(e,t)=>{const n=new Error(e.message);return n.name=e.name,n.stack=e.stack,t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n}),St(Z0,"regexp",e=>""+e,e=>{const t=e.slice(1,e.lastIndexOf("/")),n=e.slice(e.lastIndexOf("/")+1);return new RegExp(t,n)}),St(Nr,"set",e=>[...e.values()],e=>new Set(e)),St(Dr,"map",e=>[...e.entries()],e=>new Map(e)),St(e=>qa(e)||r1(e),"number",e=>qa(e)?"NaN":e>0?"Infinity":"-Infinity",Number),St(e=>e===0&&1/e===-1/0,"number",()=>"-0",Number),St(s1,"URL",e=>e.toString(),e=>new URL(e))];function Xo(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var Nf=Xo((e,t)=>Lf(e)?!!t.symbolRegistry.getIdentifier(e):!1,(e,t)=>["symbol",t.symbolRegistry.getIdentifier(e)],e=>e.description,(e,t,n)=>{const r=n.symbolRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown symbol");return r}),i1=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),Vf=Xo(o1,e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{const n=i1[t[1]];if(!n)throw new Error("Trying to deserialize unknown typed array");return new n(e)});function Mf(e,t){return e!=null&&e.constructor?!!t.classRegistry.getIdentifier(e.constructor):!1}var Ff=Xo(Mf,(e,t)=>["class",t.classRegistry.getIdentifier(e.constructor)],(e,t)=>{const n=t.classRegistry.getAllowedProps(e.constructor);if(!n)return{...e};const r={};return n.forEach(o=>{r[o]=e[o]}),r},(e,t,n)=>{const r=n.classRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown class - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564");return Object.assign(Object.create(r.prototype),e)}),Bf=Xo((e,t)=>!!t.customTransformerRegistry.findApplicable(e),(e,t)=>["custom",t.customTransformerRegistry.findApplicable(e).name],(e,t)=>t.customTransformerRegistry.findApplicable(e).serialize(e),(e,t,n)=>{const r=n.customTransformerRegistry.findByName(t[1]);if(!r)throw new Error("Trying to deserialize unknown custom value");return r.deserialize(e)}),l1=[Ff,Nf,Bf,Vf],Ga=(e,t)=>{const n=Wa(l1,o=>o.isApplicable(e,t));if(n)return{value:n.transform(e,t),type:n.annotation(e,t)};const r=Wa(Df,o=>o.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation}},Hf={};Df.forEach(e=>{Hf[e.annotation]=e});var a1=(e,t,n)=>{if(un(t))switch(t[0]){case"symbol":return Nf.untransform(e,t,n);case"class":return Ff.untransform(e,t,n);case"custom":return Bf.untransform(e,t,n);case"typed-array":return Vf.untransform(e,t,n);default:throw new Error("Unknown transformation: "+t)}else{const r=Hf[t];if(!r)throw new Error("Unknown transformation: "+t);return r.untransform(e,n)}};I();var Rn=(e,t)=>{const n=e.keys();for(;t>0;)n.next(),t--;return n.next().value};function $f(e){if(po(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(po(e,"prototype"))throw new Error("prototype is not allowed as a property");if(po(e,"constructor"))throw new Error("constructor is not allowed as a property")}var u1=(e,t)=>{$f(t);for(let n=0;n{if($f(t),t.length===0)return n(e);let r=e;for(let s=0;sqs(s,t,[...n,...Er(i)]));return}const[r,o]=e;o&&qn(o,(s,i)=>{qs(s,t,[...n,...Er(i)])}),t(r,n)}function c1(e,t,n){return qs(t,(r,o)=>{e=Ws(e,o,s=>a1(s,r,n))}),e}function f1(e,t){function n(r,o){const s=u1(e,Er(o));r.map(Er).forEach(i=>{e=Ws(e,i,()=>s)})}if(un(t)){const[r,o]=t;r.forEach(s=>{e=Ws(e,Er(s),()=>e)}),o&&qn(o,n)}else qn(t,n);return e}var d1=(e,t)=>Rr(e)||un(e)||Dr(e)||Nr(e)||Mf(e,t);function p1(e,t,n){const r=n.get(e);r?r.push(t):n.set(e,[t])}function h1(e,t){const n={};let r;return e.forEach(o=>{if(o.length<=1)return;t||(o=o.map(l=>l.map(String)).sort((l,a)=>l.length-a.length));const[s,...i]=o;s.length===0?r=i.map(bs):n[bs(s)]=i.map(bs)}),r?Ks(n)?[r]:[r,n]:Ks(n)?void 0:n}var Uf=(e,t,n,r,o=[],s=[],i=new Map)=>{var l;const a=t1(e);if(!a){p1(e,o,t);const v=i.get(e);if(v)return r?{transformedValue:null}:v}if(!d1(e,n)){const v=Ga(e,n),_=v?{transformedValue:v.value,annotations:[v.type]}:{transformedValue:e};return a||i.set(e,_),_}if(po(s,e))return{transformedValue:null};const u=Ga(e,n),f=(l=u==null?void 0:u.value)!=null?l:e,c=un(f)?[]:{},d={};qn(f,(v,_)=>{if(_==="__proto__"||_==="constructor"||_==="prototype")throw new Error(`Detected property ${_}. This is a prototype pollution risk, please remove it from your object.`);const y=Uf(v,t,n,r,[...o,_],[...s,e],i);c[_]=y.transformedValue,un(y.annotations)?d[_]=y.annotations:Rr(y.annotations)&&qn(y.annotations,(E,S)=>{d[Rf(_)+"."+S]=E})});const p=Ks(d)?{transformedValue:c,annotations:u?[u.type]:void 0}:{transformedValue:c,annotations:u?[u.type,d]:d};return a||i.set(e,p),p};I();I();function jf(e){return Object.prototype.toString.call(e).slice(8,-1)}function Ya(e){return jf(e)==="Array"}function m1(e){if(jf(e)!=="Object")return!1;const t=Object.getPrototypeOf(e);return!!t&&t.constructor===Object&&t===Object.prototype}function g1(e,t,n,r,o){const s={}.propertyIsEnumerable.call(r,t)?"enumerable":"nonenumerable";s==="enumerable"&&(e[t]=n),o&&s==="nonenumerable"&&Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0,configurable:!0})}function Gs(e,t={}){if(Ya(e))return e.map(o=>Gs(o,t));if(!m1(e))return e;const n=Object.getOwnPropertyNames(e),r=Object.getOwnPropertySymbols(e);return[...n,...r].reduce((o,s)=>{if(Ya(t.props)&&!t.props.includes(s))return o;const i=e[s],l=Gs(i,t);return g1(o,s,l,e,t.nonenumerable),o},{})}var Ae=class{constructor({dedupe:e=!1}={}){this.classRegistry=new j0,this.symbolRegistry=new Pf(t=>{var n;return(n=t.description)!=null?n:""}),this.customTransformerRegistry=new W0,this.allowedErrorProps=[],this.dedupe=e}serialize(e){const t=new Map,n=Uf(e,t,this,this.dedupe),r={json:n.transformedValue};n.annotations&&(r.meta={...r.meta,values:n.annotations});const o=h1(t,this.dedupe);return o&&(r.meta={...r.meta,referentialEqualities:o}),r}deserialize(e){const{json:t,meta:n}=e;let r=Gs(t);return n!=null&&n.values&&(r=c1(r,n.values,this)),n!=null&&n.referentialEqualities&&(r=f1(r,n.referentialEqualities)),r}stringify(e){return JSON.stringify(this.serialize(e))}parse(e){return this.deserialize(JSON.parse(e))}registerClass(e,t){this.classRegistry.register(e,t)}registerSymbol(e,t){this.symbolRegistry.register(e,t)}registerCustom(e,t){this.customTransformerRegistry.register({name:t,...e})}allowErrorProps(...e){this.allowedErrorProps.push(...e)}};Ae.defaultInstance=new Ae;Ae.serialize=Ae.defaultInstance.serialize.bind(Ae.defaultInstance);Ae.deserialize=Ae.defaultInstance.deserialize.bind(Ae.defaultInstance);Ae.stringify=Ae.defaultInstance.stringify.bind(Ae.defaultInstance);Ae.parse=Ae.defaultInstance.parse.bind(Ae.defaultInstance);Ae.registerClass=Ae.defaultInstance.registerClass.bind(Ae.defaultInstance);Ae.registerSymbol=Ae.defaultInstance.registerSymbol.bind(Ae.defaultInstance);Ae.registerCustom=Ae.defaultInstance.registerCustom.bind(Ae.defaultInstance);Ae.allowErrorProps=Ae.defaultInstance.allowErrorProps.bind(Ae.defaultInstance);I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();I();var Xa,Ja;(Ja=(Xa=X).__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__)!=null||(Xa.__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__=[]);var Za,Qa;(Qa=(Za=X).__VUE_DEVTOOLS_KIT_RPC_CLIENT__)!=null||(Za.__VUE_DEVTOOLS_KIT_RPC_CLIENT__=null);var eu,tu;(tu=(eu=X).__VUE_DEVTOOLS_KIT_RPC_SERVER__)!=null||(eu.__VUE_DEVTOOLS_KIT_RPC_SERVER__=null);var nu,ru;(ru=(nu=X).__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__)!=null||(nu.__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__=null);var ou,su;(su=(ou=X).__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__)!=null||(ou.__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__=null);var iu,lu;(lu=(iu=X).__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__)!=null||(iu.__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__=null);I();I();I();I();I();I();I();const v1=JSON.parse(`{"logo":"logo_worldline.png","repo":"worldline/learning-kotlin","locales":{"/en/":{"selectLanguageName":"English","sidebar":["/en/presentation/","/en/kotlin-features/","/en/backend-development/","/en/front-development/","/en/other-technologies/","/en/kotlin-features-advanced/","/en/workshops/"]},"/fr/":{"selectLanguageName":"Français","sidebar":["/fr/presentation/","/fr/kotlin-features/","/fr/backend-development/","/fr/front-development/","/fr/other-technologies/","/fr/kotlin-features-advanced/","/fr/workshops/"]},"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"navbar":[],"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebar":"heading","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),_1=ce(v1),zf=()=>_1,Kf=Symbol(""),y1=()=>{const e=qe(Kf);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},b1=(e,t)=>{const{locales:n,...r}=e;return{...r,...n==null?void 0:n[t]}},E1=It({enhance({app:e}){const t=zf(),n=e._context.provides[Ei],r=F(()=>b1(t.value,n.routeLocale.value));e.provide(Kf,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}}),R0({app:e,id:"org.vuejs.vuepress.plugin-theme-data",label:"VuePress Theme Data Plugin",packageName:"@vuepress/plugin-theme-data",homepage:"https://v2.vuepress.vuejs.org",logo:"https://v2.vuepress.vuejs.org/images/hero.png",componentStateTypes:["VuePress"]},o=>{o.on.inspectComponent(s=>{s.instanceData.state.push({type:"VuePress",key:"themeData",editable:!1,value:t.value},{type:"VuePress",key:"themeLocaleData",editable:!1,value:r.value})})})}}),k1=Object.freeze(Object.defineProperty({__proto__:null,default:E1},Symbol.toStringTag,{value:"Module"})),S1=()=>zf(),He=()=>y1(),Wf=Symbol(""),w1=e=>{const t=(n=e.value)=>{const r=window.document.documentElement;r.dataset.theme=n?"dark":"light"};Be(()=>{je(e,t,{immediate:!0})}),Vo(()=>{t()})},$i=()=>{const e=qe(Wf);if(!e)throw new Error("useDarkMode() is called without provider.");return e},A1=()=>{const e=He(),t=vv(),n=Ti("vuepress-color-scheme",e.value.colorMode),r=F({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(o){o===t.value?n.value="auto":n.value=o?"dark":"light"}});en(Wf,r),w1(r)};let Es=null,cr=null;const C1={wait:()=>Es,pending:()=>{Es=new Promise(e=>{cr=e})},resolve:()=>{cr==null||cr(),Es=null,cr=null}},qf=()=>C1,Gn=(e,t)=>{const{notFound:n,meta:r,path:o}=Ir(e,t);return n?{text:o,link:o}:{text:r.title||o,link:o}},au=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),x1=(e,t)=>{if(t.hash===e)return!0;const n=au(t.path),r=au(e);return n===r},Gf=(e,t)=>e.link&&x1(e.link,t)?!0:"children"in e?e.children.some(n=>Gf(n,t)):!1,Yf=e=>!pm(e)&&!Kr(e),Xf=e=>!Ho(e)||e.includes("github.com")?"GitHub":e.includes("bitbucket.org")?"Bitbucket":e.includes("gitlab.com")?"GitLab":e.includes("gitee.com")?"Gitee":null,T1={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},O1=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const n=Xf(e);return n!==null?T1[n]:null},P1=({docsRepo:e,docsBranch:t,docsDir:n,filePathRelative:r,editLinkPattern:o})=>{if(!r)return null;const s=O1({docsRepo:e,editLinkPattern:o});return s?s.replace(/:repo/,Ho(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,Dc(`${Rc(n)}/${r}`)):null},Un=(e="",t="")=>ff(t)||Kr(t)?t:`${km(e)}${t}`,ho=ce([]),I1=()=>{const e=fn(),t=He(),n=Et(),r=F(()=>n.value.sidebarDepth??t.value.sidebarDepth??2);e.beforeEach((s,i)=>{s.path!==i.path&&(ho.value=[])});const o=()=>{if(r.value<=0){ho.value=[];return}ho.value=Rv({levels:[2,r.value+1],ignore:[".vp-badge"]})};je(r,o),Be(o)},L1=()=>ho,R1=e=>({text:e.title,link:e.link,children:Ui(e.children)}),Ui=e=>e?e.map(t=>R1(t)):[],Jf=(e,t)=>[{text:e.title,children:Ui(t)}],Zf=(e,t,n,r="")=>{const o=(s,i)=>{var a;const l=mt(s)?Gn(Un(i,s)):mt(s.link)?{...s,link:Yf(s.link)?Gn(Un(i,s.link)).link:s.link}:s;if("children"in l)return{...l,children:l.children.map(u=>o(u,Un(i,l.prefix)))};if(l.link===n){const u=((a=t[0])==null?void 0:a.level)===1?t[0].children:t;return{...l,children:Ui(u)}}return l};return e.map(s=>o(s,r))},D1=(e,t,n,r)=>{const o=Vv(e).sort((s,i)=>i.length-s.length);for(const s of o)if(cf(decodeURI(r),s)){const i=e[s];return i?i==="heading"?Jf(t,n):Zf(i,n,r,s):[]}return console.warn(`${decodeURI(r)} is missing sidebar config.`),[]},Qf=Symbol("sidebarItems"),ji=()=>{const e=qe(Qf);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},N1=(e,t,n,r,o)=>e===!1?[]:e==="heading"?Jf(t,o):Array.isArray(e)?Zf(e,o,n,r):_i(e)?D1(e,t,o,n):[],V1=()=>{const e=He(),t=Et(),n=Qn(),r=zt(),o=er(),s=L1(),i=F(()=>t.value.home?!1:t.value.sidebar??e.value.sidebar??"heading"),l=F(()=>N1(i.value,n.value,r.path,o.value,s.value));en(Qf,l)},M1=he({__name:"Badge",props:{type:{default:"tip"},text:{default:""},vertical:{default:void 0}},setup(e,{expose:t}){t();const n={};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}}),Oe=(e,t)=>{const n=e.__vccOpts||e;for(const[r,o]of t)n[r]=o;return n};function F1(e,t,n,r,o,s){return Y(),ne("span",{class:nt(["vp-badge",n.type]),style:Xn({verticalAlign:n.vertical})},[Le(e.$slots,"default",{},()=>[sn(Ie(n.text),1)])],6)}const B1=Oe(M1,[["render",F1],["__file","Badge.vue"]]),H1=he({__name:"VPHomeFeatures",setup(e,{expose:t}){t();const n=Et(),r=F(()=>n.value.features??[]),o={frontmatter:n,features:r};return Object.defineProperty(o,"__isScriptSetup",{enumerable:!1,value:!0}),o}}),$1={key:0,class:"vp-features"};function U1(e,t,n,r,o,s){return r.features.length?(Y(),ne("div",$1,[(Y(!0),ne(_e,null,rn(r.features,i=>(Y(),ne("div",{key:i.title,class:"vp-feature"},[ie("h2",null,Ie(i.title),1),ie("p",null,Ie(i.details),1)]))),128))])):Me("",!0)}const j1=Oe(H1,[["render",U1],["__file","VPHomeFeatures.vue"]]),z1=he({__name:"VPHomeFooter",setup(e,{expose:t}){t();const n=Et(),r=F(()=>n.value.footer),o=F(()=>n.value.footerHtml),s={frontmatter:n,footer:r,footerHtml:o};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}}),K1=["innerHTML"],W1=["textContent"];function q1(e,t,n,r,o,s){return r.footer?(Y(),ne(_e,{key:0},[r.footerHtml?(Y(),ne("div",{key:0,class:"vp-footer","vp-footer":"",innerHTML:r.footer},null,8,K1)):(Y(),ne("div",{key:1,class:"vp-footer","vp-footer":"",textContent:Ie(r.footer)},null,8,W1))],64)):Me("",!0)}const G1=Oe(z1,[["render",q1],["__file","VPHomeFooter.vue"]]),Y1=he({__name:"VPHomeHero",setup(e,{expose:t}){t();const n=Et(),r=ki(),o=$i(),s=F(()=>n.value.heroText===null?null:n.value.heroText||r.value.title||"Hello"),i=F(()=>n.value.tagline===null?null:n.value.tagline||r.value.description||"Welcome to your VuePress site"),l=F(()=>o.value&&n.value.heroImageDark!==void 0?n.value.heroImageDark:n.value.heroImage),a=F(()=>n.value.heroAlt||s.value||"hero"),u=F(()=>n.value.heroHeight??280),f=F(()=>Array.isArray(n.value.actions)?n.value.actions.map(({text:p,link:v,type:_="primary"})=>({text:p,link:v,type:_})):[]),d={frontmatter:n,siteLocale:r,isDarkMode:o,heroText:s,tagline:i,heroImage:l,heroAlt:a,heroHeight:u,actions:f,HomeHeroImage:()=>{if(!l.value)return null;const p=le("img",{class:"vp-hero-image",src:zo(l.value),alt:a.value,height:u.value});return n.value.heroImageDark===void 0?p:le(Si,()=>p)},get AutoLink(){return tr}};return Object.defineProperty(d,"__isScriptSetup",{enumerable:!1,value:!0}),d}}),X1={class:"vp-hero"},J1={key:0,id:"main-title"},Z1={key:1,class:"vp-hero-description"},Q1={key:2,class:"vp-hero-actions"};function ey(e,t,n,r,o,s){return Y(),ne("header",X1,[ae(r.HomeHeroImage),r.heroText?(Y(),ne("h1",J1,Ie(r.heroText),1)):Me("",!0),r.tagline?(Y(),ne("p",Z1,Ie(r.tagline),1)):Me("",!0),r.actions.length?(Y(),ne("p",Q1,[(Y(!0),ne(_e,null,rn(r.actions,i=>(Y(),Re(r.AutoLink,{key:i.text,class:nt(["vp-hero-action-button",[i.type]]),config:i},null,8,["class","config"]))),128))])):Me("",!0)])}const ty=Oe(Y1,[["render",ey],["__file","VPHomeHero.vue"]]),ny=he({__name:"VPHome",setup(e,{expose:t}){t();const n={VPHomeFeatures:j1,VPHomeFooter:G1,VPHomeHero:ty,get Content(){return wi}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}}),ry={class:"vp-home"},oy={class:"theme-default-content","vp-content":""};function sy(e,t,n,r,o,s){return Y(),ne("main",ry,[ae(r.VPHomeHero),ae(r.VPHomeFeatures),ie("div",oy,[ae(r.Content)]),ae(r.VPHomeFooter)])}const iy=Oe(ny,[["render",sy],["__file","VPHome.vue"]]),ly=he({__name:"VPNavbarBrand",setup(e,{expose:t}){t();const n=er(),r=ki(),o=He(),s=$i(),i=F(()=>o.value.home||n.value),l=F(()=>r.value.title),a=F(()=>s.value&&o.value.logoDark!==void 0?o.value.logoDark:o.value.logo),u=F(()=>o.value.logoAlt??l.value),f=F(()=>l.value.toLocaleUpperCase().trim()===u.value.toLocaleUpperCase().trim()),d={routeLocale:n,siteLocale:r,themeLocale:o,isDarkMode:s,navbarBrandLink:i,navbarBrandTitle:l,navbarBrandLogo:a,navbarBrandLogoAlt:u,navBarLogoAltMatchesTitle:f,NavbarBrandLogo:()=>{if(!a.value)return null;const p=le("img",{class:"vp-site-logo",src:zo(a.value),alt:u.value});return o.value.logoDark===void 0?p:le(Si,()=>p)},get RouteLink(){return jo}};return Object.defineProperty(d,"__isScriptSetup",{enumerable:!1,value:!0}),d}}),ay=["aria-hidden"];function uy(e,t,n,r,o,s){return Y(),Re(r.RouteLink,{to:r.navbarBrandLink},{default:Ve(()=>[ae(r.NavbarBrandLogo),r.navbarBrandTitle?(Y(),ne("span",{key:0,class:nt(["vp-site-name",{"vp-hide-mobile":r.navbarBrandLogo}]),"aria-hidden":r.navBarLogoAltMatchesTitle},Ie(r.navbarBrandTitle),11,ay)):Me("",!0)]),_:1},8,["to"])}const cy=Oe(ly,[["render",uy],["__file","VPNavbarBrand.vue"]]),fy=he({__name:"VPDropdownTransition",setup(e,{expose:t}){t();const o={setHeight:s=>{s.style.height=`${s.scrollHeight}px`},unsetHeight:s=>{s.style.height=""}};return Object.defineProperty(o,"__isScriptSetup",{enumerable:!1,value:!0}),o}});function dy(e,t,n,r,o,s){return Y(),Re(Bo,{name:"vp-dropdown",onEnter:r.setHeight,onAfterEnter:r.unsetHeight,onBeforeLeave:r.setHeight},{default:Ve(()=>[Le(e.$slots,"default")]),_:3})}const ed=Oe(fy,[["render",dy],["__file","VPDropdownTransition.vue"]]),py=he({__name:"VPNavbarDropdown",props:{item:{}},setup(e,{expose:t}){t();const n=e,{item:r}=ai(n),o=zt(),s=ce(!1),i=F(()=>r.value.ariaLabel||r.value.text),l=(f,c)=>c[c.length-1]===f,a=f=>{const c=f.detail===0;s.value=c?!s.value:!1};je(()=>o.path,()=>{s.value=!1});const u={props:n,item:r,route:o,open:s,dropdownAriaLabel:i,isLastItemOfArray:l,handleDropdown:a,VPDropdownTransition:ed,get AutoLink(){return tr}};return Object.defineProperty(u,"__isScriptSetup",{enumerable:!1,value:!0}),u}}),hy=["aria-label"],my={class:"title"},gy=["aria-label"],vy={class:"title"},_y={class:"vp-navbar-dropdown"},yy={class:"vp-navbar-dropdown-subtitle"},by={key:1},Ey={class:"vp-navbar-dropdown-subitem-wrapper"};function ky(e,t,n,r,o,s){return Y(),ne("div",{class:nt(["vp-navbar-dropdown-wrapper",{open:r.open}])},[ie("button",{class:"vp-navbar-dropdown-title",type:"button","aria-label":r.dropdownAriaLabel,onClick:r.handleDropdown},[ie("span",my,Ie(r.item.text),1),t[1]||(t[1]=ie("span",{class:"arrow down"},null,-1))],8,hy),ie("button",{class:"vp-navbar-dropdown-title-mobile",type:"button","aria-label":r.dropdownAriaLabel,onClick:t[0]||(t[0]=i=>r.open=!r.open)},[ie("span",vy,Ie(r.item.text),1),ie("span",{class:nt(["arrow",r.open?"down":"right"])},null,2)],8,gy),ae(r.VPDropdownTransition,null,{default:Ve(()=>[bo(ie("ul",_y,[(Y(!0),ne(_e,null,rn(r.item.children,i=>(Y(),ne("li",{key:i.text,class:"vp-navbar-dropdown-item"},["children"in i?(Y(),ne(_e,{key:0},[ie("h4",yy,[i.link?(Y(),Re(r.AutoLink,{key:0,config:i,onFocusout:l=>r.isLastItemOfArray(i,r.item.children)&&i.children.length===0&&(r.open=!1)},null,8,["config","onFocusout"])):(Y(),ne("span",by,Ie(i.text),1))]),ie("ul",Ey,[(Y(!0),ne(_e,null,rn(i.children,l=>(Y(),ne("li",{key:l.link,class:"vp-navbar-dropdown-subitem"},[ae(r.AutoLink,{config:l,onFocusout:a=>r.isLastItemOfArray(l,i.children)&&r.isLastItemOfArray(i,r.item.children)&&(r.open=!1)},null,8,["config","onFocusout"])]))),128))])],64)):(Y(),Re(r.AutoLink,{key:1,config:i,onFocusout:l=>r.isLastItemOfArray(i,r.item.children)&&(r.open=!1)},null,8,["config","onFocusout"]))]))),128))],512),[[Ao,r.open]])]),_:1})],2)}const Sy=Oe(py,[["render",ky],["__file","VPNavbarDropdown.vue"]]),td=(e,t="")=>mt(e)?Gn(Un(t,e)):"children"in e?{...e,children:e.children.map(n=>td(n,Un(t,e.prefix)))}:{...e,link:Yf(e.link)?Gn(Un(t,e.link)).link:e.link},wy=()=>{const e=He();return F(()=>(e.value.navbar||[]).map(t=>td(t)))},Ay=()=>{const e=He(),t=F(()=>e.value.repo),n=F(()=>t.value?Xf(t.value):null),r=F(()=>t.value&&!Ho(t.value)?`https://github.com/${t.value}`:t.value),o=F(()=>r.value?e.value.repoLabel?e.value.repoLabel:n.value===null?"Source":n.value:null);return F(()=>!r.value||!o.value?[]:[{text:o.value,link:r.value}])},Cy=()=>{const e=zt(),t=Dv(),n=er(),r=nf(),o=ki(),s=S1(),i=He();return F(()=>{const l=Object.keys(r.value.locales);if(l.length<2)return[];const a=e.path,u=e.fullPath;return[{text:`${i.value.selectLanguageText}`,ariaLabel:`${i.value.selectLanguageAriaLabel??i.value.selectLanguageText}`,children:l.map(c=>{var E,S;const d=((E=r.value.locales)==null?void 0:E[c])??{},p=((S=s.value.locales)==null?void 0:S[c])??{},v=`${d.lang}`,_=p.selectLanguageName??v;if(v===o.value.lang)return{text:_,activeMatch:".",link:e.fullPath};const y=a.replace(n.value,c);return{text:_,link:t.value.some(h=>h===y)?u.replace(a,y):p.home??c}})}]})},xy="719px",Ty={mobile:xy};var Vr;(function(e){e.Mobile="mobile"})(Vr||(Vr={}));const Oy={[Vr.Mobile]:Number.parseInt(Ty.mobile.replace("px",""),10)},nd=(e,t)=>{const n=Oy[e];Number.isInteger(n)&&(ct("orientationchange",()=>{t(n)},!1),ct("resize",()=>{t(n)},!1),Be(()=>{t(n)}))},Py=he({__name:"VPNavbarItems",setup(e,{expose:t}){t();const n=wy(),r=Cy(),o=Ay(),s=ce(!1),i=F(()=>He().value.navbarLabel??"site navigation"),l=F(()=>[...n.value,...r.value,...o.value]);nd(Vr.Mobile,u=>{s.value=window.innerWidth(Y(),ne("div",{key:i.text,class:"vp-navbar-item"},["children"in i?(Y(),Re(r.VPNavbarDropdown,{key:0,class:nt({mobile:r.isMobile}),item:i},null,8,["class","item"])):(Y(),Re(r.AutoLink,{key:1,config:i},null,8,["config"]))]))),128))],8,Iy)):Me("",!0)}const rd=Oe(Py,[["render",Ly],["__file","VPNavbarItems.vue"]]),Ry={},Dy={class:"dark-icon",viewBox:"0 0 32 32"};function Ny(e,t){return Y(),ne("svg",Dy,t[0]||(t[0]=[ie("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1)]))}const Vy=Oe(Ry,[["render",Ny],["__file","VPDarkIcon.vue"]]),My={},Fy={class:"light-icon",viewBox:"0 0 32 32"};function By(e,t){return Y(),ne("svg",Fy,t[0]||(t[0]=[kh('',9)]))}const Hy=Oe(My,[["render",By],["__file","VPLightIcon.vue"]]),$y=he({__name:"VPToggleColorModeButton",setup(e,{expose:t}){t();const n=He(),r=$i(),s={themeLocale:n,isDarkMode:r,toggleColorMode:()=>{r.value=!r.value},VPDarkIcon:Vy,VPLightIcon:Hy};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}}),Uy=["title"];function jy(e,t,n,r,o,s){return Y(),ne("button",{type:"button",class:"vp-toggle-color-mode-button",title:r.themeLocale.toggleColorMode,onClick:r.toggleColorMode},[bo(ae(r.VPLightIcon,null,null,512),[[Ao,!r.isDarkMode]]),bo(ae(r.VPDarkIcon,null,null,512),[[Ao,r.isDarkMode]])],8,Uy)}const zy=Oe($y,[["render",jy],["__file","VPToggleColorModeButton.vue"]]),Ky=he({__name:"VPToggleSidebarButton",emits:["toggle"],setup(e,{expose:t}){t();const r={themeLocale:He()};return Object.defineProperty(r,"__isScriptSetup",{enumerable:!1,value:!0}),r}}),Wy=["title"];function qy(e,t,n,r,o,s){return Y(),ne("div",{class:"vp-toggle-sidebar-button",title:r.themeLocale.toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:t[0]||(t[0]=i=>e.$emit("toggle"))},t[1]||(t[1]=[ie("div",{class:"icon","aria-hidden":"true"},[ie("span"),ie("span"),ie("span")],-1)]),8,Wy)}const Gy=Oe(Ky,[["render",qy],["__file","VPToggleSidebarButton.vue"]]),Yy=he({__name:"VPNavbar",emits:["toggleSidebar"],setup(e,{expose:t}){t();const n=af("SearchBox")?pi("SearchBox"):()=>null,r=He(),o=ce(null),s=ce(null),i=ce(0),l=F(()=>i.value?{maxWidth:`${i.value}px`}:{}),a=(f,c)=>{var v;const d=(v=f==null?void 0:f.ownerDocument.defaultView)==null?void 0:v.getComputedStyle(f,null)[c],p=Number.parseInt(d,10);return Number.isNaN(p)?0:p};nd(Vr.Mobile,f=>{var d;const c=a(o.value,"paddingLeft")+a(o.value,"paddingRight");window.innerWidthe.$emit("toggleSidebar"))}),ie("span",Jy,[ae(r.VPNavbarBrand)],512),ie("div",{class:"vp-navbar-items-wrapper",style:Xn(r.linksWrapperStyle)},[Le(e.$slots,"before"),ae(r.VPNavbarItems,{class:"vp-hide-mobile"}),Le(e.$slots,"after"),r.themeLocale.colorModeSwitch?(Y(),Re(r.VPToggleColorModeButton,{key:0})):Me("",!0),ae(r.SearchBox)],4)],512)}const Qy=Oe(Yy,[["render",Zy],["__file","VPNavbar.vue"]]),eb={},tb={class:"edit-icon",viewBox:"0 0 1024 1024"};function nb(e,t){return Y(),ne("svg",tb,t[0]||(t[0]=[ie("g",{fill:"currentColor"},[ie("path",{d:"M430.818 653.65a60.46 60.46 0 0 1-50.96-93.281l71.69-114.012 7.773-10.365L816.038 80.138A60.46 60.46 0 0 1 859.225 62a60.46 60.46 0 0 1 43.186 18.138l43.186 43.186a60.46 60.46 0 0 1 0 86.373L588.879 565.55l-8.637 8.637-117.466 68.234a60.46 60.46 0 0 1-31.958 11.229z"}),ie("path",{d:"M728.802 962H252.891A190.883 190.883 0 0 1 62.008 771.98V296.934a190.883 190.883 0 0 1 190.883-192.61h267.754a60.46 60.46 0 0 1 0 120.92H252.891a69.962 69.962 0 0 0-69.098 69.099V771.98a69.962 69.962 0 0 0 69.098 69.098h475.911A69.962 69.962 0 0 0 797.9 771.98V503.363a60.46 60.46 0 1 1 120.922 0V771.98A190.883 190.883 0 0 1 728.802 962z"})],-1)]))}const rb=Oe(eb,[["render",nb],["__file","VPEditIcon.vue"]]),ob=()=>{const e=He(),t=Qn(),n=Et();return F(()=>{var o;return n.value.contributors??e.value.contributors??!0?((o=t.value.git)==null?void 0:o.contributors)??null:null})},sb=()=>{const e=He(),t=Qn(),n=Et();return F(()=>{if(!(n.value.editLink??e.value.editLink??!0))return null;const{repo:o,docsRepo:s=o,docsBranch:i="main",docsDir:l="",editLinkText:a}=e.value;if(!s)return null;const u=P1({docsRepo:s,docsBranch:i,docsDir:l,filePathRelative:t.value.filePathRelative,editLinkPattern:n.value.editLinkPattern??e.value.editLinkPattern});return u?{text:a??"Edit this page",link:u}:null})},ib=()=>{const e=He(),t=Qn(),n=Et();return F(()=>{var s;return!(n.value.lastUpdated??e.value.lastUpdated??!0)||!((s=t.value.git)!=null&&s.updatedTime)?null:new Date(t.value.git.updatedTime).toLocaleString()})},lb=he({__name:"VPPageMeta",setup(e,{expose:t}){t();const n=He(),r=sb(),o=ib(),s=ob(),i={themeLocale:n,editLink:r,lastUpdated:o,contributors:s,VPEditIcon:rb,get AutoLink(){return tr}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}}),ab={class:"vp-page-meta"},ub={key:0,class:"vp-meta-item edit-link"},cb={class:"vp-meta-item git-info"},fb={key:0,class:"vp-meta-item last-updated"},db={class:"meta-item-label"},pb={class:"meta-item-info"},hb={key:1,class:"vp-meta-item contributors"},mb={class:"meta-item-label"},gb={class:"meta-item-info"},vb=["title"];function _b(e,t,n,r,o,s){const i=pi("ClientOnly");return Y(),ne("footer",ab,[r.editLink?(Y(),ne("div",ub,[ae(r.AutoLink,{class:"label",config:r.editLink},{before:Ve(()=>[ae(r.VPEditIcon)]),_:1},8,["config"])])):Me("",!0),ie("div",cb,[r.lastUpdated?(Y(),ne("div",fb,[ie("span",db,Ie(r.themeLocale.lastUpdatedText)+": ",1),ae(i,null,{default:Ve(()=>[ie("span",pb,Ie(r.lastUpdated),1)]),_:1})])):Me("",!0),r.contributors&&r.contributors.length?(Y(),ne("div",hb,[ie("span",mb,Ie(r.themeLocale.contributorsText)+": ",1),ie("span",gb,[(Y(!0),ne(_e,null,rn(r.contributors,(l,a)=>(Y(),ne(_e,{key:a},[ie("span",{class:"contributor",title:`email: ${l.email}`},Ie(l.name),9,vb),a!==r.contributors.length-1?(Y(),ne(_e,{key:0},[sn(", ")],64)):Me("",!0)],64))),128))])])):Me("",!0)])])}const yb=Oe(lb,[["render",_b],["__file","VPPageMeta.vue"]]),bb=()=>{const e=fn(),t=zt();return n=>{n&&(ff(n)?t.path!==n&&e.push(n):Kr(n)?window.open(n):e.push(encodeURI(n)))}},uu=(e,t)=>e===!1?!1:mt(e)?Gn(e,t):_i(e)?{...e,link:Gn(e.link,t).link}:null,Ys=(e,t,n)=>{const r=e.findIndex(s=>s.link===t);if(r!==-1){const s=e[r+n];return s?s.link?s:"prefix"in s&&!Ir(s.prefix).notFound?{...s,link:s.prefix}:null:null}for(const s of e)if("children"in s){const i=Ys(s.children,t,n);if(i)return i}const o=e.findIndex(s=>"prefix"in s&&s.prefix===t);if(o!==-1){const s=e[o+n];return s?s.link?s:"prefix"in s&&!Ir(s.prefix).notFound?{...s,link:s.prefix}:null:null}return null},Eb=()=>{const e=Et(),t=He(),n=ji(),r=zt(),o=F(()=>{const i=uu(e.value.prev,r.path);return i===!1?null:i??(t.value.prev===!1?null:Ys(n.value,r.path,-1))}),s=F(()=>{const i=uu(e.value.next,r.path);return i===!1?null:i??(t.value.next===!1?null:Ys(n.value,r.path,1))});return{prevLink:o,nextLink:s}},kb=he({__name:"VPPageNav",setup(e,{expose:t}){t();const n=He(),r=bb(),{prevLink:o,nextLink:s}=Eb(),i=F(()=>n.value.pageNavbarLabel??"page navigation");ct("keydown",a=>{a.altKey&&(a.key==="ArrowRight"?s.value&&(r(s.value.link),a.preventDefault()):a.key==="ArrowLeft"&&o.value&&(r(o.value.link),a.preventDefault()))});const l={themeLocale:n,navigate:r,prevLink:o,nextLink:s,navbarLabel:i,get AutoLink(){return tr}};return Object.defineProperty(l,"__isScriptSetup",{enumerable:!1,value:!0}),l}}),Sb=["aria-label"],wb={class:"hint"},Ab={class:"link"},Cb={class:"hint"},xb={class:"link"};function Tb(e,t,n,r,o,s){return r.prevLink||r.nextLink?(Y(),ne("nav",{key:0,class:"vp-page-nav","aria-label":r.navbarLabel},[r.prevLink?(Y(),Re(r.AutoLink,{key:0,class:"prev",config:r.prevLink},{default:Ve(()=>[ie("div",wb,[t[0]||(t[0]=ie("span",{class:"arrow left"},null,-1)),sn(" "+Ie(r.themeLocale.prev??"Prev"),1)]),ie("div",Ab,[ie("span",null,Ie(r.prevLink.text),1)])]),_:1},8,["config"])):Me("",!0),r.nextLink?(Y(),Re(r.AutoLink,{key:1,class:"next",config:r.nextLink},{default:Ve(()=>[ie("div",Cb,[sn(Ie(r.themeLocale.next??"Next")+" ",1),t[1]||(t[1]=ie("span",{class:"arrow right"},null,-1))]),ie("div",xb,[ie("span",null,Ie(r.nextLink.text),1)])]),_:1},8,["config"])):Me("",!0)],8,Sb)):Me("",!0)}const Ob=Oe(kb,[["render",Tb],["__file","VPPageNav.vue"]]),Pb=he({__name:"VPPage",setup(e,{expose:t}){t(),I1();const n={VPPageMeta:yb,VPPageNav:Ob,get Content(){return wi}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}}),Ib={class:"vp-page"},Lb={class:"theme-default-content","vp-content":""};function Rb(e,t,n,r,o,s){return Y(),ne("main",Ib,[Le(e.$slots,"top"),ie("div",Lb,[Le(e.$slots,"content-top"),ae(r.Content),Le(e.$slots,"content-bottom")]),ae(r.VPPageMeta),ae(r.VPPageNav),Le(e.$slots,"bottom")])}const Db=Oe(Pb,[["render",Rb],["__file","VPPage.vue"]]),Nb=he({__name:"VPSidebarItem",props:{item:{},depth:{default:0}},setup(e,{expose:t}){t();const n=e,{item:r,depth:o}=ai(n),s=zt(),i=fn(),l=F(()=>"collapsible"in r.value&&r.value.collapsible),a=F(()=>Gf(r.value,s)),u=F(()=>({"vp-sidebar-item":!0,"vp-sidebar-heading":o.value===0,active:a.value,collapsible:l.value})),f=F(()=>l.value?a.value:!0),[c,d]=fv(f.value),p=y=>{l.value&&(y.preventDefault(),d())},v=i.afterEach(()=>{Zn(()=>{c.value=f.value})});No(()=>{v()});const _={props:n,item:r,depth:o,route:s,router:i,collapsible:l,isActive:a,itemClass:u,isOpenDefault:f,isOpen:c,toggleIsOpen:d,onClick:p,unregisterRouterHook:v,VPDropdownTransition:ed,get AutoLink(){return tr}};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}}),Vb={class:"vp-sidebar-children"};function Mb(e,t,n,r,o,s){const i=pi("VPSidebarItem",!0);return Y(),ne("li",null,[r.item.link?(Y(),Re(r.AutoLink,{key:0,class:nt(r.itemClass),config:r.item},null,8,["class","config"])):(Y(),ne("p",{key:1,tabindex:"0",class:nt(r.itemClass),onClick:r.onClick,onKeydown:im(r.onClick,["enter"])},[sn(Ie(r.item.text)+" ",1),r.collapsible?(Y(),ne("span",{key:0,class:nt(["arrow",r.isOpen?"down":"right"])},null,2)):Me("",!0)],34)),"children"in r.item&&r.item.children.length?(Y(),Re(r.VPDropdownTransition,{key:2},{default:Ve(()=>[bo(ie("ul",Vb,[(Y(!0),ne(_e,null,rn(r.item.children,l=>(Y(),Re(i,{key:`${r.depth}${l.text}${l.link}`,item:l,depth:r.depth+1},null,8,["item","depth"]))),128))],512),[[Ao,r.isOpen]])]),_:1})):Me("",!0)])}const Fb=Oe(Nb,[["render",Mb],["__file","VPSidebarItem.vue"]]),Bb=he({__name:"VPSidebarItems",setup(e,{expose:t}){t();const n=zt(),r=ji();Be(()=>{je(()=>n.hash,s=>{const i=document.querySelector(".vp-sidebar");if(!i)return;const l=document.querySelector(`.vp-sidebar a.vp-sidebar-item[href="${n.path}${s}"]`);if(!l)return;const{top:a,height:u}=i.getBoundingClientRect(),{top:f,height:c}=l.getBoundingClientRect();fa+u&&l.scrollIntoView(!1)})});const o={route:n,sidebarItems:r,VPSidebarItem:Fb};return Object.defineProperty(o,"__isScriptSetup",{enumerable:!1,value:!0}),o}}),Hb={key:0,class:"vp-sidebar-items"};function $b(e,t,n,r,o,s){return r.sidebarItems.length?(Y(),ne("ul",Hb,[(Y(!0),ne(_e,null,rn(r.sidebarItems,i=>(Y(),Re(r.VPSidebarItem,{key:`${i.text}${i.link}`,item:i},null,8,["item"]))),128))])):Me("",!0)}const Ub=Oe(Bb,[["render",$b],["__file","VPSidebarItems.vue"]]),jb=he({__name:"VPSidebar",setup(e,{expose:t}){t();const n={VPNavbarItems:rd,VPSidebarItems:Ub};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}}),zb={class:"vp-sidebar","vp-sidebar":""};function Kb(e,t,n,r,o,s){return Y(),ne("aside",zb,[ae(r.VPNavbarItems),Le(e.$slots,"top"),ae(r.VPSidebarItems),Le(e.$slots,"bottom")])}const Wb=Oe(jb,[["render",Kb],["__file","VPSidebar.vue"]]),qb=he({__name:"Layout",setup(e,{expose:t}){t();const n=Qn(),r=Et(),o=He(),s=F(()=>r.value.navbar!==!1&&o.value.navbar!==!1),i=ji(),l=ce(!1),a=h=>{l.value=typeof h=="boolean"?h:!l.value},u={x:0,y:0},f=h=>{u.x=h.changedTouches[0].clientX,u.y=h.changedTouches[0].clientY},c=h=>{const b=h.changedTouches[0].clientX-u.x,R=h.changedTouches[0].clientY-u.y;Math.abs(b)>Math.abs(R)&&Math.abs(b)>40&&(b>0&&u.x<=80?a(!0):a(!1))},d=F(()=>r.value.externalLinkIcon??o.value.externalLinkIcon??!0),p=F(()=>[{"no-navbar":!s.value,"no-sidebar":!i.value.length,"sidebar-open":l.value,"external-link-icon":d.value},r.value.pageClass]);let v;Be(()=>{v=fn().afterEach(()=>{a(!1)})}),Vo(()=>{v()});const _=qf(),y=_.resolve,E=_.pending,S={page:n,frontmatter:r,themeLocale:o,shouldShowNavbar:s,sidebarItems:i,isSidebarOpen:l,toggleSidebar:a,touchStart:u,onTouchStart:f,onTouchEnd:c,enableExternalLinkIcon:d,containerClass:p,get unregisterRouterHook(){return v},set unregisterRouterHook(h){v=h},scrollPromise:_,onBeforeEnter:y,onBeforeLeave:E,VPHome:iy,VPNavbar:Qy,VPPage:Db,VPSidebar:Wb};return Object.defineProperty(S,"__isScriptSetup",{enumerable:!1,value:!0}),S}});function Gb(e,t,n,r,o,s){return Y(),ne("div",{class:nt(["vp-theme-container",r.containerClass]),"vp-container":"",onTouchstart:r.onTouchStart,onTouchend:r.onTouchEnd},[Le(e.$slots,"navbar",{},()=>[r.shouldShowNavbar?(Y(),Re(r.VPNavbar,{key:0,onToggleSidebar:r.toggleSidebar},{before:Ve(()=>[Le(e.$slots,"navbar-before")]),after:Ve(()=>[Le(e.$slots,"navbar-after")]),_:3})):Me("",!0)]),ie("div",{class:"vp-sidebar-mask",onClick:t[0]||(t[0]=i=>r.toggleSidebar(!1))}),Le(e.$slots,"sidebar",{},()=>[ae(r.VPSidebar,null,{top:Ve(()=>[Le(e.$slots,"sidebar-top")]),bottom:Ve(()=>[Le(e.$slots,"sidebar-bottom")]),_:3})]),Le(e.$slots,"page",{},()=>[r.frontmatter.home?(Y(),Re(r.VPHome,{key:0})):(Y(),Re(Bo,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:r.onBeforeEnter,onBeforeLeave:r.onBeforeLeave},{default:Ve(()=>[(Y(),Re(r.VPPage,{key:r.page.path},{top:Ve(()=>[Le(e.$slots,"page-top")]),"content-top":Ve(()=>[Le(e.$slots,"page-content-top")]),"content-bottom":Ve(()=>[Le(e.$slots,"page-content-bottom")]),bottom:Ve(()=>[Le(e.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34)}const Yb=Oe(qb,[["render",Gb],["__file","Layout.vue"]]),Xb=he({__name:"NotFound",setup(e,{expose:t}){t();const n=er(),r=He(),o=r.value.notFound??["Not Found"],s=()=>o[Math.floor(Math.random()*o.length)],i=r.value.home??n.value,l=r.value.backToHome??"Back to home",a={routeLocale:n,themeLocale:r,messages:o,getMsg:s,homeLink:i,homeText:l,get RouteLink(){return jo}};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}}),Jb={class:"vp-theme-container","vp-container":""},Zb={class:"page"},Qb={class:"theme-default-content","vp-content":""};function eE(e,t,n,r,o,s){return Y(),ne("div",Jb,[ie("main",Zb,[ie("div",Qb,[t[0]||(t[0]=ie("h1",null,"404",-1)),ie("blockquote",null,Ie(r.getMsg()),1),ae(r.RouteLink,{to:r.homeLink},{default:Ve(()=>[sn(Ie(r.homeText),1)]),_:1},8,["to"])])])])}const tE=Oe(Xb,[["render",eE],["__scopeId","data-v-67c08c1d"],["__file","NotFound.vue"]]),nE=It({enhance({app:e,router:t}){af("Badge")||e.component("Badge",B1);const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...r)=>(await qf().wait(),n(...r))},setup(){A1(),V1()},layouts:{Layout:Yb,NotFound:tE}}),rE=Object.freeze(Object.defineProperty({__proto__:null,default:nE},Symbol.toStringTag,{value:"Module"})),oE=[{title:"Welcome",headers:[{level:2,title:"Who we are",slug:"who-we-are",link:"#who-we-are",children:[]},{level:2,title:"Prerequisites",slug:"prerequisites",link:"#prerequisites",children:[]},{level:2,title:"Useful links",slug:"useful-links",link:"#useful-links",children:[]}],path:"/",pathLocale:"/",extraFields:[]},{title:"Welcome",headers:[{level:2,title:"Who we are",slug:"who-we-are",link:"#who-we-are",children:[]},{level:2,title:"Prerequisites",slug:"prerequisites",link:"#prerequisites",children:[]},{level:2,title:"Useful links",slug:"useful-links",link:"#useful-links",children:[]}],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"",headers:[{level:2,title:"Prerequisites",slug:"prerequisites",link:"#prerequisites",children:[]},{level:2,title:"Liens utiles",slug:"liens-utiles",link:"#liens-utiles",children:[]}],path:"/fr/",pathLocale:"/fr/",extraFields:[]},{title:"📚 Backend development",headers:[{level:2,title:"Ktor",slug:"ktor",link:"#ktor",children:[{level:3,title:"🧪 develop an API with Ktor",slug:"🧪-develop-an-api-with-ktor",link:"#🧪-develop-an-api-with-ktor",children:[]}]},{level:2,title:"Spring framework",slug:"spring-framework",link:"#spring-framework",children:[{level:3,title:"🧪 Spring boot part 1 - develop the same API with Spring Boot",slug:"🧪-spring-boot-part-1-develop-the-same-api-with-spring-boot",link:"#🧪-spring-boot-part-1-develop-the-same-api-with-spring-boot",children:[]},{level:3,title:"🧪 Spring boot part 2 - adding a database",slug:"🧪-spring-boot-part-2-adding-a-database",link:"#🧪-spring-boot-part-2-adding-a-database",children:[]},{level:3,title:"🧪 Spring boot part 2 - adding tests",slug:"🧪-spring-boot-part-2-adding-tests",link:"#🧪-spring-boot-part-2-adding-tests",children:[]}]},{level:2,title:"node.js",slug:"node-js",link:"#node-js",children:[{level:3,title:"🧪 Getting started with Kotlin/JS and Express",slug:"🧪-getting-started-with-kotlin-js-and-express",link:"#🧪-getting-started-with-kotlin-js-and-express",children:[]},{level:3,title:"🧪 Adding a post endpoint and an external Kotlin/JS definition",slug:"🧪-adding-a-post-endpoint-and-an-external-kotlin-js-definition",link:"#🧪-adding-a-post-endpoint-and-an-external-kotlin-js-definition",children:[]},{level:3,title:"🧪 Adding more endpoints",slug:"🧪-adding-more-endpoints",link:"#🧪-adding-more-endpoints",children:[]}]},{level:2,title:"🎯 Solutions",slug:"🎯-solutions",link:"#🎯-solutions",children:[]},{level:2,title:"Other frameworks",slug:"other-frameworks",link:"#other-frameworks",children:[]},{level:2,title:"📖 Further readings",slug:"📖-further-readings",link:"#📖-further-readings",children:[]}],path:"/en/backend-development/",pathLocale:"/en/",extraFields:[]},{title:"📚 Frontend development",headers:[{level:2,title:"Kotlin Multiplatform (KMP)",slug:"kotlin-multiplatform-kmp",link:"#kotlin-multiplatform-kmp",children:[]},{level:2,title:"Kotlin/JS and Kotlin/WASM",slug:"kotlin-js-and-kotlin-wasm",link:"#kotlin-js-and-kotlin-wasm",children:[{level:3,title:"🧪 Kotlin/WASM web app",slug:"🧪-kotlin-wasm-web-app",link:"#🧪-kotlin-wasm-web-app",children:[]},{level:3,title:"Kotlin/JS and Kotlin/WASM common points",slug:"kotlin-js-and-kotlin-wasm-common-points",link:"#kotlin-js-and-kotlin-wasm-common-points",children:[]}]},{level:2,title:"Compose multiplatform",slug:"compose-multiplatform",link:"#compose-multiplatform",children:[{level:3,title:"🧪 Create a Compose multiplatform app",slug:"🧪-create-a-compose-multiplatform-app",link:"#🧪-create-a-compose-multiplatform-app",children:[]},{level:3,title:"🧪 Playing with the Compose multiplatform API",slug:"🧪-playing-with-the-compose-multiplatform-api",link:"#🧪-playing-with-the-compose-multiplatform-api",children:[]}]},{level:2,title:"🎯 Solutions",slug:"🎯-solutions",link:"#🎯-solutions",children:[]},{level:2,title:"📖 Further reading",slug:"📖-further-reading",link:"#📖-further-reading",children:[]}],path:"/en/front-development/",pathLocale:"/en/",extraFields:[]},{title:"📚 Kotlin language features",headers:[{level:2,title:"Basic features",slug:"basic-features",link:"#basic-features",children:[{level:3,title:"Basic constructs (variables, control flow)",slug:"basic-constructs-variables-control-flow",link:"#basic-constructs-variables-control-flow",children:[]},{level:3,title:"Functions",slug:"functions",link:"#functions",children:[]},{level:3,title:"Null safety",slug:"null-safety",link:"#null-safety",children:[]},{level:3,title:"Enumerations",slug:"enumerations",link:"#enumerations",children:[]},{level:3,title:"🧪 Exercises",slug:"🧪-exercises",link:"#🧪-exercises",children:[]}]},{level:2,title:"Intermediate features",slug:"intermediate-features",link:"#intermediate-features",children:[{level:3,title:"Object oriented programming",slug:"object-oriented-programming",link:"#object-oriented-programming",children:[]},{level:3,title:"Data class",slug:"data-class",link:"#data-class",children:[]},{level:3,title:"Functional programming",slug:"functional-programming",link:"#functional-programming",children:[]},{level:3,title:"Kotlin and Java interoperability",slug:"kotlin-and-java-interoperability",link:"#kotlin-and-java-interoperability",children:[]},{level:3,title:"🧪 Exercises",slug:"🧪-exercises-1",link:"#🧪-exercises-1",children:[]}]},{level:2,title:"📖 Further reading",slug:"📖-further-reading",link:"#📖-further-reading",children:[]}],path:"/en/kotlin-features/",pathLocale:"/en/",extraFields:[]},{title:"📚 Advanced and other Kotlin features",headers:[{level:2,title:"Delegated properties",slug:"delegated-properties",link:"#delegated-properties",children:[]},{level:2,title:"Concurrency and Coroutines",slug:"concurrency-and-coroutines",link:"#concurrency-and-coroutines",children:[]},{level:2,title:"Function literal with receiver and Type-safe builders",slug:"function-literal-with-receiver-and-type-safe-builders",link:"#function-literal-with-receiver-and-type-safe-builders",children:[]},{level:2,title:"🧪 Exercises",slug:"🧪-exercises",link:"#🧪-exercises",children:[]}],path:"/en/kotlin-features-advanced/",pathLocale:"/en/",extraFields:[]},{title:"🛠 Let's make a cross-plaform app !",headers:[],path:"/en/other-technologies/",pathLocale:"/en/",extraFields:[]},{title:"🚀 Presentation of Kotlin",headers:[{level:2,title:"Some features",slug:"some-features",link:"#some-features",children:[]},{level:2,title:"History",slug:"history",link:"#history",children:[]},{level:2,title:"Some numbers and facts",slug:"some-numbers-and-facts",link:"#some-numbers-and-facts",children:[]},{level:2,title:"Why switch from Java to Kotlin",slug:"why-switch-from-java-to-kotlin",link:"#why-switch-from-java-to-kotlin",children:[]},{level:2,title:"A decision tree to help you decide if you should use Kotlin",slug:"a-decision-tree-to-help-you-decide-if-you-should-use-kotlin",link:"#a-decision-tree-to-help-you-decide-if-you-should-use-kotlin",children:[]},{level:2,title:"Prerequisites",slug:"prerequisites",link:"#prerequisites",children:[]},{level:2,title:"📖 Further reading",slug:"📖-further-reading",link:"#📖-further-reading",children:[]}],path:"/en/presentation/",pathLocale:"/en/",extraFields:[]},{title:"📅 Workshops",headers:[{level:2,title:"(2023) Android makers : Kotlin Beyond Android",slug:"_2023-android-makers-kotlin-beyond-android",link:"#_2023-android-makers-kotlin-beyond-android",children:[{level:3,title:"Link",slug:"link",link:"#link",children:[]},{level:3,title:"Agenda",slug:"agenda",link:"#agenda",children:[]}]},{level:2,title:"(2023) JNation : Let's discover the possibilities of Kotlin",slug:"_2023-jnation-let-s-discover-the-possibilities-of-kotlin",link:"#_2023-jnation-let-s-discover-the-possibilities-of-kotlin",children:[{level:3,title:"Link",slug:"link-1",link:"#link-1",children:[]},{level:3,title:"Agenda",slug:"agenda-1",link:"#agenda-1",children:[]}]},{level:2,title:"(2023) Mobile DevOps summit",slug:"_2023-mobile-devops-summit",link:"#_2023-mobile-devops-summit",children:[{level:3,title:"Agenda",slug:"agenda-2",link:"#agenda-2",children:[]}]},{level:2,title:"(2024) MiXit",slug:"_2024-mixit",link:"#_2024-mixit",children:[{level:3,title:"Agenda",slug:"agenda-3",link:"#agenda-3",children:[]}]}],path:"/en/workshops/",pathLocale:"/en/",extraFields:[]},{title:"📚 Développement du backend",headers:[{level:2,title:"Ktor",slug:"ktor",link:"#ktor",children:[{level:3,title:"TP : développer une API avec Ktor",slug:"tp-developper-une-api-avec-ktor",link:"#tp-developper-une-api-avec-ktor",children:[]}]},{level:2,title:"node.js",slug:"node-js",link:"#node-js",children:[{level:3,title:"TP : API Rest avec Kotlin/JS et Express",slug:"tp-api-rest-avec-kotlin-js-et-express",link:"#tp-api-rest-avec-kotlin-js-et-express",children:[]}]},{level:2,title:"Spring framework",slug:"spring-framework",link:"#spring-framework",children:[{level:3,title:"TP : Spring boot part 1 - développer la même API avec Spring Boot",slug:"tp-spring-boot-part-1-developper-la-meme-api-avec-spring-boot",link:"#tp-spring-boot-part-1-developper-la-meme-api-avec-spring-boot",children:[]},{level:3,title:"TP : Spring boot partie 2 - ajouter une base de données",slug:"tp-spring-boot-partie-2-ajouter-une-base-de-donnees",link:"#tp-spring-boot-partie-2-ajouter-une-base-de-donnees",children:[]},{level:3,title:"TP : Spring boot partie 3 - ajouter des tests",slug:"tp-spring-boot-partie-3-ajouter-des-tests",link:"#tp-spring-boot-partie-3-ajouter-des-tests",children:[]},{level:3,title:"Projets terminés",slug:"projets-termines",link:"#projets-termines",children:[]}]},{level:2,title:"Aller plus loin",slug:"aller-plus-loin",link:"#aller-plus-loin",children:[]},{level:2,title:"Lien et références",slug:"lien-et-references",link:"#lien-et-references",children:[]}],path:"/fr/backend-development/",pathLocale:"/fr/",extraFields:[]},{title:"📚 Développement frontend",headers:[{level:2,title:"KMP",slug:"kmp",link:"#kmp",children:[]},{level:2,title:"Kotlin/JS et Kotlin/WASM",slug:"kotlin-js-et-kotlin-wasm",link:"#kotlin-js-et-kotlin-wasm",children:[{level:3,title:"🧪 Application web Kotlin/WASM",slug:"🧪-application-web-kotlin-wasm",link:"#🧪-application-web-kotlin-wasm",children:[]},{level:3,title:"🧪 Application web KotlinJS",slug:"🧪-application-web-kotlinjs",link:"#🧪-application-web-kotlinjs",children:[]}]},{level:2,title:"Compose",slug:"compose",link:"#compose",children:[{level:3,title:"🧪 Compose Web",slug:"🧪-compose-web",link:"#🧪-compose-web",children:[]},{level:3,title:"🧪 Compose desktop + Android app",slug:"🧪-compose-desktop-android-app",link:"#🧪-compose-desktop-android-app",children:[]}]},{level:2,title:"Pour aller plus loin",slug:"pour-aller-plus-loin",link:"#pour-aller-plus-loin",children:[]}],path:"/fr/front-development/",pathLocale:"/fr/",extraFields:[]},{title:"📚 Fonctionnalités du langage Kotlin",headers:[{level:2,title:"Caractéristiques de base",slug:"caracteristiques-de-base",link:"#caracteristiques-de-base",children:[{level:3,title:"Constructions de base (variables, flux de contrôle)",slug:"constructions-de-base-variables-flux-de-controle",link:"#constructions-de-base-variables-flux-de-controle",children:[]},{level:3,title:"Les fonctions",slug:"les-fonctions",link:"#les-fonctions",children:[]},{level:3,title:"Null safety",slug:"null-safety",link:"#null-safety",children:[]},{level:3,title:"Énumérations",slug:"enumerations",link:"#enumerations",children:[]},{level:3,title:"Exercices",slug:"exercices",link:"#exercices",children:[]}]},{level:2,title:"Fonctionnalités intermédiaires",slug:"fonctionnalites-intermediaires",link:"#fonctionnalites-intermediaires",children:[{level:3,title:"Programmation orientée objet",slug:"programmation-orientee-objet",link:"#programmation-orientee-objet",children:[]},{level:3,title:"Data class",slug:"data-class",link:"#data-class",children:[]},{level:3,title:"Programmation fonctionnelle",slug:"programmation-fonctionnelle",link:"#programmation-fonctionnelle",children:[]},{level:3,title:"Kotlin and Java interoperability",slug:"kotlin-and-java-interoperability",link:"#kotlin-and-java-interoperability",children:[]},{level:3,title:"Exercices",slug:"exercices-1",link:"#exercices-1",children:[]}]},{level:2,title:"Plus d'exercices et de lecture",slug:"plus-d-exercices-et-de-lecture",link:"#plus-d-exercices-et-de-lecture",children:[]}],path:"/fr/kotlin-features/",pathLocale:"/fr/",extraFields:[]},{title:"📚 Fonctionnalités avancées de Kotlin",headers:[{level:2,title:"Propriétés déléguées",slug:"proprietes-deleguees",link:"#proprietes-deleguees",children:[]},{level:2,title:"Concurrence et coroutines",slug:"concurrence-et-coroutines",link:"#concurrence-et-coroutines",children:[]},{level:2,title:"Littéral de fonction avec récepteur et constructeurs de type sécurisé",slug:"litteral-de-fonction-avec-recepteur-et-constructeurs-de-type-securise",link:"#litteral-de-fonction-avec-recepteur-et-constructeurs-de-type-securise",children:[]},{level:2,title:"Exercises",slug:"exercises",link:"#exercises",children:[{level:3,title:"Exercise 1",slug:"exercise-1",link:"#exercise-1",children:[]}]}],path:"/fr/kotlin-features-advanced/",pathLocale:"/fr/",extraFields:[]},{title:"🛠 Construisons une app multiplateforme !",headers:[],path:"/fr/other-technologies/",pathLocale:"/fr/",extraFields:[]},{title:"🚀 Présentation de Kotlin",headers:[{level:2,title:"Certaines fonctionnalités",slug:"certaines-fonctionnalites",link:"#certaines-fonctionnalites",children:[]},{level:2,title:"Histoire",slug:"histoire",link:"#histoire",children:[]},{level:2,title:"Quelques chiffres et faits",slug:"quelques-chiffres-et-faits",link:"#quelques-chiffres-et-faits",children:[]},{level:2,title:"Pourquoi passer de Java à Kotlin",slug:"pourquoi-passer-de-java-a-kotlin",link:"#pourquoi-passer-de-java-a-kotlin",children:[]},{level:2,title:"Sources et plus de lecture",slug:"sources-et-plus-de-lecture",link:"#sources-et-plus-de-lecture",children:[]}],path:"/fr/presentation/",pathLocale:"/fr/",extraFields:[]},{title:"📅 Workshops",headers:[{level:2,title:"Android makers 2023: Kotlin Beyond Android",slug:"android-makers-2023-kotlin-beyond-android",link:"#android-makers-2023-kotlin-beyond-android",children:[{level:3,title:"Liens",slug:"liens",link:"#liens",children:[]},{level:3,title:"Agenda",slug:"agenda",link:"#agenda",children:[]}]},{level:2,title:"Mobile DevOps summit 2023",slug:"mobile-devops-summit-2023",link:"#mobile-devops-summit-2023",children:[{level:3,title:"Agenda",slug:"agenda-1",link:"#agenda-1",children:[]}]},{level:2,title:"Devoxx Morocco 2023",slug:"devoxx-morocco-2023",link:"#devoxx-morocco-2023",children:[{level:3,title:"Agenda",slug:"agenda-2",link:"#agenda-2",children:[]}]},{level:2,title:"(2024) MiXit",slug:"_2024-mixit",link:"#_2024-mixit",children:[{level:3,title:"Agenda",slug:"agenda-3",link:"#agenda-3",children:[]}]}],path:"/fr/workshops/",pathLocale:"/fr/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],sE=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,iE=(e,t)=>t.some(n=>{if(mt(n))return n===e.key;const{key:r,ctrl:o=!1,shift:s=!1,alt:i=!1}=n;return r===e.key&&o===e.ctrlKey&&s===e.shiftKey&&i===e.altKey}),lE=/[^\x00-\x7F]/,aE=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),cu=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),fu=(e,t)=>{const n=t.join(" "),r=aE(e);if(lE.test(e))return r.some(s=>n.toLowerCase().includes(s));const o=e.endsWith(" ");return new RegExp(`${r.map((s,i)=>r.length===i+1&&!o?`(?=.*\\b${cu(s)})`:`(?=.*\\b${cu(s)}\\b)`).join("")}.+`,"gi").test(n)},uE=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const n=r=>{e.value&&iE(r,t.value)&&!sE(r.target)&&(r.preventDefault(),e.value.focus())};Be(()=>{document.addEventListener("keydown",n)}),No(()=>{document.removeEventListener("keydown",n)})},cE=ce(oE),fE=()=>cE,dE=({searchIndex:e,routeLocale:t,query:n,maxSuggestions:r})=>{const o=F(()=>e.value.filter(s=>s.pathLocale===t.value));return F(()=>{const s=n.value.trim().toLowerCase();if(!s)return[];const i=[],l=(a,u)=>{fu(s,[u.title])&&i.push({link:`${a.path}#${u.slug}`,title:a.title,header:u.title});for(const f of u.children){if(i.length>=r.value)return;l(a,f)}};for(const a of o.value){if(i.length>=r.value)break;if(fu(s,[a.title,...a.extraFields])){i.push({link:a.path,title:a.title});continue}for(const u of a.headers){if(i.length>=r.value)break;l(a,u)}}return i})},pE=e=>{const t=ce(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}},hE=he({name:"SearchBox",props:{locales:{type:Object,default:()=>({})},hotKeys:{type:Array,default:()=>[]},maxSuggestions:{type:Number,default:5}},setup(e){const{locales:t,hotKeys:n,maxSuggestions:r}=ai(e),o=fn(),s=er(),i=fE(),l=ce(null),a=ce(!1),u=ce(""),f=F(()=>t.value[s.value]??{}),c=dE({searchIndex:i,routeLocale:s,query:u,maxSuggestions:r}),{focusIndex:d,focusNext:p,focusPrev:v}=pE(c);uE({input:l,hotKeys:n});const _=F(()=>a.value&&!!c.value.length),y=()=>{_.value&&v()},E=()=>{_.value&&p()},S=h=>{if(!_.value)return;const b=c.value[h];b&&o.push(b.link).then(()=>{u.value="",d.value=0})};return()=>le("form",{class:"search-box",role:"search"},[le("input",{ref:l,type:"search",placeholder:f.value.placeholder,autocomplete:"off",spellcheck:!1,value:u.value,onFocus:()=>{a.value=!0},onBlur:()=>{a.value=!1},onInput:h=>{u.value=h.target.value},onKeydown:h=>{switch(h.key){case"ArrowUp":{y();break}case"ArrowDown":{E();break}case"Enter":{h.preventDefault(),S(d.value);break}}}}),_.value&&le("ul",{class:"suggestions",onMouseleave:()=>{d.value=-1}},c.value.map(({link:h,title:b,header:R},j)=>le("li",{class:["suggestion",{focus:d.value===j}],onMouseenter:()=>{d.value=j},onMousedown:()=>{S(j)}},le("a",{href:h,onClick:M=>{M.preventDefault()}},[le("span",{class:"page-title"},b),R&&le("span",{class:"page-header"},`> ${R}`)]))))])}});var mE=["s","/"],gE={"/en/":{placeholder:"Search"},"/fr/":{placeholder:"Rechercher"}};const vE=gE,_E=mE,yE=5;var bE=It({enhance({app:e}){e.component("SearchBox",t=>le(hE,{locales:vE,hotKeys:_E,maxSuggestions:yE,...t}))}});const EE=Object.freeze(Object.defineProperty({__proto__:null,default:bE},Symbol.toStringTag,{value:"Module"}));function kE(e){return{all:e=e||new Map,on:function(t,n){var r=e.get(t);r?r.push(n):e.set(t,[n])},off:function(t,n){var r=e.get(t);r&&(n?r.splice(r.indexOf(n)>>>0,1):e.set(t,[]))},emit:function(t,n){var r=e.get(t);r&&r.slice().map(function(o){o(n)}),(r=e.get("*"))&&r.slice().map(function(o){o(t,n)})}}}const od=Symbol(""),SE=()=>{const e=qe(od);if(!e)throw new Error("usePwaEvent() is called without provider.");return e},wE=()=>{navigator.serviceWorker.getRegistration().then(e=>{e!=null&&e.active&&e.addEventListener("updatefound",()=>{window.location.reload(!0)})})},AE=async(e,t={},n=!0)=>{const{register:r}=await De(async()=>{const{register:o}=await import("./index-DTEEl-sV.js");return{register:o}},[]);r(e,{ready(o){var s;n&&console.info("[Service Worker]: active"),(s=t.ready)==null||s.call(t,o)},registered(o){var s;n&&console.log("[Service Worker]: registered"),(s=t.registered)==null||s.call(t,o)},cached(o){var s;n&&console.log("[Service Worker]: cached"),(s=t.cached)==null||s.call(t,o)},async updatefound(o){var s;await navigator.serviceWorker.getRegistration()&&(n&&console.log("[Service Worker]: update found"),(s=t.updatefound)==null||s.call(t,o))},updated(o){var s;n&&console.log("[Service Worker]: updated"),(s=t.updated)==null||s.call(t,o)},offline(){var o;n&&console.log("[Service Worker]: offline"),(o=t.offline)==null||o.call(t)},error(o){var s;n&&console.error("[Service Worker]: ",o),(s=t.error)==null||s.call(t,o)}})},CE=async(e,t)=>AE(zo(e),{ready(n){t.emit("ready",n)},registered(n){t.emit("registered",n)},cached(n){t.emit("cached",n)},updatefound(n){t.emit("updatefound",n)},updated(n){const r="service-worker-version",o=Number(localStorage.getItem(r)||0);localStorage.setItem(r,(o+1).toString()),localStorage.removeItem("manifest"),t.emit("updated",n)},offline(){t.emit("offline")},error(n){t.emit("error",n)}}),xE=(e,t=!1)=>{const n=kE();en(od,n),Be(async()=>{if(!("serviceWorker"in navigator))return;let r=!1;navigator.serviceWorker.controller&&navigator.serviceWorker.addEventListener("controllerchange",()=>{r||(r=!0,window.location.reload())}),t&&wE(),await CE(e,n)})},TE=()=>{Be(()=>{if(window.matchMedia("(display-mode: standalone)").matches){const e=document.head.querySelector('meta[name="viewport"]');if(e){e.setAttribute("content","width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover");return}const t=document.createElement("meta");t.name="viewport",t.content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover",document.head.appendChild(t)}})},sd=({name:e="",color:t="currentColor"},{slots:n})=>le("svg",{xmlns:"http://www.w3.org/2000/svg",class:["icon",`${e}-icon`],viewBox:"0 0 1024 1024",fill:t,"aria-label":`${e} icon`},n.default());sd.displayName="SVGWrapper";const id=()=>le(sd,{name:"update"},()=>le("path",{d:"M949.949 146.25v255.826c0 21.981-13.989 35.97-35.97 35.97H658.154c-13.988 0-25.983-7.992-33.973-21.981-5.997-13.989-4-27.977 7.991-39.97l79.942-77.946c-55.954-51.973-121.918-77.955-199.863-77.955-37.975 0-75.95 8.002-113.924 21.99-37.975 15.985-67.948 37.976-91.934 63.957-25.982 23.987-47.973 53.96-63.957 91.934-29.983 73.955-29.983 153.895 0 227.85 15.984 37.976 37.975 67.947 63.957 91.934 23.986 25.982 53.959 47.973 91.934 63.956 37.974 13.989 75.95 21.991 113.924 21.991 45.967 0 87.942-9.998 127.913-29.982 41.976-17.99 75.951-45.967 101.931-83.943 7.993-4 11.994-5.995 13.989-5.995 5.997 0 9.998 1.994 13.988 5.995l77.958 77.946c3.989 4 5.986 7.993 5.986 11.994 0 1.994-1.996 5.995-3.99 11.994-43.973 51.962-93.941 91.934-151.9 117.914-53.958 25.983-115.92 39.972-185.874 39.972-61.961 0-119.921-11.984-169.89-33.973-57.96-25.985-105.923-57.963-139.896-93.943-35.98-33.972-67.958-81.936-93.94-139.897-45.967-101.93-45.967-237.846 0-339.777 25.982-57.96 57.96-105.923 93.94-139.896 33.973-35.98 81.936-67.958 139.896-93.94 49.968-21.99 107.928-33.974 169.89-33.974 55.963 0 109.923 9.988 161.885 29.973 53.97 21.99 101.933 51.963 139.908 89.938l73.954-73.944c9.987-9.998 23.987-13.988 39.971-8.002 13.988 8.002 21.98 19.995 21.98 33.984z"}));id.displayName="UpdateIcon";const OE=he({name:"PwaFoundPopup",props:{locales:{type:Object,required:!0}},slots:Object,setup(e,{slots:t}){const n=Oi(e.locales),r=ce(!1),o=()=>{r.value&&(window.location.reload(!0),r.value=!1)};return Be(()=>{const s=SE();s.on("updatefound",()=>{navigator.serviceWorker.getRegistration().then(i=>{i!=null&&i.active&&(r.value=!0)})}),s.on("updated",()=>{r.value=!1})}),()=>le(Bo,{name:"popup"},()=>{var s;return((s=t.default)==null?void 0:s.call(t,{found:r.value,refresh:o}))??(r.value?le("button",{type:"button",class:"sw-hint-popup",tabindex:0,onClick:()=>{o()}},[n.value.hint,le("span",{class:"icon-wrapper"},le(id))]):null)})}}),PE={"/en/":{install:"Install",iOSInstall:"Tap the share button and then 'Add to Home Screen'",cancel:"Cancel",close:"Close",prevImage:"Previous Image",nextImage:"Next Image",desc:"Description",feature:"Key Features",explain:"This app can be installed on your PC or mobile device. This will allow this web app to look and behave like any other installed app. You will find it in your app lists and be able to pin it to your home screen, start menus or task bars. This installed web app will also be able to safely interact with other apps and your operating system. ",hint:"New content found.",update:"New content is available."},"/fr/":{install:"Installer",iOSInstall:"Appuyez sur le bouton partager puis 'Ajouter à l'écran d'accueil'",cancel:"Annuler",close:"Fermer",prevImage:"Image précédente",nextImage:"Image suivante",desc:"Description",feature:"Composants clés",explain:"Cette app peut être installée sur PC ou smartphone. Cela permettra de rendre cette page web comme n'importe quelle autre application. Vous la trouverez dans votre liste d'application et serez capable de la pin sur votre écran principal et divers menus. L'application web installée sera capable d'interagir avec les autres applications et le système d'exploitation.",hint:"New content found.",update:"New content is available."},"/":{install:"Install",iOSInstall:"Tap the share button and then 'Add to Home Screen'",cancel:"Cancel",close:"Close",prevImage:"Previous Image",nextImage:"Next Image",desc:"Description",feature:"Key Features",explain:"This app can be installed on your PC or mobile device. This will allow this web app to look and behave like any other installed app. You will find it in your app lists and be able to pin it to your home screen, start menus or task bars. This installed web app will also be able to safely interact with other apps and your operating system. ",hint:"New content found.",update:"New content is available."}},IE=It({setup:()=>{xE("service-worker.js",!1),TE()},rootComponents:[()=>le(OE,{locales:PE})]}),LE=Object.freeze(Object.defineProperty({__proto__:null,default:IE},Symbol.toStringTag,{value:"Module"}));/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */var _n=Object.assign||function(e){for(var t=1;t1&&arguments[1]!==void 0?arguments[1]:{},r=window.Promise||function(A){function D(){}A(D,D)},o=function(A){var D=A.target;if(D===U){v();return}h.indexOf(D)!==-1&&_({target:D})},s=function(){if(!(R||!w.original)){var A=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(j-A)>M.scrollOffset&&setTimeout(v,150)}},i=function(A){var D=A.key||A.keyCode;(D==="Escape"||D==="Esc"||D===27)&&v()},l=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},D=A;if(A.background&&(U.style.background=A.background),A.container&&A.container instanceof Object&&(D.container=_n({},M.container,A.container)),A.template){var J=mo(A.template)?A.template:document.querySelector(A.template);D.template=J}return M=_n({},M,D),h.forEach(function(ee){ee.dispatchEvent(Pn("medium-zoom:update",{detail:{zoom:x}}))}),x},a=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(_n({},M,A))},u=function(){for(var A=arguments.length,D=Array(A),J=0;J0?D.reduce(function(P,N){return[].concat(P,pu(N))},[]):h;return ee.forEach(function(P){P.classList.remove("medium-zoom-image"),P.dispatchEvent(Pn("medium-zoom:detach",{detail:{zoom:x}}))}),h=h.filter(function(P){return ee.indexOf(P)===-1}),x},c=function(A,D){var J=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return h.forEach(function(ee){ee.addEventListener("medium-zoom:"+A,D,J)}),b.push({type:"medium-zoom:"+A,listener:D,options:J}),x},d=function(A,D){var J=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return h.forEach(function(ee){ee.removeEventListener("medium-zoom:"+A,D,J)}),b=b.filter(function(ee){return!(ee.type==="medium-zoom:"+A&&ee.listener.toString()===D.toString())}),x},p=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},D=A.target,J=function(){var P={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},N=void 0,K=void 0;if(M.container)if(M.container instanceof Object)P=_n({},P,M.container),N=P.width-P.left-P.right-M.margin*2,K=P.height-P.top-P.bottom-M.margin*2;else{var ue=mo(M.container)?M.container:document.querySelector(M.container),ye=ue.getBoundingClientRect(),Te=ye.width,be=ye.height,Ze=ye.left,gt=ye.top;P=_n({},P,{width:Te,height:be,left:Ze,top:gt})}N=N||P.width-M.margin*2,K=K||P.height-M.margin*2;var Qe=w.zoomedHd||w.original,et=du(Qe)?N:Qe.naturalWidth||N,T=du(Qe)?K:Qe.naturalHeight||K,q=Qe.getBoundingClientRect(),z=q.top,Z=q.left,de=q.width,Ee=q.height,m=Math.min(Math.max(de,et),N)/de,g=Math.min(Math.max(Ee,T),K)/Ee,k=Math.min(m,g),O=(-Z+(N-de)/2+M.margin+P.left)/k,C=(-z+(K-Ee)/2+M.margin+P.top)/k,L="scale("+k+") translate3d("+O+"px, "+C+"px, 0)";w.zoomed.style.transform=L,w.zoomedHd&&(w.zoomedHd.style.transform=L)};return new r(function(ee){if(D&&h.indexOf(D)===-1){ee(x);return}var P=function Te(){R=!1,w.zoomed.removeEventListener("transitionend",Te),w.original.dispatchEvent(Pn("medium-zoom:opened",{detail:{zoom:x}})),ee(x)};if(w.zoomed){ee(x);return}if(D)w.original=D;else if(h.length>0){var N=h;w.original=N[0]}else{ee(x);return}if(w.original.dispatchEvent(Pn("medium-zoom:open",{detail:{zoom:x}})),j=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,R=!0,w.zoomed=NE(w.original),document.body.appendChild(U),M.template){var K=mo(M.template)?M.template:document.querySelector(M.template);w.template=document.createElement("div"),w.template.appendChild(K.content.cloneNode(!0)),document.body.appendChild(w.template)}if(w.original.parentElement&&w.original.parentElement.tagName==="PICTURE"&&w.original.currentSrc&&(w.zoomed.src=w.original.currentSrc),document.body.appendChild(w.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),w.original.classList.add("medium-zoom-image--hidden"),w.zoomed.classList.add("medium-zoom-image--opened"),w.zoomed.addEventListener("click",v),w.zoomed.addEventListener("transitionend",P),w.original.getAttribute("data-zoom-src")){w.zoomedHd=w.zoomed.cloneNode(),w.zoomedHd.removeAttribute("srcset"),w.zoomedHd.removeAttribute("sizes"),w.zoomedHd.removeAttribute("loading"),w.zoomedHd.src=w.zoomed.getAttribute("data-zoom-src"),w.zoomedHd.onerror=function(){clearInterval(ue),console.warn("Unable to reach the zoom image target "+w.zoomedHd.src),w.zoomedHd=null,J()};var ue=setInterval(function(){w.zoomedHd.complete&&(clearInterval(ue),w.zoomedHd.classList.add("medium-zoom-image--opened"),w.zoomedHd.addEventListener("click",v),document.body.appendChild(w.zoomedHd),J())},10)}else if(w.original.hasAttribute("srcset")){w.zoomedHd=w.zoomed.cloneNode(),w.zoomedHd.removeAttribute("sizes"),w.zoomedHd.removeAttribute("loading");var ye=w.zoomedHd.addEventListener("load",function(){w.zoomedHd.removeEventListener("load",ye),w.zoomedHd.classList.add("medium-zoom-image--opened"),w.zoomedHd.addEventListener("click",v),document.body.appendChild(w.zoomedHd),J()})}else J()})},v=function(){return new r(function(A){if(R||!w.original){A(x);return}var D=function J(){w.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(w.zoomed),w.zoomedHd&&document.body.removeChild(w.zoomedHd),document.body.removeChild(U),w.zoomed.classList.remove("medium-zoom-image--opened"),w.template&&document.body.removeChild(w.template),R=!1,w.zoomed.removeEventListener("transitionend",J),w.original.dispatchEvent(Pn("medium-zoom:closed",{detail:{zoom:x}})),w.original=null,w.zoomed=null,w.zoomedHd=null,w.template=null,A(x)};R=!0,document.body.classList.remove("medium-zoom--opened"),w.zoomed.style.transform="",w.zoomedHd&&(w.zoomedHd.style.transform=""),w.template&&(w.template.style.transition="opacity 150ms",w.template.style.opacity=0),w.original.dispatchEvent(Pn("medium-zoom:close",{detail:{zoom:x}})),w.zoomed.addEventListener("transitionend",D)})},_=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},D=A.target;return w.original?v():p({target:D})},y=function(){return M},E=function(){return h},S=function(){return w.original},h=[],b=[],R=!1,j=0,M=n,w={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?M=t:(t||typeof t=="string")&&u(t),M=_n({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},M);var U=DE(M.background);document.addEventListener("click",o),document.addEventListener("keyup",i),document.addEventListener("scroll",s),window.addEventListener("resize",v);var x={open:p,close:v,toggle:_,update:l,clone:a,attach:u,detach:f,on:c,off:d,getOptions:y,getImages:E,getZoomedImage:S};return x};function ME(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(typeof document>"u")){var r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",n==="top"&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}var FE=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";ME(FE);const BE=Symbol("mediumZoom");var HE={};const $E="[vp-content] > img, [vp-content] :not(a) > img",UE=HE,jE=500,zE=It({enhance({app:e,router:t}){const n=VE(UE);n.refresh=(r=$E)=>{n.detach(),n.attach(r)},e.provide(BE,n),t.afterEach(()=>{uf(jE).then(()=>{n.refresh()})})}}),KE=Object.freeze(Object.defineProperty({__proto__:null,default:zE},Symbol.toStringTag,{value:"Module"})),WE=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),qE={enhance:({app:e})=>{}},GE=Object.freeze(Object.defineProperty({__proto__:null,default:qE},Symbol.toStringTag,{value:"Module"})),ao=[Pv,Hv,qv,Yv,t_,o_,c_,k1,rE,EE,LE,KE,WE,GE].map(e=>e.default).filter(Boolean),YE=JSON.parse(`{"base":"/learning-kotlin/","lang":"en-US","title":"","description":"","head":[["link",{"rel":"icon","href":"/learning-kotlin/favicon.ico"}],["link",{"rel":"manifest","href":"/learning-kotlin/manifest.webmanifest"}],["meta",{"name":"theme-color","content":"#2176d6"}]],"locales":{"/en/":{"lang":"en-US","title":"Learning Kotlin","description":"Learning Kotlin"},"/fr/":{"lang":"fr-FR","title":"Apprendre Kotlin","description":"Une formation d'introduction à Kotlin"}}}`);var mr=Ot(YE),XE=ug,JE=()=>{const e=jg({history:XE(Rc("/learning-kotlin/")),routes:[{name:"vuepress-route",path:"/:catchAll(.*)",components:{}}],scrollBehavior:(t,n,r)=>r||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{if(t.path!==n.path||n===Nt){const r=Ir(t.fullPath);if(r.path!==t.fullPath)return r.path;const o=await r.loader();t.meta={...r.meta,_pageChunk:o}}else t.path===n.path&&(t.meta=n.meta)}),e},ZE=e=>{e.component("ClientOnly",Si),e.component("Content",wi),e.component("RouteLink",jo)},QE=(e,t,n)=>{const r=F(()=>t.currentRoute.value.path),o=tp((y,E)=>({get(){return y(),t.currentRoute.value.meta._pageChunk},set(S){t.currentRoute.value.meta._pageChunk=S,E()}})),s=F(()=>gn.resolveLayouts(n)),i=F(()=>gn.resolveRouteLocale(mr.value.locales,r.value)),l=F(()=>gn.resolveSiteLocaleData(mr.value,i.value)),a=F(()=>o.value.comp),u=F(()=>o.value.data),f=F(()=>u.value.frontmatter),c=F(()=>gn.resolvePageHeadTitle(u.value,l.value)),d=F(()=>gn.resolvePageHead(c.value,f.value,l.value)),p=F(()=>gn.resolvePageLang(u.value,l.value)),v=F(()=>gn.resolvePageLayout(u.value,s.value)),_={layouts:s,pageData:u,pageComponent:a,pageFrontmatter:f,pageHead:d,pageHeadTitle:c,pageLang:p,pageLayout:v,redirects:Fs,routeLocale:i,routePath:r,routes:$n,siteData:mr,siteLocaleData:l};return e.provide(Ei,_),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>f.value},$head:{get:()=>d.value},$headTitle:{get:()=>c.value},$lang:{get:()=>p.value},$page:{get:()=>u.value},$routeLocale:{get:()=>i.value},$site:{get:()=>mr.value},$siteLocale:{get:()=>l.value},$withBase:{get:()=>zo}}),_},ek=([e,t,n=""])=>{const r=Object.entries(t).map(([l,a])=>mt(a)?`[${l}=${JSON.stringify(a)}]`:a?`[${l}]`:"").join(""),o=`head > ${e}${r}`;return Array.from(document.querySelectorAll(o)).find(l=>l.innerText===n)??null},tk=([e,t,n])=>{if(!mt(e))return null;const r=document.createElement(e);return _i(t)&&Object.entries(t).forEach(([o,s])=>{mt(s)?r.setAttribute(o,s):s&&r.setAttribute(o,"")}),mt(n)&&r.appendChild(document.createTextNode(n)),r},nk=()=>{const e=Wg(),t=qg();let n=[];const r=()=>{e.value.forEach(i=>{const l=ek(i);l&&n.push(l)})},o=()=>{const i=[];return e.value.forEach(l=>{const a=tk(l);a&&i.push(a)}),i},s=()=>{document.documentElement.lang=t.value;const i=o();n.forEach((l,a)=>{const u=i.findIndex(f=>l.isEqualNode(f));u===-1?(l.remove(),delete n[a]):i.splice(u,1)}),i.forEach(l=>document.head.appendChild(l)),n=[...n.filter(l=>!!l),...i]};en(Xg,s),Be(()=>{r(),je(e,s,{immediate:!1})})},rk=um,ok=async()=>{var r;const e=rk({name:"Vuepress",setup(){var i;nk();for(const l of ao)(i=l.setup)==null||i.call(l);const o=ao.flatMap(({rootComponents:l=[]})=>l.map(a=>le(a))),s=Gg();return()=>[le(s.value),o]}}),t=JE();ZE(e);const n=QE(e,t,ao);{const{setupDevtools:o}=await De(async()=>{const{setupDevtools:s}=await import("./setupDevtools-7MC2TMWH-TJgRKbnT.js");return{setupDevtools:s}},[]);o(e,n)}for(const o of ao)await((r=o.enhance)==null?void 0:r.call(o,{app:e,router:t,siteData:mr}));return e.use(t),{app:e,router:t}};ok().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{Oe as _,kh as a,ae as b,ne as c,ok as createVueApp,Ve as d,ie as e,sn as f,Y as o,pi as r,R0 as s,je as w}; diff --git a/assets/compose-multiplaform-Dfyu_rxB.gif b/assets/compose-multiplaform-Dfyu_rxB.gif new file mode 100644 index 0000000..ffa4079 Binary files /dev/null and b/assets/compose-multiplaform-Dfyu_rxB.gif differ diff --git a/assets/compose-multiplaform-web-wH6XfCHb.gif b/assets/compose-multiplaform-web-wH6XfCHb.gif new file mode 100644 index 0000000..b85ee79 Binary files /dev/null and b/assets/compose-multiplaform-web-wH6XfCHb.gif differ diff --git a/assets/hello-compose-demo-B4DIIuDy.gif b/assets/hello-compose-demo-B4DIIuDy.gif new file mode 100644 index 0000000..d4fe51b Binary files /dev/null and b/assets/hello-compose-demo-B4DIIuDy.gif differ diff --git a/assets/index-DTEEl-sV.js b/assets/index-DTEEl-sV.js new file mode 100644 index 0000000..6932654 --- /dev/null +++ b/assets/index-DTEEl-sV.js @@ -0,0 +1 @@ +var v=function(){return!!(window.location.hostname==="localhost"||window.location.hostname==="[::1]"||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))},c;typeof window<"u"&&(typeof Promise<"u"?c=new Promise(function(t){return window.addEventListener("load",t)}):c={then:function(t){return window.addEventListener("load",t)}});function s(t,n){n===void 0&&(n={});var i=n.registrationOptions;i===void 0&&(i={}),delete n.registrationOptions;var e=function(r){for(var f=[],a=arguments.length-1;a-- >0;)f[a]=arguments[a+1];n&&n[r]&&n[r].apply(n,f)};"serviceWorker"in navigator&&c.then(function(){v()?(l(t,e,i),navigator.serviceWorker.ready.then(function(r){e("ready",r)}).catch(function(r){return o(e,r)})):(u(t,e,i),navigator.serviceWorker.ready.then(function(r){e("ready",r)}).catch(function(r){return o(e,r)}))})}function o(t,n){navigator.onLine||t("offline"),t("error",n)}function u(t,n,i){navigator.serviceWorker.register(t,i).then(function(e){if(n("registered",e),e.waiting){n("updated",e);return}e.onupdatefound=function(){n("updatefound",e);var r=e.installing;r.onstatechange=function(){r.state==="installed"&&(navigator.serviceWorker.controller?n("updated",e):n("cached",e))}}}).catch(function(e){return o(n,e)})}function l(t,n,i){fetch(t).then(function(e){e.status===404?(n("error",new Error("Service worker not found at "+t)),d()):e.headers.get("content-type").indexOf("javascript")===-1?(n("error",new Error("Expected "+t+" to have javascript content-type, but received "+e.headers.get("content-type"))),d()):u(t,n,i)}).catch(function(e){return o(n,e)})}function d(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(t){t.unregister()}).catch(function(t){return o(emit,t)})}export{s as register,d as unregister}; diff --git a/assets/index.html-28L8qS8U.js b/assets/index.html-28L8qS8U.js new file mode 100644 index 0000000..3c7d291 --- /dev/null +++ b/assets/index.html-28L8qS8U.js @@ -0,0 +1 @@ +import{_ as t}from"./logo_worldline-dinT9MYm.js";import{_ as i,c as n,a,o as r}from"./app-Djq7wF8p.js";const l={};function s(o,e){return r(),n("div",null,e[0]||(e[0]=[a('

Welcome

Who we are

avatar

We design payments technology that powers the growth of millions​ of businesses around the world. Engineering the next frontiers​ in payments technology​

  • Leader in payment and secured transactions
  • Over 50 billion transactions/year​
  • 7000+ engineers in over 40 countries
  • A huge & diverse tech-stack

Tips

This training is also available in French / Cette formation est aussi disponible en Français

Prerequisites

  • Basic knowledge of object-oriented language like Java
  • Prepare your development environment and install stuff before the session (see Tooling section)
',10)]))}const p=i(l,[["render",s],["__file","index.html.vue"]]),c=JSON.parse(`{"path":"/","title":"Welcome","lang":"en-US","frontmatter":{"home":true,"heroImage":"./kotlin_logo.png","tagline":"A beginner's guide to a modern programming language","actions":[{"text":"Get started →","link":"/en/presentation/","type":"primary"}],"features":[{"title":"Language features","details":"null safety, extensions, lambdas, Java interoperability and more"},{"title":"Backend development","details":"With Ktor, spring and NodeJS"},{"title":"Frontend development","details":"Compose multiplatform, Kotlin/JS, Kotlin/WASM and JVM frameworks"},{"title":"Cross-platform development","details":"With KMP and Compose multiplatform"},{"title":"Advanced Kotlin","details":"Coroutines, delegates, Function literal with receiver, DSLs and more"},{"title":"Practical exercises and solutions","details":"All chapters have a set of exercises"}],"footer":"Worldline, 2023"},"headers":[{"level":2,"title":"Who we are","slug":"who-we-are","link":"#who-we-are","children":[]},{"level":2,"title":"Prerequisites","slug":"prerequisites","link":"#prerequisites","children":[]},{"level":2,"title":"Useful links","slug":"useful-links","link":"#useful-links","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"index.md"}`);export{p as comp,c as data}; diff --git a/assets/index.html-2LK4oqoY.js b/assets/index.html-2LK4oqoY.js new file mode 100644 index 0000000..fa29d96 --- /dev/null +++ b/assets/index.html-2LK4oqoY.js @@ -0,0 +1,13 @@ +import{_ as e,c as a,a as s,o as t}from"./app-Djq7wF8p.js";const i={};function l(c,n){return t(),a("div",null,n[0]||(n[0]=[s(`

📚 Advanced and other Kotlin features

Delegated properties

Kotlin allows to delegate the getter and setter of a property to another object, which is called a delegate. It is a class that defines the getValue and setValue methods.

Kotlin provides standard delegates such lazy properties and observable properties.

▶️ this code illustrates delegate properties.

Concurrency and Coroutines

Kotlin provides a high level concurrency model called Coroutines. The developer can delegated the management of threads to the compiler and runtime and using higher level constructs than threads to express asynchronous operations.

Coroutines in Kotlin revolve around these concepts:

  • A coroutine is an instance of suspendable computation.
    • Kotlin has many methods for creating a coroutine such as launch.
  • A coroutine must exist within a coroutine scope.
    • For example runBlocking creates a coroutine scope whithin which coroutines can be launched.
  • A coroutine can run suspend functions which can suspend the coroutine but do not block the thread.
    • For example: the delay suspend the coroutine but does not block the thread on which it is running.
    • Suspend functions are operations that may take time such http requests and file system calls.
  • The suspend qualifier defines a suspend function. It runs within a coroutine and can call other suspend functions.
  • Flow allows to generate a list of asynchronous values.
  • Deferred and Channel transfer a single value and a stream of values, respectively, between coroutines.

▶️ this code show how to create a coroutine and suspend function and how to use them.

▶️ this code illustrated flows.

▶️ this code illustrates channels and deferred.

Function literal with receiver and Type-safe builders

As seen previously, function extension add behavior to existing classes. Inside the definition of the function extension, we can reference the extension receiver (or this) implicitly.

fun String.countCharacters() = length // or this.length
+println("hello".countCharacters()) // prints 5
+

We can define this extension with a function literal (or lambda) in instead of a named function (declared with fun).

var extFn: String.() -> Int
+extFn = { length } // extFn is a function literal
+println("hello".extFn()) // prints 5
+println(extFn("hello")) // prints 5
+

extFn is a function literal (lambda) that has access to the receiver (this). That's why it's called a function literal with receiver.

extFn("hello") or extFn("hello") call the extension as expected from extension functions.

The type of a function literal with receiver is funName: ReceiverType.(arg1Type, arg2Type, etc.) -> ReturnType and is called with funName(receiverValue, arg1Value, etc.) or receiverValue.funName(arg1Value, etc.). However, this is not the interesting aspect.

The important part is extFn = { length } which can be put as a function argument in a higher order function. The developer that calls the higher order function must define extFn, which in turn has access to the receiver. This allows for a nice style of programming. ▶️ this code shows an example.

Type-safe builders combine well-named builder functions and functions literals with receiver to create type-safe, statically typed builders in Kotlin.

Builder pattern

The builder pattern is a way to construct complex objects.

// StirngBuilder uses the builder pattern
+val text = StringBuilder("Temp")
+  .append(1)
+  .append(true)
+  .append("friend")
+  .toString()
+

This code shows a basic type-safe builder.

Kotlin docs provides an example of an advanced type-safe builder that builds an HTML page.

🧪 Exercises

Exercise 1

  1. open the java-integration-exercise projects in the materials folder.
  2. Have a look at the Java class we provided you in the src/main/java/com/worldline/learning/kotlin/java2kotlin package. (yes, that's the Pokemon class)
  3. Convert that Java class in Kotlin using IntelliJ's awesome copy-pasta tool! (just copy paste the java code in a kotlin file, one is provided at src/main/kotlin/com/worldline/learning/kotlin/java2kotlin)
  4. Have a look at the generated Kotlin code, and note the major differences you spot!
`,28)]))}const p=e(i,[["render",l],["__file","index.html.vue"]]),r=JSON.parse('{"path":"/en/kotlin-features-advanced/","title":"📚 Advanced and other Kotlin features","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Delegated properties","slug":"delegated-properties","link":"#delegated-properties","children":[]},{"level":2,"title":"Concurrency and Coroutines","slug":"concurrency-and-coroutines","link":"#concurrency-and-coroutines","children":[]},{"level":2,"title":"Function literal with receiver and Type-safe builders","slug":"function-literal-with-receiver-and-type-safe-builders","link":"#function-literal-with-receiver-and-type-safe-builders","children":[]},{"level":2,"title":"🧪 Exercises","slug":"🧪-exercises","link":"#🧪-exercises","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/kotlin-features-advanced/README.md"}');export{p as comp,r as data}; diff --git a/assets/index.html-2g5kMIFT.js b/assets/index.html-2g5kMIFT.js new file mode 100644 index 0000000..9b14f21 --- /dev/null +++ b/assets/index.html-2g5kMIFT.js @@ -0,0 +1,7 @@ +import{_ as e,c as I,a,o as g}from"./app-Djq7wF8p.js";const i={};function c(n,l){return g(),I("div",null,l[0]||(l[0]=[a(`

📚 Fonctionnalités du langage Kotlin

Kotlin est un langage qui support les paradigmes orienté objet et fonctionnel. Ce chapitre couvre les caractéristiques basiques et intermédiaires. Le chapitre suivant couvrira les fonctionnalités avancées.

Caractéristiques de base

Constructions de base (variables, flux de contrôle)

  • Kotlin est typé statiquement et prend en charge le typage implicite.
    • Typage statique : les types ne peuvent pas changer à l'exécution (c'est l'inverse du typage dynamique).
    • Typage implicite : le compilateur peut inférer le type tant que c'est possible.
  • var crée des variables ré-assignables.
  • val crée des variables qu'on ne peut plus ré-assigner.
  • Les points-virgules sont facultatifs.
  • Kotlin prend en charge la déclaration de haut niveau des variables et des fonctions (elles peuvent être déclarées en dehors des classes).
  • L'interpolation de chaîne de caractères est disponible avec cette syntaxe \${expression}.
  • if et when sont des expressions (elles peuvent renvoyer une valeur).
    • when est équivalent à l'instruction switch des autres langages
    • L'opérateur ternaire n'est pas disponible. L'expression if le remplace.
  • for-each est le seul type de boucle for disponible.
  • La programmation orientée objet est prise en charge comme en Java avec quelques fonctionnalités supplémentaires telles que les extensions.
  • Le compilateur prend en charge la Null Safety. Il permet d'écrire du code sans erreur de pointeur nulle vérifié à la compilation.
  • La programmation fonctionnelle est prise en charge (fonctions d'ordre supérieur et fonctions en tant qu'éléments de 1ère classe, etc.).

Utiliser val par défaut

Utiliser var uniquement si vous réassignez une variable ou argument.

▶️ this code highlights the above features.

Les fonctions

Dans cette section, les termes 'argument' et 'paramètre' sont utilisés de manière interchangeable.

Les fonctions de Kotlin ont les caractéristiques suivantes :

  • Déclaration : fun functionName(arg1 : type1 = defaultvalue1, ...) : retunrType.
  • Appeler une fonction en passant la valeur dans l'ordre de déclaration.
    • Utilisez des étiquettes d'argument pour plus de clarté, cependant, cela permet également un classement arbitraire des arguments.
  • Les arguments optionnels ont une valeur par défaut et peuvent être omis lors de l'appel.
  • Les fonctions sont des éléments de première classe ou citoyens : elles peuvent être affectées à une variable, passées en tant que paramètre de fonction ou renvoyées par une fonction.
    • 💡 Une fonction qui prend une fonction comme argument ou en renvoie une est une fonction d'ordre supérieur.
  • Un type de fonction peut être exprimé comme suit : (typeOfParam1, typeOfParam2, etc) -> returnType (Le type de retour vide est Unit).
  • Les fonctions anonymes utilisent la syntaxe suivante { argName1, argName2, etc. -> // code }
    • Aussi appelées fonctions lambda ou fonctions littérales
  • Le dernier argument de la fonction peut être mis après la fermeture après la parenthèse fermante compute(9, 5) { x, y -> x * y }

▶️ Ce code illustre les fonctions en Kotlin.

La prochaine section abordera le null safety.

Null safety

null safety est une fonctionnalité du compilateur qui élimine la fameuse Null pointer exception ou npe. En effet, le compilateur signale des erreurs et des avertissements lorsque nous manipulons des types nullables (également appelées types optionnels) dès qu'il y a un risque de npe à l'exécution. Ainsi, afin de mettre Voici une liste des fonctionnalités de sécurité null fournies par Kotlin :

  • Tous les types ne sont pas nullables par défaut ; nous ne pouvons pas affecter null à une variable ou à un argument.
    • Par exemple, ce code échoue var s: String = null.
  • Un type peut être rendu nullable en le suffixant avec un ?. Par exemple : var s : chaîne ? = nul.
  • Kotlin interdit d'appeler une méthode ou une propriété de type non nullable, sauf si l'on fait l'une de ces possibilités :
    • Utilisez le chaînage optionnel avec le suffixe ?.
    • Fournissez une valeur par défaut avec l'opérateur elvis ?:.
    • Smart-cast le nullable dans un non-nullable.
    • Utilisez l'opérateur !! qui élimine les vérifications du compilateur. Cela ne devrait jamais être utilisé.

Ne jamais déballer avec !!

Car cela équivaut à désactiver la null safety. Utilisez les autres possibilités à la place.

▶️ ce code illustrate la null safety et les types optionnels.

La classe \`Optional\` de Java ne fournit aucun protection à la compilation

Ce code lance une npe en Java: Optional<String> s = null; s.isPresent();. Le compilateur Java (au moins à la version version 17) ne propose pas d'équivalent à ce que propose Kotlin comme le smart casting.

Énumérations

Les énumérations permettent de travailler avec un groupe de valeurs de façon cadrée. Contrairement aux énumérations Java, les énumérations Kotlin sont des classes. Les enum class de Kotlin fournissent ces fonctionnalités :

  • Les expressions when prennent en charge les énumérations.
  • Une enum class peut définir des méthodes et implémenter des interfaces mais elle ne peut pas dériver d'une classe.
  • Il existe des méthodes pour lister les constantes d'une enum class.
  • Chaque constante d'une énumération a des propriétés pour obtenir son nom et sa position (en commençant par 0).

▶️ ce code illustres les enum en Kotlin de façon succincte. Veuillez consulter la documentation officielle pour aller plus loin.

Exercices

Exercice 1

Veuillez cliquer sur le lien pour consulter l'énoncé

Déplier pour consulter la solution

Solution

Exercise 2

Veuillez cliquer sur le lien pour consulter l'énoncé

Déplier pour consulter la solution

Solution

Fonctionnalités intermédiaires

Programmation orientée objet

Kotlin permet d'écrire du code Orienté Object concis grâce aux caractéristiques suivantes :

  • Concepts disponibles : classes, héritage, interfaces et classes abstraites.
  • Prise en charge possée des propriétés : les getters et les setters sont automatiquement implémentés.
    • On peut les personnaliser les accesseurs en définissant les fonctions get() et set(value) à côté de la déclaration de la propriété.
  • Les arguments du constructeur sont définis à côté du nom de la classe class ClassName(arg1, atg2, )
  • Préfixer les arguments d'un constructeur avec val ou var en fait une propriété (val la rend non ré-assignable).
  • Le nom du constructeur est init et ne nécessite pas de paramètres.
  • Le compilateur vérifie que toutes les propriétés non nullables sont initialisées à la fin du constructeur.
    • ⚠️ Le compilateur ne vérifie pas l'initialisation des propriétés lateinit. Ainsi, y accéder avant alors qu'elles ne sont pas initialisés provoque une exception.
  • Une classe doit être préfixée avec open pour permettre l'héritage.
  • Kotlin utilise le niveau d'accès public par défaut.
  • L'opérateur d'égalité == appelle implicitement la méthode equals() (contrairement à Java qui utilise l'égalité de référence).
  • Un objet compagnon contient des méthodes et des propriétés statiques.
  • Les extensions ajoutent des fonctions et des propriétés aux classes existantes.
    • 💡 Ils remplacent l'héritage dans de nombreuses situations.
    • Par exemple, nous pouvons ajouter des fonctions à la classe String au lieu de créer une nouvelle classe StringUtils.
  • Les classes et interfaces scellées ne peuvent pas être étendues ou implémentées par des tiers.

Ne définir les accesseurs que si vous avez un comportement personnalisé

Kotlin prend en charge les propriétés de façon plus poussée que Java et permet d'ajouter des accesseurs ultérieurement sans refactoriser le code qui appelle ces propriétés. Ainsi, par défaut, il suffit de définir le nom des propriétés sans accesseurs et on peut les utiliser directement.

▶️ ce code illustre la POO en Kotlin.

Data class

Ce sont des classes qui implémentent des méthodes communes:

  • equals(), hashCode(), copy() et toString()
  • componentN() qui est une syntaxe alternative pour récupérer les propriétés.

Cependant, les data class ont des restrictions:

  • Le constructeur principal doit avoir au moins un paramètre.
  • Tous les paramètres du constructeur principal doivent être marqués comme val ou var.
  • Une Data class ne peut pas être abstraite, ouverte à l'héritage, scellée ou interne (💡 mais des extensions sont possibles).

▶️ ce code illustrate les data class.

Programmation fonctionnelle

Concepts généraux

La programmation fonctionnelle s'articule autour de ces concepts : fonctions pures, récursivité, transparence référentielle, variables immuables, fonctions en tant que citoyens de première classe et fonctions d'ordre supérieur.

Expliquons brièvement ces concepts :

  • Les variables immuables signifient qu'on ne peut pas changer la valeur d'une variable ou ses propriétés une fois qu'elle a été créée. Si nous voulons le faire, nous devons créer une nouvelle instance avec la nouvelle valeur.
  • Les fonctions pures sont des fonctions qui n'ont pas d'effets secondaires et renverront donc toujours la même sortie étant donné la même entrée.
  • Les fonctions sont des citoyennes de première classe : elles peuvent être affectées à une variable ou utilisées dans des fonctions d'ordre supérieur (passées en tant qu'un argument de fonction ou retournées dans un fonction).
  • Transparence référentielle : signifie qu'une expression peut être remplacée par son résultat sans modifier le comportement du programme.

💡 Les langages fonctionnels purs fournissent ces fonctionnalités de manière native et les appliquent (au moment de la construction).

Kotlin et programmation fonctionnelle

Kotlin n'est pas un langage fonctionnel pur mais il prend en charge certaines fonctionnalités. En effet, Kotlin ne sait pas dire si une fonction est pures ou non, mais il fournit des collections immuables via la bibliothèque kotlinx.collections.immutable pour nous aider à manipuler des données immuables.

\`listOf\` génère des listes en lecture seule, mais qui sont mutables

Une liste en lecture seule ne peut pas ajouter ou supprimer des éléments, mais elle peut modifier les données sous-jacentes.

@Test
+fun givenReadOnlyList_whenCastToMutableList_checkNewElementsAdded(){
+    val list: List<String> = listOf("This", "Is", "Totally", "Immutable")
+    (list as MutableList<String>)[2] = "Not"
+    assertEquals(listOf("This", "Is", "Not", "Immutable"), list)
+}
+

La librairie Arrow-kt permet d'aller encore plus loin en développement fonctionnel.

Programmation déclarative

La programmation déclarative est un style célèbre dans la programmation fonctionnelle. Il consiste à écrire du code sous la forme d'un enchaînement d'appels de fonction dans ce style val result = f(x).g(y). .... Les fonctions d'ordre supérieur remplacent de nombreuses situations où nous utiliserions des boucles. Cela favorise le code lisible qui est facile à déboguer et à maintenir.

▶️ ce code montre comment manipuler une liste avec la programmation déclarative.

Kotlin and Java interoperability

  • Kotlin is designed with Java interoperability in mind.
  • Kotlin code may require some annotations to be called from Java.
  • It is possible to mix Java and Kotlin in the same project.
  • JetBrain's IntelliJ and Android Studio can convert to Kotlin when pasting java code.
  • Kotlin generates Java records by annotating a data class with @JvmRecord and targeting JVM 16, among other requirement listed here.
  • It is much more easier and natural to call Java from Kotlin.
    • For example: Java accessors are converted to Kotlin properties.

▶️ this code shows how to convert a Kotlin List to a Java ArrayList.

The official documentation provides exhaustive documentation on Kotlin and JVM integration

Exercices

Exercice 3

Voir l'exercice

Solution(s)

Solution

Exercice 4

Exercice

Solutions(s)

Solution

Exercice 5

Exercice

Solution(s)

Solution

Exercice 6

Exercice

solution(s)

Solution

Exercice 7

Exercice

Solution(s)

Solution

Plus d'exercices et de lecture

`,77)]))}const s=e(i,[["render",c],["__file","index.html.vue"]]),t=JSON.parse(`{"path":"/fr/kotlin-features/","title":"📚 Fonctionnalités du langage Kotlin","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"Caractéristiques de base","slug":"caracteristiques-de-base","link":"#caracteristiques-de-base","children":[{"level":3,"title":"Constructions de base (variables, flux de contrôle)","slug":"constructions-de-base-variables-flux-de-controle","link":"#constructions-de-base-variables-flux-de-controle","children":[]},{"level":3,"title":"Les fonctions","slug":"les-fonctions","link":"#les-fonctions","children":[]},{"level":3,"title":"Null safety","slug":"null-safety","link":"#null-safety","children":[]},{"level":3,"title":"Énumérations","slug":"enumerations","link":"#enumerations","children":[]},{"level":3,"title":"Exercices","slug":"exercices","link":"#exercices","children":[]}]},{"level":2,"title":"Fonctionnalités intermédiaires","slug":"fonctionnalites-intermediaires","link":"#fonctionnalites-intermediaires","children":[{"level":3,"title":"Programmation orientée objet","slug":"programmation-orientee-objet","link":"#programmation-orientee-objet","children":[]},{"level":3,"title":"Data class","slug":"data-class","link":"#data-class","children":[]},{"level":3,"title":"Programmation fonctionnelle","slug":"programmation-fonctionnelle","link":"#programmation-fonctionnelle","children":[]},{"level":3,"title":"Kotlin and Java interoperability","slug":"kotlin-and-java-interoperability","link":"#kotlin-and-java-interoperability","children":[]},{"level":3,"title":"Exercices","slug":"exercices-1","link":"#exercices-1","children":[]}]},{"level":2,"title":"Plus d'exercices et de lecture","slug":"plus-d-exercices-et-de-lecture","link":"#plus-d-exercices-et-de-lecture","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/kotlin-features/README.md"}`);export{s as comp,t as data}; diff --git a/assets/index.html-B08ZAEqY.js b/assets/index.html-B08ZAEqY.js new file mode 100644 index 0000000..878b91d --- /dev/null +++ b/assets/index.html-B08ZAEqY.js @@ -0,0 +1,272 @@ +import{_ as c,c as r,a as o,b as e,d as t,r as l,o as u,e as n,f as s}from"./app-Djq7wF8p.js";const d={};function k(m,a){const p=l("CodeGroupItem"),i=l("CodeGroup");return u(),r("div",null,[a[2]||(a[2]=o(`

📚 Backend development

Many frameworks officially support Kotlin: Spring, Quarkus, Ktor, among others listed here.

In addition to that, Kotlin is theoretically compatible with any framework that targets the JVM or JS. For example, this tutorial shows how to use node.js with Kotlin. However, frameworks that do not officially support Kotlin may require some tweaking to use it.

Ktor

Ktor is a cross-platform Kotlin library for building both HTTP clients and servers. This makes Ktor a useful library to learn for both front-end developers for its HTTP client capabilities and backend-development for its HTTP server capabilities. In the following, we'll create a REST API with Ktor server.

🧪 develop an API with Ktor

  • Create a project on start.ktor.io with the following plugins: Content Negotiation, kotlinx.serialization, and Routing.
  • Click on "Generate project".
  • Download the archive, unzip it, and open the project with IntelliJ.
  • Create a models package and add to it a Customer data class with these immutable properties id: String, firstName: String, lastName: String, email: String.
  • Annotate the class with @Serializable.
  • Create a new package named routes and add to it a file CustomerRoutes.kt that will contain the code for the /customer endpoint.
  • The code below provides the implementation of some endpoints. Please implement the remaining ones.
  • To enable the route call customerRouting() in the routing configuration file located in plugins/Routing.kt.
  • For simplicity, use a global in-memory list of customers val store = mutableListOf<Customer>().
  • Run the server by running the main method.
  • Test the api on the IDE by using an http file or using any other client.
CustomerRoutes.kt
val store = mutableListOf<Customer>()
+
+fun Route.customerRouting() {
+    route("/customer") {
+        get {
+            call.respond(store)
+        }
+        get("{id?}") {
+            val id = call.parameters["id"] ?: return@get call.respondText(
+                "Missing id",
+                status = HttpStatusCode.BadRequest
+            )
+            val customer =
+                store.find { it.id == id } ?: return@get call.respondText(
+                    "No customer with id $id",
+                    status = HttpStatusCode.NotFound
+                )
+            call.respond(customer)
+        }
+        post {
+            val customer = call.receive<Customer>()
+            store.add(customer)
+            call.respondText("Customer stored correctly", status = HttpStatusCode.Created)
+        }
+        delete("{id?}") {
+
+        }
+    }
+}
+
plugins/Routing.kt
fun Application.configureRouting() {
+    routing {
+        customerRouting()
+    }
+}
+

return@label

You can specify which level you want to return with an explicit label using return@lambda.

lambdaA {
+    lambdaB {
+        lambdaC {
+            val randomInt = Random.nextInt(0, 100)
+            if (randomInt > 50) return@lambdaC else return@lambdaB
+        }
+        printf("In lambdaB")
+    }
+}
+

This code runs another example.

CustomerTest.http
POST http://127.0.0.1:8080/customer
+Content-Type: application/json
+
+{
+  "id": "100",
+  "firstName": "Jane",
+  "lastName": "Smith",
+  "email": "jane.smith@company.com"
+}
+
+
+###
+POST http://127.0.0.1:8080/customer
+Content-Type: application/json
+
+{
+  "id": "200",
+  "firstName": "John",
+  "lastName": "Smith",
+  "email": "john.smith@company.com"
+}
+
+###
+POST http://127.0.0.1:8080/customer
+Content-Type: application/json
+
+{
+  "id": "300",
+  "firstName": "Mary",
+  "lastName": "Smith",
+  "email": "mary.smith@company.com"
+}
+
+
+###
+GET http://127.0.0.1:8080/customer
+Accept: application/json
+
+###
+GET http://127.0.0.1:8080/customer/200
+Accept: application/json
+
+###
+GET http://127.0.0.1:8080/customer/500
+Accept: application/json
+
+###
+DELETE http://127.0.0.1:8080/customer/100
+
+###
+DELETE http://127.0.0.1:8080/customer/500
+

This page has detailed steps

Spring framework

Spring is a famous framework for developing server-side applications: APIs, server generated web pages, microservices, etc. It relies on the the Java ecosystem to build and run, thus making it compatible with Kotlin. Even better, Spring officially supports Kotlin. It even allows in start a new project with Kotlin and Gradle-Kotlin. In the next section, we'll use this starter to recreate our above REST API with Spring.

🧪 Spring boot part 1 - develop the same API with Spring Boot

  • Create a project on start.spring.io (also called Spring initializr) with the following dependencies: Spring Web and Spring Boot DevTools.
  • Choose Kotlin as the language and Kotlin-Grade as the project manager.
  • Add these dependencies: Spring Web, Spring Boot DevTools, h2 database and Spring Data JPA.
  • Click on "Generate". Download the archive, unzip it, and open the project with IntelliJ (preferably) or VSCode.
  • Create Customer data class in the model package without the @Serializable annotation.
  • Create a controller package that contains a CustomerController class which provides a CRUD using a global list. You can find a skeleton below.
    • 💡 In Spring, Rest controllers serve the purpose of Ktor routes, where a controller defines a REST resource.
  • Define the same endpoints as in the previous PW.
  • Start the REST API server by running .\\gradlew bootRun or from your IDE.
  • Please test the endpoints with a REST client. You can find http files here in JetBrains format or VSCode's REST Client extension
CustomerController.kt
val store = mutableListOf<Customer>()
+
+@RestController
+@RequestMapping("/customer")
+class CustomerController {
+    @GetMapping
+    fun getAll() = store
+
+    @GetMapping("{id}")
+    fun getById(@PathVariable id: String) { /* TODO: implement */ }
+
+    @PostMapping
+    fun addOne(@RequestBody customer: Customer) { /* TODO: implement */ }
+
+    @DeleteMapping("{id}")
+    fun deleteOne(@PathVariable id: String) { /* TODO: implement */ }
+}
+

Models or model package ? plural or not ?

Both are ok as long as you follow the same convention in the project.

🧪 Spring boot part 2 - adding a database

Let's go a little bit further by storing data in a database and writing some tests.

We'll use the H2 in-memory database for the sake of simplicity, since it does not require a server to run. Classes will mapped to database tables with JPA annotations. The database API we'll be using is called JPARepository. It is a lightweight API that provides common CRUD features by just defining an interface.

On the testing side, we'll see two different syntaxes. The default one that is more familiar with Java style and the DSL one which is more readable and more familiar with Kotlin developers.

  • Create a new Spring project using Spring initializr with Kotlin and the following dependencies: Spring Data JPA, H2 Database, Spring Boot DevTools, Spring Web
  • Open the project and add this class in the model package @Entity class Product(@Id @GeneratedValue var id: Long? = null, var name: String, var price: Int). This single defines the class as well as the minimal JPA annotations (@Entity, @Id and @GeneratedValue) to generate the corresponding table.
  • In the repository package, declare the ProductRepository interface as follows interface ProductRepository: JpaRepository<Product, Long>. This is enough for Spring to generate an implementation with common features as we'll see later.
  • Next, create a ProductService class which will contain the business logic. In terms of architecture, the controller calls a service which in turn rely on other services or repositories.
ProductService.kt
@Service
+class ProductService(@Autowired val productRepository: ProductRepository) {
+    fun getAll() = productRepository.findAll()
+
+    // use findByIdOrNull instad of findById because the latter returns an optional<Product> instead of Product?
+    fun getById(id: Long) = productRepository.findByIdOrNull(id)
+}
+
  • In the controller package, create a ProductController class that is mapped to /product and injects the with @Autowired. Reply to @Get as follows.
ProductController.kt
@RestController
+@RequestMapping("/product")
+class ProductController(@Autowired val productService: ProductService) {
+    @GetMapping fun getAll() = productService.getAll()
+
+    @GetMapping("{id}")
+    fun getById(@PathVariable id: Long) =
+        productService.getById(id) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
+}
+

Kotlin makes getById(@PathVariable id: Long) more concise

The Elvis operator ?: allows to simplify the code. Here is a longer version as reference.

@GetMapping("{id}")
+fun getById(@PathVariable id: Long): Product {
+    val product = productService.getById(id)
+    if (product != null){
+        return product
+    }
+    throw ResponseStatusException(HttpStatus.NOT_FOUND)
+}
+

In addition to that, Spring provides @ControllerAdvice to change the exception message. You can see an example here.

  • Let's run the project. Before running the project, we need to add a plugin that allows Kotlin classes to generate a default constructor id("org.jetbrains.kotlin.plugin.jpa") version "1.8.10". The plugins should look as follows:
plugins {
+    id("org.jetbrains.kotlin.plugin.jpa") version "1.8.10"
+ id("org.springframework.boot") version "3.0.4"
+ id("io.spring.dependency-management") version "1.1.0"
+ kotlin("jvm") version "1.8.10"
+ kotlin("plugin.spring") version "1.8.10"
+}
+
  • As an exercise, implement these endpoints: POST a single product, DELETE by id (/product/{id}) and GET by id (/product/{id}).
    • Hint: ProductController already provides the necessary methods.
  • Call the different endpoints with a REST client.

🧪 Spring boot part 2 - adding tests

Spring frameworks helps perform different types of tests by providing different classes out of the box:

  • Unit testing of services, repositories and the REST API. This is done through mock utilities such as MockMVC.
  • Integration testing of the REST API using TestRestTemplate. In this situation, a full server is run and tested.

Most, if not all classes provided by Spring provide an elegant syntax for Java developers. Some of them go further by taking advantage of Kotlin specific features. In the following, we're going to focus on parts that provide Kotlin DSLs, namely unit testing the REST API with MockMVC.

  • Create a test class ProductControllerUnitTests with this initial content. MockMvc allows to unit test the REST API. The @AutoConfigureMockMvc annotation allows spring to configure it automatically
@SpringBootTest
+@AutoConfigureMockMvc
+class ProductControllerTests(
+    @Autowired val mockMvc: MockMvc,
+    @Autowired val productRepository: ProductRepository) {
+
+    @BeforeEach
+    fun reset(){
+        productRepository.deleteAll()
+    }
+}
+
  • Add these two tests. The first one uses a classic approach while the second take advantage of Kotlin DSL capabilities. In addition to that, we name using a more readable string literal
`,37)),e(i,null,{default:t(()=>[e(p,{title:"Without DSL (Test Get All)"},{default:t(()=>a[0]||(a[0]=[n("div",{class:"language-kotlin line-numbers-mode","data-highlighter":"prismjs","data-ext":"kt","data-title":"kt"},[n("pre",null,[n("code",null,[n("span",{class:"line"},[n("span",{class:"token annotation builtin"},"@Test")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token keyword"},"fun"),s(),n("span",{class:"token function"},"testWithClassicApproach"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" mockMvc"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"perform"),n("span",{class:"token punctuation"},"("),n("span",{class:"token keyword"},"get"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"/product"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"status"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),s("isOk"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"content"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"string"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"containsString"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"[]"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"})])]),n("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"})])],-1)])),_:1}),e(p,{title:"With DSL (Test Get Single)"},{default:t(()=>a[1]||(a[1]=[n("div",{class:"language-kotlin line-numbers-mode","data-highlighter":"prismjs","data-ext":"kt","data-title":"kt"},[n("pre",null,[n("code",null,[n("span",{class:"line"},[n("span",{class:"token annotation builtin"},"@Test")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token keyword"},"fun"),s(),n("span",{class:"token function"},"`test GET a single product`"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" mockMvc"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"get"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"/product/1"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),s(),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" status "),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"isOk"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token function"},"jsonPath"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"$.name"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"value"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"A"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token function"},"jsonPath"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"$.price"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"value"),n("span",{class:"token punctuation"},"("),n("span",{class:"token number"},"1"),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" content "),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"contentType"),n("span",{class:"token punctuation"},"("),s("MediaType"),n("span",{class:"token punctuation"},"."),s("APPLICATION_JSON"),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"})])]),n("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"})])],-1)])),_:1})]),_:1}),a[3]||(a[3]=o(`
  • As an exercise, unit tests for the other endpoints.

The request builder of JpaRepository

Spring repositories implement requests based on the name of their methods. For example, to get all products sorted by name, we can add this method to the interface.

interface ProductRepository: JpaRepository<Product, Long> {
+    fun findAllByOrderByNameAsc(): List<Product>;
+}
+

The official documentation provides more detailed explanations and examples.

node.js

Thanks to Kotlin/JS, we can write apps that target node.js using Kotlin. We can even import npm libraries as long as you declare the JS API surface that you'll be using in Kotlin. This is called external declaration (You can think of it as an equivalent of TypeScript's type definitions) that declares the symbols that we want to access in Kotlin thanks to @JsModule and @JsNonModule annotations.

Defining such external declarations can be a hassle and there seems to be no official automatic generator (dukat has been removed in kotlin 1.8.20). In that case, we have two options, either we write the external declaration ourselves or import it as a dependency if available. Fortunately for express developers, chrisnkrueger/kotlin-express provides declarations for the express library.

There are two gradle plugins that allow to create node.js projects: the kotlin("js") one and the kotlin("multiplatform") one. The difference between the two plugins is that the former only supports JS or WASM while the latter supports more platforms but requires to configure source sets. Thus, the former may seem easier to setup but the latter is better in the long run because it allows us to get more familiar with Kotlin Multiplatform (KMP).

🧪 Getting started with Kotlin/JS and Express

At the time of writing, I didn't find an official wizard or starter project. So we'll create one from scratch using gradle init.

  • Create a new Gradle project using IntelliJ or by running gradle init in a empty folder (see below for the replies to the gradle init command).
gradle init
gradle init
+Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
+
+Select type of project to generate:
+  1: basic
+  2: application
+  3: library
+  4: Gradle plugin
+Enter selection (default: basic) [1..4] 1
+
+Select build script DSL:
+  1: Kotlin
+  2: Groovy
+Enter selection (default: Kotlin) [1..2] 1
+
+Project name (default: starter): rest-api-kotlin-nodejs
+
+Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] yes
+
+
+> Task :init
+To learn more about Gradle by exploring our Samples at https://docs.gradle.org/8.3/samples
+
+BUILD SUCCESSFUL in 24s
+2 actionable tasks: 2 executed
+
  • In build.gradle.kts, add and configure the kotlin("multiplatform") plugin. Also add the express and dev.chriskrueger:kotlin-express dependencies.
build.gradle.kts
plugins {
+    kotlin("multiplatform") version "1.9.20-Beta"
+}
+
+repositories {
+    mavenCentral()
+}
+
+group = "tech.worldline.demo"
+version = "1.0-SNAPSHOT"
+
+kotlin {
+    js {
+        nodejs {
+        }
+        binaries.executable()
+        useCommonJs()
+    }
+
+    sourceSets {
+        val jsMain by getting {
+            dependencies {
+                implementation(npm("express", "> 4.0.0 < 5.0.0"))
+                implementation("dev.chriskrueger:kotlin-express:1.2.0")
+            }
+        }
+    }
+}
+

Some notes on the build file

  • create a main.kt file in src/jsMain/kotlin with the following content:
main.kt
data class Message(val id: Int, val message: String)
+
+val messages = mutableListOf(Message(0, "I love Kotlin/JS"))
+
+fun main() {
+    val app = express.Express()
+
+    // REST API that provides a **GET /hello** endpoint
+    app.get("/hello") { _, res ->
+        res.send(messages)
+    }
+
+    // Create a server that listens to port 3000
+    app.listen(3000) {
+        console.log("server start at port 3000")
+    }
+}
+
  • Run the task jsRun from IntelliJ of from the command line ./gradlew --console=plain jsRun. The server should start running.
  • Open the hello endpoint on http://localhost:3000/hello

Execution failed for task ':kotlinStoreYarnLock'

If you get this error:

Execution failed for task ':kotlinStoreYarnLock'.
+> yarn.lock was changed. Run the \`kotlinUpgradeYarnLock\` task to actualize yarn.lock file
+

Run ./gradlew kotlinUpgradeYarnLock so that yarn.lock is updated

🧪 Adding a post endpoint and an external Kotlin/JS definition

Let's add a post endpoint which reads the body as a json. In order to read the body as json, we must add this possibility to express by importing the npm library body-parser and by calling app.use(bodyParser.json()). Once this setup is complete, req.body will contain the content of the body. However, there is no available external definition for bodyParser as of the time of writing. Thus, we must create or own external definition.

  • First, add the body-parser dependncy in the build file implementation(npm("body-parser", "> 1.0.0 < 2.0.0"))
  • Next, we would write: app.use(bodyparser.json()) to activate the library. Let's guess what a minimal definition of bodyparser can be.
BodyParser.kt
// external means that this class is defined in JS
+external class BodyParser {
+    // we tell Kotlin that we want to use the json() function.
+    fun json(): Any
+    // It is not required to define all the functions of the module
+}
+
+// @JsModule is used to import the module from the NPM registry
+@JsModule("body-parser")
+external val bodyParser: BodyParser
+
  • Finally, we just need to add the BodyParser.kt file into the project and use it in our server.
main.kt
app.use(bodyParser.json())
+app.post("/hello") { req, res ->
+    // Kotlin does not keep the original field name when parsing JSON from JS (you can see it the in get response)
+    if (req.body as? Message == null) {
+        println("failed to get the body from Kotlin")
+    }
+    // Thus, we need to use js() to get the the field by its expected name
+    // js() calls JS from Kotlin
+    println("req.body from JS \${js("req.body.id")} - \${js("req.body.message")}")
+    val id = js("req.body.id") as? Int
+    val message = js("req.body.message") as? String
+    if (message != null && id != null) {
+        messages.add(Message(id, message))
+        res.status(201).end()
+    } else {
+        res.status(400).send(js("{cause : 'error'}") as Any)
+    }
+}
+

🧪 Adding more endpoints

  • Add PUT and DELETE endpoints

🎯 Solutions

Other frameworks

Micronaut and Quarkus

Micronaut and Quarkus are two other frameworks that support Kotlin. Bootstrap websites are available here and here.

📖 Further readings

These official tutorials go even further:

References

`,34))])}const g=c(d,[["render",k],["__file","index.html.vue"]]),b=JSON.parse('{"path":"/en/backend-development/","title":"📚 Backend development","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Ktor","slug":"ktor","link":"#ktor","children":[{"level":3,"title":"🧪 develop an API with Ktor","slug":"🧪-develop-an-api-with-ktor","link":"#🧪-develop-an-api-with-ktor","children":[]}]},{"level":2,"title":"Spring framework","slug":"spring-framework","link":"#spring-framework","children":[{"level":3,"title":"🧪 Spring boot part 1 - develop the same API with Spring Boot","slug":"🧪-spring-boot-part-1-develop-the-same-api-with-spring-boot","link":"#🧪-spring-boot-part-1-develop-the-same-api-with-spring-boot","children":[]},{"level":3,"title":"🧪 Spring boot part 2 - adding a database","slug":"🧪-spring-boot-part-2-adding-a-database","link":"#🧪-spring-boot-part-2-adding-a-database","children":[]},{"level":3,"title":"🧪 Spring boot part 2 - adding tests","slug":"🧪-spring-boot-part-2-adding-tests","link":"#🧪-spring-boot-part-2-adding-tests","children":[]}]},{"level":2,"title":"node.js","slug":"node-js","link":"#node-js","children":[{"level":3,"title":"🧪 Getting started with Kotlin/JS and Express","slug":"🧪-getting-started-with-kotlin-js-and-express","link":"#🧪-getting-started-with-kotlin-js-and-express","children":[]},{"level":3,"title":"🧪 Adding a post endpoint and an external Kotlin/JS definition","slug":"🧪-adding-a-post-endpoint-and-an-external-kotlin-js-definition","link":"#🧪-adding-a-post-endpoint-and-an-external-kotlin-js-definition","children":[]},{"level":3,"title":"🧪 Adding more endpoints","slug":"🧪-adding-more-endpoints","link":"#🧪-adding-more-endpoints","children":[]}]},{"level":2,"title":"🎯 Solutions","slug":"🎯-solutions","link":"#🎯-solutions","children":[]},{"level":2,"title":"Other frameworks","slug":"other-frameworks","link":"#other-frameworks","children":[]},{"level":2,"title":"📖 Further readings","slug":"📖-further-readings","link":"#📖-further-readings","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/backend-development/README.md"}');export{g as comp,b as data}; diff --git a/assets/index.html-BHDS7_46.js b/assets/index.html-BHDS7_46.js new file mode 100644 index 0000000..ab0d3ca --- /dev/null +++ b/assets/index.html-BHDS7_46.js @@ -0,0 +1,35 @@ +import{_ as e}from"./kotlin-wasm-webapp-R4_9ho9v.js";import{_ as s,c as a,a as t,o as l}from"./app-Djq7wF8p.js";const o="/learning-kotlin/assets/kotlin-wasm-flag-BKaaN9Pq.png",i="/learning-kotlin/assets/wasm-build-conf-edit-CmamvRv7.png",p="/learning-kotlin/assets/wasm-run-configuration-x_w9-EC1.png",r="/learning-kotlin/assets/compose-multiplaform-web-wH6XfCHb.gif",u="/learning-kotlin/assets/compose-multiplaform-Dfyu_rxB.gif",c={};function d(m,n){return l(),a("div",null,n[0]||(n[0]=[t('

📚 Développement frontend

Kotlin supporte une large sélection de frameworks frontaux sur toutes les plateformes : mobile, desktop et web. Vous trouverez ci-dessous un aperçu des possibilités que vous pouvez faire directement à partir d'IntelliJ :

  • Côté bureau
    • Grâce au support de la JVM, Kotlin supporte JavaFX. 💡 Il existe même un équivalent en Kotlin appelé tornadofx.
    • Compose Multiplatform apporte l'API Jetpack Compose sur le bureau, le web et le mobile.
  • Sur le web
    • Ktor peut utiliser des moteurs de modèles tels que FreeMarker pour créer des pages de serveur.
    • Avec KotlinJS, les développeurs peuvent créer des applications React, nodsjs ou vanilla JS en utilisant Kotlin.
    • Kotlin WASM se compile en Web Assembly. Il peut compléter KotlinJS pour les tâches à forte intensité de calcul.
    • Compose Multiplatform apporte deux options sur le web: Compose web et Compose for Web Canvas.
  • Sur les mobiles

Comme nous pouvons le voir, Kotlin propose plusieurs options. L'option la plus séduisante en terme de partage de code est Compose Multiplatform. Ceci est possible notamment grâce à KMP

KMP

  • KMP (Kotlin Multiplatform) permet de partager une base de code unique sur plusieurs cibles.
  • KMP s'appuie sur Kotlin native et d'autres fonctionnalités de Kotlin pour aider les développeurs à créer des projets destinés à plusieurs plates-formes en utilisant une base de code Kotlin commune.

KMP

  • De nombreuses combinaisons de cibles et de cas d'utilisation sont possibles :
  • KMM est une ancienne dénomination qui est dépréciée.

Dans la suite de ce chapitre, nous explorerons les différentes possibilités individuellement et on fera un projet KMP dans le chapitre suivant.

Kotlin/JS et Kotlin/WASM

  • Kotlin/JS peut également cibler le web et même utiliser des frameworks web (tels que react) dans Kolitn.
  • Kotlin WASM est une autre possibilité de cibler le web, mais il génère WASM au lieu de code JS pur.
    • Il peut être utilisé par exemple pour développer des bibliothèques à forte intensité de calcul.
  • Nous pourrons peut-être faire encore plus à l'avenir grâce à l'évolution de toutes ces technologies (Kotlin, WASM et Kotlin/WASM). - Par exemple, [WASI] (https://wasi.dev/) permet à WASM de communiquer avec le système d'exploitation. - Cela signifie que je pourrais voir des projets Kotlin/WASM à l'avenir qui peuvent cibler à la fois le navigateur et le système d'exploitation.
  • Continuons à observer 😄.

🧪 Application web Kotlin/WASM

  • Les assistants de création de projet Kotlin/WASM et Kotlin/JS sur IntelliJ fonctionnent de manière similaire:
    • L'IDE génère un fichier Kotlin qui sera compilé par la suite en WASM et/ou JS. Kotlin/JS ne génère que du JS tandis que Kotin/WASM génère à la fois du JS et du WASM.
    • Dans les deux cas, le point d'entrée du code généré est un fichier JS appelé nom_du_module.js.
    • L'IDE génère également dans le dossier des ressources un fichier index.html dont le but est de charger le JS généré (le fichier nom_du_module.js).
    • La tâche wasmBrowserDevelopmentRun ou jsWasmBrowserDevelopmentRun lancera un serveur local qui hébergera à la fois les fichiers index.html et les fichiers JS et WASM générés.
  • Créons une application Kotlin/WASM. Tout d'abord, activez l'assistant Kotlin/WASM en activant kotlin.wasm.wizard dans le registre d'IntelliJ (ouvrez le registre en appuyant deux fois sur shift et en tapant "registry" dans la boîte de recherche). Alternativement, clonez ce projet.

  • Vérifiez qu'on est sur la dernière version de Kotlin dans build.gradle.kts (l'assistant peut le configurer à une version antérieure).
  • Ouvrez src/wasmMain/kotlin/sample.kt et cliquez sur le bouton lancer qui apparaît à côté de la fonction main.
  • Si la compilation échoue parce que l'IDE a utilisé la mauvaise tâche gradle, veuillez la changer en wasmBrowserDevelopmentRun et essayez de l'exécuter à nouveau.

  • Le serveur de développement devrait démarrer et vous pouvez ouvrir votre application web sur http://localhost:8080/
  • ⚠️ Il se peut que vous deviez activer certains drapeaux sur votre navigateur pour que l'application fonctionne. Si vous voyez une page blanche, veuillez lire les journaux du navigateur pour vérifier les instructions.

  • Le fichier wasm généré est disponible dans build/js/packages/nom_du_projet/kotlin
  • WASM étant un format binaire, nous devons d'abord le convertir au format texte.
    • Nous pouvons soit installer [WABT (The WebAssembly Binary Toolkit ou wabbit)] (https://github.com/WebAssembly/wabt) et utiliser l'outil wasm2wattool wasm2wat --enable-all -v .\\kotlin-wasm-demo-wasm.wasm -o wasm.wat,
    • ou utiliser un convertisseur en ligne comme celui-ci
    • ❗ Cependant, je n'ai pas réussi à le faire fonctionner

🧪 Application web KotlinJS

L'assistant Kotlin/JS crée une application très similaire à celle de Kotlin/WASM. Dans un prochain PW, nous créerons une application complète avec Ktor et Kotlin/JS.

Compose

Compose multiplatform est une famille de frameworks d'interface utilisateur déclaratifs pour Android (Jetpack Compose), le bureau (Compose Desktop) et le web (Compose Web). Il dispose d'un support expérimental pour iOS et Web Canvas.

Compose multiplatform vs Jetpack Compose

Bien que très similaire, Compose multiplatform est différent de Jetpack Compose car ce dernier n'est compatible qu'avec Android. Google fournit un JetPack compose tutorial pour le développement Android.

Compose Web vs Compose for Web Canvas

  • La surface de l'API de Compose Web est différente des autres cibles de Compose car elle travaille directement avec le DOM.
  • Compose for Web Canvas a la même surface d'API que celle du Desktop, Android et iOS car il dessine sur un Canvas et ne manipule pas le DOM.

Cela signifie que le premier a un meilleur support web et que le second a plus de code réutilisable.

🧪 Compose Web

  • Créez un nouveau projet IntelliJ -> Compose Multiplaform.
  • Choisissez "Single platform" -> "Web" et remplissez les autres champs.
  • Choisissez Finish
  • IntelliJ peut prendre un certain temps pour préparer le projet et peut demander d'installer des plugins supplémentaires.
  • Lancez le serveur de développement de l'application web à l'aide de la commande ./gradlew jsBrowserRun --continuous.
  • Modifiez Main.kt comme suit et lancez l'application.
  • Ouvrez cette adresse : localhost:8080.
fun main() {
+    renderComposable(rootElementId = "root") {
+        Div({ style { padding(25.px) } }) {
+            var expanded by remember { mutableStateOf(false) }
+            Button(
+                attrs = {
+                    onClick { expanded = !expanded }
+                }
+            ) { Text("Cliquez sur moi") }
+            Div({ style { display(if (expanded) DisplayStyle.Block else DisplayStyle.None) } }) {
+                Text("Cliquez sur moi !")
+            }
+        }
+    }
+}
+

compose multiplatform demo

🧪 Compose desktop + Android app

  • Créez un nouveau projet sur IntelliJ -> Compose Multiplatform.
  • Choisissez "multiple platforms" et remplissez les autres champs. Choisissez ensuite Finish.
  • IntelliJ commence à préparer le projet et peut demander l'installation de plugins.
  • Une fois le projet prêt, lancez l'application Android en utilisant le bouton vert run.
  • Lancez l'application desktop en exécutant la fonction principale du projet desktop (qui devrait se trouver dans Main.kt).
  • Modifiez App.kt dans le projet principal comme suit et lancez l'application.
@Composable
+fun App() {
+    val platformName = getPlatformName()
+    Card {
+        var expanded by remember { mutableStateOf(false) }
+        Column(Modifier.clickable { expanded = !expanded }) {
+            Texte(
+                text="Cliquez sur moi !",
+                style = MaterialTheme.typography.h2
+            )
+            AnimatedVisibility(expanded){
+                Texte(
+                    text = "Bonjour, \${platformName} 🎊",
+                    style = MaterialTheme.typography.h1
+                )
+            }
+        }
+    }
+}
+

compose multiplatform demo

Pour aller plus loin

',35)]))}const v=s(c,[["render",d],["__file","index.html.vue"]]),f=JSON.parse('{"path":"/fr/front-development/","title":"📚 Développement frontend","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"KMP","slug":"kmp","link":"#kmp","children":[]},{"level":2,"title":"Kotlin/JS et Kotlin/WASM","slug":"kotlin-js-et-kotlin-wasm","link":"#kotlin-js-et-kotlin-wasm","children":[{"level":3,"title":"🧪 Application web Kotlin/WASM","slug":"🧪-application-web-kotlin-wasm","link":"#🧪-application-web-kotlin-wasm","children":[]},{"level":3,"title":"🧪 Application web KotlinJS","slug":"🧪-application-web-kotlinjs","link":"#🧪-application-web-kotlinjs","children":[]}]},{"level":2,"title":"Compose","slug":"compose","link":"#compose","children":[{"level":3,"title":"🧪 Compose Web","slug":"🧪-compose-web","link":"#🧪-compose-web","children":[]},{"level":3,"title":"🧪 Compose desktop + Android app","slug":"🧪-compose-desktop-android-app","link":"#🧪-compose-desktop-android-app","children":[]}]},{"level":2,"title":"Pour aller plus loin","slug":"pour-aller-plus-loin","link":"#pour-aller-plus-loin","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/front-development/README.md"}');export{v as comp,f as data}; diff --git a/assets/index.html-BZTbG60u.js b/assets/index.html-BZTbG60u.js new file mode 100644 index 0000000..3439f10 --- /dev/null +++ b/assets/index.html-BZTbG60u.js @@ -0,0 +1 @@ +import{_ as t}from"./kmp_codelab-CiTPMWjt.js";import{_ as n,c as r,a as i,o as a}from"./app-Djq7wF8p.js";const o={};function l(s,e){return a(),r("div",null,e[0]||(e[0]=[i('

🛠 Construisons une app multiplateforme !

En combinant KMP, KMM et Compose, il est possible de développer des applications mobiles et de bureau multiplateformes en utilisant uniquement Kotlin.

Prérequis

  • Connaissance de base du développement en Kotlin (notamment la nullabilité, les fonctions en ligne et les fonctions lambda)
  • IDE Android Studio avec la version stable la plus récente, version Giraffe ou supérieure
  • Une bonne connectivité

Conseil

Pour plus d'informations sur votre environnement de développement (DEV) et les installations, veuillez consulter la documentation liée à JetBrains ici.

____ 🚀 Demarrer la session pratique ici 🚀___

kmp codelab

',7)]))}const u=n(o,[["render",l],["__file","index.html.vue"]]),c=JSON.parse('{"path":"/fr/other-technologies/","title":"🛠 Construisons une app multiplateforme !","lang":"fr-FR","frontmatter":{},"headers":[],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/other-technologies/README.md"}');export{u as comp,c as data}; diff --git a/assets/index.html-BwZborl3.js b/assets/index.html-BwZborl3.js new file mode 100644 index 0000000..9f02671 --- /dev/null +++ b/assets/index.html-BwZborl3.js @@ -0,0 +1 @@ +import{_ as i}from"./kotlin-used-for-Bdlavnqs.js";import{_ as t,c as l,a as r,o as n}from"./app-Djq7wF8p.js";const a={};function o(s,e){return n(),l("div",null,e[0]||(e[0]=[r('

🚀 Présentation de Kotlin

Kotlin est un langage de programmation moderne développé par JetBrains.

Certaines fonctionnalités

  • Kotlin est capable de compiler vers différentes cibles : la JVM, JS, Android, iOS, Les OS de bureau, etc.
    • Pris en charge officiellement par de grands frameworks back-end, tels que Spring et Quarkus,
    • Langage préféré pour le développement Android,
    • Kotlin Native compile en code natif,
    • Kotlin peut être considéré comme un langage fullstack
  • Interopérable avec Java.
  • Fournit des fonctionnalités modernes telles que la null safety à la compilation.
  • Prend en charge la programmation orientée objet et la programmation fonctionnelle.
  • Processus d'évolution open source: Kotlin KEEP.

Histoire

  • 15 février 2016 : sortie de Kotlin 1.0.
  • 4 janvier 2017 : Spring a introduit le support de Kotlin dans Spring 5.
  • Lors de Google I/O 2017, Google a annoncé une prise en charge officielle de Kotlin sur Android.
  • Le 7 mai 2019, Google a annoncé que Kotlin était le langage préféré des développeurs d'applications Android.
  • Juin 2022 : Kotlin 1.7 est sorti avec la version du nouveau compilateur K2.

Quelques chiffres et faits

Source : Amyra Sheldon

  • En 2022, Kotlin est utilisé par 7,8 % des experts de l'industrie.
  • Selon StackOverflow, Kotlin était le 4ème langage le plus apprécié en 2020 avec 62,9 % des votes.
  • Kotlin est désormais répertorié parmi les 20 meilleurs langages de programmation par Redmonk.
  • Kotlin fait partie des 3 principaux langages vers lesquels la plupart des entreprises prévoient de migrer leurs applications en 2022.
  • Kotlin est utilisé par des entreprises mondiales telles que Google, Netflix, Amazon, Trello, etc.
  • Plusieurs entreprises dont Google, Pinterest et Uber ont migré leurs applications de Java vers Kotlin.

kotlin utilisé pour quoi ?

Veuillez trouver plus de statiques ici :

Pourquoi passer de Java à Kotlin

Voici quelques arguments qui motivent le passage de Java (version 17 LTS au moment de la rédaction) à Kotlin.

  • Kotlin prend en charge plus de cibles que Java.
  • Kotlin protège des références null à la compilation (les Optional Java sont ne sont pas de protections à la compilation).
  • Les chaînes de caractères Kotlin prennent en charge l'interpolation.
  • Les fonctionnalités de programmation fonctionnelle de Kotlin sont meilleures. Il permet même de définir des constructeurs et des DSL (Domain Specific Language) dont le typage est sécurisé (type-safe).
  • Kotlin peut être mélangé avec du code Java, facilitant ainsi le processus de migration.

Vous pouvez lire plus d'arguments dans ces articles :

Sources et plus de lecture

',19)]))}const d=t(a,[["render",o],["__file","index.html.vue"]]),c=JSON.parse('{"path":"/fr/presentation/","title":"🚀 Présentation de Kotlin","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"Certaines fonctionnalités","slug":"certaines-fonctionnalites","link":"#certaines-fonctionnalites","children":[]},{"level":2,"title":"Histoire","slug":"histoire","link":"#histoire","children":[]},{"level":2,"title":"Quelques chiffres et faits","slug":"quelques-chiffres-et-faits","link":"#quelques-chiffres-et-faits","children":[]},{"level":2,"title":"Pourquoi passer de Java à Kotlin","slug":"pourquoi-passer-de-java-a-kotlin","link":"#pourquoi-passer-de-java-a-kotlin","children":[]},{"level":2,"title":"Sources et plus de lecture","slug":"sources-et-plus-de-lecture","link":"#sources-et-plus-de-lecture","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/presentation/README.md"}');export{d as comp,c as data}; diff --git a/assets/index.html-CIUQNmed.js b/assets/index.html-CIUQNmed.js new file mode 100644 index 0000000..ba2f1b9 --- /dev/null +++ b/assets/index.html-CIUQNmed.js @@ -0,0 +1 @@ +import{_ as a}from"./Kotlin-Beyond-Android-CYulNy7n.js";import{_ as d,c as s,a as r,e as l,b as o,d as i,f as n,r as p,o as u}from"./app-Djq7wF8p.js";const m={};function f(k,e){const t=p("RouteLink");return u(),s("div",null,[e[41]||(e[41]=r('

📅 Workshops

(2023) Android makers : Kotlin Beyond Android

am2023 logo

Workshop link: awl.li/am23-kt

![qr code](../../assets/Androidmakers2023Kotlinshortlink.svg =350x)

Agenda

',7)),l("ul",null,[l("li",null,[o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[0]||(e[0]=[n("Backend development: Rest API with Ktor")])),_:1})]),l("li",null,[e[2]||(e[2]=n("Optional: ")),o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[1]||(e[1]=[n("Backend development: Rest API with node.js and Kotlin/JS")])),_:1})]),l("li",null,[o(t,{to:"/en/front-development/#kotlin-js-and-kotlin-wasm"},{default:i(()=>e[3]||(e[3]=[n("Front-end development: Kotlin/WASM and Kotlin/JS webapp")])),_:1})]),l("li",null,[o(t,{to:"/en/front-development/#compose"},{default:i(()=>e[4]||(e[4]=[n("Front-end development: cross-platform Hello world App with Compose multiplatform")])),_:1})]),e[6]||(e[6]=l("li",null,[l("a",{href:"https://worldline.github.io/learning-kotlin-multiplatform/",target:"_blank",rel:"noopener noreferrer"},"Front-end development: Cross-platform Quiz App with Compose multiplatform")],-1)),l("li",null,[o(t,{to:"/en/other-technologies/#pw-add-a-ktor-server-app"},{default:i(()=>e[5]||(e[5]=[n("Full-stack development: Quiz App with Compose multiplatform and Ktor server")])),_:1})])]),e[42]||(e[42]=r('

(2023) JNation : Let's discover the possibilities of Kotlin

Workshop link: awl.li/jnation23-kt

![qr code](data:image/gif;base64,R0lGODdhkgCSAIAAAAAAAP///ywAAAAAkgCSAAAC/4yPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kwD9o3jho3ogb8D9G4O3o94MAZzyKAzyUQqj9Ecpcp8LoVUrrZb5AKPw+rwixV7u+nrWmFsg8n07bkOhauz+Ls535cwBTEouBdlRzc1FvcW2MhX+PQ36XgnASllOVdmBbi4qdcpaajXWLl1OpGpaupIqbhGKgo1xlDoo8qq5pbKi8eo2Xl7SJuZSMyHHJsburCLWisrLE28HN08y9bEyUyNedgaaP2ZZm7bfS1Nquupbew+De53Xu96/+wJ7/tF6KwNzRCuTQPhKcvXjha5eQ0AhnvFrR+gS+UO4hMnkaK/c//YfiWM1TEkyJEfS9pbddKkSJUkPbpc+dKbHBED0dGrFxHYL1/B0DhzUTPnTZwQ6Y3SNzJjiGPbFOqMtgznMG9h2oEa2muOxaflfILiWI1qQ2o9K/4cSzHbN4TyzLoq+xWRWaYeroaN9I+bXXSwxM2UWawD0z9wd05Muk5vW59pi4rFMFhuYYl7IR60y/hwwccVKvNEmiiyxpZHJydWW/ldqa7btjYLvZh13MuG5dBWtxELbNSK2T3Ei/tuYKOkL4Dl/XmqQd2cLw6XHTNrR4w6I4NVjviv38DAO7cVvXr3b7nYt/etzT2eBdt5CT+n/D02Zq5Kd1GvKrl9fnWbodL//z/fUK+h5NRCWuU0H3XaoXeeU1sxNJqDmvTHVVC3VUfeI9PYtAGHAy5XoGZCCRfcZ54tNeKHq/FF0Ib6VeJQg+N4x5JvdHVjIYMZmsccjBm6UWOLN5Z1lFc76ijjX+BsZmOLIUolYmNShiXgWck41qSB8F0HoHxeMglaBFxaF9uV55lmYnzE+ajaW0eKF6FAPTbFWpprZveQBlYpFpWTOPLJlo/4+XeclfmwGV+AblE544Acwmake5C912WJf073JoYXjvYogelU+ml5MS0YKVIUWjooZ3HZiWdmU7oK6qYZOAqoeN2dCN+roCIaJ5CGbeliGFoWxyqh5nAaZqqn//7p0LAfFYsnqXK2eeiKmfKDGKK3jgjpp8tS6+x4jdG6nKShkuitY7169ySlPMLSZ6loRruWnuoueieX8WpqKnqlKoXfnq5ZNh6F2+maoJDMgUunfQgSDG1mCSNc5mnqoaTiVGol16qGpQG6arpFGnexc2SSW6eISQYrcmKTYhVetZb6FqfD9RWsJskwrxvysLBWeR9g864HMss9Mwr0Wrx5eCx0nV6Zr9IP09ya1A43uTK2ky4I74xu6jtXvfy6x7CZR3ZNLVEpiuuxxXiVbfE+jDZbNYvOzSw1PvYObCTPOH9LFrcHIgu3qMbue3fV/iXe6caqGrrvwZcGKnR0lP/faLJLigpLp8ZFM72nm8pSeqfW7HYuXGprhz7ti81ZK7rOdf+oIdmBFxqj5gp3TXSafLeOXOVvu46524ITHczmGPY9ecLPWjt88Mj3VjHzIc97/a9h24y6r+9OuDDbN584PNRzV4+x1fGwx/H4OZdPOeJei4m+zw2jP5vlMA9JfV31y9y6n6kscOSg1dGe9gAW2Y1fcose+CLnItoYMFkJnNrD/gW7+8EPe3Pa1oMqqJqASAxL4JPVxKKEtMr5yh+mw9WipAWrE/JHfPQrV5iu5q8KEexC+UMgrzyVNDCZ63C1y1QPjxe23sUMU8ZyXgRJhy4foi5onEOWoOg1rif/4o11uXHh9EaoKOWNTl5FG5lpCoeuK+bqMEuynLTyB0GAjQVthqIb04gYQy9hR4BdvGEd8xKc58lwVy2TY+xq5i4tCo+G3zujHw3JlmWpcYACW1+/yEi+R87PQEHxXPbAoyQ5TTJxpoOkhPR2oE+mJ2KifJ3nRrYus30seYn6GxSh1UgLQqmNR6Tl/prWuA4iyY9q29vnFFZKfHUsjxTjnv8Kk6XuKVNyzEShrZDIyzylUHX8g8ksc8YxEW5yjiVk2ZTg582xlTFugIllAOM3ziHOz3HFe+XgljgrChKJnCrKXbeCyTpJkqyXFYPmDrXHwycO7X6mbCUuIaZMbOUo/2pZeycVT2e4VkrQklUk5AkDis0KorKTU8wP3apZTZDCjWri5CI7k/lGhVLPoEps4CVfdyZd3pSgH9tZPj1JwoSC8oHkHCUAdfWy1AV1p0Ql0xjPhUh3mo+WghwmS90oTDL2lI3p6xPKmqjPUcnUhTndJwu5OlWxwrKoHtUjWlHIMDFqVK0uA2EOUfqfU46Tcavrq/uKmbKYflOql4PiBzNmPMEaj6LXGsECZ0jSx851i/rLK4oMZsHMheifgvuqNdPHvlSa9IJiqSQHc6qtkPrudjiDqe4wldDBRnFOZy3gKoFH198B9LUidajsbNutrZpkgbs1arvQ+MMjwgRw7JuZ6Du/KSOGdCecYmVu+Jy71tXK6qzb2ipxQpjI4BZ2owLl7sWUm0HwzlC8maPqvbLS3d4mbbWoWiRZ/wjf855FiJa0nXkV29C4AnKaudUmYxGbWjDWCogA7GZxxAlWBKtQh2alX6H+qh/iLhjAs7Ph9EKLtQyTdp8cDiWEaYDiFKt4xSxusYtfDOMYy3jGNK6xjW+M4xzreAMFAAA7 =350x)

Agenda

',5)),l("ul",null,[l("li",null,[o(t,{to:"/en/presentation/#prerequisites"},{default:i(()=>e[7]||(e[7]=[n("Prerequisutes")])),_:1})]),l("li",null,[e[10]||(e[10]=n("Selection of Kotlin's languages features: ")),o(t,{to:"/en/kotlin-features/#null-safety"},{default:i(()=>e[8]||(e[8]=[n("null safety")])),_:1}),e[11]||(e[11]=n(" and ")),o(t,{to:"/en/kotlin-features/#functions"},{default:i(()=>e[9]||(e[9]=[n("functions")])),_:1})]),l("li",null,[o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[12]||(e[12]=[n("Backend development: Rest API with Ktor")])),_:1})]),l("li",null,[e[14]||(e[14]=n("Optional: ")),o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[13]||(e[13]=[n("Backend development: Rest API with node.js and Kotlin/JS")])),_:1})]),l("li",null,[o(t,{to:"/en/front-development/#kotlin-js-and-kotlin-wasm"},{default:i(()=>e[15]||(e[15]=[n("Front-end development: Kotlin/WASM and Kotlin/JS webapp")])),_:1})]),l("li",null,[o(t,{to:"/en/front-development/#compose"},{default:i(()=>e[16]||(e[16]=[n("Front-end development: cross-platform Hello world App with Compose multiplatform")])),_:1})]),e[18]||(e[18]=l("li",null,[l("a",{href:"https://worldline.github.io/learning-kotlin-multiplatform/",target:"_blank",rel:"noopener noreferrer"},"Front-end development: Cross-platform Quiz App with Compose multiplatform")],-1)),l("li",null,[o(t,{to:"/en/other-technologies/#pw-add-a-ktor-server-app"},{default:i(()=>e[17]||(e[17]=[n("Full-stack development: Quiz App with Compose multiplatform and Ktor server")])),_:1})])]),e[43]||(e[43]=r('

(2023) Mobile DevOps summit

  • Title: From Android to Multiplatform: leveraging the full potential of Kotlin
  • Link: awl.li/mds23-kt

![qr code](../../assets/qrcode-mds2023.gif =200x)

Agenda

',4)),l("ul",null,[l("li",null,[o(t,{to:"/en/other-technologies/#pw-add-a-ktor-server-app"},{default:i(()=>e[19]||(e[19]=[n("Initiate a cross-platform app")])),_:1})]),l("li",null,[e[23]||(e[23]=n("Live examples of other Kotlin possibilities: ")),l("ul",null,[l("li",null,[o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[20]||(e[20]=[n("Backend development: Rest API with Ktor")])),_:1})]),l("li",null,[o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[21]||(e[21]=[n("Backend development: Rest API with node.js and Kotlin/JS")])),_:1})]),l("li",null,[o(t,{to:"/en/front-development/#kotlin-js-and-kotlin-wasm"},{default:i(()=>e[22]||(e[22]=[n("Front-end development: Kotlin/WASM and Kotlin/JS webapp")])),_:1})])])])]),e[44]||(e[44]=l("h2",{id:"_2024-mixit",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#_2024-mixit"},[l("span",null,"(2024) MiXit")])],-1)),e[45]||(e[45]=l("ul",null,[l("li",null,[n("Titre : "),l("strong",null,"Développement front et back en Kotlin. Une visite guidée de KMP")])],-1)),e[46]||(e[46]=l("p",null,"![qr code](../../assets/qrcode-mixtit24.svg =200x)",-1)),e[47]||(e[47]=l("h3",{id:"agenda-3",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#agenda-3"},[l("span",null,"Agenda")])],-1)),l("ul",null,[l("li",null,[o(t,{to:"/en/presentation/#prerequisites"},{default:i(()=>e[24]||(e[24]=[n("Prérequis")])),_:1})]),l("li",null,[e[27]||(e[27]=n("Fonctionnalités notables: ")),o(t,{to:"/en/kotlin-features/#null-safety"},{default:i(()=>e[25]||(e[25]=[n("null safety")])),_:1}),e[28]||(e[28]=n(" et ")),o(t,{to:"/en/kotlin-features/#functions"},{default:i(()=>e[26]||(e[26]=[n("les fonctions")])),_:1})]),l("li",null,[e[32]||(e[32]=l("strong",null,"Développement backend",-1)),l("ul",null,[e[31]||(e[31]=l("li",null,[l("a",{href:"https://speakerdeck.com/yostane/kotlin-pour-le-developpement-backend",target:"_blank",rel:"noopener noreferrer"},"Présentation d'introduction à Kotlin pour le développement backend")],-1)),l("li",null,[o(t,{to:"/en/backend-development/#spring-framework"},{default:i(()=>e[29]||(e[29]=[n("API Rest avec Spring boot")])),_:1})]),l("li",null,[o(t,{to:"/en/backend-development/#ktor"},{default:i(()=>e[30]||(e[30]=[n("API Rest avec Ktor")])),_:1})])])]),l("li",null,[e[34]||(e[34]=l("strong",null,"Développement frontend",-1)),l("ul",null,[l("li",null,[o(t,{to:"/en/front-development/#compose"},{default:i(()=>e[33]||(e[33]=[n('Application "Hello World" avec Compose Multiplatform')])),_:1})])])]),l("li",null,[e[36]||(e[36]=l("strong",null,"Développement fullstack",-1)),l("ul",null,[l("li",null,[o(t,{to:"/en/other-technologies/#pw-add-a-ktor-server-app"},{default:i(()=>e[35]||(e[35]=[n("Application de quiz avec Ktor + Compose Multiplatform")])),_:1})])])]),l("li",null,[e[40]||(e[40]=l("strong",null,"Autres fonctionnalités",-1)),l("ul",null,[l("li",null,[o(t,{to:"/en/front-development/#kotlin-js-and-kotlin-wasm"},{default:i(()=>e[37]||(e[37]=[n("Kotlin/WASM")])),_:1})]),l("li",null,[o(t,{to:"/en/backend-development/#node.js"},{default:i(()=>e[38]||(e[38]=[n("Développement node.js en Kotlin")])),_:1})]),l("li",null,[o(t,{to:"/en/kotlin-features-advanced/#concurrency-and-coroutines"},{default:i(()=>e[39]||(e[39]=[n("Coroutines")])),_:1})])])])])])}const b=d(m,[["render",f],["__file","index.html.vue"]]),A=JSON.parse(`{"path":"/en/workshops/","title":"📅 Workshops","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"(2023) Android makers : Kotlin Beyond Android","slug":"_2023-android-makers-kotlin-beyond-android","link":"#_2023-android-makers-kotlin-beyond-android","children":[{"level":3,"title":"Link","slug":"link","link":"#link","children":[]},{"level":3,"title":"Agenda","slug":"agenda","link":"#agenda","children":[]}]},{"level":2,"title":"(2023) JNation : Let's discover the possibilities of Kotlin","slug":"_2023-jnation-let-s-discover-the-possibilities-of-kotlin","link":"#_2023-jnation-let-s-discover-the-possibilities-of-kotlin","children":[{"level":3,"title":"Link","slug":"link-1","link":"#link-1","children":[]},{"level":3,"title":"Agenda","slug":"agenda-1","link":"#agenda-1","children":[]}]},{"level":2,"title":"(2023) Mobile DevOps summit","slug":"_2023-mobile-devops-summit","link":"#_2023-mobile-devops-summit","children":[{"level":3,"title":"Agenda","slug":"agenda-2","link":"#agenda-2","children":[]}]},{"level":2,"title":"(2024) MiXit","slug":"_2024-mixit","link":"#_2024-mixit","children":[{"level":3,"title":"Agenda","slug":"agenda-3","link":"#agenda-3","children":[]}]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/workshops/README.md"}`);export{b as comp,A as data}; diff --git a/assets/index.html-COrAJfz9.js b/assets/index.html-COrAJfz9.js new file mode 100644 index 0000000..dc544f2 --- /dev/null +++ b/assets/index.html-COrAJfz9.js @@ -0,0 +1,7 @@ +import{_ as I,c as g,a,o as c}from"./app-Djq7wF8p.js";const i={};function e(n,l){return c(),g("div",null,l[0]||(l[0]=[a(`

📚 Kotlin language features

Kotlin is an object oriented language with functional features. This chapter covers important and relevant features of the language slit into basic and intermediate. Another chapter covers advanced features.

Basic features

Basic constructs (variables, control flow)

  • Kotlin is statically typed and supports implicit typing.
    • Static typing: types cannot change on runtime (it is the opposite of dynamic typing).
    • Implicit typing: the compiler can infer the type whenever possible.
  • var creates mutable variables.
  • val creates immutable variables or constants.
  • Semi-colons are optional.
  • Kotlin supports top level declaration of variables and functions (They can be declared outside of classes).
  • String interpolation is available with this syntax \${expression}.
  • if, and when statements are expressions (they can return a value).
    • when is equivalent to the switch statement of other languages
    • The ternary operator is not available but the if statement replaces-it.
  • for-each is the only type of for loop available.
  • Object oriented programming is supported as in Java with some additional features such as extensions.
  • The compiler supports Null Safety. It allows to write code free from null pointer errors with a compile time guarantee.
  • Functional programming is supported (Higher-order functions and functions as 1st class items, etc.).

Use val by default

Replace by var only if needed.

▶️ this code highlights the above features.

Functions

In the this section, the terms 'argument' and 'parameter' are used interchangeably.

Functions in Kotlin have the following features:

  • Declaration: fun functionName(arg1: type1 = defaultvalue1, ...) : retunrType.
  • Call a function by passing the value in the declaration order.
    • Use argument labels for more clarity, however, it also allows for arbitrary ordering of arguments.
  • Optional arguments have a default value and can be omitted during the call.
  • Functions are first class items or citizen: they can be assigned to a variable, passed as a function parameter, or returned from a function.
    • 💡 A function that takes a function as an argument or returns one is a higher order function.
  • A function type can be expressed as follows: (typeOfParam1, typeOfParam2, etc) -> returnType (The empty return type is Unit).
  • Anonymous functions use the following syntax { argName1, argName2, etc. -> // code }
    • Also called or lambda functions or literal functions
  • The last function argument can be put after the closing after the closing parenthesis compute(9, 5) { x, y -> x * y }

▶️ this code highlights the above features.

The next section talk about null safety.

Null safety

In a nutshell, null safety is a compiler feature that eliminates the infamous Null pointer exception or npe. The Kotlin compiler reports errors and warnings when we manipulate nullable (also called optional) values. Here is a list of null safety features provided by Kotlin:

  • All types are non-nullable by default; we cannot assign null to a variable or an argument.
    • For example, this code fails var s: String = null.
  • A type can be made nullable by suffixing it with a ?. For example: var s: String? = null.
  • Kotlin forbids calling a method or a property of a non-nullable type, unless we do one of these possibilities:
    • Use optional chaining with the ? suffix.
    • Provide a default value with the elvis ?: operator.
    • Smart-cast the nullable into a non-nullable.
    • Use the !! operator that eliminates compiler checks. This should never be used.

Never unwrap with !!

Use other safe techniques instead.

▶️ this code illustrates null safety and how to use optional types.

Java \`Optional\` does not provide compile time null checks

Optional wrap null values on runtime. The Java compiler (as of version 17) does not provide unwrapping features such as smart casting. It is still possible to have a npe like this: Optional<String> s = null; s.isPresent();

Enumerations

Enumerations allow to work with a group of values in a type-safe fashion. Unlike Java enums, Kotlin enums are classes. Kotlin enum classes provide these features:

  • when statements support enumerations.
  • Enum constants can declare their own anonymous classes with their corresponding methods, as well as with overriding base methods.
  • An enum class can implement an interface but it cannot derive from a class
  • There are methods for listing the defined enum constants and getting an enum constant by its name.
  • Every enum constant has properties for obtaining its name and position (starting with 0).

▶️ this code illustrated the features above. For further reading please consult the official documentation.

🧪 Exercises

Exercise 1

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Exercise 2

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Intermediate features

Object oriented programming

Kotlin allows to write concise OOP code and has the following features:

  • Available common features: classes, inheritance, interfaces, and abstract classes.
  • Native support of properties: do not define getters and setters unless needed.
    • Just add get() and set(value) functions next to the property declaration.
  • Constructor arguments are defined next to the class name class ClassName(arg1, atg2, )
  • Prefixing a constructor arguments with val or var makes it a property (val makes it read-only).
  • The constructor name is init and does not require parameters.
  • The compiler checks that all non-nullable properties are initialized by the end of the constructor.
    • ⚠️ The compiler does not check the initialization of lateinit properties. Thus, accessing them before while uninitialized causes an exception.
  • Prefix classes with open to allow inheritance.
  • Kotlin enables the public access level by default.
  • The equality operator == calls equals() (as opposed to Java which uses reference equality).
  • A companion object contains static methods and properties.
  • Extensions add function and properties to existing classes.
    • 💡 They replace inheritance in many situations.
    • For example, we can add functions to the String class instead of creating a new StringUtils class.
  • Sealed classes and interfaces cannot be extended or implemented by third parties.

Do not define accessors unless needed

As opposed to Java, Kotlin supports properties and allows to add accessors later without refactoring the code that calls these properties. Thus, by default, just define the name of properties without accessors and use them directly.

▶️ this code illustrates some features.

Data class

Data classes are final (cannot be inherited from) classes that provide standard functionality:

  • equals() and hashCode()
  • toString() of the form "class(field=value, ...)"
  • componentN() that correspond to the properties in their order of declaration.
  • copy()

However, they have the following constraints:

  • The primary constructor needs to have at least one parameter.
  • All primary constructor parameters need to be marked as val or var.
  • They cannot be abstract, open, sealed, or inner (💡 but extensions are possible).

▶️ this code illustrates some features.

Functional programming

General concepts

Functional programming revolves around these concepts: pure functions, recursion, referential transparency, immutable variables, functions as first-class citizens, and higher-order functions.

Let's briefly explain these concepts:

  • Immutable variables means that we cannot change the value of a variable or its properties once it has been created. If we want to do so, we must create a new instance with the new value.
  • Pure functions are functions that do not have side effects and will thus return always the same output given the same input.
  • Functions are first class citizens: they can be assigned to a variable or used in higher-order functions (passed as a function parameter to another function or returned from a function).
  • Referential transparency: means that an expression can be replaced by its result without changing the behavior of the program. Transparency refers to the fact that the implementation of the expression is irrelevant.

💡 Pure functional languages provide these features natively and enforces them (at build time).

Kotlin and functional programming

Kotlin is not a pure functional languages but it supports some features. For example, Kotlin does not have compile time verification of pure functions, but it provides immutable collections through the kotlinx.collections.immutable library.

listOf generates read-only lists, which are not immutable

A read-only list cannot add or remove elements, but it can change the underlying data.

@Test
+fun givenReadOnlyList_whenCastToMutableList_checkNewElementsAdded(){
+    val list: List<String> = listOf("This", "Is", "Totally", "Immutable")
+    (list as MutableList<String>)[2] = "Not"
+    assertEquals(listOf("This", "Is", "Not", "Immutable"), list)
+}
+

The Arrow-kt library add more functional programming features.

Declarative programming

Declarative programming is a famous style within functional programming. It consists of writing code as a chaining of function calls in this style val result = f(x).g(y). .... Higher order functions replace many situation where we would use loops. This favors readable code which is easy to debug an maintain.

▶️ this code show an example of list manipulation using declarative programming.

Kotlin and Java interoperability

  • Kotlin is designed with Java interoperability in mind.
  • Kotlin code may require some annotations to be called from Java.
  • It is possible to mix Java and Kotlin in the same project.
  • JetBrain's IntelliJ and Android Studio can convert to Kotlin when pasting java code.
  • Kotlin generates Java records by annotating a data class with @JvmRecord and targeting JVM 16, among other requirement listed here.
  • It is much more easier and natural to call Java from Kotlin.
    • For example: Java accessors are converted to Kotlin properties.

▶️ this code shows how to convert a Kotlin List to a Java ArrayList.

The official documentation provides exhaustive documentation on Kotlin and JVM integration

🧪 Exercises

Exercise 3

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Exercise 4

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Exercise 5

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Exercise 6

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

Exercise 7

Please click on this link to view the exercise

Please open to see the solution(s)

Solution

📖 Further reading

`,77)]))}const s=I(i,[["render",e],["__file","index.html.vue"]]),t=JSON.parse('{"path":"/en/kotlin-features/","title":"📚 Kotlin language features","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Basic features","slug":"basic-features","link":"#basic-features","children":[{"level":3,"title":"Basic constructs (variables, control flow)","slug":"basic-constructs-variables-control-flow","link":"#basic-constructs-variables-control-flow","children":[]},{"level":3,"title":"Functions","slug":"functions","link":"#functions","children":[]},{"level":3,"title":"Null safety","slug":"null-safety","link":"#null-safety","children":[]},{"level":3,"title":"Enumerations","slug":"enumerations","link":"#enumerations","children":[]},{"level":3,"title":"🧪 Exercises","slug":"🧪-exercises","link":"#🧪-exercises","children":[]}]},{"level":2,"title":"Intermediate features","slug":"intermediate-features","link":"#intermediate-features","children":[{"level":3,"title":"Object oriented programming","slug":"object-oriented-programming","link":"#object-oriented-programming","children":[]},{"level":3,"title":"Data class","slug":"data-class","link":"#data-class","children":[]},{"level":3,"title":"Functional programming","slug":"functional-programming","link":"#functional-programming","children":[]},{"level":3,"title":"Kotlin and Java interoperability","slug":"kotlin-and-java-interoperability","link":"#kotlin-and-java-interoperability","children":[]},{"level":3,"title":"🧪 Exercises","slug":"🧪-exercises-1","link":"#🧪-exercises-1","children":[]}]},{"level":2,"title":"📖 Further reading","slug":"📖-further-reading","link":"#📖-further-reading","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/kotlin-features/README.md"}');export{s as comp,t as data}; diff --git a/assets/index.html-CcuJhM9n.js b/assets/index.html-CcuJhM9n.js new file mode 100644 index 0000000..7da026c --- /dev/null +++ b/assets/index.html-CcuJhM9n.js @@ -0,0 +1 @@ +import{_ as t}from"./kmp_codelab-CiTPMWjt.js";import{_ as a,c as o,a as r,o as i}from"./app-Djq7wF8p.js";const n={};function l(s,e){return i(),o("div",null,e[0]||(e[0]=[r('

🛠 Let's make a cross-plaform app !

By combining KMP and Compose, it is possible to fully develop cross-platform mobile, web and desktop apps using only Kotlin.

Prerequisites

  • Basic knowledge of kotlin development (nullability,inline & lambda functions mainly)
  • Android Studio IDE with latest stable version Giraffe version or above
  • A good connectivity

Tips

For more information about your DEV environment and installs please have a look to jetbrain related docs

_____ 🚀 Start the practical work here 🚀_____

kmp codelab

',7)]))}const c=a(n,[["render",l],["__file","index.html.vue"]]),h=JSON.parse(`{"path":"/en/other-technologies/","title":"🛠 Let's make a cross-plaform app !","lang":"en-US","frontmatter":{},"headers":[],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/other-technologies/README.md"}`);export{c as comp,h as data}; diff --git a/assets/index.html-CeMqYfna.js b/assets/index.html-CeMqYfna.js new file mode 100644 index 0000000..77358e1 --- /dev/null +++ b/assets/index.html-CeMqYfna.js @@ -0,0 +1 @@ +import{_ as t,c as i,a as n,o as r}from"./app-Djq7wF8p.js";const l={};function a(s,e){return r(),i("div",null,e[0]||(e[0]=[n('

Conseil

This training is also available in English / Cette formation est aussi disponible en Anglais

Prerequisites

  • Connaissance de base en language de programmation orienté object comme Java
  • Préparez votre environnement de développement et installez des éléments avant la session (voir la section Outillage)

Liens utiles

',5)]))}const m=t(l,[["render",a],["__file","index.html.vue"]]),p=JSON.parse(`{"path":"/fr/","title":"","lang":"fr-FR","frontmatter":{"home":true,"heroImage":"./kotlin_logo.png","tagline":"A beginner's guide to a modern programming language","actions":[{"text":"Débuter →","link":"/fr/presentation/","type":"primary"}],"features":[{"title":"Bien commencer avec Kotlin","details":"lorem"},{"title":"Syntaxe de base","details":"lorem"},{"title":"Exemples","details":"lorem"}],"footer":"Worldline, 2021"},"headers":[{"level":2,"title":"Prerequisites","slug":"prerequisites","link":"#prerequisites","children":[]},{"level":2,"title":"Liens utiles","slug":"liens-utiles","link":"#liens-utiles","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/index.md"}`);export{m as comp,p as data}; diff --git a/assets/index.html-D-c6bFFq.js b/assets/index.html-D-c6bFFq.js new file mode 100644 index 0000000..d375f50 --- /dev/null +++ b/assets/index.html-D-c6bFFq.js @@ -0,0 +1 @@ +import{_ as t}from"./kotlin-used-for-Bdlavnqs.js";import{_ as i,c as o,a as n,o as r}from"./app-Djq7wF8p.js";const a="/learning-kotlin/assets/kotlin-decision-tree-4i7nEr1Z.svg",l={};function s(h,e){return r(),o("div",null,e[0]||(e[0]=[n('

🚀 Presentation of Kotlin

Kotlin is a modern programming language developed by JetBrains.

Some features

  • Kotlin compiles to many targets: the JVM, JS, WASM, Android, iOS, Desktop, native code, etc.
    • Many server frameworks officially support Kotlin such as Spring and Quarkus.
    • It is the first-class language for writing Android.
    • Kotlin can compile to native with Kotlin native or with GraalVM.
    • KMP allows to share code between different platforms.
  • Kotlin can be considered as both fullstack and corss-platform language.
  • Inter-operable with Java.
  • Provides modern features such as compile-time null safety and data classes.
  • Supports Object oriented programming and functional programming.
  • Kotlin KEEP is its open source evolution process.

History

  • February 15, 2016: Kotlin 1.0 was released.
  • January 04, 2017: Spring introduced Kotlin support in Spring 5.
  • At Google I/O 2017, Google announced first-class support for Kotlin on Android.
  • On 7 May 2019, Google announced that Kotlin the preferred language for Android app developers.
  • June 2022: Kotlin 1.7 was released with the version of the new K2 compiler.

Some numbers and facts

Source: Amyra Sheldon

  • As of 2022, Kotlin is used by 7.8% of the industry experts.
  • According to StackOverflow, Kotlin was the 4th most beloved language in 2020 with 62.9% votes.
  • Kotlin is now listed among the top 20 programming languages by Redmonk.
  • Kotlin is among the top 3 languages that most businesses are planning to migrate their apps to in 2022.
  • Kotlin is used by global companies like Google, NetFlix, Amazon, Trello, and more.
  • Pinterest and Uber are among the companies that migrated their apps to Kotlin from Java.

kotlin used for what?

Please find more statics here:

Why switch from Java to Kotlin

Here are some arguments that motivate switching from Java (version 17 LTS at the time of writing) to Kotlin.

  • Kotlin supports more targets than Java.
  • Kotlin has compile time null-safety (Java Optionals are runtime wrappers for nullable values and null annotations have less features).
  • Kotlin strings support interpolation.
  • Casting in Kotlin is smart.
  • Kotlin functional programming features are better. It even allows to define Type-Safe builders and DSLs.
  • Kotlin can be mixed with Java code, thus helping the migration process.

You can read more arguments in these articles:

A decision tree to help you decide if you should use Kotlin

decision tree

Prerequisites

  • Recommended: IntelliJ IDEA (Both community or ultimate are OK),
  • or GitPod by opening https://gitpod.io/#https://github.com/worldline/learning-kotlin to create a workspace and then browser to the material folder,
  • or VSCode (with Kotlin and Java plugins) + JDK 17 (install via scoop.sh on windows or SDK man on Unix) + gradle

📖 Further reading

',23)]))}const p=i(l,[["render",s],["__file","index.html.vue"]]),m=JSON.parse('{"path":"/en/presentation/","title":"🚀 Presentation of Kotlin","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Some features","slug":"some-features","link":"#some-features","children":[]},{"level":2,"title":"History","slug":"history","link":"#history","children":[]},{"level":2,"title":"Some numbers and facts","slug":"some-numbers-and-facts","link":"#some-numbers-and-facts","children":[]},{"level":2,"title":"Why switch from Java to Kotlin","slug":"why-switch-from-java-to-kotlin","link":"#why-switch-from-java-to-kotlin","children":[]},{"level":2,"title":"A decision tree to help you decide if you should use Kotlin","slug":"a-decision-tree-to-help-you-decide-if-you-should-use-kotlin","link":"#a-decision-tree-to-help-you-decide-if-you-should-use-kotlin","children":[]},{"level":2,"title":"Prerequisites","slug":"prerequisites","link":"#prerequisites","children":[]},{"level":2,"title":"📖 Further reading","slug":"📖-further-reading","link":"#📖-further-reading","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/presentation/README.md"}');export{p as comp,m as data}; diff --git a/assets/index.html-DI1rj2RX.js b/assets/index.html-DI1rj2RX.js new file mode 100644 index 0000000..1c3c62f --- /dev/null +++ b/assets/index.html-DI1rj2RX.js @@ -0,0 +1,13 @@ +import{_ as n,c as s,a,o as t}from"./app-Djq7wF8p.js";const l={};function c(i,e){return t(),s("div",null,e[0]||(e[0]=[a(`

📚 Fonctionnalités avancées de Kotlin

Propriétés déléguées

Kotlin permet de déléguer le getter et le setter d'une propriété à un autre objet, appelé délégué. C'est une classe qui définit les méthodes getValue et setValue.

Kotlin fournit des délégués standard tels que des propriétés paresseuses et des propriétés observables.

▶️ this code illustrates delegate properties.

Concurrence et coroutines

Kotlin fournit un modèle de concurrence de haut niveau appelé Coroutines. Le développeur peut déléguer la gestion des threads au compilateur et à l'exécution et utiliser des constructions de niveau supérieur aux threads pour exprimer des opérations asynchrones.

Les coroutines de Kotlin tournent autour de ces concepts :

  • Une coroutine est une instance de calcul suspendable.
    • Kotlin a de nombreuses méthodes pour créer une coroutine telle que launch.
  • Une coroutine doit exister dans une portée de coroutine.
    • Par exemple, runBlocking crée une portée de coroutine dans laquelle les coroutines peuvent être lancées.
  • Une coroutine peut exécuter des fonctions de suspension qui peuvent suspendre la coroutine mais ne bloquent pas le thread.
    • Par exemple : le delay suspend la coroutine mais ne bloque pas le thread sur lequel elle s'exécute.
    • Les fonctions de suspension sont des opérations qui peuvent prendre du temps telles que les requêtes http et les appels au système de fichiers.
  • Le qualificateur suspend définit une fonction de suspension. Il s'exécute dans une coroutine et peut appeler d'autres fonctions de suspension.
  • Flow permet de générer une liste de valeurs asynchrones.
  • Deferred et Channel transfèrent respectivement une valeur unique et un flux de valeurs entre coroutines.

▶️ this code show how to create a coroutine and suspend function and how to use them.

▶️ this code illustrated flows.

▶️ this code illustrates channels and deferred.

Littéral de fonction avec récepteur et constructeurs de type sécurisé

Comme vu précédemment, les extensions de fonctions ajoute du comportement à des classes existantes sans utiliser l'héritage. À l'intérieur de la définition de l'extension de fonction, nous pouvons référencer implicitement le récepteur d'extension (this).

fun String.countCharacters() = length // or this.length
+println("hello".countCharacters()) // prints 5
+

Nous pouvons définir cette extension avec une fonction littérale (ou lambda) au lieu d'une fonction classique (déclarée avec fun).

var extFn: String.() -> Int
+extFn = { length } // extFn is a function literal
+println("hello".extFn()) // prints 5
+println(extFn("hello")) // prints 5
+

extFn est une fonction littérale (lambda) qui a accès au récepteur (this). C'est pourquoi on l'appelle une fonction littérale avec récepteur.

extFn("hello") ou extFn("hello") appelle l'extension comme prévu par les fonctions d'extension.

Le type d'une fonction littérale avec récepteur est funName: ReceiverType.(arg1Type, arg2Type, etc.) -> ReturnType et est appelé avec funName(receiverValue, arg1Value, etc.) ou receiverValue.funName(arg1Value, etc.) .). Cependant, ce n'est pas l'aspect le plus intéressant.

La partie importante est extFn = { length } qui peut être placée comme argument de fonction dans une fonction d'ordre supérieur. Le développeur qui appelle la fonction d'ordre supérieur doit définir extFn, qui à son tour a accès au récepteur. Cela permet un style de programmation assez intéressant.

▶️ ce code montre un example.

Les Type-safe builders combinent les monteurs bien nommées et les fonctions littérales avec récepteur pour créer des monteur avec un typage statique et sécurisé. La syntaxe particulière possible avec technique permet de définir une sorte de sous-langage aussi appelé DSL (domain specific language).

Le pattern monteur (Builder)

Est une technique permettant de construire des objects avec une syntaxe élégante.

// StirngBuilder uses the builder pattern
+val text = StringBuilder("Temp")
+  .append(1)
+  .append(true)
+  .append("friend")
+  .toString()
+

Ce code montre un type-safe builder basique.

Kotlin docs fournit un exemple plus avancé d'un monteur de documents HTML.

Exercises

Exercise 1

  1. open the java-integration-exercise projects in the materials folder.
  2. Have a look at the Java class we provided you in the src/main/java/com/worldline/learning/kotlin/java2kotlin package. (yes, that's the Pokemon class)
  3. Convert that Java class in Kotlin using IntelliJ's awesome copy-pasta tool! (just copy paste the java code in a kotlin file, one is provided at src/main/kotlin/com/worldline/learning/kotlin/java2kotlin)
  4. Have a look at the generated Kotlin code, and note the major differences you spot!
`,29)]))}const p=n(l,[["render",c],["__file","index.html.vue"]]),u=JSON.parse('{"path":"/fr/kotlin-features-advanced/","title":"📚 Fonctionnalités avancées de Kotlin","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"Propriétés déléguées","slug":"proprietes-deleguees","link":"#proprietes-deleguees","children":[]},{"level":2,"title":"Concurrence et coroutines","slug":"concurrence-et-coroutines","link":"#concurrence-et-coroutines","children":[]},{"level":2,"title":"Littéral de fonction avec récepteur et constructeurs de type sécurisé","slug":"litteral-de-fonction-avec-recepteur-et-constructeurs-de-type-securise","link":"#litteral-de-fonction-avec-recepteur-et-constructeurs-de-type-securise","children":[]},{"level":2,"title":"Exercises","slug":"exercises","link":"#exercises","children":[{"level":3,"title":"Exercise 1","slug":"exercise-1","link":"#exercise-1","children":[]}]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/kotlin-features-advanced/README.md"}');export{p as comp,u as data}; diff --git a/assets/index.html-DgauC6Dk.js b/assets/index.html-DgauC6Dk.js new file mode 100644 index 0000000..378c867 --- /dev/null +++ b/assets/index.html-DgauC6Dk.js @@ -0,0 +1,195 @@ +import{_ as c,c as r,a as l,b as e,d as t,r as o,o as u,e as n,f as s}from"./app-Djq7wF8p.js";const d={};function k(m,a){const i=o("CodeGroupItem"),p=o("CodeGroup");return u(),r("div",null,[a[2]||(a[2]=l(`

📚 Développement du backend

De nombreux frameworks supportent officiellement Kotlin comme Spring, Quarkus et Ktor, parmi d'autres listés ici.

En outre, Kotlin est théoriquement compatible avec tout framework qui cible la JVM ou JS. Cependant, les frameworks qui ne supportent pas officiellement Kotlin peuvent nécessiter quelques ajustements pour l'utiliser.

Ktor

Ktor est une bibliothèque Kotlin multiplateforme permettant de développer des clients et des serveurs HTTP. Cela fait de Ktor une bibliothèque utile à la fois aux développeurs frontend, pour la partie client HTTP, ainsi qu'aux développeurs backend, pour la partie serveur HTTP. Dans ce qui suit, nous allons créer une API REST avec le serveur Ktor.

TP : développer une API avec Ktor

  • Créez un projet sur start.ktor.io avec les plugins suivants : Content Negotiation, kotlinx.serialization, et Routing.
  • Cliquez sur "Generate project".
  • Téléchargez l'archive, décompressez-la et ouvrez le projet avec votre IDE préféré.
  • Créez un package models et ajoutez-y une classe de données Customer avec ces propriétés immuables id : String, firstName : String, lastName : Chaîne, email : Chaîne.
  • Annotez la classe avec @Serializable.
  • Créez un nouveau package nommé routes et ajoutez-y un fichier CustomerRoutes.kt qui contiendra le code pour l'endpoint /customer.
  • Le code ci-dessous fournit l'implémentation de certains endpoints. Veuillez implémenter les autres.
  • Pour activer la route, appelez customerRouting() dans le fichier de configuration du routage situé dans plugins/Routing.kt.
  • Pour plus de simplicité, utilisez une liste globale de clients en mémoire val store = mutableListOf<Customer>().
  • Lancer le serveur en exécutant la méthode main.
  • Tester l'API sur l'IDE en utilisant un fichier http ou en utilisant n'importe quel autre client.
CustomerRoutes.kt
val store = mutableListOf<Customer>()
+
+fun Route.customerRouting() {
+  route("/customer") {
+    get {
+      call.respond(store)
+    }
+    get("{id?}") {
+      val id = call.parameters["id"] ? : return@get call.respondText(
+        "Missing id",
+        status = HttpStatusCode.BadRequest
+      )
+      val customer =
+        store.find { it.id == id } ? : return@get call.respondText(
+          "Pas de client avec l'id $id",
+          status = HttpStatusCode.NotFound
+        )
+      call.respond(customer)
+    }
+    post {
+      val customer = call.receive<Customer>()
+      store.add(customer)
+      call.respondText("Customer stored correctly", status = HttpStatusCode.Created)
+    }
+    delete("{id?}") {
+      // TODO
+    }
+  }
+}
+
+
plugins/Routing.kt
fun Application.configureRouting() {
+    routing {
+        customerRouting()
+    }
+}
+

return@label

Vous pouvez spécifier le niveau que vous voulez retourner avec un label explicite en utilisant return@lambda.

lambdaA {
+    lambdaB {
+        lambdaC {
+            val randomInt = Random.nextInt(0, 100)
+            if (randomInt > 50) return@lambdaC else return@lambdaB
+        }
+        printf("In lambdaB")
+    }
+}
+

Ce code exécute un autre exemple.

CustomerTest.http
POST http://127.0.0.1:8080/customer
+Content-Type : application/json
+
+{
+  "id" : "100",
+  "firstName" : "Jane",
+  "lastName" : "Smith",
+  "email" : "jane.smith@company.com"
+}
+
+
+###
+POST http://127.0.0.1:8080/customer
+Content-Type : application/json
+
+{
+  "id" : "200",
+  "firstName" : "John",
+  "lastName" : "Smith",
+  "email" : "john.smith@company.com"
+}
+
+###
+POST http://127.0.0.1:8080/customer
+Content-Type : application/json
+
+{
+  "id" : "300",
+  "firstName" : "Mary",
+  "lastName" : "Smith",
+  "email" : "mary.smith@company.com"
+}
+
+
+###
+GET http://127.0.0.1:8080/customer
+Accept : application/json
+
+###
+GET http://127.0.0.1:8080/customer/200
+Accepte : application/json
+
+###
+GET http://127.0.0.1:8080/customer/500
+Accepte : application/json
+
+###
+DELETE http://127.0.0.1:8080/customer/100
+
+###
+DELETE http://127.0.0.1:8080/customer/500
+

Cette page contient des étapes détaillées

node.js

Grâce à Kotlin/JS, nous pouvons écrire des applications qui ciblent node.js en utilisant Kotlin.

On peut même importer des librairies npm à condition de déclarer les API JS que l'on va utiliser en Kotlin. C'est ce qu'on appelle une déclaration externe (vous pouvez la considérer comme un équivalent des définitions de type de TypeScript) qui déclare les symboles auxquels nous voulons accéder en Kotlin grâce aux annotations @JsModule et @JsNonModule. Définir de telles déclarations externes peut s'avérer fastidieux et il ne semble pas y avoir de générateur automatique officiel et stable (dukat a été supprimé dans kotlin 1.8.20). Dans ce cas, nous avons deux options, soit écrire la déclaration externe nous-même, soit l'importer en tant que dépendance si elle est disponible.

Heureusement pour nous, le prochain TP utilise la librairie Express pour laquelle nous pouvons trouver une déclaration de type externe.

TP : API Rest avec Kotlin/JS et Express

  • Dans IntelliJ, créer un nouveau projet node.js
  • Une fois le projet chargé, éditer build.gradle.ts comme suit :
implementation(npm("express", "> 4.0.0 < 5.0.0"));
+implementation("dev.chriskrueger:kotlin-express:1.2.0");
+
  • Modifiez main.kt comme suit. Cela crée un serveur API REST qui écoute le port 3000 et fournit une route GET /hello.
data class Message(val id : Int, val message : String)
+
+fun main() {
+    val messages = listOf(Message(0, "I love Kotlin/JS"))
+    val app = express.Express()
+    app.get("/hello") { req, res ->
+        res.send(messages)
+    }
+
+    app.listen(3000) {
+        console.log("server start at port 3000")
+    }
+}
+
  • Exécutez la tâche nodeRun depuis votre IDE ou depuis la ligne de commande (si vous avez installé Gradle).
    • Si vous rencontrez une erreur avec Yarn lock, exécutez la tâche kotlinUpgradeYarnLock puis réessayez.
  • Ajouter des routes en POST, PUT et DELETE
  • En ce qui concerne le corps du POST, Express positionne req.body à undefined à moins que nous ne spécifions un body parser.
    • Pour un corps en JSON, nous devons appeler app.use(bodyParser.json()).
    • bodyParser est une bibliothèque npm et malheureusement, chrisnkrueger/kotlin-express ne fournit pas de définition externe pour bodyParser au moment de l'écriture de ces lignes (chrisnkrueger/kotlin-express en version 1.2.0).
    • Pouvez-vous essayer de la définir vous-même en lisant le code de la bibliothèque ?
    • Vous pouvez trouver une solution ici

Spring framework

Spring est un framework célèbre pour le développement d'applications côté serveur : API REST, pages web générées par le serveur, microservices, etc. Il s'appuie sur l'écosystème Java pour la compilation et l'exécution, ce qui le rend compatible avec Kotlin. Mieux encore, Spring supporte officiellement Kotlin. On peut même démarrer un nouveau projet avec Kotlin et Gradle-Kotlin. Dans la prochaine section, nous utiliserons ce projet pour recréer notre API REST plus haut avec Spring.

TP : Spring boot part 1 - développer la même API avec Spring Boot

  • Créez un projet sur start.spring.io (aussi appelé Spring initializr) avec les dépendances suivantes : Spring Web et Spring Boot DevTools.
  • Choisissez Kotlin comme langage et Kotlin-Grade comme gestionnaire de projet.
  • Ajoutez les dépendances suivantes : Spring Web et Spring Boot DevTools.
  • Cliquez sur Generate. Téléchargez l'archive, décompressez-la et ouvrez le projet avec IntelliJ (de préférence) ou VSCode.
  • Vérifiez que la partie plugins build.gradle.kts utilise la dernière version de Kotlin. Voici à quoi cela devrait ressembler avec Kotlin 1.8.10 :
plugins {
+  id("org.springframework.boot") version "3.0.4"
+  id("io.spring.dependency-management") version "1.1.0"
+  kotlin("jvm") version "1.8.10"
+  kotlin("plugin.spring") version "1.8.10"
+}
+
  • Créez la data class Customer dans le package model (sans l'annotation @Serializable).
  • Créez un paquetage controller qui contient une classe CustomerController qui fournit un CRUD en utilisant une liste globale.
    • Vous pouvez trouver un squelette ci-dessous.
    • 💡 Dans Spring, les contrôleurs Rest servent de routes Ktor, où un contrôleur définit une ressource REST.
  • Définissez les mêmes routes que dans le TP précédent.
  • Démarrez le serveur de l'API REST en exécutant :
    • Sur Powershell : .\\gradlew.bat bootRun
    • Tout shell Unix : .\\gradlew bootRun
    • Ou bien, vérifiez si votre IDE fournit déjà des configurations d'exécution pour les projets Spring Boot.
  • Veuillez tester les routes avec un client REST. Vous pouvez trouver des fichiers http ici au format JetBrains ou au format de l'extension REST Client de VSCode
CustomerController.kt
val store = mutableListOf<Customer>()
+
+@RestController
+@RequestMapping("/customer")
+class CustomerController {
+    @GetMapping
+    fun getAll() = store
+
+    @GetMapping("{id}")
+    fun getById(@PathVariable id : String) { /* TODO : implement */ }
+
+    @PostMapping
+    fun addOne(@RequestBody customer : Customer) { /* TODO : implement */ }
+
+    @DeleteMapping("{id}")
+    fun deleteOne(@PathVariable id : String) { /* TODO : implement */ }
+}
+

TP : Spring boot partie 2 - ajouter une base de données

Allons un peu plus loin en stockant des données dans une base de données et en écrivant quelques tests.

Nous utiliserons la base de données en mémoire H2 pour des raisons de simplicité, puisqu'elle ne nécessite pas de serveur pour fonctionner. Les classes seront mappées aux tables de la base de données avec des annotations JPA. L'API de base de données que nous utiliserons s'appelle JPARepository. C'est une API légère qui fournit des fonctionnalités CRUD communes à partir d'une simple une interface.

  • Créez un nouveau projet Spring en utilisant Spring initializr avec Kotlin et les dépendances suivantes : Spring Data JPA, H2 Database, Spring Boot DevTools, Spring Web.
  • Ouvrez le projet et ajoutez cette classe dans le package model @Entity class Product(@Id @GeneratedValue var id : Long ? = null, var name : String, var price : Int). Ceci définit la classe ainsi que les annotations JPA minimales (@Entity, @Id et @GeneratedValue) pour générer la table correspondante.
  • Dans le package repository, déclarez l'interface ProductRepository comme suit interface ProductRepository : JpaRepository<Produit, Long>. C'est suffisant pour que Spring génère une implémentation avec des caractéristiques communes comme nous le verrons plus tard.
  • Ensuite, créez une classe ProductService qui contiendra la logique métier. En termes d'architecture, le contrôleur appelle un service qui, à son tour, s'appuie sur d'autres services ou référentiels.
ProductService.kt
@Service
+class ProductService(@Autowired val productRepository: ProductRepository) {
+    fun getAll() = productRepository.findAll()
+
+    // use findByIdOrNull instad of findById because the latter returns an optional<Product> instead of Product?
+    fun getById(id: Long) = productRepository.findByIdOrNull(id)
+}
+
  • Dans le package controller, créez une classe ProductController qui est mappée à /product et injectée avec @Autowired. Répondez à @Get comme suit.
ProductController.kt
@RestController
+@RequestMapping("/product")
+class ProductController(@Autowired val productService : ProductService) {
+    @GetMapping fun getAll() = productService.getAll()
+
+    @GetMapping("{id}")
+    fun getById(@PathVariable id : Long) =
+        productService.getById(id) ? : throw ResponseStatusException(HttpStatus.NOT_FOUND)
+}
+

Kotlin rend getById(@PathVariable id : Long) plus concis

L'opérateur Elvis ?: permet de simplifier le code. Voici une version plus longue en guise de référence.

@GetMapping("{id}")
+fun getById(@PathVariable id : Long) : Produit {
+    val product = productService.getById(id)
+    if (product != null){
+        return product
+    }
+    throw ResponseStatusException(HttpStatus.NOT_FOUND)
+}
+

En outre, Spring fournit @ControllerAdvice pour modifier le message d'exception. Vous pouvez voir un [exemple ici] (https://spring.io/guides/tutorials/rest/).

  • Exécutons le projet. Avant de lancer le projet, nous devons ajouter un plugin qui permet aux classes Kotlin de générer un constructeur par défaut id("org.jetbrains.kotlin.plugin.jpa") version "1.8.10". Les plugins devraient ressembler à ce qui suit :
plugins {
+  id("org.jetbrains.kotlin.plugin.jpa") version "1.8.10"
+  id("org.springframework.boot") version "3.0.4"
+  id("io.spring.dependency-management") version "1.1.0"
+  kotlin("jvm") version "1.8.10"
+  kotlin("plugin.spring") version "1.8.10"
+}
+
+
  • En guise d'exercice, implémentez ces routes : POST d'un seul produit, DELETE par id (/produit/{id}) et GET par id (/produit/{id}).
    • Indice : ProductController fournit déjà les méthodes nécessaires.
  • Appelez les différents points de terminaison avec un client REST.
  • Tester votre API Rest avec un client HTTP

TP : Spring boot partie 3 - ajouter des tests

Les frameworks Spring permettent d'effectuer différents types de tests en fournissant différentes classes dès le départ :

  • Tests unitaires/de composants des services et de l'API REST. Cela se fait par le biais d'utilitaires de bouchonnage tels que MockMVC.
  • Tests d'intégration de l'API REST en utilisant TestRestTemplate. Dans ce cas, un serveur complet est exécuté et testé.

La plupart des classes fournies par Spring, si ce n'est toutes, offrent une syntaxe élégante pour les développeurs Java. Certaines d'entre elles vont plus loin en tirant parti des caractéristiques spécifiques de Kotlin. Dans ce qui suit, nous allons nous concentrer sur les parties qui fournissent des DSLs Kotlin, à savoir le test unitaire de l'API REST avec MockMVC.

  • Créer une classe de test ProductControllerUnitTests avec le contenu initial ci-dessous. MockMvc permet de tester unitairement l'API REST. L'annotation @AutoConfigureMockMvc permet à Spring de la configurer automatiquement.
@SpringBootTest
+@AutoConfigureMockMvc
+classe ProductControllerTests(
+    @Autowired val mockMvc : MockMvc,
+    @Autowired val productRepository : ProductRepository) {
+
+    @BeforeEach
+    fun reset(){
+        productRepository.deleteAll()
+    }
+}
+
  • Ajoutez les deux tests ci-dessous. Le premier utilise une approche classique tandis que le second tire parti des capacités du DSL de Kotlin. De plus, nous utilisons une chaîne littérale plus lisible.
`,47)),e(p,null,{default:t(()=>[e(i,{title:"Sans DSL (Test Get All)"},{default:t(()=>a[0]||(a[0]=[n("div",{class:"language-kotlin line-numbers-mode","data-highlighter":"prismjs","data-ext":"kt","data-title":"kt"},[n("pre",null,[n("code",null,[n("span",{class:"line"},[n("span",{class:"token annotation builtin"},"@Test")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token keyword"},"fun"),s(),n("span",{class:"token function"},"testWithClassicApproach"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" mockMvc"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"perform"),n("span",{class:"token punctuation"},"("),n("span",{class:"token keyword"},"get"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"/product"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"status"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),s("isOk"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"content"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"string"),n("span",{class:"token punctuation"},"("),n("span",{class:"token function"},"containsString"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"[]"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},")")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"})])]),n("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"})])],-1)])),_:1}),e(i,{title:"Avec DSL (Test Get Single)"},{default:t(()=>a[1]||(a[1]=[n("div",{class:"language-kotlin line-numbers-mode","data-highlighter":"prismjs","data-ext":"kt","data-title":"kt"},[n("pre",null,[n("code",null,[n("span",{class:"line"},[n("span",{class:"token annotation builtin"},"@Test")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token keyword"},"fun"),s(),n("span",{class:"token function"},"`test GET a single product`"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" mockMvc"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"get"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"/product/1"')]),n("span",{class:"token punctuation"},")"),n("span",{class:"token punctuation"},"."),n("span",{class:"token function"},"andExpect"),s(),n("span",{class:"token punctuation"},"{")]),s(` +`),n("span",{class:"line"},[s(" status "),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"isOk"),n("span",{class:"token punctuation"},"("),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token function"},"jsonPath"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"$.name"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"value"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"A"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token function"},"jsonPath"),n("span",{class:"token punctuation"},"("),n("span",{class:"token string-literal singleline"},[n("span",{class:"token string"},'"$.price"')]),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"value"),n("span",{class:"token punctuation"},"("),n("span",{class:"token number"},"1"),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" content "),n("span",{class:"token punctuation"},"{"),s(),n("span",{class:"token function"},"contentType"),n("span",{class:"token punctuation"},"("),s("MediaType"),n("span",{class:"token punctuation"},"."),s("APPLICATION_JSON"),n("span",{class:"token punctuation"},")"),s(),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[s(" "),n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"},[n("span",{class:"token punctuation"},"}")]),s(` +`),n("span",{class:"line"})])]),n("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"}),n("div",{class:"line-number"})])],-1)])),_:1})]),_:1}),a[3]||(a[3]=l(`
  • En guise d'exercice, écrire des tests pour les autres points d'accès.

Le constructeur de requêtes de JpaRepository

Les repository Spring implémentent des requêtes basées sur le nom de leurs méthodes. Par exemple, pour obtenir tous les produits triés par nom, nous pouvons ajouter cette méthode à l'interface.

interface ProductRepository : JpaRepository<Produit, Long> {
+    fun findAllByOrderByNameAsc() : List<Produit> ;
+}
+

La [documentation officielle] (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation) fournit des explications et des exemples plus détaillés.

Projets terminés

Aller plus loin

Ces tutoriels officiels vont encore plus loin :

Lien et références

`,9))])}const g=c(d,[["render",k],["__file","index.html.vue"]]),b=JSON.parse('{"path":"/fr/backend-development/","title":"📚 Développement du backend","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"Ktor","slug":"ktor","link":"#ktor","children":[{"level":3,"title":"TP : développer une API avec Ktor","slug":"tp-developper-une-api-avec-ktor","link":"#tp-developper-une-api-avec-ktor","children":[]}]},{"level":2,"title":"node.js","slug":"node-js","link":"#node-js","children":[{"level":3,"title":"TP : API Rest avec Kotlin/JS et Express","slug":"tp-api-rest-avec-kotlin-js-et-express","link":"#tp-api-rest-avec-kotlin-js-et-express","children":[]}]},{"level":2,"title":"Spring framework","slug":"spring-framework","link":"#spring-framework","children":[{"level":3,"title":"TP : Spring boot part 1 - développer la même API avec Spring Boot","slug":"tp-spring-boot-part-1-developper-la-meme-api-avec-spring-boot","link":"#tp-spring-boot-part-1-developper-la-meme-api-avec-spring-boot","children":[]},{"level":3,"title":"TP : Spring boot partie 2 - ajouter une base de données","slug":"tp-spring-boot-partie-2-ajouter-une-base-de-donnees","link":"#tp-spring-boot-partie-2-ajouter-une-base-de-donnees","children":[]},{"level":3,"title":"TP : Spring boot partie 3 - ajouter des tests","slug":"tp-spring-boot-partie-3-ajouter-des-tests","link":"#tp-spring-boot-partie-3-ajouter-des-tests","children":[]},{"level":3,"title":"Projets terminés","slug":"projets-termines","link":"#projets-termines","children":[]}]},{"level":2,"title":"Aller plus loin","slug":"aller-plus-loin","link":"#aller-plus-loin","children":[]},{"level":2,"title":"Lien et références","slug":"lien-et-references","link":"#lien-et-references","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/backend-development/README.md"}');export{g as comp,b as data}; diff --git a/assets/index.html-Dz4P2gMg.js b/assets/index.html-Dz4P2gMg.js new file mode 100644 index 0000000..f1bda5f --- /dev/null +++ b/assets/index.html-Dz4P2gMg.js @@ -0,0 +1 @@ +import{_ as t}from"./logo_worldline-dinT9MYm.js";import{_ as n,c as i,a,o as r}from"./app-Djq7wF8p.js";const l={};function s(o,e){return r(),i("div",null,e[0]||(e[0]=[a('

Welcome

Who we are

avatar

We design payments technology that powers the growth of millions of businesses around the world. Engineering the next frontiers in payments technology

  • Leader in payment and secured transactions
  • Over 50 billion transactions/year​
  • 7000+ engineers in over 40 countries
  • A huge & diverse tech-stack

Tips

This training is also available in French / Cette formation est aussi disponible en Français

Prerequisites

  • Basic knowledge of object-oriented language like Java
  • Prepare your development environment and install stuff before the session (see Tooling section)
',10)]))}const p=n(l,[["render",s],["__file","index.html.vue"]]),c=JSON.parse(`{"path":"/en/","title":"Welcome","lang":"en-US","frontmatter":{"home":true,"heroImage":"./kotlin_logo.png","tagline":"A beginner's guide to a modern programming language","actions":[{"text":"Get started →","link":"/en/presentation/","type":"primary"}],"features":[{"title":"Language features","details":"null safety, extensions, lambdas, Java interoperability and more"},{"title":"Backend development","details":"With Ktor, spring and node.js"},{"title":"Frontend development","details":"Compose multiplatform, Kotlin/JS, Kotlin/WASM and JVM frameworks"},{"title":"Cross-platform development","details":"With KMP and Compose multiplatform"},{"title":"Advanced Kotlin","details":"Coroutines, delegates, Function literal with receiver, DSLs and more"},{"title":"Practical exercises and solutions","details":"All chapters have a set of exercises"}],"footer":"Worldline, 2023"},"headers":[{"level":2,"title":"Who we are","slug":"who-we-are","link":"#who-we-are","children":[]},{"level":2,"title":"Prerequisites","slug":"prerequisites","link":"#prerequisites","children":[]},{"level":2,"title":"Useful links","slug":"useful-links","link":"#useful-links","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/index.md"}`);export{p as comp,c as data}; diff --git a/assets/index.html-jwVfesBb.js b/assets/index.html-jwVfesBb.js new file mode 100644 index 0000000..7f5e3c6 --- /dev/null +++ b/assets/index.html-jwVfesBb.js @@ -0,0 +1 @@ +import{_ as s}from"./Kotlin-Beyond-Android-CYulNy7n.js";import{_ as d,c as a,a as i,e,b as o,d as r,f as n,r as p,o as u}from"./app-Djq7wF8p.js";const f="/learning-kotlin/assets/Androidmakers2023Kotlinshortlink-7XGfMd7N.svg",m={};function k(v,l){const t=p("RouteLink");return u(),a("div",null,[l[42]||(l[42]=i('

📅 Workshops

Android makers 2023: Kotlin Beyond Android

am2023 logo

Liens

Lien du workshop: awl.li/am23-kt

qr code

Agenda

',7)),e("ul",null,[e("li",null,[o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[0]||(l[0]=[n("Backend development: Rest API with Ktor")])),_:1})]),e("li",null,[l[2]||(l[2]=n("Optional: ")),o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[1]||(l[1]=[n("Backend development: Rest API with node.js and Kotlin/JS")])),_:1})]),e("li",null,[o(t,{to:"/fr/front-development/#kotlin-js-and-kotlin-wasm"},{default:r(()=>l[3]||(l[3]=[n("Front-end development: Kotlin/WASM and Kotlin/JS webapp")])),_:1})]),e("li",null,[o(t,{to:"/fr/front-development/#compose"},{default:r(()=>l[4]||(l[4]=[n("Front-end development: cross-platform Hello world App with Compose multiplatform")])),_:1})]),l[6]||(l[6]=e("li",null,[e("a",{href:"https://worldline.github.io/learning-kotlin-multiplatform/",target:"_blank",rel:"noopener noreferrer"},"Front-end development: Cross-platform Quiz App with Compose multiplatform")],-1)),e("li",null,[o(t,{to:"/fr/other-technologies/#pw-add-a-ktor-server-app"},{default:r(()=>l[5]||(l[5]=[n("Full-stack development: Quiz App with Compose multiplatform and Ktor server")])),_:1})])]),l[43]||(l[43]=i('

Mobile DevOps summit 2023

  • Titre: From Android to Multiplatform: leveraging the full potential of Kotlin
  • Lien: awl.li/mds23-kt

![qr code](../../assets/qrcode-mds2023.gif =200x)

Agenda

',4)),e("ul",null,[e("li",null,[o(t,{to:"/fr/other-technologies/#pw-add-a-ktor-server-app"},{default:r(()=>l[7]||(l[7]=[n("Développement d'une application multi-plateformes")])),_:1})]),e("li",null,[l[11]||(l[11]=n("Démonstration des autres possibilités: ")),e("ul",null,[e("li",null,[o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[8]||(l[8]=[n("API Rest avec Ktor")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[9]||(l[9]=[n("API Rest avec node.js et Kotlin/JS")])),_:1})]),e("li",null,[o(t,{to:"/fr/front-development/#kotlin-js-and-kotlin-wasm"},{default:r(()=>l[10]||(l[10]=[n("Webapp Kotlin/WASM et Kotlin/JS")])),_:1})])])])]),l[44]||(l[44]=i('

Devoxx Morocco 2023

  • Titre: Let's discover the amazing possibilities of Kotlin
  • Lien: awl.li/mds23-kt

![qr code](../../assets/qrcode-devoxxma23.gif =200x)

Agenda

',4)),e("ul",null,[e("li",null,[o(t,{to:"/fr/presentation/#prerequisites"},{default:r(()=>l[12]||(l[12]=[n("Prérequis")])),_:1})]),e("li",null,[l[15]||(l[15]=n("Caractéristiques notables de Kotlin: ")),o(t,{to:"/fr/kotlin-features/#null-safety"},{default:r(()=>l[13]||(l[13]=[n("le null safety")])),_:1}),l[16]||(l[16]=n(" et ")),o(t,{to:"/fr/kotlin-features/#functions"},{default:r(()=>l[14]||(l[14]=[n("les fonctions")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#spring-framework"},{default:r(()=>l[17]||(l[17]=[n("API Rest avec Spring boot")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[18]||(l[18]=[n("API Rest avec Ktor")])),_:1})]),e("li",null,[o(t,{to:"/fr/front-development/#compose"},{default:r(()=>l[19]||(l[19]=[n(`Développement d'une application multi-plateformes type "Hello World" avec Compose Multiplatform`)])),_:1})]),e("li",null,[o(t,{to:"/fr/other-technologies/#pw-add-a-ktor-server-app"},{default:r(()=>l[20]||(l[20]=[n("Dévelopment sullstack d'une application de Quiz avec with Compose multiplatform en front et Ktor server en backend")])),_:1})]),e("li",null,[l[24]||(l[24]=n("Autres fonctionnalités et possibilités: ")),e("ul",null,[e("li",null,[o(t,{to:"/fr/front-development/#kotlin-js-and-kotlin-wasm"},{default:r(()=>l[21]||(l[21]=[n("Kotlin/WASM")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#nodejs"},{default:r(()=>l[22]||(l[22]=[n("Serveur node.js avec Kotlin/JS")])),_:1})]),e("li",null,[o(t,{to:"/fr/kotlin-features-advanced/#concurrency-and-coroutines"},{default:r(()=>l[23]||(l[23]=[n("Coroutines")])),_:1})])])])]),l[45]||(l[45]=e("h2",{id:"_2024-mixit",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2024-mixit"},[e("span",null,"(2024) MiXit")])],-1)),l[46]||(l[46]=e("ul",null,[e("li",null,[n("Titre : "),e("strong",null,"Développement front et back en Kotlin. Une visite guidée de KMP")])],-1)),l[47]||(l[47]=e("p",null,"![qr code](../../assets/qrcode-mixtit24.svg =200x)",-1)),l[48]||(l[48]=e("h3",{id:"agenda-3",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#agenda-3"},[e("span",null,"Agenda")])],-1)),e("ul",null,[e("li",null,[o(t,{to:"/fr/presentation/#prerequisites"},{default:r(()=>l[25]||(l[25]=[n("Prérequis")])),_:1})]),e("li",null,[l[28]||(l[28]=n("Fonctionnalités notables: ")),o(t,{to:"/fr/kotlin-features/#null-safety"},{default:r(()=>l[26]||(l[26]=[n("null safety")])),_:1}),l[29]||(l[29]=n(" et ")),o(t,{to:"/fr/kotlin-features/#functions"},{default:r(()=>l[27]||(l[27]=[n("les fonctions")])),_:1})]),e("li",null,[l[33]||(l[33]=e("strong",null,"Développement backend",-1)),e("ul",null,[l[32]||(l[32]=e("li",null,[e("a",{href:"https://speakerdeck.com/yostane/kotlin-pour-le-developpement-backend",target:"_blank",rel:"noopener noreferrer"},"Présentation d'introduction à Kotlin pour le développement backend")],-1)),e("li",null,[o(t,{to:"/fr/backend-development/#spring-framework"},{default:r(()=>l[30]||(l[30]=[n("API Rest avec Spring boot")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#ktor"},{default:r(()=>l[31]||(l[31]=[n("API Rest avec Ktor")])),_:1})])])]),e("li",null,[l[35]||(l[35]=e("strong",null,"Développement frontend",-1)),e("ul",null,[e("li",null,[o(t,{to:"/fr/front-development/#compose"},{default:r(()=>l[34]||(l[34]=[n('Application "Hello World" avec Compose Multiplatform')])),_:1})])])]),e("li",null,[l[37]||(l[37]=e("strong",null,"Développement fullstack",-1)),e("ul",null,[e("li",null,[o(t,{to:"/fr/other-technologies/#pw-add-a-ktor-server-app"},{default:r(()=>l[36]||(l[36]=[n("Application de quiz avec Ktor + Compose Multiplatform")])),_:1})])])]),e("li",null,[l[41]||(l[41]=e("strong",null,"Autres fonctionnalités",-1)),e("ul",null,[e("li",null,[o(t,{to:"/fr/front-development/#kotlin-js-and-kotlin-wasm"},{default:r(()=>l[38]||(l[38]=[n("Kotlin/WASM")])),_:1})]),e("li",null,[o(t,{to:"/fr/backend-development/#nodejs"},{default:r(()=>l[39]||(l[39]=[n("Développement node.js en Kotlin")])),_:1})]),e("li",null,[o(t,{to:"/fr/kotlin-features-advanced/#concurrency-and-coroutines"},{default:r(()=>l[40]||(l[40]=[n("Coroutines")])),_:1})])])])])])}const x=d(m,[["render",k],["__file","index.html.vue"]]),A=JSON.parse('{"path":"/fr/workshops/","title":"📅 Workshops","lang":"fr-FR","frontmatter":{},"headers":[{"level":2,"title":"Android makers 2023: Kotlin Beyond Android","slug":"android-makers-2023-kotlin-beyond-android","link":"#android-makers-2023-kotlin-beyond-android","children":[{"level":3,"title":"Liens","slug":"liens","link":"#liens","children":[]},{"level":3,"title":"Agenda","slug":"agenda","link":"#agenda","children":[]}]},{"level":2,"title":"Mobile DevOps summit 2023","slug":"mobile-devops-summit-2023","link":"#mobile-devops-summit-2023","children":[{"level":3,"title":"Agenda","slug":"agenda-1","link":"#agenda-1","children":[]}]},{"level":2,"title":"Devoxx Morocco 2023","slug":"devoxx-morocco-2023","link":"#devoxx-morocco-2023","children":[{"level":3,"title":"Agenda","slug":"agenda-2","link":"#agenda-2","children":[]}]},{"level":2,"title":"(2024) MiXit","slug":"_2024-mixit","link":"#_2024-mixit","children":[{"level":3,"title":"Agenda","slug":"agenda-3","link":"#agenda-3","children":[]}]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"fr/workshops/README.md"}');export{x as comp,A as data}; diff --git a/assets/index.html-zXMBiwyM.js b/assets/index.html-zXMBiwyM.js new file mode 100644 index 0000000..0bb2b5f --- /dev/null +++ b/assets/index.html-zXMBiwyM.js @@ -0,0 +1,24 @@ +import{_ as n}from"./kotlin-wasm-webapp-R4_9ho9v.js";import{_ as t,c as a,a as o,o as s}from"./app-Djq7wF8p.js";const l="/learning-kotlin/assets/launch-android-app-BS4WBFFP.png",i="/learning-kotlin/assets/hello-compose-demo-B4DIIuDy.gif",r={};function p(c,e){return s(),a("div",null,e[0]||(e[0]=[o('

📚 Frontend development

Kotlin supports a wide selection of frontend frameworks across all platforms: mobile, desktop and web.

Please find below a glimpse of the possibilities that you can do right from IntelliJ:

  • On the Desktop side
    • Thanks to JVM support, Kotlin supports JavaFX (There was a Kotlin counterpart called tornadofx which is not maintained anymore).
    • Compose Multiplatform brings Jetpack Compose to the desktop, the web and mobile.
  • On the Web
    • Ktor can use templates engines such as FreeMarker to create server pages.
    • With KotlinJS, developers can create React, nodsjs, or vanilla JS Apps using Kotlin.
    • Kotlin WASM compiles into Web Assembly. It can complement KotlinJS for computation intensive tasks.
  • On Mobiles
    • Android developers use the Jetpack Compose UI Framework or the legacy xml layouts. It is experimental on iOS.

Kotlin supports cross platform frontend development thanks to Kotlin MultiPlatform (KMP)

Kotlin Multiplatform (KMP)

"The Kotlin Multiplatform technology is designed to simplify the development of cross-platform projects. It reduces time spent writing and maintaining the same code for different platforms while retaining the flexibility and benefits of native programming."

KMP relies on Kotlin native and other Kotlin features to help developers create projects that target multiple platforms using a common Kotlin code-base.

KMP

Many combinations of targets and use cases are possible:

Kotlin/JS and Kotlin/WASM

  • Kotlin/JS can also target the web and even use web frameworks (such as react) in Kolitn.
  • Kotlin WASM is another possibility to target the web but this will generate WASM instead of pure JS code.
    • It can be used for example to develop computation intensive libraries.
  • Maybe we can do even more in the future with as all these technologies (Kotlin, WASM and Kotlin/WASM) evolve. - For example, WASI allows WASM to communicate with the operating system. - This means that me may see Kotlin/WASM project projects in the future that can target both the browser and the OS.
  • Let's keep watching 😄.

🧪 Kotlin/WASM web app

  • Let's create a Kotlin/WASM app. By cloning git clone git@github.com:Kotlin/kotlin-wasm-examples.git and opening the browser-example folder in your IDE.
  • Open the project and run the wasmJsBrowserRun task.
  • The development server should start and you can open your WASM powered webapp on http://localhost:8080/
    • ⚠️ You may need to activate some flags on your browser for the app to work. If you see a blank page, please read the browser logs to check for the instructions.

Alt text

  • Please check the contents of src/wasmJsMain/kotlin/Simple.kt to understand how the page is coded.
  • Next, let's check the generated wasm file which is available in build/js/packages/project_name/kotlin
    • WASM being a binary format, we need to convert it first to text format.
    • We can either install WABT (The WebAssembly Binary Toolkit or wabbit) and use the wasm2wattool wasm2wat --enable-all -v .\\kotlin-wasm-demo-wasm.wasm -o wasm.wat,
    • or use an online converter such as this one
    • ❗ However, I couldn't get it to work (yet).

Kotlin/JS and Kotlin/WASM common points

Both Kotlin/WASM and Kotlin/JS IntelliJ work somewhat similarly.

  • Both rely on the KMP plugin
  • Kotlin/WASM is enabled by adding a wasmjs section in the build.gradle.kts file, while Kotlin/JS is enabled by adding a js section.
  • The Kotlin code will compile to WASM and / or JS. Kotlin/JS generates only JS while Kotin/WASM generates both JS and WASM.
  • In both cases, the entry point of the generated code is a JS file called module_name.js.
  • The index.html in the resources folder loads the generated JS explained above (the one named module_name.js).
  • The task wasmBrowserDevelopmentRun or jsWasmBrowserDevelopmentRun run a local server that hosts both the index.html files and the generated JS and WASM files.

Compose multiplatform

"Compose Multiplatform simplifies and accelerates UI development for Desktop and Web applications, and allows extensive UI code sharing between Android, iOS, Desktop and Web. It's a modern toolkit for building native UI. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs."

img

Button(
+  onClick = {
+    logger.info("Pressed!")
+  }
+) {
+  Text("Hello $platform")
+}
+

It is based on Android Jetpack Compose declarative UI approach ( which is similar also to iOS SwiftUI ) 1

Compose multiplatform vs Jetpack Compose

While very similar, Compose multiplatform is different from Jetpack Compose as the latter is only compatible with Android. Google provides a JetPack compose tutorial for Android development.

Compose HTML is not cross-platform

Compose HTML is UI a library targeting Kotlin/JS which is not compatible with Compose Multiplatform (it is a different API). For cross-platform UI development with Compose Multiplatform, compose Web is the choice.

🧪 Create a Compose multiplatform app

We'll create a multiplatform app using the official template. At the time of writing, this template does not include a compose web target.

  • Please check that your environment is correctly setup as explained here.
    • On Windows and Linux, we don't need to install iOS/macOS related tools but and we won't be able to run iOS/macOS targets.
    • If we don't want to install Android Studio, we need at least to install the Android SDK either through the official installer or from the "Languages and Framework -> Android SDK" menu in the settings.
  • Open the official template and either download a zip or use the "use this template" options on GitHub.
  • Open the downloaded projet. You'll note that it contains these modules:
    • a shared module (or subproject) that contains common code as well as
    • and another module for earch targeted platform: androidApp, iOSApp and desktopApp (When web will be included in the template, we should also see a webApp project). These contain the source code of the apps itself (such as the main activity in Android, the @main App in iOS and the main function in desktopJVM) and well as platform specific resources that cannot be placed in the shared module. Some examples of such files are the AndroidManifest.xml for android and the info.plist in iOS.
  • In order to run the desktopApp, open a terminal on the project root folder and launch this command: ./gradlew desktopApp:run.
  • In order to run the Android App, the simplest way is to launch it from IntelliJ Alt text. It is also possible define a gradle task that installs the app on the device and issues a command to the device to launch it.
  • In order to run the iOS App, the simplest way is to run it on the simulator using IntelliJ. In order to run it on a real device, the TramID needs to be defined as explained here

![Alt text](../../assets/kmp-compose-desktop.png =200x)

🧪 Playing with the Compose multiplatform API

Compose multiplatform is a component based declarative UI framework. Each component is called a Composable and is defined as a function annotated with @Composable.

In compose multiplatform, the main component (the component at the root of the App) is usually found in shared/src/commonMain/Kotlin/App.kt.

  • Take a look at shared/src/commonMain/Kotlin/App.kt, run the app and try to understand how compose works.
  • Let's create a new composable called RandomNumberList.
@Composable
+fun RandomNumberList(){
+    // Generate a list of random numbers
+    val myRandomValues = List(5) { Random.nextInt(0, 30) }
+    // LazyColumn is a vertically scrolling list that renders items on demand
+    LazyColumn {
+        items(myRandomValues.size){
+            Text(text = "$it")
+        }
+    }
+}
+
  • Place this composable below AnimatedVisibility and Button and run the app.
/*
+Button(onClick ...
+AnimatedVisibility(showImage) { ...
+*/
+RandomNumberList()
+
  • Exercise: Make the "Hello, .." button switch between showing the list and and the image.

Hello compose demo

🎯 Solutions

📖 Further reading

',44)]))}const u=t(r,[["render",p],["__file","index.html.vue"]]),h=JSON.parse('{"path":"/en/front-development/","title":"📚 Frontend development","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Kotlin Multiplatform (KMP)","slug":"kotlin-multiplatform-kmp","link":"#kotlin-multiplatform-kmp","children":[]},{"level":2,"title":"Kotlin/JS and Kotlin/WASM","slug":"kotlin-js-and-kotlin-wasm","link":"#kotlin-js-and-kotlin-wasm","children":[{"level":3,"title":"🧪 Kotlin/WASM web app","slug":"🧪-kotlin-wasm-web-app","link":"#🧪-kotlin-wasm-web-app","children":[]},{"level":3,"title":"Kotlin/JS and Kotlin/WASM common points","slug":"kotlin-js-and-kotlin-wasm-common-points","link":"#kotlin-js-and-kotlin-wasm-common-points","children":[]}]},{"level":2,"title":"Compose multiplatform","slug":"compose-multiplatform","link":"#compose-multiplatform","children":[{"level":3,"title":"🧪 Create a Compose multiplatform app","slug":"🧪-create-a-compose-multiplatform-app","link":"#🧪-create-a-compose-multiplatform-app","children":[]},{"level":3,"title":"🧪 Playing with the Compose multiplatform API","slug":"🧪-playing-with-the-compose-multiplatform-api","link":"#🧪-playing-with-the-compose-multiplatform-api","children":[]}]},{"level":2,"title":"🎯 Solutions","slug":"🎯-solutions","link":"#🎯-solutions","children":[]},{"level":2,"title":"📖 Further reading","slug":"📖-further-reading","link":"#📖-further-reading","children":[]}],"git":{"updatedTime":1729869737000,"contributors":[{"name":"yostane","email":"1958676+yostane@users.noreply.github.com","commits":1}]},"filePathRelative":"en/front-development/README.md"}');export{u as comp,h as data}; diff --git a/assets/kmp_codelab-CiTPMWjt.js b/assets/kmp_codelab-CiTPMWjt.js new file mode 100644 index 0000000..69a29a4 --- /dev/null +++ b/assets/kmp_codelab-CiTPMWjt.js @@ -0,0 +1 @@ +const s="/learning-kotlin/assets/kmp_codelab-J5AI0da_.png";export{s as _}; diff --git a/assets/kmp_codelab-J5AI0da_.png b/assets/kmp_codelab-J5AI0da_.png new file mode 100644 index 0000000..9ebc2b8 Binary files /dev/null and b/assets/kmp_codelab-J5AI0da_.png differ diff --git a/assets/kotlin-decision-tree-4i7nEr1Z.svg b/assets/kotlin-decision-tree-4i7nEr1Z.svg new file mode 100644 index 0000000..d3375a7 --- /dev/null +++ b/assets/kotlin-decision-tree-4i7nEr1Z.svg @@ -0,0 +1 @@ +
Shall I use Kotlin ?
Shall I use Kotlin...
Android
Android
Mobile (Android + iOS)
Mobile (Android + iOS)
Web
Web
Web + Mobile
Web + Mobile
What type
of front project
What type...
Frontend
Frontend
Kotlin is the default Android Language since 2019
Kotlin is the default...
No
No
Yes
Yes
Do you want
to generate native code
Do you want...
Java / JVM
Java / JVM
Other
Other
What type
of project ?
What type...
Yes
Yes
Are you intereted in
using a conise language
with null safety and full
interop with Java
Are you intereted in...
Yes
Yes
No
No
Is it a script
or WASM or WASI
project ?
Is it a script...
Use Kotlin. In addition to that, Quarkus and Spring officially support Kotlin
Use Kotlin. In addition...
Use Java or Groovy or Scala
Use Java or Groo...
Use Flutter or React native
Use Flutter or R...
Yes
Yes
No
No
Do you want to
develop the UI using native frameworks (Jetpack compose
and SwiftUI)
Do you want to...
Kotlin Multiplatform (KMP) allows to share no UI code
Kotlin Multiplatfor...
Yes
Yes
No
No
Do you to use
native System
views 
Do you to use...
Use MAUI
Use MAUI
Use KMP with Compose multiplatform
Use KMP with Compose...
Yes
Yes
No
No
Do you want to
use a conise lnguage
with null safety
Do you want to...
Use Kotlin. Howeber these features are still experimental
Use Kotlin. Howe...
Yes
Yes
No
No
Is it ok to use experimental technologies ?
Is it ok to use expe...
Use other languages
Use other langua...
JavaSctipt / TypeScript
JavaSctipt / TypeScript
Kotlin / Java
Kotlin / Java
C#
C#
Dart
Dart
Rust
Rust
Which
language are
you already
confortable with
Which...
I want 
I want 
No
No
Do you want
to share code
across mobile
and web
Do you want...
Use JS ot TS to develop the webapp
Use JS ot TS to...
Use Kotlin/JS
Use Kotlin/JS
Use Blazor
Use Blazor
User Flutter
User Flutter
Use Yew (or an alternative in Rust)
Use Yew (or an a...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/assets/kotlin-used-for-Bdlavnqs.js b/assets/kotlin-used-for-Bdlavnqs.js new file mode 100644 index 0000000..c91b22f --- /dev/null +++ b/assets/kotlin-used-for-Bdlavnqs.js @@ -0,0 +1 @@ +const s="/learning-kotlin/assets/kotlin-used-for-FU2DHhYT.png";export{s as _}; diff --git a/assets/kotlin-used-for-FU2DHhYT.png b/assets/kotlin-used-for-FU2DHhYT.png new file mode 100644 index 0000000..d023253 Binary files /dev/null and b/assets/kotlin-used-for-FU2DHhYT.png differ diff --git a/assets/kotlin-wasm-flag-BKaaN9Pq.png b/assets/kotlin-wasm-flag-BKaaN9Pq.png new file mode 100644 index 0000000..c51b253 Binary files /dev/null and b/assets/kotlin-wasm-flag-BKaaN9Pq.png differ diff --git a/assets/kotlin-wasm-webapp-R4_9ho9v.js b/assets/kotlin-wasm-webapp-R4_9ho9v.js new file mode 100644 index 0000000..d4ed5a8 --- /dev/null +++ b/assets/kotlin-wasm-webapp-R4_9ho9v.js @@ -0,0 +1 @@ +const s="/learning-kotlin/assets/kotlin-wasm-webapp-ViYyGRus.png";export{s as _}; diff --git a/assets/kotlin-wasm-webapp-ViYyGRus.png b/assets/kotlin-wasm-webapp-ViYyGRus.png new file mode 100644 index 0000000..0910b9d Binary files /dev/null and b/assets/kotlin-wasm-webapp-ViYyGRus.png differ diff --git a/assets/launch-android-app-BS4WBFFP.png b/assets/launch-android-app-BS4WBFFP.png new file mode 100644 index 0000000..0deef90 Binary files /dev/null and b/assets/launch-android-app-BS4WBFFP.png differ diff --git a/assets/logo_worldline-dinT9MYm.js b/assets/logo_worldline-dinT9MYm.js new file mode 100644 index 0000000..bba4f9b --- /dev/null +++ b/assets/logo_worldline-dinT9MYm.js @@ -0,0 +1 @@ +const o="/learning-kotlin/assets/logo_worldline-t5KadDQv.png";export{o as _}; diff --git a/assets/logo_worldline-t5KadDQv.png b/assets/logo_worldline-t5KadDQv.png new file mode 100644 index 0000000..6981642 Binary files /dev/null and b/assets/logo_worldline-t5KadDQv.png differ diff --git a/assets/setupDevtools-7MC2TMWH-TJgRKbnT.js b/assets/setupDevtools-7MC2TMWH-TJgRKbnT.js new file mode 100644 index 0000000..72faf8e --- /dev/null +++ b/assets/setupDevtools-7MC2TMWH-TJgRKbnT.js @@ -0,0 +1 @@ +import{s as T,w as E}from"./app-Djq7wF8p.js";var l="org.vuejs.vuepress",v="VuePress",I=v,r=l,N=v,i="client-data",a="Client Data",g=(p,n)=>{T({app:p,id:l,label:v,packageName:"@vuepress/client",homepage:"https://vuepress.vuejs.org",logo:"https://vuepress.vuejs.org/images/hero.png",componentStateTypes:[I]},t=>{const c=Object.entries(n),u=Object.keys(n),d=Object.values(n);t.on.inspectComponent(e=>{e.instanceData.state.push(...c.map(([s,o])=>({type:I,editable:!1,key:s,value:o.value})))}),t.addInspector({id:r,label:N,icon:"article"}),t.on.getInspectorTree(e=>{e.inspectorId===r&&(e.rootNodes=[{id:i,label:a,children:u.map(s=>({id:s,label:s}))}])}),t.on.getInspectorState(e=>{e.inspectorId===r&&(e.nodeId===i&&(e.state={[a]:c.map(([s,o])=>({key:s,value:o.value}))}),u.includes(e.nodeId)&&(e.state={[a]:[{key:e.nodeId,value:n[e.nodeId].value}]}))}),E(d,()=>{t.notifyComponentUpdate(),t.sendInspectorState(r)})})};export{g as setupDevtools}; diff --git a/assets/style-CIQ0kvik.css b/assets/style-CIQ0kvik.css new file mode 100644 index 0000000..05f22f0 --- /dev/null +++ b/assets/style-CIQ0kvik.css @@ -0,0 +1 @@ +.vp-back-to-top-button{position:fixed!important;inset-inline-end:1rem;bottom:4rem;z-index:100;width:48px;height:48px;padding:12px;border-width:0;border-radius:50%;background:var(--back-to-top-c-bg);color:var(--back-to-top-c-accent-bg);box-shadow:2px 2px 10px 4px var(--back-to-top-c-shadow);cursor:pointer}@media (max-width: 959px){.vp-back-to-top-button{transform:scale(.8);transform-origin:100% 100%}}@media print{.vp-back-to-top-button{display:none}}.vp-back-to-top-button:hover{color:var(--back-to-top-c-accent-hover)}.vp-back-to-top-button .back-to-top-icon{overflow:hidden;width:24px;height:24px;margin:0 auto;background:var(--back-to-top-c-icon);-webkit-mask-image:var(--back-to-top-icon);mask-image:var(--back-to-top-icon);-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:cover;mask-size:cover}.vp-scroll-progress{position:absolute;right:-2px;bottom:-2px;width:52px;height:52px}.vp-scroll-progress svg{width:100%;height:100%}.vp-scroll-progress circle{opacity:.9;transform:rotate(-90deg);transform-origin:50% 50%}.back-to-top-enter-active,.back-to-top-leave-active{transition:opacity .3s}.back-to-top-enter-from,.back-to-top-leave-to{opacity:0}:root{--back-to-top-z-index: 5;--back-to-top-icon: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%3e%3cpath%20fill='none'%20stroke='currentColor'%20stroke-linecap='round'%20stroke-linejoin='round'%20stroke-width='4'%20d='M24.008%2014.1V42M12%2026l12-12l12%2012M12%206h24'%20/%3e%3c/svg%3e");--back-to-top-c-bg: var(--vp-c-bg);--back-to-top-c-accent-bg: var(--vp-c-accent-bg);--back-to-top-c-accent-hover: var(--vp-c-accent-hover);--back-to-top-c-shadow: var(--vp-c-shadow);--back-to-top-c-icon: currentcolor}.vp-copy-code-button{position:absolute;top:.5em;right:.5em;z-index:5;width:2.5rem;height:2.5rem;padding:0;border-width:0;border-radius:.5rem;background:#0000;outline:none;opacity:0;cursor:pointer;transition:opacity .4s}@media print{.vp-copy-code-button{display:none}}.vp-copy-code-button:before{content:"";display:inline-block;width:1.25rem;height:1.25rem;padding:.625rem;background:currentcolor;color:var(--copy-code-c-text);font-size:1.25rem;-webkit-mask-image:var(--code-copy-icon);mask-image:var(--code-copy-icon);-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.vp-copy-code-button:focus,.vp-copy-code-button.copied{opacity:1}.vp-copy-code-button:hover,.vp-copy-code-button.copied{background:var(--copy-code-c-hover)}.vp-copy-code-button.copied:before{-webkit-mask-image:var(--code-copied-icon);mask-image:var(--code-copied-icon)}.vp-copy-code-button.copied:after{content:attr(data-copied);position:absolute;top:0;right:calc(100% + .25rem);display:block;height:1.25rem;padding:.625rem;border-radius:.5rem;background:var(--copy-code-c-hover);color:var(--copy-code-c-text);font-weight:500;line-height:1.25rem;white-space:nowrap}.no-copy-code .vp-copy-code-button{display:none}body:not(.no-copy-code) div[class*=language-]:hover:before{display:none}body:not(.no-copy-code) div[class*=language-]:hover .vp-copy-code-button{opacity:1}:root{--code-copy-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23808080' stroke-width='2'%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");--code-copied-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23808080' stroke-width='2'%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");--copy-code-c-text: var(--code-c-line-number);--copy-code-c-hover: var(--code-c-highlight-bg)}.hint-container{position:relative;border-color:var(--hint-c-accent);background:var(--hint-c-soft);transition:background var(--vp-t-color),color var(--vp-t-color)}@media print{.hint-container{page-break-inside:avoid}}.hint-container>.hint-container-title{color:var(--hint-c-title)}.hint-container :not(pre)>code{background:var(--hint-c-soft)}.hint-container .hint-container-title{position:relative;margin-block:.75em;font-weight:600;line-height:1.25}.hint-container.important,.hint-container.info,.hint-container.note,.hint-container.tip,.hint-container.warning,.hint-container.caution{margin-block:.75rem;padding:.25em 1em;border-radius:.5em;color:inherit;font-size:var(--hint-font-size)}@media print{.hint-container.important,.hint-container.info,.hint-container.note,.hint-container.tip,.hint-container.warning,.hint-container.caution{border-inline-start-width:.25em;border-inline-start-style:solid}}.hint-container.important .hint-container-title,.hint-container.info .hint-container-title,.hint-container.note .hint-container-title,.hint-container.tip .hint-container-title,.hint-container.warning .hint-container-title,.hint-container.caution .hint-container-title{padding-inline-start:1.75em}@media print{.hint-container.important .hint-container-title,.hint-container.info .hint-container-title,.hint-container.note .hint-container-title,.hint-container.tip .hint-container-title,.hint-container.warning .hint-container-title,.hint-container.caution .hint-container-title{padding-inline-start:0}}.hint-container.important .hint-container-title:before,.hint-container.info .hint-container-title:before,.hint-container.note .hint-container-title:before,.hint-container.tip .hint-container-title:before,.hint-container.warning .hint-container-title:before,.hint-container.caution .hint-container-title:before{content:" ";position:absolute;inset-inline-start:0;top:calc(50% - .6125em);width:1.25em;height:1.25em;font-size:1.25em}@media print{.hint-container.important .hint-container-title:before,.hint-container.info .hint-container-title:before,.hint-container.note .hint-container-title:before,.hint-container.tip .hint-container-title:before,.hint-container.warning .hint-container-title:before,.hint-container.caution .hint-container-title:before{display:none}}.hint-container.important p,.hint-container.info p,.hint-container.note p,.hint-container.tip p,.hint-container.warning p,.hint-container.caution p{line-height:1.5}.hint-container.important a,.hint-container.info a,.hint-container.note a,.hint-container.tip a,.hint-container.warning a,.hint-container.caution a{color:var(--vp-c-accent)}.hint-container.important{--hint-c-accent: var(--important-c-accent);--hint-c-title: var(--important-c-text);--hint-c-soft: var(--important-c-soft)}.hint-container.important>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M512 981.333a84.992 84.992 0 0 1-84.907-84.906h169.814A84.992 84.992 0 0 1 512 981.333zm384-128H128v-42.666l85.333-85.334v-256A298.325 298.325 0 0 1 448 177.92V128a64 64 0 0 1 128 0v49.92a298.325 298.325 0 0 1 234.667 291.413v256L896 810.667v42.666zm-426.667-256v85.334h85.334v-85.334h-85.334zm0-256V512h85.334V341.333h-85.334z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M512 981.333a84.992 84.992 0 0 1-84.907-84.906h169.814A84.992 84.992 0 0 1 512 981.333zm384-128H128v-42.666l85.333-85.334v-256A298.325 298.325 0 0 1 448 177.92V128a64 64 0 0 1 128 0v49.92a298.325 298.325 0 0 1 234.667 291.413v256L896 810.667v42.666zm-426.667-256v85.334h85.334v-85.334h-85.334zm0-256V512h85.334V341.333h-85.334z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.info{--hint-c-accent: var(--info-c-accent);--hint-c-title: var(--info-c-text);--hint-c-soft: var(--info-c-soft)}.hint-container.info>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.note{--hint-c-accent: var(--note-c-accent);--hint-c-title: var(--note-c-text);--hint-c-soft: var(--note-c-soft)}.hint-container.note>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.tip{--hint-c-accent: var(--tip-c-accent);--hint-c-title: var(--tip-c-text);--hint-c-soft: var(--tip-c-soft)}.hint-container.tip>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.941 18c-.297-1.273-1.637-2.314-2.187-3a8 8 0 1 1 12.49.002c-.55.685-1.888 1.726-2.185 2.998H7.94zM16 20v1a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-1h8zm-3-9.995V6l-4.5 6.005H11v4l4.5-6H13z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.941 18c-.297-1.273-1.637-2.314-2.187-3a8 8 0 1 1 12.49.002c-.55.685-1.888 1.726-2.185 2.998H7.94zM16 20v1a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2v-1h8zm-3-9.995V6l-4.5 6.005H11v4l4.5-6H13z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.warning{--hint-c-accent: var(--warning-c-accent);--hint-c-title: var(--warning-c-text);--hint-c-soft: var(--warning-c-soft)}.hint-container.warning>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M576.286 752.57v-95.425q0-7.031-4.771-11.802t-11.3-4.772h-96.43q-6.528 0-11.3 4.772t-4.77 11.802v95.424q0 7.031 4.77 11.803t11.3 4.77h96.43q6.528 0 11.3-4.77t4.77-11.803zm-1.005-187.836 9.04-230.524q0-6.027-5.022-9.543-6.529-5.524-12.053-5.524H456.754q-5.524 0-12.053 5.524-5.022 3.516-5.022 10.547l8.538 229.52q0 5.023 5.022 8.287t12.053 3.265h92.913q7.032 0 11.803-3.265t5.273-8.287zM568.25 95.65l385.714 707.142q17.578 31.641-1.004 63.282-8.538 14.564-23.354 23.102t-31.892 8.538H126.286q-17.076 0-31.892-8.538T71.04 866.074q-18.582-31.641-1.004-63.282L455.75 95.65q8.538-15.57 23.605-24.61T512 62t32.645 9.04 23.605 24.61z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Cpath d='M576.286 752.57v-95.425q0-7.031-4.771-11.802t-11.3-4.772h-96.43q-6.528 0-11.3 4.772t-4.77 11.802v95.424q0 7.031 4.77 11.803t11.3 4.77h96.43q6.528 0 11.3-4.77t4.77-11.803zm-1.005-187.836 9.04-230.524q0-6.027-5.022-9.543-6.529-5.524-12.053-5.524H456.754q-5.524 0-12.053 5.524-5.022 3.516-5.022 10.547l8.538 229.52q0 5.023 5.022 8.287t12.053 3.265h92.913q7.032 0 11.803-3.265t5.273-8.287zM568.25 95.65l385.714 707.142q17.578 31.641-1.004 63.282-8.538 14.564-23.354 23.102t-31.892 8.538H126.286q-17.076 0-31.892-8.538T71.04 866.074q-18.582-31.641-1.004-63.282L455.75 95.65q8.538-15.57 23.605-24.61T512 62t32.645 9.04 23.605 24.61z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.caution{--hint-c-accent: var(--caution-c-accent);--hint-c-title: var(--caution-c-text);--hint-c-soft: var(--caution-c-soft)}.hint-container.caution>.hint-container-title:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2c5.523 0 10 4.477 10 10v3.764a2 2 0 0 1-1.106 1.789L18 19v1a3 3 0 0 1-2.824 2.995L14.95 23a2.5 2.5 0 0 0 .044-.33L15 22.5V22a2 2 0 0 0-1.85-1.995L13 20h-2a2 2 0 0 0-1.995 1.85L9 22v.5c0 .171.017.339.05.5H9a3 3 0 0 1-3-3v-1l-2.894-1.447A2 2 0 0 1 2 15.763V12C2 6.477 6.477 2 12 2zm-4 9a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hint-container.details{position:relative;display:block;margin-block:.75rem;padding:1.25rem 1rem;border-radius:.5rem;background:var(--detail-c-bg);transition:background var(--vp-t-transform),color var(--vp-t-transform)}.hint-container.details h4{margin-top:0}.hint-container.details figure:last-child,.hint-container.details p:last-child{margin-bottom:0;padding-bottom:0}.hint-container.details a{color:var(--vp-c-accent)}.hint-container.details :not(pre)>code{background:var(--detail-c-soft)}.hint-container.details summary{position:relative;margin:-1rem;padding-block:1em;padding-inline:3em 1.5em;list-style:none;font-size:var(--hint-font-size);cursor:pointer}.hint-container.details summary::-webkit-details-marker{display:none}.hint-container.details summary::marker{color:#0000;font-size:0}.hint-container.details summary:before{background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z'/%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:1em;mask-size:1em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;content:" ";position:absolute;inset-inline-start:.8em;top:calc(50% - .5em);width:1em;height:1em;font-size:1.25rem;line-height:normal;transition:color,var(--vp-t-color),transform var(--vp-t-transform);transform:rotate(90deg)}.hint-container.details[open]>summary{margin-bottom:.5em}.hint-container.details[open]>summary:before{transform:rotate(180deg)}:root{--hint-font-size: .9rem;--important-c-accent: var(--vp-c-purple-bg);--important-c-text: var(--vp-c-purple-text);--important-c-soft: var(--vp-c-purple-soft);--info-c-accent: var(--vp-c-blue-bg);--info-c-text: var(--vp-c-blue-text);--info-c-soft: var(--vp-c-blue-soft);--note-c-accent: var(--vp-c-grey-bg);--note-c-text: var(--vp-c-grey-text);--note-c-soft: var(--vp-c-grey-soft);--tip-c-accent: var(--vp-c-green-bg);--tip-c-text: var(--vp-c-green-text);--tip-c-soft: var(--vp-c-green-soft);--warning-c-accent: var(--vp-c-yellow-bg);--warning-c-text: var(--vp-c-yellow-text);--warning-c-soft: var(--vp-c-yellow-soft);--caution-c-accent: var(--vp-c-red-bg);--caution-c-text: var(--vp-c-red-text);--caution-c-soft: var(--vp-c-red-soft);--detail-c-bg: var(--vp-c-control);--detail-c-icon: var(--vp-c-border);--detail-c-soft: var(--vp-c-grey-soft)}:root{--nprogress-c: var(--vp-c-accent);--nprogress-z-index: 1031}#nprogress{pointer-events:none}#nprogress .bar{position:fixed;top:0;left:0;z-index:var(--nprogress-z-index);width:100%;height:2px;background:var(--nprogress-c)}:root{--code-padding-x: 1.25rem;--code-padding-y: 1rem;--code-border-radius: 6px;--code-line-height: 1.6;--code-font-size: 14px;--code-font-family: consolas, monaco, "Andale Mono", "Ubuntu Mono", monospace}div[class*=language-]{position:relative;border-radius:var(--code-border-radius);background-color:var(--code-c-bg)}div[class*=language-]:before{content:attr(data-title);position:absolute;top:.8em;right:1em;z-index:3;color:var(--code-c-text);font-size:.75rem}div[class*=language-] pre{position:relative;z-index:1;overflow-x:auto;margin:0;border-radius:var(--code-border-radius);font-size:var(--code-font-size);font-family:var(--code-font-family);line-height:var(--code-line-height)}div[class*=language-] pre code{display:block;box-sizing:border-box;width:-moz-fit-content;width:fit-content;min-width:100%;padding:var(--code-padding-y) var(--code-padding-x);background-color:#0000!important;color:var(--code-c-text);overflow-wrap:unset;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}:root{--code-c-text: #f8f8f2;--code-c-bg: #2e3440;--code-c-highlight-bg: rgb(51.6454545455, 60.5484848485, 78.3545454545);--code-c-line-number: rgba(248, 248, 242, .67)}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#636f88}.token.punctuation{color:#81a1c1}.namespace{opacity:.7}.token.property,.token.tag,.token.constant,.token.symbol,.token.deleted{color:#81a1c1}.token.number{color:#b48ead}.token.boolean{color:#81a1c1}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#a3be8c}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.variable{color:#81a1c1}.token.atrule,.token.attr-value,.token.function,.token.class-name{color:#88c0d0}.token.keyword{color:#81a1c1}.token.regex,.token.important{color:#ebcb8b}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}:root{--code-line-number-width: 3rem}div[class*=language-]:not(.line-numbers-mode) .line-numbers{display:none}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;top:0;left:0;width:var(--code-line-number-width);height:100%;border-right:1px solid var(--code-c-highlight-bg, var(--code-c-text));border-radius:var(--code-border-radius) 0 0 var(--code-border-radius);transition:border var(--vp-t-color)}div[class*=language-].line-numbers-mode pre{vertical-align:middle;margin-left:var(--code-line-number-width)}div[class*=language-].line-numbers-mode code{padding-left:1rem}div[class*=language-].line-numbers-mode .line-numbers{counter-reset:line-number;position:absolute;top:0;width:var(--code-line-number-width);padding-top:var(--code-padding-y);color:var(--code-c-line-number, var(--code-c-text));font-size:var(--code-font-size);line-height:var(--code-line-height);text-align:center}div[class*=language-].line-numbers-mode .line-number{position:relative;z-index:3;font-family:var(--code-font-family);-webkit-user-select:none;-moz-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-number:before{content:counter(line-number);counter-increment:line-number}div[class*=language-] .line.highlighted{display:inline-block;width:100%;margin:0 calc(-1*var(--code-padding-x));padding:0 var(--code-padding-x);background-color:var(--code-c-highlight-bg)}div[class*=language-].has-collapsed-lines.collapsed{overflow-y:hidden;height:calc(var(--vp-collapsed-lines)*var(--code-line-height)*var(--code-font-size) + var(--code-padding-y) + 28px)}div[class*=language-].has-collapsed-lines .collapsed-lines{--vp-collapsed-lines-bg: var(--code-c-bg);position:absolute;right:0;bottom:0;left:0;z-index:4;display:flex;align-items:center;justify-content:center;height:28px;background:linear-gradient(to bottom,transparent 0%,var(--vp-collapsed-lines-bg) 55%,var(--vp-collapsed-lines-bg) 100%);cursor:pointer;transition:--vp-collapsed-lines-bg var(--vp-t-color)}div[class*=language-].has-collapsed-lines .collapsed-lines:hover{--vp-collapsed-lines-bg: rgb(0 0 0 / 10%) !important}div[class*=language-].has-collapsed-lines[data-highlighter=shiki] .collapsed-lines{--vp-collapsed-lines-bg: var(--code-c-bg, var(--shiki-light-bg))}[data-theme=dark] div[class*=language-].has-collapsed-lines[data-highlighter=shiki] .collapsed-lines{--vp-collapsed-lines-bg: var(--code-c-bg, var(--shiki-dark-bg))}div[class*=language-].has-collapsed-lines .collapsed-lines:before{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='m18 12l-6 6l-6-6m12-6l-6 6l-6-6'/%3E%3C/svg%3E");--vp-collapsed-lines-rotate: 0deg;content:"";display:inline-block;width:24px;height:24px;background-color:var(--code-c-text);-webkit-mask-image:var(--icon);mask-image:var(--icon);-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:20px;mask-size:20px;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;pointer-events:none;animation:code-collapsed-lines 1.2s infinite alternate-reverse ease-in-out}div[class*=language-].has-collapsed-lines:not(.collapsed) code{padding-bottom:max(var(--code-padding-y),28px)}div[class*=language-].has-collapsed-lines:not(.collapsed) .collapsed-lines:hover{--vp-collapsed-lines-bg: transparent !important}div[class*=language-].has-collapsed-lines:not(.collapsed) .collapsed-lines:before{--vp-collapsed-lines-rotate: 180deg}@property --vp-collapsed-lines-bg{inherits:false;initial-value:#fff;syntax:""}@keyframes code-collapsed-lines{0%{opacity:.3;transform:translateY(-2px) rotate(var(--vp-collapsed-lines-rotate))}to{opacity:1;transform:translateY(2px) rotate(var(--vp-collapsed-lines-rotate))}}.vp-code-tabs-nav{overflow-x:auto;margin:.75rem 0 -.75rem;padding:0;border-radius:6px 6px 0 0;background:var(--code-tabs-c-bg);list-style:none;white-space:nowrap;transition:background var(--vp-t-color)}@media print{.vp-code-tabs-nav{display:none}}@media (max-width: 419px){.vp-code-tabs-nav{margin-inline:-1.5rem;border-radius:0}}.vp-code-tab-nav{position:relative;min-width:3rem;margin:0;padding:6px 12px;border-width:0;border-radius:6px 6px 0 0;background:#0000;color:var(--code-tabs-c-text);font-weight:600;font-size:.875em;line-height:1.4;cursor:pointer;transition:background var(--vp-t-color),color var(--vp-t-color)}.vp-code-tab-nav:hover{background:var(--code-tabs-c-hover)}.vp-code-tab-nav:before,.vp-code-tab-nav:after{content:" ";position:absolute;bottom:0;z-index:1;width:6px;height:6px}.vp-code-tab-nav:before{right:100%}.vp-code-tab-nav:after{left:100%}.vp-code-tab-nav.active{background:var(--code-c-bg)}.vp-code-tab-nav.active:before{background:radial-gradient(12px at left top,transparent 50%,var(--code-c-bg) 50%)}.vp-code-tab-nav.active:after{background:radial-gradient(12px at right top,transparent 50%,var(--code-c-bg) 50%)}.vp-code-tab-nav:first-child:before{display:none}[dir=rtl] .vp-code-tab-nav:first-child:before{display:block}[dir=rtl] .vp-code-tab-nav:first-child:after{display:none}.vp-code-tab{display:none}@media print{.vp-code-tab{display:block}}.vp-code-tab.active{display:block}.vp-code-tab div[class*=language-]{border-top-left-radius:0;border-top-right-radius:0}@media (max-width: 419px){.vp-code-tab div[class*=language-]{margin:.75rem -1.5rem;border-radius:0}}.vp-code-tab div[class*=language-].line-numbers-mode:after{border-top-left-radius:0}.vp-code-tab div[class*=language-] pre{border-top-left-radius:0;border-top-right-radius:0}@media (max-width: 419px){.vp-code-tab div[class*=language-] pre{border-radius:0}}@media print{.vp-code-tab div[class*=language-] code{white-space:pre-wrap}}.vp-code-tab-title{display:none;font-weight:500}@media print{.vp-code-tab-title{display:block}}.vp-tabs{margin:1.5rem 0;border:1px solid var(--vp-c-border);border-radius:8px}@media (max-width: 419px){[vp-content]>.vp-tabs{margin-inline:-1.5rem;border:none;border-bottom:1px solid var(--vp-c-border);border-radius:0}}.vp-tabs-nav{overflow-x:auto;margin:0;padding:0;border-radius:.5rem .5rem 0 0;background:var(--tab-c-bg-nav);list-style:none;white-space:nowrap;transition:background var(--vp-t-color)}@media print{.vp-tabs-nav{display:none}}@media (max-width: 419px){.vp-tabs-nav{border-radius:0}}.vp-tab-nav{position:relative;min-width:4rem;margin:0;padding:.5em 1em;border:none;border-radius:.5rem .5rem 0 0;background:#0000;color:var(--tab-c-nav);font-weight:600;font-size:.875em;line-height:1.75;cursor:pointer;transition:background var(--vp-t-color),color var(--vp-t-color)}.vp-tab-nav:hover{background:var(--tab-c-bg-nav-hover)}.vp-tab-nav:before,.vp-tab-nav:after{content:" ";position:absolute;bottom:0;z-index:1;width:8px;height:8px}.vp-tab-nav:before{right:100%}.vp-tab-nav:after{left:100%}.vp-tab-nav.active{background:var(--tab-c-bg)}.vp-tab-nav.active:before{background:radial-gradient(16px at left top,transparent 50%,var(--tab-c-bg) 50%)}.vp-tab-nav.active:after{background:radial-gradient(16px at right top,transparent 50%,var(--tab-c-bg) 50%)}.vp-tab-nav:first-child:before{display:none}.vp-tab{display:none;padding:1rem .75rem;border-radius:0 0 .5rem .5rem;background:var(--tab-c-bg);transition:background var(--vp-t-color)}@media print{.vp-tab{display:block;padding:.5rem}}.vp-tab.active{display:block}.vp-tab:nth-child(n+2) .vp-tab-title{border-top:none}.vp-tab-title{display:none;padding:.25rem 0;border-top:1px solid var(--vp-c-border);font-weight:500}@media print{.vp-tab-title{display:block}}:root{--code-tabs-c-text: var(--code-c-text);--code-tabs-c-bg: var(--code-c-highlight-bg);--code-tabs-c-hover: var(--code-c-bg);--tab-c-bg: var(--vp-c-bg);--tab-c-nav: var(--vp-c-text);--tab-c-bg-nav: var(--vp-c-grey-bg);--tab-c-bg-nav-hover: var(--vp-c-control-hover)}.vp-badge{display:inline-block;vertical-align:top;height:18px;padding:0 6px;border-radius:3px;background:var(--vp-c-accent-soft);color:var(--vp-c-accent);font-size:14px;line-height:18px;transition:background var(--vp-t-color),color var(--vp-t-color)}.vp-badge+.vp-badge{margin-inline-start:5px}.vp-badge.tip{background:var(--badge-c-tip-bg);color:var(--badge-c-tip-text)}.vp-badge.warning{background:var(--badge-c-warning-bg);color:var(--badge-c-warning-text)}.vp-badge.danger{background:var(--badge-c-danger-bg);color:var(--badge-c-danger-text)}.vp-badge.important{background:var(--badge-c-important-bg);color:var(--badge-c-important-text)}.vp-badge.info{background:var(--badge-c-info-bg);color:var(--badge-c-info-text)}.vp-badge.note{background:var(--badge-c-note-bg);color:var(--badge-c-note-text)}.vp-features{display:flex;flex-wrap:wrap;place-content:stretch space-between;align-items:flex-start;margin-top:2.5rem;padding:1.2rem 0;border-top:1px solid var(--vp-c-gutter);transition:border-color var(--vp-t-color)}@media (max-width: 719px){.vp-features{flex-direction:column}}.vp-feature{flex-grow:1;flex-basis:30%;max-width:30%}@media (max-width: 719px){.vp-feature{max-width:100%;padding:0 2.5rem}}.vp-feature h2{padding-bottom:0;border-bottom:none;font-weight:500;font-size:1.4rem}@media (max-width: 419px){.vp-feature h2{font-size:1.25rem}}.vp-feature p{color:var(--vp-c-text-mute)}.vp-footer{padding:2.5rem;border-top:1px solid var(--vp-c-border);color:var(--vp-c-text-mute);text-align:center;transition:border-color var(--vp-t-color)}.vp-hero{text-align:center}.vp-hero-image{display:block;max-width:100%;max-height:280px;margin:3rem auto 1.5rem}@media (max-width: 419px){.vp-hero-image{max-height:210px;margin:2rem auto 1.2rem}}#main-title{font-size:3rem}@media (max-width: 419px){#main-title{font-size:2rem}}#main-title,.vp-hero-description,.vp-hero-actions{margin:1.8rem auto}@media (max-width: 419px){#main-title,.vp-hero-description,.vp-hero-actions{margin:1.2rem auto}}.vp-hero-actions{display:flex;flex-wrap:wrap;gap:1rem;justify-content:center}.vp-hero-description{max-width:35rem;color:var(--vp-c-text-mute);font-size:1.6rem;line-height:1.3}@media (max-width: 419px){.vp-hero-description{font-size:1.2rem}}.vp-hero-action-button{display:inline-block;box-sizing:border-box;padding:.8rem 1.6rem;border:2px solid var(--vp-c-accent-bg);border-radius:4px;background-color:var(--vp-c-bg);color:var(--vp-c-accent);font-size:1.2rem;transition:background-color border-color color var(--vp-t-color)}@media (max-width: 419px){.vp-hero-action-button{padding:.6rem 1.2rem;font-size:1rem}}.vp-hero-action-button:hover{color:var(--vp-c-accent-text)}.vp-hero-action-button.primary{background-color:var(--vp-c-accent-bg);color:var(--vp-c-accent-text)}.vp-hero-action-button.primary:hover{border-color:var(--vp-c-accent-hover);background-color:var(--vp-c-accent-hover)}.vp-home{display:block;max-width:var(--homepage-width);margin:0 auto;padding:var(--navbar-height) 2rem 0}@media (max-width: 419px){.vp-home{padding-right:1.5rem;padding-left:1.5rem}}.vp-home .theme-default-content{margin:0;padding:0}.vp-site-logo{vertical-align:top;height:var(--navbar-line-height);margin-right:var(--navbar-padding-v)}.vp-site-name{position:relative;color:var(--vp-c-text);font-weight:600;font-size:1.3rem}@media screen and (max-width: 719px){.vp-site-name{display:block;overflow:hidden;width:calc(100vw - 11rem);text-overflow:ellipsis;white-space:nowrap}}.vp-dropdown-enter-from,.vp-dropdown-leave-to{height:0!important}.vp-navbar-dropdown-wrapper{cursor:pointer}.vp-navbar-dropdown-wrapper:not(.mobile){height:1.8rem}.vp-navbar-dropdown-wrapper:not(.mobile):hover .vp-navbar-dropdown,.vp-navbar-dropdown-wrapper:not(.mobile).open .vp-navbar-dropdown{display:block!important}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown{overflow:hidden;transition:height .1s ease-out;padding-top:.5rem}.vp-navbar-dropdown-wrapper:not(.mobile) .vp-navbar-dropdown{position:absolute;top:100%;right:0;display:none;overflow-y:auto;box-sizing:border-box;height:auto!important;max-height:calc(100vh - 2.7rem);margin:0;padding:.6rem 0;border:1px solid var(--vp-c-gutter);border-radius:.5rem;background-color:var(--vp-c-bg-elv);text-align:left;white-space:nowrap}.vp-navbar-dropdown-title{display:block;padding:inherit;border:none;background:transparent;color:var(--vp-c-text);font-weight:500;font-size:.9rem;font-family:inherit;line-height:1.4rem;cursor:inherit}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown-title{display:none}.vp-navbar-dropdown-title:hover{border-color:transparent}.vp-navbar-dropdown-title-mobile{display:none;padding:inherit;border:none;background:transparent;color:var(--vp-c-text);font-weight:600;font-size:inherit;font-family:inherit;line-height:1.4rem;cursor:inherit}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown-title-mobile{display:block}.vp-navbar-dropdown-title-mobile:hover{color:var(--vp-c-accent)}.vp-navbar-dropdown-item{color:inherit;line-height:1.7rem}.vp-navbar-dropdown-item a{position:relative;display:block;margin-bottom:0;padding:0 1.5rem 0 1.25rem;border-bottom:none;font-weight:400;line-height:1.7rem}.vp-navbar-dropdown-item a:hover,.vp-navbar-dropdown-item a.route-link-active{color:var(--vp-c-accent)}.vp-navbar-dropdown-item a.route-link-active:after{content:"";position:absolute;top:calc(50% - 2px);left:9px;width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:5px solid var(--vp-c-accent)}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown-item>a{font-size:15px;line-height:2rem}.vp-navbar-dropdown-subtitle{margin:.45rem 0 0;padding:1rem 0 .45rem;border-top:1px solid var(--vp-c-gutter);font-size:.9rem}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown-subtitle{margin-top:0;padding-top:0;padding-bottom:0;border-top:0;font-size:15px;line-height:2rem}.vp-navbar-dropdown-item:first-child .vp-navbar-dropdown-subtitle{margin-top:0;padding-top:0;border-top:0}.vp-navbar-dropdown-subtitle>span{padding:0 1.5rem 0 1.25rem}.vp-navbar-dropdown-subtitle>a{font-weight:inherit}.vp-navbar-dropdown-subtitle>a.route-link-active:after{display:none}.vp-navbar-dropdown-subitem-wrapper{padding:0;list-style:none}.vp-navbar-dropdown-subitem{font-size:.9em}.vp-navbar-dropdown-wrapper.mobile .vp-navbar-dropdown-subitem{padding-left:1rem;font-size:14px}.vp-navbar-items{display:inline-block}@media print{.vp-navbar-items{display:none}}.vp-navbar-items a{display:inline-block;color:inherit;line-height:1.4rem}.vp-navbar-items a:hover,.vp-navbar-items a.route-link-active{color:var(--vp-c-text)}.vp-navbar-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:var(--navbar-line-height)}@media (max-width: 719px){.vp-navbar-item{margin-left:0}}.vp-navbar-item:first-child{margin-left:0}.vp-navbar-item a:hover,.vp-navbar-item a.route-link-active{color:var(--vp-c-accent)}.vp-navbar-item>a:hover,.vp-navbar-item>a.route-link-active{margin-bottom:-2px;border-bottom:2px solid var(--vp-c-accent)}@media (max-width: 719px){.vp-navbar-item>a:hover,.vp-navbar-item>a.route-link-active{margin-bottom:0;border-bottom:none}}.vp-toggle-color-mode-button{display:flex;margin:auto;margin-left:1rem;border:0;background:none;color:var(--vp-c-text);opacity:.8;cursor:pointer}@media print{.vp-toggle-color-mode-button{display:none}}.vp-toggle-color-mode-button:hover{opacity:1}.vp-toggle-color-mode-button .light-icon,.vp-toggle-color-mode-button .dark-icon{width:1.25rem;height:1.25rem}.vp-toggle-sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}@media screen and (max-width: 719px){.vp-toggle-sidebar-button{display:block}}.vp-toggle-sidebar-button .icon{display:flex;flex-direction:column;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;cursor:inherit}.vp-toggle-sidebar-button .icon span{display:inline-block;width:100%;height:2px;border-radius:2px;background-color:var(--vp-c-text);transition:transform var(--vp-t-transform)}.vp-toggle-sidebar-button .icon span:nth-child(2){margin:6px 0}.vp-theme-container.sidebar-open .vp-toggle-sidebar-button .icon span:nth-child(1){transform:rotate(45deg) translate3d(5.5px,5.5px,0)}.vp-theme-container.sidebar-open .vp-toggle-sidebar-button .icon span:nth-child(2){transform:scale3d(0,1,1)}.vp-theme-container.sidebar-open .vp-toggle-sidebar-button .icon span:nth-child(3){transform:rotate(-45deg) translate3d(6px,-6px,0)}.vp-theme-container.sidebar-open .vp-toggle-sidebar-button .icon span:nth-child(1),.vp-theme-container.sidebar-open .vp-toggle-sidebar-button .icon span:nth-child(3){transform-origin:center}.vp-navbar{--navbar-line-height: calc( var(--navbar-height) - 2 * var(--navbar-padding-v) );position:fixed;top:0;right:0;left:0;z-index:20;box-sizing:border-box;height:var(--navbar-height);padding:var(--navbar-padding-v) var(--navbar-padding-h);border-bottom:1px solid var(--vp-c-border);background-color:var(--vp-navbar-c-bg);line-height:var(--navbar-line-height);transition:background-color var(--vp-t-color),border-color var(--vp-t-color)}@media screen and (max-width: 719px){.vp-navbar{padding-left:4rem}}.vp-navbar-items-wrapper{position:absolute;top:var(--navbar-padding-v);right:var(--navbar-padding-h);display:flex;box-sizing:border-box;height:var(--navbar-line-height);padding-left:var(--navbar-padding-h);font-size:.9rem;white-space:nowrap}.vp-page-meta{max-width:var(--content-width);margin:0 auto;padding:.75rem 2.5rem;display:flex;flex-wrap:wrap;justify-content:space-between;overflow:auto}@media (max-width: 959px){.vp-page-meta{padding:2rem}}@media (max-width: 419px){.vp-page-meta{padding:1.5rem}}@media print{.vp-page-meta{margin:0!important;padding-right:0!important;padding-left:0!important}}@media (max-width: 719px){.vp-page-meta{display:block}}.vp-page-meta .vp-meta-item{flex-grow:1}.vp-page-meta .vp-meta-item .vp-meta-label{font-weight:500}.vp-page-meta .vp-meta-item .vp-meta-label:not(a){color:var(--vp-c-text-mute)}.vp-page-meta .vp-meta-item .vp-meta-info{color:var(--vp-c-text-mute);font-weight:400}.vp-page-meta .git-info{text-align:end}.vp-page-meta .edit-link{margin-top:.25rem;margin-right:.5rem;margin-bottom:.25rem;font-size:14px}@media print{.vp-page-meta .edit-link{display:none}}.vp-page-meta .edit-link .edit-icon{position:relative;bottom:-.125em;width:1em;height:1em;margin-right:.25em}.vp-page-meta .last-updated,.vp-page-meta .contributors{margin-top:.25rem;margin-bottom:.25rem;font-size:14px}@media (max-width: 719px){.vp-page-meta .last-updated,.vp-page-meta .contributors{font-size:13px;text-align:start}}.vp-page-nav{display:flex;flex-wrap:wrap;max-width:var(--content-width, 740px);min-height:2rem;margin-top:0;margin-right:auto;margin-left:auto;padding:1rem 2rem 0;border-top:1px solid var(--vp-c-gutter);transition:border-top var(--vp-t-color)}@media (max-width: 959px){.vp-page-nav{padding-right:1rem;padding-left:1rem}}@media print{.vp-page-nav{display:none}}.vp-page-nav .route-link{display:inline-block;flex-grow:1;margin:.25rem;padding:.25rem .5rem;border:1px solid var(--vp-c-gutter);border-radius:.25rem}.vp-page-nav .route-link:hover{background:var(--vp-c-control)}.vp-page-nav .route-link .hint{color:var(--vp-c-text-mute);font-size:.875rem;line-height:2}.vp-page-nav .prev{text-align:start}.vp-page-nav .next{text-align:end}.vp-page{display:block;padding-top:var(--navbar-height);padding-bottom:2rem;padding-left:var(--sidebar-width)}@media (max-width: 959px){.vp-page{padding-left:var(--sidebar-width-mobile)}}@media (max-width: 719px){.vp-page{padding-left:0}}.vp-page .theme-default-content{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem;padding-top:0}@media (max-width: 959px){.vp-page .theme-default-content{padding:2rem}}@media (max-width: 419px){.vp-page .theme-default-content{padding:1.5rem}}.vp-sidebar-item{border-left:.25rem solid transparent;color:var(--vp-c-text);cursor:default}.vp-sidebar-item:focus-visible{outline-width:1px;outline-offset:-1px}.vp-sidebar-item.vp-sidebar-heading{box-sizing:border-box;width:100%;margin:0;padding:.35rem 1.5rem .35rem 1.25rem;font-weight:700;font-size:1.1em;transition:color .15s ease}.vp-sidebar-item.vp-sidebar-heading+.vp-sidebar-children{overflow:hidden;transition:height .1s ease-out;margin-bottom:.75rem}.vp-sidebar-item.collapsible{cursor:pointer}.vp-sidebar-item:not(.vp-sidebar-heading){display:inline-block;box-sizing:border-box;width:100%;margin:0;padding:.35rem 1rem .35rem 2rem;font-weight:400;font-size:1em;line-height:1.4}.vp-sidebar-item:not(.vp-sidebar-heading)+.vp-sidebar-children{padding-left:1rem;font-size:.95em}.vp-sidebar-children .vp-sidebar-children .vp-sidebar-item:not(.vp-sidebar-heading){padding:.25rem 1rem .25rem 1.75rem}.vp-sidebar-children .vp-sidebar-children .vp-sidebar-item:not(.vp-sidebar-heading).active{border-left-color:transparent;font-weight:500}a.vp-sidebar-heading+.vp-sidebar-children .vp-sidebar-item:not(.vp-sidebar-heading).active{border-left-color:transparent}.vp-sidebar-item.active:not(p.vp-sidebar-heading){border-left-color:var(--vp-c-accent);color:var(--vp-c-accent);font-weight:600}a.vp-sidebar-item{cursor:pointer}a.vp-sidebar-item:hover{color:var(--vp-c-accent)}.vp-sidebar-items{margin:0;padding:1.5rem 0;list-style-type:none}@media (max-width: 719px){.vp-sidebar-items{padding:1rem 0}}.vp-sidebar-items ul{margin:0;padding:0;list-style-type:none}.vp-sidebar-items a{display:inline-block}.vp-sidebar{position:fixed;top:var(--navbar-height);bottom:0;left:0;z-index:10;overflow-y:auto;box-sizing:border-box;width:var(--sidebar-width);margin:0;border-right:1px solid var(--vp-c-border);background-color:var(--vp-sidebar-c-bg);font-size:16px;transition:transform var(--vp-t-transform),background-color var(--vp-t-color),border-color var(--vp-t-color);scrollbar-color:var(--vp-c-accent-bg) var(--vp-c-gutter);scrollbar-width:thin}@media (max-width: 959px){.vp-sidebar{width:var(--sidebar-width-mobile);font-size:15px}}@media (max-width: 719px){.vp-sidebar{top:0;padding-top:var(--navbar-height);transform:translate(-100%)}}.vp-sidebar::-webkit-scrollbar{width:7px}.vp-sidebar::-webkit-scrollbar-track{background-color:var(--vp-c-gutter)}.vp-sidebar::-webkit-scrollbar-thumb{background-color:var(--vp-c-accent-bg)}.vp-sidebar .vp-navbar-items{display:none;padding:.5rem 0 .75rem;border-bottom:1px solid var(--vp-c-gutter);transition:border-color var(--vp-t-color)}@media (max-width: 719px){.vp-sidebar .vp-navbar-items{display:block}.vp-sidebar .vp-navbar-items .vp-navbar-dropdown-item a.route-link-active:after{top:calc(1rem - 2px)}}.vp-sidebar .vp-navbar-items ul{margin:0;padding:0;list-style-type:none}.vp-sidebar .vp-navbar-items a{font-weight:600}.vp-sidebar .vp-navbar-item{display:block;padding:.5rem 0 .5rem 1.5rem;font-size:1.1em;line-height:1.25rem}.vp-sidebar-mask{position:fixed;top:0;left:0;z-index:9;display:none;width:100vw;height:100vh}.vp-theme-container.no-navbar .vp-sidebar{top:0}@media (max-width: 719px){.vp-theme-container.no-navbar .vp-sidebar{padding-top:0}}.vp-theme-container.no-navbar .vp-page{padding-top:0}.vp-theme-container.no-navbar .theme-default-content h1,.vp-theme-container.no-navbar .theme-default-content h2,.vp-theme-container.no-navbar .theme-default-content h3,.vp-theme-container.no-navbar .theme-default-content h4,.vp-theme-container.no-navbar .theme-default-content h5,.vp-theme-container.no-navbar .theme-default-content h6{margin-top:1.5rem;padding-top:0}.vp-theme-container.no-sidebar .vp-sidebar{display:none}@media (max-width: 719px){.vp-theme-container.no-sidebar .vp-sidebar{display:block}}.vp-theme-container.no-sidebar .vp-page{padding-left:0}@media (max-width: 719px){.vp-theme-container.sidebar-open .vp-sidebar{transform:translate(0)}.vp-theme-container.sidebar-open .vp-sidebar-mask{display:block}}.fade-slide-y-enter-active{transition:all .2s ease}.fade-slide-y-leave-active{transition:all .2s cubic-bezier(1,.5,.8,1)}.fade-slide-y-enter-from,.fade-slide-y-leave-to{opacity:0;transform:translateY(10px)}.vp-theme-container[data-v-67c08c1d]{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width: 959px){.vp-theme-container[data-v-67c08c1d]{padding:2rem}}:root{--vp-c-white: #fff;--vp-c-black: #000;--vp-c-grey-text: #656869;--vp-c-grey-hover: #e4e4e9;--vp-c-grey-bg: #ebebef;--vp-c-grey-soft: rgb(142 150 170 / 14%);--vp-c-indigo-text: #3451b2;--vp-c-indigo-hover: #3a5ccc;--vp-c-indigo-bg: #5672cd;--vp-c-indigo-soft: rgb(100 108 255 / 14%);--vp-c-purple-text: #6f42c1;--vp-c-purple-hover: #7e4cc9;--vp-c-purple-bg: #8e5cd9;--vp-c-purple-soft: rgb(159 122 234 / 14%);--vp-c-blue-text: #2888a7;--vp-c-blue-hover: #2d98ba;--vp-c-blue-bg: #2fa1c5;--vp-c-blue-soft: rgb(27 178 229 / 14%);--vp-c-green-text: #18794e;--vp-c-green-hover: #299764;--vp-c-green-bg: #30a46c;--vp-c-green-soft: rgb(16 185 129 / 14%);--vp-c-yellow-text: #915930;--vp-c-yellow-hover: #946300;--vp-c-yellow-bg: #c28100;--vp-c-yellow-soft: rgb(234 179 8 / 14%);--vp-c-red-text: #b8272c;--vp-c-red-hover: #d5393e;--vp-c-red-bg: #e0575b;--vp-c-red-soft: rgb(244 63 94 / 14%)}[data-theme=dark]{--vp-c-white: #000;--vp-c-black: #fff;--vp-c-grey-text: #939499;--vp-c-grey-hover: #414853;--vp-c-grey-bg: #32363f;--vp-c-grey-soft: rgb(101 117 133 / 16%);--vp-c-indigo-text: #a8b1ff;--vp-c-indigo-hover: #5c73e7;--vp-c-indigo-bg: #3e63dd;--vp-c-indigo-soft: rgb(100 108 255 / 16%);--vp-c-blue-text: #c9e8f2;--vp-c-blue-hover: #a6d9ea;--vp-c-blue-bg: #2785a3;--vp-c-blue-soft: rgb(27 178 229 / 16%);--vp-c-purple-text: #c8abfa;--vp-c-purple-hover: #a879e6;--vp-c-purple-bg: #8e5cd9;--vp-c-purple-soft: rgb(159 122 234 / 16%);--vp-c-green-text: #3dd68c;--vp-c-green-hover: #30a46c;--vp-c-green-bg: #298459;--vp-c-green-soft: rgb(16 185 129 / 16%);--vp-c-yellow-text: #f9b44e;--vp-c-yellow-hover: #da8b17;--vp-c-yellow-bg: #a46a0a;--vp-c-yellow-soft: rgb(234 179 8 / 16%);--vp-c-red-text: #f66f81;--vp-c-red-hover: #f14158;--vp-c-red-bg: #b62a3c;--vp-c-red-soft: rgb(244 63 94 / 16%)}:root{color-scheme:light}[data-theme=dark]{color-scheme:dark}html,body{background:var(--vp-c-bg, #fff);accent-color:var(--vp-c-accent, #299764);transition:background-color var(--vp-t-color)}html{font-size:16px;font-display:optional;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none}@media print{html{font-size:12pt}}html[data-theme=dark]{color-scheme:dark}body{min-height:100vh;margin:0;padding:0;color:var(--vp-c-text, rgb(60, 60, 67));font-size:1rem;font-synthesis:style}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25;overflow-wrap:break-word}h1:focus-visible,h2:focus-visible,h3:focus-visible,h4:focus-visible,h5:focus-visible,h6:focus-visible{outline:none}h1{font-size:2rem}h2{padding-bottom:.3rem;border-bottom:1px solid var(--vp-c-gutter, #e2e2e3);font-size:1.65rem;transition:border-color var(--vp-t-color)}h3{font-size:1.35rem}h4{font-size:1.15rem}h5{font-size:1.05rem}h6{font-size:1rem}p,ul,ol{line-height:1.6;overflow-wrap:break-word}@media print{p,ul,ol{line-height:1.5}}ul,ol{padding-inline-start:1.2em}a{color:var(--vp-c-accent, #299764);font-weight:500;text-decoration:none;overflow-wrap:break-word}a.header-anchor{position:relative;color:inherit;text-decoration:none}a.header-anchor:before{content:"¶";position:absolute;top:.4167em;left:-.75em;display:none;color:var(--vp-c-accent, #299764);font-size:.75em}[dir=rtl] a.header-anchor:before{right:-.75em}a.header-anchor:hover:before{display:block}a.header-anchor:focus-visible{outline:none}a.header-anchor:focus-visible:before{display:block;outline:auto}strong{font-weight:600}blockquote{margin:1rem 0;padding:.25rem 0 .25rem 1rem;border-inline-start:.2rem solid var(--vp-c-border-hard, #b8b8ba);color:var(--vp-c-text-mute, rgba(60, 60, 67, .78));font-size:1rem;overflow-wrap:break-word;transition:border-color var(--vp-t-color),color var(--vp-t-color)}blockquote>p{margin:0}hr{border:0;border-bottom:1px solid var(--vp-c-gutter, #e2e2e3);transition:border-color var(--vp-t-color)}:not(pre)>code{margin:0;padding:3px 6px;border-radius:4px;background:var(--vp-c-grey-soft, rgba(142, 150, 170, .14));font-size:.875em;overflow-wrap:break-word;transition:background-color var(--vp-t-color),color var(--vp-t-color)}p a code{color:var(--vp-c-accent, #299764);font-weight:400}table code{padding:.1rem .4rem}kbd{display:inline-block;min-width:1em;margin-inline:.125rem;padding:.25em;border:1px solid var(--vp-c-border, #c2c2c4);border-radius:.25em;box-shadow:1px 1px 4px 0 var(--vp-c-shadow, rgba(0, 0, 0, .15));line-height:1;letter-spacing:-.1em;text-align:center}table{display:block;overflow-x:auto;margin:1rem 0;border-collapse:collapse}tbody tr:nth-child(odd){background:var(--vp-c-bg-alt, #f6f8fa);transition:background-color var(--vp-t-color)}th,td{padding:.6em 1em;border:1px solid var(--vp-c-border-hard, #d1d4d7);transition:border-color var(--vp-t-color)}pre{text-align:left;direction:ltr;white-space:pre;word-spacing:normal;word-wrap:normal;word-break:normal;overflow-wrap:unset;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}@media print{pre{white-space:pre-wrap}}pre code{padding:0;border-radius:0}@page{margin:2cm;font-size:12pt;size:a4}@media print{*,:after,:before{box-shadow:none!important;text-shadow:none!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}a{color:inherit;font-weight:inherit!important;font-size:inherit!important;text-decoration:underline}a.header-anchor{text-decoration:none}abbr[title]:after{content:" (" attr(title) ")"}pre{border:1px solid #eee;white-space:pre-wrap!important}pre>code{white-space:pre-wrap!important}blockquote{border-inline-start:.2rem solid #ddd;color:inherit}blockquote,pre{orphans:5;widows:5}img,tr,canvas{page-break-inside:avoid}}@media (prefers-reduced-motion: reduce){*,:before,:after{background-attachment:initial!important;scroll-behavior:auto!important;transition-delay:0s!important;transition-duration:0s!important;animation-duration:1ms!important;animation-delay:-1ms!important;animation-iteration-count:1!important}}:root{--vp-c-accent: #299764;--vp-c-accent-bg: #3eaf7c;--vp-c-accent-hover: #4abf8a;--vp-c-accent-text: var(--vp-c-white);--vp-c-accent-soft: rgb(16 185 129 / 14%);--vp-c-bg: #fff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #fff;--vp-c-text: rgb(60 60 67);--vp-c-text-mute: rgb(60 60 67 / 78%);--vp-c-text-subtle: rgb(60 60 67 / 56%);--vp-c-gutter: #e2e2e3;--vp-c-border: #c2c2c4;--vp-c-border-hard: #b8b8ba;--vp-c-shadow: rgb(0 0 0 / 15%);--vp-c-control: rgb(142 150 170 / 10%);--vp-c-control-hover: rgb(142 150 170 / 16%);--vp-c-control-disabled: #eaeaea;--vp-navbar-c-bg: var(--vp-c-bg);--vp-sidebar-c-bg: var(--vp-c-bg);--vp-c-code-tab-title: var(--code-c-text, rgb(255 255 255 / 90%));--vp-c-code-tab-bg: var(--code-bg-color, var(--code-c-bg));--vp-c-code-tab-active: var(--vp-c-accent);--badge-c-tip-text: var(--vp-c-green-text);--badge-c-tip-bg: var(--vp-c-green-soft);--badge-c-warning-text: var(--vp-c-yellow-text);--badge-c-warning-bg: var(--vp-c-yellow-soft);--badge-c-danger-text: var(--vp-c-red-text);--badge-c-danger-bg: var(--vp-c-red-soft);--badge-c-important-text: var(--vp-c-purple-text);--badge-c-important-bg: var(--vp-c-purple-soft);--badge-c-info-text: var(--vp-c-indigo-text);--badge-c-info-bg: var(--vp-c-indigo-soft);--badge-c-note-text: var(--vp-c-grey-text);--badge-c-note-bg: var(--vp-c-grey-soft);--font-family: -apple-system, "BlinkMacSystemFont", "Segoe UI", roboto, oxygen, ubuntu, cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--navbar-height: 3.6rem;--navbar-padding-v: .7rem;--navbar-padding-h: 1.5rem;--sidebar-width: 20rem;--sidebar-width-mobile: calc(var(--sidebar-width) * .82);--content-width: 740px;--homepage-width: 960px;--header-offset: var(--navbar-height);--vp-t-color: .3s ease;--vp-t-transform: .3s ease;--external-link-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");--external-link-c-icon: var(--vp-c-text-mute)}[data-theme=dark]{--vp-c-accent: #3dd68c;--vp-c-accent-bg: #3aa675;--vp-c-accent-hover: #349469;--vp-c-accent-soft: rgb(16 185 129 / 16%);--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-text: rgb(235 235 245 / 86%);--vp-c-text-mute: rgb(235 235 245 / 60%);--vp-c-text-subtle: rgb(235 235 245 / 38%);--vp-c-gutter: #000;--vp-c-border: #3c3f44;--vp-c-border-hard: #45484e;--vp-c-shadow: rgb(0 0 0 / 30%);--vp-c-control: rgb(101 117 133 / 12%);--vp-c-control-hover: rgb(101 117 133 / 18%);--vp-c-control-disabled: #363636}body{font-family:var(--font-family)}code{font-family:var(--code-font-family)}.theme-default-content h1,.theme-default-content h2,.theme-default-content h3,.theme-default-content h4,.theme-default-content h5,.theme-default-content h6{margin-top:calc(.5rem - var(--header-offset));margin-bottom:0;padding-top:calc(1rem + var(--header-offset))}.theme-default-content h1:first-child,.theme-default-content h2:first-child,.theme-default-content h3:first-child,.theme-default-content h4:first-child,.theme-default-content h5:first-child,.theme-default-content h6:first-child{margin-bottom:1rem}.theme-default-content h1:first-child+p,.theme-default-content h1:first-child+pre,.theme-default-content h1:first-child+.custom-container,.theme-default-content h2:first-child+p,.theme-default-content h2:first-child+pre,.theme-default-content h2:first-child+.custom-container,.theme-default-content h3:first-child+p,.theme-default-content h3:first-child+pre,.theme-default-content h3:first-child+.custom-container,.theme-default-content h4:first-child+p,.theme-default-content h4:first-child+pre,.theme-default-content h4:first-child+.custom-container,.theme-default-content h5:first-child+p,.theme-default-content h5:first-child+pre,.theme-default-content h5:first-child+.custom-container,.theme-default-content h6:first-child+p,.theme-default-content h6:first-child+pre,.theme-default-content h6:first-child+.custom-container{margin-top:2rem}@media (max-width: 419px){.theme-default-content h1{font-size:1.9rem}}.theme-default-content a:not(.header-anchor){text-decoration:underline}.theme-default-content img{max-width:100%}div[class*=language-]{margin:.75rem 0;transition:background-color var(--vp-t-color),color var(--vp-t-color)}@media (max-width: 419px){div[class*=language-]{--code-border-radius: 0;margin:.75rem -1.5rem}}div[class*=language-] .line.diff,div[class*=language-] .line.highlighted{transition:background-color var(--vp-t-color)}.table-of-contents .vp-badge{vertical-align:middle}.arrow{display:inline-block;vertical-align:middle;width:1em;height:1em;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='rgba(0,0,0,0.5)' d='M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z'/%3E%3C/svg%3E");background-position:center;background-repeat:no-repeat;line-height:normal;transition:all .3s}[data-theme=dark] .arrow{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='rgba(255,255,255,0.5)' d='M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z'/%3E%3C/svg%3E")}.arrow.down{transform:rotate(180deg)}.arrow.right{transform:rotate(90deg)}.arrow.left{transform:rotate(-90deg)}.vp-external-link-icon:after{content:"";display:inline-block;flex-shrink:0;width:11px;height:11px;margin-top:-1px;margin-left:4px;background:var(--external-link-c-icon);-webkit-mask-image:var(--external-link-icon);mask-image:var(--external-link-icon)}.external-link-icon .external-link:after{content:"";display:inline-block;flex-shrink:0;width:11px;height:11px;margin-top:-1px;margin-left:4px;background:var(--external-link-c-icon);-webkit-mask-image:var(--external-link-icon);mask-image:var(--external-link-icon)}.external-link-icon .theme-default-content a[href*="://"]:not(.no-external-link-icon):after,.external-link-icon .theme-default-content a[target=_blank]:not(.no-external-link-icon):after{content:"";display:inline-block;flex-shrink:0;width:11px;height:11px;margin-top:-1px;margin-left:4px;background:var(--external-link-c-icon);-webkit-mask-image:var(--external-link-icon);mask-image:var(--external-link-icon)}@media screen and (max-width: 719px){.vp-hide-mobile{display:none}}.vp-comment{max-width:var(--content-width);margin:0 auto;padding:2rem 2.5rem}@media (max-width: 959px){.vp-comment{padding:2rem}}@media (max-width: 419px){.vp-comment{padding:1.5rem}}.vp-navbar .DocSearch{transition:background-color var(--vp-t-color)}.vp-navbar .search-box{vertical-align:top;flex:0 0 auto}@media screen and (max-width: 719px){.hint-container{margin-inline:-.75rem}}:root{--c-brand: #920097;--c-brand-light: #faaffd}html.dark{--c-brand: #920097;--c-brand-light: #faaffd}iframe{width:100%}:root{--search-c-bg: var(--vp-c-bg);--search-c-accent: var(--vp-c-accent);--search-c-text: var(--vp-c-text);--search-c-border: var(--vp-c-gutter);--search-c-item-text: var(--vp-c-text-subtle);--search-c-item-focus: var(--vp-c-bg-alt);--search-input-width: 8rem;--search-result-width: 20rem}.search-box{position:relative;display:inline-block;margin-left:1rem}@media print{.search-box{display:none}}.search-box input{display:inline-block;width:var(--search-input-width);height:2rem;padding:0 .5rem 0 2rem;border:1px solid var(--search-c-border);border-radius:2rem;background:var(--search-c-bg) url("data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='13'%3e%3cg%20stroke-width='2'%20stroke='%23aaa'%20fill='none'%3e%3cpath%20d='M11.29%2011.71l-4-4'/%3e%3ccircle%20cx='5'%20cy='5'%20r='4'/%3e%3c/g%3e%3c/svg%3e") .6rem .5rem no-repeat;background-size:1rem;color:var(--search-c-text);outline:none;font-size:.9rem;line-height:2rem;cursor:text;-webkit-appearance:none;-moz-appearance:none;appearance:none;transition:all ease .3s}@media (max-width: 719px){.search-box input{position:relative;width:0;border-color:#0000;cursor:pointer}}.search-box input:focus{border-color:var(--search-c-accent);cursor:auto}@media (max-width: 719px){.search-box input:focus{left:0;width:10rem;cursor:text}}@media (max-width: 419px){.search-box input:focus{width:8rem}}.search-box .suggestions{position:absolute;top:2rem;right:0;width:var(--search-result-width);padding:.4rem;border:1px solid var(--search-c-border);border-radius:6px;background:var(--search-c-bg);list-style-type:none}@media (max-width: 419px){.search-box .suggestions{right:-.5rem;width:calc(100vw - 4rem)}}.search-box .suggestion{padding:.4rem .6rem;border-radius:4px;line-height:1.4;cursor:pointer}.search-box .suggestion a{color:var(--search-c-item-text);white-space:normal}.search-box .suggestion.focus{background-color:var(--search-c-item-focus)}.search-box .suggestion.focus a{color:var(--search-c-accent)}.search-box .suggestion .page-title{font-weight:600}.search-box .suggestion .page-header{margin-left:.25em;font-size:.9em}@keyframes rotate{0%{transform:rotate(0)}50%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.popup-enter-active,.popup-leave-active{transition:opacity .3s,transform .3s}.popup-enter-from,.popup-leave-to{opacity:0;transform:translateY(50%) scale(.5)}.sw-hint-popup,.sw-update-popup{position:fixed;inset-inline-end:1rem;bottom:1rem;z-index:var(--pwa-z-index);padding:.5rem .75rem;border-width:0;border-radius:.5rem;background:var(--pwa-c-bg);color:var(--pwa-c-text);box-shadow:0 2px 12px 0 var(--pwa-c-shadow);font-size:1rem;line-height:1.5;cursor:pointer}@media print{.sw-hint-popup,.sw-update-popup{display:none}}.sw-hint-popup .icon-wrapper,.sw-update-popup .icon-wrapper{display:inline-block;vertical-align:middle;width:1.5rem;height:1.5rem;margin-inline-start:.4rem;border-radius:.75rem;background:var(--pwa-c-accent-bg)}.sw-hint-popup .icon-wrapper:hover,.sw-update-popup .icon-wrapper:hover{background:var(--pwa-c-accent-hover)}.sw-hint-popup .icon-wrapper svg,.sw-update-popup .icon-wrapper svg{width:1.2rem;height:1.2rem;margin:.15rem;color:var(--pwa-c-accent-text);animation:rotate 3s ease infinite}:root{--pwa-z-index: 10;--pwa-c-bg: var(--vp-c-bg-elv);--pwa-c-text: var(--vp-c-text);--pwa-c-shadow: var(--vp-c-shadow);--pwa-c-accent-bg: var(--vp-c-accent-bg);--pwa-c-accent-hover: var(--vp-c-accent-hover);--pwa-c-accent-text: var(--vp-c-accent-text);--pwa-c-control: var(--vp-c-control);--pwa-c-control-hover: var(--vp-c-control-hover);--pwa-c-text-mute: var(--vp-c-text-mute)}:root{--medium-zoom-z-index: 100;--medium-zoom-c-bg: var(--vp-c-bg-elv, #fff);--medium-zoom-opacity: 1}.medium-zoom-overlay{z-index:var(--medium-zoom-z-index);background-color:var(--medium-zoom-c-bg)!important}.medium-zoom-overlay~img{z-index:calc(var(--medium-zoom-z-index) + 1)}.medium-zoom--opened .medium-zoom-overlay{opacity:var(--medium-zoom-opacity)} diff --git a/assets/wasm-build-conf-edit-CmamvRv7.png b/assets/wasm-build-conf-edit-CmamvRv7.png new file mode 100644 index 0000000..56d8bff Binary files /dev/null and b/assets/wasm-build-conf-edit-CmamvRv7.png differ diff --git a/assets/wasm-run-configuration-x_w9-EC1.png b/assets/wasm-run-configuration-x_w9-EC1.png new file mode 100644 index 0000000..6ca168c Binary files /dev/null and b/assets/wasm-run-configuration-x_w9-EC1.png differ diff --git a/en/backend-development/index.html b/en/backend-development/index.html new file mode 100644 index 0000000..2e8225a --- /dev/null +++ b/en/backend-development/index.html @@ -0,0 +1,299 @@ + + + + + + + + + 📚 Backend development | Learning Kotlin + + + + + +
+ + + diff --git a/en/front-development/index.html b/en/front-development/index.html new file mode 100644 index 0000000..b692064 --- /dev/null +++ b/en/front-development/index.html @@ -0,0 +1,66 @@ + + + + + + + + + 📚 Frontend development | Learning Kotlin + + + + + +
+ + + diff --git a/en/index.html b/en/index.html new file mode 100644 index 0000000..866e4ac --- /dev/null +++ b/en/index.html @@ -0,0 +1,43 @@ + + + + + + + + + Welcome | Learning Kotlin + + + + + +
+ + + diff --git a/en/kotlin-features-advanced/index.html b/en/kotlin-features-advanced/index.html new file mode 100644 index 0000000..4f0a25b --- /dev/null +++ b/en/kotlin-features-advanced/index.html @@ -0,0 +1,55 @@ + + + + + + + + + 📚 Advanced and other Kotlin features | Learning Kotlin + + + + + +
+ + + diff --git a/en/kotlin-features/index.html b/en/kotlin-features/index.html new file mode 100644 index 0000000..6292608 --- /dev/null +++ b/en/kotlin-features/index.html @@ -0,0 +1,49 @@ + + + + + + + + + 📚 Kotlin language features | Learning Kotlin + + + + + +
+ + + diff --git a/en/other-technologies/index.html b/en/other-technologies/index.html new file mode 100644 index 0000000..3c18523 --- /dev/null +++ b/en/other-technologies/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 🛠 Let's make a cross-plaform app ! | Learning Kotlin + + + + + +
+ + + diff --git a/en/presentation/index.html b/en/presentation/index.html new file mode 100644 index 0000000..341bdfd --- /dev/null +++ b/en/presentation/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 🚀 Presentation of Kotlin | Learning Kotlin + + + + + +
+ + + diff --git a/en/workshops/index.html b/en/workshops/index.html new file mode 100644 index 0000000..7753bf9 --- /dev/null +++ b/en/workshops/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 📅 Workshops | Learning Kotlin + + + + + +
+ + + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..0e4322c Binary files /dev/null and b/favicon.ico differ diff --git a/fr/backend-development/index.html b/fr/backend-development/index.html new file mode 100644 index 0000000..aba41d4 --- /dev/null +++ b/fr/backend-development/index.html @@ -0,0 +1,222 @@ + + + + + + + + + 📚 Développement du backend | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/front-development/index.html b/fr/front-development/index.html new file mode 100644 index 0000000..380b55c --- /dev/null +++ b/fr/front-development/index.html @@ -0,0 +1,77 @@ + + + + + + + + + 📚 Développement frontend | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/index.html b/fr/index.html new file mode 100644 index 0000000..61f2b1d --- /dev/null +++ b/fr/index.html @@ -0,0 +1,43 @@ + + + + + + + + + Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/kotlin-features-advanced/index.html b/fr/kotlin-features-advanced/index.html new file mode 100644 index 0000000..b7350f7 --- /dev/null +++ b/fr/kotlin-features-advanced/index.html @@ -0,0 +1,55 @@ + + + + + + + + + 📚 Fonctionnalités avancées de Kotlin | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/kotlin-features/index.html b/fr/kotlin-features/index.html new file mode 100644 index 0000000..c6862a3 --- /dev/null +++ b/fr/kotlin-features/index.html @@ -0,0 +1,49 @@ + + + + + + + + + 📚 Fonctionnalités du langage Kotlin | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/other-technologies/index.html b/fr/other-technologies/index.html new file mode 100644 index 0000000..603460d --- /dev/null +++ b/fr/other-technologies/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 🛠 Construisons une app multiplateforme ! | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/presentation/index.html b/fr/presentation/index.html new file mode 100644 index 0000000..4f7b360 --- /dev/null +++ b/fr/presentation/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 🚀 Présentation de Kotlin | Apprendre Kotlin + + + + + +
+ + + diff --git a/fr/workshops/index.html b/fr/workshops/index.html new file mode 100644 index 0000000..e1571fb --- /dev/null +++ b/fr/workshops/index.html @@ -0,0 +1,43 @@ + + + + + + + + + 📅 Workshops | Apprendre Kotlin + + + + + +
+ + + diff --git a/icon-192x192.png b/icon-192x192.png new file mode 100644 index 0000000..45057eb Binary files /dev/null and b/icon-192x192.png differ diff --git a/icon-256x256.png b/icon-256x256.png new file mode 100644 index 0000000..2053f3a Binary files /dev/null and b/icon-256x256.png differ diff --git a/icon-384x384.png b/icon-384x384.png new file mode 100644 index 0000000..1447d28 Binary files /dev/null and b/icon-384x384.png differ diff --git a/icon-512x512.png b/icon-512x512.png new file mode 100644 index 0000000..6474ce2 Binary files /dev/null and b/icon-512x512.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..42d6f95 --- /dev/null +++ b/index.html @@ -0,0 +1,43 @@ + + + + + + + + + Welcome + + + + + +
+ + + diff --git a/kotlin_logo.png b/kotlin_logo.png new file mode 100644 index 0000000..22d7a18 Binary files /dev/null and b/kotlin_logo.png differ diff --git a/logo_worldline.png b/logo_worldline.png new file mode 100644 index 0000000..6981642 Binary files /dev/null and b/logo_worldline.png differ diff --git a/manifest.webmanifest b/manifest.webmanifest new file mode 100644 index 0000000..95213a2 --- /dev/null +++ b/manifest.webmanifest @@ -0,0 +1 @@ +{"name":"Kotlin training","short_name":"Kotlin training","description":"A site built with vuepress","lang":"en-US","start_url":"/learning-kotlin/index.html","scope":"/learning-kotlin/","display":"standalone","theme_color":"#f635a4","background_color":"#e8d4f2","orientation":"portrait-primary","prefer_related_applications":false,"icons":[{"src":"icon-192x192.png","sizes":"192x192","type":"image/png"},{"src":"icon-256x256.png","sizes":"256x256","type":"image/png"},{"src":"icon-384x384.png","sizes":"384x384","type":"image/png"},{"src":"icon-512x512.png","sizes":"512x512","type":"image/png"}]} diff --git a/service-worker.js b/service-worker.js new file mode 100644 index 0000000..f526c6d --- /dev/null +++ b/service-worker.js @@ -0,0 +1 @@ +if(!self.define){let e,s={};const i=(i,d)=>(i=new URL(i+".js",d).href,s[i]||new Promise((s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()})).then((()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e})));self.define=(d,n)=>{const r=e||("document"in self?document.currentScript.src:"")||location.href;if(s[r])return;let a={};const f=e=>i(e,r),c={module:{uri:r},exports:a,require:f};s[r]=Promise.all(d.map((e=>c[e]||f(e)))).then((e=>(n(...e),a)))}}define(["./workbox-1ab968a5"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.clientsClaim(),e.precacheAndRoute([{url:"assets/404.html-CB0hfWEP.js",revision:"0a131510de57c6e8d042cca8f79723a0"},{url:"assets/Androidmakers2023Kotlinshortlink-7XGfMd7N.svg",revision:"d6f2cc50c4311d68a92f93e0d12b284b"},{url:"assets/app-Djq7wF8p.js",revision:"ac5615f7999b1595d7f98d9755b749f5"},{url:"assets/index-DTEEl-sV.js",revision:"46a193641571106d3b7b43f9bc2a2735"},{url:"assets/index.html-28L8qS8U.js",revision:"2c4026042143cc9e1ad37c32c7aa7f7e"},{url:"assets/index.html-2g5kMIFT.js",revision:"82d63f43ce16bdd1bb017065c70248f6"},{url:"assets/index.html-2LK4oqoY.js",revision:"be89bf0377b851b90460b9e505abbf36"},{url:"assets/index.html-B08ZAEqY.js",revision:"8ec77c8f764d12efdfe835e4e3602ab9"},{url:"assets/index.html-BHDS7_46.js",revision:"981445ca7b818d48c9f8c80eeaec9b3d"},{url:"assets/index.html-BwZborl3.js",revision:"9bdfa2de6505de8d147207d5abf70943"},{url:"assets/index.html-BZTbG60u.js",revision:"0d14c9af9ac170be32b3e126385e8420"},{url:"assets/index.html-CcuJhM9n.js",revision:"3496172fe20fc0bf47bca2d052da5ae5"},{url:"assets/index.html-CeMqYfna.js",revision:"205e34794eb21c3146582d65b6b50dcb"},{url:"assets/index.html-CIUQNmed.js",revision:"0a44a55b87678a83f66cf9a4aa8d3f6a"},{url:"assets/index.html-COrAJfz9.js",revision:"54502cabb63319e6f840277e2cbe0041"},{url:"assets/index.html-D-c6bFFq.js",revision:"770d652c53305ec2c2bac1818775dc5c"},{url:"assets/index.html-DgauC6Dk.js",revision:"4402dc67be4be09cecdf36f95bb47374"},{url:"assets/index.html-DI1rj2RX.js",revision:"42ad257f12b109263cee35db3eb9e950"},{url:"assets/index.html-Dz4P2gMg.js",revision:"c9ebe159dadf0b117eb6c027801d8f34"},{url:"assets/index.html-jwVfesBb.js",revision:"5b069ca27e9559fdff8e0c674e3a79f9"},{url:"assets/index.html-zXMBiwyM.js",revision:"8dffedceb18d5c732333a7e4129b908f"},{url:"assets/kmp_codelab-CiTPMWjt.js",revision:"6105fc434ff6ae7dfe6a0c1067618361"},{url:"assets/Kotlin-Beyond-Android-CYulNy7n.js",revision:"08541d5d5af1996b1062332cd764ad7c"},{url:"assets/kotlin-decision-tree-4i7nEr1Z.svg",revision:"f257bed572584c782ad1e37c483ba4b6"},{url:"assets/kotlin-used-for-Bdlavnqs.js",revision:"92007e36f0c0d3b7b6265af81a141307"},{url:"assets/kotlin-wasm-webapp-R4_9ho9v.js",revision:"4be4df631b1ce26e600722ef2854991e"},{url:"assets/logo_worldline-dinT9MYm.js",revision:"aa655bfd05e03a82f745b7aa0a99c90f"},{url:"assets/setupDevtools-7MC2TMWH-TJgRKbnT.js",revision:"398aad61e25f6bc03e099b16f9f59303"},{url:"assets/style-CIQ0kvik.css",revision:"09977608070cc14a9771d793a71886b9"},{url:"404.html",revision:"2185fa2595202b4f1ce924157008af30"},{url:"en/backend-development/index.html",revision:"8dd549578b7507f217ff362499284e20"},{url:"en/front-development/index.html",revision:"b368bde3fd9965f45cd8c215fc50352d"},{url:"en/index.html",revision:"89a52569d75c8a8d0e6ce63c5f97b378"},{url:"en/kotlin-features-advanced/index.html",revision:"db56e9116504a138bdc3dc9007a22250"},{url:"en/kotlin-features/index.html",revision:"7aed027658ded7bd9824fd3889cfe3c3"},{url:"en/other-technologies/index.html",revision:"a13f6f29bbaec818b116d357cfc237ca"},{url:"en/presentation/index.html",revision:"858065eec900b3382ade5cfca48572cf"},{url:"en/workshops/index.html",revision:"dc4b77ab4b0592fb374208b3af9c6304"},{url:"fr/backend-development/index.html",revision:"f9d642a7ee2325004b7aff95dc6e54c8"},{url:"fr/front-development/index.html",revision:"5d94cda740027d03f33a92584c39a7fc"},{url:"fr/index.html",revision:"e8e0741e6a35cd5924a3edff73a933a1"},{url:"fr/kotlin-features-advanced/index.html",revision:"ad07bb353640d159cc59dc2884a701a4"},{url:"fr/kotlin-features/index.html",revision:"0176a79b8c56ce3c0e36078bbfa30d4d"},{url:"fr/other-technologies/index.html",revision:"11c93b83da64d78521cc081cda404cd8"},{url:"fr/presentation/index.html",revision:"6f28aeb24943393b695f964e797b7fe9"},{url:"fr/workshops/index.html",revision:"2fbf964df4178ec186941faf27049bd8"},{url:"index.html",revision:"db53718f09a831bf793bde46761f6cfc"}],{}),e.cleanupOutdatedCaches()})); diff --git a/workbox-1ab968a5.js b/workbox-1ab968a5.js new file mode 100644 index 0000000..b46d3f7 --- /dev/null +++ b/workbox-1ab968a5.js @@ -0,0 +1 @@ +define(["exports"],(function(t){"use strict";try{self["workbox:core:7.0.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.0.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super((({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)}),e,s)}}class o{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",(t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map((e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})})));t.waitUntil(s),t.ports&&t.ports[0]&&s.then((()=>t.ports[0].postMessage(!0)))}}))}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let o=r&&r.handler;const c=t.method;if(!o&&this.i.has(c)&&(o=this.i.get(c)),!o)return;let a;try{a=o.handle({url:s,request:t,event:e,params:i})}catch(t){a=Promise.reject(t)}const h=r&&r.catchHandler;return a instanceof Promise&&(this.o||h)&&(a=a.catch((async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n}))),a}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const o=r.match({url:t,sameOrigin:e,request:s,event:n});if(o)return i=o,(Array.isArray(i)&&0===i.length||o.constructor===Object&&0===Object.keys(o).length||"boolean"==typeof o)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let c;const a=()=>(c||(c=new o,c.addFetchListener(),c.addCacheListener()),c);const h={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},u=t=>[h.prefix,t,h.suffix].filter((t=>t&&t.length>0)).join("-"),l=t=>t||u(h.precache),f=t=>t||u(h.runtime);function w(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.0.0"]&&_()}catch(t){}function d(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class p{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class y{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.h.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.h=t}}let g;async function R(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=e?e(r):r,c=function(){if(void 0===g){const t=new Response("");if("body"in t)try{new Response(t.body),g=!0}catch(t){g=!1}g=!1}return g}()?i.body:await i.blob();return new Response(c,o)}function m(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class v{constructor(){this.promise=new Promise(((t,e)=>{this.resolve=t,this.reject=e}))}}const q=new Set;try{self["workbox:strategies:7.0.0"]&&_()}catch(t){}function U(t){return"string"==typeof t?new Request(t):t}class L{constructor(t,e){this.u={},Object.assign(this,e),this.event=e.event,this.l=t,this.p=new v,this.R=[],this.m=[...t.plugins],this.v=new Map;for(const t of this.m)this.v.set(t,{});this.event.waitUntil(this.p.promise)}async fetch(t){const{event:e}=this;let n=U(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.l.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=U(t);let s;const{cacheName:n,matchOptions:i}=this.l,r=await this.getCacheKey(e,"read"),o=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,o);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=U(t);var i;await(i=0,new Promise((t=>setTimeout(t,i))));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(o=r.url,new URL(String(o),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var o;const c=await this.q(e);if(!c)return!1;const{cacheName:a,matchOptions:h}=this.l,u=await self.caches.open(a),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=m(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),o=await t.keys(e,r);for(const e of o)if(i===m(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?c.clone():c)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of q)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:a,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.u[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=U(await t({mode:e,request:n,event:this.event,params:this.params}));this.u[s]=n}return this.u[s]}hasCallback(t){for(const e of this.l.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.l.plugins)if("function"==typeof e[t]){const s=this.v.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.R.push(t),t}async doneWaiting(){let t;for(;t=this.R.shift();)await t}destroy(){this.p.resolve(null)}async q(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class b{constructor(t={}){this.cacheName=f(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new L(this,{event:e,request:s,params:n}),r=this.U(i,s,e);return[r,this.L(r,i,s,e)]}async U(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this._(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async L(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}class C extends b{constructor(t={}){t.cacheName=l(t.cacheName),super(t),this.C=!1!==t.fallbackToNetwork,this.plugins.push(C.copyRedirectedCacheableResponsesPlugin)}async _(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.O(t,e):await this.N(t,e))}async N(t,e){let n;const i=e.params||{};if(!this.C)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,o=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&o&&"no-cors"!==t.mode&&(this.k(),await e.cachePut(t,n.clone()))}return n}async O(t,e){this.k();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}k(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==C.copyRedirectedCacheableResponsesPlugin&&(n===C.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(C.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}C.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},C.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await R(t):t};class E{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.K=new Map,this.P=new Map,this.T=new Map,this.l=new C({cacheName:l(t),plugins:[...e,new y({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.l}precache(t){this.addToCacheList(t),this.W||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.W=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=d(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.K.has(i)&&this.K.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.K.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.T.has(t)&&this.T.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.T.set(t,n.integrity)}if(this.K.set(i,t),this.P.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return w(t,(async()=>{const e=new p;this.strategy.plugins.push(e);for(const[e,s]of this.K){const n=this.T.get(s),i=this.P.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}}))}activate(t){return w(t,(async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.K.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}}))}getURLsToCacheKeys(){return this.K}getCachedURLs(){return[...this.K.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.K.get(e.href)}getIntegrityForCacheKey(t){return this.T.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}let O;const x=()=>(O||(O=new E),O);class N extends i{constructor(t,e){super((({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const o=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some((t=>t.test(s)))&&t.searchParams.delete(s);return t}(r,e);if(yield o.href,s&&o.pathname.endsWith("/")){const t=new URL(o.href);t.pathname+=s,yield t.href}if(n){const t=new URL(o.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}}),t.strategy)}}function k(t){const e=x();!function(t,e,n){let o;if("string"==typeof t){const s=new URL(t,location.href);o=new i((({url:t})=>t.href===s.href),e,n)}else if(t instanceof RegExp)o=new r(t,e,n);else if("function"==typeof t)o=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});o=t}a().registerRoute(o)}(new N(e,t))}t.cleanupOutdatedCaches=function(){self.addEventListener("activate",(t=>{const e=l();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter((s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t));return await Promise.all(s.map((t=>self.caches.delete(t)))),s})(e).then((t=>{})))}))},t.clientsClaim=function(){self.addEventListener("activate",(()=>self.clients.claim()))},t.precacheAndRoute=function(t,e){!function(t){x().precache(t)}(t),k(e)}}));